Compare commits

Invalid templates have been ignored

1 invalid template(s) found .github/PULL_REQUEST_TEMPLATE.md: 'about' is required

...

131 Commits

Author SHA1 Message Date
nakarlsson 8f3841e3ce
Merge pull request #180 from OpenEtherCATsociety/feature/improve_eeprom_reload_handling_al2
Improve emulated EEPROM reload handling
2024-04-09 16:15:44 +02:00
Andreas Karlsson fcd43fb2e6 Improve emulated EEPROM reload handling
Add variable to control if ESC support read size 4
or 8 Byte. Depends on ESC

Add variable and function to set user function to
perform emulated EEPROM reload.

Include custom reload sample snippets.
2024-04-09 14:03:31 +02:00
nakarlsson 66111d50fa
Merge pull request #176 from OpenEtherCATsociety/feature/add_sm_disabled_enabled_readback
Add readback that SM bit is set enabled/disabled
2024-03-27 11:09:03 +01:00
Andreas Karlsson 41438c4a33 Add readback that SM bit is set enabled/disabled
On PDI disable/enable, add polling readback that
it is set/cleared. Set 1 is delayed
until the end of a frame which is currently
processed, ET1100 datasheet.

This aligns the code base with SCC behavior.
2024-03-27 09:07:13 +01:00
nakarlsson 56124c2348
Merge pull request #170 from OpenEtherCATsociety/fix/reset_esc_repeat_ack
Sync local SM PDIreg with ESC PDIreg at Mbx start
2024-03-20 10:04:54 +01:00
Andreas Karlsson d04bed4666 Sync local SM PDIreg with ESC PDIreg at Mbx start
When starting mailbox service, write the value of
ECAT RepeatRequest to PDI RepeatAck. Otherwise
it is risk of a race condition when running
CTT and the repeat ack would hold the value
of previous repeat ack test.

The race condition occurs on slow targets
that doesn't handle the repeat request
fast enough. The resulting mailbox read
will come before the mailbox is emptied
on the SM changed event.

fixes
2024-03-20 08:26:25 +01:00
nakarlsson 05bf6c6726
Merge pull request #167 from OpenEtherCATsociety/fix/download_variable_using_CA
Fix padding of index 0 for object type variable
2024-02-05 16:38:10 +01:00
Andreas Karlsson 9525469a68 Fix padding of index 0 for object type variable
If object of type Variable return true bitsize
of subindex 0.

fixes #166
2024-02-05 09:36:04 +01:00
nakarlsson 3fe4511230
Merge pull request #152 from nakarlsson/fix/don_t_enable_debug_prints_by_default
Fix disable esc debug
2023-04-24 13:42:30 +02:00
Vijay Katoch e2f3fb7fd2 Fix disable esc debug 2023-04-24 13:39:34 +02:00
nakarlsson 6e70471e1b
Merge pull request #150 from nakarlsson/fix/Wconversion_generated_by_clang
Fix Wconversion issues for clang
2023-04-24 07:53:34 +02:00
Andreas Karlsson 70a1042188 Use inttypes print formatting macros
Use inttypes print formatting macros

Update DPRINT support for rt-kernel
2023-04-14 12:12:51 +02:00
Andreas Karlsson 2f4afb3230 Fix Wconversion issues for clang
Add explicit uint16_t cast for EoE header SET macros.
Used for SET of FrameInfo 1 and FrameInfo 2.

Increase datatype for offset used by EOE_HDR_FRAME_OFFSET_GET.

Change debug print formatting to %u for unsigned datatypes.
2023-04-14 12:12:22 +02:00
nakarlsson 5221cfbe76
Merge pull request #149 from nakarlsson/fix/warnings_generated_by_flag_Wconversion
Fix/warnings generated by flag wconversion
2023-03-29 12:13:27 +02:00
Andreas Karlsson 0d232899bb Enable Wconversion for Linux
Enable Wconversion for Linux for CI
to be used as regression.

Fix esc_hw.c warnings by adding explicit
typecasts. The code is based on Microchip
reference code so keep changes to a minimal.
2023-03-28 22:43:57 +02:00
Andreas Karlsson 3896a981ce Fix esc_foe Wconversion warnings
- make "size" variables not reflecting hardware or protocol
  uint32_t or size_t.

- add excplcit typecaste for uint8_t and uint16_t that need it
  due to integer promotion
2023-03-28 21:18:19 +02:00
Andreas Karlsson 45d390a014 Fix esc_eoe Wconversion warnings
- make "size" variables not reflecting hardware or protocol
  uint32_t.

- add excplcit typecaste for uint8_t and uint16_t that need it
  due to integer promotion

- split assignment using macros and bitwise operations to avoid
  implicit conversion and need of explicit conversion.
2023-03-28 21:18:14 +02:00
Andreas Karlsson f63bca476d Fix esc_coe Wconversion warnings
- make "size" variables not reflecting hardware or protocol
  uint32_t.

- change size_t to uint32_t to avoid conversion when compiling
  on x64

- add excplcit typecaste for uint8_t and uint16_t that need it
  due to integer promotion

- split assignment using macros and bitwise operations to avoid
  imlicit conversion and need of explicit conversion.

- add excplicit typecast to htoe MACROs
2023-03-28 21:17:59 +02:00
Andreas Karlsson d22277f4a5 Add typecast for bitwise operations of ESC
Add explicit typecasts for bitwise operations and
bitfields opeations of ESC.
2023-03-27 20:48:59 +02:00
Andreas Karlsson ac198e05b1 Add explicit typecast for ESC SM addressing
Add explicit typecast for uint16_t address
for ESC_read/WAC_write. The ESC RAM address
space is limited to 16Bit.
2023-03-27 20:48:59 +02:00
Andreas Karlsson 60e397aebc Change ESCvar member datatypes
* Align ESCvar.Alevent with ESC HW. Legacy it was 16-bit
      to be used with 2-byte mode SPI transfers that returned
      0x220-0x221.

* Increase size for fragments variables to avoid conversion
  warnings when counting mailbox data size. ESCvar.frags and
  ESCvar.fragsleft.
2023-03-27 20:48:59 +02:00
Andreas Karlsson 97472108e3 Add reference to objectlist in SM mappings
Rationale, users might need more info on what
object it is that is mapped. Having a reference to
objectlist enable the user to know what index it is
and got a reference to the entire object. The obj
only know what subindex it is.

fixes #137
2023-02-27 13:50:42 +01:00
Andreas Karlsson fd6dbdf188 Don't force packing of objd/objectlist stucts
objd/objectlist don't map to any EtheCAT protocol
headers, hence they don't need to be packed.

Pro and conns for packing or not.

Packed structs give optimized smaller size of ObjectDictionary.

Unpacked structs give optimized performance when iterating and
accessing processdata pointers.

Unpacked give more toolchain portable code.
2023-02-27 13:48:30 +01:00
Andreas Karlsson 3bb489469b Add support for CoE flags requried by MFC2020
Backup
Settings
RWop
RWpre_safe

(defined in ETG1000-6)

fixes #142
2023-02-27 13:48:30 +01:00
nakarlsson 8bb4350cd5
Merge pull request #140 from OpenEtherCATsociety/fix/bitpos_offset_in_mailbox_response
Add fix for bitpos2byteoffset
2022-11-28 16:49:51 +01:00
Andreas Karlsson fff8e22603 Add fix for bitpos2byteoffset
Can't use BITS2BYTE when calculating true bit offset
in a byte. Instead add a new macro that don't
round up to full byte size.

fixes #139
2022-11-26 13:11:34 +01:00
nakarlsson a7a017c26f
Merge pull request #120 from nakarlsson/master
Improve SM validation for input- ouput only slaves
2022-10-03 19:53:38 +02:00
nakarlsson ac0031aef5
Merge pull request #134 from m-dema/master
Exit eoe receive function if buffer is not valid
2022-09-27 18:23:37 +02:00
Andreas Karlsson 8ebb78ea10 Enable SM3 interrupt for input only slave
Enable SM3 interrupt if the slave only got
inputs.

On PREOP_TO_SAFEOP do an intial write to SM3,
otherwise the SM3 will never occur since there
is no data present to read.
2022-09-27 18:16:22 +02:00
m-dema 66b040a257
Exit eoe receive function if buffer is not valid
If buffer is invalid the call to the subsequent memcpy will corrupt memory
2022-09-23 17:04:42 +02:00
nakarlsson 8de160a851
Merge pull request #126 from fsugai/master
Fix: FOE_fwrite is unable to detect a failure if write_function fails to write on last data
2022-08-19 15:56:45 +02:00
Fumihito Sugai 35288ff3e7 Do not increment ncopied if failed writing 2022-08-19 22:47:45 +09:00
nakarlsson fc72fbeeec
Merge pull request #123 from konradhermsdorf/fix/rxpdo-handling-in-safeop
do not update output variables in SafeOp
2022-07-02 11:30:19 +02:00
Konrad Hermsdorf 254a6f807d do not update output variables in SafeOp
Just read SM data to reset SM Watchdog but do not update the output variables linked to the RxPDOs in SafeOp
2022-06-29 16:03:49 +02:00
andreas karlsson 48c80f5cae Impove SM validation for input- ouput only slaves
Re-add always verify SM length

Add validation of SM disabled, don't allow master
to activate or set a length if disabled.

Add validation of SM enabled, don't allow master
to set a length and de-activate.
2022-06-19 10:51:51 +02:00
nakarlsson acc59dd6b8
Merge pull request #119 from nakarlsson/master
Add support for input- or output only slaves
2022-06-15 20:58:33 +02:00
andreas karlsson 366c07f446 Add support for input- or output only slaves
Seperate validation of SM configuration that
depend on size of tx/rx pdo.

Add disable of SM3 when input only slave
reports error in OP.

Don't enable SM3 on start input if no inputs

Don't enable SM2 on start outputs if no
outputs

fix #112
fix #113
2022-06-15 20:50:31 +02:00
nakarlsson 6fc395e085
Merge pull request #117 from hefloryd/master
Declare rxpdo, txpdo as arrays
2022-06-02 14:16:26 +02:00
Hans-Erik Floryd d96f7cefef Declare rxpdo, txpdo as arrays
Rxpdo/txpdo were declared as external pointers if MAX_MAPPINGS2/3 were
0. However they must be declared as arrays for an external unit to be
able to use them as such.

Change-Id: I4bd547ae809ccfcb2dc1761f0f511f7e6088b712
2022-06-02 13:59:43 +02:00
nakarlsson fa0d6bf4d6
Merge pull request #116 from lrsdnlssn/master
Add support for Explicit Device Identification
2022-05-31 06:48:38 +02:00
Lars Danielsson 69b1049970 Add support for Explicit Device Identification
Change-Id: Idbf636f37c02923d251742cc5f49ff1579eaebc6
2022-05-30 15:51:20 +02:00
Hans-Erik Floryd 3c5af65be6
Merge pull request #109 from OpenEtherCATsociety/fix/download_segmented_completeaccess
Fix errornous segmented download CompleteAccess
2021-12-16 14:06:50 +01:00
andreas karlsson df0d169eef Fix errornous segmented download CompleteAccess
On the final segment the SDO shoud be written using the
pre-allocated buffer used to store segments during transfer.
When completed the pre-allocated buffer is written to the SDO.
This fix change to correct complete_access_subindex_loop
 - buffer, ESCvar.mbxdata
 - to use the lookup indexes for ESCVar.index -> nidx and
   ESCvar.subindex -> nsub.
2021-12-16 10:36:54 +01:00
nakarlsson 311977e47a
Merge pull request #105 from Joanle/fix-eeprom-command-def
correct eeprom command
2021-10-26 16:02:15 +02:00
Juan Leyva da33a714a1 Merge branch 'fix-eeprom-command-def' of https://github.com/Joanle/SOES into fix-eeprom-command-def 2021-10-26 08:50:04 -05:00
Juan Leyva cd12c0d156 correct eeprom command
change reload command to the correct value
2021-10-26 08:49:41 -05:00
nakarlsson ff6be22c80
Merge pull request #106 from hefloryd/master
Bump build platform and fix GCC9 warnings
2021-10-26 15:35:44 +02:00
Hans-Erik Floryd 2808e95668 Bump cmake version
Specifying a minimum cmake version 0f 2.8.4 triggers a warning with
never cmake, due to backwards compatibility issue. Bump to 2.8.12
which is the oldest version without the warning.
2021-10-26 09:36:04 +02:00
Hans-Erik Floryd 097477035d Fix address-of-packed-member warnings
GCC9 introduced an address-of-packed-member warning that triggers in
esc_coe.c. The issue is that a packed struct has an overall alignment
of 1, and taking the address of a member in a packed struct is not
guaranteed to have any particular alignment. However, in esc_coe these
structs are always overlayed on aligned memory so in practice there is
no problem.

Fix the problem by explicitly setting the minimum alignment for the
structs used in this manner. Also fix an instance where an unaligned
pointer was used but never dereferenced (by changing the type of the
pointer from uint32_t* to void*).
2021-10-26 09:36:04 +02:00
Hans-Erik Floryd 4d9da268be Bump build platform
Ubuntu 16.04 is now deprecated. Build using latest LTS.
2021-10-25 09:57:18 +02:00
Juan Leyva 5e94f0bb81 correct eeprom command
change reload command to the correct value
2021-10-15 23:32:20 -05:00
Hans-Erik Floryd 4549d0af9a
Merge pull request #103 from MechaMagpie/etherberry
Etherberry support
2021-09-06 16:44:29 +02:00
MechaMagpie 98a90d61ea Add simple demo for Raspberry Pi
Add a demo application for Raspberry Pi with a LAN9252-based EtherCat hat,
such as with the SG Electronics Systems EtherBerry.
2021-09-02 16:40:40 +02:00
iwoodsawyer b3e2a0a2c1 Add HAL for Raspberry Pi / LAN9252
Add support for EtherCAT slave HAT with LAN9252 chip (like EasyCAT or
EtherC/EtherBerry) for Raspberry Pi using the BCM2835 library.
2021-08-31 13:40:21 +02:00
nakarlsson 2fd5088fea
Merge pull request #100 from m-dema/patch-1
Fix inconsistent function name
2021-05-10 14:16:23 +02:00
m-dema c84a3ffb4d
Fix inconsistent function name
the function is different in header declaration (EOE_ecat_get_mac)
2021-05-06 17:05:46 +02:00
nakarlsson 1f24b72c5c
Merge pull request #99 from lrsdnlssn/master
Fix segmented download using complete access
2021-04-06 14:23:36 +02:00
Lars Danielsson e40d95cc1e Fix segmented download using complete access
Change-Id: If6060fb5bb1084c88c4159e2bcd38ba9b8eb3d40
2021-04-01 11:05:28 +02:00
nakarlsson f244ea522d
Merge pull request #98 from hefloryd/feature/gh-actions
Migrate to Github Actions
2021-02-17 16:45:26 +01:00
Hans-Erik Floryd 0d6f7de0e6 Migrate to Github Actions 2021-02-17 16:33:17 +01:00
Hans-Erik Floryd 591d08d474
Merge pull request #97 from hefloryd/master
Regenerate rtl_xmc4_dynpdo
2021-02-11 17:09:34 +01:00
Hans-Erik Floryd 85319b8524 Regenerate rtl_xmc4_dynpdo
Regenerate source and artifacts from slave.esx using EtherCAT Slave
Editor.
2021-02-11 16:40:22 +01:00
Hans-Erik Floryd eb1848a9a3
Merge pull request #92 from lrsdnlssn/master
Let hook modify size, and also fix handling of large objects
2021-02-10 16:12:33 +01:00
Lars Danielsson 8d5afc9b2d Convert bits to bytes in the correct place 2021-02-10 14:58:15 +01:00
Lars Danielsson 87b2c1eb93 Fix for very large objects (with Complete Access)
Change-Id: I95c7b0f73e581ef6dace14e9b8f02ceff50f38ca
2020-10-26 10:57:51 +01:00
Lars Danielsson 48772707a6 Fix handling of large objects in SDO Upload with Complete Access
Change-Id: I64471e2ac1ac1865db43c48fd15b0e1d44651a66
2020-10-19 14:22:02 +02:00
Lars Danielsson c814d2dacf Allow the pre_object_upload_hook to modify size
Change-Id: Ia95a1e8e3ba7e6bde3286f4eb15f8ba7f0cb85b2
2020-10-19 14:21:09 +02:00
Hans-Erik Floryd 71bb37091f
Merge pull request #89 from lrsdnlssn/master
Allow Download Complete Access data size to be less than full size
2020-09-29 15:39:39 +02:00
Lars Danielsson 74d710b8b7 Add more data types which may have flexible length
Change-Id: Ia78d89adfb4017e970ace7fdf0b1bccffc8ac357
2020-09-28 15:41:27 +02:00
Lars Danielsson a6f45c308f Allow Download Complete Access data size to be less than full size
Change-Id: Ie27c54547c88d89bc1a8c99afc875ea1276a6d85
2020-09-28 15:39:16 +02:00
Hans-Erik Floryd 9ea52dff56
Merge pull request #87 from lrsdnlssn/master
Export SDO_findobject and fix missing include path
2020-09-16 14:50:30 +02:00
Lars Danielsson c0d3e17bcf Export function SDO_findobject()
Change-Id: I30b1c3b6a47111c1305aaa310bfdd882951689a1
2020-09-16 12:59:58 +02:00
Lars Danielsson 177739b02d Fix missing include path
Change-Id: Icb3188babcac2124a0dd1d3c86a9686e6d98f647
2020-09-16 12:59:49 +02:00
Hans-Erik Floryd ed6a6542c8
Merge pull request #86 from lrsdnlssn/master
Simplify foe et al.
2020-09-10 13:04:18 +02:00
Lars Danielsson d9ebdc99fe Simplify foe
Change-Id: I4de53dddf63b6ceb8c9654c9dad73f7d69bd5ee0
2020-09-09 15:44:39 +02:00
Lars Danielsson 59728c994c Add option to skip default initialization
Change-Id: I08bad59fe5adbb616a9005570a153511738bee1e
2020-09-09 15:44:29 +02:00
Lars Danielsson dd21bd3423 Improve debug printout in FOE_write()
Change-Id: Ib79ca30360f2b1ed5eb86cbc72850c5068e05c54
2020-09-09 15:44:20 +02:00
Lars Danielsson d970d8eb1e Increase maximum file name length
Change-Id: Ief4ac03f8b47f0cfa5a3086a41e57e7d81c2c764
2020-09-09 15:44:09 +02:00
Lars Danielsson 9a430287d1 Add error code FOE_ERR_CHECKSUM (0x800C)
Change-Id: Ic607fd3d93c10bfaae28102182434f6d59ab7734
2020-09-09 15:43:59 +02:00
Lars Danielsson aee9bf569b Export function SDO_findsubindex()
Change-Id: I79a364687510a9869c4c9287121093e3a2f003b9
2020-09-09 15:43:43 +02:00
Hans-Erik Floryd 4746f22c78
Merge pull request #82 from nakarlsson/master
Don't always include optional IP parameter lengths
2020-08-20 10:36:08 +02:00
Hans-Erik Floryd 09394ecfc8
Merge pull request #83 from lrsdnlssn/master
Handle SDO entries with flexible length
2020-08-20 10:34:58 +02:00
Lars Danielsson 32c8901940 Optimize function SDO_findsubindex()
Since most objects contain all subindexes (i.e. are not sparse),
check the most likely scenario first.

Change-Id: Idfda8ae3a3903c8312e02c9354b241af804f69ed
2020-08-19 14:49:28 +02:00
Lars Danielsson 12006a53a5 Make not exported functions static declared
Change-Id: I7e9bdb7f651ab26bffc3466f8e3a050db91659c6
2020-08-19 14:49:23 +02:00
Lars Danielsson 86c17dbb14 Add handling of write-only objects
Change-Id: I9bfdb11c5d1d83cb2c23115e204ffe6875b4457b
2020-08-19 14:49:16 +02:00
Lars Danielsson cde698b1ea Handle SDO entries with flexible length
Change-Id: I1d2e1549c497aaef801b1ea42342843e5ff3e73d
2020-08-19 14:49:06 +02:00
Andreas Karlsson 28e19f4f82 Don't always include optional IP parameter lengths
Obvious fix, the optional IP parameters length should
only be included in total length if they are included.

fixes #81
2020-08-16 11:32:25 +02:00
nakarlsson ba3adf8b74
Merge pull request #80 from lrsdnlssn/master
SOES extensions: Add Download SDO Segment
2020-08-12 13:58:31 +02:00
Lars Danielsson e428008ea3 Add more SDO abort codes
Change-Id: I7855d8bf0c73ded816cc529c91216d12545a0d93
2020-08-12 13:35:09 +02:00
Lars Danielsson b6f4444b9e Corrected size in callback for segmented data
The upload pre callback was called with incorrect size for
segmented data (segmented size instead of the total size).

Change-Id: Ie29f138187d70c115d40267e4181e203bdfec5d1
2020-08-12 13:34:54 +02:00
Lars Danielsson 78871af81b Add data types BITARR8/16/32
Change-Id: Id8c75ff095cdee5d167df33ab3a80912a325adc7
2020-08-12 13:34:39 +02:00
Lars Danielsson 6eedcb7cdf Use callback also when data is NULL
Change-Id: Id75f52772dfb80fc6802a7a9e252e9f3fc2f33f0
2020-08-12 13:34:21 +02:00
Lars Danielsson bdea958dd5 Add Download SDO Segment
Change-Id: I4748930d80c831947ff2d8b300ca590a4a67b84f
2020-08-12 13:33:37 +02:00
Andreas Karlsson 24b700e1c4 Init CoE SDO defaults on SOES stack init
The init of COE SDO defaults shall not be part of the
state machine according to ETG. Move the init to
SOES stack init where it will only be run once.

Small editorial changes on function and paranthesis
to unify in that function.
2020-08-11 14:47:12 +02:00
Hans-Erik Floryd 46240450af
Merge pull request #77 from lrsdnlssn/master
Add SDO Complete Access
2020-07-07 14:40:27 +02:00
Lars Danielsson bb566504de Fix missing include path 2020-07-07 14:35:13 +02:00
Lars Danielsson 81ff180e7e Add SDO Complete Access
Limitation: Download SDO Segment is not supported.

Change-Id: I74daccd2a2ce4cf9aa8bb1e46cf6ac1478d5bdd5
2020-07-07 13:11:49 +02:00
Hans-Erik Floryd 3792b58fea
Merge pull request #75 from lrsdnlssn/master
Add/extend support for upload and download callbacks
2020-06-22 15:18:16 +02:00
Lars Danielsson 2296b55812 Add/extend support for upload and download callbacks 2020-06-22 15:01:06 +02:00
Hans-Erik Floryd 0878d71924
Merge pull request #70 from OpenEtherCATsociety/fix/xmc4xrelax_phy_reset
XMC4 rt-kernel ESC HW improvments
2019-10-07 17:38:37 +02:00
Andreas Karlsson 8ff826c409 Update ESCvar.time in rtk esc_hw workerthread loop
ESCvar.time is used by emulated eeprom handler to
measure idle time, when enough time have elapsed the
write is assumed to be completed and the EEPROM RAM
buffer is flushed to FLASH.

fix #69
2019-10-07 16:51:06 +02:00
Andreas Karlsson 767c38b0b6 Let XMC4 BSPs configure and keep ECAT PHY in reset
Configure ECAT_PHY_RESET as a general purpose output in BSP
and set/keep PHYs in reset and let the EtherCAT slave
stack handle release/re-configure of PHY reset to correct
alternate function after EtherCAT block is released from
reset.

fix #68
2019-10-07 16:31:09 +02:00
Hans-Erik Floryd f16daf271e allow setting default lower bits of large values
The objd value member is 32 bits; it cannot set the upper bits but
could be useful to set the lower bits of values larger than 32 bits.
2019-07-11 10:07:52 +02:00
Hans-Erik Floryd 9cc583613b update README.md 2019-07-10 16:19:10 +02:00
nakarlsson 45bca4853a
Merge pull request #62 from hefloryd/master
Fixes for #59 and #57
2019-07-10 14:19:58 +02:00
Hans-Erik Floryd c8575b795f use gcc __builtin_bswap16 to byteswap 16-bit values
__builtin_bswap16 is available since gcc4.8.
2019-07-10 12:25:13 +02:00
Hans-Erik Floryd f0a378382e redefine DPRINT macro
Set DPRINT macro to printf by default. Long term this should be in an
os-abstraction layer but currently that would only include this macro.

Also fix an instance of invalid DPRINT usage.

Fix #57
2019-07-10 12:05:23 +02:00
Hans-Erik Floryd f61e77a5d1 revert to 32-bit objd values
The size of the objd->value member was previously increased to 64-bit
to allow setting 64-bit default values. This may waste some (ROM)
memory as 64-bit values are somewhat uncommon, and the value can be
set from an application hook instead. Revert to 32-bit values.

Fix #59
2019-07-10 12:05:23 +02:00
Ilias Patsiaouras 75a5514430 Feature/add al status code definitions (#60)
Add AL Status code definitions
2019-06-27 07:19:20 +02:00
Ilias Patsiaouras 38099d31ed ecat control latch input selection and ecat reset request (#56)
* ecat port control common register initialization
2019-06-26 13:43:15 +02:00
nakarlsson 0f2959be46
Merge pull request #58 from elsp1991/bug/fi_foe_read_supported_build
fix build fail when FOE_READ_SUPPORTED is defined
2019-06-26 08:31:15 +02:00
Ilias Patsiaouras 576624fd70 fix build fail when FOE_READ_SUPPORTED is defined 2019-06-24 12:52:10 +02:00
Hans-Erik Floryd b46bb0ab0e
Merge pull request #52 from hefloryd/feature/soesv3
Feature/soesv3
2019-05-09 15:45:42 +02:00
Hans-Erik Floryd 489c5e257e bump version to 3.0.0 2019-05-09 15:44:03 +02:00
Hans-Erik Floryd 27ab8dfba5 cleanup applications
Remove rtl_lan9252demo and rtl_xmc4_irq as they are similar to other
applications.
2019-05-09 15:43:07 +02:00
Andreas Karlsson e600a515c5 add support for legacy static PDO mapping
Add possibility to use static PDO mapping. Upgrade XMC43 bare-metal
example to SOESv3.0 and use the static mapping.
2019-05-09 15:43:07 +02:00
Andreas Karlsson 5770a66558 Update applications to SOES v3.0 2019-05-09 15:43:07 +02:00
Andreas Karlsson 68427b6e1e EoE updates
- Add missing EoE include, make worker semaphore global to be able to
   trigger from application
 - Add an EoE fragment sent event callback
2019-05-09 15:43:07 +02:00
Andreas Karlsson 54de5af4b5 Update EoE application to new SOES version 2019-05-09 15:43:07 +02:00
Hans-Erik Floryd 14397b0575 add APP_setwatchdog
Add function to set watchdog count.
2019-05-09 15:43:07 +02:00
Hans-Erik Floryd d204255ad3 update objecthandler and hooks
Replace isCA with a set of flags to hold more data.

The pre_object_download_hook should return a COE abort code which is
an unsigned 32-bit value.
2019-05-09 15:43:07 +02:00
Hans-Erik Floryd 236a02bfb4 add hook for setting default values
Add set_defaults_hook to let application override default values.
2019-05-09 15:43:07 +02:00
Hans-Erik Floryd 55df56821a use options.h for config
Simplify configuration by using options.h directly.
2019-05-09 15:43:07 +02:00
Hans-Erik Floryd e27b6bcbb1 move globals to ecat_slv 2019-05-09 15:43:07 +02:00
Hans-Erik Floryd aa811ae2f4 add eoe to ecat_slv 2019-05-09 15:43:07 +02:00
Hans-Erik Floryd 675d3516fb add options.h
Add a header file for setting default stack configuration
options. Options can be overriden by a user configuration file.
2019-05-09 15:43:07 +02:00
Hans-Erik Floryd 0170a15229 add sample application for dynamic pdos 2019-05-09 15:43:07 +02:00
Hans-Erik Floryd 5b33b077ca add support for dynamic pdos
Add support for dynamic pdos, i.e. pdos that can be configured by the
EtherCAT master.
2019-05-09 15:43:07 +02:00
Andreas Karlsson 6fb665a701 Update App to use new DC checks, set error function, SM watchdog, fixed EEPROM delayed write and move generic slave functionallity to generic SOES 2019-05-09 15:43:07 +02:00
Andreas Karlsson ca48f9db21 Move DC config to the applications 2019-05-09 15:43:07 +02:00
Andreas Karlsson 446b79d456 Add function to enter state with error 2019-05-09 15:43:07 +02:00
113 changed files with 8652 additions and 6969 deletions

23
.github/workflows/build.yml vendored 100644
View File

@ -0,0 +1,23 @@
name: build
on: [push, pull_request]
env:
BUILD_TYPE: Release
jobs:
build:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Configure
shell: bash
run: |
cmake -E make_directory $GITHUB_WORKSPACE/build
cmake -B $GITHUB_WORKSPACE/build -S $GITHUB_WORKSPACE \
-DCMAKE_BUILD_TYPE=$BUILD_TYPE
- name: Build
shell: bash
run: |
cmake --build $GITHUB_WORKSPACE/build -j4

1
.gitignore vendored
View File

@ -33,3 +33,4 @@
/build
soes/version.h
applications/xmc4300_slavedemo/XMC_Peripheral_Library

View File

@ -1,8 +0,0 @@
language: c
script:
- mkdir build
- pushd build
- cmake .. -DCMAKE_BUILD_TYPE=Release
- make
- popd

View File

@ -1,12 +1,12 @@
# CMakeLists files in this project can
# refer to the root source directory of the project as ${SOES_SOURCE_DIR} and
# to the root binary directory of the project as ${SOES_BINARY_DIR}.
cmake_minimum_required (VERSION 2.8.4)
cmake_minimum_required (VERSION 2.8.12)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
project (SOES)
set (SOES_VERSION_MAJOR 2)
set (SOES_VERSION_MINOR 2)
set (SOES_VERSION_MAJOR 3)
set (SOES_VERSION_MINOR 0)
set (SOES_VERSION_PATCH 0)
# Generate version numbers

View File

@ -1,6 +1,6 @@
Simple Open Source EtherCAT Slave
====
[![Build Status](https://travis-ci.org/OpenEtherCATsociety/SOES.svg?branch=master)](https://travis-ci.org/OpenEtherCATsociety/SOES)
[![Build Status](https://github.com/OpenEtherCATsociety/SOES/workflows/build/badge.svg?branch=master)](https://github.com/OpenEtherCATsociety/SOES/actions?workflow=build)
SOES (Simple OpenSource EtherCAT Slave Stack) is an opensource slave
stack that is very easy to use and provides a small footprint. It is a
@ -20,13 +20,13 @@ Feature list:
- Object dictionary
- SDO read and write for all sizes including segmented transfers
- Easy portable C-code suited for embedded applications
- Fixed PDO mapping
- Fixed and/or dynamic PDO mapping
- FoE with bootstrap template
- Support for Little and Big endian targets
- Run polling, mixed polling/interrupt or interrupt
- Support for SM Synchronization
- Support DC sync0 and DC Synchronization
- Add stack configuration via new configuration paramater to/or from
- Add stack configuration via new configuration parameter to/or from
"stack"_init
- EoE

View File

@ -1,7 +1,6 @@
add_executable (demo
main.c
slave.c
slave_objectlist.c
)
target_link_libraries(demo LINK_PUBLIC soes)

View File

@ -1,35 +0,0 @@
#ifndef __CONFIG_H__
#define __CONFIG_H__
#include <cc.h>
#define MBXSIZE 128
#define MBXSIZEBOOT 128
#define MBXBUFFERS 3
#define MBX0_sma 0x1000
#define MBX0_sml MBXSIZE
#define MBX0_sme MBX0_sma+MBX0_sml-1
#define MBX0_smc 0x26
#define MBX1_sma MBX0_sma+MBX0_sml
#define MBX1_sml MBXSIZE
#define MBX1_sme MBX1_sma+MBX1_sml-1
#define MBX1_smc 0x22
#define MBX0_sma_b 0x1000
#define MBX0_sml_b MBXSIZEBOOT
#define MBX0_sme_b MBX0_sma_b+MBX0_sml_b-1
#define MBX0_smc_b 0x26
#define MBX1_sma_b MBX0_sma_b+MBX0_sml_b
#define MBX1_sml_b MBXSIZEBOOT
#define MBX1_sme_b MBX1_sma_b+MBX1_sml_b-1
#define MBX1_smc_b 0x22
#define SM2_sma 0x1100
#define SM2_smc 0x24
#define SM2_act 1
#define SM3_sma 0x1180
#define SM3_smc 0x20
#define SM3_act 1
#endif /* __CONFIG_H__ */

View File

@ -0,0 +1,44 @@
#ifndef __ECAT_OPTIONS_H__
#define __ECAT_OPTIONS_H__
#include "cc.h"
#define USE_FOE 1
#define USE_EOE 0
#define MBXSIZE 128
#define MBXSIZEBOOT 128
#define MBXBUFFERS 3
#define MBX0_sma 0x1000
#define MBX0_sml MBXSIZE
#define MBX0_sme MBX0_sma+MBX0_sml-1
#define MBX0_smc 0x26
#define MBX1_sma MBX0_sma+MBX0_sml
#define MBX1_sml MBXSIZE
#define MBX1_sme MBX1_sma+MBX1_sml-1
#define MBX1_smc 0x22
#define MBX0_sma_b 0x1000
#define MBX0_sml_b MBXSIZEBOOT
#define MBX0_sme_b MBX0_sma_b+MBX0_sml_b-1
#define MBX0_smc_b 0x26
#define MBX1_sma_b MBX0_sma_b+MBX0_sml_b
#define MBX1_sml_b MBXSIZEBOOT
#define MBX1_sme_b MBX1_sma_b+MBX1_sml_b-1
#define MBX1_smc_b 0x22
#define SM2_sma 0x1100
#define SM2_smc 0x24
#define SM2_act 1
#define SM3_sma 0x1180
#define SM3_smc 0x20
#define SM3_act 1
#define MAX_RXPDO_SIZE 42
#define MAX_TXPDO_SIZE 42
#define MAX_MAPPINGS_SM2 2
#define MAX_MAPPINGS_SM3 1
#endif /* __ECAT_OPTIONS_H__ */

View File

@ -1,48 +1,54 @@
#include <stdio.h>
#include "slave.h"
#include "ecat_slv.h"
#include "utypes.h"
/**
* This function reads physical input values and assigns the corresponding members
* of Rb.Buttons
*/
void cb_get_Buttons()
/* Application variables */
_Objects Obj;
void cb_get_inputs (void)
{
}
/**
* This function writes physical output values from the corresponding members of
* Wb.LEDs
*/
void cb_set_LEDs()
void cb_set_outputs (void)
{
}
/**
* This function is called after a SDO write of the object Cb.Parameters.
*/
void cb_post_write_Parameters(int subindex)
int main_run (void * arg)
{
static esc_cfg_t config =
{
.user_arg = "/dev/lan9252",
.use_interrupt = 0,
.watchdog_cnt = 150,
.set_defaults_hook = NULL,
.pre_state_change_hook = NULL,
.post_state_change_hook = NULL,
.application_hook = NULL,
.safeoutput_override = NULL,
.pre_object_download_hook = NULL,
.post_object_download_hook = NULL,
.rxpdo_override = NULL,
.txpdo_override = NULL,
.esc_hw_interrupt_enable = NULL,
.esc_hw_interrupt_disable = NULL,
.esc_hw_eep_handler = NULL,
.esc_check_dc_handler = NULL,
};
}
printf ("Hello Main\n");
ecat_slv_init (&config);
void main_run(void * arg)
{
soes_init();
while (1)
{
ecat_slv();
}
while(1) {
soes();
}
}
int main(void)
{
printf("Hello Main\n");
main_run(NULL);
return 0;
}
int main (void)
{
printf ("Hello Main\n");
main_run (NULL);
return 0;
}

View File

@ -1,300 +0,0 @@
#include <stddef.h>
#include "utypes.h"
#include "esc.h"
#include "esc_coe.h"
#include "esc_foe.h"
#include "config.h"
#include "slave.h"
#define WATCHDOG_RESET_VALUE 150
#define DEFAULTTXPDOMAP 0x1a00
#define DEFAULTRXPDOMAP 0x1600
#define DEFAULTTXPDOITEMS 1
#define DEFAULTRXPDOITEMS 1
/* Global variables used by the stack */
uint8_t MBX[MBXBUFFERS * MAX(MBXSIZE,MBXSIZEBOOT)];
_MBXcontrol MBXcontrol[MBXBUFFERS];
_ESCvar ESCvar;
/* Application variables */
_Rbuffer Rb;
_Wbuffer Wb;
_Cbuffer Cb;
/* Private variables */
uint16_t txpdomap = DEFAULTTXPDOMAP;
uint16_t rxpdomap = DEFAULTRXPDOMAP;
uint8_t txpdoitems = DEFAULTTXPDOITEMS;
uint8_t rxpdoitems = DEFAULTTXPDOITEMS;
static int watchdog = WATCHDOG_RESET_VALUE;
static void (*application_loop_callback)(void) = NULL;
/** Function to pre-qualify the incoming SDO download.
*
* @param[in] index = index of SDO download request to check
* @param[in] sub-index = sub-index of SDO download request to check
* @return 1 if the SDO Download is correct. 0 If not correct.
*/
int ESC_pre_objecthandler (uint16_t index, uint8_t subindex)
{
if ((index == 0x1c12) && (subindex > 0) && (rxpdoitems != 0))
{
SDO_abort (index, subindex, ABORT_READONLY);
return 0;
}
if ((index == 0x1c13) && (subindex > 0) && (txpdoitems != 0))
{
SDO_abort (index, subindex, ABORT_READONLY);
return 0;
}
return 1;
}
/** Mandatory: Hook called from the slave stack SDO Download handler to act on
* user specified Index and Sub-index.
*
* @param[in] index = index of SDO download request to handle
* @param[in] sub-index = sub-index of SDO download request to handle
*/
void ESC_objecthandler (uint16_t index, uint8_t subindex)
{
switch (index)
{
case 0x1c12:
{
if (rxpdoitems > 1)
{
rxpdoitems = 1;
}
if ((rxpdomap != 0x1600) && (rxpdomap != 0x1601)
&& (rxpdomap != 0x0000))
{
rxpdomap = 0x1600;
}
ESCvar.RXPDOsize = ESCvar.ESC_SM2_sml = sizeOfPDO(RX_PDO_OBJIDX);
break;
}
case 0x1c13:
{
if (txpdoitems > 1)
{
txpdoitems = 1;
}
if ((txpdomap != 0x1A00) && (txpdomap != 0x1A01)
&& (rxpdomap != 0x0000))
{
txpdomap = 0x1A00;
}
ESCvar.TXPDOsize = ESCvar.ESC_SM3_sml = sizeOfPDO(TX_PDO_OBJIDX);
break;
}
/* Handle post-write of parameter values */
case 0x8000:
{
cb_post_write_Parameters(subindex);
break;
}
default:
break;
}
}
/** Mandatory: Hook called from the slave stack ESC_stopoutputs to act on state changes
* forcing us to stop outputs. Here we can set them to a safe state.
* set
*/
void APP_safeoutput (void)
{
DPRINT ("APP_safeoutput\n");
// Set safe values for Wb.LEDs
Wb.LEDs.LED0 = 0;
Wb.LEDs.LED1 = 0;
}
/** Mandatory: Write local process data to Sync Manager 3, Master Inputs.
*/
void TXPDO_update (void)
{
ESC_write (SM3_sma, &Rb, ESCvar.TXPDOsize);
}
/** Mandatory: Read Sync Manager 2 to local process data, Master Outputs.
*/
void RXPDO_update (void)
{
ESC_read (SM2_sma, &Wb, ESCvar.RXPDOsize);
}
/** Mandatory: Function to update local I/O, call read ethercat outputs, call
* write ethercat inputs. Implement watch-dog counter to count-out if we have
* made state change affecting the App.state.
*/
void DIG_process (void)
{
if (watchdog > 0)
{
watchdog--;
}
if (ESCvar.App.state & APPSTATE_OUTPUT)
{
/* SM2 trigger ? */
if (ESCvar.ALevent & ESCREG_ALEVENT_SM2)
{
ESCvar.ALevent &= ~ESCREG_ALEVENT_SM2;
RXPDO_update();
watchdog = WATCHDOG_RESET_VALUE;
/* Set outputs */
cb_set_LEDs();
}
if (watchdog <= 0)
{
DPRINT("DIG_process watchdog expired\n");
ESC_stopoutput();
/* watchdog, invalid outputs */
ESC_ALerror (ALERR_WATCHDOG);
/* goto safe-op with error bit set */
ESC_ALstatus (ESCsafeop | ESCerror);
}
}
else
{
watchdog = WATCHDOG_RESET_VALUE;
}
if (ESCvar.App.state)
{
/* Update inputs */
cb_get_Buttons();
TXPDO_update();
}
}
/********** TODO: Generic code beyond this point ***************/
/** Optional: Hook called after state change for application specific
* actions for specific state changes.
*/
void post_state_change_hook (uint8_t * as, uint8_t * an)
{
#if 0
/* Add specific step change hooks here */
if ((*as == BOOT_TO_INIT) && (*an == ESCinit))
{
boot_inithook();
}
else if((*as == INIT_TO_BOOT) && (*an & ESCerror ) == 0)
{
init_boothook();
}
#endif
}
/**
* Set callback run once every loop in the SOES application loop.
*/
void set_application_loop_hook(void (*callback)(void))
{
application_loop_callback = callback;
}
/**
* SOES main function. It should be called periodically.
* Reads the EtherCAT state and status. Responsible for I/O updates.
*/
void soes (void)
{
/* On init restore PDO mappings to default size */
if((ESCvar.ALstatus & 0x0f) == ESCinit)
{
txpdomap = DEFAULTTXPDOMAP;
rxpdomap = DEFAULTRXPDOMAP;
txpdoitems = DEFAULTTXPDOITEMS;
rxpdoitems = DEFAULTTXPDOITEMS;
}
/* Read local time from ESC */
ESC_read (ESCREG_LOCALTIME, (void *) &ESCvar.Time, sizeof (ESCvar.Time));
ESCvar.Time = etohl (ESCvar.Time);
/* Check the state machine */
ESC_state();
/* Check the SM activation event */
ESC_sm_act_event();
/* Check mailboxes */
if (ESC_mbxprocess())
{
ESC_coeprocess();
ESC_foeprocess();
ESC_xoeprocess();
}
DIG_process();
if (application_loop_callback != NULL)
{
(application_loop_callback)();
}
}
/**
* Initialize the SOES stack.
*/
void soes_init (void)
{
DPRINT ("SOES (Simple Open EtherCAT Slave)\n");
ESCvar.TXPDOsize = ESCvar.ESC_SM3_sml = sizeOfPDO(TX_PDO_OBJIDX);
ESCvar.RXPDOsize = ESCvar.ESC_SM2_sml = sizeOfPDO(RX_PDO_OBJIDX);
/* Setup config hooks */
static esc_cfg_t config =
{
.user_arg = "/dev/lan9252",
.use_interrupt = 0,
.watchdog_cnt = 0,
.mbxsize = MBXSIZE,
.mbxsizeboot = MBXSIZEBOOT,
.mbxbuffers = MBXBUFFERS,
.mb[0] = {MBX0_sma, MBX0_sml, MBX0_sme, MBX0_smc, 0},
.mb[1] = {MBX1_sma, MBX1_sml, MBX1_sme, MBX1_smc, 0},
.mb_boot[0] = {MBX0_sma_b, MBX0_sml_b, MBX0_sme_b, MBX0_smc_b, 0},
.mb_boot[1] = {MBX1_sma_b, MBX1_sml_b, MBX1_sme_b, MBX1_smc_b, 0},
.pdosm[0] = {SM2_sma, 0, 0, SM2_smc, SM2_act},
.pdosm[1] = {SM3_sma, 0, 0, SM3_smc, SM3_act},
.pre_state_change_hook = NULL,
.post_state_change_hook = NULL,
.application_hook = NULL,
.safeoutput_override = NULL,
.pre_object_download_hook = NULL,
.post_object_download_hook = NULL,
.rxpdo_override = NULL,
.txpdo_override = NULL,
.esc_hw_interrupt_enable = NULL,
.esc_hw_interrupt_disable = NULL,
.esc_hw_eep_handler = NULL
};
ESC_config (&config);
ESC_init (&config);
/* wait until ESC is started up */
while ((ESCvar.DLstatus & 0x0001) == 0)
{
ESC_read (ESCREG_DLSTATUS, (void *) &ESCvar.DLstatus,
sizeof (ESCvar.DLstatus));
ESCvar.DLstatus = etohs (ESCvar.DLstatus);
}
/* Init FoE */
FOE_init();
/* reset ESC to init state */
ESC_ALstatus (ESCinit);
ESC_ALerror (ALERR_NONE);
ESC_stopmbx();
ESC_stopinput();
ESC_stopoutput();
}

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<Slave id="evb9252_dig" productCode="1234">
<Slave xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="com.rtlabs.emf.esx" fileVersion="2" id="evb9252_dig" productCode="1234" additionalInfo="0x0190">
<Name>lan9252</Name>
<Vendor>
<Id>0x1337</Id>
@ -24,275 +24,332 @@
<BootStrap>0010800080108000</BootStrap>
</Eeprom>
<Dictionary>
<Item>
<Name>Device Type</Name>
<Item Managed="true">
<Index>0x1000</Index>
<Name>Device Type</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x01901389</DefaultValue>
</Item>
<Item Managed="true">
<Name>Device Name</Name>
<Index>0x1008</Index>
<Name>Device Name</Name>
<DataType>VISIBLE_STRING</DataType>
<DefaultValue>evb9252_dig</DefaultValue>
<Length>11</Length>
</Item>
<Item>
<Name>Hardware Version</Name>
<Item Managed="false">
<Index>0x1009</Index>
<Name>Hardware Version</Name>
<DataType>VISIBLE_STRING</DataType>
<DefaultValue>1.0</DefaultValue>
</Item>
<Item>
<Name>Software Version</Name>
<Item Managed="false">
<Index>0x100A</Index>
<Name>Software Version</Name>
<DataType>VISIBLE_STRING</DataType>
<DefaultValue>1.0</DefaultValue>
</Item>
<Item Managed="true">
<Name>Identity Object</Name>
<Index>0x1018</Index>
<Name>Identity Object</Name>
<DataType>RECORD</DataType>
<SubItem>
<Name>Number of Elements</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>4</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>Vendor ID</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x1337</DefaultValue>
</SubItem>
<SubItem>
<Index>0x02</Index>
<Name>Product Code</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>1234</DefaultValue>
</SubItem>
<SubItem>
<Index>0x03</Index>
<Name>Revision Number</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0</DefaultValue>
</SubItem>
<SubItem>
<Index>0x04</Index>
<Name>Serial Number</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x00000000</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Name>LEDs</Name>
<Index>0x1600</Index>
<Name>LEDs</Name>
<DataType>RECORD</DataType>
<SubItem>
<Name>Number of Elements</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>2</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>LED0</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x70000108</DefaultValue>
</SubItem>
<SubItem>
<Index>0x02</Index>
<Name>LED1</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x70000208</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Name>Buttons</Name>
<Index>0x1A00</Index>
<Name>Buttons</Name>
<DataType>RECORD</DataType>
<SubItem>
<Name>Number of Elements</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>Button1</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x60000108</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Name>Sync Manager Communication Type</Name>
<Index>0x1C00</Index>
<Name>Sync Manager Communication Type</Name>
<DataType>ARRAY</DataType>
<SubItem>
<Name>Number of Elements</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>4</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>Communications Type SM0</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x02</Index>
<Name>Communications Type SM1</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>2</DefaultValue>
</SubItem>
<SubItem>
<Index>0x03</Index>
<Name>Communications Type SM2</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>3</DefaultValue>
</SubItem>
<SubItem>
<Index>0x04</Index>
<Name>Communications Type SM3</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>4</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Name>Sync Manager 2 PDO Assignment</Name>
<Index>0x1C12</Index>
<Name>Sync Manager 2 PDO Assignment</Name>
<DataType>ARRAY</DataType>
<SubItem>
<Name>Number of Elements</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>PDO Mapping</Name>
<DataType>UNSIGNED16</DataType>
<DefaultValue>0x1600</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Name>Sync Manager 3 PDO Assignment</Name>
<Index>0x1C13</Index>
<Name>Sync Manager 3 PDO Assignment</Name>
<DataType>ARRAY</DataType>
<SubItem>
<Name>Number of Elements</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>PDO Mapping</Name>
<DataType>UNSIGNED16</DataType>
<DefaultValue>0x1A00</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Name>Buttons</Name>
<Index>0x6000</Index>
<Name>Buttons</Name>
<DataType>RECORD</DataType>
<Variable>Buttons</Variable>
<VariableType>Input</VariableType>
<SubItem>
<Name>Number of Elements</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Access>RO</Access>
<Name>Button1</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>0</DefaultValue>
<Access>RO</Access>
<Variable>Button1</Variable>
<VariableType>Input</VariableType>
</SubItem>
</Item>
<Item Managed="true">
<Name>LEDs</Name>
<Index>0x7000</Index>
<Name>LEDs</Name>
<DataType>RECORD</DataType>
<Variable>LEDs</Variable>
<VariableType>Output</VariableType>
<SubItem>
<Name>Number of Elements</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>2</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Access>RO</Access>
<Name>LED0</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>0</DefaultValue>
<Access>RO</Access>
<Variable>LED0</Variable>
<VariableType>Output</VariableType>
</SubItem>
<SubItem>
<Index>0x02</Index>
<Access>RO</Access>
<Name>LED1</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>0</DefaultValue>
<Access>RO</Access>
<Variable>LED1</Variable>
<VariableType>Output</VariableType>
</SubItem>
</Item>
<Item Managed="true">
<Name>Parameters</Name>
<Index>0x8000</Index>
<Name>Parameters</Name>
<DataType>RECORD</DataType>
<Variable>Parameters</Variable>
<VariableType>Parameter</VariableType>
<SubItem>
<Name>Number of Elements</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Access>RW</Access>
<Name>Multiplier</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0</DefaultValue>
<Access>RW</Access>
<Variable>Multiplier</Variable>
<VariableType>Parameter</VariableType>
</SubItem>
</Item>
</Dictionary>
<SmAssignment>
<Index>0x1C12</Index>
<Entry>
<Index>0x01</Index>
<AssignedPdo>0x1600</AssignedPdo>
</Entry>
</SmAssignment>
<SmAssignment>
<Index>0x1C13</Index>
<Entry>
<Index>0x01</Index>
<AssignedPdo>0x1A00</AssignedPdo>
</Entry>
</SmAssignment>
<RxPdo>
<Index>0x1600</Index>
<Container>LEDs</Container>
<Name>LEDs</Name>
<Entry>
<Index>0x7000</Index>
<SubIndex>1</SubIndex>
<Index>0x1</Index>
<MappedIndex>0x7000</MappedIndex>
<MappedSubIndex>0x01</MappedSubIndex>
<Variable>LED0</Variable>
</Entry>
<Entry>
<Index>0x7000</Index>
<SubIndex>2</SubIndex>
<Index>0x2</Index>
<MappedIndex>0x7000</MappedIndex>
<MappedSubIndex>0x02</MappedSubIndex>
<Variable>LED1</Variable>
</Entry>
</RxPdo>
<TxPdo>
<Index>0x1A00</Index>
<Container>Buttons</Container>
<Name>Buttons</Name>
<Entry>
<Index>0x6000</Index>
<SubIndex>1</SubIndex>
<Index>0x1</Index>
<MappedIndex>0x6000</MappedIndex>
<MappedSubIndex>0x01</MappedSubIndex>
<Variable>Button1</Variable>
</Entry>
</TxPdo>
<Input>
<Index>0x6000</Index>
<Name>Buttons</Name>
<Type>RECORD</Type>
<ObjectType>RECORD</ObjectType>
<Member>
<Index>0x01</Index>
<Access>RO</Access>
<Name>Button1</Name>
<Type>UNSIGNED8</Type>
<DefaultValue>0</DefaultValue>
</Member>
</Input>
<Output>
<Index>0x7000</Index>
<Name>LEDs</Name>
<Type>RECORD</Type>
<ObjectType>RECORD</ObjectType>
<Member>
<Index>0x01</Index>
<Access>RO</Access>
<Name>LED0</Name>
<Type>UNSIGNED8</Type>
<DefaultValue>0</DefaultValue>
</Member>
<Member>
<Index>0x02</Index>
<Access>RO</Access>
<Name>LED1</Name>
<Type>UNSIGNED8</Type>
<DefaultValue>0</DefaultValue>
</Member>
</Output>
<Parameter>
<Index>0x8000</Index>
<Name>Parameters</Name>
<Type>RECORD</Type>
<ObjectType>RECORD</ObjectType>
<Member>
<Index>0x01</Index>
<Access>RW</Access>
<Name>Multiplier</Name>
<Type>UNSIGNED32</Type>
<DefaultValue>0</DefaultValue>
</Member>
</Parameter>
</Slave>
</Slave>

View File

@ -1,38 +0,0 @@
#ifndef __SLAVE_H__
#define __SLAVE_H__
#include "utypes.h"
/**
* This function reads physical input values and assigns the corresponding members
* of Rb.Buttons
*/
void cb_get_Buttons();
/**
* This function writes physical output values from the corresponding members of
* Wb.LEDs
*/
void cb_set_LEDs();
/**
* This function is called after a SDO write of the object Cb.Parameters.
*/
void cb_post_write_Parameters(int subindex);
/**
* This function sets an application loop callback function.
*/
void set_application_loop_hook(void (*callback)(void));
/**
* Main function for SOES application
*/
void soes (void);
/**
* Initialize the SOES stack
*/
void soes_init (void);
#endif /* __SLAVE_H__ */

View File

@ -26,7 +26,7 @@
<BitSize>144</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
@ -80,7 +80,7 @@
<BitSize>80</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
@ -114,7 +114,7 @@
<BitSize>48</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
@ -147,7 +147,7 @@
<BitSize>48</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
@ -179,7 +179,7 @@
<BitSize>32</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
@ -211,7 +211,7 @@
<BitSize>32</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
@ -234,7 +234,7 @@
<BitSize>24</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
@ -258,7 +258,7 @@
<BitSize>32</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
@ -292,7 +292,7 @@
<BitSize>48</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
@ -311,10 +311,6 @@
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>STRING(3)</Name>
<BitSize>24</BitSize>
</DataType>
<DataType>
<Name>STRING(11)</Name>
<BitSize>88</BitSize>
@ -327,6 +323,10 @@
<Name>UINT</Name>
<BitSize>16</BitSize>
</DataType>
<DataType>
<Name>STRING(0)</Name>
<BitSize>0</BitSize>
</DataType>
<DataType>
<Name>USINT</Name>
<BitSize>8</BitSize>
@ -361,8 +361,8 @@
<Object>
<Index>#x1009</Index>
<Name>Hardware Version</Name>
<Type>STRING(3)</Type>
<BitSize>24</BitSize>
<Type>STRING(0)</Type>
<BitSize>0</BitSize>
<Info>
<DefaultString>1.0</DefaultString>
</Info>
@ -374,8 +374,8 @@
<Object>
<Index>#x100A</Index>
<Name>Software Version</Name>
<Type>STRING(3)</Type>
<BitSize>24</BitSize>
<Type>STRING(0)</Type>
<BitSize>0</BitSize>
<Info>
<DefaultString>1.0</DefaultString>
</Info>
@ -390,7 +390,7 @@
<BitSize>144</BitSize>
<Info>
<SubItem>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>4</DefaultValue>
</Info>
@ -431,7 +431,7 @@
<BitSize>80</BitSize>
<Info>
<SubItem>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>2</DefaultValue>
</Info>
@ -460,7 +460,7 @@
<BitSize>48</BitSize>
<Info>
<SubItem>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
@ -483,7 +483,7 @@
<BitSize>48</BitSize>
<Info>
<SubItem>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>4</DefaultValue>
</Info>
@ -524,7 +524,7 @@
<BitSize>32</BitSize>
<Info>
<SubItem>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
@ -547,7 +547,7 @@
<BitSize>32</BitSize>
<Info>
<SubItem>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
@ -570,7 +570,7 @@
<BitSize>24</BitSize>
<Info>
<SubItem>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
@ -593,7 +593,7 @@
<BitSize>32</BitSize>
<Info>
<SubItem>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>2</DefaultValue>
</Info>
@ -622,7 +622,7 @@
<BitSize>48</BitSize>
<Info>
<SubItem>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
@ -652,14 +652,14 @@
<Name>LEDs</Name>
<Entry>
<Index>#x7000</Index>
<SubIndex>1</SubIndex>
<SubIndex>#x1</SubIndex>
<BitLen>8</BitLen>
<Name>LED0</Name>
<DataType>USINT</DataType>
</Entry>
<Entry>
<Index>#x7000</Index>
<SubIndex>2</SubIndex>
<SubIndex>#x2</SubIndex>
<BitLen>8</BitLen>
<Name>LED1</Name>
<DataType>USINT</DataType>
@ -670,14 +670,14 @@
<Name>Buttons</Name>
<Entry>
<Index>#x6000</Index>
<SubIndex>1</SubIndex>
<SubIndex>#x1</SubIndex>
<BitLen>8</BitLen>
<Name>Button1</Name>
<DataType>USINT</DataType>
</Entry>
</TxPdo>
<Mailbox DataLinkLayer="true">
<CoE CompleteAccess="false" PdoUpload="true" SdoInfo="true"/>
<CoE CompleteAccess="false" PdoUpload="false" SdoInfo="true"/>
<FoE/>
</Mailbox>
<Eeprom>

View File

@ -1,66 +1,70 @@
#include "soes/esc_coe.h"
#include "esc_coe.h"
#include "utypes.h"
#include <stddef.h>
#ifndef HW_REV
#define HW_REV "1.0"
#endif
#ifndef SW_REV
#define SW_REV "1.0"
#endif
static const char acName1000[] = "Device Type";
static const char acName1000_0[] = "Device Type";
static const char acName1008[] = "Device Name";
static const char acName1008_0[] = "Device Name";
static const char acName1009[] = "Hardware Version";
static const char acName1009_0[] = "Hardware Version";
static const char acName100A[] = "Software Version";
static const char acName100A_0[] = "Software Version";
static const char acName1018[] = "Identity Object";
static const char acName1018_00[] = "Number of Elements";
static const char acName1018_00[] = "Max SubIndex";
static const char acName1018_01[] = "Vendor ID";
static const char acName1018_02[] = "Product Code";
static const char acName1018_03[] = "Revision Number";
static const char acName1018_04[] = "Serial Number";
static const char acName1600[] = "LEDs";
static const char acName1600_00[] = "Number of Elements";
static const char acName1600_00[] = "Max SubIndex";
static const char acName1600_01[] = "LED0";
static const char acName1600_02[] = "LED1";
static const char acName1A00[] = "Buttons";
static const char acName1A00_00[] = "Number of Elements";
static const char acName1A00_00[] = "Max SubIndex";
static const char acName1A00_01[] = "Button1";
static const char acName1C00[] = "Sync Manager Communication Type";
static const char acName1C00_00[] = "Number of Elements";
static const char acName1C00_00[] = "Max SubIndex";
static const char acName1C00_01[] = "Communications Type SM0";
static const char acName1C00_02[] = "Communications Type SM1";
static const char acName1C00_03[] = "Communications Type SM2";
static const char acName1C00_04[] = "Communications Type SM3";
static const char acName1C12[] = "Sync Manager 2 PDO Assignment";
static const char acName1C12_00[] = "Number of Elements";
static const char acName1C12_00[] = "Max SubIndex";
static const char acName1C12_01[] = "PDO Mapping";
static const char acName1C13[] = "Sync Manager 3 PDO Assignment";
static const char acName1C13_00[] = "Number of Elements";
static const char acName1C13_00[] = "Max SubIndex";
static const char acName1C13_01[] = "PDO Mapping";
static const char acName6000[] = "Buttons";
static const char acName6000_00[] = "Number of Elements";
static const char acName6000_00[] = "Max SubIndex";
static const char acName6000_01[] = "Button1";
static const char acName7000[] = "LEDs";
static const char acName7000_00[] = "Number of Elements";
static const char acName7000_00[] = "Max SubIndex";
static const char acName7000_01[] = "LED0";
static const char acName7000_02[] = "LED1";
static const char acName8000[] = "Parameters";
static const char acName8000_00[] = "Number of Elements";
static const char acName8000_00[] = "Max SubIndex";
static const char acName8000_01[] = "Multiplier";
const _objd SDO1000[] =
{
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000_0, 0x01901389, NULL},
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000, 0x01901389, NULL},
};
const _objd SDO1008[] =
{
{0x0, DTYPE_VISIBLE_STRING, 88, ATYPE_RO, acName1008_0, 0, "evb9252_dig"},
{0x0, DTYPE_VISIBLE_STRING, 88, ATYPE_RO, acName1008, 0, "evb9252_dig"},
};
const _objd SDO1009[] =
{
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName1009_0, 0, "1.0"},
{0x0, DTYPE_VISIBLE_STRING, 0, ATYPE_RO, acName1009, 0, HW_REV},
};
const _objd SDO100A[] =
{
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName100A_0, 0, "1.0"},
{0x0, DTYPE_VISIBLE_STRING, 0, ATYPE_RO, acName100A, 0, SW_REV},
};
const _objd SDO1018[] =
{
@ -102,18 +106,18 @@ const _objd SDO1C13[] =
const _objd SDO6000[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6000_00, 1, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6000_01, 0, &Rb.Buttons.Button1},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6000_01, 0, &Obj.Buttons.Button1},
};
const _objd SDO7000[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_00, 2, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_01, 0, &Wb.LEDs.LED0},
{0x02, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_02, 0, &Wb.LEDs.LED1},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_01, 0, &Obj.LEDs.LED0},
{0x02, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_02, 0, &Obj.LEDs.LED1},
};
const _objd SDO8000[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName8000_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RW, acName8000_01, 0, &Cb.Parameters.Multiplier},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RW, acName8000_01, 0, &Obj.Parameters.Multiplier},
};
const _objectlist SDOobjects[] =

View File

@ -1,47 +1,45 @@
#ifndef __UTYPES_H__
#define __UTYPES_H__
#include <cc.h>
#include "cc.h"
/* Object dictionary storage */
CC_PACKED_BEGIN
typedef struct
{
CC_PACKED_BEGIN
/* Inputs */
struct
{
uint8_t Button1;
} CC_PACKED Buttons;
CC_PACKED_END
} CC_PACKED _Rbuffer;
CC_PACKED_END
} Buttons;
CC_PACKED_BEGIN
typedef struct
{
CC_PACKED_BEGIN
/* Outputs */
struct
{
uint8_t LED0;
uint8_t LED1;
} CC_PACKED LEDs;
CC_PACKED_END
} CC_PACKED _Wbuffer;
CC_PACKED_END
} LEDs;
CC_PACKED_BEGIN
typedef struct
{
CC_PACKED_BEGIN
/* Parameters */
struct
{
uint32_t Multiplier;
} CC_PACKED Parameters;
CC_PACKED_END
} CC_PACKED _Cbuffer;
CC_PACKED_END
} Parameters;
extern _Rbuffer Rb;
extern _Wbuffer Wb;
extern _Cbuffer Cb;
/* Manufacturer specific data */
/* Dynamic TX PDO:s */
/* Dynamic RX PDO:s */
/* Sync Managers */
} _Objects;
extern _Objects Obj;
#endif /* __UTYPES_H__ */

View File

@ -0,0 +1,8 @@
add_executable (soes-demo
main.c
slave_objectlist.c
)
target_link_libraries(soes-demo LINK_PUBLIC soes bcm2835)
install (TARGETS soes-demo DESTINATION sbin)
install (PROGRAMS S60soes DESTINATION /etc/init.d)

View File

@ -0,0 +1,40 @@
#!/bin/sh
#
# soes Starts soes.
#
start() {
printf "Starting soes: "
/usr/sbin/soes-demo &
touch /var/lock/soes-demo
echo "OK"
}
stop() {
printf "Stopping soes: "
killall soes-demo
rm -f /var/lock/soes-demo
echo "OK"
}
restart() {
stop
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart|reload)
restart
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
exit $?

View File

@ -0,0 +1,42 @@
#ifndef __ECAT_OPTIONS_H__
#define __ECAT_OPTIONS_H__
#define USE_FOE 1
#define USE_EOE 0
#define MBXSIZE 128
#define MBXSIZEBOOT 128
#define MBXBUFFERS 3
#define MBX0_sma 0x1000
#define MBX0_sml MBXSIZE
#define MBX0_sme MBX0_sma+MBX0_sml-1
#define MBX0_smc 0x26
#define MBX1_sma MBX0_sma+MBX0_sml
#define MBX1_sml MBXSIZE
#define MBX1_sme MBX1_sma+MBX1_sml-1
#define MBX1_smc 0x22
#define MBX0_sma_b 0x1000
#define MBX0_sml_b MBXSIZEBOOT
#define MBX0_sme_b MBX0_sma_b+MBX0_sml_b-1
#define MBX0_smc_b 0x26
#define MBX1_sma_b MBX0_sma_b+MBX0_sml_b
#define MBX1_sml_b MBXSIZEBOOT
#define MBX1_sme_b MBX1_sma_b+MBX1_sml_b-1
#define MBX1_smc_b 0x22
#define SM2_sma 0x1100
#define SM2_smc 0x24
#define SM2_act 1
#define SM3_sma 0x1180
#define SM3_smc 0x20
#define SM3_act 1
#define MAX_MAPPINGS_SM2 7
#define MAX_MAPPINGS_SM3 7
#define MAX_RXPDO_SIZE 42
#define MAX_TXPDO_SIZE 42
#endif /* __ECAT_OPTIONS_H__ */

View File

@ -0,0 +1,108 @@
#include <stdio.h>
#include "ecat_slv.h"
#include "utypes.h"
#include <bcm2835.h>
/* Application variables */
_Objects Obj;
#define GPIO21 RPI_BPLUS_GPIO_J8_40
#define GPIO20 RPI_BPLUS_GPIO_J8_38
#define GPIO16 RPI_BPLUS_GPIO_J8_36
#define GPIO12 RPI_BPLUS_GPIO_J8_32
#define GPIO24 RPI_BPLUS_GPIO_J8_18
#define GPIO23 RPI_BPLUS_GPIO_J8_16
#define GPIO26 RPI_BPLUS_GPIO_J8_37
#define GPIO19 RPI_BPLUS_GPIO_J8_35
#define GPIO13 RPI_BPLUS_GPIO_J8_33
#define GPIO06 RPI_BPLUS_GPIO_J8_31
#define GPIO05 RPI_BPLUS_GPIO_J8_29
#define GPIO22 RPI_BPLUS_GPIO_J8_15
void cb_get_inputs (void)
{
// Assume LEDs connected to 3.3v
bcm2835_gpio_write(GPIO21, (Obj.LEDs.LED0 ? LOW : HIGH));
bcm2835_gpio_write(GPIO20, (Obj.LEDs.LED1 ? LOW : HIGH));
bcm2835_gpio_write(GPIO16, (Obj.LEDs.LED2 ? LOW : HIGH));
bcm2835_gpio_write(GPIO12, (Obj.LEDs.LED3 ? LOW : HIGH));
bcm2835_gpio_write(GPIO24, (Obj.LEDs.LED4 ? LOW : HIGH));
bcm2835_gpio_write(GPIO23, (Obj.LEDs.LED5 ? LOW : HIGH));
}
void cb_set_outputs (void)
{
// Assume Buttons connected to 3.3v
Obj.Buttons.Button0 = bcm2835_gpio_lev(GPIO26);
Obj.Buttons.Button0 = bcm2835_gpio_lev(GPIO19);
Obj.Buttons.Button0 = bcm2835_gpio_lev(GPIO13);
Obj.Buttons.Button0 = bcm2835_gpio_lev(GPIO06);
Obj.Buttons.Button0 = bcm2835_gpio_lev(GPIO05);
Obj.Buttons.Button0 = bcm2835_gpio_lev(GPIO22);
}
void GPIO_init (void)
{
bcm2835_init();
// Assume LEDs connected to 3.3v side of header
bcm2835_gpio_fsel(GPIO21, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel(GPIO20, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel(GPIO16, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel(GPIO12, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel(GPIO24, BCM2835_GPIO_FSEL_OUTP);
bcm2835_gpio_fsel(GPIO23, BCM2835_GPIO_FSEL_OUTP);
// Assume buttons connected to 5v side of header
// Do not bridge to 5v, the ports might burn
bcm2835_gpio_fsel(GPIO26, BCM2835_GPIO_FSEL_INPT);
bcm2835_gpio_fsel(GPIO19, BCM2835_GPIO_FSEL_INPT);
bcm2835_gpio_fsel(GPIO13, BCM2835_GPIO_FSEL_INPT);
bcm2835_gpio_fsel(GPIO06, BCM2835_GPIO_FSEL_INPT);
bcm2835_gpio_fsel(GPIO05, BCM2835_GPIO_FSEL_INPT);
bcm2835_gpio_fsel(GPIO22, BCM2835_GPIO_FSEL_INPT);
bcm2835_gpio_set_pud(GPIO26, BCM2835_GPIO_PUD_DOWN);
bcm2835_gpio_set_pud(GPIO19, BCM2835_GPIO_PUD_DOWN);
bcm2835_gpio_set_pud(GPIO13, BCM2835_GPIO_PUD_DOWN);
bcm2835_gpio_set_pud(GPIO06, BCM2835_GPIO_PUD_DOWN);
bcm2835_gpio_set_pud(GPIO05, BCM2835_GPIO_PUD_DOWN);
bcm2835_gpio_set_pud(GPIO22, BCM2835_GPIO_PUD_DOWN);
}
int main_run (void * arg)
{
static esc_cfg_t config =
{
.user_arg = "rpi3,cs0",
.use_interrupt = 0,
.watchdog_cnt = 150,
.set_defaults_hook = NULL,
.pre_state_change_hook = NULL,
.post_state_change_hook = NULL,
.application_hook = NULL,
.safeoutput_override = NULL,
.pre_object_download_hook = NULL,
.post_object_download_hook = NULL,
.rxpdo_override = NULL,
.txpdo_override = NULL,
.esc_hw_interrupt_enable = NULL,
.esc_hw_interrupt_disable = NULL,
.esc_hw_eep_handler = NULL,
.esc_check_dc_handler = NULL,
};
printf ("Hello Main\n");
GPIO_init();
ecat_slv_init (&config);
while (1)
{
ecat_slv();
}
return 0;
}
int main (void)
{
printf ("Hello Main\n");
main_run (NULL);
return 0;
}

View File

@ -0,0 +1,532 @@
<?xml version="1.0" encoding="UTF-8"?>
<Slave xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="com.rtlabs.emf.esx" fileVersion="2" id="evb9252_dig" productCode="1234" additionalInfo="0x0190">
<Name>lan9252</Name>
<Vendor>
<Id>0x1337</Id>
<Name>rt-labs AB</Name>
</Vendor>
<Group>
<Type>lan9252_spi</Type>
<Name>lan9252</Name>
</Group>
<Fmmu>Outputs</Fmmu>
<Fmmu>Inputs</Fmmu>
<Sm ControlByte="0x26" DefaultSize="128" StartAddress="0x1000">MBoxOut</Sm>
<Sm ControlByte="0x22" DefaultSize="128" StartAddress="0x1080">MBoxIn</Sm>
<Sm ControlByte="0x24" DefaultSize="0" StartAddress="0x1100">Outputs</Sm>
<Sm ControlByte="0x20" DefaultSize="0" StartAddress="0x1180">Inputs</Sm>
<Mailbox CoE="true" FoE="true">
<Bootstrap Length="128" Start="0x1000"/>
<Standard Length="128" Start="0x1000"/>
</Mailbox>
<Eeprom Lan9252="true">
<ConfigData>8002000000000000</ConfigData>
<BootStrap>0010800080108000</BootStrap>
</Eeprom>
<Dictionary>
<Item Managed="true">
<Index>0x1000</Index>
<Name>Device Type</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x01901389</DefaultValue>
</Item>
<Item Managed="true">
<Index>0x1008</Index>
<Name>Device Name</Name>
<DataType>VISIBLE_STRING</DataType>
<DefaultValue>evb9252_dig</DefaultValue>
<Length>11</Length>
</Item>
<Item Managed="false">
<Index>0x1009</Index>
<Name>Hardware Version</Name>
<DataType>VISIBLE_STRING</DataType>
<DefaultValue>1.0</DefaultValue>
</Item>
<Item Managed="false">
<Index>0x100A</Index>
<Name>Software Version</Name>
<DataType>VISIBLE_STRING</DataType>
<DefaultValue>1.0</DefaultValue>
</Item>
<Item Managed="true">
<Index>0x1018</Index>
<Name>Identity Object</Name>
<DataType>RECORD</DataType>
<SubItem>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>4</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>Vendor ID</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x1337</DefaultValue>
</SubItem>
<SubItem>
<Index>0x02</Index>
<Name>Product Code</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>1234</DefaultValue>
</SubItem>
<SubItem>
<Index>0x03</Index>
<Name>Revision Number</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0</DefaultValue>
</SubItem>
<SubItem>
<Index>0x04</Index>
<Name>Serial Number</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x00000000</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Index>0x1600</Index>
<Name>LEDs</Name>
<DataType>RECORD</DataType>
<SubItem>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>9</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>LED0</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x70000108</DefaultValue>
</SubItem>
<SubItem>
<Index>0x02</Index>
<Name>LED1</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x70000208</DefaultValue>
</SubItem>
<SubItem>
<Index>0x03</Index>
<Name>New Member</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x70000301</DefaultValue>
</SubItem>
<SubItem>
<Index>0x04</Index>
<Name>New Member</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x70000401</DefaultValue>
</SubItem>
<SubItem>
<Index>0x05</Index>
<Name>New Member</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x70000501</DefaultValue>
</SubItem>
<SubItem>
<Index>0x06</Index>
<Name>New Member</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x70000601</DefaultValue>
</SubItem>
<SubItem>
<Index>0x07</Index>
<Name>New Member</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x70000701</DefaultValue>
</SubItem>
<SubItem>
<Index>0x08</Index>
<Name>New Member</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x70000801</DefaultValue>
</SubItem>
<SubItem>
<Index>0x09</Index>
<Name>Padding 9</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x00000002</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Index>0x1A00</Index>
<Name>Buttons</Name>
<DataType>RECORD</DataType>
<SubItem>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>Button1</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x60000108</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Index>0x1C00</Index>
<Name>Sync Manager Communication Type</Name>
<DataType>ARRAY</DataType>
<SubItem>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>4</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>Communications Type SM0</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x02</Index>
<Name>Communications Type SM1</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>2</DefaultValue>
</SubItem>
<SubItem>
<Index>0x03</Index>
<Name>Communications Type SM2</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>3</DefaultValue>
</SubItem>
<SubItem>
<Index>0x04</Index>
<Name>Communications Type SM3</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>4</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Index>0x1C12</Index>
<Name>Sync Manager 2 PDO Assignment</Name>
<DataType>ARRAY</DataType>
<SubItem>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>PDO Mapping</Name>
<DataType>UNSIGNED16</DataType>
<DefaultValue>0x1600</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Index>0x1C13</Index>
<Name>Sync Manager 3 PDO Assignment</Name>
<DataType>ARRAY</DataType>
<SubItem>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>PDO Mapping</Name>
<DataType>UNSIGNED16</DataType>
<DefaultValue>0x1A00</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Index>0x6000</Index>
<Name>Buttons</Name>
<DataType>RECORD</DataType>
<Variable>Buttons</Variable>
<VariableType>Input</VariableType>
<SubItem>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Access>RO</Access>
<Name>Button1</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>0</DefaultValue>
<Variable>Button1</Variable>
<VariableType>Input</VariableType>
</SubItem>
</Item>
<Item Managed="true">
<Index>0x7000</Index>
<Name>LEDs</Name>
<DataType>RECORD</DataType>
<Variable>LEDs</Variable>
<VariableType>Output</VariableType>
<SubItem>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>8</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Access>RO</Access>
<Name>LED0</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>0</DefaultValue>
<Variable>LED0</Variable>
<VariableType>Output</VariableType>
</SubItem>
<SubItem>
<Index>0x02</Index>
<Access>RO</Access>
<Name>LED1</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>0</DefaultValue>
<Variable>LED1</Variable>
<VariableType>Output</VariableType>
</SubItem>
<SubItem>
<Index>0x03</Index>
<Access>RO</Access>
<Name>New Member</Name>
<DataType>BOOLEAN</DataType>
<DefaultValue>0</DefaultValue>
<PdoMapping>RX</PdoMapping>
<Variable>New_Member</Variable>
<VariableType>Output</VariableType>
</SubItem>
<SubItem>
<Index>0x04</Index>
<Access>RO</Access>
<Name>New Member</Name>
<DataType>BOOLEAN</DataType>
<DefaultValue>0</DefaultValue>
<PdoMapping>RX</PdoMapping>
<Variable>New_Member</Variable>
<VariableType>Output</VariableType>
</SubItem>
<SubItem>
<Index>0x05</Index>
<Access>RO</Access>
<Name>New Member</Name>
<DataType>BOOLEAN</DataType>
<DefaultValue>0</DefaultValue>
<PdoMapping>RX</PdoMapping>
<Variable>New_Member</Variable>
<VariableType>Output</VariableType>
</SubItem>
<SubItem>
<Index>0x06</Index>
<Access>RO</Access>
<Name>New Member</Name>
<DataType>BOOLEAN</DataType>
<DefaultValue>0</DefaultValue>
<PdoMapping>RX</PdoMapping>
<Variable>New_Member</Variable>
<VariableType>Output</VariableType>
</SubItem>
<SubItem>
<Index>0x07</Index>
<Access>RO</Access>
<Name>New Member</Name>
<DataType>BOOLEAN</DataType>
<DefaultValue>0</DefaultValue>
<PdoMapping>RX</PdoMapping>
<Variable>New_Member</Variable>
<VariableType>Output</VariableType>
</SubItem>
<SubItem>
<Index>0x08</Index>
<Access>RO</Access>
<Name>New Member</Name>
<DataType>BOOLEAN</DataType>
<DefaultValue>0</DefaultValue>
<PdoMapping>RX</PdoMapping>
<Variable>New_Member</Variable>
<VariableType>Output</VariableType>
</SubItem>
</Item>
<Item Managed="true">
<Index>0x8000</Index>
<Name>Parameters</Name>
<DataType>RECORD</DataType>
<Variable>Parameters</Variable>
<VariableType>Parameter</VariableType>
<SubItem>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Access>RW</Access>
<Name>Multiplier</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0</DefaultValue>
<Variable>Multiplier</Variable>
<VariableType>Parameter</VariableType>
</SubItem>
</Item>
</Dictionary>
<SmAssignment>
<Index>0x1C12</Index>
<Entry>
<Index>0x01</Index>
<AssignedPdo>0x1600</AssignedPdo>
</Entry>
</SmAssignment>
<SmAssignment>
<Index>0x1C13</Index>
<Entry>
<Index>0x01</Index>
<AssignedPdo>0x1A00</AssignedPdo>
</Entry>
</SmAssignment>
<RxPdo>
<Index>0x1600</Index>
<Name>LEDs</Name>
<Entry>
<Index>0x1</Index>
<MappedIndex>0x7000</MappedIndex>
<MappedSubIndex>0x01</MappedSubIndex>
<Variable>LED0</Variable>
</Entry>
<Entry>
<Index>0x2</Index>
<MappedIndex>0x7000</MappedIndex>
<MappedSubIndex>0x02</MappedSubIndex>
<Variable>LED1</Variable>
</Entry>
<Entry>
<Index>0x3</Index>
<MappedIndex>0x7000</MappedIndex>
<MappedSubIndex>0x03</MappedSubIndex>
<Variable>LED2</Variable>
</Entry>
<Entry>
<Index>0x4</Index>
<MappedIndex>0x7000</MappedIndex>
<MappedSubIndex>0x04</MappedSubIndex>
<Variable>LED3</Variable>
</Entry>
<Entry>
<Index>0x5</Index>
<MappedIndex>0x7000</MappedIndex>
<MappedSubIndex>0x05</MappedSubIndex>
<Variable>LED4</Variable>
</Entry>
<Entry>
<Index>0x6</Index>
<MappedIndex>0x7000</MappedIndex>
<MappedSubIndex>0x06</MappedSubIndex>
<Variable>LED5</Variable>
</Entry>
<Entry padBits="2">
<Index>0x09</Index>
</Entry>
</RxPdo>
<TxPdo>
<Index>0x1A00</Index>
<Name>Buttons</Name>
<Entry>
<Index>0x1</Index>
<MappedIndex>0x6000</MappedIndex>
<MappedSubIndex>0x01</MappedSubIndex>
<Variable>Button0</Variable>
</Entry>
</TxPdo>
<Input>
<Index>0x6000</Index>
<Name>Buttons</Name>
<ObjectType>RECORD</ObjectType>
<Member>
<Index>0x01</Index>
<Access>RO</Access>
<Name>Button0</Name>
<Type>BOOLEAN</Type>
<DefaultValue>0</DefaultValue>
<PdoMapping>TX</PdoMapping>
</Member>
<Member>
<Index>0x02</Index>
<Name>Button1</Name>
<PdoMapping>TX</PdoMapping>
</Member>
<Member>
<Index>0x03</Index>
<Name>Button2</Name>
<PdoMapping>TX</PdoMapping>
</Member>
<Member>
<Index>0x04</Index>
<Name>Button3</Name>
<PdoMapping>TX</PdoMapping>
</Member>
<Member>
<Index>0x05</Index>
<Name>Button4</Name>
<PdoMapping>TX</PdoMapping>
</Member>
<Member>
<Index>0x06</Index>
<Name>Button5</Name>
<PdoMapping>TX</PdoMapping>
</Member>
</Input>
<Output>
<Index>0x7000</Index>
<Name>LEDs</Name>
<ObjectType>RECORD</ObjectType>
<Member>
<Index>0x01</Index>
<Access>RO</Access>
<Name>LED0</Name>
<Type>BOOLEAN</Type>
<DefaultValue>0</DefaultValue>
<PdoMapping>RX</PdoMapping>
</Member>
<Member>
<Index>0x02</Index>
<Access>RO</Access>
<Name>LED1</Name>
<Type>BOOLEAN</Type>
<DefaultValue>0</DefaultValue>
<PdoMapping>RX</PdoMapping>
</Member>
<Member>
<Index>0x03</Index>
<Name>LED2</Name>
<PdoMapping>RX</PdoMapping>
</Member>
<Member>
<Index>0x04</Index>
<Name>LED3</Name>
<PdoMapping>RX</PdoMapping>
</Member>
<Member>
<Index>0x05</Index>
<Name>LED4</Name>
<PdoMapping>RX</PdoMapping>
</Member>
<Member>
<Index>0x06</Index>
<Name>LED5</Name>
<PdoMapping>RX</PdoMapping>
</Member>
</Output>
<Parameter>
<Index>0x8000</Index>
<Name>Parameters</Name>
<ObjectType>RECORD</ObjectType>
<Member>
<Index>0x01</Index>
<Access>RW</Access>
<Name>Multiplier</Name>
<Type>UNSIGNED32</Type>
<DefaultValue>0</DefaultValue>
</Member>
</Parameter>
</Slave>

View File

@ -0,0 +1,179 @@
#include "esc_coe.h"
#include "utypes.h"
#include <stddef.h>
#ifndef HW_REV
#define HW_REV "1.0"
#endif
#ifndef SW_REV
#define SW_REV "1.0"
#endif
static const char acName1000[] = "Device Type";
static const char acName1008[] = "Device Name";
static const char acName1009[] = "Hardware Version";
static const char acName100A[] = "Software Version";
static const char acName1018[] = "Identity Object";
static const char acName1018_00[] = "Max SubIndex";
static const char acName1018_01[] = "Vendor ID";
static const char acName1018_02[] = "Product Code";
static const char acName1018_03[] = "Revision Number";
static const char acName1018_04[] = "Serial Number";
static const char acName1600[] = "LEDs";
static const char acName1600_00[] = "Max SubIndex";
static const char acName1600_01[] = "LED0";
static const char acName1600_02[] = "LED1";
static const char acName1600_03[] = "LED2";
static const char acName1600_04[] = "LED3";
static const char acName1600_05[] = "LED4";
static const char acName1600_06[] = "LED5";
static const char acName1600_07[] = "Padding 7";
static const char acName1A00[] = "Buttons";
static const char acName1A00_00[] = "Max SubIndex";
static const char acName1A00_01[] = "Button0";
static const char acName1A00_02[] = "Button1";
static const char acName1A00_03[] = "Button2";
static const char acName1A00_04[] = "Button3";
static const char acName1A00_05[] = "Button4";
static const char acName1A00_06[] = "Button5";
static const char acName1A00_07[] = "Padding 7";
static const char acName1C00[] = "Sync Manager Communication Type";
static const char acName1C00_00[] = "Max SubIndex";
static const char acName1C00_01[] = "Communications Type SM0";
static const char acName1C00_02[] = "Communications Type SM1";
static const char acName1C00_03[] = "Communications Type SM2";
static const char acName1C00_04[] = "Communications Type SM3";
static const char acName1C12[] = "Sync Manager 2 PDO Assignment";
static const char acName1C12_00[] = "Max SubIndex";
static const char acName1C12_01[] = "PDO Mapping";
static const char acName1C13[] = "Sync Manager 3 PDO Assignment";
static const char acName1C13_00[] = "Max SubIndex";
static const char acName1C13_01[] = "PDO Mapping";
static const char acName6000[] = "Buttons";
static const char acName6000_00[] = "Max SubIndex";
static const char acName6000_01[] = "Button0";
static const char acName6000_02[] = "Button1";
static const char acName6000_03[] = "Button2";
static const char acName6000_04[] = "Button3";
static const char acName6000_05[] = "Button4";
static const char acName6000_06[] = "Button5";
static const char acName7000[] = "LEDs";
static const char acName7000_00[] = "Max SubIndex";
static const char acName7000_01[] = "LED0";
static const char acName7000_02[] = "LED1";
static const char acName7000_03[] = "LED2";
static const char acName7000_04[] = "LED3";
static const char acName7000_05[] = "LED4";
static const char acName7000_06[] = "LED5";
static const char acName8000[] = "Parameters";
static const char acName8000_00[] = "Max SubIndex";
static const char acName8000_01[] = "Multiplier";
const _objd SDO1000[] =
{
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000, 0x01901389, NULL},
};
const _objd SDO1008[] =
{
{0x0, DTYPE_VISIBLE_STRING, 88, ATYPE_RO, acName1008, 0, "evb9252_dig"},
};
const _objd SDO1009[] =
{
{0x0, DTYPE_VISIBLE_STRING, 0, ATYPE_RO, acName1009, 0, HW_REV},
};
const _objd SDO100A[] =
{
{0x0, DTYPE_VISIBLE_STRING, 0, ATYPE_RO, acName100A, 0, SW_REV},
};
const _objd SDO1018[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1018_00, 4, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_01, 0x1337, NULL},
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_02, 1234, NULL},
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_03, 0, NULL},
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_04, 0x00000000, &Obj.serial},
};
const _objd SDO1600[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1600_00, 7, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_01, 0x70000101, NULL},
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_02, 0x70000201, NULL},
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_03, 0x70000301, NULL},
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_04, 0x70000401, NULL},
{0x05, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_05, 0x70000501, NULL},
{0x06, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_06, 0x70000601, NULL},
{0x07, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_07, 0x00000002, NULL},
};
const _objd SDO1A00[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1A00_00, 7, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_01, 0x60000101, NULL},
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_02, 0x60000201, NULL},
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_03, 0x60000301, NULL},
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_04, 0x60000401, NULL},
{0x05, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_05, 0x60000501, NULL},
{0x06, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_06, 0x60000601, NULL},
{0x07, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_07, 0x00000002, NULL},
};
const _objd SDO1C00[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_00, 4, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_01, 1, NULL},
{0x02, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_02, 2, NULL},
{0x03, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_03, 3, NULL},
{0x04, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_04, 4, NULL},
};
const _objd SDO1C12[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C12_00, 1, NULL},
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C12_01, 0x1600, NULL},
};
const _objd SDO1C13[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C13_00, 1, NULL},
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C13_01, 0x1A00, NULL},
};
const _objd SDO6000[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6000_00, 6, NULL},
{0x01, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_TXPDO, acName6000_01, 0, &Obj.Buttons.Button0},
{0x02, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_TXPDO, acName6000_02, 0, &Obj.Buttons.Button1},
{0x03, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_TXPDO, acName6000_03, 0, &Obj.Buttons.Button2},
{0x04, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_TXPDO, acName6000_04, 0, &Obj.Buttons.Button3},
{0x05, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_TXPDO, acName6000_05, 0, &Obj.Buttons.Button4},
{0x06, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_TXPDO, acName6000_06, 0, &Obj.Buttons.Button5},
};
const _objd SDO7000[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_00, 6, NULL},
{0x01, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_RXPDO, acName7000_01, 0, &Obj.LEDs.LED0},
{0x02, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_RXPDO, acName7000_02, 0, &Obj.LEDs.LED1},
{0x03, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_RXPDO, acName7000_03, 0, &Obj.LEDs.LED2},
{0x04, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_RXPDO, acName7000_04, 0, &Obj.LEDs.LED3},
{0x05, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_RXPDO, acName7000_05, 0, &Obj.LEDs.LED4},
{0x06, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_RXPDO, acName7000_06, 0, &Obj.LEDs.LED5},
};
const _objd SDO8000[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName8000_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RW, acName8000_01, 0, &Obj.Parameters.Multiplier},
};
const _objectlist SDOobjects[] =
{
{0x1000, OTYPE_VAR, 0, 0, acName1000, SDO1000},
{0x1008, OTYPE_VAR, 0, 0, acName1008, SDO1008},
{0x1009, OTYPE_VAR, 0, 0, acName1009, SDO1009},
{0x100A, OTYPE_VAR, 0, 0, acName100A, SDO100A},
{0x1018, OTYPE_RECORD, 4, 0, acName1018, SDO1018},
{0x1600, OTYPE_RECORD, 7, 0, acName1600, SDO1600},
{0x1A00, OTYPE_RECORD, 7, 0, acName1A00, SDO1A00},
{0x1C00, OTYPE_ARRAY, 4, 0, acName1C00, SDO1C00},
{0x1C12, OTYPE_ARRAY, 1, 0, acName1C12, SDO1C12},
{0x1C13, OTYPE_ARRAY, 1, 0, acName1C13, SDO1C13},
{0x6000, OTYPE_RECORD, 6, 0, acName6000, SDO6000},
{0x7000, OTYPE_RECORD, 6, 0, acName7000, SDO7000},
{0x8000, OTYPE_RECORD, 1, 0, acName8000, SDO8000},
{0xffff, 0xff, 0xff, 0xff, NULL, NULL}
};

View File

@ -0,0 +1,49 @@
#ifndef __UTYPES_H__
#define __UTYPES_H__
#include "cc.h"
/* Object dictionary storage */
typedef struct
{
/* Identity */
uint32_t serial;
/* Inputs */
struct
{
uint8_t Button0;
uint8_t Button1;
uint8_t Button2;
uint8_t Button3;
uint8_t Button4;
uint8_t Button5;
} Buttons;
/* Outputs */
struct
{
uint8_t LED0;
uint8_t LED1;
uint8_t LED2;
uint8_t LED3;
uint8_t LED4;
uint8_t LED5;
} LEDs;
/* Parameters */
struct
{
uint32_t Multiplier;
} Parameters;
} _Objects;
extern _Objects Obj;
#endif /* __UTYPES_H__ */

View File

@ -1,49 +0,0 @@
#include <kern.h>
#include "slave.h"
/**
* This function reads physical input values and assigns the corresponding members
* of Rb.Buttons
*/
void cb_get_Buttons()
{
}
/**
* This function writes physical output values from the corresponding members of
* Wb.LEDs
*/
void cb_set_LEDs()
{
}
/**
* This function is called after a SDO write of the object Cb.Parameters.
*/
void cb_post_write_Parameters(int subindex)
{
}
void main_run(void * arg)
{
soes_init();
while(1) {
soes();
}
}
int main(void)
{
rprintf("Hello Main\n");
task_spawn ("soes", main_run, 8, 2048, NULL);
return 0;
}

View File

@ -1,298 +0,0 @@
#include <stddef.h>
#include "utypes.h"
#include "esc.h"
#include "esc_coe.h"
#include "esc_foe.h"
#include "config.h"
#include "slave.h"
#define WATCHDOG_RESET_VALUE 150
#define DEFAULTTXPDOMAP 0x1a00
#define DEFAULTRXPDOMAP 0x1600
#define DEFAULTTXPDOITEMS 1
#define DEFAULTRXPDOITEMS 1
/* Global variables used by the stack */
uint8_t MBX[MBXBUFFERS * MAX(MBXSIZE,MBXSIZEBOOT)];
_MBXcontrol MBXcontrol[MBXBUFFERS];
_ESCvar ESCvar;
/* Application variables */
_Rbuffer Rb;
_Wbuffer Wb;
_Cbuffer Cb;
/* Private variables */
uint16_t txpdomap = DEFAULTTXPDOMAP;
uint16_t rxpdomap = DEFAULTRXPDOMAP;
uint8_t txpdoitems = DEFAULTTXPDOITEMS;
uint8_t rxpdoitems = DEFAULTTXPDOITEMS;
static int watchdog = WATCHDOG_RESET_VALUE;
static void (*application_loop_callback)(void) = NULL;
/** Function to pre-qualify the incoming SDO download.
*
* @param[in] index = index of SDO download request to check
* @param[in] sub-index = sub-index of SDO download request to check
* @return 1 if the SDO Download is correct. 0 If not correct.
*/
int ESC_pre_objecthandler (uint16_t index, uint8_t subindex)
{
if ((index == 0x1c12) && (subindex > 0) && (rxpdoitems != 0))
{
SDO_abort (index, subindex, ABORT_READONLY);
return 0;
}
if ((index == 0x1c13) && (subindex > 0) && (txpdoitems != 0))
{
SDO_abort (index, subindex, ABORT_READONLY);
return 0;
}
return 1;
}
/** Mandatory: Hook called from the slave stack SDO Download handler to act on
* user specified Index and Sub-index.
*
* @param[in] index = index of SDO download request to handle
* @param[in] sub-index = sub-index of SDO download request to handle
*/
void ESC_objecthandler (uint16_t index, uint8_t subindex)
{
switch (index)
{
case 0x1c12:
{
if (rxpdoitems > 1)
{
rxpdoitems = 1;
}
if ((rxpdomap != 0x1600) && (rxpdomap != 0x1601)
&& (rxpdomap != 0x0000))
{
rxpdomap = 0x1600;
}
ESCvar.RXPDOsize = ESCvar.ESC_SM2_sml = sizeOfPDO(RX_PDO_OBJIDX);
break;
}
case 0x1c13:
{
if (txpdoitems > 1)
{
txpdoitems = 1;
}
if ((txpdomap != 0x1A00) && (txpdomap != 0x1A01)
&& (rxpdomap != 0x0000))
{
txpdomap = 0x1A00;
}
ESCvar.TXPDOsize = ESC_SM3_sml = sizeOfPDO(TX_PDO_OBJIDX);
break;
}
/* Handle post-write of parameter values */
case 0x8000:
{
cb_post_write_Parameters(subindex);
break;
}
default:
break;
}
}
/** Mandatory: Hook called from the slave stack ESC_stopoutputs to act on state changes
* forcing us to stop outputs. Here we can set them to a safe state.
* set
*/
void APP_safeoutput (void)
{
DPRINT ("APP_safeoutput\n");
// Set safe values for Wb.LEDs
Wb.LEDs.LED0 = 0;
Wb.LEDs.LED1 = 0;
}
/** Mandatory: Write local process data to Sync Manager 3, Master Inputs.
*/
void TXPDO_update (void)
{
ESC_write (SM3_sma, &Rb, ESCvar.TXPDOsize);
}
/** Mandatory: Read Sync Manager 2 to local process data, Master Outputs.
*/
void RXPDO_update (void)
{
ESC_read (SM2_sma, &Wb, ESCvar.RXPDOsize);
}
/** Mandatory: Function to update local I/O, call read ethercat outputs, call
* write ethercat inputs. Implement watch-dog counter to count-out if we have
* made state change affecting the App.state.
*/
void DIG_process (void)
{
if (watchdog > 0)
{
watchdog--;
}
if (ESCvar.App.state & APPSTATE_OUTPUT)
{
/* SM2 trigger ? */
if (ESCvar.ALevent & ESCREG_ALEVENT_SM2)
{
ESCvar.ALevent &= ~ESCREG_ALEVENT_SM2;
RXPDO_update();
watchdog = WATCHDOG_RESET_VALUE;
/* Set outputs */
cb_set_LEDs();
}
if (watchdog <= 0)
{
DPRINT("DIG_process watchdog expired\n");
ESC_stopoutput();
/* watchdog, invalid outputs */
ESC_ALerror (ALERR_WATCHDOG);
/* goto safe-op with error bit set */
ESC_ALstatus (ESCsafeop | ESCerror);
}
}
else
{
watchdog = WATCHDOG_RESET_VALUE;
}
if (ESCvar.App.state)
{
/* Update inputs */
cb_get_Buttons();
TXPDO_update();
}
}
/********** TODO: Generic code beyond this point ***************/
/** Optional: Hook called after state change for application specific
* actions for specific state changes.
*/
void post_state_change_hook (uint8_t * as, uint8_t * an)
{
#if 0
/* Add specific step change hooks here */
if ((*as == BOOT_TO_INIT) && (*an == ESCinit))
{
boot_inithook();
}
else if((*as == INIT_TO_BOOT) && (*an & ESCerror ) == 0)
{
init_boothook();
}
#endif
}
/**
* Set callback run once every loop in the SOES application loop.
*/
void set_application_loop_hook(void (*callback)(void))
{
application_loop_callback = callback;
}
/**
* SOES main function. It should be called periodically.
* Reads the EtherCAT state and status. Responsible for I/O updates.
*/
void soes (void)
{
/* On init restore PDO mappings to default size */
if((ESCvar.ALstatus & 0x0f) == ESCinit)
{
txpdomap = DEFAULTTXPDOMAP;
rxpdomap = DEFAULTRXPDOMAP;
txpdoitems = DEFAULTTXPDOITEMS;
rxpdoitems = DEFAULTTXPDOITEMS;
}
/* Read local time from ESC */
ESC_read (ESCREG_LOCALTIME, (void *) &ESCvar.Time, sizeof (ESCvar.Time));
ESCvar.Time = etohl (ESCvar.Time);
/* Check the state machine */
ESC_state();
/* Check mailboxes */
if (ESC_mbxprocess())
{
ESC_coeprocess();
ESC_foeprocess();
ESC_xoeprocess();
}
DIG_process();
if (application_loop_callback != NULL)
{
(application_loop_callback)();
}
}
/**
* Initialize the SOES stack.
*/
void soes_init (void)
{
DPRINT ("SOES (Simple Open EtherCAT Slave)\n");
ESCvar.TXPDOsize = ESCvar.ESC_SM3_sml = sizeOfPDO(TX_PDO_OBJIDX);
ESCvar.RXPDOsize = ESCvar.ESC_SM2_sml = sizeOfPDO(RX_PDO_OBJIDX);
/* Setup config hooks */
static esc_cfg_t config =
{
.user_arg = "/spi1/lan9252",
.use_interrupt = 0,
.watchdog_cnt = 0,
.mbxsize = MBXSIZE,
.mbxsizeboot = MBXSIZEBOOT,
.mbxbuffers = MBXBUFFERS,
.mb[0] = {MBX0_sma, MBX0_sml, MBX0_sme, MBX0_smc, 0},
.mb[1] = {MBX1_sma, MBX1_sml, MBX1_sme, MBX1_smc, 0},
.mb_boot[0] = {MBX0_sma_b, MBX0_sml_b, MBX0_sme_b, MBX0_smc_b, 0},
.mb_boot[1] = {MBX1_sma_b, MBX1_sml_b, MBX1_sme_b, MBX1_smc_b, 0},
.pdosm[0] = {SM2_sma, 0, 0, SM2_smc, SM2_act},
.pdosm[1] = {SM3_sma, 0, 0, SM3_smc, SM3_act},
.pre_state_change_hook = NULL,
.post_state_change_hook = NULL,
.application_hook = NULL,
.safeoutput_override = NULL,
.pre_object_download_hook = NULL,
.post_object_download_hook = NULL,
.rxpdo_override = NULL,
.txpdo_override = NULL,
.esc_hw_interrupt_enable = NULL,
.esc_hw_interrupt_disable = NULL,
.esc_hw_eep_handler = NULL
};
ESC_config (&config);
ESC_init (&config);
/* wait until ESC is started up */
while ((ESCvar.DLstatus & 0x0001) == 0)
{
ESC_read (ESCREG_DLSTATUS, (void *) &ESCvar.DLstatus,
sizeof (ESCvar.DLstatus));
ESCvar.DLstatus = etohs (ESCvar.DLstatus);
}
/* Init FoE */
FOE_init();
/* reset ESC to init state */
ESC_ALstatus (ESCinit);
ESC_ALerror (ALERR_NONE);
ESC_stopmbx();
ESC_stopinput();
ESC_stopoutput();
}

View File

@ -1,38 +0,0 @@
#ifndef __SLAVE_H__
#define __SLAVE_H__
#include "utypes.h"
/**
* This function reads physical input values and assigns the corresponding members
* of Rb.Buttons
*/
void cb_get_Buttons();
/**
* This function writes physical output values from the corresponding members of
* Wb.LEDs
*/
void cb_set_LEDs();
/**
* This function is called after a SDO write of the object Cb.Parameters.
*/
void cb_post_write_Parameters(int subindex);
/**
* This function sets an application loop callback function.
*/
void set_application_loop_hook(void (*callback)(void));
/**
* Main function for SOES application
*/
void soes (void);
/**
* Initialize the SOES stack
*/
void soes_init (void);
#endif /* __SLAVE_H__ */

View File

@ -1,47 +0,0 @@
#ifndef __UTYPES_H__
#define __UTYPES_H__
#include <cc.h>
CC_PACKED_BEGIN
typedef struct
{
CC_PACKED_BEGIN
struct
{
uint8_t Button1;
} CC_PACKED Buttons;
CC_PACKED_END
} CC_PACKED _Rbuffer;
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct
{
CC_PACKED_BEGIN
struct
{
uint8_t LED0;
uint8_t LED1;
} CC_PACKED LEDs;
CC_PACKED_END
} CC_PACKED _Wbuffer;
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct
{
CC_PACKED_BEGIN
struct
{
uint32_t Multiplier;
} CC_PACKED Parameters;
CC_PACKED_END
} CC_PACKED _Cbuffer;
CC_PACKED_END
extern _Rbuffer Rb;
extern _Wbuffer Wb;
extern _Cbuffer Cb;
#endif /* __UTYPES_H__ */

View File

@ -1,35 +0,0 @@
#ifndef __CONFIG_H__
#define __CONFIG_H__
#include <cc.h>
#define MBXSIZE 128
#define MBXSIZEBOOT 256
#define MBXBUFFERS 3
#define MBX0_sma 0x1000
#define MBX0_sml MBXSIZE
#define MBX0_sme MBX0_sma+MBX0_sml-1
#define MBX0_smc 0x26
#define MBX1_sma MBX0_sma+MBX0_sml
#define MBX1_sml MBXSIZE
#define MBX1_sme MBX1_sma+MBX1_sml-1
#define MBX1_smc 0x22
#define MBX0_sma_b 0x1000
#define MBX0_sml_b MBXSIZEBOOT
#define MBX0_sme_b MBX0_sma_b+MBX0_sml_b-1
#define MBX0_smc_b 0x26
#define MBX1_sma_b MBX0_sma_b+MBX0_sml_b
#define MBX1_sml_b MBXSIZEBOOT
#define MBX1_sme_b MBX1_sma_b+MBX1_sml_b-1
#define MBX1_smc_b 0x22
#define SM2_sma 0x1100
#define SM2_smc 0x24
#define SM2_act 1
#define SM3_sma 0x1180
#define SM3_smc 0x20
#define SM3_act 1
#endif /* __CONFIG_H__ */

View File

@ -1,7 +1,13 @@
#ifndef __CONFIG_H__
#define __CONFIG_H__
#ifndef __ECAT_OPTIONS_H__
#define __ECAT_OPTIONS_H__
#include <cc.h>
#include "cc.h"
#define USE_FOE 0
#define USE_EOE 1
#define MAX_INPUT_SIZE 128
#define MAX_OUTPUT_SIZE 128
#define MBXSIZE 128
#define MBXSIZEBOOT 128
@ -26,10 +32,13 @@
#define MBX1_smc_b 0x22
#define SM2_sma 0x1100
#define SM2_smc 0x24
#define SM2_smc 0x64
#define SM2_act 1
#define SM3_sma 0x1180
#define SM3_smc 0x20
#define SM3_act 1
#endif /* __CONFIG_H__ */
#define MAX_MAPPINGS_SM2 2
#define MAX_MAPPINGS_SM3 1
#endif /* __ECAT_OPTIONS_H__ */

View File

@ -1,312 +0,0 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
/** \file
* \brief
* ESC hardware layer functions.
*
* Function to read and write commands to the ESC. Used to read/write ESC
* registers and memory.
*/
#include <kern.h>
#include <bsp.h>
#include <xmc4.h>
#include <eru.h>
#include <string.h>
#include "esc_hw.h"
#include "slave.h"
#include "esc_eep.h"
#define ESCADDR(x) (((uint8_t *) ECAT0_BASE) + x)
static volatile esc_registers_t * ecat0 = (esc_registers_t *)ECAT0_BASE;
static int use_all_interrupts = 0;
//static sem_t * ecat_isr_sem;
static void sync0_isr (void * arg);
static volatile uint8_t read_ack;
static const eru_cfg_t cfg = {
.base = ERU1_BASE,
.channel = 2,
.in_a = 0,
.in_b = 3,
.exicon = ERU_EXICON_PE_ENABLED |
ERU_EXICON_LD_ENABLED |
ERU_EXICON_RE_ENABLED |
ERU_EXICON_OCS(2) |
ERU_EXICON_SS(1),
.exocon = ERU_EXOCON_ISS(0) |
ERU_EXOCON_GP(1) |
ERU_EXOCON_IPEEN(0),
.irq = IRQ_ERU1_SR7,
.isr = sync0_isr,
.arg = NULL,
};
static const scu_ecat_cfg_t port_control =
{
.con = {0},
.conp0 = {
.rxd[0] = ECAT_PORT0_CTRL_RXDO0,
.rxd[1] = ECAT_PORT0_CTRL_RXDO1,
.rxd[2] = ECAT_PORT0_CTRL_RXDO2,
.rxd[3] = ECAT_PORT0_CTRL_RXDO3,
.rx_clk = ECAT_PORT0_CTRL_RX_CLK,
.rx_dv = ECAT_PORT0_CTRL_RX_DV,
.rx_err = ECAT_PORT0_CTRL_RX_ERR,
.link = ECAT_PORT0_CTRL_LINK,
.tx_clk = ECAT_PORT0_CTRL_TX_CLK,
.tx_shift = ECAT_PORT0_CTRL_TX_SHIFT
},
.conp1 = {
.rxd[0] = ECAT_PORT1_CTRL_RXDO0,
.rxd[1] = ECAT_PORT1_CTRL_RXDO1,
.rxd[2] = ECAT_PORT1_CTRL_RXDO2,
.rxd[3] = ECAT_PORT1_CTRL_RXDO3,
.rx_clk = ECAT_PORT1_CTRL_RX_CLK,
.rx_dv = ECAT_PORT1_CTRL_RX_DV,
.rx_err = ECAT_PORT1_CTRL_RX_ERR,
.link = ECAT_PORT1_CTRL_LINK,
.tx_clk = ECAT_PORT1_CTRL_TX_CLK,
.tx_shift = ECAT_PORT1_CTRL_TX_SHIFT
}
};
/* EtherCAT module clock ungating and deassert reset API (Enables ECAT) */
void ESC_enable(void)
{
scu_put_peripheral_in_reset (SCU_PERIPHERAL_ECAT0);
scu_ungate_clock_to_peripheral (SCU_PERIPHERAL_ECAT0);
scu_release_peripheral_from_reset (SCU_PERIPHERAL_ECAT0);
}
/* EtherCAT module clock gating and assert reset API (Disables ECAT)*/
void ESC_disable(void)
{
scu_put_peripheral_in_reset (SCU_PERIPHERAL_ECAT0);
scu_gate_clock_to_peripheral (SCU_PERIPHERAL_ECAT0);
}
/** ESC read function used by the Slave stack.
*
* @param[in] address = address of ESC register to read
* @param[out] buf = pointer to buffer to read in
* @param[in] len = number of bytes to read
*/
void ESC_read (uint16_t address, void *buf, uint16_t len)
{
if(use_all_interrupts == 0)
{
ESCvar.ALevent = etohs ((uint16_t)ecat0->AL_EVENT_REQ);
}
memcpy (buf, ESCADDR(address), len);
}
/** ESC write function used by the Slave stack.
*
* @param[in] address = address of ESC register to write
* @param[out] buf = pointer to buffer to write from
* @param[in] len = number of bytes to write
*/
void ESC_write (uint16_t address, void *buf, uint16_t len)
{
if(use_all_interrupts == 0)
{
ESCvar.ALevent = etohs ((uint16_t)ecat0->AL_EVENT_REQ);
}
memcpy (ESCADDR(address), buf, len);
}
/** ESC reset hardware.
*/
void ESC_reset (void)
{
/* disable ESC to force reset */
ESC_disable ();
/* initialize EEPROM emulation */
EEP_init ();
}
/** ESC interrupt enable function by the Slave stack in IRQ mode.
*
* @param[in] mask = of interrupts to enable
*/
void ESC_interrupt_enable (uint32_t mask)
{
if(ESCREG_ALEVENT_DC_SYNC0 & mask)
{
mask &= ~ESCREG_ALEVENT_DC_SYNC0;
int_enable(cfg.irq);
}
if(ESCREG_ALEVENT_DC_SYNC1 & mask)
{
mask &= ~ESCREG_ALEVENT_DC_SYNC1;
UASSERT(0,EARG);
}
if(ESCREG_ALEVENT_DC_LATCH & mask)
{
mask &= ~ESCREG_ALEVENT_DC_LATCH;
UASSERT(0,EARG);
}
ecat0->AL_EVENT_MASK |= mask;
}
/** ESC interrupt disable function by the Slave stack in IRQ mode.
*
* @param[in] mask = interrupts to disable
*/
void ESC_interrupt_disable (uint32_t mask)
{
if(ESCREG_ALEVENT_DC_SYNC0 & mask)
{
mask &= ~ESCREG_ALEVENT_DC_SYNC0;
int_disable(cfg.irq);
}
if(ESCREG_ALEVENT_DC_SYNC1 & mask)
{
mask &= ~ESCREG_ALEVENT_DC_SYNC1;
UASSERT(0,EARG);
}
if(ESCREG_ALEVENT_DC_LATCH & mask)
{
mask &= ~ESCREG_ALEVENT_DC_LATCH;
UASSERT(0,EARG);
}
ecat0->AL_EVENT_MASK &= ~mask;
}
/** ESC emulated EEPROM handler
*/
void ESC_eep_handler(void)
{
EEP_process ();
EEP_hw_process();
}
/** SYNC0 ISR handler
*
* @param[in] arg = NOT USED
*/
static void sync0_isr (void * arg)
{
DIG_process(DIG_PROCESS_APP_HOOK_FLAG | DIG_PROCESS_INPUTS_FLAG);
read_ack = ecat0->DC_SYNC0_STAT;
}
/** PDI ISR handler
*
* @param[in] arg = NOT USED
*/
static void ecat_isr (void * arg)
{
ESC_read (ESCREG_LOCALTIME, (void *) &ESCvar.Time, sizeof (ESCvar.Time));
ESCvar.Time = etohl (ESCvar.Time);
CC_ATOMIC_SET(ESCvar.ALevent, etohl(ecat0->AL_EVENT_REQ));
if(ESCvar.ALevent & ESCREG_ALEVENT_SM2)
{
if(ESCvar.dcsync == 0)
{
DIG_process(DIG_PROCESS_OUTPUTS_FLAG | DIG_PROCESS_APP_HOOK_FLAG |
DIG_PROCESS_INPUTS_FLAG);
}
else
{
DIG_process(DIG_PROCESS_OUTPUTS_FLAG);
}
}
#if 1
if(ESCvar.ALevent & (ESCREG_ALEVENT_CONTROL | ESCREG_ALEVENT_SMCHANGE
| ESCREG_ALEVENT_SM0 | ESCREG_ALEVENT_SM1 | ESCREG_ALEVENT_EEP))
{
/* Mask interrupts while servicing them */
ecat0->AL_EVENT_MASK &= ~(ESCREG_ALEVENT_CONTROL | ESCREG_ALEVENT_SMCHANGE
| ESCREG_ALEVENT_SM0 | ESCREG_ALEVENT_SM1 | ESCREG_ALEVENT_EEP);
extern flags_t * ecat_events;
flags_set(ecat_events, EVENT_ISR);
//sem_signal(ecat_isr_sem);
}
#endif
}
#if 0
/* Function for PDI ISR serving task */
static void isr_run(void * arg)
{
while(1)
{
sem_wait(ecat_isr_sem);
ecat_slv_worker(ESCREG_ALEVENT_CONTROL | ESCREG_ALEVENT_SMCHANGE
| ESCREG_ALEVENT_SM0 | ESCREG_ALEVENT_SM1 | ESCREG_ALEVENT_EEP);
}
}
#endif
/** ESC and CPU related HW init
*
* @param[in] arg = esc_cfg provided by the application
*/
void ESC_init (const esc_cfg_t * config)
{
eep_config_t ecat_config;
ESC_reset();
scu_configure_ethercat_signals(&port_control);
/* read config from emulated EEPROM */
memset(&ecat_config, 0, sizeof(eep_config_t));
EEP_read (0, (uint8_t *) &ecat_config, sizeof(eep_config_t));
ESC_enable();
/* words 0x0-0x3 */
ecat0->EEP_DATA[0U] = ecat_config.dword[0U];
ecat0->EEP_DATA[1U] = ecat_config.dword[1U];
ecat0->EEP_CONT_STAT |= (uint16_t)(BIT(10)); /* ESI EEPROM Reload */
/* words 0x4-0x7 */
ecat0->EEP_DATA[0U] = ecat_config.dword[2U];
ecat0->EEP_DATA[1U] = ecat_config.dword[3U];
ecat0->EEP_CONT_STAT |= (uint16_t)(BIT(10)); /* ESI EEPROM Reload */
while (ecat0->EEP_CONT_STAT & BIT(12)) /* ESI EEPROM loading status */
{
/* Wait until the EEPROM_Loaded signal is active */
}
/* Configure CPU interrupts */
if(config->use_interrupt != 0)
{
// ecat_isr_sem = sem_create(0);
// task_spawn ("soes_isr", isr_run, 9, 2048, NULL);
use_all_interrupts = 0;
ecat0->AL_EVENT_MASK = 0;
ecat0->AL_EVENT_MASK = (ESCREG_ALEVENT_SMCHANGE |
ESCREG_ALEVENT_EEP |
ESCREG_ALEVENT_CONTROL |
ESCREG_ALEVENT_SM0 |
ESCREG_ALEVENT_SM1);
int_connect (IRQ_ECAT0_SR0, ecat_isr, NULL);
int_enable (IRQ_ECAT0_SR0);
// /* Activate for running external sync IRQ */
// scu_put_peripheral_in_reset (SCU_PERIPHERAL_ERU1);
// scu_ungate_clock_to_peripheral (SCU_PERIPHERAL_ERU1);
// scu_release_peripheral_from_reset (SCU_PERIPHERAL_ERU1);
//
// eru_configure(&cfg);
// /* Let the stack decide when to enable */
// int_disable(cfg.irq);
}
}

View File

@ -1,179 +0,0 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
/** \file
* \brief
* ESC hardware specifoc EEPROM emulation functions.
*/
#ifndef __esc_hw__
#define __esc_hw__
#include <kern.h>
/* ================================================================================ */
/* ================ ECAT [ECAT0] ================ */
/* ================================================================================ */
#define EVENT_PERIODIC BIT(0)
#define EVENT_TX BIT(1)
#define EVENT_ISR BIT(2)
/**
* @brief EtherCAT 0 (ECAT)
*/
typedef struct esc_registers
{ /*!< (@ 0x54010000) ECAT Structure */
uint8_t TYPE; /*!< (@ 0x54010000) Type of EtherCAT Controller */
uint8_t REVISION; /*!< (@ 0x54010001) Revision of EtherCAT Controller */
uint16_t BUILD; /*!< (@ 0x54010002) Build Version */
uint8_t FMMU_NUM; /*!< (@ 0x54010004) FMMUs Supported */
uint8_t SYNC_MANAGER; /*!< (@ 0x54010005) SyncManagers Supported */
uint8_t RAM_SIZE; /*!< (@ 0x54010006) RAM Size */
uint8_t PORT_DESC; /*!< (@ 0x54010007) Port Descriptor */
uint16_t FEATURE; /*!< (@ 0x54010008) ESC Features Supported */
uint16_t RESERVED[3];
uint16_t STATION_ADR; /*!< (@ 0x54010010) Configured Station Address */
uint16_t STATION_ALIAS; /*!< (@ 0x54010012) Configured Station Alias */
uint32_t RESERVED1[3];
uint8_t WR_REG_ENABLE; /*!< (@ 0x54010020) Write Register Enable */
uint8_t WR_REG_PROTECT; /*!< (@ 0x54010021) Write Register Protection */
uint16_t RESERVED2[7];
uint8_t ESC_WR_ENABLE; /*!< (@ 0x54010030) ESC Write Enable */
uint8_t ESC_WR_PROTECT; /*!< (@ 0x54010031) ESC Write Protection */
uint16_t RESERVED3[7];
union
{
uint8_t ESC_RESET_ECAT_READMode; /*!< (@ 0x54010040) ESC Reset ECAT [READ Mode] */
uint8_t ESC_RESET_ECAT_WRITEMode; /*!< (@ 0x54010040) ESC Reset ECAT [WRITE Mode] */
};
union {
uint8_t ESC_RESET_PDI_READMode; /*!< (@ 0x54010041) ESC Reset PDI [READ Mode] */
uint8_t ESC_RESET_PDI_WRITEMode; /*!< (@ 0x54010041) ESC Reset PDI [WRITE Mode] */
};
uint16_t RESERVED4[95];
uint32_t ESC_DL_CONTROL; /*!< (@ 0x54010100) ESC DL Control */
uint32_t RESERVED5;
uint16_t PHYSICAL_RW_OFFSET; /*!< (@ 0x54010108) Physical Read/Write Offset */
uint16_t RESERVED6[3];
uint16_t ESC_DL_STATUS; /*!< (@ 0x54010110) ESC DL Status */
uint16_t RESERVED7[7];
uint16_t AL_CONTROL; /*!< (@ 0x54010120) AL Control */
uint16_t RESERVED8[7];
uint16_t AL_STATUS; /*!< (@ 0x54010130) AL Status */
uint16_t RESERVED9;
uint16_t AL_STATUS_CODE; /*!< (@ 0x54010134) AL Status Code */
uint16_t RESERVED10;
uint8_t RUN_LED; /*!< (@ 0x54010138) RUN LED Override */
uint8_t ERR_LED; /*!< (@ 0x54010139) RUN ERR Override */
uint16_t RESERVED11[3];
uint8_t PDI_CONTROL; /*!< (@ 0x54010140) PDI Control */
uint8_t ESC_CONFIG; /*!< (@ 0x54010141) ESC Configuration */
uint16_t RESERVED12[7];
uint8_t PDI_CONFIG; /*!< (@ 0x54010150) PDI Control */
uint8_t SYNC_LATCH_CONFIG; /*!< (@ 0x54010151) Sync/Latch[1:0] PDI Configuration */
uint16_t PDI_EXT_CONFIG; /*!< (@ 0x54010152) PDI Synchronous Microcontroller extended Configuration */
uint32_t RESERVED13[43];
uint16_t EVENT_MASK; /*!< (@ 0x54010200) ECAT Event Mask */
uint16_t RESERVED14;
uint32_t AL_EVENT_MASK; /*!< (@ 0x54010204) PDI AL Event Mask */
uint32_t RESERVED15[2];
uint16_t EVENT_REQ; /*!< (@ 0x54010210) ECAT Event Request */
uint16_t RESERVED16[7];
uint32_t AL_EVENT_REQ; /*!< (@ 0x54010220) AL Event Request */
uint32_t RESERVED17[55];
uint16_t RX_ERR_COUNT0; /*!< (@ 0x54010300) RX Error Counter Port 0 */
uint16_t RX_ERR_COUNT1; /*!< (@ 0x54010302) RX Error Counter Port 1 */
uint32_t RESERVED18;
uint8_t FWD_RX_ERR_COUNT0; /*!< (@ 0x54010308) Forwarded RX Error Counter Port 0 */
uint8_t FWD_RX_ERR_COUNT1; /*!< (@ 0x54010309) Forwarded RX Error Counter Port 1 */
uint16_t RESERVED19;
uint8_t PROC_ERR_COUNT; /*!< (@ 0x5401030C) ECAT Processing Unit Error Counter */
uint8_t PDI_ERR_COUNT; /*!< (@ 0x5401030D) PDI Error Counter */
uint16_t RESERVED20;
uint8_t LOST_LINK_COUNT0; /*!< (@ 0x54010310) Lost Link Counter Port 0 */
uint8_t LOST_LINK_COUNT1; /*!< (@ 0x54010311) Lost Link Counter Port 1 */
uint16_t RESERVED21[119];
uint16_t WD_DIVIDE; /*!< (@ 0x54010400) Watchdog Divider */
uint16_t RESERVED22[7];
uint16_t WD_TIME_PDI; /*!< (@ 0x54010410) Watchdog Time PDI */
uint16_t RESERVED23[7];
uint16_t WD_TIME_PDATA; /*!< (@ 0x54010420) Watchdog Time Process Data */
uint16_t RESERVED24[15];
uint16_t WD_STAT_PDATA; /*!< (@ 0x54010440) Watchdog Status Process Data */
uint8_t WD_COUNT_PDATA; /*!< (@ 0x54010442) Watchdog Counter Process Data */
uint8_t WD_COUNT_PDI; /*!< (@ 0x54010443) Watchdog Counter PDI */
uint32_t RESERVED25[47];
uint8_t EEP_CONF; /*!< (@ 0x54010500) EEPROM Configuration */
uint8_t EEP_STATE; /*!< (@ 0x54010501) EEPROM PDI Access State */
uint16_t EEP_CONT_STAT; /*!< (@ 0x54010502) EEPROM Control/Status */
uint32_t EEP_ADR; /*!< (@ 0x54010504) EEPROM Address */
uint32_t EEP_DATA[2]; /*!< (@ 0x54010508) EEPROM Read/Write data */
uint16_t MII_CONT_STAT; /*!< (@ 0x54010510) MII Management Control/Status */
uint8_t MII_PHY_ADR; /*!< (@ 0x54010512) PHY Address */
uint8_t MII_PHY_REG_ADR; /*!< (@ 0x54010513) PHY Register Address */
uint16_t MII_PHY_DATA; /*!< (@ 0x54010514) PHY Data */
uint8_t MII_ECAT_ACS_STATE; /*!< (@ 0x54010516) MII ECAT ACS STATE */
uint8_t MII_PDI_ACS_STATE; /*!< (@ 0x54010517) MII PDI ACS STATE */
uint32_t RESERVED26[250];
uint32_t DC_RCV_TIME_PORT0; /*!< (@ 0x54010900) Receive Time Port 0 */
uint32_t DC_RCV_TIME_PORT1; /*!< (@ 0x54010904) Receive Time Port 1 */
uint32_t RESERVED27[2];
union
{
uint32_t READMode_DC_SYS_TIME[2]; /*!< (@ 0x54010910) System Time read access */
uint32_t DC_SYS_TIME_WRITEMode; /*!< (@ 0x54010910) System Time [WRITE Mode] */
};
uint32_t RECEIVE_TIME_PU[2]; /*!< (@ 0x54010918) Local time of the beginning of a frame */
uint32_t DC_SYS_TIME_OFFSET[2]; /*!< (@ 0x54010920) Difference between local time and System Time */
uint32_t DC_SYS_TIME_DELAY; /*!< (@ 0x54010928) System Time Delay */
uint32_t DC_SYS_TIME_DIFF; /*!< (@ 0x5401092C) System Time Difference */
uint16_t DC_SPEED_COUNT_START; /*!< (@ 0x54010930) Speed Counter Start */
uint16_t DC_SPEED_COUNT_DIFF; /*!< (@ 0x54010932) Speed Counter Diff */
uint8_t DC_SYS_TIME_FIL_DEPTH; /*!< (@ 0x54010934) System Time Difference Filter Depth */
uint8_t DC_SPEED_COUNT_FIL_DEPTH; /*!< (@ 0x54010935) Speed Counter Filter Depth */
uint16_t RESERVED28[37];
uint8_t DC_CYC_CONT; /*!< (@ 0x54010980) Cyclic Unit Control */
uint8_t DC_ACT; /*!< (@ 0x54010981) Activation register */
uint16_t DC_PULSE_LEN; /*!< (@ 0x54010982) Pulse Length of SyncSignals */
uint8_t DC_ACT_STAT; /*!< (@ 0x54010984) Activation Status */
uint8_t RESERVED29[9];
uint8_t DC_SYNC0_STAT; /*!< (@ 0x5401098E) SYNC0 Status */
uint8_t DC_SYNC1_STAT; /*!< (@ 0x5401098F) SYNC1 Status */
uint32_t DC_CYC_START_TIME[2]; /*!< (@ 0x54010990) Start Time Cyclic Operation */
uint32_t DC_NEXT_SYNC1_PULSE[2]; /*!< (@ 0x54010998) System time of next SYNC1 pulse in ns */
uint32_t DC_SYNC0_CYC_TIME; /*!< (@ 0x540109A0) SYNC0 Cycle Time */
uint32_t DC_SYNC1_CYC_TIME; /*!< (@ 0x540109A4) SYNC1 Cycle Time */
uint8_t DC_LATCH0_CONT; /*!< (@ 0x540109A8) Latch0 Control */
uint8_t DC_LATCH1_CONT; /*!< (@ 0x540109A9) Latch1 Control */
uint32_t RESERVED30;
uint8_t DC_LATCH0_STAT; /*!< (@ 0x540109AE) Latch0 Status */
uint8_t DC_LATCH1_STAT; /*!< (@ 0x540109AF) Latch1 Status */
uint32_t DC_LATCH0_TIME_POS[2]; /*!< (@ 0x540109B0) Register captures System time at the positive
edge of the Latch0 signal */
uint32_t DC_LATCH0_TIME_NEG[2]; /*!< (@ 0x540109B8) Register captures System time at the negative
edge of the Latch0 signal */
uint32_t DC_LATCH1_TIME_POS[2]; /*!< (@ 0x540109C0) Register captures System time at the positive
edge of the Latch1 signal */
uint32_t DC_LATCH1_TIME_NEG[2]; /*!< (@ 0x540109C8) Register captures System time at the negative
edge of the Latch1 signal */
uint32_t RESERVED31[8];
uint32_t DC_ECAT_CNG_EV_TIME; /*!< (@ 0x540109F0) EtherCAT Buffer Change Event Time */
uint32_t RESERVED32;
uint32_t DC_PDI_START_EV_TIME; /*!< (@ 0x540109F8) PDI Buffer Start Event Time */
uint32_t DC_PDI_CNG_EV_TIME; /*!< (@ 0x540109FC) PDI Buffer Change Event Time */
uint32_t RESERVED33[256];
uint32_t ID; /*!< (@ 0x54010E00) ECAT0 Module ID */
uint32_t RESERVED34;
uint32_t STATUS; /*!< (@ 0x54010E08) ECAT0 Status */
} esc_registers_t;
void EEP_hw_process (void);
void ESC_eep_handler(void);
void ESC_interrupt_enable (uint32_t mask);
void ESC_interrupt_disable (uint32_t mask);
#endif

View File

@ -1,311 +0,0 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
/** \file
* \brief
* ESC hardware specific EEPROM emulation functions.
*/
#include <cc.h>
#include <fce.h>
#include <string.h>
#include <drivers/nor/nor.h>
#include "esc.h"
#include "esc_hw_eep.h"
extern const uint8_t _binary_sii_eeprom_bin_start;
extern const uint8_t _binary_sii_eeprom_bin_end;
#define SII_EE_DEFLT (&_binary_sii_eeprom_bin_start)
#define SII_EE_DEFLT_SIZE (uint32_t)(&_binary_sii_eeprom_bin_end - &_binary_sii_eeprom_bin_start)
#define EEP_DEFAULT_BTN_INIT() { }
#define EEP_DEFAULT_BTN_STATE() 0
#define EEP_BUSY_LED_INIT() { }
#define EEP_BUSY_LED_ON() { }
#define EEP_BUSY_LED_OFF() { }
#if EEP_BYTES_PER_BLOCK > EEP_BYTES_PER_SECTOR
#error EEP_BYTES_PER_BLOCK needs to fit into EEP_BYTES_PER_SECTOR
#endif
/** CRC engine configuration */
static const fce_kernel_cfg_t fce_config =
{
.crc_kernel_addr = FCE_KE0_BASE,
.kernel_cfg = 0,
.seed = 0xffffffff
};
static uint8_t eep_buf[EEP_EMU_BYTES];
static uint8_t eep_buf_dirty;
static uint32_t eep_last_write;
static uint8_t eep_write_req;
static eep_block_t *eep_curr_block;
static eep_block_t *eep_next_block;
static uint32_t *eep_write_src;
static uint32_t *eep_write_dst;
static uint32_t eep_write_page;
static eep_block_t eep_write_buf;
static drv_t * drv;
static void init_flash_data(void);
static void find_latest_block(eep_block_t *addr);
static eep_block_t *get_next_block(eep_block_t *block);
static eep_block_t *cleanup_unused_sect(eep_block_t *block);
static int32_t is_sector_empty(uint32_t *addr);
/** Initialize EEPROM emulation (load default data, validate checksums, ...).
*
*/
void EEP_init (void)
{
/* initialize write buffer */
memset(&eep_write_buf, 0, EEP_BYTES_PER_BLOCK);
/* Initialize the FCE Configuration */
fce_init(&fce_config);
drv = dev_find_driver ("/pflash");
ASSERT (drv != NULL);
/* try to find latest block in both sectors */
eep_curr_block = NULL;
if (!EEP_DEFAULT_BTN_STATE()) {
find_latest_block((eep_block_t *) EEP_SECTOR_A);
find_latest_block((eep_block_t *) EEP_SECTOR_B);
}
EEP_BUSY_LED_ON();
/* no valid block found -> initialize flash with default data */
if (eep_curr_block == NULL) {
init_flash_data();
}
/* cleanup unused block */
cleanup_unused_sect(eep_curr_block);
/* copy data from block to emu buffer */
memcpy(eep_buf, eep_curr_block->data, EEP_EMU_BYTES);
/* initialize state variables */
eep_buf_dirty = 0;
eep_last_write = 0;
eep_write_req = 0;
eep_next_block = NULL;
}
/** EEPROM emulation controller side periodic task.
*
*/
void EEP_hw_process (void)
{
/* check for dirty buffer and set write */
if (eep_buf_dirty) {
int32_t idle_time = ((int32_t) ESCvar.Time) - ((int32_t) eep_last_write);
if (idle_time > EEP_IDLE_TIMEOUT) {
eep_buf_dirty = 0;
eep_write_req = 1;
}
}
/* check for write process */
if (eep_next_block != NULL) {
/* write flash page */
nor_write(drv, EEP_FLASH_SECTOR_OFFSET((uint32_t)eep_write_dst),
EEP_BYTES_PER_PAGE, (const uint8_t *)eep_write_src);
eep_write_src += (EEP_BYTES_PER_PAGE / sizeof(*eep_write_src));
eep_write_dst += (EEP_BYTES_PER_PAGE / sizeof(*eep_write_dst));
/* update counter */
eep_write_page++;
/* check for finished job */
if (eep_write_page >= EEP_PAGES_PER_BLOCK) {
/* update block pointer and reset write state */
eep_curr_block = eep_next_block;
eep_next_block = NULL;
}
return;
}
/* start write of new block */
if (eep_write_req) {
EEP_BUSY_LED_ON();
/* get next block */
eep_next_block = get_next_block(eep_curr_block);
/* copy data */
memcpy(eep_write_buf.data, eep_buf, EEP_EMU_BYTES);
/* setup header */
eep_write_buf.header.seq = eep_curr_block->header.seq + 1;
eep_write_buf.header.crc = fce_crc32 (&fce_config,
(const uint32_t *)eep_write_buf.data, EEP_DATA_BYTES);
/* initialize write position */
eep_write_src = (uint32_t *) &eep_write_buf;
eep_write_dst = (uint32_t *) eep_next_block;
eep_write_page = 0;
/* reset write request */
eep_write_req = 0;
}
}
/** EEPROM read function
*
* @param[in] addr = EEPROM byte address
* @param[out] data = pointer to buffer of output data
* @param[in] count = number of bytes to read
* @return 0 on OK, 1 on error
*/
int8_t EEP_read (uint32_t addr, uint8_t *data, uint16_t count)
{
if (addr >= EEP_EMU_BYTES) {
return 1;
}
/* read data from ram buffer */
memcpy(data, eep_buf + addr, count);
return 0;
}
/** EEPROM write function
*
* @param[in] addr = EEPROM byte address
* @param[out] data = pointer to buffer of input data
* @param[in] count = number of bytes to write
* @return 0 on OK, 1 on error
*/
int8_t EEP_write (uint32_t addr, uint8_t *data, uint16_t count)
{
if (addr >= EEP_EMU_BYTES) {
return 1;
}
/* write data to ram buffer */
memcpy(eep_buf + addr, data, count);
/* mark buffer as dirty */
eep_buf_dirty = 1;
eep_write_req = 0;
eep_last_write = ESCvar.Time;
return 0;
}
static void init_flash_data(void)
{
uint32_t i;
const uint32_t *src;
uint32_t dst;
/* erase both sectors */
nor_erase(drv, EEP_FLASH_SECTOR_OFFSET(EEP_SECTOR_A), EEP_BYTES_PER_SECTOR);
nor_erase(drv, EEP_FLASH_SECTOR_OFFSET(EEP_SECTOR_B), EEP_BYTES_PER_SECTOR);
/* copy default data to write buffer */
memcpy(eep_write_buf.data, SII_EE_DEFLT, (SII_EE_DEFLT_SIZE < EEP_EMU_BYTES) ? SII_EE_DEFLT_SIZE : EEP_EMU_BYTES);
/*
* memcpy(eep_write_buf.data, SII_EE_DEFLT, (SII_EE_DEFLT_SIZE < EEP_EMU_BYTES) ? SII_EE_DEFLT_SIZE : EEP_EMU_BYTES);
*/
/* setup header data */
eep_write_buf.header.seq = 0;
eep_write_buf.header.crc = fce_crc32 (&fce_config,
(const uint32_t *)eep_write_buf.data, EEP_DATA_BYTES);
/* write pages */
src = (const uint32_t *) &eep_write_buf;
dst = EEP_SECTOR_A;
for (i = 0; i < EEP_PAGES_PER_BLOCK; i++) {
nor_write(drv, EEP_FLASH_SECTOR_OFFSET(dst), EEP_BYTES_PER_PAGE,
(const uint8_t *)src);
src += (EEP_BYTES_PER_PAGE / sizeof(*src));
dst += EEP_BYTES_PER_PAGE;
}
/* set current block */
eep_curr_block = (eep_block_t *) EEP_SECTOR_A;
}
static void find_latest_block(eep_block_t *addr)
{
uint32_t blk, crc;
for (blk = 0; blk < EPP_BLOCKS_PER_SECT; blk++, addr++) {
/* check crc, skip invalid blocks */
crc = fce_crc32 (&fce_config, (const uint32_t *) addr->data,
EEP_DATA_BYTES);
if (addr->header.crc != crc) {
continue;
}
/* check sequence number and update last pointer */
if (eep_curr_block == NULL || (addr->header.seq - eep_curr_block->header.seq) > 0) {
eep_curr_block = addr;
}
}
}
static eep_block_t *get_next_block(eep_block_t *block)
{
/* simple case: new block fits in current sector */
uint32_t sect_offset = ((uint32_t)block) & (EEP_BYTES_PER_SECTOR - 1);
if ((sect_offset + EEP_BYTES_PER_BLOCK) < EEP_BYTES_PER_SECTOR) {
return block + 1;
}
/* use other sector */
return cleanup_unused_sect(block);
}
static eep_block_t *cleanup_unused_sect(eep_block_t *block)
{
/* get other sector */
uint32_t sect_addr = (((uint32_t)block) & ~(EEP_BYTES_PER_SECTOR - 1));
if (sect_addr == EEP_SECTOR_A) {
sect_addr = EEP_SECTOR_B;
} else {
sect_addr = EEP_SECTOR_A;
}
/* check if sector is empty, erase if not */
if (!is_sector_empty((uint32_t *)sect_addr)) {
nor_erase(drv, EEP_FLASH_SECTOR_OFFSET(sect_addr), EEP_BYTES_PER_SECTOR);
}
return (eep_block_t *) sect_addr;
}
static int32_t is_sector_empty(uint32_t *addr)
{
uint32_t i;
/* check for all bytes erased */
for (i=0; i<EEP_BYTES_PER_SECTOR; i+=sizeof(uint32_t), addr++) {
if (*addr != 0) {
return 0;
}
}
return 1;
}

View File

@ -1,54 +0,0 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
/** \file
* \brief
* ESC hardware specifoc EEPROM emulation functions.
*/
#ifndef __esc_hw_eep__
#define __esc_hw_eep__
#include <bsp.h>
#include <cc.h>
#include "esc_eep.h"
/* idle timeout in ns before actual flash write will be issued */
#define EEP_IDLE_TIMEOUT 100000000
/* Pages per emulated EEPROM block */
#define EEP_BYTES_PER_SECTOR XMC4_EEPROM_SECTOR_SIZE_BYTES
#define EEP_BYTES_PER_PAGE XMC4_PAGE_SIZE_BYTES
#define EEP_PAGES_PER_BLOCK 16
/* block header */
typedef struct CC_PACKED
{
int32_t seq;
uint32_t crc;
} eep_header_t;
/* calculate resulting sizes */
#define EEP_BYTES_PER_BLOCK (EEP_PAGES_PER_BLOCK * EEP_BYTES_PER_PAGE)
#define EPP_BLOCKS_PER_SECT (EEP_BYTES_PER_SECTOR / EEP_BYTES_PER_BLOCK)
#define EEP_DATA_BYTES (EEP_BYTES_PER_BLOCK - sizeof(eep_header_t))
/* eeprom size increments in steps of 0x80 bytes */
#define EEP_EMU_BYTES (EEP_DATA_BYTES & ~0x7f)
/* block structure */
typedef struct CC_PACKED
{
eep_header_t header;
uint8_t data[EEP_DATA_BYTES];
} eep_block_t;
/* periodic task */
void EEP_hw_process (void);
#endif

View File

@ -1,19 +1,22 @@
#include <kern.h>
#include <xmc4.h>
#include <bsp.h>
#include "esc.h"
#include "esc_eoe.h"
#include "slave.h"
#include "esc_hw.h"
#include "config.h"
#include "ecat_slv.h"
#include "options.h"
#include "utypes.h"
#include <lwip/sys.h>
#include <lwip/netifapi.h>
#include <netif/etharp.h>
#include <string.h>
#define CFG_HOSTNAME "xmc48relax"
static struct netif * found_if;
static mbox_t * pbuf_mbox;
static tmr_t * ecat_timer;
static uint8_t mac_address[6] = {0x1E, 0x30, 0x6C, 0xA2, 0x45, 0x5E};
static void appl_get_buffer (eoe_pbuf_t * ebuf);
@ -23,88 +26,69 @@ static int appl_store_ethernet_settings (void);
static void appl_handle_recv_buffer (uint8_t port, eoe_pbuf_t * ebuf);
static int appl_fetch_send_buffer (uint8_t port, eoe_pbuf_t * ebuf);
flags_t * ecat_events;
/* Application variables */
_Objects Obj;
/**
* This function gets input values and updates Rb.Button1
*/
void cb_get_Button1()
extern sem_t * ecat_isr_sem;
struct netif * net_add_interface (err_t (*netif_fn) (struct netif * netif))
{
Rb.Button1.B = gpio_get(GPIO_BUTTON1);
struct netif * netif;
ip_addr_t ipaddr;
ip_addr_t netmask;
ip_addr_t gateway;
err_enum_t error;
netif = malloc (sizeof(struct netif));
UASSERT (netif != NULL, EMEM);
/* Set default (zero) values */
ip_addr_set_zero (&ipaddr);
ip_addr_set_zero (&netmask);
ip_addr_set_zero (&gateway);
/* Let lwIP TCP/IP thread initialise and add the interface. The interface
* will be down until net_configure() is called.
*/
error = netifapi_netif_add (
netif, &ipaddr, &netmask, &gateway, NULL, netif_fn, tcpip_input);
UASSERT (error == ERR_OK, EARG);
return netif;
}
/**
* This function gets input values and updates Rb.Button2
*/
void cb_get_Button2()
void cb_get_inputs (void)
{
Rb.Button2.B = gpio_get(GPIO_BUTTON2);
static int count;
Obj.Buttons.Button1 = gpio_get(GPIO_BUTTON1);
if(Obj.Buttons.Button1 == 0)
{
count++;
if(count > 1000)
{
ESC_ALstatusgotoerror((ESCsafeop | ESCerror), ALERR_WATCHDOG);
}
}
else
{
count = 0;
}
}
/**
* This function sets output values according to Wb.LEDgroup1
*/
void cb_set_LEDgroup1()
void cb_set_outputs (void)
{
gpio_set(GPIO_LED1_B, Wb.LEDgroup1.LED);
gpio_set(GPIO_LED1, Obj.LEDgroup0.LED0);
gpio_set(GPIO_LED2, Obj.LEDgroup1.LED1);
}
/**
* This function sets output values according to Wb.LEDgroup2
*/
void cb_set_LEDgroup2()
void cb_state_change (uint8_t * as, uint8_t * an)
{
gpio_set(GPIO_LED2_B, Wb.LEDgroup2.LED);
}
if (*as == SAFEOP_TO_OP)
{
/* Enable watchdog interrupt */
ESC_ALeventmaskwrite(ESC_ALeventmaskread() | ESCREG_ALEVENT_WD);
}
/**
* This function sets output values according to Wb.LEDgroup3
*/
void cb_set_LEDgroup3()
{
gpio_set(GPIO_LED3_B, Wb.LEDgroup3.LED);
}
/**
* This function sets output values according to Wb.LEDgroup4
*/
void cb_set_LEDgroup4()
{
gpio_set(GPIO_LED4_B, Wb.LEDgroup4.LED);
}
/**
* This function sets output values according to Wb.LEDgroup5
*/
void cb_set_LEDgroup5()
{
gpio_set(GPIO_LED5_B, Wb.LEDgroup5.LED5);
gpio_set(GPIO_LED6_B, Wb.LEDgroup5.LED678 & 0x1);
gpio_set(GPIO_LED7_B, Wb.LEDgroup5.LED678 & 0x2);
gpio_set(GPIO_LED8_B, Wb.LEDgroup5.LED678 & 0x4);
}
/**
* This function is called after a SDO write of the object Cb.Parameters.
*/
void cb_post_write_Parameters(int subindex)
{
}
/**
* This function is called after a SDO write of the object Cb.variableRW.
*/
void cb_post_write_variableRW(int subindex)
{
}
/** Optional: Hook called after state change for application specific
* actions for specific state changes.
*/
void pre_state_change_hook (uint8_t * as, uint8_t * an)
{
/* Clean up data if we have been in INIT state */
if ((*as == INIT_TO_PREOP) && (*an == ESCinit))
{
@ -123,50 +107,6 @@ void pre_state_change_hook (uint8_t * as, uint8_t * an)
}
}
/* Configuration parameters for EoE
* Function callbacks to interact with an TCP/IP stack
*/
static eoe_cfg_t eoe_config =
{
.get_buffer = appl_get_buffer,
.free_buffer = appl_free_buffer,
.load_eth_settings = appl_load_eth_settings,
.store_ethernet_settings = appl_store_ethernet_settings,
.handle_recv_buffer = appl_handle_recv_buffer,
.fetch_send_buffer = appl_fetch_send_buffer,
};
/* Configuration parameters for SOES
* SM and Mailbox parameters comes from the
* generated config.h
*/
static esc_cfg_t config =
{
.user_arg = NULL,
.use_interrupt = 1,
.watchdog_cnt = 1000,
.mbxsize = MBXSIZE,
.mbxsizeboot = MBXSIZEBOOT,
.mbxbuffers = MBXBUFFERS,
.mb[0] = {MBX0_sma, MBX0_sml, MBX0_sme, MBX0_smc, 0},
.mb[1] = {MBX1_sma, MBX1_sml, MBX1_sme, MBX1_smc, 0},
.mb_boot[0] = {MBX0_sma_b, MBX0_sml_b, MBX0_sme_b, MBX0_smc_b, 0},
.mb_boot[1] = {MBX1_sma_b, MBX1_sml_b, MBX1_sme_b, MBX1_smc_b, 0},
.pdosm[0] = {SM2_sma, 0, 0, SM2_smc, SM2_act},
.pdosm[1] = {SM3_sma, 0, 0, SM3_smc, SM3_act},
.pre_state_change_hook = pre_state_change_hook,
.post_state_change_hook = NULL,
.application_hook = NULL,
.safeoutput_override = NULL,
.pre_object_download_hook = NULL,
.post_object_download_hook = NULL,
.rxpdo_override = NULL,
.txpdo_override = NULL,
.esc_hw_interrupt_enable = ESC_interrupt_enable,
.esc_hw_interrupt_disable = ESC_interrupt_disable,
.esc_hw_eep_handler = ESC_eep_handler
};
/* Callback to allocate a buffer */
static void appl_get_buffer (eoe_pbuf_t * ebuf)
{
@ -281,7 +221,7 @@ static void appl_handle_recv_buffer (uint8_t port, eoe_pbuf_t * ebuf)
}
else
{
flags_set(ecat_events, EVENT_TX);
sem_signal(ecat_isr_sem);
}
}
/* Normal procedure to pass the Ethernet frame to lwIP to handle */
@ -332,7 +272,7 @@ static err_t transmit_frame (struct netif *netif, struct pbuf *p)
{
/* Create a pbuf ref to keep the buf alive until it is sent over EoE */
pbuf_ref(p);
flags_set(ecat_events, EVENT_TX);
sem_signal(ecat_isr_sem);
}
return ERR_OK;
}
@ -355,27 +295,54 @@ err_t eoe_netif_init (struct netif * netif)
return ERR_OK;
}
/* Periodic EtherCAT timer */
static void soes_timer (tmr_t * timer, void * arg)
/* Callback on fragment sent event, we trigger a stack cycle to handle mailbox traffic
* if we might have more fragements in queue.
*/
void eoe_frame_sent (void)
{
flags_t * ev = arg;
flags_set(ev, EVENT_PERIODIC);
sem_signal(ecat_isr_sem);
}
/* Main EtherCAT loop */
void main_run(void * arg)
int main (void)
{
uint32_t mask = EVENT_ISR | EVENT_TX | EVENT_PERIODIC;
uint32_t flags;
static esc_cfg_t config =
{
.user_arg = NULL,
.use_interrupt = 1,
.watchdog_cnt = INT32_MAX, /* Use HW SM watchdog instead */
.set_defaults_hook = NULL,
.pre_state_change_hook = NULL,
.post_state_change_hook = cb_state_change,
.application_hook = NULL,
.safeoutput_override = NULL,
.pre_object_download_hook = NULL,
.post_object_download_hook = NULL,
.rxpdo_override = NULL,
.txpdo_override = NULL,
.esc_hw_interrupt_enable = ESC_interrupt_enable,
.esc_hw_interrupt_disable = ESC_interrupt_disable,
.esc_hw_eep_handler = ESC_eep_handler,
.esc_check_dc_handler = NULL
};
/* Configuration parameters for EoE
* Function callbacks to interact with an TCP/IP stack
*/
static eoe_cfg_t eoe_config =
{
.get_buffer = appl_get_buffer,
.free_buffer = appl_free_buffer,
.load_eth_settings = appl_load_eth_settings,
.store_ethernet_settings = appl_store_ethernet_settings,
.handle_recv_buffer = appl_handle_recv_buffer,
.fetch_send_buffer = appl_fetch_send_buffer,
.fragment_sent_event = eoe_frame_sent,
};
/* Create an mailbox for interprocess communication between TCP/IP stack and
* EtherCAT stack.
*/
pbuf_mbox = mbox_create (10);
/* Create periodic events to run the EtherCAT stack and application */
ecat_events = flags_create (0);
ecat_timer = tmr_create (tick_from_ms (1), soes_timer, ecat_events, TMR_CYCL);
tmr_start (ecat_timer);
/* Set up dummy IF */
found_if = net_add_interface(eoe_netif_init);
if(found_if == NULL)
@ -384,55 +351,11 @@ void main_run(void * arg)
}
/* Init EoE */
EOE_config(&eoe_config);
EOE_init();
/* Init EtherCAT slave stack */
ecat_slv_init(&config);
for(;;)
{
if(config.use_interrupt != 0)
{
/* Wait for incoming event from application or EtherCAT stack */
flags_wait_any (ecat_events, mask, &flags);
/* Cyclic event */
if(flags & EVENT_PERIODIC)
{
DIG_process(DIG_PROCESS_WD_FLAG);
ecat_slv_poll();
ESC_eoeprocess_tx();
flags_clr(ecat_events, EVENT_PERIODIC);
}
/* Low prio interrupt from the ESC */
if(flags & EVENT_ISR)
{
ecat_slv_poll();
ESC_eoeprocess_tx();
flags_clr(ecat_events, EVENT_ISR);
ESC_interrupt_enable(ESCREG_ALEVENT_CONTROL | ESCREG_ALEVENT_SMCHANGE
| ESCREG_ALEVENT_SM0 | ESCREG_ALEVENT_SM1 | ESCREG_ALEVENT_EEP);
}
/* The TCP/IP stack have posted a TX job */
if(flags & EVENT_TX)
{
ESC_eoeprocess_tx();
flags_clr(ecat_events, EVENT_TX);
}
}
else
{
ecat_slv();
ESC_eoeprocess_tx();
}
}
}
rprintf ("Hello world\n");
ecat_slv_init (&config);
/* Start the main application loop */
int main(void)
{
rprintf("Hello Main\n");
task_spawn ("soes", main_run, 4, 2048, NULL);
/* The stack is run from interrupt and a worker thread in esc_hw.c */
return 0;
}

Binary file not shown.

View File

@ -1,99 +0,0 @@
#ifndef __SLAVE_H__
#define __SLAVE_H__
#include "utypes.h"
#include "esc.h"
/**
* This function gets input values and updates Rb.Button1
*/
void cb_get_Button1();
/**
* This function gets input values and updates Rb.Button2
*/
void cb_get_Button2();
/**
* This function sets output values according to Wb.LEDgroup1
*/
void cb_set_LEDgroup1();
/**
* This function sets output values according to Wb.LEDgroup2
*/
void cb_set_LEDgroup2();
/**
* This function sets output values according to Wb.LEDgroup3
*/
void cb_set_LEDgroup3();
/**
* This function sets output values according to Wb.LEDgroup4
*/
void cb_set_LEDgroup4();
/**
* This function sets output values according to Wb.LEDgroup5
*/
void cb_set_LEDgroup5();
/**
* This function is called after a SDO write of the object Cb.Parameters.
*/
void cb_post_write_Parameters(int subindex);
/**
* This function is called after a SDO write of the object Cb.variableRW.
*/
void cb_post_write_variableRW(int subindex);
#define DIG_PROCESS_INPUTS_FLAG 0x01
#define DIG_PROCESS_OUTPUTS_FLAG 0x02
#define DIG_PROCESS_WD_FLAG 0x04
#define DIG_PROCESS_APP_HOOK_FLAG 0x08
/** Implements the watch-dog counter to count if we should make a state change
* due to missing incoming SM2 events. Updates local I/O and run the application
* in the following order, call read EtherCAT outputs, execute user provided
* application hook and call write EtherCAT inputs.
*
* @param[in] flags = User input what to execute
*/
void DIG_process (uint8_t flags);
/**
* Handler for SM change, SM0/1, AL CONTROL and EEPROM events, the application
* control what interrupts that should be served and re-activated with
* event mask argument
*
* @param[in] event_mask = Event mask for interrupts to serve and re-activate
* after served
*/
void ecat_slv_worker (uint32_t event_mask);
/**
* ISR for SM0/1, EEPROM and AL CONTROL events in a SM/DC
* synchronization application
*/
CC_DEPRECATED void ecat_slv_isr (void);
/**
* Poll SM0/1, EEPROM and AL CONTROL events in a SM/DC synchronization
* application
*/
void ecat_slv_poll (void);
/**
* Poll all events in a free-run application
*/
void ecat_slv (void);
/**
* Initialize the slave stack
*
* @param[in] config = User input how to configure the stack
*/
void ecat_slv_init (esc_cfg_t * config);
#endif /* __SLAVE_H__ */

Binary file not shown.

View File

@ -0,0 +1,14 @@
#include <stddef.h>
#include "utypes.h"
#include "ecat_options.h"
#include "esc.h"
/* Global variables used by the stack */
uint8_t MBX[MBXBUFFERS * MAX(MBXSIZE,MBXSIZEBOOT)];
_MBXcontrol MBXcontrol[MBXBUFFERS];
_ESCvar ESCvar;
_SMmap SMmap2[MAX_MAPPINGS_SM2];
_SMmap SMmap3[MAX_MAPPINGS_SM3];
/* Application variables */
_Objects _Obj;

View File

@ -1,298 +1,421 @@
<?xml version="1.0" encoding="UTF-8"?>
<Slave id="evb9252_dig" productCode="1234">
<Name>lan9252</Name>
<Slave xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="com.rtlabs.emf.esx" fileVersion="2" id="slave30" productCode="0x3030">
<Name>slave30 product</Name>
<Vendor>
<Id>0x1337</Id>
<Name>rt-labs AB</Name>
<Name>rt-labs</Name>
</Vendor>
<Group>
<Type>lan9252_spi</Type>
<Name>lan9252</Name>
<Type>sdk test</Type>
<Name>sdk test</Name>
</Group>
<Fmmu>Outputs</Fmmu>
<Fmmu>Inputs</Fmmu>
<Fmmu>MBoxState</Fmmu>
<Sm ControlByte="0x26" DefaultSize="128" StartAddress="0x1000">MBoxOut</Sm>
<Sm ControlByte="0x22" DefaultSize="128" StartAddress="0x1080">MBoxIn</Sm>
<Sm ControlByte="0x24" DefaultSize="0" StartAddress="0x1100">Outputs</Sm>
<Sm ControlByte="0x64" DefaultSize="0" StartAddress="0x1100">Outputs</Sm>
<Sm ControlByte="0x20" DefaultSize="0" StartAddress="0x1180">Inputs</Sm>
<Mailbox CoE="true" FoE="true">
<Mailbox CoE="true" EoE="true">
<Bootstrap Length="128" Start="0x1000"/>
<Standard Length="128" Start="0x1000"/>
</Mailbox>
<Eeprom>
<ConfigData>8002000000000000</ConfigData>
<ConfigData>8006810600000000</ConfigData>
<BootStrap>0010800080108000</BootStrap>
</Eeprom>
<Dictionary>
<Item>
<Name>Device Type</Name>
<Index>0x1000</Index>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x01901389</DefaultValue>
</Item>
<Item Managed="true">
<Name>Device Name</Name>
<Index>0x1008</Index>
<DataType>VISIBLE_STRING</DataType>
<DefaultValue>evb9252_dig</DefaultValue>
</Item>
<Item>
<Name>Hardware Version</Name>
<Index>0x1009</Index>
<Name>Hardware Version</Name>
<DataType>VISIBLE_STRING</DataType>
<DefaultValue>1.0</DefaultValue>
<Length>4</Length>
</Item>
<Item>
<Name>Software Version</Name>
<Index>0x100A</Index>
<Name>Software Version</Name>
<DataType>VISIBLE_STRING</DataType>
<DefaultValue>1.0</DefaultValue>
<Length>4</Length>
</Item>
<Item Managed="true">
<Index>0x1000</Index>
<Name>Device Type</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x00001389</DefaultValue>
</Item>
<Item Managed="true">
<Index>0x1008</Index>
<Name>Device Name</Name>
<DataType>VISIBLE_STRING</DataType>
<DefaultValue>slave30</DefaultValue>
<Length>7</Length>
</Item>
<Item Managed="true">
<Name>Identity Object</Name>
<Index>0x1018</Index>
<Name>Identity Object</Name>
<DataType>RECORD</DataType>
<SubItem>
<Name>Number of Elements</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>4</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>Vendor ID</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x1337</DefaultValue>
</SubItem>
<SubItem>
<Index>0x02</Index>
<Name>Product Code</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>1234</DefaultValue>
<DefaultValue>0x3030</DefaultValue>
</SubItem>
<SubItem>
<Index>0x03</Index>
<Name>Revision Number</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0</DefaultValue>
</SubItem>
<SubItem>
<Index>0x04</Index>
<Name>Serial Number</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x00000000</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Name>LEDs</Name>
<Index>0x1600</Index>
<Name>LEDgroup0</Name>
<DataType>RECORD</DataType>
<SubItem>
<Name>Number of Elements</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>2</DefaultValue>
</SubItem>
<SubItem>
<Name>LED0</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x70000108</DefaultValue>
</SubItem>
<SubItem>
<Name>LED1</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x70000208</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Name>Buttons</Name>
<Index>0x1A00</Index>
<DataType>RECORD</DataType>
<SubItem>
<Name>Number of Elements</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>LED0</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x70000108</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Index>0x1601</Index>
<Name>LEDgroup1</Name>
<DataType>RECORD</DataType>
<SubItem>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>LED1</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x70010108</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Index>0x1A00</Index>
<Name>Buttons</Name>
<DataType>RECORD</DataType>
<SubItem>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>Button1</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x60000108</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Name>Sync Manager Communication Type</Name>
<Index>0x1C00</Index>
<Name>Sync Manager Communication Type</Name>
<DataType>ARRAY</DataType>
<SubItem>
<Name>Number of Elements</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>4</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>Communications Type SM0</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x02</Index>
<Name>Communications Type SM1</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>2</DefaultValue>
</SubItem>
<SubItem>
<Index>0x03</Index>
<Name>Communications Type SM2</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>3</DefaultValue>
</SubItem>
<SubItem>
<Index>0x04</Index>
<Name>Communications Type SM3</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>4</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Name>Sync Manager 2 PDO Assignment</Name>
<Index>0x1C12</Index>
<Name>Sync Manager 2 PDO Assignment</Name>
<DataType>ARRAY</DataType>
<SubItem>
<Name>Number of Elements</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
<DefaultValue>2</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>PDO Mapping</Name>
<DataType>UNSIGNED16</DataType>
<DefaultValue>0x1600</DefaultValue>
</SubItem>
<SubItem>
<Index>0x02</Index>
<Name>PDO Mapping</Name>
<DataType>UNSIGNED16</DataType>
<DefaultValue>0x1601</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Name>Sync Manager 3 PDO Assignment</Name>
<Index>0x1C13</Index>
<Name>Sync Manager 3 PDO Assignment</Name>
<DataType>ARRAY</DataType>
<SubItem>
<Name>Number of Elements</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>PDO Mapping</Name>
<DataType>UNSIGNED16</DataType>
<DefaultValue>0x1A00</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Name>Buttons</Name>
<Index>0x6000</Index>
<Name>Buttons</Name>
<DataType>RECORD</DataType>
<Variable>Buttons</Variable>
<VariableType>Input</VariableType>
<SubItem>
<Name>Number of Elements</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Access>RO</Access>
<Name>Button1</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>0</DefaultValue>
<Access>RO</Access>
<PdoMapping>TX</PdoMapping>
<Variable>Button1</Variable>
<VariableType>Input</VariableType>
</SubItem>
</Item>
<Item Managed="true">
<Name>LEDs</Name>
<Index>0x7000</Index>
<Name>LEDgroup0</Name>
<DataType>RECORD</DataType>
<Variable>LEDs</Variable>
<Variable>LEDgroup0</Variable>
<VariableType>Output</VariableType>
<SubItem>
<Name>Number of Elements</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>2</DefaultValue>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Access>RO</Access>
<Name>LED0</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>0</DefaultValue>
<Access>RO</Access>
<PdoMapping>RX</PdoMapping>
<Variable>LED0</Variable>
<VariableType>Output</VariableType>
</SubItem>
</Item>
<Item Managed="true">
<Index>0x7001</Index>
<Name>LEDgroup1</Name>
<DataType>RECORD</DataType>
<Variable>LEDgroup1</Variable>
<VariableType>Output</VariableType>
<SubItem>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Access>RO</Access>
<Name>LED1</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>0</DefaultValue>
<Access>RO</Access>
<PdoMapping>RX</PdoMapping>
<Variable>LED1</Variable>
<VariableType>Output</VariableType>
</SubItem>
</Item>
<Item Managed="true">
<Name>Parameters</Name>
<Index>0x8000</Index>
<Name>Parameters</Name>
<DataType>RECORD</DataType>
<Variable>Parameters</Variable>
<VariableType>Parameter</VariableType>
<SubItem>
<Name>Number of Elements</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Access>RO</Access>
<Name>Multiplier</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0</DefaultValue>
<Access>RW</Access>
<PdoMapping>TX_AND_RX</PdoMapping>
<Variable>Multiplier</Variable>
<VariableType>Parameter</VariableType>
</SubItem>
</Item>
<Item Managed="true">
<Index>0x8001</Index>
<Access>RO</Access>
<Name>variableRW</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0</DefaultValue>
<Variable>variableRW</Variable>
<VariableType>Parameter</VariableType>
</Item>
</Dictionary>
<RxPdo>
<Index>0x1600</Index>
<Container>LEDs</Container>
<Name>LEDs</Name>
<SmAssignment>
<Index>0x1C12</Index>
<Entry>
<Index>0x7000</Index>
<SubIndex>1</SubIndex>
<Variable>LED0</Variable>
<Index>0x01</Index>
<AssignedPdo>0x1600</AssignedPdo>
</Entry>
<Entry>
<Index>0x7000</Index>
<SubIndex>2</SubIndex>
<Index>0x02</Index>
<AssignedPdo>0x1601</AssignedPdo>
</Entry>
</SmAssignment>
<SmAssignment>
<Index>0x1C13</Index>
<Entry>
<Index>0x01</Index>
<AssignedPdo>0x1A00</AssignedPdo>
</Entry>
</SmAssignment>
<RxPdo>
<Index>0x1600</Index>
<Name>LEDgroup0</Name>
<Entry>
<Index>0x1</Index>
<MappedIndex>0x7000</MappedIndex>
<MappedSubIndex>0x01</MappedSubIndex>
<Variable>LED0</Variable>
</Entry>
</RxPdo>
<RxPdo>
<Index>0x1601</Index>
<Name>LEDgroup1</Name>
<Entry>
<Index>0x1</Index>
<MappedIndex>0x7001</MappedIndex>
<MappedSubIndex>0x01</MappedSubIndex>
<Variable>LED1</Variable>
</Entry>
</RxPdo>
<TxPdo>
<Index>0x1A00</Index>
<Container>Buttons</Container>
<Name>Buttons</Name>
<Entry>
<Index>0x6000</Index>
<SubIndex>1</SubIndex>
<Index>0x1</Index>
<MappedIndex>0x6000</MappedIndex>
<MappedSubIndex>0x01</MappedSubIndex>
<Variable>Button1</Variable>
</Entry>
</TxPdo>
<Input>
<Index>0x6000</Index>
<Name>Buttons</Name>
<Type>RECORD</Type>
<PdoMapping>TX</PdoMapping>
<ObjectType>RECORD</ObjectType>
<Member>
<Index>0x01</Index>
<Name>Button1</Name>
<Type>UNSIGNED8</Type>
<PdoMapping>TX</PdoMapping>
</Member>
</Input>
<Output>
<Name>LEDs</Name>
<Type>RECORD</Type>
<Index>0x7000</Index>
<Name>LEDgroup0</Name>
<PdoMapping>RX</PdoMapping>
<ObjectType>RECORD</ObjectType>
<Member>
<Index>0x01</Index>
<Name>LED0</Name>
<Type>UNSIGNED8</Type>
<PdoMapping>RX</PdoMapping>
</Member>
</Output>
<Output>
<Index>0x7001</Index>
<Name>LEDgroup1</Name>
<PdoMapping>RX</PdoMapping>
<ObjectType>RECORD</ObjectType>
<Member>
<Index>0x01</Index>
<Name>LED1</Name>
<Type>UNSIGNED8</Type>
<PdoMapping>RX</PdoMapping>
</Member>
</Output>
<Parameter>
<Index>0x8000</Index>
<Name>Parameters</Name>
<Type>RECORD</Type>
<PdoMapping>NONE</PdoMapping>
<ObjectType>RECORD</ObjectType>
<Member>
<Index>0x01</Index>
<Name>Multiplier</Name>
<Type>UNSIGNED32</Type>
<PdoMapping>TX_AND_RX</PdoMapping>
</Member>
</Parameter>
</Slave>
<Parameter>
<Index>0x8001</Index>
<Name>variableRW</Name>
<Type>UNSIGNED32</Type>
<PdoMapping>NONE</PdoMapping>
<ObjectType>VAR</ObjectType>
</Parameter>
</Slave>

View File

@ -2,23 +2,23 @@
<EtherCATInfo>
<Vendor>
<Id>#x1337</Id>
<Name LcId="1033">rt-labs AB</Name>
<Name LcId="1033">rt-labs</Name>
</Vendor>
<Descriptions>
<Groups>
<Group>
<Type>lan9252_spi</Type>
<Name LcId="1033">lan9252</Name>
<Type>sdk test</Type>
<Name LcId="1033">sdk test</Name>
</Group>
</Groups>
<Devices>
<Device Physics="YY">
<Type ProductCode="1234" RevisionNo="0">evb9252_dig</Type>
<Name LcId="1033">lan9252</Name>
<GroupType>lan9252_spi</GroupType>
<Type ProductCode="#x3030" RevisionNo="0">slave30</Type>
<Name LcId="1033">slave30 product</Name>
<GroupType>sdk test</GroupType>
<Profile>
<ProfileNo>5001</ProfileNo>
<AddInfo>400</AddInfo>
<AddInfo>0</AddInfo>
<Dictionary>
<DataTypes>
<DataType>
@ -26,7 +26,7 @@
<BitSize>144</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
@ -77,10 +77,10 @@
</DataType>
<DataType>
<Name>DT1600</Name>
<BitSize>80</BitSize>
<BitSize>48</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
@ -98,12 +98,26 @@
<Access>ro</Access>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>DT1601</Name>
<BitSize>48</BitSize>
<SubItem>
<SubIdx>2</SubIdx>
<SubIdx>0</SubIdx>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<SubIdx>1</SubIdx>
<Name>LED1</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<BitOffs>48</BitOffs>
<BitOffs>16</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
@ -114,7 +128,7 @@
<BitSize>48</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
@ -147,7 +161,7 @@
<BitSize>48</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
@ -168,18 +182,18 @@
<DataType>
<Name>DT1C12ARR</Name>
<BaseType>UINT</BaseType>
<BitSize>16</BitSize>
<BitSize>32</BitSize>
<ArrayInfo>
<LBound>1</LBound>
<Elements>1</Elements>
<Elements>2</Elements>
</ArrayInfo>
</DataType>
<DataType>
<Name>DT1C12</Name>
<BitSize>32</BitSize>
<BitSize>48</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
@ -190,7 +204,7 @@
<SubItem>
<Name>Elements</Name>
<Type>DT1C12ARR</Type>
<BitSize>16</BitSize>
<BitSize>32</BitSize>
<BitOffs>16</BitOffs>
<Flags>
<Access>ro</Access>
@ -211,7 +225,7 @@
<BitSize>32</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
@ -234,7 +248,7 @@
<BitSize>24</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
@ -250,15 +264,16 @@
<BitOffs>16</BitOffs>
<Flags>
<Access>ro</Access>
<PdoMapping>T</PdoMapping>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>DT7000</Name>
<BitSize>32</BitSize>
<BitSize>24</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
@ -272,18 +287,34 @@
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>16</BitOffs>
<Flags>
<Access>ro</Access>
<PdoMapping>R</PdoMapping>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>DT7001</Name>
<BitSize>24</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<SubIdx>2</SubIdx>
<SubIdx>1</SubIdx>
<Name>LED1</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>24</BitOffs>
<BitOffs>16</BitOffs>
<Flags>
<Access>ro</Access>
<PdoMapping>R</PdoMapping>
</Flags>
</SubItem>
</DataType>
@ -292,7 +323,7 @@
<BitSize>48</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
@ -307,17 +338,14 @@
<BitSize>32</BitSize>
<BitOffs>16</BitOffs>
<Flags>
<Access>rw</Access>
<Access>ro</Access>
<PdoMapping>TR</PdoMapping>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>STRING(3)</Name>
<BitSize>24</BitSize>
</DataType>
<DataType>
<Name>STRING(11)</Name>
<BitSize>88</BitSize>
<Name>STRING(4)</Name>
<BitSize>32</BitSize>
</DataType>
<DataType>
<Name>UDINT</Name>
@ -327,42 +355,21 @@
<Name>UINT</Name>
<BitSize>16</BitSize>
</DataType>
<DataType>
<Name>STRING(7)</Name>
<BitSize>56</BitSize>
</DataType>
<DataType>
<Name>USINT</Name>
<BitSize>8</BitSize>
</DataType>
</DataTypes>
<Objects>
<Object>
<Index>#x1000</Index>
<Name>Device Type</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<Info>
<DefaultValue>#x01901389</DefaultValue>
</Info>
<Flags>
<Access>ro</Access>
<Category>m</Category>
</Flags>
</Object>
<Object>
<Index>#x1008</Index>
<Name>Device Name</Name>
<Type>STRING(11)</Type>
<BitSize>88</BitSize>
<Info>
<DefaultString>evb9252_dig</DefaultString>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1009</Index>
<Name>Hardware Version</Name>
<Type>STRING(3)</Type>
<BitSize>24</BitSize>
<Type>STRING(4)</Type>
<BitSize>32</BitSize>
<Info>
<DefaultString>1.0</DefaultString>
</Info>
@ -374,8 +381,8 @@
<Object>
<Index>#x100A</Index>
<Name>Software Version</Name>
<Type>STRING(3)</Type>
<BitSize>24</BitSize>
<Type>STRING(4)</Type>
<BitSize>32</BitSize>
<Info>
<DefaultString>1.0</DefaultString>
</Info>
@ -383,6 +390,31 @@
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1000</Index>
<Name>Device Type</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<Info>
<DefaultValue>#x00001389</DefaultValue>
</Info>
<Flags>
<Access>ro</Access>
<Category>m</Category>
</Flags>
</Object>
<Object>
<Index>#x1008</Index>
<Name>Device Name</Name>
<Type>STRING(7)</Type>
<BitSize>56</BitSize>
<Info>
<DefaultString>slave30</DefaultString>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1018</Index>
<Name>Identity Object</Name>
@ -390,7 +422,7 @@
<BitSize>144</BitSize>
<Info>
<SubItem>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>4</DefaultValue>
</Info>
@ -404,7 +436,7 @@
<SubItem>
<Name>Product Code</Name>
<Info>
<DefaultValue>1234</DefaultValue>
<DefaultValue>#x3030</DefaultValue>
</Info>
</SubItem>
<SubItem>
@ -426,14 +458,14 @@
</Object>
<Object>
<Index>#x1600</Index>
<Name>LEDs</Name>
<Name>LEDgroup0</Name>
<Type>DT1600</Type>
<BitSize>80</BitSize>
<BitSize>48</BitSize>
<Info>
<SubItem>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>2</DefaultValue>
<DefaultValue>1</DefaultValue>
</Info>
</SubItem>
<SubItem>
@ -442,10 +474,27 @@
<DefaultValue>#x70000108</DefaultValue>
</Info>
</SubItem>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1601</Index>
<Name>LEDgroup1</Name>
<Type>DT1601</Type>
<BitSize>48</BitSize>
<Info>
<SubItem>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>LED1</Name>
<Info>
<DefaultValue>#x70000208</DefaultValue>
<DefaultValue>#x70010108</DefaultValue>
</Info>
</SubItem>
</Info>
@ -460,7 +509,7 @@
<BitSize>48</BitSize>
<Info>
<SubItem>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
@ -483,7 +532,7 @@
<BitSize>48</BitSize>
<Info>
<SubItem>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>4</DefaultValue>
</Info>
@ -521,12 +570,12 @@
<Index>#x1C12</Index>
<Name>Sync Manager 2 PDO Assignment</Name>
<Type>DT1C12</Type>
<BitSize>32</BitSize>
<BitSize>48</BitSize>
<Info>
<SubItem>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
<DefaultValue>2</DefaultValue>
</Info>
</SubItem>
<SubItem>
@ -535,6 +584,12 @@
<DefaultValue>#x1600</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>PDO Mapping</Name>
<Info>
<DefaultValue>#x1601</DefaultValue>
</Info>
</SubItem>
</Info>
<Flags>
<Access>ro</Access>
@ -547,7 +602,7 @@
<BitSize>32</BitSize>
<Info>
<SubItem>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
@ -570,7 +625,7 @@
<BitSize>24</BitSize>
<Info>
<SubItem>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
@ -588,14 +643,14 @@
</Object>
<Object>
<Index>#x7000</Index>
<Name>LEDs</Name>
<Name>LEDgroup0</Name>
<Type>DT7000</Type>
<BitSize>32</BitSize>
<BitSize>24</BitSize>
<Info>
<SubItem>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>2</DefaultValue>
<DefaultValue>1</DefaultValue>
</Info>
</SubItem>
<SubItem>
@ -604,6 +659,23 @@
<DefaultValue>0</DefaultValue>
</Info>
</SubItem>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x7001</Index>
<Name>LEDgroup1</Name>
<Type>DT7001</Type>
<BitSize>24</BitSize>
<Info>
<SubItem>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>LED1</Name>
<Info>
@ -622,7 +694,7 @@
<BitSize>48</BitSize>
<Info>
<SubItem>
<Name>Number of Elements</Name>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
@ -638,28 +710,45 @@
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x8001</Index>
<Name>variableRW</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<Info>
<DefaultValue>0</DefaultValue>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
</Objects>
</Dictionary>
</Profile>
<Fmmu>Outputs</Fmmu>
<Fmmu>Inputs</Fmmu>
<Fmmu>MBoxState</Fmmu>
<Sm ControlByte="#x26" DefaultSize="128" Enable="1" StartAddress="#x1000">MBoxOut</Sm>
<Sm ControlByte="#x22" DefaultSize="128" Enable="1" StartAddress="#x1080">MBoxIn</Sm>
<Sm ControlByte="#x24" Enable="1" StartAddress="#x1100">Outputs</Sm>
<Sm ControlByte="#x64" Enable="1" StartAddress="#x1100">Outputs</Sm>
<Sm ControlByte="#x20" Enable="1" StartAddress="#x1180">Inputs</Sm>
<RxPdo Fixed="true" Mandatory="true" Sm="2">
<Index>#x1600</Index>
<Name>LEDs</Name>
<Name>LEDgroup0</Name>
<Entry>
<Index>#x7000</Index>
<SubIndex>1</SubIndex>
<SubIndex>#x1</SubIndex>
<BitLen>8</BitLen>
<Name>LED0</Name>
<DataType>USINT</DataType>
</Entry>
</RxPdo>
<RxPdo Fixed="true" Mandatory="true" Sm="2">
<Index>#x1601</Index>
<Name>LEDgroup1</Name>
<Entry>
<Index>#x7000</Index>
<SubIndex>2</SubIndex>
<Index>#x7001</Index>
<SubIndex>#x1</SubIndex>
<BitLen>8</BitLen>
<Name>LED1</Name>
<DataType>USINT</DataType>
@ -670,19 +759,19 @@
<Name>Buttons</Name>
<Entry>
<Index>#x6000</Index>
<SubIndex>1</SubIndex>
<SubIndex>#x1</SubIndex>
<BitLen>8</BitLen>
<Name>Button1</Name>
<DataType>USINT</DataType>
</Entry>
</TxPdo>
<Mailbox DataLinkLayer="true">
<CoE CompleteAccess="false" PdoUpload="true" SdoInfo="true"/>
<FoE/>
<EoE/>
<CoE CompleteAccess="false" PdoAssign="false" PdoUpload="false" SdoInfo="true"/>
</Mailbox>
<Eeprom>
<ByteSize>256</ByteSize>
<ConfigData>8002000000000000</ConfigData>
<ConfigData>8006810600000000</ConfigData>
<BootStrap>0010800080108000</BootStrap>
</Eeprom>
</Device>

View File

@ -1,80 +1,94 @@
#include "soes/esc_coe.h"
#include "esc_coe.h"
#include "utypes.h"
#include <stddef.h>
static const char acName1000[] = "Device Type";
static const char acName1000_0[] = "Device Type";
static const char acName1008[] = "Device Name";
static const char acName1008_0[] = "Device Name";
#ifndef HW_REV
#define HW_REV "1.0"
#endif
#ifndef SW_REV
#define SW_REV "1.0"
#endif
static const char acName1009[] = "Hardware Version";
static const char acName1009_0[] = "Hardware Version";
static const char acName100A[] = "Software Version";
static const char acName100A_0[] = "Software Version";
static const char acName1000[] = "Device Type";
static const char acName1008[] = "Device Name";
static const char acName1018[] = "Identity Object";
static const char acName1018_00[] = "Number of Elements";
static const char acName1018_00[] = "Max SubIndex";
static const char acName1018_01[] = "Vendor ID";
static const char acName1018_02[] = "Product Code";
static const char acName1018_03[] = "Revision Number";
static const char acName1018_04[] = "Serial Number";
static const char acName1600[] = "LEDs";
static const char acName1600_00[] = "Number of Elements";
static const char acName1600[] = "LEDgroup0";
static const char acName1600_00[] = "Max SubIndex";
static const char acName1600_01[] = "LED0";
static const char acName1600_02[] = "LED1";
static const char acName1601[] = "LEDgroup1";
static const char acName1601_00[] = "Max SubIndex";
static const char acName1601_01[] = "LED1";
static const char acName1A00[] = "Buttons";
static const char acName1A00_00[] = "Number of Elements";
static const char acName1A00_00[] = "Max SubIndex";
static const char acName1A00_01[] = "Button1";
static const char acName1C00[] = "Sync Manager Communication Type";
static const char acName1C00_00[] = "Number of Elements";
static const char acName1C00_00[] = "Max SubIndex";
static const char acName1C00_01[] = "Communications Type SM0";
static const char acName1C00_02[] = "Communications Type SM1";
static const char acName1C00_03[] = "Communications Type SM2";
static const char acName1C00_04[] = "Communications Type SM3";
static const char acName1C12[] = "Sync Manager 2 PDO Assignment";
static const char acName1C12_00[] = "Number of Elements";
static const char acName1C12_00[] = "Max SubIndex";
static const char acName1C12_01[] = "PDO Mapping";
static const char acName1C12_02[] = "PDO Mapping";
static const char acName1C13[] = "Sync Manager 3 PDO Assignment";
static const char acName1C13_00[] = "Number of Elements";
static const char acName1C13_00[] = "Max SubIndex";
static const char acName1C13_01[] = "PDO Mapping";
static const char acName6000[] = "Buttons";
static const char acName6000_00[] = "Number of Elements";
static const char acName6000_00[] = "Max SubIndex";
static const char acName6000_01[] = "Button1";
static const char acName7000[] = "LEDs";
static const char acName7000_00[] = "Number of Elements";
static const char acName7000[] = "LEDgroup0";
static const char acName7000_00[] = "Max SubIndex";
static const char acName7000_01[] = "LED0";
static const char acName7000_02[] = "LED1";
static const char acName7001[] = "LEDgroup1";
static const char acName7001_00[] = "Max SubIndex";
static const char acName7001_01[] = "LED1";
static const char acName8000[] = "Parameters";
static const char acName8000_00[] = "Number of Elements";
static const char acName8000_00[] = "Max SubIndex";
static const char acName8000_01[] = "Multiplier";
static const char acName8001[] = "variableRW";
const _objd SDO1000[] =
{
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000_0, 0x01901389, NULL},
};
const _objd SDO1008[] =
{
{0x0, DTYPE_VISIBLE_STRING, 88, ATYPE_RO, acName1008_0, 0, "evb9252_dig"},
};
const _objd SDO1009[] =
{
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName1009_0, 0, "1.0"},
{0x0, DTYPE_VISIBLE_STRING, 32, ATYPE_RO, acName1009, 0, HW_REV},
};
const _objd SDO100A[] =
{
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName100A_0, 0, "1.0"},
{0x0, DTYPE_VISIBLE_STRING, 32, ATYPE_RO, acName100A, 0, SW_REV},
};
const _objd SDO1000[] =
{
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000, 0x00001389, NULL},
};
const _objd SDO1008[] =
{
{0x0, DTYPE_VISIBLE_STRING, 56, ATYPE_RO, acName1008, 0, "slave30"},
};
const _objd SDO1018[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1018_00, 4, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_01, 0x1337, NULL},
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_02, 1234, NULL},
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_02, 0x3030, NULL},
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_03, 0, NULL},
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_04, 0x00000000, NULL},
};
const _objd SDO1600[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1600_00, 2, NULL},
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1600_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_01, 0x70000108, NULL},
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_02, 0x70000208, NULL},
};
const _objd SDO1601[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1601_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1601_01, 0x70010108, NULL},
};
const _objd SDO1A00[] =
{
@ -91,8 +105,9 @@ const _objd SDO1C00[] =
};
const _objd SDO1C12[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C12_00, 1, NULL},
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C12_00, 2, NULL},
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C12_01, 0x1600, NULL},
{0x02, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C12_02, 0x1601, NULL},
};
const _objd SDO1C13[] =
{
@ -102,18 +117,26 @@ const _objd SDO1C13[] =
const _objd SDO6000[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6000_00, 1, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6000_01, 0, &Rb.Buttons.Button1},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO | ATYPE_TXPDO, acName6000_01, 0, &Obj.Buttons.Button1},
};
const _objd SDO7000[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_00, 2, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_01, 0, &Wb.LEDs.LED0},
{0x02, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_02, 0, &Wb.LEDs.LED1},
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_00, 1, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO | ATYPE_RXPDO, acName7000_01, 0, &Obj.LEDgroup0.LED0},
};
const _objd SDO7001[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7001_00, 1, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO | ATYPE_RXPDO, acName7001_01, 0, &Obj.LEDgroup1.LED1},
};
const _objd SDO8000[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName8000_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RW, acName8000_01, 0, &Cb.Parameters.Multiplier},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO | ATYPE_TXPDO | ATYPE_RXPDO, acName8000_01, 0, &Obj.Parameters.Multiplier},
};
const _objd SDO8001[] =
{
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName8001, 0, &Obj.variableRW},
};
const _objectlist SDOobjects[] =
@ -123,13 +146,16 @@ const _objectlist SDOobjects[] =
{0x1009, OTYPE_VAR, 0, 0, acName1009, SDO1009},
{0x100A, OTYPE_VAR, 0, 0, acName100A, SDO100A},
{0x1018, OTYPE_RECORD, 4, 0, acName1018, SDO1018},
{0x1600, OTYPE_RECORD, 2, 0, acName1600, SDO1600},
{0x1600, OTYPE_RECORD, 1, 0, acName1600, SDO1600},
{0x1601, OTYPE_RECORD, 1, 0, acName1601, SDO1601},
{0x1A00, OTYPE_RECORD, 1, 0, acName1A00, SDO1A00},
{0x1C00, OTYPE_ARRAY, 4, 0, acName1C00, SDO1C00},
{0x1C12, OTYPE_ARRAY, 1, 0, acName1C12, SDO1C12},
{0x1C12, OTYPE_ARRAY, 2, 0, acName1C12, SDO1C12},
{0x1C13, OTYPE_ARRAY, 1, 0, acName1C13, SDO1C13},
{0x6000, OTYPE_RECORD, 1, 0, acName6000, SDO6000},
{0x7000, OTYPE_RECORD, 2, 0, acName7000, SDO7000},
{0x7000, OTYPE_RECORD, 1, 0, acName7000, SDO7000},
{0x7001, OTYPE_RECORD, 1, 0, acName7001, SDO7001},
{0x8000, OTYPE_RECORD, 1, 0, acName8000, SDO8000},
{0x8001, OTYPE_VAR, 0, 0, acName8001, SDO8001},
{0xffff, 0xff, 0xff, 0xff, NULL, NULL}
};

View File

@ -1,310 +0,0 @@
#ifndef SOES_V1
#include "esc_coe.h"
#include "utypes.h"
#include <stddef.h>
#ifndef HW_REV
#define HW_REV "1.0"
#endif
#ifndef SW_REV
#define SW_REV "1.0"
#endif
static const char acName1000[] = "Device Type";
static const char acName1000_0[] = "Device Type";
static const char acName1008[] = "Device Name";
static const char acName1008_0[] = "Device Name";
static const char acName1009[] = "Hardware Version";
static const char acName1009_0[] = "Hardware Version";
static const char acName100A[] = "Software Version";
static const char acName100A_0[] = "Software Version";
static const char acName1018[] = "Identity Object";
static const char acName1018_00[] = "Max SubIndex";
static const char acName1018_01[] = "Vendor ID";
static const char acName1018_02[] = "Product Code";
static const char acName1018_03[] = "Revision Number";
static const char acName1018_04[] = "Serial Number";
static const char acName10F1[] = "ErrorSettings";
static const char acName10F1_00[] = "Max SubIndex";
static const char acName10F1_01[] = "Dummy_x01";
static const char acName10F1_02[] = "SyncErrorCounterLimit";
static const char acName1600[] = "LEDgroup1";
static const char acName1600_00[] = "Max SubIndex";
static const char acName1600_01[] = "LED";
static const char acName1601[] = "LEDgroup2";
static const char acName1601_00[] = "Max SubIndex";
static const char acName1601_01[] = "LED";
static const char acName1602[] = "LEDgroup3";
static const char acName1602_00[] = "Max SubIndex";
static const char acName1602_01[] = "LED";
static const char acName1603[] = "LEDgroup4";
static const char acName1603_00[] = "Max SubIndex";
static const char acName1603_01[] = "LED";
static const char acName1604[] = "LEDgroup5";
static const char acName1604_00[] = "Max SubIndex";
static const char acName1604_01[] = "LED5";
static const char acName1604_02[] = "LED678";
static const char acName1A00[] = "Button1";
static const char acName1A00_00[] = "Max SubIndex";
static const char acName1A00_01[] = "B";
static const char acName1A01[] = "Button2";
static const char acName1A01_00[] = "Max SubIndex";
static const char acName1A01_01[] = "B";
static const char acName1C00[] = "Sync Manager Communication Type";
static const char acName1C00_00[] = "Max SubIndex";
static const char acName1C00_01[] = "Communications Type SM0";
static const char acName1C00_02[] = "Communications Type SM1";
static const char acName1C00_03[] = "Communications Type SM2";
static const char acName1C00_04[] = "Communications Type SM3";
static const char acName1C12[] = "Sync Manager 2 PDO Assignment";
static const char acName1C12_00[] = "Max SubIndex";
static const char acName1C12_01[] = "PDO Mapping";
static const char acName1C12_02[] = "PDO Mapping";
static const char acName1C12_03[] = "PDO Mapping";
static const char acName1C12_04[] = "PDO Mapping";
static const char acName1C12_05[] = "PDO Mapping";
static const char acName1C13[] = "Sync Manager 3 PDO Assignment";
static const char acName1C13_00[] = "Max SubIndex";
static const char acName1C13_01[] = "PDO Mapping";
static const char acName1C13_02[] = "PDO Mapping";
static const char acName1C32[] = "SyncMgrParam";
static const char acName1C32_00[] = "Max SubIndex";
static const char acName1C32_01[] = "SyncType";
static const char acName1C32_02[] = "CycleTime";
static const char acName1C32_03[] = "ShiftTime";
static const char acName1C32_04[] = "SyncTypeSupport";
static const char acName1C32_05[] = "MinCycleTime";
static const char acName1C32_06[] = "CalcCopyTime";
static const char acName1C32_07[] = "MinDelayTime";
static const char acName1C32_08[] = "GetCycleTime";
static const char acName1C32_09[] = "DelayTime";
static const char acName1C32_0A[] = "Sync0CycleTime";
static const char acName1C32_0B[] = "SMEventMissedCnt";
static const char acName1C32_0C[] = "CycleTimeTooSmallCnt";
static const char acName1C32_0D[] = "ShiftTimeTooSmallCnt";
static const char acName1C32_0E[] = "RxPDOToggleFailed";
static const char acName1C32_0F[] = "MinCycleDist";
static const char acName1C32_10[] = "MaxCycleDist";
static const char acName1C32_11[] = "MinSMSYNCDist";
static const char acName1C32_12[] = "MaxSMSYNCDist";
static const char acName1C32_14[] = "Dummy_x14";
static const char acName1C32_20[] = "SyncError";
static const char acName6005[] = "Button1";
static const char acName6005_00[] = "Max SubIndex";
static const char acName6005_01[] = "B";
static const char acName6006[] = "Button2";
static const char acName6006_00[] = "Max SubIndex";
static const char acName6006_01[] = "B";
static const char acName7005[] = "LEDgroup1";
static const char acName7005_00[] = "Max SubIndex";
static const char acName7005_01[] = "LED";
static const char acName7006[] = "LEDgroup2";
static const char acName7006_00[] = "Max SubIndex";
static const char acName7006_01[] = "LED";
static const char acName7007[] = "LEDgroup3";
static const char acName7007_00[] = "Max SubIndex";
static const char acName7007_01[] = "LED";
static const char acName7008[] = "LEDgroup4";
static const char acName7008_00[] = "Max SubIndex";
static const char acName7008_01[] = "LED";
static const char acName7009[] = "LEDgroup5";
static const char acName7009_00[] = "Max SubIndex";
static const char acName7009_01[] = "LED5";
static const char acName7009_02[] = "LED678";
static const char acName8000[] = "Parameters";
static const char acName8000_00[] = "Max SubIndex";
static const char acName8000_01[] = "Multiplier";
static const char acName8001[] = "variableRW";
static const char acName8001_0[] = "variableRW";
const _objd SDO1000[] =
{
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000_0, 0x00001389, NULL},
};
const _objd SDO1008[] =
{
{0x0, DTYPE_VISIBLE_STRING, 88, ATYPE_RO, acName1008_0, 0, "xmc48_slave"},
};
const _objd SDO1009[] =
{
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName1009_0, 0, HW_REV},
};
const _objd SDO100A[] =
{
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName100A_0, 0, SW_REV},
};
const _objd SDO1018[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1018_00, 4, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_01, 0x1337, NULL},
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_02, 0x4800, NULL},
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_03, 0, NULL},
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_04, 0x00000000, NULL},
};
const _objd SDO10F1[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName10F1_00, 2, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName10F1_01, 0, &Mb.ErrorSettings.Dummy_x01},
{0x02, DTYPE_UNSIGNED16, 16, ATYPE_RW, acName10F1_02, 2, &Mb.ErrorSettings.SyncErrorCounterLimit},
};
const _objd SDO1600[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1600_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_01, 0x70050120, NULL},
};
const _objd SDO1601[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1601_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1601_01, 0x70060108, NULL},
};
const _objd SDO1602[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1602_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1602_01, 0x70070108, NULL},
};
const _objd SDO1603[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1603_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1603_01, 0x70080108, NULL},
};
const _objd SDO1604[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1604_00, 2, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1604_01, 0x70090108, NULL},
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1604_02, 0x70090208, NULL},
};
const _objd SDO1A00[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1A00_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_01, 0x60050108, NULL},
};
const _objd SDO1A01[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1A01_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A01_01, 0x60060120, NULL},
};
const _objd SDO1C00[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_00, 4, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_01, 1, NULL},
{0x02, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_02, 2, NULL},
{0x03, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_03, 3, NULL},
{0x04, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_04, 4, NULL},
};
const _objd SDO1C12[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C12_00, 5, NULL},
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C12_01, 0x1600, NULL},
{0x02, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C12_02, 0x1601, NULL},
{0x03, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C12_03, 0x1602, NULL},
{0x04, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C12_04, 0x1603, NULL},
{0x05, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C12_05, 0x1604, NULL},
};
const _objd SDO1C13[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C13_00, 2, NULL},
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C13_01, 0x1A00, NULL},
{0x02, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C13_02, 0x1A01, NULL},
};
const _objd SDO1C32[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C32_00, 32, NULL},
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_01, 1, &Mb.SyncMgrParam.SyncType},
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_02, 0, &Mb.SyncMgrParam.CycleTime},
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_03, 0, &Mb.SyncMgrParam.ShiftTime},
{0x04, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_04, 0x6, &Mb.SyncMgrParam.SyncTypeSupport},
{0x05, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_05, 125000, &Mb.SyncMgrParam.MinCycleTime},
{0x06, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_06, 0, &Mb.SyncMgrParam.CalcCopyTime},
{0x07, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_07, 0, &Mb.SyncMgrParam.MinDelayTime},
{0x08, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_08, 0, &Mb.SyncMgrParam.GetCycleTime},
{0x09, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_09, 0, &Mb.SyncMgrParam.DelayTime},
{0x0A, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_0A, 0, &Mb.SyncMgrParam.Sync0CycleTime},
{0x0B, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_0B, 0, &Mb.SyncMgrParam.SMEventMissedCnt},
{0x0C, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_0C, 0, &Mb.SyncMgrParam.CycleTimeTooSmallCnt},
{0x0D, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_0D, 0, &Mb.SyncMgrParam.ShiftTimeTooSmallCnt},
{0x0E, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_0E, 0, &Mb.SyncMgrParam.RxPDOToggleFailed},
{0x0F, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_0F, 0, &Mb.SyncMgrParam.MinCycleDist},
{0x10, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_10, 0, &Mb.SyncMgrParam.MaxCycleDist},
{0x11, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_11, 0, &Mb.SyncMgrParam.MinSMSYNCDist},
{0x12, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_12, 0, &Mb.SyncMgrParam.MaxSMSYNCDist},
{0x14, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C32_14, 0, &Mb.SyncMgrParam.Dummy_x14},
{0x20, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C32_20, 0, &Mb.SyncMgrParam.SyncError},
};
const _objd SDO6005[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6005_00, 1, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6005_01, 0, &Rb.Button1.B},
};
const _objd SDO6006[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6006_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName6006_01, 0, &Rb.Button2.B},
};
const _objd SDO7005[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7005_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName7005_01, 0, &Wb.LEDgroup1.LED},
};
const _objd SDO7006[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7006_00, 1, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7006_01, 0, &Wb.LEDgroup2.LED},
};
const _objd SDO7007[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7007_00, 1, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7007_01, 0, &Wb.LEDgroup3.LED},
};
const _objd SDO7008[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7008_00, 1, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7008_01, 0, &Wb.LEDgroup4.LED},
};
const _objd SDO7009[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7009_00, 2, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7009_01, 0, &Wb.LEDgroup5.LED5},
{0x02, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7009_02, 0, &Wb.LEDgroup5.LED678},
};
const _objd SDO8000[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName8000_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RW, acName8000_01, 0, &Cb.Parameters.Multiplier},
};
const _objd SDO8001[] =
{
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RW, acName8001_0, 0, &Cb.variableRW},
};
const _objectlist SDOobjects[] =
{
{0x1000, OTYPE_VAR, 0, 0, acName1000, SDO1000},
{0x1008, OTYPE_VAR, 0, 0, acName1008, SDO1008},
{0x1009, OTYPE_VAR, 0, 0, acName1009, SDO1009},
{0x100A, OTYPE_VAR, 0, 0, acName100A, SDO100A},
{0x1018, OTYPE_RECORD, 4, 0, acName1018, SDO1018},
{0x10F1, OTYPE_RECORD, 2, 0, acName10F1, SDO10F1},
{0x1600, OTYPE_RECORD, 1, 0, acName1600, SDO1600},
{0x1601, OTYPE_RECORD, 1, 0, acName1601, SDO1601},
{0x1602, OTYPE_RECORD, 1, 0, acName1602, SDO1602},
{0x1603, OTYPE_RECORD, 1, 0, acName1603, SDO1603},
{0x1604, OTYPE_RECORD, 2, 0, acName1604, SDO1604},
{0x1A00, OTYPE_RECORD, 1, 0, acName1A00, SDO1A00},
{0x1A01, OTYPE_RECORD, 1, 0, acName1A01, SDO1A01},
{0x1C00, OTYPE_ARRAY, 4, 0, acName1C00, SDO1C00},
{0x1C12, OTYPE_ARRAY, 5, 0, acName1C12, SDO1C12},
{0x1C13, OTYPE_ARRAY, 2, 0, acName1C13, SDO1C13},
{0x1C32, OTYPE_RECORD, 32, 0, acName1C32, SDO1C32},
{0x6005, OTYPE_RECORD, 1, 0, acName6005, SDO6005},
{0x6006, OTYPE_RECORD, 1, 0, acName6006, SDO6006},
{0x7005, OTYPE_RECORD, 1, 0, acName7005, SDO7005},
{0x7006, OTYPE_RECORD, 1, 0, acName7006, SDO7006},
{0x7007, OTYPE_RECORD, 1, 0, acName7007, SDO7007},
{0x7008, OTYPE_RECORD, 1, 0, acName7008, SDO7008},
{0x7009, OTYPE_RECORD, 2, 0, acName7009, SDO7009},
{0x8000, OTYPE_RECORD, 1, 0, acName8000, SDO8000},
{0x8001, OTYPE_VAR, 0, 0, acName8001, SDO8001},
{0xffff, 0xff, 0xff, 0xff, NULL, NULL}
};
#endif

View File

@ -1,121 +1,50 @@
#ifndef __UTYPES_H__
#define __UTYPES_H__
#include <cc.h>
#include "cc.h"
/* Object dictionary storage */
/* Inputs */
CC_PACKED_BEGIN
typedef struct
{
CC_PACKED_BEGIN
/* Inputs */
struct
{
uint8_t B;
} CC_PACKED Button1;
CC_PACKED_END
CC_PACKED_BEGIN
struct
{
uint32_t B;
} CC_PACKED Button2;
CC_PACKED_END
} CC_PACKED _Rbuffer;
CC_PACKED_END
uint8_t Button1;
} Buttons;
/* Outputs */
CC_PACKED_BEGIN
typedef struct
{
CC_PACKED_BEGIN
struct
{
uint32_t LED;
} CC_PACKED LEDgroup1;
CC_PACKED_END
CC_PACKED_BEGIN
struct
{
uint8_t LED;
} CC_PACKED LEDgroup2;
CC_PACKED_END
CC_PACKED_BEGIN
struct
{
uint8_t LED;
} CC_PACKED LEDgroup3;
CC_PACKED_END
CC_PACKED_BEGIN
struct
{
uint8_t LED;
} CC_PACKED LEDgroup4;
CC_PACKED_END
CC_PACKED_BEGIN
struct
{
uint8_t LED5;
uint8_t LED678;
} CC_PACKED LEDgroup5;
CC_PACKED_END
} CC_PACKED _Wbuffer;
CC_PACKED_END
/* Parameters */
CC_PACKED_BEGIN
typedef struct
{
CC_PACKED_BEGIN
/* Outputs */
struct
{
uint8_t LED0;
} LEDgroup0;
struct
{
uint8_t LED1;
} LEDgroup1;
/* Parameters */
struct
{
uint32_t Multiplier;
} CC_PACKED Parameters;
CC_PACKED_END
} Parameters;
uint32_t variableRW;
} CC_PACKED _Cbuffer;
CC_PACKED_END
/* Manufacturer specific data */
CC_PACKED_BEGIN
typedef struct
{
CC_PACKED_BEGIN
struct
{
uint16_t SyncType;
uint32_t CycleTime;
uint32_t ShiftTime;
uint16_t SyncTypeSupport;
uint32_t MinCycleTime;
uint32_t CalcCopyTime;
uint32_t MinDelayTime;
uint16_t GetCycleTime;
uint32_t DelayTime;
uint32_t Sync0CycleTime;
uint16_t SMEventMissedCnt;
uint16_t CycleTimeTooSmallCnt;
uint16_t ShiftTimeTooSmallCnt;
uint16_t RxPDOToggleFailed;
uint32_t MinCycleDist;
uint32_t MaxCycleDist;
uint32_t MinSMSYNCDist;
uint32_t MaxSMSYNCDist;
uint8_t Dummy_x14;
uint8_t SyncError;
} CC_PACKED SyncMgrParam;
CC_PACKED_END
CC_PACKED_BEGIN
struct
{
uint8_t Dummy_x01;
uint16_t SyncErrorCounterLimit;
} CC_PACKED ErrorSettings;
CC_PACKED_END
} CC_PACKED _Mbuffer;
CC_PACKED_END
/* Manufacturer specific data */
extern _Rbuffer Rb;
extern _Wbuffer Wb;
extern _Cbuffer Cb;
extern _Mbuffer Mb;
/* Dynamic TX PDO:s */
/* Dynamic RX PDO:s */
/* Sync Managers */
} _Objects;
extern _Objects Obj;
#endif /* __UTYPES_H__ */

View File

@ -1,6 +1,5 @@
add_executable (rtl_slavedemo
soes.c
objectlist.c
led_handler.c
bootstrap.c

View File

@ -46,7 +46,7 @@ void boot_inithook (void)
}
}
uint32_t flash_foe_buffer (foe_writefile_cfg_t * self, uint8_t * data)
uint32_t flash_foe_buffer (foe_writefile_cfg_t * self, uint8_t * data, size_t length)
{
uint32_t flash_cmd_failed = 0;
uint32_t calculated_address = self->dest_start_address + self->address_offset;
@ -118,7 +118,6 @@ void bootstrap_foe_init (void)
{
.buffer_size = FLASH_WRITE_BLOCK_SIZE, /* Buffer size before we flush to destination */
.fbuffer = (uint8_t *)&fbuf,
.empty_write = 0xFF,
.n_files = NELEMENTS (files),
.files = files
};

View File

@ -0,0 +1,44 @@
#ifndef __ECAT_OPTIONS_H__
#define __ECAT_OPTIONS_H__
#include "cc.h"
#define USE_FOE 1
#define USE_EOE 0
#define MBXSIZE 128
#define MBXSIZEBOOT 128
#define MBXBUFFERS 3
#define MBX0_sma 0x1000
#define MBX0_sml MBXSIZE
#define MBX0_sme MBX0_sma+MBX0_sml-1
#define MBX0_smc 0x26
#define MBX1_sma MBX0_sma+MBX0_sml
#define MBX1_sml MBXSIZE
#define MBX1_sme MBX1_sma+MBX1_sml-1
#define MBX1_smc 0x22
#define MBX0_sma_b 0x1000
#define MBX0_sml_b MBXSIZEBOOT
#define MBX0_sme_b MBX0_sma_b+MBX0_sml_b-1
#define MBX0_smc_b 0x26
#define MBX1_sma_b MBX0_sma_b+MBX0_sml_b
#define MBX1_sml_b MBXSIZEBOOT
#define MBX1_sme_b MBX1_sma_b+MBX1_sml_b-1
#define MBX1_smc_b 0x22
#define SM2_sma 0x1100
#define SM2_smc 0x24
#define SM2_act 1
#define SM3_sma 0x1180
#define SM3_smc 0x20
#define SM3_act 1
#define MAX_RXPDO_SIZE 42
#define MAX_TXPDO_SIZE 42
#define MAX_MAPPINGS_SM2 1
#define MAX_MAPPINGS_SM3 2
#endif /* __ECAT_OPTIONS_H__ */

View File

@ -4,8 +4,128 @@
*/
#include <kern.h>
#include "ecat_slv.h"
#include "utypes.h"
#include "bsp.h"
#include "bootstrap.h"
int main(void)
/* Application variables */
_Rbuffer Rb;
_Wbuffer Wb;
_Cbuffer Cb;
uint32_t encoder_scale;
uint32_t encoder_scale_mirror;
void cb_get_inputs (void)
{
Rb.button = gpio_get(GPIO_BUTTON_SW1);
//Rb.button = (flash_drv_get_active_swap() && 0x8);
Cb.reset_counter++;
Rb.encoder = Cb.reset_counter;
}
void cb_set_outputs (void)
{
gpio_set(GPIO_LED_BLUE, Wb.LED & BIT(0));
}
/** Optional: Hook called after state change for application specific
* actions for specific state changes.
*/
void post_state_change_hook (uint8_t * as, uint8_t * an)
{
/* Add specific step change hooks here */
if ((*as == BOOT_TO_INIT) && (*an == ESCinit))
{
boot_inithook ();
}
else if((*as == INIT_TO_BOOT) && (*an & ESCerror ) == 0)
{
init_boothook ();
}
}
void post_object_download_hook (uint16_t index, uint8_t subindex,
uint16_t flags)
{
switch(index)
{
case 0x7100:
{
switch (subindex)
{
case 0x01:
{
encoder_scale_mirror = encoder_scale;
break;
}
}
break;
}
case 0x8001:
{
switch (subindex)
{
case 0x01:
{
Cb.reset_counter = 0;
break;
}
}
break;
}
}
}
void soes (void * arg)
{
/* Setup config hooks */
static esc_cfg_t config =
{
.user_arg = "/spi0/et1100",
.use_interrupt = 0,
.set_defaults_hook = NULL,
.watchdog_cnt = 1000,
.pre_state_change_hook = NULL,
.post_state_change_hook = post_state_change_hook,
.application_hook = NULL,
.safeoutput_override = NULL,
.pre_object_download_hook = NULL,
.post_object_download_hook = NULL,
.rxpdo_override = NULL,
.txpdo_override = NULL,
.esc_hw_interrupt_enable = NULL,
.esc_hw_interrupt_disable = NULL,
.esc_hw_eep_handler = NULL
};
ecat_slv_init (&config);
while (1)
{
ecat_slv();
}
}
uint8_t load1s, load5s, load10s;
void my_cyclic_callback (void * arg)
{
while (1)
{
task_delay(tick_from_ms (20000));
stats_get_load (&load1s, &load5s, &load10s);
DPRINT ("%d:%d:%d (1s:5s:10s)\n",
load1s, load5s, load10s);
DPRINT ("Local bootstate: %d App.state: %d\n", local_boot_state,App.state);
DPRINT ("AlStatus : 0x%x, AlError : 0x%x, Watchdog : %d \n", (ESCvar.ALstatus & 0x001f),ESCvar.ALerror,wd_cnt);
}
}
int main (void)
{
extern void led_run (void *arg);
extern void led_error (void *arg);

View File

@ -1,351 +0,0 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
/** \file
* \brief
* The application.
*
* The application, the main loop that service EtherCAT.
*/
#include <kern.h>
#include <flash_drv.h>
#include <esc.h>
#include <esc_coe.h>
#include <esc_foe.h>
#include "utypes.h"
#include "config.h"
#include "bootstrap.h"
#define WD_RESET 1000
#define DEFAULTTXPDOMAP 0x1a00
#define DEFAULTRXPDOMAP 0x1600
#define DEFAULTTXPDOITEMS 1
#define DEFAULTRXPDOITEMS 1
uint32_t encoder_scale;
uint32_t encoder_scale_mirror;
/* Global variables used by the stack */
uint8_t MBX[MBXBUFFERS * MAX(MBXSIZE,MBXSIZEBOOT)];
_MBXcontrol MBXcontrol[MBXBUFFERS];
_ESCvar ESCvar;
/* Application variables */
_Rbuffer Rb;
_Wbuffer Wb;
_Cbuffer Cb;
/* Private variables */
int wd_cnt = WD_RESET;
volatile uint8_t digoutput;
volatile uint8_t diginput;
uint16_t txpdomap = DEFAULTTXPDOMAP;
uint16_t rxpdomap = DEFAULTRXPDOMAP;
uint8_t txpdoitems = DEFAULTTXPDOITEMS;
uint8_t rxpdoitems = DEFAULTTXPDOITEMS;
extern uint32_t local_boot_state;
/** Function to pre-qualify the incoming SDO download.
*
* @param[in] index = index of SDO download request to check
* @param[in] sub-index = sub-index of SDO download request to check
* @return 1 if the SDO Download is correct. 0 If not correct.
*/
int ESC_pre_objecthandler (uint16_t index, uint8_t subindex)
{
if ((index == 0x1c12) && (subindex > 0) && (rxpdoitems != 0))
{
SDO_abort (index, subindex, ABORT_READONLY);
return 0;
}
if ((index == 0x1c13) && (subindex > 0) && (txpdoitems != 0))
{
SDO_abort (index, subindex, ABORT_READONLY);
return 0;
}
return 1;
}
/** Mandatory: Hook called from the slave stack SDO Download handler to act on
* user specified Index and Sub-index.
*
* @param[in] index = index of SDO download request to handle
* @param[in] sub-index = sub-index of SDO download request to handle
*/
void ESC_objecthandler (uint16_t index, uint8_t subindex)
{
switch (index)
{
case 0x1c12:
{
if (rxpdoitems > 1)
{
rxpdoitems = 1;
}
if ((rxpdomap != 0x1600) && (rxpdomap != 0x1601)
&& (rxpdomap != 0x0000))
{
rxpdomap = 0x1600;
}
ESCvar.RXPDOsize = ESCvar.ESC_SM2_sml = sizeOfPDO(RX_PDO_OBJIDX);
break;
}
case 0x1c13:
{
if (txpdoitems > 1)
{
txpdoitems = 1;
}
if ((txpdomap != 0x1A00) && (txpdomap != 0x1A01)
&& (rxpdomap != 0x0000))
{
txpdomap = 0x1A00;
}
ESCvar.TXPDOsize = ESCvar.ESC_SM3_sml = sizeOfPDO(TX_PDO_OBJIDX);
break;
}
case 0x7100:
{
switch (subindex)
{
case 0x01:
{
encoder_scale_mirror = encoder_scale;
break;
}
}
break;
}
case 0x8001:
{
switch (subindex)
{
case 0x01:
{
Cb.reset_counter = 0;
break;
}
}
break;
}
}
}
/** Mandatory: Hook called from the slave stack ESC_stopoutputs to act on state changes
* forcing us to stop outputs. Here we can set them to a safe state.
* set
*/
void APP_safeoutput (void)
{
DPRINT ("APP_safeoutput called\n");
Wb.LED = 0;
}
/** Mandatory: Write local process data to Sync Manager 3, Master Inputs.
*/
void TXPDO_update (void)
{
ESC_write (SM3_sma, &Rb.button, ESCvar.TXPDOsize);
}
/** Mandatory: Read Sync Manager 2 to local process data, Master Outputs.
*/
void RXPDO_update (void)
{
ESC_read (SM2_sma, &Wb.LED, ESCvar.RXPDOsize);
}
/** Mandatory: Function to update local I/O, call read ethercat outputs, call
* write ethercat inputs. Implement watch-dog counter to count-out if we have
* made state change affecting the App.state.
*/
void DIG_process (void)
{
if (wd_cnt)
{
wd_cnt--;
}
if (ESCvar.App.state & APPSTATE_OUTPUT)
{
/* SM2 trigger ? */
if (ESCvar.ALevent & ESCREG_ALEVENT_SM2)
{
ESCvar.ALevent &= ~ESCREG_ALEVENT_SM2;
RXPDO_update ();
wd_cnt = WD_RESET;
/* dummy output point */
//gpio_set(GPIO_LED, Wb.LED & BIT(0));
}
if (!wd_cnt)
{
DPRINT("DIG_process watchdog tripped\n");
ESC_stopoutput ();
/* watchdog, invalid outputs */
ESC_ALerror (ALERR_WATCHDOG);
/* goto safe-op with error bit set */
ESC_ALstatus (ESCsafeop | ESCerror);
}
}
else
{
wd_cnt = WD_RESET;
}
if (ESCvar.App.state)
{
//Rb.button = gpio_get(GPIO_WAKEUP);
Rb.button = (flash_drv_get_active_swap() && 0x8);
Cb.reset_counter++;
Rb.encoder = Cb.reset_counter;
TXPDO_update ();
}
}
/** Optional: Hook called after state change for application specific
* actions for specific state changes.
*/
void post_state_change_hook (uint8_t * as, uint8_t * an)
{
/* Add specific step change hooks here */
if ((*as == BOOT_TO_INIT) && (*an == ESCinit))
{
boot_inithook ();
}
else if((*as == INIT_TO_BOOT) && (*an & ESCerror ) == 0)
{
init_boothook ();
}
}
/** SOES main loop. Start by initializing the stack software followed by
* the application loop for cyclic read the EtherCAT state and staus, update
* of I/O.
*/
void soes (void *arg)
{
DPRINT ("SOES (Simple Open EtherCAT Slave)\n");
ESCvar.TXPDOsize = ESCvar.ESC_SM3_sml = sizeOfPDO(TX_PDO_OBJIDX);
ESCvar.RXPDOsize = ESCvar.ESC_SM2_sml = sizeOfPDO(RX_PDO_OBJIDX);
/* Setup config hooks */
static esc_cfg_t config =
{
.user_arg = "/spi0/et1100",
.use_interrupt = 0,
.watchdog_cnt = 0,
.mbxsize = MBXSIZE,
.mbxsizeboot = MBXSIZEBOOT,
.mbxbuffers = MBXBUFFERS,
.mb[0] = {MBX0_sma, MBX0_sml, MBX0_sme, MBX0_smc, 0},
.mb[1] = {MBX1_sma, MBX1_sml, MBX1_sme, MBX1_smc, 0},
.mb_boot[0] = {MBX0_sma_b, MBX0_sml_b, MBX0_sme_b, MBX0_smc_b, 0},
.mb_boot[1] = {MBX1_sma_b, MBX1_sml_b, MBX1_sme_b, MBX1_smc_b, 0},
.pdosm[0] = {SM2_sma, 0, 0, SM2_smc, SM2_act},
.pdosm[1] = {SM3_sma, 0, 0, SM3_smc, SM3_act},
.pre_state_change_hook = NULL,
.post_state_change_hook = NULL,
.application_hook = NULL,
.safeoutput_override = NULL,
.pre_object_download_hook = NULL,
.post_object_download_hook = NULL,
.rxpdo_override = NULL,
.txpdo_override = NULL,
.esc_hw_interrupt_enable = NULL,
.esc_hw_interrupt_disable = NULL,
.esc_hw_eep_handler = NULL
};
ESC_config (&config);
ESC_init (&config);
task_delay (tick_from_ms (200));
/* wait until ESC is started up */
while ((ESCvar.DLstatus & 0x0001) == 0)
{
ESC_read (ESCREG_DLSTATUS, (void *) &ESCvar.DLstatus,
sizeof (ESCvar.DLstatus));
ESCvar.DLstatus = etohs (ESCvar.DLstatus);
}
/* Pre FoE to set up Application information */
bootstrap_foe_init ();
/* Init FoE */
FOE_init();
/* reset ESC to init state */
ESC_ALstatus (ESCinit);
ESC_ALerror (ALERR_NONE);
ESC_stopmbx ();
ESC_stopinput ();
ESC_stopoutput ();
DPRINT ("Application_loop GO\n");
/* application run loop */
while (1)
{
/* On init restore PDO mappings to default size */
if((ESCvar.ALstatus & 0x0f) == ESCinit)
{
txpdomap = DEFAULTTXPDOMAP;
rxpdomap = DEFAULTRXPDOMAP;
txpdoitems = DEFAULTTXPDOITEMS;
rxpdoitems = DEFAULTTXPDOITEMS;
}
/* Read local time from ESC*/
ESC_read (ESCREG_LOCALTIME, (void *) &ESCvar.Time, sizeof (ESCvar.Time));
ESCvar.Time = etohl (ESCvar.Time);
/* Check the state machine */
ESC_state ();
/* If else to two separate execution paths
* If we're running BOOSTRAP
* - MailBox
* - FoE
* Else we're running normal execution
* - MailBox
* - CoE
*/
if(local_boot_state)
{
if (ESC_mbxprocess ())
{
ESC_foeprocess ();
ESC_xoeprocess ();
}
bootstrap_state ();
}
else
{
if (ESC_mbxprocess ())
{
ESC_coeprocess ();
ESC_xoeprocess ();
}
DIG_process ();
}
};
}
uint8_t load1s, load5s, load10s;
void my_cyclic_callback (void * arg)
{
while (1)
{
task_delay(tick_from_ms (20000));
stats_get_load (&load1s, &load5s, &load10s);
DPRINT ("%d:%d:%d (1s:5s:10s)\n",
load1s, load5s, load10s);
DPRINT ("Local bootstate: %d App.state: %d\n", local_boot_state,App.state);
DPRINT ("AlStatus : 0x%x, AlError : 0x%x, Watchdog : %d \n", (ESCvar.ALstatus & 0x001f),ESCvar.ALerror,wd_cnt);
}
}

View File

@ -18,7 +18,6 @@
typedef struct
{
uint8_t state;
uint8_t button;
uint32_t encoder;
} _Rbuffer;

View File

@ -0,0 +1,14 @@
add_custom_command (
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/sii_eeprom.o
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/sii_eeprom.bin
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND arm-eabi-objcopy -I binary -O elf32-littlearm -B arm sii_eeprom.bin ${CMAKE_CURRENT_BINARY_DIR}/sii_eeprom.o
)
add_executable (demo
slave_objectlist.c
main.c
${CMAKE_CURRENT_BINARY_DIR}/sii_eeprom.o
)
target_link_libraries(demo LINK_PUBLIC soes)

View File

@ -0,0 +1,42 @@
#ifndef __ECAT_OPTIONS_H__
#define __ECAT_OPTIONS_H__
#define USE_FOE 0
#define USE_EOE 0
#define MBXSIZE 512
#define MBXSIZEBOOT 512
#define MBXBUFFERS 3
#define MBX0_sma 0x1000
#define MBX0_sml MBXSIZE
#define MBX0_sme MBX0_sma+MBX0_sml-1
#define MBX0_smc 0x26
#define MBX1_sma MBX0_sma+MBX0_sml
#define MBX1_sml MBXSIZE
#define MBX1_sme MBX1_sma+MBX1_sml-1
#define MBX1_smc 0x22
#define MBX0_sma_b 0x1000
#define MBX0_sml_b MBXSIZEBOOT
#define MBX0_sme_b MBX0_sma_b+MBX0_sml_b-1
#define MBX0_smc_b 0x26
#define MBX1_sma_b MBX0_sma_b+MBX0_sml_b
#define MBX1_sml_b MBXSIZEBOOT
#define MBX1_sme_b MBX1_sma_b+MBX1_sml_b-1
#define MBX1_smc_b 0x22
#define SM2_sma 0x1400
#define SM2_smc 0x64
#define SM2_act 1
#define SM3_sma 0x1A00
#define SM3_smc 0x20
#define SM3_act 1
#define MAX_MAPPINGS_SM2 10
#define MAX_MAPPINGS_SM3 9
#define MAX_RXPDO_SIZE 512
#define MAX_TXPDO_SIZE 512
#endif /* __ECAT_OPTIONS_H__ */

View File

@ -0,0 +1,86 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
#include <kern.h>
#include "esc.h"
#include "esc_hw.h"
#include "ecat_slv.h"
#include "options.h"
#include "utypes.h"
#include "bsp.h"
/* Application variables */
_Objects Obj;
/*
* This function is called to get input values
*/
void cb_get_inputs()
{
Obj.Buttons.Button1 = gpio_get (GPIO_BUTTON1);
}
/*
* This function is called to set output values
*/
void cb_set_outputs()
{
gpio_set (GPIO_LED1, Obj.LEDgroup0.LED0);
gpio_set (GPIO_LED2, Obj.LEDgroup1.LED1);
}
void cb_state_change (uint8_t * as, uint8_t * an)
{
if (*as == SAFEOP_TO_OP)
{
/* Enable watchdog interrupt */
ESC_ALeventmaskwrite (ESC_ALeventmaskread() | ESCREG_ALEVENT_WD);
}
else if (*as == PREOP_TO_SAFEOP)
{
/* Write initial input data requried if an input only slave,
* otherwise the SM3 will never occur.
*/
DIG_process (DIG_PROCESS_INPUTS_FLAG);
}
}
/* Setup of DC */
uint16_t dc_checker (void)
{
/* Indicate we run DC */
ESCvar.dcsync = 1;
/* Fetch the sync counter limit (SDO10F1) */
ESCvar.synccounterlimit = Obj.ErrorSettings.SyncErrorCounterLimit;
return 0;
}
int main (void)
{
static esc_cfg_t config =
{
.user_arg = NULL,
.use_interrupt = 1,
.watchdog_cnt = INT32_MAX, /* Use HW SM watchdog instead */
.set_defaults_hook = NULL,
.pre_state_change_hook = NULL,
.post_state_change_hook = cb_state_change,
.application_hook = NULL,
.safeoutput_override = NULL,
.pre_object_download_hook = NULL,
.post_object_download_hook = NULL,
.rxpdo_override = NULL,
.txpdo_override = NULL,
.esc_hw_interrupt_enable = ESC_interrupt_enable,
.esc_hw_interrupt_disable = ESC_interrupt_disable,
.esc_hw_eep_handler = ESC_eep_handler,
.esc_check_dc_handler = dc_checker
.get_device_id = NULL
};
rprintf ("Hello world\n");
ecat_slv_init (&config);
return 0;
}

Binary file not shown.

View File

@ -0,0 +1,289 @@
#include "esc_coe.h"
#include "utypes.h"
#include <stddef.h>
#ifndef HW_REV
#define HW_REV "1.0"
#endif
#ifndef SW_REV
#define SW_REV "1.0"
#endif
static const char acName1000[] = "Device Type";
static const char acName1008[] = "Device Name";
static const char acName1009[] = "Hardware Version";
static const char acName100A[] = "Software Version";
static const char acName1018[] = "Identity Object";
static const char acName1018_00[] = "Max SubIndex";
static const char acName1018_01[] = "Vendor ID";
static const char acName1018_02[] = "Product Code";
static const char acName1018_03[] = "Revision Number";
static const char acName1018_04[] = "Serial Number";
static const char acName10F1[] = "ErrorSettings";
static const char acName10F1_00[] = "Max SubIndex";
static const char acName10F1_01[] = "Local Error Reaction";
static const char acName10F1_02[] = "SyncErrorCounterLimit";
static const char acName1600[] = "RXPDO 1";
static const char acName1600_00[] = "Max SubIndex";
static const char acName1600_01[] = "LED0";
static const char acName1601[] = "RXPDO 2";
static const char acName1601_00[] = "Max SubIndex";
static const char acName1601_01[] = "LED1";
static const char acName1602[] = "RXPDO 3";
static const char acName1602_00[] = "Max SubIndex";
static const char acName1602_01[] = "PDO Entry 1602:01";
static const char acName1602_02[] = "PDO Entry 1602:02";
static const char acName1602_03[] = "PDO Entry 1602:03";
static const char acName1602_04[] = "PDO Entry 1602:04";
static const char acName1602_05[] = "PDO Entry 1602:05";
static const char acName1602_06[] = "PDO Entry 1602:06";
static const char acName1602_07[] = "PDO Entry 1602:07";
static const char acName1602_08[] = "PDO Entry 1602:08";
static const char acName1A00[] = "TXPDO 1";
static const char acName1A00_00[] = "Max SubIndex";
static const char acName1A00_01[] = "Button1";
static const char acName1A01[] = "TXPDO 2";
static const char acName1A01_00[] = "Max SubIndex";
static const char acName1A01_01[] = "PDO Entry 1A01:01";
static const char acName1A01_02[] = "PDO Entry 1A01:02";
static const char acName1A01_03[] = "PDO Entry 1A01:03";
static const char acName1A01_04[] = "PDO Entry 1A01:04";
static const char acName1A01_05[] = "PDO Entry 1A01:05";
static const char acName1A01_06[] = "PDO Entry 1A01:06";
static const char acName1A01_07[] = "PDO Entry 1A01:07";
static const char acName1A01_08[] = "PDO Entry 1A01:08";
static const char acName1C00[] = "Sync Manager Communication Type";
static const char acName1C00_00[] = "Max SubIndex";
static const char acName1C00_01[] = "Communications Type SM0";
static const char acName1C00_02[] = "Communications Type SM1";
static const char acName1C00_03[] = "Communications Type SM2";
static const char acName1C00_04[] = "Communications Type SM3";
static const char acName1C12[] = "Sync Manager 2 PDO Assignment";
static const char acName1C12_00[] = "Max SubIndex";
static const char acName1C12_01[] = "PDO Mapping";
static const char acName1C12_02[] = "PDO Mapping";
static const char acName1C12_03[] = "SM Entry 1C12:03";
static const char acName1C12_04[] = "SM Entry 1C12:04";
static const char acName1C12_05[] = "SM Entry 1C12:05";
static const char acName1C12_06[] = "SM Entry 1C12:06";
static const char acName1C12_07[] = "SM Entry 1C12:07";
static const char acName1C12_08[] = "SM Entry 1C12:08";
static const char acName1C13[] = "Sync Manager 3 PDO Assignment";
static const char acName1C13_00[] = "Max SubIndex";
static const char acName1C13_01[] = "PDO Mapping";
static const char acName1C13_02[] = "SM Entry 1C13:02";
static const char acName1C13_03[] = "SM Entry 1C13:03";
static const char acName1C13_04[] = "SM Entry 1C13:04";
static const char acName1C13_05[] = "SM Entry 1C13:05";
static const char acName1C13_06[] = "SM Entry 1C13:06";
static const char acName1C13_07[] = "SM Entry 1C13:07";
static const char acName1C13_08[] = "SM Entry 1C13:08";
static const char acName1C32[] = "SyncMgrParam";
static const char acName1C32_00[] = "Max SubIndex";
static const char acName1C32_01[] = "Sync mode";
static const char acName1C32_02[] = "CycleTime";
static const char acName1C32_03[] = "ShiftTime";
static const char acName1C32_04[] = "Sync modes supported";
static const char acName1C32_05[] = "Minimum Cycle Time";
static const char acName1C32_06[] = "Calc and Copy Time";
static const char acName1C32_07[] = "Minimum Delay Time";
static const char acName1C32_08[] = "GetCycleTime";
static const char acName1C32_09[] = "DelayTime";
static const char acName1C32_0A[] = "Sync0CycleTime";
static const char acName1C32_0B[] = "SMEventMissedCnt";
static const char acName1C32_0C[] = "CycleTimeTooSmallCnt";
static const char acName1C32_0D[] = "Shift too short counter";
static const char acName1C32_0E[] = "RxPDOToggleFailed";
static const char acName1C32_0F[] = "Minimum Cycle Distance";
static const char acName1C32_10[] = "Maximum Cycle Distance";
static const char acName1C32_11[] = "Minimum SM Sync Distance";
static const char acName1C32_12[] = "Maximum SM Sync Distance";
static const char acName1C32_20[] = "SyncError";
static const char acName6000[] = "Buttons";
static const char acName6000_00[] = "Max SubIndex";
static const char acName6000_01[] = "Button1";
static const char acName7000[] = "LEDgroup0";
static const char acName7000_00[] = "Max SubIndex";
static const char acName7000_01[] = "LED0";
static const char acName7001[] = "LEDgroup1";
static const char acName7001_00[] = "Max SubIndex";
static const char acName7001_01[] = "LED1";
static const char acName8000[] = "Parameters";
static const char acName8000_00[] = "Max SubIndex";
static const char acName8000_01[] = "Multiplier";
static const char acName8001[] = "variableRW";
const _objd SDO1000[] =
{
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000, 0x00001389, NULL},
};
const _objd SDO1008[] =
{
{0x0, DTYPE_VISIBLE_STRING, 80, ATYPE_RO, acName1008, 0, "xmc48relax"},
};
const _objd SDO1009[] =
{
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName1009, 0, HW_REV},
};
const _objd SDO100A[] =
{
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName100A, 0, SW_REV},
};
const _objd SDO1018[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1018_00, 4, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_01, 0x1337, NULL},
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_02, 0x4800, NULL},
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_03, 0, NULL},
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_04, 0x00000000, &Obj.serial},
};
const _objd SDO10F1[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName10F1_00, 2, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RW, acName10F1_01, 0, &Obj.ErrorSettings.Local_Error_Reaction},
{0x02, DTYPE_UNSIGNED16, 16, ATYPE_RW, acName10F1_02, 2, &Obj.ErrorSettings.SyncErrorCounterLimit},
};
const _objd SDO1600[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1600_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_01, 0x70000108, NULL},
};
const _objd SDO1601[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1601_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1601_01, 0x70010108, NULL},
};
const _objd SDO1602[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RWpre, acName1602_00, 8, &Obj.PDO1602.maxsub},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1602_01, 0x00000000, &Obj.PDO1602.value[0]},
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1602_02, 0x00000000, &Obj.PDO1602.value[1]},
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1602_03, 0x00000000, &Obj.PDO1602.value[2]},
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1602_04, 0x00000000, &Obj.PDO1602.value[3]},
{0x05, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1602_05, 0x00000000, &Obj.PDO1602.value[4]},
{0x06, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1602_06, 0x00000000, &Obj.PDO1602.value[5]},
{0x07, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1602_07, 0x00000000, &Obj.PDO1602.value[6]},
{0x08, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1602_08, 0x00000000, &Obj.PDO1602.value[7]},
};
const _objd SDO1A00[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1A00_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_01, 0x60000108, NULL},
};
const _objd SDO1A01[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RWpre, acName1A01_00, 8, &Obj.PDO1A01.maxsub},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1A01_01, 0x00000000, &Obj.PDO1A01.value[0]},
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1A01_02, 0x00000000, &Obj.PDO1A01.value[1]},
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1A01_03, 0x00000000, &Obj.PDO1A01.value[2]},
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1A01_04, 0x00000000, &Obj.PDO1A01.value[3]},
{0x05, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1A01_05, 0x00000000, &Obj.PDO1A01.value[4]},
{0x06, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1A01_06, 0x00000000, &Obj.PDO1A01.value[5]},
{0x07, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1A01_07, 0x00000000, &Obj.PDO1A01.value[6]},
{0x08, DTYPE_UNSIGNED32, 32, ATYPE_RWpre, acName1A01_08, 0x00000000, &Obj.PDO1A01.value[7]},
};
const _objd SDO1C00[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_00, 4, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_01, 1, NULL},
{0x02, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_02, 2, NULL},
{0x03, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_03, 3, NULL},
{0x04, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_04, 4, NULL},
};
const _objd SDO1C12[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RWpre, acName1C12_00, 8, &Obj.SM1C12.maxsub},
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C12_01, 0x1600, &Obj.SM1C12.value[0]},
{0x02, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C12_02, 0x1601, &Obj.SM1C12.value[1]},
{0x03, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C12_03, 0x0000, &Obj.SM1C12.value[2]},
{0x04, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C12_04, 0x0000, &Obj.SM1C12.value[3]},
{0x05, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C12_05, 0x0000, &Obj.SM1C12.value[4]},
{0x06, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C12_06, 0x0000, &Obj.SM1C12.value[5]},
{0x07, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C12_07, 0x0000, &Obj.SM1C12.value[6]},
{0x08, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C12_08, 0x0000, &Obj.SM1C12.value[7]},
};
const _objd SDO1C13[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RWpre, acName1C13_00, 8, &Obj.SM1C13.maxsub},
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C13_01, 0x1A00, &Obj.SM1C13.value[0]},
{0x02, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C13_02, 0x0000, &Obj.SM1C13.value[1]},
{0x03, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C13_03, 0x0000, &Obj.SM1C13.value[2]},
{0x04, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C13_04, 0x0000, &Obj.SM1C13.value[3]},
{0x05, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C13_05, 0x0000, &Obj.SM1C13.value[4]},
{0x06, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C13_06, 0x0000, &Obj.SM1C13.value[5]},
{0x07, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C13_07, 0x0000, &Obj.SM1C13.value[6]},
{0x08, DTYPE_UNSIGNED16, 16, ATYPE_RWpre, acName1C13_08, 0x0000, &Obj.SM1C13.value[7]},
};
const _objd SDO1C32[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C32_00, 32, NULL},
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RW, acName1C32_01, 0, &Obj.SyncMgrParam.Sync_mode},
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_02, 0, &Obj.SyncMgrParam.CycleTime},
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_03, 0, &Obj.SyncMgrParam.ShiftTime},
{0x04, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_04, 0, &Obj.SyncMgrParam.Sync_modes_supported},
{0x05, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_05, 125000, &Obj.SyncMgrParam.Minimum_Cycle_Time},
{0x06, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_06, 0, &Obj.SyncMgrParam.Calc_and_Copy_Time},
{0x07, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_07, 0, &Obj.SyncMgrParam.Minimum_Delay_Time},
{0x08, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_08, 0, &Obj.SyncMgrParam.GetCycleTime},
{0x09, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_09, 0, &Obj.SyncMgrParam.DelayTime},
{0x0A, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_0A, 0, &Obj.SyncMgrParam.Sync0CycleTime},
{0x0B, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_0B, 0, &Obj.SyncMgrParam.SMEventMissedCnt},
{0x0C, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_0C, 0, &Obj.SyncMgrParam.CycleTimeTooSmallCnt},
{0x0D, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_0D, 0, &Obj.SyncMgrParam.Shift_too_short_counter},
{0x0E, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_0E, 0, &Obj.SyncMgrParam.RxPDOToggleFailed},
{0x0F, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_0F, 0, &Obj.SyncMgrParam.Minimum_Cycle_Distance},
{0x10, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_10, 0, &Obj.SyncMgrParam.Maximum_Cycle_Distance},
{0x11, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_11, 0, &Obj.SyncMgrParam.Minimum_SM_Sync_Distance},
{0x12, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_12, 0, &Obj.SyncMgrParam.Maximum_SM_Sync_Distance},
{0x20, DTYPE_BOOLEAN, 1, ATYPE_RO, acName1C32_20, 0, &Obj.SyncMgrParam.SyncError},
};
const _objd SDO6000[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6000_00, 1, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO | ATYPE_TXPDO, acName6000_01, 0, &Obj.Buttons.Button1},
};
const _objd SDO7000[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_00, 1, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO | ATYPE_RXPDO, acName7000_01, 0, &Obj.LEDgroup0.LED0},
};
const _objd SDO7001[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7001_00, 1, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO | ATYPE_RXPDO, acName7001_01, 0, &Obj.LEDgroup1.LED1},
};
const _objd SDO8000[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName8000_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName8000_01, 0, &Obj.Parameters.Multiplier},
};
const _objd SDO8001[] =
{
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RW, acName8001, 0, &Obj.variableRW},
};
const _objectlist SDOobjects[] =
{
{0x1000, OTYPE_VAR, 0, 0, acName1000, SDO1000},
{0x1008, OTYPE_VAR, 0, 0, acName1008, SDO1008},
{0x1009, OTYPE_VAR, 0, 0, acName1009, SDO1009},
{0x100A, OTYPE_VAR, 0, 0, acName100A, SDO100A},
{0x1018, OTYPE_RECORD, 4, 0, acName1018, SDO1018},
{0x10F1, OTYPE_RECORD, 2, 0, acName10F1, SDO10F1},
{0x1600, OTYPE_RECORD, 1, 0, acName1600, SDO1600},
{0x1601, OTYPE_RECORD, 1, 0, acName1601, SDO1601},
{0x1602, OTYPE_RECORD, 8, 0, acName1602, SDO1602},
{0x1A00, OTYPE_RECORD, 1, 0, acName1A00, SDO1A00},
{0x1A01, OTYPE_RECORD, 8, 0, acName1A01, SDO1A01},
{0x1C00, OTYPE_ARRAY, 4, 0, acName1C00, SDO1C00},
{0x1C12, OTYPE_ARRAY, 8, 0, acName1C12, SDO1C12},
{0x1C13, OTYPE_ARRAY, 8, 0, acName1C13, SDO1C13},
{0x1C32, OTYPE_RECORD, 19, 0, acName1C32, SDO1C32},
{0x6000, OTYPE_RECORD, 1, 0, acName6000, SDO6000},
{0x7000, OTYPE_RECORD, 1, 0, acName7000, SDO7000},
{0x7001, OTYPE_RECORD, 1, 0, acName7001, SDO7001},
{0x8000, OTYPE_RECORD, 1, 0, acName8000, SDO8000},
{0x8001, OTYPE_VAR, 0, 0, acName8001, SDO8001},
{0xffff, 0xff, 0xff, 0xff, NULL, NULL}
};

View File

@ -0,0 +1,103 @@
#ifndef __UTYPES_H__
#define __UTYPES_H__
#include "cc.h"
/* Object dictionary storage */
typedef struct
{
/* Identity */
uint32_t serial;
/* Inputs */
struct
{
uint8_t Button1;
} Buttons;
/* Outputs */
struct
{
uint8_t LED0;
} LEDgroup0;
struct
{
uint8_t LED1;
} LEDgroup1;
/* Parameters */
struct
{
uint32_t Multiplier;
} Parameters;
uint32_t variableRW;
/* Manufacturer specific data */
struct
{
uint32_t Local_Error_Reaction;
uint16_t SyncErrorCounterLimit;
} ErrorSettings;
struct
{
uint16_t Sync_mode;
uint32_t CycleTime;
uint32_t ShiftTime;
uint16_t Sync_modes_supported;
uint32_t Minimum_Cycle_Time;
uint32_t Calc_and_Copy_Time;
uint32_t Minimum_Delay_Time;
uint16_t GetCycleTime;
uint32_t DelayTime;
uint32_t Sync0CycleTime;
uint16_t SMEventMissedCnt;
uint16_t CycleTimeTooSmallCnt;
uint16_t Shift_too_short_counter;
uint16_t RxPDOToggleFailed;
uint32_t Minimum_Cycle_Distance;
uint32_t Maximum_Cycle_Distance;
uint32_t Minimum_SM_Sync_Distance;
uint32_t Maximum_SM_Sync_Distance;
uint8_t SyncError;
} SyncMgrParam;
/* Dynamic TX PDO:s */
struct
{
uint8_t maxsub;
uint32_t value[8];
} PDO1A01;
/* Dynamic RX PDO:s */
struct
{
uint8_t maxsub;
uint32_t value[8];
} PDO1602;
/* Dynamic Sync Managers */
struct
{
uint8_t maxsub;
uint32_t value[8];
} SM1C12;
struct
{
uint8_t maxsub;
uint32_t value[8];
} SM1C13;
} _Objects;
extern _Objects Obj;
#endif /* __UTYPES_H__ */

View File

@ -1,35 +0,0 @@
#ifndef __CONFIG_H__
#define __CONFIG_H__
#include <cc.h>
#define MBXSIZE 128
#define MBXSIZEBOOT 256
#define MBXBUFFERS 3
#define MBX0_sma 0x1000
#define MBX0_sml MBXSIZE
#define MBX0_sme MBX0_sma+MBX0_sml-1
#define MBX0_smc 0x26
#define MBX1_sma MBX0_sma+MBX0_sml
#define MBX1_sml MBXSIZE
#define MBX1_sme MBX1_sma+MBX1_sml-1
#define MBX1_smc 0x22
#define MBX0_sma_b 0x1000
#define MBX0_sml_b MBXSIZEBOOT
#define MBX0_sme_b MBX0_sma_b+MBX0_sml_b-1
#define MBX0_smc_b 0x26
#define MBX1_sma_b MBX0_sma_b+MBX0_sml_b
#define MBX1_sml_b MBXSIZEBOOT
#define MBX1_sme_b MBX1_sma_b+MBX1_sml_b-1
#define MBX1_smc_b 0x22
#define SM2_sma 0x1100
#define SM2_smc 0x24
#define SM2_act 1
#define SM3_sma 0x1180
#define SM3_smc 0x20
#define SM3_act 1
#endif /* __CONFIG_H__ */

View File

@ -1,184 +0,0 @@
#include <kern.h>
#include <xmc4.h>
#include <bsp.h>
#include "slave.h"
#include "esc_hw.h"
#include "config.h"
#define SAMPLE_CODE 0
/**
* This function reads physical input values and assigns the corresponding members
* of Rb.Buttons
*/
void cb_get_Buttons()
{
Rb.Buttons.Button1 = gpio_get(GPIO_BUTTON1);
}
/**
* This function writes physical output values from the corresponding members of
* Wb.LEDs
*/
void cb_set_LEDgroup0()
{
gpio_set(GPIO_LED1, Wb.LEDgroup0.LED0);
}
/**
* This function writes physical output values from the corresponding members of
* Wb.LEDs
*/
void cb_set_LEDgroup1()
{
gpio_set(GPIO_LED2, Wb.LEDgroup1.LED1);
}
/**
* This function is called after a SDO write of the object Cb.Parameters.
*/
void cb_post_write_variableRW(int subindex)
{
}
/** Optional: Hook called after state change for application specific
* actions for specific state changes.
*/
void pre_state_change_hook (uint8_t * as, uint8_t * an)
{
}
/** Optional: Hook called after state change for application specific
* actions for specific state changes.
*/
void post_state_change_hook (uint8_t * as, uint8_t * an)
{
#if SAMPLE_CODE
/* Add specific step change hooks here */
if ((*as == BOOT_TO_INIT) && (*an == ESCinit))
{
rprintf("boot BOOT_TO_INIT\n");
upgrade_finished();
/* If we return here */
ESC_ALerror (ALERR_NOVALIDFIRMWARE);
/* Upgrade failed, enter init with error */
*an = (ESCinit | ESCerror);
}
else if((*as == PREOP_TO_SAFEOP))
{
rprintf("boot PREOP_TO_SAFEOP\n");
ESC_ALerror (ALERR_NOVALIDFIRMWARE);
/* Stay in preop with error bit set */
*an = (ESCpreop | ESCerror);
}
#endif
}
void user_post_dl_objecthandler (uint16_t index, uint8_t subindex)
{
#if SAMPLE_CODE
switch (index)
{
case 0x1c12:
{
RXPDOsize = ESC_SM2_sml = sizeRXPDO();
break;
}
/* Handle post-write of parameter values */
default:
break;
}
#endif
}
int user_pre_dl_objecthandler (uint16_t index, uint8_t subindex)
{
#if SAMPLE_CODE
if (index == 0x1c12)
{
SDO_abort (index, subindex, ABORT_READONLY);
return 0;
}
if (index == 0x1c13)
{
SDO_abort (index, subindex, ABORT_READONLY);
return 0;
}
#endif
return 1;
}
/* Called from stack when stopping outputs */
void user_safeoutput (void)
{
#if SAMPLE_CODE
DPRINT ("APP_safeoutput\n");
// Set safe values for Wb.LEDgroup0
Wb.LEDgroup0.LED0 = 1;
// Set safe values for Wb.LEDgroup1
Wb.LEDgroup1.LED1 = 1;
#endif
}
/* Configuration parameters for SOES
* SM and Mailbox parameters comes from the
* generated config.h
*/
static esc_cfg_t config =
{
.user_arg = NULL,
.use_interrupt = 1,
.watchdog_cnt = 100,
.mbxsize = MBXSIZE,
.mbxsizeboot = MBXSIZEBOOT,
.mbxbuffers = MBXBUFFERS,
.mb[0] = {MBX0_sma, MBX0_sml, MBX0_sme, MBX0_smc, 0},
.mb[1] = {MBX1_sma, MBX1_sml, MBX1_sme, MBX1_smc, 0},
.mb_boot[0] = {MBX0_sma_b, MBX0_sml_b, MBX0_sme_b, MBX0_smc_b, 0},
.mb_boot[1] = {MBX1_sma_b, MBX1_sml_b, MBX1_sme_b, MBX1_smc_b, 0},
.pdosm[0] = {SM2_sma, 0, 0, SM2_smc, SM2_act},
.pdosm[1] = {SM3_sma, 0, 0, SM3_smc, SM3_act},
.pre_state_change_hook = NULL,
.post_state_change_hook = NULL,
.application_hook = NULL,
.safeoutput_override = user_safeoutput,
.pre_object_download_hook = user_pre_dl_objecthandler,
.post_object_download_hook = user_post_dl_objecthandler,
.rxpdo_override = NULL,
.txpdo_override = NULL,
.esc_hw_interrupt_enable = ESC_interrupt_enable,
.esc_hw_interrupt_disable = ESC_interrupt_disable,
.esc_hw_eep_handler = ESC_eep_handler
};
void main_run(void * arg)
{
ecat_slv_init(&config);
while(1)
{
if(config.use_interrupt != 0)
{
DIG_process(DIG_PROCESS_WD_FLAG);
}
else
{
ecat_slv();
}
task_delay(1);
}
}
int main(void)
{
rprintf("Hello Main\n");
task_spawn ("soes", main_run, 8, 2048, NULL);
return 0;
}

Binary file not shown.

View File

@ -1,334 +0,0 @@
#ifndef SOES_V1
#include <stddef.h>
#include "utypes.h"
#include "esc.h"
#include "esc_coe.h"
#include "esc_foe.h"
#include "config.h"
#include "slave.h"
/* Global variables used by the stack */
uint8_t MBX[MBXBUFFERS * MAX(MBXSIZE,MBXSIZEBOOT)];
_MBXcontrol MBXcontrol[MBXBUFFERS];
_ESCvar ESCvar;
/* Application variables */
_Rbuffer Rb;
_Wbuffer Wb;
_Cbuffer Cb;
_Mbuffer Mb;
/* Private variables */
static volatile int watchdog;
/** Mandatory: Function to pre-qualify the incoming SDO download.
*
* @param[in] index = index of SDO download request to check
* @param[in] sub-index = sub-index of SDO download request to check
* @return 1 if the SDO Download is correct. 0 If not correct.
*/
int ESC_pre_objecthandler (uint16_t index, uint8_t subindex)
{
int result = 1;
if(ESCvar.pre_object_download_hook)
{
result = (ESCvar.pre_object_download_hook)(index, subindex);
}
return result;
}
/** Mandatory: Hook called from the slave stack SDO Download handler to act on
* user specified Index and Sub-index.
*
* @param[in] index = index of SDO download request to handle
* @param[in] sub-index = sub-index of SDO download request to handle
*/
void ESC_objecthandler (uint16_t index, uint8_t subindex)
{
switch (index)
{
/* Handle post-write of parameter values */
case 0x8001:
{
cb_post_write_variableRW(subindex);
break;
}
default:
{
if(ESCvar.post_object_download_hook != NULL)
{
(ESCvar.post_object_download_hook)(index, subindex);
}
break;
}
}
}
/** Mandatory: Hook called from the slave stack ESC_stopoutputs to act on state changes
* forcing us to stop outputs. Here we can set them to a safe state.
* set
*/
void APP_safeoutput (void)
{
DPRINT ("APP_safeoutput\n");
if(ESCvar.safeoutput_override != NULL)
{
(ESCvar.safeoutput_override)();
}
else
{
// Set safe values for Wb.LEDgroup0
Wb.LEDgroup0.LED0 = 0;
// Set safe values for Wb.LEDgroup1
Wb.LEDgroup1.LED1 = 0;
}
}
/** Mandatory: Write local process data to Sync Manager 3, Master Inputs.
*/
void TXPDO_update (void)
{
if(ESCvar.txpdo_override != NULL)
{
(ESCvar.txpdo_override)();
}
else
{
ESC_write (SM3_sma, &Rb, ESCvar.TXPDOsize);
}
}
/** Mandatory: Read Sync Manager 2 to local process data, Master Outputs.
*/
void RXPDO_update (void)
{
if(ESCvar.rxpdo_override != NULL)
{
(ESCvar.rxpdo_override)();
}
else
{
ESC_read (SM2_sma, &Wb, ESCvar.RXPDOsize);
}
}
/** Mandatory: Function to update local I/O, call read ethercat outputs, call
* write ethercat inputs. Implement watch-dog counter to count-out if we have
* made state change affecting the App.state.
*/
void DIG_process (uint8_t flags)
{
/* Handle watchdog */
if((flags & DIG_PROCESS_WD_FLAG) > 0)
{
if (CC_ATOMIC_GET(watchdog) > 0)
{
CC_ATOMIC_SUB(watchdog, 1);
}
if ((CC_ATOMIC_GET(watchdog) <= 0) &&
((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0))
{
DPRINT("DIG_process watchdog expired\n");
ESC_stopoutput();
/* watchdog, invalid outputs */
ESC_ALerror (ALERR_WATCHDOG);
/* goto safe-op with error bit set */
ESC_ALstatus (ESCsafeop | ESCerror);
}
else if(((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) == 0))
{
CC_ATOMIC_SET(watchdog, ESCvar.watchdogcnt);
}
}
/* Handle Outputs */
if ((flags & DIG_PROCESS_OUTPUTS_FLAG) > 0)
{
if(((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0) &&
(ESCvar.ALevent & ESCREG_ALEVENT_SM2))
{
RXPDO_update();
CC_ATOMIC_SET(watchdog, ESCvar.watchdogcnt);
if(ESCvar.dcsync > 0)
{
CC_ATOMIC_ADD(ESCvar.synccounter, 1);
}
/* Set outputs */
cb_set_LEDgroup0();
cb_set_LEDgroup1();
}
else if (ESCvar.ALevent & ESCREG_ALEVENT_SM2)
{
RXPDO_update();
}
}
/* Call application */
if ((flags & DIG_PROCESS_APP_HOOK_FLAG) > 0)
{
if((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0)
{
CC_ATOMIC_SUB(ESCvar.synccounter, 1);
}
if((ESCvar.dcsync > 0) &&
((CC_ATOMIC_GET(ESCvar.synccounter) < -ESCvar.synccounterlimit) ||
(CC_ATOMIC_GET(ESCvar.synccounter) > ESCvar.synccounterlimit)))
{
if((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0)
{
DPRINT("sync error = %d\n", ESCvar.synccounter);
ESC_stopoutput();
/* Sync error */
ESC_ALerror (ALERR_SYNCERROR);
/* goto safe-op with error bit set */
ESC_ALstatus (ESCsafeop | ESCerror);
CC_ATOMIC_SET(ESCvar.synccounter, 0);
}
}
/* Call application callback if set */
if (ESCvar.application_hook != NULL)
{
(ESCvar.application_hook)();
}
}
/* Handle Inputs */
if ((flags & DIG_PROCESS_INPUTS_FLAG) > 0)
{
if(CC_ATOMIC_GET(ESCvar.App.state) > 0)
{
/* Update inputs */
cb_get_Buttons();
TXPDO_update();
}
}
}
/**
* Handler for SM change, SM0/1, AL CONTROL and EEPROM events, the application
* control what interrupts that should be served and re-activated with
* event mask argument
*/
void ecat_slv_worker (uint32_t event_mask)
{
do
{
/* Check the state machine */
ESC_state();
/* Check the SM activation event */
ESC_sm_act_event();
/* Check mailboxes */
while ((ESC_mbxprocess() > 0) || (ESCvar.txcue > 0))
{
ESC_coeprocess();
ESC_foeprocess();
ESC_xoeprocess();
}
/* Call emulated eeprom handler if set */
if (ESCvar.esc_hw_eep_handler != NULL)
{
(ESCvar.esc_hw_eep_handler)();
}
CC_ATOMIC_SET(ESCvar.ALevent, ESC_ALeventread());
}while(ESCvar.ALevent & event_mask);
ESC_ALeventmaskwrite(ESC_ALeventmaskread() | event_mask);
}
/**
* ISR function. It should be called from ISR for applications entirely driven by
* interrupts.
* Read and handle events for the EtherCAT state, status, mailbox and eeprom.
*/
void ecat_slv_isr (void)
{
ecat_slv_worker(ESCREG_ALEVENT_CONTROL | ESCREG_ALEVENT_SMCHANGE
| ESCREG_ALEVENT_SM0 | ESCREG_ALEVENT_SM1 | ESCREG_ALEVENT_EEP);
}
/**
* Polling function. It should be called periodically for an application
* when only SM2/DC interrupt is active.
* Read and handle events for the EtherCAT state, status, mailbox and eeprom.
*/
void ecat_slv_poll (void)
{
/* Read local time from ESC*/
ESC_read (ESCREG_LOCALTIME, (void *) &ESCvar.Time, sizeof (ESCvar.Time));
ESCvar.Time = etohl (ESCvar.Time);
/* Check the state machine */
ESC_state();
/* Check the SM activation event */
ESC_sm_act_event();
/* Check mailboxes */
if (ESC_mbxprocess())
{
ESC_coeprocess();
ESC_foeprocess();
ESC_xoeprocess();
}
/* Call emulated eeprom handler if set */
if (ESCvar.esc_hw_eep_handler != NULL)
{
(ESCvar.esc_hw_eep_handler)();
}
}
void ecat_slv (void)
{
ecat_slv_poll();
DIG_process(DIG_PROCESS_WD_FLAG | DIG_PROCESS_OUTPUTS_FLAG |
DIG_PROCESS_APP_HOOK_FLAG | DIG_PROCESS_INPUTS_FLAG);
}
/**
* Initialize the slave stack.
*/
void ecat_slv_init (esc_cfg_t * config)
{
DPRINT ("Slave stack init started\n");
ESCvar.TXPDOsize = ESCvar.ESC_SM3_sml = sizeOfPDO(TX_PDO_OBJIDX);
ESCvar.RXPDOsize = ESCvar.ESC_SM2_sml = sizeOfPDO(RX_PDO_OBJIDX);
/* Init watchdog */
watchdog = config->watchdog_cnt;
/* Call stack configuration */
ESC_config (config);
/* Call HW init */
ESC_init (config);
/* wait until ESC is started up */
while ((ESCvar.DLstatus & 0x0001) == 0)
{
ESC_read (ESCREG_DLSTATUS, (void *) &ESCvar.DLstatus,
sizeof (ESCvar.DLstatus));
ESCvar.DLstatus = etohs (ESCvar.DLstatus);
}
/* Init FoE */
FOE_init();
/* reset ESC to init state */
ESC_ALstatus (ESCinit);
ESC_ALerror (ALERR_NONE);
ESC_stopmbx();
ESC_stopinput();
ESC_stopoutput();
}
#endif

View File

@ -1,74 +0,0 @@
#ifndef __SLAVE_H__
#define __SLAVE_H__
#include "utypes.h"
#include "esc.h"
/**
* This function gets input values and updates Rb.Buttons
*/
void cb_get_Buttons();
/**
* This function sets output values according to Wb.LEDgroup0
*/
void cb_set_LEDgroup0();
/**
* This function sets output values according to Wb.LEDgroup1
*/
void cb_set_LEDgroup1();
/**
* This function is called after a SDO write of the object Cb.variableRW.
*/
void cb_post_write_variableRW(int subindex);
#define DIG_PROCESS_INPUTS_FLAG 0x01
#define DIG_PROCESS_OUTPUTS_FLAG 0x02
#define DIG_PROCESS_WD_FLAG 0x04
#define DIG_PROCESS_APP_HOOK_FLAG 0x08
/** Implements the watch-dog counter to count if we should make a state change
* due to missing incoming SM2 events. Updates local I/O and run the application
* in the following order, call read EtherCAT outputs, execute user provided
* application hook and call write EtherCAT inputs.
*
* @param[in] flags = User input what to execute
*/
void DIG_process (uint8_t flags);
/**
* Handler for SM change, SM0/1, AL CONTROL and EEPROM events, the application
* control what interrupts that should be served and re-activated with
* event mask argument
*
* @param[in] event_mask = Event mask for interrupts to serve and re-activate
* after served
*/
void ecat_slv_worker (uint32_t event_mask);
/**
* ISR for SM0/1, EEPROM and AL CONTROL events in a SM/DC
* synchronization application
*/
CC_DEPRECATED void ecat_slv_isr (void);
/**
* Poll SM0/1, EEPROM and AL CONTROL events in a SM/DC synchronization
* application
*/
void ecat_slv_poll (void);
/**
* Poll all events in a free-run application
*/
void ecat_slv (void);
/**
* Initialize the slave stack
*
* @param[in] config = User input how to configure the stack
*/
void ecat_slv_init (esc_cfg_t * config);
#endif /* __SLAVE_H__ */

View File

@ -1,218 +0,0 @@
#ifndef SOES_V1
#include "esc_coe.h"
#include "utypes.h"
#include <stddef.h>
static const char acName1000[] = "Device Type";
static const char acName1000_0[] = "Device Type";
static const char acName1008[] = "Device Name";
static const char acName1008_0[] = "Device Name";
static const char acName1009[] = "Hardware Version";
static const char acName1009_0[] = "Hardware Version";
static const char acName100A[] = "Software Version";
static const char acName100A_0[] = "Software Version";
static const char acName1018[] = "Identity Object";
static const char acName1018_00[] = "Max SubIndex";
static const char acName1018_01[] = "Vendor ID";
static const char acName1018_02[] = "Product Code";
static const char acName1018_03[] = "Revision Number";
static const char acName1018_04[] = "Serial Number";
static const char acName10F1[] = "ErrorSettings";
static const char acName10F1_00[] = "Max SubIndex";
static const char acName10F1_01[] = "Dummy_x01";
static const char acName10F1_02[] = "SyncErrorCounterLimit";
static const char acName1600[] = "LEDgroup0";
static const char acName1600_00[] = "Max SubIndex";
static const char acName1600_01[] = "LED0";
static const char acName1601[] = "LEDgroup1";
static const char acName1601_00[] = "Max SubIndex";
static const char acName1601_01[] = "LED1";
static const char acName1A00[] = "Buttons";
static const char acName1A00_00[] = "Max SubIndex";
static const char acName1A00_01[] = "Button1";
static const char acName1C00[] = "Sync Manager Communication Type";
static const char acName1C00_00[] = "Max SubIndex";
static const char acName1C00_01[] = "Communications Type SM0";
static const char acName1C00_02[] = "Communications Type SM1";
static const char acName1C00_03[] = "Communications Type SM2";
static const char acName1C00_04[] = "Communications Type SM3";
static const char acName1C12[] = "Sync Manager 2 PDO Assignment";
static const char acName1C12_00[] = "Max SubIndex";
static const char acName1C12_01[] = "PDO Mapping";
static const char acName1C12_02[] = "PDO Mapping";
static const char acName1C13[] = "Sync Manager 3 PDO Assignment";
static const char acName1C13_00[] = "Max SubIndex";
static const char acName1C13_01[] = "PDO Mapping";
static const char acName1C32[] = "SyncMgrParam";
static const char acName1C32_00[] = "Max SubIndex";
static const char acName1C32_01[] = "SyncType";
static const char acName1C32_02[] = "CycleTime";
static const char acName1C32_03[] = "ShiftTime";
static const char acName1C32_04[] = "SyncTypeSupport";
static const char acName1C32_05[] = "MinCycleTime";
static const char acName1C32_06[] = "CalcCopyTime";
static const char acName1C32_07[] = "MinDelayTime";
static const char acName1C32_08[] = "GetCycleTime";
static const char acName1C32_09[] = "DelayTime";
static const char acName1C32_0A[] = "Sync0CycleTime";
static const char acName1C32_0B[] = "SMEventMissedCnt";
static const char acName1C32_0C[] = "CycleTimeTooSmallCnt";
static const char acName1C32_0D[] = "ShiftTimeTooSmallCnt";
static const char acName1C32_0E[] = "RxPDOToggleFailed";
static const char acName1C32_0F[] = "MinCycleDist";
static const char acName1C32_10[] = "MaxCycleDist";
static const char acName1C32_11[] = "MinSMSYNCDist";
static const char acName1C32_12[] = "MaxSMSYNCDist";
static const char acName1C32_14[] = "Dummy_x14";
static const char acName1C32_20[] = "SyncError";
static const char acName6005[] = "Buttons";
static const char acName6005_00[] = "Max SubIndex";
static const char acName6005_01[] = "Button1";
static const char acName7005[] = "LEDgroup0";
static const char acName7005_00[] = "Max SubIndex";
static const char acName7005_01[] = "LED0";
static const char acName7006[] = "LEDgroup1";
static const char acName7006_00[] = "Max SubIndex";
static const char acName7006_01[] = "LED1";
static const char acName8000[] = "Parameters";
static const char acName8000_00[] = "Max SubIndex";
static const char acName8000_01[] = "Multiplier";
static const char acName8001[] = "variableRW";
static const char acName8001_0[] = "variableRW";
const _objd SDO1000[] =
{
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000_0, 0x00001389, NULL},
};
const _objd SDO1008[] =
{
{0x0, DTYPE_VISIBLE_STRING, 88, ATYPE_RO, acName1008_0, 0, "xmc43_slave"},
};
const _objd SDO1009[] =
{
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName1009_0, 0, "1.0"},
};
const _objd SDO100A[] =
{
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName100A_0, 0, "1.0"},
};
const _objd SDO1018[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1018_00, 4, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_01, 0x1337, NULL},
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_02, 4300, NULL},
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_03, 0, NULL},
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_04, 0x00000000, NULL},
};
const _objd SDO10F1[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName10F1_00, 2, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName10F1_01, 0, &Mb.ErrorSettings.Dummy_x01},
{0x02, DTYPE_UNSIGNED16, 16, ATYPE_RW, acName10F1_02, 2, &Mb.ErrorSettings.SyncErrorCounterLimit},
};
const _objd SDO1600[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1600_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_01, 0x70050108, NULL},
};
const _objd SDO1601[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1601_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1601_01, 0x70060108, NULL},
};
const _objd SDO1A00[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1A00_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_01, 0x60050108, NULL},
};
const _objd SDO1C00[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_00, 4, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_01, 1, NULL},
{0x02, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_02, 2, NULL},
{0x03, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_03, 3, NULL},
{0x04, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_04, 4, NULL},
};
const _objd SDO1C12[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C12_00, 2, NULL},
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C12_01, 0x1600, NULL},
{0x02, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C12_02, 0x1601, NULL},
};
const _objd SDO1C13[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C13_00, 1, NULL},
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C13_01, 0x1A00, NULL},
};
const _objd SDO1C32[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C32_00, 32, NULL},
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_01, 1, &Mb.SyncMgrParam.SyncType},
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_02, 0, &Mb.SyncMgrParam.CycleTime},
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_03, 0, &Mb.SyncMgrParam.ShiftTime},
{0x04, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_04, 0x6, &Mb.SyncMgrParam.SyncTypeSupport},
{0x05, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_05, 125000, &Mb.SyncMgrParam.MinCycleTime},
{0x06, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_06, 0, &Mb.SyncMgrParam.CalcCopyTime},
{0x07, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_07, 0, &Mb.SyncMgrParam.MinDelayTime},
{0x08, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_08, 0, &Mb.SyncMgrParam.GetCycleTime},
{0x09, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_09, 0, &Mb.SyncMgrParam.DelayTime},
{0x0A, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_0A, 0, &Mb.SyncMgrParam.Sync0CycleTime},
{0x0B, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_0B, 0, &Mb.SyncMgrParam.SMEventMissedCnt},
{0x0C, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_0C, 0, &Mb.SyncMgrParam.CycleTimeTooSmallCnt},
{0x0D, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_0D, 0, &Mb.SyncMgrParam.ShiftTimeTooSmallCnt},
{0x0E, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C32_0E, 0, &Mb.SyncMgrParam.RxPDOToggleFailed},
{0x0F, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_0F, 0, &Mb.SyncMgrParam.MinCycleDist},
{0x10, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_10, 0, &Mb.SyncMgrParam.MaxCycleDist},
{0x11, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_11, 0, &Mb.SyncMgrParam.MinSMSYNCDist},
{0x12, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1C32_12, 0, &Mb.SyncMgrParam.MaxSMSYNCDist},
{0x14, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C32_14, 0, &Mb.SyncMgrParam.Dummy_x14},
{0x20, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C32_20, 0, &Mb.SyncMgrParam.SyncError},
};
const _objd SDO6005[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6005_00, 1, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6005_01, 0, &Rb.Buttons.Button1},
};
const _objd SDO7005[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7005_00, 1, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7005_01, 0, &Wb.LEDgroup0.LED0},
};
const _objd SDO7006[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7006_00, 1, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7006_01, 0, &Wb.LEDgroup1.LED1},
};
const _objd SDO8000[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName8000_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RW, acName8000_01, 0, &Cb.Parameters.Multiplier},
};
const _objd SDO8001[] =
{
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RW, acName8001_0, 0, &Cb.variableRW},
};
const _objectlist SDOobjects[] =
{
{0x1000, OTYPE_VAR, 0, 0, acName1000, SDO1000},
{0x1008, OTYPE_VAR, 0, 0, acName1008, SDO1008},
{0x1009, OTYPE_VAR, 0, 0, acName1009, SDO1009},
{0x100A, OTYPE_VAR, 0, 0, acName100A, SDO100A},
{0x1018, OTYPE_RECORD, 4, 0, acName1018, SDO1018},
{0x10F1, OTYPE_RECORD, 2, 0, acName10F1, SDO10F1},
{0x1600, OTYPE_RECORD, 1, 0, acName1600, SDO1600},
{0x1601, OTYPE_RECORD, 1, 0, acName1601, SDO1601},
{0x1A00, OTYPE_RECORD, 1, 0, acName1A00, SDO1A00},
{0x1C00, OTYPE_ARRAY, 4, 0, acName1C00, SDO1C00},
{0x1C12, OTYPE_ARRAY, 2, 0, acName1C12, SDO1C12},
{0x1C13, OTYPE_ARRAY, 1, 0, acName1C13, SDO1C13},
{0x1C32, OTYPE_RECORD, 32, 0, acName1C32, SDO1C32},
{0x6005, OTYPE_RECORD, 1, 0, acName6005, SDO6005},
{0x7005, OTYPE_RECORD, 1, 0, acName7005, SDO7005},
{0x7006, OTYPE_RECORD, 1, 0, acName7006, SDO7006},
{0x8000, OTYPE_RECORD, 1, 0, acName8000, SDO8000},
{0x8001, OTYPE_VAR, 0, 0, acName8001, SDO8001},
{0xffff, 0xff, 0xff, 0xff, NULL, NULL}
};
#endif

View File

@ -1,96 +0,0 @@
#ifndef __UTYPES_H__
#define __UTYPES_H__
#include <cc.h>
/* Inputs */
CC_PACKED_BEGIN
typedef struct
{
CC_PACKED_BEGIN
struct
{
uint8_t Button1;
} CC_PACKED Buttons;
CC_PACKED_END
} CC_PACKED _Rbuffer;
CC_PACKED_END
/* Outputs */
CC_PACKED_BEGIN
typedef struct
{
CC_PACKED_BEGIN
struct
{
uint8_t LED0;
} CC_PACKED LEDgroup0;
CC_PACKED_END
CC_PACKED_BEGIN
struct
{
uint8_t LED1;
} CC_PACKED LEDgroup1;
CC_PACKED_END
} CC_PACKED _Wbuffer;
CC_PACKED_END
/* Parameters */
CC_PACKED_BEGIN
typedef struct
{
CC_PACKED_BEGIN
struct
{
uint32_t Multiplier;
} CC_PACKED Parameters;
CC_PACKED_END
uint32_t variableRW;
} CC_PACKED _Cbuffer;
CC_PACKED_END
/* Manufacturer specific data */
CC_PACKED_BEGIN
typedef struct
{
CC_PACKED_BEGIN
struct
{
uint16_t SyncType;
uint32_t CycleTime;
uint32_t ShiftTime;
uint16_t SyncTypeSupport;
uint32_t MinCycleTime;
uint32_t CalcCopyTime;
uint32_t MinDelayTime;
uint16_t GetCycleTime;
uint32_t DelayTime;
uint32_t Sync0CycleTime;
uint16_t SMEventMissedCnt;
uint16_t CycleTimeTooSmallCnt;
uint16_t ShiftTimeTooSmallCnt;
uint16_t RxPDOToggleFailed;
uint32_t MinCycleDist;
uint32_t MaxCycleDist;
uint32_t MinSMSYNCDist;
uint32_t MaxSMSYNCDist;
uint8_t Dummy_x14;
uint8_t SyncError;
} CC_PACKED SyncMgrParam;
CC_PACKED_END
CC_PACKED_BEGIN
struct
{
uint8_t Dummy_x01;
uint16_t SyncErrorCounterLimit;
} CC_PACKED ErrorSettings;
CC_PACKED_END
} CC_PACKED _Mbuffer;
CC_PACKED_END
extern _Rbuffer Rb;
extern _Wbuffer Wb;
extern _Cbuffer Cb;
extern _Mbuffer Mb;
#endif /* __UTYPES_H__ */

Binary file not shown.

View File

@ -0,0 +1,263 @@
<?xml version="1.0" encoding="UTF-8"?>
<Slave xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="com.rtlabs.emf.esx" fileVersion="2" id="am335xice" productCode="0x9876">
<Name>slave</Name>
<Vendor>
<Id>0x1337</Id>
<Name>rt-labs</Name>
</Vendor>
<Group>
<Type>am335xice_t</Type>
<Name>am335xice_n</Name>
</Group>
<Fmmu>Outputs</Fmmu>
<Fmmu>Inputs</Fmmu>
<Fmmu>MBoxState</Fmmu>
<Sm ControlByte="0x26" DefaultSize="512" StartAddress="0x1000">MBoxOut</Sm>
<Sm ControlByte="0x22" DefaultSize="512" StartAddress="0x1200">MBoxIn</Sm>
<Sm ControlByte="0x24" DefaultSize="0" StartAddress="0x1400">Outputs</Sm>
<Sm ControlByte="0x20" DefaultSize="0" StartAddress="0x1A00">Inputs</Sm>
<Mailbox CoE="true">
<Bootstrap Length="512" Start="0x1000"/>
<Standard Length="512" Start="0x1000"/>
</Mailbox>
<Eeprom>
<ByteSize>2048</ByteSize>
<ConfigData>8006E08800000000</ConfigData>
<BootStrap>0010000200120002</BootStrap>
</Eeprom>
<Dictionary>
<Item Managed="true">
<Index>0x1000</Index>
<Name>Device Type</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x00001389</DefaultValue>
</Item>
<Item Managed="true">
<Index>0x1008</Index>
<Name>Device Name</Name>
<DataType>VISIBLE_STRING</DataType>
<DefaultValue>am335xice</DefaultValue>
<Length>9</Length>
</Item>
<Item>
<Index>0x1009</Index>
<Name>Hardware Version</Name>
<DataType>VISIBLE_STRING</DataType>
<DefaultValue>1.0</DefaultValue>
<Length>3</Length>
</Item>
<Item>
<Index>0x100A</Index>
<Name>Software Version</Name>
<DataType>VISIBLE_STRING</DataType>
<DefaultValue>1.0</DefaultValue>
<Length>3</Length>
</Item>
<Item Managed="true">
<Index>0x1018</Index>
<Name>Identity Object</Name>
<DataType>RECORD</DataType>
<SubItem>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>4</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>Vendor ID</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x1337</DefaultValue>
</SubItem>
<SubItem>
<Index>0x02</Index>
<Name>Product Code</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x9876</DefaultValue>
</SubItem>
<SubItem>
<Index>0x03</Index>
<Name>Revision Number</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0</DefaultValue>
</SubItem>
<SubItem>
<Index>0x04</Index>
<Name>Serial Number</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x00000000</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Index>0x1600</Index>
<Name>LED</Name>
<DataType>RECORD</DataType>
<SubItem>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>LED</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x70000020</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Index>0x1A00</Index>
<Name>BUTTON</Name>
<DataType>RECORD</DataType>
<SubItem>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>BUTTON</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x60000020</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Index>0x1C00</Index>
<Name>Sync Manager Communication Type</Name>
<DataType>ARRAY</DataType>
<SubItem>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>4</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>Communications Type SM0</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x02</Index>
<Name>Communications Type SM1</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>2</DefaultValue>
</SubItem>
<SubItem>
<Index>0x03</Index>
<Name>Communications Type SM2</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>3</DefaultValue>
</SubItem>
<SubItem>
<Index>0x04</Index>
<Name>Communications Type SM3</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>4</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Index>0x1C12</Index>
<Name>Sync Manager 2 PDO Assignment</Name>
<DataType>ARRAY</DataType>
<SubItem>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>PDO Mapping</Name>
<DataType>UNSIGNED16</DataType>
<DefaultValue>0x1600</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Index>0x1C13</Index>
<Name>Sync Manager 3 PDO Assignment</Name>
<DataType>ARRAY</DataType>
<SubItem>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Index>0x01</Index>
<Name>PDO Mapping</Name>
<DataType>UNSIGNED16</DataType>
<DefaultValue>0x1A00</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Index>0x6000</Index>
<Access>RO</Access>
<Name>BUTTON</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0</DefaultValue>
<PdoMapping>TX</PdoMapping>
<Variable>BUTTON</Variable>
<VariableType>Input</VariableType>
</Item>
<Item Managed="true">
<Index>0x7000</Index>
<Access>RO</Access>
<Name>LED</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0</DefaultValue>
<PdoMapping>RX</PdoMapping>
<Variable>LED</Variable>
<VariableType>Output</VariableType>
</Item>
</Dictionary>
<SmAssignment>
<Index>0x1C12</Index>
<Entry>
<Index>0x01</Index>
<AssignedPdo>0x1600</AssignedPdo>
</Entry>
</SmAssignment>
<SmAssignment>
<Index>0x1C13</Index>
<Entry>
<Index>0x01</Index>
<AssignedPdo>0x1A00</AssignedPdo>
</Entry>
</SmAssignment>
<RxPdo>
<Index>0x1600</Index>
<Name>LED</Name>
<Entry>
<Index>0x1</Index>
<MappedIndex>0x7000</MappedIndex>
<MappedSubIndex>0x00</MappedSubIndex>
<Variable>LED</Variable>
</Entry>
</RxPdo>
<TxPdo>
<Index>0x1A00</Index>
<Name>BUTTON</Name>
<Entry>
<Index>0x1</Index>
<MappedIndex>0x6000</MappedIndex>
<MappedSubIndex>0x00</MappedSubIndex>
<Variable>BUTTON</Variable>
</Entry>
</TxPdo>
<Input>
<Index>0x6000</Index>
<Name>BUTTON</Name>
<Type>UNSIGNED32</Type>
<PdoMapping>TX</PdoMapping>
<ObjectType>VAR</ObjectType>
</Input>
<Output>
<Index>0x7000</Index>
<Name>LED</Name>
<Type>UNSIGNED32</Type>
<PdoMapping>RX</PdoMapping>
<ObjectType>VAR</ObjectType>
</Output>
</Slave>

View File

@ -0,0 +1,537 @@
<?xml version="1.0" encoding="UTF-8"?>
<EtherCATInfo>
<Vendor>
<Id>#x1337</Id>
<Name LcId="1033">rt-labs</Name>
</Vendor>
<Descriptions>
<Groups>
<Group>
<Type>am335xice_t</Type>
<Name LcId="1033">am335xice_n</Name>
</Group>
</Groups>
<Devices>
<Device Physics="YY">
<Type ProductCode="#x9876" RevisionNo="0">am335xice</Type>
<Name LcId="1033">slave</Name>
<GroupType>am335xice_t</GroupType>
<Profile>
<ProfileNo>5001</ProfileNo>
<AddInfo>0</AddInfo>
<Dictionary>
<DataTypes>
<DataType>
<Name>DT1018</Name>
<BitSize>144</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<SubIdx>1</SubIdx>
<Name>Vendor ID</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<BitOffs>16</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<SubIdx>2</SubIdx>
<Name>Product Code</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<BitOffs>48</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<SubIdx>3</SubIdx>
<Name>Revision Number</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<BitOffs>80</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<SubIdx>4</SubIdx>
<Name>Serial Number</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<BitOffs>112</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>DT1600</Name>
<BitSize>48</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<SubIdx>1</SubIdx>
<Name>LED</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<BitOffs>16</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>DT1A00</Name>
<BitSize>48</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<SubIdx>1</SubIdx>
<Name>BUTTON</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<BitOffs>16</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>DT1C00ARR</Name>
<BaseType>USINT</BaseType>
<BitSize>32</BitSize>
<ArrayInfo>
<LBound>1</LBound>
<Elements>4</Elements>
</ArrayInfo>
</DataType>
<DataType>
<Name>DT1C00</Name>
<BitSize>48</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<Name>Elements</Name>
<Type>DT1C00ARR</Type>
<BitSize>32</BitSize>
<BitOffs>16</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>DT1C12ARR</Name>
<BaseType>UINT</BaseType>
<BitSize>16</BitSize>
<ArrayInfo>
<LBound>1</LBound>
<Elements>1</Elements>
</ArrayInfo>
</DataType>
<DataType>
<Name>DT1C12</Name>
<BitSize>32</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<Name>Elements</Name>
<Type>DT1C12ARR</Type>
<BitSize>16</BitSize>
<BitOffs>16</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>DT1C13ARR</Name>
<BaseType>UINT</BaseType>
<BitSize>16</BitSize>
<ArrayInfo>
<LBound>1</LBound>
<Elements>1</Elements>
</ArrayInfo>
</DataType>
<DataType>
<Name>DT1C13</Name>
<BitSize>32</BitSize>
<SubItem>
<SubIdx>0</SubIdx>
<Name>Max SubIndex</Name>
<Type>USINT</Type>
<BitSize>8</BitSize>
<BitOffs>0</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
<SubItem>
<Name>Elements</Name>
<Type>DT1C13ARR</Type>
<BitSize>16</BitSize>
<BitOffs>16</BitOffs>
<Flags>
<Access>ro</Access>
</Flags>
</SubItem>
</DataType>
<DataType>
<Name>STRING(3)</Name>
<BitSize>24</BitSize>
</DataType>
<DataType>
<Name>UDINT</Name>
<BitSize>32</BitSize>
</DataType>
<DataType>
<Name>UINT</Name>
<BitSize>16</BitSize>
</DataType>
<DataType>
<Name>USINT</Name>
<BitSize>8</BitSize>
</DataType>
<DataType>
<Name>STRING(9)</Name>
<BitSize>72</BitSize>
</DataType>
</DataTypes>
<Objects>
<Object>
<Index>#x1000</Index>
<Name>Device Type</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<Info>
<DefaultValue>#x00001389</DefaultValue>
</Info>
<Flags>
<Access>ro</Access>
<Category>m</Category>
</Flags>
</Object>
<Object>
<Index>#x1008</Index>
<Name>Device Name</Name>
<Type>STRING(9)</Type>
<BitSize>72</BitSize>
<Info>
<DefaultString>am335xice</DefaultString>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1009</Index>
<Name>Hardware Version</Name>
<Type>STRING(3)</Type>
<BitSize>24</BitSize>
<Info>
<DefaultString>1.0</DefaultString>
</Info>
<Flags>
<Access>ro</Access>
<Category>o</Category>
</Flags>
</Object>
<Object>
<Index>#x100A</Index>
<Name>Software Version</Name>
<Type>STRING(3)</Type>
<BitSize>24</BitSize>
<Info>
<DefaultString>1.0</DefaultString>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1018</Index>
<Name>Identity Object</Name>
<Type>DT1018</Type>
<BitSize>144</BitSize>
<Info>
<SubItem>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>4</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>Vendor ID</Name>
<Info>
<DefaultValue>#x1337</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>Product Code</Name>
<Info>
<DefaultValue>#x9876</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>Revision Number</Name>
<Info>
<DefaultValue>0</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>Serial Number</Name>
<Info>
<DefaultValue>#x00000000</DefaultValue>
</Info>
</SubItem>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1600</Index>
<Name>LED</Name>
<Type>DT1600</Type>
<BitSize>48</BitSize>
<Info>
<SubItem>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>LED</Name>
<Info>
<DefaultValue>#x70000020</DefaultValue>
</Info>
</SubItem>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1A00</Index>
<Name>BUTTON</Name>
<Type>DT1A00</Type>
<BitSize>48</BitSize>
<Info>
<SubItem>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>BUTTON</Name>
<Info>
<DefaultValue>#x60000020</DefaultValue>
</Info>
</SubItem>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1C00</Index>
<Name>Sync Manager Communication Type</Name>
<Type>DT1C00</Type>
<BitSize>48</BitSize>
<Info>
<SubItem>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>4</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>Communications Type SM0</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>Communications Type SM1</Name>
<Info>
<DefaultValue>2</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>Communications Type SM2</Name>
<Info>
<DefaultValue>3</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>Communications Type SM3</Name>
<Info>
<DefaultValue>4</DefaultValue>
</Info>
</SubItem>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1C12</Index>
<Name>Sync Manager 2 PDO Assignment</Name>
<Type>DT1C12</Type>
<BitSize>32</BitSize>
<Info>
<SubItem>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>PDO Mapping</Name>
<Info>
<DefaultValue>#x1600</DefaultValue>
</Info>
</SubItem>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x1C13</Index>
<Name>Sync Manager 3 PDO Assignment</Name>
<Type>DT1C13</Type>
<BitSize>32</BitSize>
<Info>
<SubItem>
<Name>Max SubIndex</Name>
<Info>
<DefaultValue>1</DefaultValue>
</Info>
</SubItem>
<SubItem>
<Name>PDO Mapping</Name>
<Info>
<DefaultValue>#x1A00</DefaultValue>
</Info>
</SubItem>
</Info>
<Flags>
<Access>ro</Access>
</Flags>
</Object>
<Object>
<Index>#x6000</Index>
<Name>BUTTON</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<Info>
<DefaultValue>0</DefaultValue>
</Info>
<Flags>
<Access>ro</Access>
<PdoMapping>T</PdoMapping>
</Flags>
</Object>
<Object>
<Index>#x7000</Index>
<Name>LED</Name>
<Type>UDINT</Type>
<BitSize>32</BitSize>
<Info>
<DefaultValue>0</DefaultValue>
</Info>
<Flags>
<Access>ro</Access>
<PdoMapping>R</PdoMapping>
</Flags>
</Object>
</Objects>
</Dictionary>
</Profile>
<Fmmu>Outputs</Fmmu>
<Fmmu>Inputs</Fmmu>
<Fmmu>MBoxState</Fmmu>
<Sm ControlByte="#x26" DefaultSize="512" Enable="1" StartAddress="#x1000">MBoxOut</Sm>
<Sm ControlByte="#x22" DefaultSize="512" Enable="1" StartAddress="#x1200">MBoxIn</Sm>
<Sm ControlByte="#x24" Enable="1" StartAddress="#x1400">Outputs</Sm>
<Sm ControlByte="#x20" Enable="1" StartAddress="#x1A00">Inputs</Sm>
<RxPdo Fixed="true" Mandatory="true" Sm="2">
<Index>#x1600</Index>
<Name>LED</Name>
<Entry>
<Index>#x7000</Index>
<SubIndex>#x0</SubIndex>
<BitLen>32</BitLen>
<Name>LED</Name>
<DataType>UDINT</DataType>
</Entry>
</RxPdo>
<TxPdo Fixed="true" Mandatory="true" Sm="3">
<Index>#x1A00</Index>
<Name>BUTTON</Name>
<Entry>
<Index>#x6000</Index>
<SubIndex>#x0</SubIndex>
<BitLen>32</BitLen>
<Name>BUTTON</Name>
<DataType>UDINT</DataType>
</Entry>
</TxPdo>
<Mailbox DataLinkLayer="true">
<CoE CompleteAccess="false" PdoUpload="false" SdoInfo="true"/>
</Mailbox>
<Eeprom>
<ByteSize>2048</ByteSize>
<ConfigData>8006E08800000000</ConfigData>
<BootStrap>0010000200120002</BootStrap>
</Eeprom>
</Device>
</Devices>
</Descriptions>
</EtherCATInfo>

View File

@ -0,0 +1,120 @@
#include "esc_coe.h"
#include "utypes.h"
#include <stddef.h>
#ifndef HW_REV
#define HW_REV "1.0"
#endif
#ifndef SW_REV
#define SW_REV "1.0"
#endif
static const char acName1000[] = "Device Type";
static const char acName1008[] = "Device Name";
static const char acName1009[] = "Hardware Version";
static const char acName100A[] = "Software Version";
static const char acName1018[] = "Identity Object";
static const char acName1018_00[] = "Max SubIndex";
static const char acName1018_01[] = "Vendor ID";
static const char acName1018_02[] = "Product Code";
static const char acName1018_03[] = "Revision Number";
static const char acName1018_04[] = "Serial Number";
static const char acName1600[] = "LED";
static const char acName1600_00[] = "Max SubIndex";
static const char acName1600_01[] = "LED";
static const char acName1A00[] = "BUTTON";
static const char acName1A00_00[] = "Max SubIndex";
static const char acName1A00_01[] = "BUTTON";
static const char acName1C00[] = "Sync Manager Communication Type";
static const char acName1C00_00[] = "Max SubIndex";
static const char acName1C00_01[] = "Communications Type SM0";
static const char acName1C00_02[] = "Communications Type SM1";
static const char acName1C00_03[] = "Communications Type SM2";
static const char acName1C00_04[] = "Communications Type SM3";
static const char acName1C12[] = "Sync Manager 2 PDO Assignment";
static const char acName1C12_00[] = "Max SubIndex";
static const char acName1C12_01[] = "PDO Mapping";
static const char acName1C13[] = "Sync Manager 3 PDO Assignment";
static const char acName1C13_00[] = "Max SubIndex";
static const char acName1C13_01[] = "PDO Mapping";
static const char acName6000[] = "BUTTON";
static const char acName7000[] = "LED";
const _objd SDO1000[] =
{
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000, 0x00001389, NULL},
};
const _objd SDO1008[] =
{
{0x0, DTYPE_VISIBLE_STRING, 72, ATYPE_RO, acName1008, 0, "am335xice"},
};
const _objd SDO1009[] =
{
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName1009, 0, HW_REV},
};
const _objd SDO100A[] =
{
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName100A, 0, SW_REV},
};
const _objd SDO1018[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1018_00, 4, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_01, 0x1337, NULL},
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_02, 0x9876, NULL},
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_03, 0, NULL},
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_04, 0x00000000, NULL},
};
const _objd SDO1600[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1600_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_01, 0x70000020, NULL},
};
const _objd SDO1A00[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1A00_00, 1, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_01, 0x60000020, NULL},
};
const _objd SDO1C00[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_00, 4, NULL},
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_01, 1, NULL},
{0x02, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_02, 2, NULL},
{0x03, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_03, 3, NULL},
{0x04, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_04, 4, NULL},
};
const _objd SDO1C12[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C12_00, 1, NULL},
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C12_01, 0x1600, NULL},
};
const _objd SDO1C13[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C13_00, 1, NULL},
{0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C13_01, 0x1A00, NULL},
};
const _objd SDO6000[] =
{
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO | ATYPE_TXPDO, acName6000, 0, &Obj.BUTTON},
};
const _objd SDO7000[] =
{
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO | ATYPE_RXPDO, acName7000, 0, &Obj.LED},
};
const _objectlist SDOobjects[] =
{
{0x1000, OTYPE_VAR, 0, 0, acName1000, SDO1000},
{0x1008, OTYPE_VAR, 0, 0, acName1008, SDO1008},
{0x1009, OTYPE_VAR, 0, 0, acName1009, SDO1009},
{0x100A, OTYPE_VAR, 0, 0, acName100A, SDO100A},
{0x1018, OTYPE_RECORD, 4, 0, acName1018, SDO1018},
{0x1600, OTYPE_RECORD, 1, 0, acName1600, SDO1600},
{0x1A00, OTYPE_RECORD, 1, 0, acName1A00, SDO1A00},
{0x1C00, OTYPE_ARRAY, 4, 0, acName1C00, SDO1C00},
{0x1C12, OTYPE_ARRAY, 1, 0, acName1C12, SDO1C12},
{0x1C13, OTYPE_ARRAY, 1, 0, acName1C13, SDO1C13},
{0x6000, OTYPE_VAR, 0, 0, acName6000, SDO6000},
{0x7000, OTYPE_VAR, 0, 0, acName7000, SDO7000},
{0xffff, 0xff, 0xff, 0xff, NULL, NULL}
};

View File

@ -0,0 +1,44 @@
#ifndef __ECAT_OPTIONS_H__
#define __ECAT_OPTIONS_H__
#include "cc.h"
#define USE_FOE 0
#define USE_EOE 0
#define MBXSIZE 512
#define MBXSIZEBOOT 512
#define MBXBUFFERS 3
#define MBX0_sma 0x1000
#define MBX0_sml MBXSIZE
#define MBX0_sme MBX0_sma+MBX0_sml-1
#define MBX0_smc 0x26
#define MBX1_sma MBX0_sma+MBX0_sml
#define MBX1_sml MBXSIZE
#define MBX1_sme MBX1_sma+MBX1_sml-1
#define MBX1_smc 0x22
#define MBX0_sma_b 0x1000
#define MBX0_sml_b MBXSIZEBOOT
#define MBX0_sme_b MBX0_sma_b+MBX0_sml_b-1
#define MBX0_smc_b 0x26
#define MBX1_sma_b MBX0_sma_b+MBX0_sml_b
#define MBX1_sml_b MBXSIZEBOOT
#define MBX1_sme_b MBX1_sma_b+MBX1_sml_b-1
#define MBX1_smc_b 0x22
#define SM2_sma 0x1400
#define SM2_smc 0x24
#define SM2_act 1
#define SM3_sma 0x1A00
#define SM3_smc 0x20
#define SM3_act 1
#define MAX_RXPDO_SIZE 512
#define MAX_TXPDO_SIZE 512
#define MAX_MAPPINGS_SM2 1
#define MAX_MAPPINGS_SM3 1
#endif /* __ECAT_OPTIONS_H__ */

View File

@ -0,0 +1,85 @@
#include "esc_hw.h"
#include "ecat_slv.h"
#include "options.h"
#include "utypes.h"
#include <string.h>
#include "tiescutils.h"
#include <examples/board/include/board_i2cLed.h>
#include <examples/board/include/board_rotary_switch.h>
#if 1
/* Application variables */
_Objects Obj;
/**
* This function reads physical input values and assigns the corresponding members
* of Rb.Buttons
*/
void cb_get_inputs()
{
volatile uint8_t io_input;
Board_readRotarySwitch((uint8_t *)&io_input);
Obj.BUTTON = io_input;
}
/**
* This function writes physical output values from the corresponding members of
* Wb.LEDs
*/
void cb_set_outputs()
{
volatile uint8_t io_output;
io_output = Obj.LED;
Board_setDigOutput(io_output);
}
#endif
/* Called from stack when stopping outputs */
void user_safeoutput (void)
{
memset(&Obj.LED, 0, (sizeof(Obj.LED)));
Board_setDigOutput(0);
}
/* Configuration parameters for SOES
* SM and Mailbox parameters comes from the
* generated config.h
*/
static esc_cfg_t config =
{
.user_arg = NULL,
.use_interrupt = 1,
.watchdog_cnt = 9998,
.set_defaults_hook = NULL,
.pre_state_change_hook = NULL,
.post_state_change_hook = NULL,
.application_hook = NULL,
.safeoutput_override = user_safeoutput,
.pre_object_download_hook = NULL,
.post_object_download_hook = NULL,
.rxpdo_override = NULL,
.txpdo_override = NULL,
.esc_hw_interrupt_enable = ESC_interrupt_enable,
.esc_hw_interrupt_disable = ESC_interrupt_disable,
.esc_hw_eep_handler = ESC_eep_handler,
.esc_check_dc_handler = NULL
};
int MainInit(void)
{
ecat_slv_init(&config);
return 0;
}
void MainLoop(void)
{
ecat_slv_poll();
DIG_process(DIG_PROCESS_WD_FLAG);
}
int main()
{
common_main();
return 0;
}

View File

@ -0,0 +1,31 @@
#ifndef __UTYPES_H__
#define __UTYPES_H__
#include "cc.h"
/* Object dictionary storage */
typedef struct
{
/* Inputs */
uint32_t BUTTON;
/* Outputs */
uint32_t LED;
/* Parameters */
/* Manufacturer specific data */
/* Dynamic TX PDO:s */
/* Dynamic RX PDO:s */
/* Sync Managers */
} _Objects;
extern _Objects Obj;
#endif /* __UTYPES_H__ */

View File

@ -1,35 +0,0 @@
#ifndef __CONFIG_H__
#define __CONFIG_H__
#include <cc.h>
#define MBXSIZE 128
#define MBXSIZEBOOT 128
#define MBXBUFFERS 3
#define MBX0_sma 0x1000
#define MBX0_sml MBXSIZE
#define MBX0_sme MBX0_sma+MBX0_sml-1
#define MBX0_smc 0x26
#define MBX1_sma MBX0_sma+MBX0_sml
#define MBX1_sml MBXSIZE
#define MBX1_sme MBX1_sma+MBX1_sml-1
#define MBX1_smc 0x22
#define MBX0_sma_b 0x1000
#define MBX0_sml_b MBXSIZEBOOT
#define MBX0_sme_b MBX0_sma_b+MBX0_sml_b-1
#define MBX0_smc_b 0x26
#define MBX1_sma_b MBX0_sma_b+MBX0_sml_b
#define MBX1_sml_b MBXSIZEBOOT
#define MBX1_sme_b MBX1_sma_b+MBX1_sml_b-1
#define MBX1_smc_b 0x22
#define SM2_sma 0x1100
#define SM2_smc 0x24
#define SM2_act 1
#define SM3_sma 0x1180
#define SM3_smc 0x20
#define SM3_act 1
#endif /* __CONFIG_H__ */

View File

@ -0,0 +1,44 @@
#ifndef __ECAT_OPTIONS_H__
#define __ECAT_OPTIONS_H__
#include "cc.h"
#define USE_FOE 0
#define USE_EOE 0
#define MBXSIZE 512
#define MBXSIZEBOOT 512
#define MBXBUFFERS 3
#define MBX0_sma 0x1000
#define MBX0_sml MBXSIZE
#define MBX0_sme MBX0_sma+MBX0_sml-1
#define MBX0_smc 0x26
#define MBX1_sma MBX0_sma+MBX0_sml
#define MBX1_sml MBXSIZE
#define MBX1_sme MBX1_sma+MBX1_sml-1
#define MBX1_smc 0x22
#define MBX0_sma_b 0x1000
#define MBX0_sml_b MBXSIZEBOOT
#define MBX0_sme_b MBX0_sma_b+MBX0_sml_b-1
#define MBX0_smc_b 0x26
#define MBX1_sma_b MBX0_sma_b+MBX0_sml_b
#define MBX1_sml_b MBXSIZEBOOT
#define MBX1_sme_b MBX1_sma_b+MBX1_sml_b-1
#define MBX1_smc_b 0x22
#define SM2_sma 0x1400
#define SM2_smc 0x24
#define SM2_act 1
#define SM3_sma 0x1A00
#define SM3_smc 0x20
#define SM3_act 1
#define MAX_RXPDO_SIZE 512
#define MAX_TXPDO_SIZE 512
#define MAX_MAPPINGS_SM2 1
#define MAX_MAPPINGS_SM3 1
#endif /* __ECAT_OPTIONS_H__ */

Binary file not shown.

View File

@ -1,326 +0,0 @@
#ifndef SOES_V1
#include <stddef.h>
#include "utypes.h"
#include "esc.h"
#include "esc_coe.h"
#include "esc_foe.h"
#include "config.h"
#include "k2gice.h"
/* Global variables used by the stack */
uint8_t MBX[MBXBUFFERS * MAX(MBXSIZE,MBXSIZEBOOT)];
_MBXcontrol MBXcontrol[MBXBUFFERS];
_ESCvar ESCvar;
/* Application variables */
_Rbuffer Rb;
_Wbuffer Wb;
_Cbuffer Cb;
_Mbuffer Mb;
/* Private variables */
static volatile int watchdog;
/** Mandatory: Function to pre-qualify the incoming SDO download.
*
* @param[in] index = index of SDO download request to check
* @param[in] sub-index = sub-index of SDO download request to check
* @return 1 if the SDO Download is correct. 0 If not correct.
*/
int ESC_pre_objecthandler (uint16_t index, uint8_t subindex)
{
int result = 1;
if(ESCvar.pre_object_download_hook)
{
result = (ESCvar.pre_object_download_hook)(index, subindex);
}
return result;
}
/** Mandatory: Hook called from the slave stack SDO Download handler to act on
* user specified Index and Sub-index.
*
* @param[in] index = index of SDO download request to handle
* @param[in] sub-index = sub-index of SDO download request to handle
*/
void ESC_objecthandler (uint16_t index, uint8_t subindex)
{
switch (index)
{
/* Handle post-write of parameter values */
default:
{
if(ESCvar.post_object_download_hook != NULL)
{
(ESCvar.post_object_download_hook)(index, subindex);
}
break;
}
}
}
/** Mandatory: Hook called from the slave stack ESC_stopoutputs to act on state changes
* forcing us to stop outputs. Here we can set them to a safe state.
* set
*/
void APP_safeoutput (void)
{
DPRINT ("APP_safeoutput\n");
if(ESCvar.safeoutput_override != NULL)
{
(ESCvar.safeoutput_override)();
}
else
{
// Set safe values for Wb.LED
Wb.LED = 0;
}
}
/** Mandatory: Write local process data to Sync Manager 3, Master Inputs.
*/
void TXPDO_update (void)
{
if(ESCvar.txpdo_override != NULL)
{
(ESCvar.txpdo_override)();
}
else
{
ESC_write (SM3_sma, &Rb, ESCvar.TXPDOsize);
}
}
/** Mandatory: Read Sync Manager 2 to local process data, Master Outputs.
*/
void RXPDO_update (void)
{
if(ESCvar.rxpdo_override != NULL)
{
(ESCvar.rxpdo_override)();
}
else
{
ESC_read (SM2_sma, &Wb, ESCvar.RXPDOsize);
}
}
/** Mandatory: Function to update local I/O, call read ethercat outputs, call
* write ethercat inputs. Implement watch-dog counter to count-out if we have
* made state change affecting the App.state.
*/
void DIG_process (uint8_t flags)
{
/* Handle watchdog */
if((flags & DIG_PROCESS_WD_FLAG) > 0)
{
if (CC_ATOMIC_GET(watchdog) > 0)
{
CC_ATOMIC_SUB(watchdog, 1);
}
if ((CC_ATOMIC_GET(watchdog) <= 0) &&
((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0))
{
DPRINT("DIG_process watchdog expired\n");
ESC_stopoutput();
/* watchdog, invalid outputs */
ESC_ALerror (ALERR_WATCHDOG);
/* goto safe-op with error bit set */
ESC_ALstatus (ESCsafeop | ESCerror);
}
else if(((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) == 0))
{
CC_ATOMIC_SET(watchdog, ESCvar.watchdogcnt);
}
}
/* Handle Outputs */
if ((flags & DIG_PROCESS_OUTPUTS_FLAG) > 0)
{
if(((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0) &&
(ESCvar.ALevent & ESCREG_ALEVENT_SM2))
{
RXPDO_update();
CC_ATOMIC_SET(watchdog, ESCvar.watchdogcnt);
if(ESCvar.dcsync > 0)
{
CC_ATOMIC_ADD(ESCvar.synccounter, 1);
}
/* Set outputs */
cb_set_LED();
}
else if (ESCvar.ALevent & ESCREG_ALEVENT_SM2)
{
RXPDO_update();
}
}
/* Call application */
if ((flags & DIG_PROCESS_APP_HOOK_FLAG) > 0)
{
if((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0)
{
CC_ATOMIC_SUB(ESCvar.synccounter, 1);
}
if((ESCvar.dcsync > 0) &&
((CC_ATOMIC_GET(ESCvar.synccounter) < -ESCvar.synccounterlimit) ||
(CC_ATOMIC_GET(ESCvar.synccounter) > ESCvar.synccounterlimit)))
{
if((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0)
{
DPRINT("sync error = %d\n", ESCvar.synccounter);
ESC_stopoutput();
/* Sync error */
ESC_ALerror (ALERR_SYNCERROR);
/* goto safe-op with error bit set */
ESC_ALstatus (ESCsafeop | ESCerror);
CC_ATOMIC_SET(ESCvar.synccounter, 0);
}
}
/* Call application callback if set */
if (ESCvar.application_hook != NULL)
{
(ESCvar.application_hook)();
}
}
/* Handle Inputs */
if ((flags & DIG_PROCESS_INPUTS_FLAG) > 0)
{
if(CC_ATOMIC_GET(ESCvar.App.state) > 0)
{
/* Update inputs */
cb_get_BUTTON();
TXPDO_update();
}
}
}
/**
* Handler for SM change, SM0/1, AL CONTROL and EEPROM events, the application
* control what interrupts that should be served and re-activated with
* event mask argument
*/
void ecat_slv_worker (uint32_t event_mask)
{
do
{
/* Check the state machine */
ESC_state();
/* Check the SM activation event */
ESC_sm_act_event();
/* Check mailboxes */
while ((ESC_mbxprocess() > 0) || (ESCvar.txcue > 0))
{
ESC_coeprocess();
ESC_foeprocess();
ESC_xoeprocess();
}
/* Call emulated eeprom handler if set */
if (ESCvar.esc_hw_eep_handler != NULL)
{
(ESCvar.esc_hw_eep_handler)();
}
CC_ATOMIC_SET(ESCvar.ALevent, ESC_ALeventread());
}while(ESCvar.ALevent & event_mask);
ESC_ALeventmaskwrite(ESC_ALeventmaskread() | event_mask);
}
/**
* ISR function. It should be called from ISR for applications entirely driven by
* interrupts.
* Read and handle events for the EtherCAT state, status, mailbox and eeprom.
*/
void ecat_slv_isr (void)
{
ecat_slv_worker(ESCREG_ALEVENT_CONTROL | ESCREG_ALEVENT_SMCHANGE
| ESCREG_ALEVENT_SM0 | ESCREG_ALEVENT_SM1 | ESCREG_ALEVENT_EEP);
}
/**
* Polling function. It should be called periodically for an application
* when only SM2/DC interrupt is active.
* Read and handle events for the EtherCAT state, status, mailbox and eeprom.
*/
void ecat_slv_poll (void)
{
/* Read local time from ESC*/
ESC_read (ESCREG_LOCALTIME, (void *) &ESCvar.Time, sizeof (ESCvar.Time));
ESCvar.Time = etohl (ESCvar.Time);
/* Check the state machine */
ESC_state();
/* Check the SM activation event */
ESC_sm_act_event();
/* Check mailboxes */
if (ESC_mbxprocess())
{
ESC_coeprocess();
ESC_foeprocess();
ESC_xoeprocess();
}
/* Call emulated eeprom handler if set */
if (ESCvar.esc_hw_eep_handler != NULL)
{
(ESCvar.esc_hw_eep_handler)();
}
}
void ecat_slv (void)
{
ecat_slv_poll();
DIG_process(DIG_PROCESS_WD_FLAG | DIG_PROCESS_OUTPUTS_FLAG |
DIG_PROCESS_APP_HOOK_FLAG | DIG_PROCESS_INPUTS_FLAG);
}
/**
* Initialize the slave stack.
*/
void ecat_slv_init (esc_cfg_t * config)
{
DPRINT ("Slave stack init started\n");
ESCvar.TXPDOsize = ESCvar.ESC_SM3_sml = sizeOfPDO(TX_PDO_OBJIDX);
ESCvar.RXPDOsize = ESCvar.ESC_SM2_sml = sizeOfPDO(RX_PDO_OBJIDX);
/* Init watchdog */
watchdog = config->watchdog_cnt;
/* Call stack configuration */
ESC_config (config);
/* Call HW init */
ESC_init (config);
/* wait until ESC is started up */
while ((ESCvar.DLstatus & 0x0001) == 0)
{
ESC_read (ESCREG_DLSTATUS, (void *) &ESCvar.DLstatus,
sizeof (ESCvar.DLstatus));
ESCvar.DLstatus = etohs (ESCvar.DLstatus);
}
/* Init FoE */
FOE_init();
/* reset ESC to init state */
ESC_ALstatus (ESCinit);
ESC_ALerror (ALERR_NONE);
ESC_stopmbx();
ESC_stopinput();
ESC_stopoutput();
}
#endif

View File

@ -1,229 +1,248 @@
<?xml version="1.0" encoding="UTF-8"?>
<Slave fileVersion="1" id="k2gice" productCode="0x1234">
<Name>k2gice</Name>
<Slave xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="com.rtlabs.emf.esx" fileVersion="2" id="k2gice" productCode="0x4291ce">
<Name>k2gice_n</Name>
<Vendor>
<Id>0x1337</Id>
<Name>rt-labs</Name>
</Vendor>
<Group>
<Type>k2gice_t</Type>
<Name>k2gice_n</Name>
<Name>am335xice_n</Name>
</Group>
<Fmmu>Outputs</Fmmu>
<Fmmu>Inputs</Fmmu>
<Fmmu>MBoxState</Fmmu>
<Sm ControlByte="0x26" DefaultSize="128" StartAddress="0x1000">MBoxOut</Sm>
<Sm ControlByte="0x22" DefaultSize="128" StartAddress="0x1080">MBoxIn</Sm>
<Sm ControlByte="0x24" DefaultSize="0" StartAddress="0x1100">Outputs</Sm>
<Sm ControlByte="0x20" DefaultSize="0" StartAddress="0x1180">Inputs</Sm>
<Sm ControlByte="0x26" DefaultSize="512" StartAddress="0x1000">MBoxOut</Sm>
<Sm ControlByte="0x22" DefaultSize="512" StartAddress="0x1200">MBoxIn</Sm>
<Sm ControlByte="0x24" DefaultSize="0" StartAddress="0x1400">Outputs</Sm>
<Sm ControlByte="0x20" DefaultSize="0" StartAddress="0x1A00">Inputs</Sm>
<Mailbox CoE="true">
<Bootstrap Length="128" Start="0x1000"/>
<Standard Length="128" Start="0x1000"/>
<Bootstrap Length="512" Start="0x1000"/>
<Standard Length="512" Start="0x1000"/>
</Mailbox>
<Eeprom>
<ByteSize>2048</ByteSize>
<ConfigData>800CE08800000000</ConfigData>
<BootStrap>0010800080108000</BootStrap>
<BootStrap>0010000200120002</BootStrap>
</Eeprom>
<Dictionary>
<Item>
<Name>Device Type</Name>
<Item Managed="true">
<Index>0x1000</Index>
<Name>Device Type</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x00001389</DefaultValue>
</Item>
<Item Managed="true">
<Name>Device Name</Name>
<Index>0x1008</Index>
<Name>Device Name</Name>
<DataType>VISIBLE_STRING</DataType>
<DefaultValue>k2gice</DefaultValue>
<Length>6</Length>
</Item>
<Item>
<Name>Hardware Version</Name>
<Index>0x1009</Index>
<Name>Hardware Version</Name>
<DataType>VISIBLE_STRING</DataType>
<DefaultValue>1.0</DefaultValue>
<Length>3</Length>
</Item>
<Item>
<Name>Software Version</Name>
<Index>0x100A</Index>
<Name>Software Version</Name>
<DataType>VISIBLE_STRING</DataType>
<DefaultValue>1.0</DefaultValue>
<Length>3</Length>
</Item>
<Item Managed="true">
<Name>Identity Object</Name>
<Index>0x1018</Index>
<Name>Identity Object</Name>
<DataType>RECORD</DataType>
<SubItem>
<Name>Max SubIndex</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>4</DefaultValue>
</SubItem>
<SubItem>
<Name>Vendor ID</Name>
<Index>0x01</Index>
<Name>Vendor ID</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x1337</DefaultValue>
</SubItem>
<SubItem>
<Name>Product Code</Name>
<Index>0x02</Index>
<Name>Product Code</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x1234</DefaultValue>
<DefaultValue>0x4291ce</DefaultValue>
</SubItem>
<SubItem>
<Name>Revision Number</Name>
<Index>0x03</Index>
<Name>Revision Number</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0</DefaultValue>
</SubItem>
<SubItem>
<Name>Serial Number</Name>
<Index>0x04</Index>
<Name>Serial Number</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x00000000</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Name>LED</Name>
<Index>0x1600</Index>
<Name>LED</Name>
<DataType>RECORD</DataType>
<SubItem>
<Name>Max SubIndex</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Name>LED</Name>
<Index>0x01</Index>
<Name>LED</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x70000020</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Name>BUTTON</Name>
<Index>0x1A00</Index>
<Name>BUTTON</Name>
<DataType>RECORD</DataType>
<SubItem>
<Name>Max SubIndex</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Name>BUTTON</Name>
<Index>0x01</Index>
<Name>BUTTON</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0x60000020</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Name>Sync Manager Communication Type</Name>
<Index>0x1C00</Index>
<Name>Sync Manager Communication Type</Name>
<DataType>ARRAY</DataType>
<SubItem>
<Name>Max SubIndex</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>4</DefaultValue>
</SubItem>
<SubItem>
<Name>Communications Type SM0</Name>
<Index>0x01</Index>
<Name>Communications Type SM0</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Name>Communications Type SM1</Name>
<Index>0x02</Index>
<Name>Communications Type SM1</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>2</DefaultValue>
</SubItem>
<SubItem>
<Name>Communications Type SM2</Name>
<Index>0x03</Index>
<Name>Communications Type SM2</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>3</DefaultValue>
</SubItem>
<SubItem>
<Name>Communications Type SM3</Name>
<Index>0x04</Index>
<Name>Communications Type SM3</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>4</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Name>Sync Manager 2 PDO Assignment</Name>
<Index>0x1C12</Index>
<Name>Sync Manager 2 PDO Assignment</Name>
<DataType>ARRAY</DataType>
<SubItem>
<Name>Max SubIndex</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Name>PDO Mapping</Name>
<Index>0x01</Index>
<Name>PDO Mapping</Name>
<DataType>UNSIGNED16</DataType>
<DefaultValue>0x1600</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Name>Sync Manager 3 PDO Assignment</Name>
<Index>0x1C13</Index>
<Name>Sync Manager 3 PDO Assignment</Name>
<DataType>ARRAY</DataType>
<SubItem>
<Name>Max SubIndex</Name>
<Index>0x00</Index>
<Name>Max SubIndex</Name>
<DataType>UNSIGNED8</DataType>
<DefaultValue>1</DefaultValue>
</SubItem>
<SubItem>
<Name>PDO Mapping</Name>
<Index>0x01</Index>
<Name>PDO Mapping</Name>
<DataType>UNSIGNED16</DataType>
<DefaultValue>0x1A00</DefaultValue>
</SubItem>
</Item>
<Item Managed="true">
<Name>BUTTON</Name>
<Index>0x6000</Index>
<Access>RO</Access>
<Name>BUTTON</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0</DefaultValue>
<Access>RO</Access>
<PdoMapping>TX</PdoMapping>
<Variable>BUTTON</Variable>
<VariableType>Input</VariableType>
</Item>
<Item Managed="true">
<Name>LED</Name>
<Index>0x7000</Index>
<Access>RO</Access>
<Name>LED</Name>
<DataType>UNSIGNED32</DataType>
<DefaultValue>0</DefaultValue>
<Access>RO</Access>
<PdoMapping>RX</PdoMapping>
<Variable>LED</Variable>
<VariableType>Output</VariableType>
</Item>
</Dictionary>
<SmAssignment>
<Index>0x1C12</Index>
<Entry>
<Index>0x01</Index>
<AssignedPdo>0x1600</AssignedPdo>
</Entry>
</SmAssignment>
<SmAssignment>
<Index>0x1C13</Index>
<Entry>
<Index>0x01</Index>
<AssignedPdo>0x1A00</AssignedPdo>
</Entry>
</SmAssignment>
<RxPdo>
<Index>0x1600</Index>
<Container>LED</Container>
<Name>LED</Name>
<Entry>
<Index>0x7000</Index>
<SubIndex>0</SubIndex>
<Index>0x1</Index>
<MappedIndex>0x7000</MappedIndex>
<MappedSubIndex>0x00</MappedSubIndex>
<Variable>LED</Variable>
</Entry>
</RxPdo>
<TxPdo>
<Index>0x1A00</Index>
<Container>BUTTON</Container>
<Name>BUTTON</Name>
<Entry>
<Index>0x6000</Index>
<SubIndex>0</SubIndex>
<Index>0x1</Index>
<MappedIndex>0x6000</MappedIndex>
<MappedSubIndex>0x00</MappedSubIndex>
<Variable>BUTTON</Variable>
</Entry>
</TxPdo>
@ -231,12 +250,14 @@
<Index>0x6000</Index>
<Name>BUTTON</Name>
<Type>UNSIGNED32</Type>
<PdoMapping>TX</PdoMapping>
<ObjectType>VAR</ObjectType>
</Input>
<Output>
<Index>0x7000</Index>
<Name>LED</Name>
<Type>UNSIGNED32</Type>
<PdoMapping>RX</PdoMapping>
<ObjectType>VAR</ObjectType>
</Output>
</Slave>
</Slave>

View File

@ -8,13 +8,13 @@
<Groups>
<Group>
<Type>k2gice_t</Type>
<Name LcId="1033">k2gice_n</Name>
<Name LcId="1033">am335xice_n</Name>
</Group>
</Groups>
<Devices>
<Device Physics="YY">
<Type ProductCode="#x1234" RevisionNo="0">k2gice</Type>
<Name LcId="1033">k2gice</Name>
<Type ProductCode="#x4291ce" RevisionNo="0">k2gice</Type>
<Name LcId="1033">k2gice_n</Name>
<GroupType>k2gice_t</GroupType>
<Profile>
<ProfileNo>5001</ProfileNo>
@ -312,7 +312,7 @@
<SubItem>
<Name>Product Code</Name>
<Info>
<DefaultValue>#x1234</DefaultValue>
<DefaultValue>#x4291ce</DefaultValue>
</Info>
</SubItem>
<SubItem>
@ -475,6 +475,7 @@
</Info>
<Flags>
<Access>ro</Access>
<PdoMapping>T</PdoMapping>
</Flags>
</Object>
<Object>
@ -487,6 +488,7 @@
</Info>
<Flags>
<Access>ro</Access>
<PdoMapping>R</PdoMapping>
</Flags>
</Object>
</Objects>
@ -495,16 +497,16 @@
<Fmmu>Outputs</Fmmu>
<Fmmu>Inputs</Fmmu>
<Fmmu>MBoxState</Fmmu>
<Sm ControlByte="#x26" DefaultSize="128" Enable="1" StartAddress="#x1000">MBoxOut</Sm>
<Sm ControlByte="#x22" DefaultSize="128" Enable="1" StartAddress="#x1080">MBoxIn</Sm>
<Sm ControlByte="#x24" Enable="1" StartAddress="#x1100">Outputs</Sm>
<Sm ControlByte="#x20" Enable="1" StartAddress="#x1180">Inputs</Sm>
<Sm ControlByte="#x26" DefaultSize="512" Enable="1" StartAddress="#x1000">MBoxOut</Sm>
<Sm ControlByte="#x22" DefaultSize="512" Enable="1" StartAddress="#x1200">MBoxIn</Sm>
<Sm ControlByte="#x24" Enable="1" StartAddress="#x1400">Outputs</Sm>
<Sm ControlByte="#x20" Enable="1" StartAddress="#x1A00">Inputs</Sm>
<RxPdo Fixed="true" Mandatory="true" Sm="2">
<Index>#x1600</Index>
<Name>LED</Name>
<Entry>
<Index>#x7000</Index>
<SubIndex>0</SubIndex>
<SubIndex>#x0</SubIndex>
<BitLen>32</BitLen>
<Name>LED</Name>
<DataType>UDINT</DataType>
@ -515,19 +517,19 @@
<Name>BUTTON</Name>
<Entry>
<Index>#x6000</Index>
<SubIndex>0</SubIndex>
<SubIndex>#x0</SubIndex>
<BitLen>32</BitLen>
<Name>BUTTON</Name>
<DataType>UDINT</DataType>
</Entry>
</TxPdo>
<Mailbox DataLinkLayer="true">
<CoE CompleteAccess="false" PdoUpload="true" SdoInfo="true"/>
<CoE CompleteAccess="false" PdoUpload="false" SdoInfo="true"/>
</Mailbox>
<Eeprom>
<ByteSize>2048</ByteSize>
<ConfigData>800CE08800000000</ConfigData>
<BootStrap>0010800080108000</BootStrap>
<ConfigData>800EE08800000000</ConfigData>
<BootStrap>0010000200120002</BootStrap>
</Eeprom>
</Device>
</Devices>

View File

@ -1,4 +1,3 @@
#ifndef SOES_V1
#include "esc_coe.h"
#include "utypes.h"
#include <stddef.h>
@ -12,13 +11,9 @@
#endif
static const char acName1000[] = "Device Type";
static const char acName1000_0[] = "Device Type";
static const char acName1008[] = "Device Name";
static const char acName1008_0[] = "Device Name";
static const char acName1009[] = "Hardware Version";
static const char acName1009_0[] = "Hardware Version";
static const char acName100A[] = "Software Version";
static const char acName100A_0[] = "Software Version";
static const char acName1018[] = "Identity Object";
static const char acName1018_00[] = "Max SubIndex";
static const char acName1018_01[] = "Vendor ID";
@ -44,31 +39,29 @@ static const char acName1C13[] = "Sync Manager 3 PDO Assignment";
static const char acName1C13_00[] = "Max SubIndex";
static const char acName1C13_01[] = "PDO Mapping";
static const char acName6000[] = "BUTTON";
static const char acName6000_0[] = "BUTTON";
static const char acName7000[] = "LED";
static const char acName7000_0[] = "LED";
const _objd SDO1000[] =
{
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000_0, 0x00001389, NULL},
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000, 0x00001389, NULL},
};
const _objd SDO1008[] =
{
{0x0, DTYPE_VISIBLE_STRING, 48, ATYPE_RO, acName1008_0, 0, "k2gice"},
{0x0, DTYPE_VISIBLE_STRING, 48, ATYPE_RO, acName1008, 0, "k2gice"},
};
const _objd SDO1009[] =
{
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName1009_0, 0, HW_REV},
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName1009, 0, HW_REV},
};
const _objd SDO100A[] =
{
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName100A_0, 0, SW_REV},
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName100A, 0, SW_REV},
};
const _objd SDO1018[] =
{
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1018_00, 4, NULL},
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_01, 0x1337, NULL},
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_02, 0x1234, NULL},
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_02, 0x4291ce, NULL},
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_03, 0, NULL},
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_04, 0x00000000, NULL},
};
@ -102,11 +95,11 @@ const _objd SDO1C13[] =
};
const _objd SDO6000[] =
{
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName6000_0, 0, &Rb.BUTTON},
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO | ATYPE_TXPDO, acName6000, 0, &Obj.BUTTON},
};
const _objd SDO7000[] =
{
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName7000_0, 0, &Wb.LED},
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO | ATYPE_RXPDO, acName7000, 0, &Obj.LED},
};
const _objectlist SDOobjects[] =
@ -125,4 +118,3 @@ const _objectlist SDOobjects[] =
{0x7000, OTYPE_VAR, 0, 0, acName7000, SDO7000},
{0xffff, 0xff, 0xff, 0xff, NULL, NULL}
};
#endif

View File

@ -1,38 +1,39 @@
#include "k2gice.h"
#include "esc_hw.h"
#include "config.h"
#include "ecat_slv.h"
#include "options.h"
#include "utypes.h"
#include <string.h>
#include "tiescutils.h"
#include <examples/board/include/board_i2cLed.h>
#include <examples/board/include/board_rotary_switch.h>
/* Application variables */
_Objects Obj;
/**
* This function reads physical input values and assigns the corresponding members
* of Rb.Buttons
*/
void cb_get_BUTTON()
void cb_get_inputs()
{
volatile uint8_t io_input;
Board_readRotarySwitch(&io_input);
Rb.BUTTON = io_input;
Board_readRotarySwitch((uint8_t *)&io_input);
Obj.BUTTON = io_input;
}
/**
* This function writes physical output values from the corresponding members of
* Wb.LEDs
* This function writes physical output values from the corresponding members
*/
void cb_set_LED()
void cb_set_outputs()
{
volatile uint8_t io_output;
io_output = Wb.LED;
io_output = Obj.LED;
Board_setDigOutput(io_output);
}
/* Called from stack when stopping outputs */
void user_safeoutput (void)
{
memset(&Wb, 0, (sizeof(Wb)));
memset(&Obj.LED, 0, (sizeof(Obj.LED)));
Board_setDigOutput(0);
}
@ -44,16 +45,8 @@ static esc_cfg_t config =
{
.user_arg = NULL,
.use_interrupt = 1,
.watchdog_cnt = 9999,
.mbxsize = MBXSIZE,
.mbxsizeboot = MBXSIZEBOOT,
.mbxbuffers = MBXBUFFERS,
.mb[0] = {MBX0_sma, MBX0_sml, MBX0_sme, MBX0_smc, 0},
.mb[1] = {MBX1_sma, MBX1_sml, MBX1_sme, MBX1_smc, 0},
.mb_boot[0] = {MBX0_sma_b, MBX0_sml_b, MBX0_sme_b, MBX0_smc_b, 0},
.mb_boot[1] = {MBX1_sma_b, MBX1_sml_b, MBX1_sme_b, MBX1_smc_b, 0},
.pdosm[0] = {SM2_sma, 0, 0, SM2_smc, SM2_act},
.pdosm[1] = {SM3_sma, 0, 0, SM3_smc, SM3_act},
.watchdog_cnt = 9998,
.set_defaults_hook = NULL,
.pre_state_change_hook = NULL,
.post_state_change_hook = NULL,
.application_hook = NULL,
@ -64,7 +57,8 @@ static esc_cfg_t config =
.txpdo_override = NULL,
.esc_hw_interrupt_enable = ESC_interrupt_enable,
.esc_hw_interrupt_disable = ESC_interrupt_disable,
.esc_hw_eep_handler = ESC_eep_handler
.esc_hw_eep_handler = ESC_eep_handler,
.esc_check_dc_handler = NULL
};
int MainInit(void)

View File

@ -1,41 +1,31 @@
#ifndef __UTYPES_H__
#define __UTYPES_H__
#include <cc.h>
#include "cc.h"
/* Object dictionary storage */
/* Inputs */
CC_PACKED_BEGIN
typedef struct
{
/* Inputs */
uint32_t BUTTON;
} CC_PACKED _Rbuffer;
CC_PACKED_END
/* Outputs */
CC_PACKED_BEGIN
typedef struct
{
/* Outputs */
uint32_t LED;
} CC_PACKED _Wbuffer;
CC_PACKED_END
/* Parameters */
CC_PACKED_BEGIN
typedef struct
{
} CC_PACKED _Cbuffer;
CC_PACKED_END
/* Parameters */
/* Manufacturer specific data */
CC_PACKED_BEGIN
typedef struct
{
} CC_PACKED _Mbuffer;
CC_PACKED_END
/* Manufacturer specific data */
extern _Rbuffer Rb;
extern _Wbuffer Wb;
extern _Cbuffer Cb;
extern _Mbuffer Mb;
/* Dynamic TX PDO:s */
/* Dynamic RX PDO:s */
/* Sync Managers */
} _Objects;
extern _Objects Obj;
#endif /* __UTYPES_H__ */

View File

@ -13,7 +13,7 @@ SOES_DIR = ../../soes
SRC = \
main.c \
objectlist.c \
soes.c \
$(SOES_DIR)/ecat_slv.c \
$(SOES_DIR)/esc.c \
$(SOES_DIR)/esc_coe.c \
$(SOES_DIR)/esc_eep.c \

View File

@ -0,0 +1,44 @@
#ifndef __ECAT_OPTIONS_H__
#define __ECAT_OPTIONS_H__
#include "cc.h"
#define USE_FOE 0
#define USE_EOE 0
#define MBXSIZE 128
#define MBXSIZEBOOT 128
#define MBXBUFFERS 3
#define MBX0_sma 0x1000
#define MBX0_sml MBXSIZE
#define MBX0_sme MBX0_sma+MBX0_sml-1
#define MBX0_smc 0x26
#define MBX1_sma MBX0_sma+MBX0_sml
#define MBX1_sml MBXSIZE
#define MBX1_sme MBX1_sma+MBX1_sml-1
#define MBX1_smc 0x22
#define MBX0_sma_b 0x1000
#define MBX0_sml_b MBXSIZEBOOT
#define MBX0_sme_b MBX0_sma_b+MBX0_sml_b-1
#define MBX0_smc_b 0x26
#define MBX1_sma_b MBX0_sma_b+MBX0_sml_b
#define MBX1_sml_b MBXSIZEBOOT
#define MBX1_sme_b MBX1_sma_b+MBX1_sml_b-1
#define MBX1_smc_b 0x22
#define SM2_sma 0x1100
#define SM2_smc 0x24
#define SM2_act 1
#define SM3_sma 0x1180
#define SM3_smc 0x20
#define SM3_act 1
#define MAX_RXPDO_SIZE 42
#define MAX_TXPDO_SIZE 42
#define MAX_MAPPINGS_SM2 0
#define MAX_MAPPINGS_SM3 0
#endif /* __ECAT_OPTIONS_H__ */

View File

@ -1,15 +1,136 @@
#include <string.h>
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
#include "ecat_slv.h"
#include "utypes.h"
#include "xmc_gpio.h"
#include "soes.h"
#ifdef XMC4800_F144x2048
#define P_LED P5_8
#define P_BTN P15_12
#endif
int main(void)
#ifdef XMC4300_F100x256
#define P_LED P4_1
#define P_BTN P3_4
#endif
extern void ESC_eep_handler(void);
/* Application variables */
_Rbuffer Rb;
_Wbuffer Wb;
_Cbuffer Cb;
uint8_t * rxpdo = (uint8_t *)&Wb.LED;
uint8_t * txpdo = (uint8_t *)&Rb.button;
uint32_t encoder_scale;
uint32_t encoder_scale_mirror;
static const XMC_GPIO_CONFIG_t gpio_config_btn = {
.mode = XMC_GPIO_MODE_INPUT_INVERTED_PULL_UP,
.output_level = 0,
.output_strength = 0
};
static const XMC_GPIO_CONFIG_t gpio_config_led = {
.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL,
.output_level = XMC_GPIO_OUTPUT_LEVEL_LOW,
.output_strength = XMC_GPIO_OUTPUT_STRENGTH_STRONG_SOFT_EDGE
};
void cb_get_inputs (void)
{
soes_init();
while(1) {
soes_task();
}
Rb.button = XMC_GPIO_GetInput(P_BTN);
Cb.reset_counter++;
Rb.encoder = ESCvar.Time;
}
void cb_set_outputs (void)
{
if (Wb.LED)
{
XMC_GPIO_SetOutputHigh(P_LED);
}
else
{
XMC_GPIO_SetOutputLow(P_LED);
}
}
void post_object_download_hook (uint16_t index, uint8_t subindex,
uint16_t flags)
{
switch(index)
{
case 0x7100:
{
switch (subindex)
{
case 0x01:
{
encoder_scale_mirror = encoder_scale;
break;
}
}
break;
}
case 0x8001:
{
switch (subindex)
{
case 0x01:
{
Cb.reset_counter = 0;
break;
}
}
break;
}
}
}
void soes (void * arg)
{
/* Setup config hooks */
static esc_cfg_t config =
{
.user_arg = NULL,
.use_interrupt = 0,
.watchdog_cnt = 5000,
.set_defaults_hook = NULL,
.pre_state_change_hook = NULL,
.post_state_change_hook = NULL,
.application_hook = NULL,
.safeoutput_override = NULL,
.pre_object_download_hook = NULL,
.post_object_download_hook = post_object_download_hook,
.rxpdo_override = NULL,
.txpdo_override = NULL,
.esc_hw_interrupt_enable = NULL,
.esc_hw_interrupt_disable = NULL,
.esc_hw_eep_handler = ESC_eep_handler
};
DPRINT ("SOES (Simple Open EtherCAT Slave)\n");
// configure I/O
XMC_GPIO_Init(P_BTN, &gpio_config_btn);
XMC_GPIO_Init(P_LED, &gpio_config_led);
ecat_slv_init (&config);
while (1)
{
ecat_slv();
}
}
int main (void)
{
soes (NULL);
return 0;
}

View File

@ -1,316 +0,0 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
/** \file
* \brief
* The application.
*
* The application, the main loop that service EtherCAT.
*/
#include <stddef.h>
#include "esc.h"
#include "esc_coe.h"
#include "esc_eep.h"
#include "esc_hw_eep.h"
#include "utypes.h"
#include "soes.h"
#define WD_RESET 1000
#define DEFAULTTXPDOMAP 0x1a00
#define DEFAULTRXPDOMAP 0x1600
#define DEFAULTTXPDOITEMS 1
#define DEFAULTRXPDOITEMS 1
static const XMC_GPIO_CONFIG_t gpio_config_btn = {
.mode = XMC_GPIO_MODE_INPUT_INVERTED_PULL_UP,
.output_level = 0,
.output_strength = 0
};
static const XMC_GPIO_CONFIG_t gpio_config_led = {
.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL,
.output_level = XMC_GPIO_OUTPUT_LEVEL_LOW,
.output_strength = XMC_GPIO_OUTPUT_STRENGTH_STRONG_SOFT_EDGE
};
uint32_t encoder_scale;
uint32_t encoder_scale_mirror;
/* Global variables used by the stack */
uint8_t MBX[MBXBUFFERS * MAX(MBXSIZE,MBXSIZEBOOT)];
_MBXcontrol MBXcontrol[MBXBUFFERS];
_ESCvar ESCvar;
/* Application variables */
_Rbuffer Rb;
_Wbuffer Wb;
_Cbuffer Cb;
/* Private variables */
volatile uint8_t digoutput;
volatile uint8_t diginput;
uint16_t txpdomap = DEFAULTTXPDOMAP;
uint16_t rxpdomap = DEFAULTRXPDOMAP;
uint8_t txpdoitems = DEFAULTTXPDOITEMS;
uint8_t rxpdoitems = DEFAULTTXPDOITEMS;
/** Function to pre-qualify the incoming SDO download.
*
* @param[in] index = index of SDO download request to check
* @param[in] sub-index = sub-index of SDO download request to check
* @return 1 if the SDO Download is correct. 0 If not correct.
*/
int ESC_pre_objecthandler (uint16_t index, uint8_t subindex)
{
if ((index == 0x1c12) && (subindex > 0) && (rxpdoitems != 0))
{
SDO_abort (index, subindex, ABORT_READONLY);
return 0;
}
if ((index == 0x1c13) && (subindex > 0) && (txpdoitems != 0))
{
SDO_abort (index, subindex, ABORT_READONLY);
return 0;
}
return 1;
}
/** Mandatory: Hook called from the slave stack SDO Download handler to act on
* user specified Index and Sub-index.
*
* @param[in] index = index of SDO download request to handle
* @param[in] sub-index = sub-index of SDO download request to handle
*/
void ESC_objecthandler (uint16_t index, uint8_t subindex)
{
switch (index)
{
case 0x1c12:
{
if (rxpdoitems > 1)
{
rxpdoitems = 1;
}
if ((rxpdomap != 0x1600) && (rxpdomap != 0x1601)
&& (rxpdomap != 0x0000))
{
rxpdomap = 0x1600;
}
ESCvar.RXPDOsize = ESCvar.ESC_SM2_sml = sizeOfPDO(RX_PDO_OBJIDX);
break;
}
case 0x1c13:
{
if (txpdoitems > 1)
{
txpdoitems = 1;
}
if ((txpdomap != 0x1A00) && (txpdomap != 0x1A01)
&& (rxpdomap != 0x0000))
{
txpdomap = 0x1A00;
}
ESCvar.TXPDOsize = ESCvar.ESC_SM3_sml = sizeOfPDO(TX_PDO_OBJIDX);
break;
}
case 0x7100:
{
switch (subindex)
{
case 0x01:
{
encoder_scale_mirror = encoder_scale;
break;
}
}
break;
}
case 0x8001:
{
switch (subindex)
{
case 0x01:
{
Cb.reset_counter = 0;
break;
}
}
break;
}
}
}
/** Mandatory: Hook called from the slave stack ESC_stopoutputs to act on state changes
* forcing us to stop outputs. Here we can set them to a safe state.
* set
*/
void APP_safeoutput (void)
{
DPRINT ("APP_safeoutput called\n");
Wb.LED = 0;
}
/** Mandatory: Write local process data to Sync Manager 3, Master Inputs.
*/
void TXPDO_update (void)
{
ESC_write (SM3_sma, &Rb.button, ESCvar.TXPDOsize);
}
/** Mandatory: Read Sync Manager 2 to local process data, Master Outputs.
*/
void RXPDO_update (void)
{
ESC_read (SM2_sma, &Wb.LED, ESCvar.RXPDOsize);
}
/** Mandatory: Function to update local I/O, call read ethercat outputs, call
* write ethercat inputs. Implement watch-dog counter to count-out if we have
* made state change affecting the App.state.
*/
void DIG_process (void)
{
if (wd_cnt)
{
wd_cnt--;
}
if (ESCvar.App.state & APPSTATE_OUTPUT)
{
/* SM2 trigger ? */
if (ESCvar.ALevent & ESCREG_ALEVENT_SM2)
{
ESCvar.ALevent &= ~ESCREG_ALEVENT_SM2;
RXPDO_update ();
wd_cnt = WD_RESET;
/* dummy output point */
if (Wb.LED) {
XMC_GPIO_SetOutputHigh(P_LED);
} else {
XMC_GPIO_SetOutputLow(P_LED);
}
}
if (!wd_cnt)
{
DPRINT("DIG_process watchdog tripped\n");
ESC_stopoutput ();
/* watchdog, invalid outputs */
ESC_ALerror (ALERR_WATCHDOG);
/* goto safe-op with error bit set */
ESC_ALstatus (ESCsafeop | ESCerror);
}
}
else
{
wd_cnt = WD_RESET;
}
if (ESCvar.App.state)
{
Rb.button = XMC_GPIO_GetInput(P_BTN);
Cb.reset_counter++;
Rb.encoder = ESCvar.Time;
TXPDO_update ();
}
}
/** SOES main loop. Start by initializing the stack software followed by
* the application loop for cyclic read the EtherCAT state and staus, update
* of I/O.
*/
void soes_init (void)
{
DPRINT ("SOES (Simple Open EtherCAT Slave)\n");
// configure I/O
XMC_GPIO_Init(P_BTN, &gpio_config_btn);
XMC_GPIO_Init(P_LED, &gpio_config_led);
ESCvar.TXPDOsize = ESCvar.ESC_SM3_sml = sizeOfPDO(TX_PDO_OBJIDX);
ESCvar.RXPDOsize = ESCvar.ESC_SM2_sml = sizeOfPDO(RX_PDO_OBJIDX);
/* Setup config hooks */
static esc_cfg_t config =
{
.user_arg = NULL,
.use_interrupt = 0,
.watchdog_cnt = 0,
.mbxsize = MBXSIZE,
.mbxsizeboot = MBXSIZEBOOT,
.mbxbuffers = MBXBUFFERS,
.mb[0] = {MBX0_sma, MBX0_sml, MBX0_sme, MBX0_smc, 0},
.mb[1] = {MBX1_sma, MBX1_sml, MBX1_sme, MBX1_smc, 0},
.mb_boot[0] = {MBX0_sma_b, MBX0_sml_b, MBX0_sme_b, MBX0_smc_b, 0},
.mb_boot[1] = {MBX1_sma_b, MBX1_sml_b, MBX1_sme_b, MBX1_smc_b, 0},
.pdosm[0] = {SM2_sma, 0, 0, SM2_smc, SM2_act},
.pdosm[1] = {SM3_sma, 0, 0, SM3_smc, SM3_act},
.pre_state_change_hook = NULL,
.post_state_change_hook = NULL,
.application_hook = NULL,
.safeoutput_override = NULL,
.pre_object_download_hook = NULL,
.post_object_download_hook = NULL,
.rxpdo_override = NULL,
.txpdo_override = NULL,
.esc_hw_interrupt_enable = NULL,
.esc_hw_interrupt_disable = NULL,
.esc_hw_eep_handler = NULL
};
ESC_config (&config);
ESC_init (NULL);
/* wait until ESC is started up */
do {
ESC_read (ESCREG_DLSTATUS, (void *) &ESCvar.DLstatus,
sizeof (ESCvar.DLstatus));
ESCvar.DLstatus = etohs (ESCvar.DLstatus);
} while ((ESCvar.DLstatus & 0x0001) == 0);
/* reset ESC to init state */
ESC_ALstatus (ESCinit);
ESC_ALerror (ALERR_NONE);
ESC_stopmbx ();
ESC_stopinput ();
ESC_stopoutput ();
}
void soes_task (void)
{
/* On init restore PDO mappings to default size */
if((ESCvar.ALstatus & 0x0f) == ESCinit)
{
txpdomap = DEFAULTTXPDOMAP;
rxpdomap = DEFAULTRXPDOMAP;
txpdoitems = DEFAULTTXPDOITEMS;
rxpdoitems = DEFAULTTXPDOITEMS;
}
/* Read local time from ESC*/
ESC_read (ESCREG_LOCALTIME, (void *) &ESCvar.Time, sizeof (ESCvar.Time));
ESCvar.Time = etohl (ESCvar.Time);
/* Check the state machine */
ESC_state();
/* Check the SM activation event */
ESC_sm_act_event();
/* If else to two separate execution paths
* If we're running BOOSTRAP
* - MailBox
* - FoE
* Else we're running normal execution
* - MailBox
* - CoE
*/
if (ESC_mbxprocess ())
{
ESC_coeprocess ();
ESC_xoeprocess ();
}
DIG_process ();
EEP_process ();
EEP_hw_process();
}

View File

@ -1,14 +0,0 @@
#ifndef _SOES_H_
#define _SOES_H_
#include <xmc_gpio.h>
#include <xmc_scu.h>
#define P_LED P4_1
#define P_BTN P3_4
extern void soes_init (void);
extern void soes_task (void);
#endif

View File

@ -16,21 +16,27 @@
#include <cc.h>
CC_PACKED_BEGIN
typedef struct
{
uint8_t state;
uint8_t button;
uint32_t encoder;
} _Rbuffer;
}CC_PACKED _Rbuffer;
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct
{
uint8_t LED;
} _Wbuffer;
}CC_PACKED _Wbuffer;
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct
{
uint32_t reset_counter;
} _Cbuffer;
}CC_PACKED _Cbuffer;
CC_PACKED_END
#endif

View File

@ -1,14 +1,20 @@
set(SOES_DEMO applications/linux_lan9252demo)
if(RPI_VARIANT)
set (SOES_DEMO applications/raspberry_lan9252demo)
set(HAL_SOURCES
${SOES_SOURCE_DIR}/soes/hal/raspberrypi-lan9252/esc_hw.c
${SOES_SOURCE_DIR}/soes/hal/raspberrypi-lan9252/esc_hw.h
)
else()
set(SOES_DEMO applications/linux_lan9252demo)
set(HAL_SOURCES
${SOES_SOURCE_DIR}/soes/hal/linux-lan9252/esc_hw.c
)
endif()
include_directories(
${SOES_SOURCE_DIR}/soes/include/sys/gcc
${SOES_SOURCE_DIR}/${SOES_DEMO}
)
set(HAL_SOURCES
${SOES_SOURCE_DIR}/soes/hal/linux-lan9252/esc_hw.c
)
# Common compile flags
add_compile_options(-Wall -Wextra -Wno-unused-parameter -Werror)
add_compile_options(-Wall -Wextra -Wconversion -Wno-unused-parameter -Werror)

View File

@ -0,0 +1,29 @@
# Guard against multiple inclusion
if(_TOOLCHAIN_CMAKE_)
return()
endif()
set(_TOOLCHAIN_CMAKE_ TRUE)
INCLUDE(CMakeForceCompiler)
SET(CMAKE_SYSTEM_NAME rt-kernel)
# specify the cross compiler
CMAKE_FORCE_C_COMPILER(arm-eabi-gcc GNU)
CMAKE_FORCE_CXX_COMPILER(arm-eabi-g++ GNU)
set(ARCH xmc4)
set(CPU cortex-m4f)
set(BSP xmc48relax)
set(MACHINE_FLAGS "-mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16")
set(SOES_DEMO applications/rtl_xmc4_dynpdo)
include_directories(
${SOES_SOURCE_DIR}/${SOES_DEMO}
${SOES_SOURCE_DIR}/soes/hal/rt-kernel-xmc4
)
set(HAL_SOURCES
${SOES_SOURCE_DIR}/soes/hal/rt-kernel-xmc4/esc_hw.c
${SOES_SOURCE_DIR}/soes/hal/rt-kernel-xmc4/esc_hw_eep.c
)

View File

@ -11,6 +11,9 @@ add_library (soes
esc_eoe.h
esc_eep.c
esc_eep.h
ecat_slv.c
ecat_slv.h
options.h
${HAL_SOURCES}
)

View File

@ -1,80 +1,135 @@
#ifndef SOES_V1
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
#include <stddef.h>
#include "utypes.h"
#include "esc.h"
#include "esc_coe.h"
#include "esc_foe.h"
#include "esc_eoe.h"
#include "config.h"
#include "slave.h"
#include "ecat_slv.h"
#define IS_RXPDO(index) ((index) >= 0x1600 && (index) < 0x1800)
#define IS_TXPDO(index) ((index) >= 0x1A00 && (index) < 0x1C00)
/* Global variables used by the stack */
uint8_t MBX[MBXBUFFERS * MAX(MBXSIZE,MBXSIZEBOOT)];
_MBXcontrol MBXcontrol[MBXBUFFERS];
_SMmap SMmap2[MAX_MAPPINGS_SM2];
_SMmap SMmap3[MAX_MAPPINGS_SM3];
_ESCvar ESCvar;
/* Application variables */
_Rbuffer Rb;
_Wbuffer Wb;
_Cbuffer Cb;
_Mbuffer Mb;
/* Private variables */
static volatile int watchdog;
/** Mandatory: Function to pre-qualify the incoming SDO download.
#if MAX_MAPPINGS_SM2 > 0
static uint8_t rxpdo[MAX_RXPDO_SIZE] __attribute__((aligned (8)));
#else
extern uint8_t rxpdo[];
#endif
#if MAX_MAPPINGS_SM3 > 0
static uint8_t txpdo[MAX_TXPDO_SIZE] __attribute__((aligned (8)));
#else
extern uint8_t txpdo[];
#endif
/** Function to pre-qualify the incoming SDO download.
*
* @param[in] index = index of SDO download request to check
* @param[in] sub-index = sub-index of SDO download request to check
* @return 1 if the SDO Download is correct. 0 If not correct.
* @return SDO abort code, or 0 on success
*/
int ESC_pre_objecthandler (uint16_t index, uint8_t subindex)
uint32_t ESC_download_pre_objecthandler (uint16_t index,
uint8_t subindex,
void * data,
size_t size,
uint16_t flags)
{
int result = 1;
if(ESCvar.pre_object_download_hook)
if (IS_RXPDO (index) ||
IS_TXPDO (index) ||
index == RX_PDO_OBJIDX ||
index == TX_PDO_OBJIDX)
{
result = (ESCvar.pre_object_download_hook)(index, subindex);
uint8_t minSub = ((flags & COMPLETE_ACCESS_FLAG) == 0) ? 0 : 1;
if (subindex > minSub && COE_maxSub (index) != 0)
{
return ABORT_SUBINDEX0_NOT_ZERO;
}
}
return result;
if (ESCvar.pre_object_download_hook)
{
return (ESCvar.pre_object_download_hook) (index,
subindex,
data,
size,
flags);
}
return 0;
}
/** Mandatory: Hook called from the slave stack SDO Download handler to act on
/** Hook called from the slave stack SDO Download handler to act on
* user specified Index and Sub-index.
*
* @param[in] index = index of SDO download request to handle
* @param[in] sub-index = sub-index of SDO download request to handle
* @return SDO abort code, or 0 on success
*/
void ESC_objecthandler (uint16_t index, uint8_t subindex)
uint32_t ESC_download_post_objecthandler (uint16_t index, uint8_t subindex, uint16_t flags)
{
switch (index)
if (ESCvar.post_object_download_hook != NULL)
{
/* Handle post-write of parameter values */
case 0x8000:
{
cb_post_write_Parameters(subindex);
break;
}
case 0x8001:
{
cb_post_write_variableRW(subindex);
break;
}
default:
{
if(ESCvar.post_object_download_hook != NULL)
{
(ESCvar.post_object_download_hook)(index, subindex);
}
break;
}
return (ESCvar.post_object_download_hook)(index, subindex, flags);
}
return 0;
}
/** Mandatory: Hook called from the slave stack ESC_stopoutputs to act on state changes
/** Function to pre-qualify the incoming SDO upload.
*
* @param[in] index = index of SDO upload request to handle
* @param[in] sub-index = sub-index of SDO upload request to handle
* @return SDO abort code, or 0 on success
*/
uint32_t ESC_upload_pre_objecthandler (uint16_t index,
uint8_t subindex,
void * data,
size_t *size,
uint16_t flags)
{
if (ESCvar.pre_object_upload_hook != NULL)
{
return (ESCvar.pre_object_upload_hook) (index,
subindex,
data,
size,
flags);
}
return 0;
}
/** Hook called from the slave stack SDO Upload handler to act on
* user specified Index and Sub-index.
*
* @param[in] index = index of SDO upload request to handle
* @param[in] sub-index = sub-index of SDO upload request to handle
* @return SDO abort code, or 0 on success
*/
uint32_t ESC_upload_post_objecthandler (uint16_t index, uint8_t subindex, uint16_t flags)
{
if (ESCvar.post_object_upload_hook != NULL)
{
return (ESCvar.post_object_upload_hook)(index, subindex, flags);
}
return 0;
}
/** Hook called from the slave stack ESC_stopoutputs to act on state changes
* forcing us to stop outputs. Here we can set them to a safe state.
* set
*/
void APP_safeoutput (void)
{
@ -84,23 +139,9 @@ void APP_safeoutput (void)
{
(ESCvar.safeoutput_override)();
}
else
{
// Set safe values for Wb.LEDgroup1
Wb.LEDgroup1.LED = 0;
// Set safe values for Wb.LEDgroup2
Wb.LEDgroup2.LED = 0;
// Set safe values for Wb.LEDgroup3
Wb.LEDgroup3.LED = 0;
// Set safe values for Wb.LEDgroup4
Wb.LEDgroup4.LED = 0;
// Set safe values for Wb.LEDgroup5
Wb.LEDgroup5.LED5 = 0;
Wb.LEDgroup5.LED678 = 0;
}
}
/** Mandatory: Write local process data to Sync Manager 3, Master Inputs.
/** Write local process data to Sync Manager 3, Master Inputs.
*/
void TXPDO_update (void)
{
@ -110,11 +151,15 @@ void TXPDO_update (void)
}
else
{
ESC_write (SM3_sma, &Rb, ESCvar.TXPDOsize);
if (MAX_MAPPINGS_SM3 > 0)
{
COE_pdoPack (txpdo, ESCvar.sm3mappings, SMmap3);
}
ESC_write (ESC_SM3_sma, txpdo, ESCvar.ESC_SM3_sml);
}
}
/** Mandatory: Read Sync Manager 2 to local process data, Master Outputs.
/** Read Sync Manager 2 to local process data, Master Outputs.
*/
void RXPDO_update (void)
{
@ -124,11 +169,25 @@ void RXPDO_update (void)
}
else
{
ESC_read (SM2_sma, &Wb, ESCvar.RXPDOsize);
ESC_read (ESC_SM2_sma, rxpdo, ESCvar.ESC_SM2_sml);
if (MAX_MAPPINGS_SM2 > 0)
{
COE_pdoUnpack (rxpdo, ESCvar.sm2mappings, SMmap2);
}
}
}
/** Mandatory: Function to update local I/O, call read ethercat outputs, call
/* Set the watchdog count value, don't have any affect when using
* HW watchdog 0x4xx
*
* @param[in] watchdogcnt = new watchdog count value
*/
void APP_setwatchdog (int watchdogcnt)
{
CC_ATOMIC_SET(ESCvar.watchdogcnt, watchdogcnt);
}
/* Function to update local I/O, call read ethercat outputs, call
* write ethercat inputs. Implement watch-dog counter to count-out if we have
* made state change affecting the App.state.
*/
@ -137,21 +196,17 @@ void DIG_process (uint8_t flags)
/* Handle watchdog */
if((flags & DIG_PROCESS_WD_FLAG) > 0)
{
if (CC_ATOMIC_GET(watchdog) > 0)
{
CC_ATOMIC_SUB(watchdog, 1);
}
if ((CC_ATOMIC_GET(watchdog) <= 0) &&
((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0))
((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0) &&
(ESCvar.ESC_SM2_sml > 0))
{
DPRINT("DIG_process watchdog expired\n");
ESC_stopoutput();
/* watchdog, invalid outputs */
ESC_ALerror (ALERR_WATCHDOG);
/* goto safe-op with error bit set */
ESC_ALstatus (ESCsafeop | ESCerror);
ESC_ALstatusgotoerror((ESCsafeop | ESCerror), ALERR_WATCHDOG);
}
else if(((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) == 0))
{
@ -167,47 +222,18 @@ void DIG_process (uint8_t flags)
{
RXPDO_update();
CC_ATOMIC_SET(watchdog, ESCvar.watchdogcnt);
if(ESCvar.dcsync > 0)
{
CC_ATOMIC_ADD(ESCvar.synccounter, 1);
}
/* Set outputs */
cb_set_LEDgroup1();
cb_set_LEDgroup2();
cb_set_LEDgroup3();
cb_set_LEDgroup4();
cb_set_LEDgroup5();
cb_set_outputs();
}
else if (ESCvar.ALevent & ESCREG_ALEVENT_SM2)
{
RXPDO_update();
ESC_read (ESC_SM2_sma, rxpdo, ESCvar.ESC_SM2_sml);
}
}
/* Call application */
if ((flags & DIG_PROCESS_APP_HOOK_FLAG) > 0)
{
if((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0)
{
CC_ATOMIC_SUB(ESCvar.synccounter, 1);
}
if((ESCvar.dcsync > 0) &&
((CC_ATOMIC_GET(ESCvar.synccounter) < -ESCvar.synccounterlimit) ||
(CC_ATOMIC_GET(ESCvar.synccounter) > ESCvar.synccounterlimit)))
{
if((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0)
{
DPRINT("sync error = %d\n", ESCvar.synccounter);
ESC_stopoutput();
/* Sync error */
ESC_ALerror (ALERR_SYNCERROR);
/* goto safe-op with error bit set */
ESC_ALstatus (ESCsafeop | ESCerror);
CC_ATOMIC_SET(ESCvar.synccounter, 0);
}
}
/* Call application callback if set */
if (ESCvar.application_hook != NULL)
{
@ -221,14 +247,13 @@ void DIG_process (uint8_t flags)
if(CC_ATOMIC_GET(ESCvar.App.state) > 0)
{
/* Update inputs */
cb_get_Button1();
cb_get_Button2();
cb_get_inputs();
TXPDO_update();
}
}
}
/**
/*
* Handler for SM change, SM0/1, AL CONTROL and EEPROM events, the application
* control what interrupts that should be served and re-activated with
* event mask argument
@ -246,10 +271,17 @@ void ecat_slv_worker (uint32_t event_mask)
while ((ESC_mbxprocess() > 0) || (ESCvar.txcue > 0))
{
ESC_coeprocess();
#if USE_FOE
ESC_foeprocess();
#endif
#if USE_EOE
ESC_eoeprocess();
#endif
ESC_xoeprocess();
}
#if USE_EOE
ESC_eoeprocess_tx();
#endif
/* Call emulated eeprom handler if set */
if (ESCvar.esc_hw_eep_handler != NULL)
{
@ -263,18 +295,7 @@ void ecat_slv_worker (uint32_t event_mask)
ESC_ALeventmaskwrite(ESC_ALeventmaskread() | event_mask);
}
/**
* ISR function. It should be called from ISR for applications entirely driven by
* interrupts.
* Read and handle events for the EtherCAT state, status, mailbox and eeprom.
*/
void ecat_slv_isr (void)
{
ecat_slv_worker(ESCREG_ALEVENT_CONTROL | ESCREG_ALEVENT_SMCHANGE
| ESCREG_ALEVENT_SM0 | ESCREG_ALEVENT_SM1 | ESCREG_ALEVENT_EEP);
}
/**
/*
* Polling function. It should be called periodically for an application
* when only SM2/DC interrupt is active.
* Read and handle events for the EtherCAT state, status, mailbox and eeprom.
@ -294,10 +315,17 @@ void ecat_slv_poll (void)
if (ESC_mbxprocess())
{
ESC_coeprocess();
#if USE_FOE
ESC_foeprocess();
#endif
#if USE_EOE
ESC_eoeprocess();
#endif
ESC_xoeprocess();
}
#if USE_EOE
ESC_eoeprocess_tx();
#endif
/* Call emulated eeprom handler if set */
if (ESCvar.esc_hw_eep_handler != NULL)
@ -306,6 +334,9 @@ void ecat_slv_poll (void)
}
}
/*
* Poll all events in a free-run application
*/
void ecat_slv (void)
{
ecat_slv_poll();
@ -313,16 +344,13 @@ void ecat_slv (void)
DIG_PROCESS_APP_HOOK_FLAG | DIG_PROCESS_INPUTS_FLAG);
}
/**
/*
* Initialize the slave stack.
*/
void ecat_slv_init (esc_cfg_t * config)
{
DPRINT ("Slave stack init started\n");
ESCvar.TXPDOsize = ESCvar.ESC_SM3_sml = sizeOfPDO(TX_PDO_OBJIDX);
ESCvar.RXPDOsize = ESCvar.ESC_SM2_sml = sizeOfPDO(RX_PDO_OBJIDX);
/* Init watchdog */
watchdog = config->watchdog_cnt;
@ -339,14 +367,22 @@ void ecat_slv_init (esc_cfg_t * config)
ESCvar.DLstatus = etohs (ESCvar.DLstatus);
}
#if USE_FOE
/* Init FoE */
FOE_init();
FOE_init ();
#endif
#if USE_EOE
/* Init EoE */
EOE_init ();
#endif
/* reset ESC to init state */
ESC_ALstatus (ESCinit);
ESC_ALerror (ALERR_NONE);
ESC_stopmbx();
ESC_stopinput();
ESC_stopoutput();
ESC_stopmbx ();
ESC_stopinput ();
ESC_stopoutput ();
/* Init Object Dictionary default values */
COE_initDefaultValues ();
}
#endif

View File

@ -1,18 +1,29 @@
#ifndef __K2GICE_H__
#define __K2GICE_H__
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
#include "utypes.h"
#ifndef __ECAT_SLV_H__
#define __ECAT_SLV_H__
#include "options.h"
#include "esc.h"
/**
* This function gets input values and updates Rb.BUTTON
* This function is called when to get input values
*/
void cb_get_BUTTON();
void cb_get_inputs();
/**
* This function sets output values according to Wb.LED
* This function is called when to set outputs values
*/
void cb_set_LED();
void cb_set_outputs();
/** Set the watchdog count value
*
* @param[in] watchdogcnt = new watchdog count value
*/
void APP_setwatchdog (int watchdogcnt);
#define DIG_PROCESS_INPUTS_FLAG 0x01
#define DIG_PROCESS_OUTPUTS_FLAG 0x02
@ -37,12 +48,6 @@ void DIG_process (uint8_t flags);
*/
void ecat_slv_worker (uint32_t event_mask);
/**
* ISR for SM0/1, EEPROM and AL CONTROL events in a SM/DC
* synchronization application
*/
CC_DEPRECATED void ecat_slv_isr (void);
/**
* Poll SM0/1, EEPROM and AL CONTROL events in a SM/DC synchronization
* application
@ -61,4 +66,4 @@ void ecat_slv (void);
*/
void ecat_slv_init (esc_cfg_t * config);
#endif /* __K2GICE_H__ */
#endif /* __ECAT_SLV_H__ */

View File

@ -41,6 +41,48 @@ void ESC_ALstatus (uint8_t status)
ESC_write (ESCREG_ALSTATUS, &dummy, sizeof (dummy));
}
/** Write AL Status and AL Status code to the ESC.
* Call pre- and poststate change hook
*
* @param[in] status = Write current slave status to register 0x130 AL Status
* reflecting actual state and error indication if present
* @param[in] errornumber = Write an by EtherCAT specified Error number
* register 0x134 AL Status Code
*/
void ESC_ALstatusgotoerror (uint8_t status, uint16_t errornumber)
{
uint8_t an, as;
if(status & ESCop)
{
/* Erroneous input, ignore */
return;
}
/* Mask error ack of current state */
as = ESCvar.ALstatus & ESCREG_AL_ERRACKMASK;
an = as;
/* Set the state transition, new state in high bits and old in bits */
as = (uint8_t)(((status & ESCREG_AL_ERRACKMASK) << 4) | (as & 0x0f));
/* Call post state change hook case it have been configured */
if (ESCvar.pre_state_change_hook != NULL)
{
ESCvar.pre_state_change_hook (&as, &an);
}
/* Stop outputs if active */
if ((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0)
{
ESC_stopoutput();
}
ESC_ALerror(errornumber);
ESC_ALstatus(status);
an = status;
/* Call post state change hook case it have been configured */
if (ESCvar.post_state_change_hook != NULL)
{
ESCvar.post_state_change_hook (&as, &an);
}
}
/** Write ALeventMask register 0x204.
*
* @param[in] n = AL Event Mask
@ -94,7 +136,7 @@ uint32_t ESC_ALeventread (void)
void ESC_SMack (uint8_t n)
{
uint8_t dummy;
ESC_read (ESCREG_SM0ACTIVATE + (n << 3), &dummy, 1);
ESC_read ((uint16_t)(ESCREG_SM0ACTIVATE + (n << 3)), &dummy, 1);
}
/** Read SM Status register 0x805(+ offset to SyncManager n) and save the
@ -106,7 +148,7 @@ void ESC_SMstatus (uint8_t n)
{
_ESCsm2 *sm;
sm = (_ESCsm2 *)&ESCvar.SM[n];
ESC_read (ESCREG_SM0STATUS + (n << 3), &(sm->Status), 1);
ESC_read ((uint16_t)(ESCREG_SM0STATUS + (n << 3)), &(sm->Status), 1);
}
/** Write ESCvar.SM[n] data to ESC PDI control register 0x807(+ offset to SyncManager n).
@ -117,7 +159,18 @@ void ESC_SMwritepdi (uint8_t n)
{
_ESCsm2 *sm;
sm = (_ESCsm2 *)&ESCvar.SM[n];
ESC_write (ESCREG_SM0PDI + (n << 3), &(sm->ActPDI), 1);
ESC_write ((uint16_t)(ESCREG_SM0PDI + (n << 3)), &(sm->ActPDI), 1);
}
/** Read ESC PDI control register 0x807(+ offset to SyncManager n) to ESCvar.SM[n] data.
*
* @param[in] n = Read from Sync Manager no. n
*/
void ESC_SMreadpdi (uint8_t n)
{
_ESCsm2* sm;
sm = (_ESCsm2*)&ESCvar.SM[n];
ESC_read ((uint16_t)(ESCREG_SM0PDI + (n << 3)), &(sm->ActPDI), 1);
}
/** Write 0 to Bit0 in SM PDI control register 0x807(+ offset to SyncManager n) to Activate the Sync Manager n.
@ -128,8 +181,13 @@ void ESC_SMenable (uint8_t n)
{
_ESCsm2 *sm;
sm = (_ESCsm2 *)&ESCvar.SM[n];
sm->ActPDI &= ~ESCREG_SMENABLE_BIT;
sm->ActPDI &= (uint8_t)~ESCREG_SMENABLE_BIT;
ESC_SMwritepdi (n);
/* Read back wait until enabled */
do
{
ESC_SMreadpdi (n);
} while ((sm->ActPDI & ESCREG_SMENABLE_BIT) == 1);
}
/** Write 1 to Bit0 in SM PDI control register 0x807(+ offset to SyncManager n) to De-activte the Sync Manager n.
*
@ -141,6 +199,11 @@ void ESC_SMdisable (uint8_t n)
sm = (_ESCsm2 *)&ESCvar.SM[n];
sm->ActPDI |= ESCREG_SMENABLE_BIT;
ESC_SMwritepdi (n);
/* Read back wait until disabled */
do
{
ESC_SMreadpdi (n);
} while ((sm->ActPDI & ESCREG_SMENABLE_BIT) == 0);
}
/** Read Configured Station Address register 0x010 assigned by the Master.
*
@ -208,51 +271,16 @@ uint16_t ESC_checkDC (void)
uint16_t ret = 0;
uint8_t sync_act = ESC_SYNCactivation();
uint32_t sync0_cycletime = ESC_SYNC0cycletime();
uint16_t sync_type_supported1c32 = 0;
uint32_t mincycletime = 0;
/* Do we need to check sync settings? */
if((sync_act & (ESCREG_SYNC_ACT_ACTIVATED | ESCREG_SYNC_AUTO_ACTIVATED)) > 0)
{
/* If the sync unit is active at least on signal should be activated */
if(COE_getSyncMgrPara(0x1c32, 0x4, &sync_type_supported1c32, DTYPE_UNSIGNED16) == 0)
/* Trigger a by the application given DC check handler, return error if
* non is given
*/
ret = ALERR_DCINVALIDSYNCCFG;
if(ESCvar.esc_check_dc_handler != NULL)
{
ret = ALERR_DCINVALIDSYNCCFG;
}
else if(COE_getSyncMgrPara(0x1c32, 0x5, &mincycletime, DTYPE_UNSIGNED32) == 0)
{
ret = ALERR_DCINVALIDSYNCCFG;
}
else if(COE_getSyncMgrPara(0x10F1, 0x2, &ESCvar.synccounterlimit, DTYPE_UNSIGNED16) == 0)
{
ret = ALERR_DCINVALIDSYNCCFG;
}
else if((sync_act & (ESCREG_SYNC_SYNC0_EN | ESCREG_SYNC_SYNC1_EN)) == 0)
{
ret = ALERR_DCINVALIDSYNCCFG;
}
/* Do we support activated signals */
else if(((sync_type_supported1c32 & SYNCTYPE_SUPPORT_DCSYNC0) == 0) &&
((sync_act & ESCREG_SYNC_SYNC0_EN) > 0))
{
ret = ALERR_DCINVALIDSYNCCFG;
}
/* Do we support activated signals */
else if(((sync_type_supported1c32 & SYNCTYPE_SUPPORT_DCSYNC1) == 0) &&
((sync_act & ESCREG_SYNC_SYNC1_EN) > 0))
{
ret = ALERR_DCINVALIDSYNCCFG;
}
else if((sync0_cycletime != 0) && (sync0_cycletime < mincycletime))
{
ret = ALERR_DCSYNC0CYCLETIME;
}
else
{
ESCvar.dcsync = 1;
ESCvar.synccounter = 0;
ret = (ESCvar.esc_check_dc_handler)();
}
}
else
@ -310,11 +338,10 @@ uint8_t ESC_checkmbx (uint8_t state)
uint8_t ESC_startmbx (uint8_t state)
{
/* Assign SM settings */
ESCvar.activembxsize = ESCvar.mbxsize;
ESCvar.activembxsize = MBXSIZE;
ESCvar.activemb0 = &ESCvar.mb[0];
ESCvar.activemb1 = &ESCvar.mb[1];
ESC_SMenable (0);
ESC_SMenable (1);
ESC_SMstatus (0);
@ -327,6 +354,8 @@ uint8_t ESC_startmbx (uint8_t state)
else
{
ESCvar.toggle = ESCvar.SM[1].ECrep; //sync repeat request toggle state
ESCvar.SM[1].PDIrep = ESCvar.toggle & 0x1U;
ESC_SMwritepdi (1);
ESCvar.MBXrun = 1;
}
return state;
@ -344,7 +373,7 @@ uint8_t ESC_startmbx (uint8_t state)
uint8_t ESC_startmbxboot (uint8_t state)
{
/* Assign SM settings */
ESCvar.activembxsize = ESCvar.mbxsizeboot;
ESCvar.activembxsize = MBXSIZEBOOT;
ESCvar.activemb0 = &ESCvar.mbboot[0];
ESCvar.activemb1 = &ESCvar.mbboot[1];
@ -360,6 +389,8 @@ uint8_t ESC_startmbxboot (uint8_t state)
else
{
ESCvar.toggle = ESCvar.SM[1].ECrep; //sync repeat request toggle state
ESCvar.SM[1].PDIrep = ESCvar.toggle & 0x1U;
ESC_SMwritepdi (1);
ESCvar.MBXrun = 1;
}
return state;
@ -388,6 +419,9 @@ void ESC_stopmbx (void)
ESCvar.frags = 0;
ESCvar.fragsleft = 0;
ESCvar.txcue = 0;
ESCvar.index = 0;
ESCvar.subindex = 0;
ESCvar.flags = 0;
}
/** Read Receive mailbox and store data in local ESCvar.MBX variable.
@ -404,9 +438,9 @@ void ESC_readmbx (void)
if (length > (ESC_MBX0_sml - ESC_MBXHSIZE))
{
length = ESC_MBX0_sml - ESC_MBXHSIZE;
length = (uint16_t)(ESC_MBX0_sml - ESC_MBXHSIZE);
}
ESC_read (ESC_MBX0_sma + ESC_MBXHSIZE, MB->b, length);
ESC_read ((uint16_t)(ESC_MBX0_sma + ESC_MBXHSIZE), MB->b, length);
if (length + ESC_MBXHSIZE < ESC_MBX0_sml)
{
ESC_read (ESC_MBX0_sme, &length, 1);
@ -429,9 +463,9 @@ void ESC_writembx (uint8_t n)
if (length > (ESC_MBX1_sml - ESC_MBXHSIZE))
{
length = ESC_MBX1_sml - ESC_MBXHSIZE;
length = (uint16_t)(ESC_MBX1_sml - ESC_MBXHSIZE);
}
ESC_write (ESC_MBX1_sma, MBh, ESC_MBXHSIZE + length);
ESC_write (ESC_MBX1_sma, MBh, (uint16_t)(ESC_MBXHSIZE + length));
if (length + ESC_MBXHSIZE < ESC_MBX1_sml)
{
ESC_write (ESC_MBX1_sme, &dummy, 1);
@ -477,7 +511,7 @@ uint8_t ESC_claimbuffer (void)
MBh->address = htoes (0x0000); // destination is master
MBh->channel = 0;
MBh->priority = 0;
MBh->mbxcnt = ESCvar.mbxcnt;
MBh->mbxcnt = ESCvar.mbxcnt & 0xFU;
ESCvar.txcue++;
}
return n;
@ -591,7 +625,7 @@ uint8_t ESC_mbxprocess (void)
ESC_writembx (ESCvar.mbxbackup);
}
ESCvar.toggle = ESCvar.SM[1].ECrep;
ESCvar.SM[1].PDIrep = ESCvar.toggle;
ESCvar.SM[1].PDIrep = ESCvar.toggle & 0x1U;
ESC_SMwritepdi (1);
}
return 0;
@ -678,23 +712,78 @@ uint8_t ESC_checkSM23 (uint8_t state)
_ESCsm2 *SM;
ESC_read (ESCREG_SM2, (void *) &ESCvar.SM[2], sizeof (ESCvar.SM[2]));
SM = (_ESCsm2 *) & ESCvar.SM[2];
if ((etohs (SM->PSA) != ESC_SM2_sma) || (etohs (SM->Length) != ESCvar.ESC_SM2_sml)
|| (SM->Command != ESC_SM2_smc) || !(SM->ActESC & ESC_SM2_act))
/* Check SM settings */
if ((etohs (SM->PSA) != ESC_SM2_sma) ||
(SM->Command != ESC_SM2_smc))
{
ESCvar.SMtestresult = SMRESULT_ERRSM2;
/* fail state change */
return (ESCpreop | ESCerror);
}
/* Check run-time settings */
/* Check length */
else if (etohs (SM->Length) != ESCvar.ESC_SM2_sml)
{
ESCvar.SMtestresult = SMRESULT_ERRSM2;
/* fail state change */
return (ESCpreop | ESCerror);
}
/* SM disabled and (SM activated or length > 0) set by master */
else if (((ESC_SM2_act & ESCREG_SYNC_ACT_ACTIVATED) == 0) &&
((SM->ActESC & ESCREG_SYNC_ACT_ACTIVATED) || (ESCvar.ESC_SM2_sml > 0)))
{
ESCvar.SMtestresult = SMRESULT_ERRSM2;
/* fail state change */
return (ESCpreop | ESCerror);
}
/* SM enabled and (length > 0 but SM disabled) set by master */
else if (((ESC_SM2_act & ESCREG_SYNC_ACT_ACTIVATED) > 0) &&
((SM->ActESC & ESCREG_SYNC_ACT_ACTIVATED) == 0) &&
(ESCvar.ESC_SM2_sml > 0))
{
ESCvar.SMtestresult = SMRESULT_ERRSM2;
/* fail state change */
return (ESCpreop | ESCerror);
}
if ((ESC_SM2_sma + (etohs (SM->Length) * 3)) > ESC_SM3_sma)
{
ESCvar.SMtestresult = SMRESULT_ERRSM2;
/* SM2 overlaps SM3, fail state change */
return (ESCpreop | ESCerror);
}
ESC_read (ESCREG_SM3, (void *) &ESCvar.SM[3], sizeof (ESCvar.SM[3]));
SM = (_ESCsm2 *) & ESCvar.SM[3];
if ((etohs (SM->PSA) != ESC_SM3_sma) || (etohs (SM->Length) != ESCvar.ESC_SM3_sml)
|| (SM->Command != ESC_SM3_smc) || !(SM->ActESC & ESC_SM3_act))
/* Check SM settings */
if ((etohs (SM->PSA) != ESC_SM3_sma) ||
(SM->Command != ESC_SM3_smc))
{
ESCvar.SMtestresult = SMRESULT_ERRSM3;
/* fail state change */
return (ESCpreop | ESCerror);
}
/* Check run-time settings */
/* Check length */
else if (etohs (SM->Length) != ESCvar.ESC_SM3_sml)
{
ESCvar.SMtestresult = SMRESULT_ERRSM3;
/* fail state change */
return (ESCpreop | ESCerror);
}
/* SM disabled and (SM activated or length > 0) set by master */
else if (((ESC_SM3_act & ESCREG_SYNC_ACT_ACTIVATED) == 0) &&
((SM->ActESC & ESCREG_SYNC_ACT_ACTIVATED) || (ESCvar.ESC_SM3_sml > 0)))
{
ESCvar.SMtestresult = SMRESULT_ERRSM3;
/* fail state change */
return (ESCpreop | ESCerror);
}
/* SM enabled and (length > 0 but SM disabled) set by master */
else if (((ESC_SM3_act & ESCREG_SYNC_ACT_ACTIVATED) > 0) &&
((SM->ActESC & ESCREG_SYNC_ACT_ACTIVATED) == 0) &&
(ESCvar.ESC_SM3_sml > 0))
{
ESCvar.SMtestresult = SMRESULT_ERRSM3;
/* fail state change */
@ -717,7 +806,12 @@ uint8_t ESC_startinput (uint8_t state)
if (state != (ESCpreop | ESCerror))
{
ESC_SMenable (3);
/* If inputs > 0 , enable SM3 */
if (ESCvar.ESC_SM3_sml > 0)
{
ESC_SMenable (3);
}
/* Go to state input regardless of any inputs present */
CC_ATOMIC_SET(ESCvar.App.state, APPSTATE_INPUT);
}
else
@ -757,15 +851,22 @@ uint8_t ESC_startinput (uint8_t state)
{
if (ESCvar.esc_hw_interrupt_enable != NULL)
{
if(ESCvar.dcsync > 0)
uint32_t int_mask;
if (ESCvar.ESC_SM2_sml == 0)
{
ESCvar.esc_hw_interrupt_enable(ESCREG_ALEVENT_DC_SYNC0 |
ESCREG_ALEVENT_SM2);
int_mask = ESCREG_ALEVENT_SM3;
}
else
{
ESCvar.esc_hw_interrupt_enable(ESCREG_ALEVENT_SM2);
int_mask = ESCREG_ALEVENT_SM2;
}
if (ESCvar.dcsync > 0)
{
int_mask |= ESCREG_ALEVENT_DC_SYNC0;
}
ESCvar.esc_hw_interrupt_enable (int_mask);
}
}
}
@ -788,7 +889,8 @@ void ESC_stopinput (void)
(ESCvar.esc_hw_interrupt_disable != NULL))
{
ESCvar.esc_hw_interrupt_disable (ESCREG_ALEVENT_DC_SYNC0 |
ESCREG_ALEVENT_SM2);
ESCREG_ALEVENT_SM2 |
ESCREG_ALEVENT_SM3);
}
}
@ -802,8 +904,13 @@ void ESC_stopinput (void)
*/
uint8_t ESC_startoutput (uint8_t state)
{
ESC_SMenable (2);
/* If outputs > 0 , enable SM2 */
if (ESCvar.ESC_SM2_sml > 0)
{
ESC_SMenable (2);
}
/* Go to state output regardless of any outputs present */
CC_ATOMIC_OR(ESCvar.App.state, APPSTATE_OUTPUT);
return state;
@ -910,6 +1017,75 @@ void ESC_sm_act_event (void)
ESC_SMack (7);
}
}
static bool ESC_check_id_request (uint16_t ALcontrol, uint8_t * an)
{
if ((ALcontrol & ESCREG_AL_ID_REQUEST) != 0)
{
uint8_t state = ALcontrol & ESCREG_AL_ERRACKMASK;
if ((state != ESCboot) &&
((state < ESCsafeop) || (*an == ESCsafeop) || (*an == ESCop)))
{
uint16_t ALstatuscode;
ESC_read (ESCREG_ALERROR,
(void *)&ALstatuscode,
sizeof (ALstatuscode));
return (ALstatuscode == ALERR_NONE);
}
}
return false;
}
static uint8_t ESC_load_device_id (void)
{
uint16_t device_id;
if (ESCvar.get_device_id != NULL)
{
if (ESCvar.get_device_id (&device_id) != 0)
{
device_id = 0;
}
}
else
{
ESC_read (ESCREG_CONF_STATION_ALIAS,
(void *)&device_id,
sizeof (device_id));
}
if (device_id != 0)
{
/* Load the Device Identification Value to the AL Status Code register */
ESC_ALerror (device_id);
return ESCREG_AL_ID_REQUEST;
}
return 0;
}
#ifdef ESC_DEBUG
static char * ESC_state_to_string (uint8_t ESC_state)
{
switch (ESC_state)
{
case ESCinit: return "Init";
case ESCpreop: return "Pre-Operational";
case ESCboot: return "Bootstrap";
case ESCsafeop: return "Safe-Operational";
case ESCop: return "Operational";
case ESCerror: return "Error";
}
return "Unknown";
}
#endif
/** The state handler acting on ALControl Bit(0)
* events in the Al Event Request register 0x220.
*
@ -948,7 +1124,7 @@ void ESC_state (void)
}
/* Mask high bits ALcommand, low bits ALstatus */
as = (ac << 4) | (as & 0x0f);
as = (uint8_t)((ac << 4) | (as & 0x0f));
/* Call post state change hook case it have been configured */
if (ESCvar.pre_state_change_hook != NULL)
@ -971,7 +1147,6 @@ void ESC_state (void)
{
/* get station address */
ESC_address ();
COE_initDefaultSyncMgrPara ();
an = ESC_startmbx (ac);
break;
}
@ -1029,8 +1204,24 @@ void ESC_state (void)
case PREOP_TO_SAFEOP:
case SAFEOP_TO_SAFEOP:
{
ESCvar.ESC_SM2_sml = sizeOfPDO (RX_PDO_OBJIDX);
ESCvar.ESC_SM3_sml = sizeOfPDO (TX_PDO_OBJIDX);
ESCvar.ESC_SM2_sml = sizeOfPDO (RX_PDO_OBJIDX, &ESCvar.sm2mappings,
SMmap2, MAX_MAPPINGS_SM2);
if (ESCvar.sm2mappings < 0)
{
an = ESCpreop | ESCerror;
ESC_ALerror (ALERR_INVALIDOUTPUTSM);
break;
}
ESCvar.ESC_SM3_sml = sizeOfPDO (TX_PDO_OBJIDX, &ESCvar.sm3mappings,
SMmap3, MAX_MAPPINGS_SM3);
if (ESCvar.sm3mappings < 0)
{
an = ESCpreop | ESCerror;
ESC_ALerror (ALERR_INVALIDINPUTSM);
break;
}
an = ESC_startinput (ac);
if (an == ac)
{
@ -1073,6 +1264,11 @@ void ESC_state (void)
an = ESCsafeop | ESCerror;
ESC_ALerror (ALERR_INVALIDSTATECHANGE);
ESC_stopoutput ();
/* If no outputs present, we need to flag error using SM3 */
if (ESCvar.ESC_SM2_sml == 0 && ESCvar.ESC_SM3_sml > 0)
{
ESC_SMdisable (3);
}
break;
}
case OP_TO_SAFEOP:
@ -1086,6 +1282,11 @@ void ESC_state (void)
if (an == ESCop)
{
ESC_stopoutput ();
/* If no outputs present, we need to flag error using SM3 */
if (ESCvar.ESC_SM2_sml == 0 && ESCvar.ESC_SM3_sml > 0)
{
ESC_SMdisable (3);
}
an = ESCsafeop;
}
if (as == ESCsafeop)
@ -1110,8 +1311,16 @@ void ESC_state (void)
ESC_ALerror (ALERR_NONE);
}
if (ESC_check_id_request (ESCvar.ALcontrol, &an))
{
an |= ESC_load_device_id ();
}
ESC_ALstatus (an);
#ifdef ESC_DEBUG
DPRINT ("state %s\n", ESC_state_to_string (an & 0xF));
#endif
}
/** Function copying the application configuration variable
* data to the stack local variable.
@ -1121,29 +1330,35 @@ void ESC_state (void)
*/
void ESC_config (esc_cfg_t * cfg)
{
/* Copy configuration data */
static sm_cfg_t mb0 = {MBX0_sma, MBX0_sml, MBX0_sme, MBX0_smc, 0};
static sm_cfg_t mb1 = {MBX1_sma, MBX1_sml, MBX1_sme, MBX1_smc, 0};
static sm_cfg_t mbboot0 = {MBX0_sma_b, MBX0_sml_b, MBX0_sme_b, MBX0_smc_b, 0};
static sm_cfg_t mbboot1 = {MBX1_sma_b, MBX1_sml_b, MBX1_sme_b, MBX1_smc_b, 0};
/* Configure stack */
ESCvar.use_interrupt = cfg->use_interrupt;
ESCvar.watchdogcnt = cfg->watchdog_cnt;
ESCvar.mbxsize = cfg->mbxsize;
ESCvar.mbxsizeboot = cfg->mbxsizeboot;
ESCvar.mbxbuffers = cfg->mbxbuffers;
ESCvar.mb[0] = cfg->mb[0];
ESCvar.mb[1] = cfg->mb[1];
ESCvar.mbboot[0] = cfg->mb_boot[0];
ESCvar.mbboot[1] = cfg->mb_boot[1];
ESCvar.pdosm[0] = cfg->pdosm[0];
ESCvar.pdosm[1] = cfg->pdosm[1];
ESCvar.mb[0] = mb0;
ESCvar.mb[1] = mb1;
ESCvar.mbboot[0] = mbboot0;
ESCvar.mbboot[1] = mbboot1;
ESCvar.skip_default_initialization = cfg->skip_default_initialization;
ESCvar.set_defaults_hook = cfg->set_defaults_hook;
ESCvar.pre_state_change_hook = cfg->pre_state_change_hook;
ESCvar.post_state_change_hook = cfg->post_state_change_hook;
ESCvar.application_hook = cfg->application_hook;
ESCvar.safeoutput_override = cfg->safeoutput_override;
ESCvar.pre_object_download_hook = cfg->pre_object_download_hook;
ESCvar.post_object_download_hook = cfg->post_object_download_hook;
ESCvar.pre_object_upload_hook = cfg->pre_object_upload_hook;
ESCvar.post_object_upload_hook = cfg->post_object_upload_hook;
ESCvar.rxpdo_override = cfg->rxpdo_override;
ESCvar.txpdo_override = cfg->txpdo_override;
ESCvar.esc_hw_interrupt_enable = cfg->esc_hw_interrupt_enable;
ESCvar.esc_hw_interrupt_disable = cfg->esc_hw_interrupt_disable;
ESCvar.esc_hw_eep_handler = cfg->esc_hw_eep_handler;
ESCvar.esc_check_dc_handler = cfg->esc_check_dc_handler;
ESCvar.get_device_id = cfg->get_device_id;
}

View File

@ -11,12 +11,18 @@
#ifndef __esc__
#define __esc__
#include <stdbool.h>
#include <cc.h>
#include <esc_coe.h>
#include "options.h"
#define ESCREG_ADDRESS 0x0010
#define ESCREG_CONF_STATION_ALIAS 0x0012
#define ESCREG_DLSTATUS 0x0110
#define ESCREG_ALCONTROL 0x0120
#define ESCREG_ALCONTROL_ERROR_ACK 0x0010
#define ESCREG_ALSTATUS 0x0130
#define ESCREG_ALSTATUS_ERROR_IND 0x0010
#define ESCREG_ALERROR 0x0134
#define ESCREG_ALEVENTMASK 0x0204
#define ESCREG_ALEVENT 0x0220
@ -27,6 +33,7 @@
#define ESCREG_ALEVENT_DC_SYNC0 0x0004
#define ESCREG_ALEVENT_DC_SYNC1 0x0008
#define ESCREG_ALEVENT_EEP 0x0020
#define ESCREG_ALEVENT_WD 0x0040
#define ESCREG_ALEVENT_SM0 0x0100
#define ESCREG_ALEVENT_SM1 0x0200
#define ESCREG_ALEVENT_SM2 0x0400
@ -54,6 +61,7 @@
#define ESCREG_AL_STATEMASK 0x001f
#define ESCREG_AL_ALLBUTINITMASK 0x0e
#define ESCREG_AL_ERRACKMASK 0x0f
#define ESCREG_AL_ID_REQUEST 0x0020
#define SYNCTYPE_SUPPORT_FREERUN 0x01
#define SYNCTYPE_SUPPORT_SYNCHRON 0x02
@ -95,6 +103,8 @@
#define OP_TO_OP 0x88
#define ALERR_NONE 0x0000
#define ALERR_UNSPECIFIEDERROR 0x0001
#define ALERR_NOMEMORY 0x0002
#define ALERR_INVALIDSTATECHANGE 0x0011
#define ALERR_UNKNOWNSTATE 0x0012
#define ALERR_BOOTNOTSUPPORTED 0x0013
@ -102,12 +112,49 @@
#define ALERR_INVALIDBOOTMBXCONFIG 0x0015
#define ALERR_INVALIDMBXCONFIG 0x0016
#define ALERR_INVALIDSMCONFIG 0x0017
#define ALERR_NOVALIDINPUTS 0x0018
#define ALERR_NOVALIDOUTPUTS 0x0019
#define ALERR_SYNCERROR 0x001A
#define ALERR_WATCHDOG 0x001B
#define ALERR_INVALIDSYNCMANAGERTYP 0x001C
#define ALERR_INVALIDOUTPUTSM 0x001D
#define ALERR_INVALIDINPUTSM 0x001E
#define ALERR_INVALIDWDTCFG 0x001F
#define ALERR_SLAVENEEDSCOLDSTART 0x0020
#define ALERR_SLAVENEEDSINIT 0x0021
#define ALERR_SLAVENEEDSPREOP 0x0022
#define ALERR_SLAVENEEDSSAFEOP 0x0023
#define ALERR_INVALIDINPUTMAPPING 0x0024
#define ALERR_INVALIDOUTPUTMAPPING 0x0025
#define ALERR_INCONSISTENTSETTINGS 0x0026
#define ALERR_FREERUNNOTSUPPORTED 0x0027
#define ALERR_SYNCNOTSUPPORTED 0x0028
#define ALERR_FREERUNNEEDS3BUFFMODE 0x0029
#define ALERR_BACKGROUNDWATCHDOG 0x002A
#define ALERR_NOVALIDINPUTSOUTPUTS 0x002B
#define ALERR_FATALSYNCERROR 0x002C
#define ALERR_NOSYNCERROR 0x002D
#define ALERR_INVALIDINPUTFMMUCFG 0x002E
#define ALERR_DCINVALIDSYNCCFG 0x0030
#define ALERR_INVALIDDCLATCHCFG 0x0031
#define ALERR_PLLERROR 0x0032
#define ALERR_DCSYNCIOERROR 0x0033
#define ALERR_DCSYNCTIMEOUT 0x0034
#define ALERR_DCSYNCCYCLETIME 0x0035
#define ALERR_DCSYNC0CYCLETIME 0x0036
#define ALERR_DCSYNC1CYCLETIME 0x0037
#define ALERR_MBXAOE 0x0041
#define ALERR_MBXEOE 0x0042
#define ALERR_MBXCOE 0x0043
#define ALERR_MBXFOE 0x0044
#define ALERR_MBXSOE 0x0045
#define ALERR_MBXVOE 0x004F
#define ALERR_EEPROMNOACCESS 0x0050
#define ALERR_EEPROMERROR 0x0051
#define ALERR_SLAVERESTARTEDLOCALLY 0x0060
#define ALERR_DEVICEIDVALUEUPDATED 0x0061
#define ALERR_APPLCTRLAVAILABLE 0x00f0
#define ALERR_UNKNOWN 0xffff
#define MBXERR_SYNTAX 0x0001
#define MBXERR_UNSUPPORTEDPROTOCOL 0x0002
@ -119,15 +166,41 @@
#define MBXERR_INVALIDSIZE 0x0008
#define ABORT_NOTOGGLE 0x05030000
#define ABORT_TRANSFER_TIMEOUT 0x05040000
#define ABORT_UNKNOWN 0x05040001
#define ABORT_INVALID_BLOCK_SIZE 0x05040002
#define ABORT_INVALID_SEQUENCE_NUMBER 0x05040003
#define ABORT_BLOCK_CRC_ERROR 0x05040004
#define ABORT_OUT_OF_MEMORY 0x05040005
#define ABORT_UNSUPPORTED 0x06010000
#define ABORT_WRITEONLY 0x06010001
#define ABORT_READONLY 0x06010002
#define ABORT_SUBINDEX0_NOT_ZERO 0x06010003
#define ABORT_CA_NOT_SUPPORTED 0x06010004
#define ABORT_EXCEEDS_MBOX_SIZE 0x06010005
#define ABORT_SDO_DOWNLOAD_BLOCKED 0x06010006
#define ABORT_NOOBJECT 0x06020000
#define ABORT_MAPPING_OBJECT_ERROR 0x06040041
#define ABORT_MAPPING_LENGTH_ERROR 0x06040042
#define ABORT_GENERAL_PARAMETER_ERROR 0x06040043
#define ABORT_GENERAL_DEVICE_ERROR 0x06040047
#define ABORT_HARDWARE_ERROR 0x06060000
#define ABORT_TYPEMISMATCH 0x06070010
#define ABORT_DATATYPE_TOO_HIGH 0x06070012
#define ABORT_DATATYPE_TOO_LOW 0x06070013
#define ABORT_NOSUBINDEX 0x06090011
#define ABORT_VALUE_EXCEEDED 0x06090030
#define ABORT_VALUE_TOO_HIGH 0x06090031
#define ABORT_VALUE_TOO_LOW 0x06090032
#define ABORT_MODULE_LIST_MISMATCH 0x06090033
#define ABORT_MAX_VAL_LESS_THAN_MIN_VAL 0x06090036
#define ABORT_RESOURCE_NOT_AVAILABLE 0x060A0023
#define ABORT_GENERALERROR 0x08000000
#define ABORT_DATA_STORE_ERROR 0x08000020
#define ABORT_DATA_STORE_LOCAL_ERROR 0x08000021
#define ABORT_NOTINTHISSTATE 0x08000022
#define ABORT_OBJECT_DICTIONARY_ERROR 0x08000023
#define ABORT_NO_DATA_AVAILABLE 0x08000024
#define MBXstate_idle 0x00
#define MBXstate_inclaim 0x01
@ -137,9 +210,9 @@
#define MBXstate_backup 0x05
#define MBXstate_again 0x06
#define COE_DEFAULTLENGTH 0x0a
#define COE_HEADERSIZE 0x0a
#define COE_SEGMENTHEADERSIZE 0x03
#define COE_DEFAULTLENGTH 0x0AU
#define COE_HEADERSIZE 0x0AU
#define COE_SEGMENTHEADERSIZE 0x03U
#define COE_SDOREQUEST 0x02
#define COE_SDORESPONSE 0x03
#define COE_SDOINFORMATION 0x08
@ -148,7 +221,10 @@
#define COE_COMMAND_UPLOADRESPONSE 0x40
#define COE_COMMAND_UPLOADSEGMENT 0x00
#define COE_COMMAND_UPLOADSEGREQ 0x60
#define COE_COMMAND_DOWNLOADREQUEST 0x20
#define COE_COMMAND_DOWNLOADRESPONSE 0x60
#define COE_COMMAND_DOWNLOADSEGREQ 0x00
#define COE_COMMAND_DOWNLOADSEGRESP 0x20
#define COE_COMMAND_LASTSEGMENTBIT 0x01
#define COE_SIZE_INDICATOR 0x01
#define COE_EXPEDITED_INDICATOR 0x02
@ -195,6 +271,7 @@
#define FOE_ERR_NOTINBOOTSTRAP 0x8009
#define FOE_ERR_NORIGHTS 0x800A
#define FOE_ERR_PROGERROR 0x800B
#define FOE_ERR_CHECKSUM 0x800C
#define FOE_OP_RRQ 1
#define FOE_OP_WRQ 2
@ -219,6 +296,8 @@
#define APPSTATE_INPUT 0x01
#define APPSTATE_OUTPUT 0x02
#define PREALLOC_BUFFER_SIZE (PREALLOC_FACTOR * MBXSIZE)
typedef struct sm_cfg
{
uint16_t cfg_sma;
@ -233,23 +312,35 @@ typedef struct esc_cfg
void * user_arg;
int use_interrupt;
int watchdog_cnt;
size_t mbxsize;
size_t mbxsizeboot;
int mbxbuffers;
sm_cfg_t mb[2];
sm_cfg_t mb_boot[2];
sm_cfg_t pdosm[2];
bool skip_default_initialization;
void (*set_defaults_hook) (void);
void (*pre_state_change_hook) (uint8_t * as, uint8_t * an);
void (*post_state_change_hook) (uint8_t * as, uint8_t * an);
void (*application_hook) (void);
void (*safeoutput_override) (void);
int (*pre_object_download_hook) (uint16_t index, uint8_t subindex);
void (*post_object_download_hook) (uint16_t index, uint8_t subindex);
uint32_t (*pre_object_download_hook) (uint16_t index,
uint8_t subindex,
void * data,
size_t size,
uint16_t flags);
uint32_t (*post_object_download_hook) (uint16_t index,
uint8_t subindex,
uint16_t flags);
uint32_t (*pre_object_upload_hook) (uint16_t index,
uint8_t subindex,
void * data,
size_t *size,
uint16_t flags);
uint32_t (*post_object_upload_hook) (uint16_t index,
uint8_t subindex,
uint16_t flags);
void (*rxpdo_override) (void);
void (*txpdo_override) (void);
void (*esc_hw_interrupt_enable) (uint32_t mask);
void (*esc_hw_interrupt_disable) (uint32_t mask);
void (*esc_hw_eep_handler) (void);
uint16_t (*esc_check_dc_handler) (void);
int (*get_device_id) (uint16_t * device_id);
} esc_cfg_t;
typedef struct
@ -344,31 +435,43 @@ typedef struct
{
/* Configuration input is saved so the user variable may go out-of-scope */
int use_interrupt;
size_t mbxsize;
size_t mbxsizeboot;
int mbxbuffers;
sm_cfg_t mb[2];
sm_cfg_t mbboot[2];
sm_cfg_t pdosm[2];
bool skip_default_initialization;
void (*set_defaults_hook) (void);
void (*pre_state_change_hook) (uint8_t * as, uint8_t * an);
void (*post_state_change_hook) (uint8_t * as, uint8_t * an);
void (*application_hook) (void);
void (*safeoutput_override) (void);
int (*pre_object_download_hook) (uint16_t index, uint8_t subindex);
void (*post_object_download_hook) (uint16_t index, uint8_t subindex);
uint32_t (*pre_object_download_hook) (uint16_t index,
uint8_t subindex,
void * data,
size_t size,
uint16_t flags);
uint32_t (*post_object_download_hook) (uint16_t index,
uint8_t subindex,
uint16_t flags);
uint32_t (*pre_object_upload_hook) (uint16_t index,
uint8_t subindex,
void * data,
size_t *size,
uint16_t flags);
uint32_t (*post_object_upload_hook) (uint16_t index,
uint8_t subindex,
uint16_t flags);
void (*rxpdo_override) (void);
void (*txpdo_override) (void);
void (*esc_hw_interrupt_enable) (uint32_t mask);
void (*esc_hw_interrupt_disable) (uint32_t mask);
void (*esc_hw_eep_handler) (void);
uint16_t (*esc_check_dc_handler) (void);
int (*get_device_id) (uint16_t * device_id);
uint8_t MBXrun;
size_t activembxsize;
uint32_t activembxsize;
sm_cfg_t * activemb0;
sm_cfg_t * activemb1;
uint16_t ESC_SM2_sml;
uint16_t ESC_SM3_sml;
uint16_t TXPDOsize;
uint16_t RXPDOsize;
uint8_t dcsync;
uint16_t synccounterlimit;
uint16_t ALstatus;
@ -386,11 +489,16 @@ typedef struct
uint8_t segmented;
void *data;
uint16_t entries;
uint16_t frags;
uint16_t fragsleft;
uint32_t frags;
uint32_t fragsleft;
uint16_t index;
uint8_t subindex;
uint16_t flags;
uint8_t toggle;
int sm2mappings;
int sm3mappings;
uint8_t SMtestresult;
uint32_t PrevTime;
@ -398,9 +506,10 @@ typedef struct
/* Volatile since it may be read from ISR */
volatile int watchdogcnt;
volatile uint32_t Time;
volatile uint16_t ALevent;
volatile uint32_t ALevent;
volatile int8_t synccounter;
volatile _App App;
uint8_t mbxdata[PREALLOC_BUFFER_SIZE];
} _ESCvar;
CC_PACKED_BEGIN
@ -470,7 +579,7 @@ typedef struct CC_PACKED
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct CC_PACKED
typedef struct CC_PACKED CC_ALIGNED(4)
{
_MBXh mbxheader;
_COEh coeheader;
@ -482,7 +591,7 @@ typedef struct CC_PACKED
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct CC_PACKED
typedef struct CC_PACKED CC_ALIGNED(4)
{
_MBXh mbxheader;
_COEh coeheader;
@ -584,19 +693,19 @@ typedef struct
#define ESC_MBX1_sml (ESCvar.activemb1->cfg_sml)
#define ESC_MBX1_sme (ESCvar.activemb1->cfg_sme)
#define ESC_MBX1_smc (ESCvar.activemb1->cfg_smc)
#define ESC_MBXBUFFERS (ESCvar.mbxbuffers)
#define ESC_SM2_sma (ESCvar.pdosm[0].cfg_sma)
#define ESC_SM2_smc (ESCvar.pdosm[0].cfg_smc)
#define ESC_SM2_act (ESCvar.pdosm[0].cfg_smact)
#define ESC_SM3_sma (ESCvar.pdosm[1].cfg_sma)
#define ESC_SM3_smc (ESCvar.pdosm[1].cfg_smc)
#define ESC_SM3_act (ESCvar.pdosm[1].cfg_smact)
#define ESC_MBXBUFFERS (MBXBUFFERS)
#define ESC_SM2_sma (SM2_sma)
#define ESC_SM2_smc (SM2_smc)
#define ESC_SM2_act (SM2_act)
#define ESC_SM3_sma (SM3_sma)
#define ESC_SM3_smc (SM3_smc)
#define ESC_SM3_act (SM3_act)
#define ESC_MBXHSIZE sizeof(_MBXh)
#define ESC_MBXHSIZE ((uint32_t)sizeof(_MBXh))
#define ESC_MBXDSIZE (ESC_MBXSIZE - ESC_MBXHSIZE)
#define ESC_FOEHSIZE sizeof(_FOEh)
#define ESC_FOEHSIZE (uint32_t)sizeof(_FOEh)
#define ESC_FOE_DATA_SIZE (ESC_MBXSIZE - (ESC_MBXHSIZE +ESC_FOEHSIZE))
#define ESC_EOEHSIZE sizeof(_EOEh)
#define ESC_EOEHSIZE ((uint32_t)sizeof(_EOEh))
#define ESC_EOE_DATA_SIZE (ESC_MBXSIZE - (ESC_MBXHSIZE +ESC_EOEHSIZE))
void ESC_config (esc_cfg_t * cfg);
@ -606,6 +715,7 @@ uint32_t ESC_ALeventread (void);
void ESC_ALeventmaskwrite (uint32_t mask);
uint32_t ESC_ALeventmaskread (void);
void ESC_ALstatus (uint8_t status);
void ESC_ALstatusgotoerror (uint8_t status, uint16_t errornumber);
void ESC_SMstatus (uint8_t n);
uint8_t ESC_WDstatus (void);
uint8_t ESC_claimbuffer (void);
@ -632,6 +742,8 @@ extern void APP_safeoutput ();
extern _ESCvar ESCvar;
extern _MBXcontrol MBXcontrol[];
extern uint8_t MBX[];
extern _SMmap SMmap2[];
extern _SMmap SMmap3[];
/* ATOMIC operations are used when running interrupt driven */
#ifndef CC_ATOMIC_SET

File diff suppressed because it is too large Load Diff

View File

@ -13,21 +13,20 @@
#include <cc.h>
CC_PACKED_BEGIN
typedef struct CC_PACKED
typedef struct
{
uint16_t subindex;
uint16_t datatype;
uint16_t bitlength;
uint16_t access;
uint16_t flags;
const char *name;
uint32_t value;
void *data;
} _objd;
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct CC_PACKED
typedef struct
{
uint16_t index;
uint16_t objtype;
@ -36,7 +35,14 @@ typedef struct CC_PACKED
const char *name;
const _objd *objdesc;
} _objectlist;
CC_PACKED_END
typedef struct
{
const _objd * obj;
const _objectlist * objectlistitem;
uint32_t offset;
} _SMmap;
#define OBJH_READ 0
#define OBJH_WRITE 1
@ -66,6 +72,9 @@ CC_PACKED_END
#define DTYPE_REAL64 0x0011
#define DTYPE_PDO_MAPPING 0x0021
#define DTYPE_IDENTITY 0x0023
#define DTYPE_BITARR8 0x002D
#define DTYPE_BITARR16 0x002E
#define DTYPE_BITARR32 0x002F
#define DTYPE_BIT1 0x0030
#define DTYPE_BIT2 0x0031
#define DTYPE_BIT3 0x0032
@ -74,24 +83,56 @@ CC_PACKED_END
#define DTYPE_BIT6 0x0035
#define DTYPE_BIT7 0x0036
#define DTYPE_BIT8 0x0037
#define DTYPE_ARRAY_OF_INT 0x0260
#define DTYPE_ARRAY_OF_SINT 0x0261
#define DTYPE_ARRAY_OF_DINT 0x0262
#define DTYPE_ARRAY_OF_UDINT 0x0263
#define ATYPE_RO 0x07
#define ATYPE_RW 0x3F
#define ATYPE_RWpre 0x0F
#define ATYPE_Rpre 0x01
#define ATYPE_Rsafe 0x02
#define ATYPE_Rop 0x04
#define ATYPE_Wpre 0x08
#define ATYPE_Wsafe 0x10
#define ATYPE_Wop 0x20
#define ATYPE_RXPDO 0x40
#define ATYPE_TXPDO 0x80
#define ATYPE_BACKUP 0x100
#define ATYPE_SETTING 0x200
#define ATYPE_RO (ATYPE_Rpre | ATYPE_Rsafe | ATYPE_Rop)
#define ATYPE_WO (ATYPE_Wpre | ATYPE_Wsafe | ATYPE_Wop)
#define ATYPE_RW (ATYPE_RO | ATYPE_WO)
#define ATYPE_RWpre (ATYPE_Wpre | ATYPE_RO)
#define ATYPE_RWop (ATYPE_Wop | ATYPE_RO)
#define ATYPE_RWpre_safe (ATYPE_Wpre | ATYPE_Wsafe | ATYPE_RO)
#define TX_PDO_OBJIDX 0x1c13
#define RX_PDO_OBJIDX 0x1c12
void ESC_coeprocess (void);
uint16_t sizeOfPDO (uint16_t index);
void SDO_abort (uint16_t index, uint8_t subindex, uint32_t abortcode);
void COE_initDefaultSyncMgrPara (void);
int COE_getSyncMgrPara (uint16_t index, uint8_t subindex, void * buf, uint16_t datatype);
#define COMPLETE_ACCESS_FLAG (1 << 15)
extern void ESC_objecthandler (uint16_t index, uint8_t subindex);
extern int ESC_pre_objecthandler (uint16_t index, uint8_t subindex);
void ESC_coeprocess (void);
int16_t SDO_findsubindex (int32_t nidx, uint8_t subindex);
int32_t SDO_findobject (uint16_t index);
uint16_t sizeOfPDO (uint16_t index, int * nmappings, _SMmap * sm, int max_mappings);
void COE_initDefaultValues (void);
void COE_pdoPack (uint8_t * buffer, int nmappings, _SMmap * sm);
void COE_pdoUnpack (uint8_t * buffer, int nmappings, _SMmap * sm);
uint8_t COE_maxSub (uint16_t index);
extern uint32_t ESC_download_post_objecthandler (uint16_t index, uint8_t subindex, uint16_t flags);
extern uint32_t ESC_download_pre_objecthandler (uint16_t index,
uint8_t subindex,
void * data,
size_t size,
uint16_t flags);
extern uint32_t ESC_upload_pre_objecthandler (uint16_t index,
uint8_t subindex,
void * data,
size_t *size,
uint16_t flags);
extern uint32_t ESC_upload_post_objecthandler (uint16_t index, uint8_t subindex, uint16_t flags);
extern const _objectlist SDOobjects[];
#endif

View File

@ -15,6 +15,8 @@
#include <string.h>
static uint8_t eep_buf[8];
static uint16_t eep_read_size = 8U;
static void (*eep_reload_ptr)(eep_stat_t *stat) = NULL;
/** EPP periodic task of ESC side EEPROM emulation.
*
@ -51,19 +53,53 @@ void EEP_process (void)
break;
case EEP_CMD_READ:
case EEP_CMD_RELOAD:
/* handle read request */
if (EEP_read (stat.addr * sizeof(uint16_t), eep_buf, EEP_READ_SIZE) != 0) {
if (EEP_read (stat.addr * 2U /* sizeof(uint16_t) */, eep_buf, eep_read_size) != 0) {
stat.contstat.bits.ackErr = 1;
} else {
ESC_write (ESCREG_EEDATA, eep_buf, EEP_READ_SIZE);
}
else {
ESC_write(ESCREG_EEDATA, eep_buf, eep_read_size);
}
break;
case EEP_CMD_RELOAD:
/* user defined reload if set */
if (eep_reload_ptr != NULL) {
/* Reload function is responsible to update
* control status register bits.
*/
(*eep_reload_ptr)(&stat);
}
else {
if (eep_read_size == 8U) {
/* handle reload request */
if (EEP_read(stat.addr * 2U /* sizeof(uint16_t) */, eep_buf, eep_read_size) != 0) {
stat.contstat.bits.ackErr = 1;
}
else {
ESC_write(ESCREG_EEDATA, eep_buf, eep_read_size);
}
}
else {
/* Default handler of reload request for 4 Byte read, load config alias.
* To support other ESC behavior, implement user defined reload.
*/
if (EEP_read(EEP_CONFIG_ALIAS_WORD_OFFSET * 2U /* sizeof(uint16_t) */,
eep_buf,
2U /* 2 Bytes config alias*/) != 0) {
stat.contstat.bits.ackErr = 1;
}
else {
ESC_write(ESCREG_EEDATA, eep_buf, 2U /* 2 Bytes config alias*/);
}
}
}
break;
case EEP_CMD_WRITE:
/* handle write request */
ESC_read (ESCREG_EEDATA, eep_buf, EEP_WRITE_SIZE);
if (EEP_write (stat.addr * sizeof(uint16_t), eep_buf, EEP_WRITE_SIZE) != 0) {
if (EEP_write (stat.addr * 2U /* sizeof(uint16_t) */, eep_buf, EEP_WRITE_SIZE) != 0) {
stat.contstat.bits.ackErr = 1;
}
break;
@ -78,3 +114,24 @@ void EEP_process (void)
}
}
/** EPP Set read size, 4 Byte or 8 Byte depending on ESC.
* Default 8 Byte.
*/
void EEP_set_read_size (uint16_t read_size)
{
if ((read_size == 8U) || (read_size == 4U)) {
eep_read_size = read_size;
}
}
/** EPP Set reload function pointer.
* Function shall update current stat accordingly.
* Eg. on CRC error reload function shall set
* stat.contstat.bits.csumErr = 1
* stat.contstat.bits.ackErr = 1
*
*/
void EEP_set_reload_function_pointer(void (*reload_ptr)(eep_stat_t* stat))
{
eep_reload_ptr = reload_ptr;
}

View File

@ -15,14 +15,16 @@
#include "esc.h"
/* EEPROM commands */
#define EEP_CMD_IDLE 0x0
#define EEP_CMD_READ 0x1
#define EEP_CMD_WRITE 0x2
#define EEP_CMD_RELOAD 0x3
#define EEP_CMD_IDLE 0x0
#define EEP_CMD_READ 0x1
#define EEP_CMD_WRITE 0x2
#define EEP_CMD_RELOAD 0x4
/* read/write size */
#define EEP_READ_SIZE 8
#define EEP_WRITE_SIZE 2
/* write size */
#define EEP_WRITE_SIZE 2
/* EEPROm word offset */
#define EEP_CONFIG_ALIAS_WORD_OFFSET 4
/* CONSTAT register content */
typedef struct CC_PACKED
@ -69,6 +71,80 @@ typedef union eep_config
/* periodic task */
void EEP_process (void);
/**
* Application Notes: EEPROM emulation
*
* NOTE: Special handling needed when 4 Byte read is supported.
*
* Ref. ET1100 Datasheet sec2_registers_3i0, chapter 2.45.1,
* "EEPROM emulation with 32 bit EEPROM data register (0x0502[6]=0)".
*
* For a Reload command, fill the EEPROM Data register with the
* values shown in the chapter 2.45.1 before acknowledging
* the command. These values are automatically transferred to the
* designated registers after the Reload command is acknowledged.
*
* NOTE: When 4 Byte read is supported, EEP_process will only load
* config alias on reload.
*
* NOTE: EEP_process support implementing a custom reload function
* for both 4 Byte and 8 Byte read support.
*
* NOTE: Code snippet for custom reload function when 4 Byte read is supported.
*
* void reload_ptr(eep_stat_t *stat)
* {
* eep_config_t ee_cfg;
*
* // Read configuration area
* EEP_read(0, &ee_cfg, sizeof(ee_cfg);
*
* // Check CRC
* if(is_crc_ok(&ee_cfg) == true)
* {
* // Write config alias to EEPROM data registers.
* // Will be loaded to 0x12:13 on command ack.
* ESC_write(ESCREG_EEDATA,
* &ee_cfg.configured_station_alias,
* sizeof(configured_station_alias));
* }
* else
* {
* // Indicate CRC error
* stat->contstat.bits.csumErr = 1;
* stat->contstat.bits.ackErr = 1;
* }
* }
* NOTE: Code snippet for custom reload function when 8 Byte read is supported.
*
* void reload_ptr(eep_stat_t *stat)
* {
* eep_config_t ee_cfg;
*
* // Read configuration area
* EEP_read(0, &ee_cfg, sizeof(ee_cfg);
*
* // Check CRC
* if(is_crc_ok(&ee_cfg) == true)
* {
* // Load EEPROM data at requested EEPROM address
* EEP_read (stat->addr * sizeof(uint16_t), eep_buf, 8U);
* // Write loaded data to EEPROM data registers
* ESC_write(ESCREG_EEDATA, eep_buf, 8U);
* }
* else
* {
* // Indicate CRC error
* stat->contstat.bits.csumErr = 1;
* stat->contstat.bits.ackErr = 1;
* }
* }
*/
/* Set eep internal variables */
void EEP_set_read_size (uint16_t read_size);
void EEP_set_reload_function_pointer (void (*reload_ptr)(eep_stat_t *stat));
/* From hardware file */
void EEP_init (void);
int8_t EEP_read (uint32_t addr, uint8_t *data, uint16_t size);

View File

@ -20,12 +20,12 @@
#define EOE_HTONL(x) (x)
#define EOE_NTOHL(x) (x)
#else
#define EOE_HTONS(x) ((((x) & 0x00ffUL) << 8) | (((x) & 0xff00UL) >> 8))
#define EOE_HTONS(x) ((((x) & 0x00ffU) << 8) | (((x) & 0xff00U) >> 8))
#define EOE_NTOHS(x) EOE_HTONS(x)
#define EOE_HTONL(x) ((((x) & 0x000000ffUL) << 24) | \
(((x) & 0x0000ff00UL) << 8) | \
(((x) & 0x00ff0000UL) >> 8) | \
(((x) & 0xff000000UL) >> 24))
#define EOE_HTONL(x) ((((x) & 0x000000ffU) << 24) | \
(((x) & 0x0000ff00U) << 8) | \
(((x) & 0x00ff0000U) >> 8) | \
(((x) & 0xff000000U) >> 24))
#define EOE_NTOHL(x) EOE_HTONL(x)
#endif /* #if defined(EC_BIG_ENDIAN) */
@ -47,37 +47,37 @@
/** Header frame info 1 */
#define EOE_HDR_FRAME_TYPE_OFFSET 0
#define EOE_HDR_FRAME_TYPE (0xF << 0)
#define EOE_HDR_FRAME_TYPE_SET(x) (((x) & 0xF) << 0)
#define EOE_HDR_FRAME_TYPE_SET(x) ((uint16_t)(((x) & 0xF) << 0))
#define EOE_HDR_FRAME_TYPE_GET(x) (((x) >> 0) & 0xF)
#define EOE_HDR_FRAME_PORT_OFFSET 4
#define EOE_HDR_FRAME_PORT (0xF << 4)
#define EOE_HDR_FRAME_PORT_SET(x) (((x) & 0xF) << 4)
#define EOE_HDR_FRAME_PORT_SET(x) ((uint16_t)(((x) & 0xF) << 4))
#define EOE_HDR_FRAME_PORT_GET(x) (((x) >> 4) & 0xF)
#define EOE_HDR_LAST_FRAGMENT_OFFSET 8
#define EOE_HDR_LAST_FRAGMENT (0x1 << 8)
#define EOE_HDR_LAST_FRAGMENT_SET(x) (((x) & 0x1) << 8)
#define EOE_HDR_LAST_FRAGMENT_SET(x) ((uint16_t)(((x) & 0x1) << 8))
#define EOE_HDR_LAST_FRAGMENT_GET(x) (((x) >> 8) & 0x1)
#define EOE_HDR_TIME_APPEND_OFFSET 9
#define EOE_HDR_TIME_APPEND (0x1 << 9)
#define EOE_HDR_TIME_APPEND_SET(x) (((x) & 0x1) << 9)
#define EOE_HDR_TIME_APPEND_SET(x) ((uint16_t)(((x) & 0x1) << 9))
#define EOE_HDR_TIME_APPEND_GET(x) (((x) >> 9) & 0x1)
#define EOE_HDR_TIME_REQUEST_OFFSET 10
#define EOE_HDR_TIME_REQUEST (0x1 << 10)
#define EOE_HDR_TIME_REQUEST_SET(x) (((x) & 0x1) << 10)
#define EOE_HDR_TIME_REQUEST_SET(x) ((uint16_t)(((x) & 0x1) << 10))
#define EOE_HDR_TIME_REQUEST_GET(x) (((x) >> 10) & 0x1)
/** Header frame info 2 */
#define EOE_HDR_FRAG_NO_OFFSET 0
#define EOE_HDR_FRAG_NO (0x3F << 0)
#define EOE_HDR_FRAG_NO_SET(x) (((x) & 0x3F) << 0)
#define EOE_HDR_FRAG_NO_SET(x) ((uint16_t)(((x) & 0x3F) << 0))
#define EOE_HDR_FRAG_NO_GET(x) (((x) >> 0) & 0x3F)
#define EOE_HDR_FRAME_OFFSET_OFFSET 6
#define EOE_HDR_FRAME_OFFSET (0x3F << 6)
#define EOE_HDR_FRAME_OFFSET_SET(x) (((x) & 0x3F) << 6)
#define EOE_HDR_FRAME_OFFSET_SET(x) ((uint16_t)(((x) & 0x3F) << 6))
#define EOE_HDR_FRAME_OFFSET_GET(x) (((x) >> 6) & 0x3F)
#define EOE_HDR_FRAME_NO_OFFSET 12
#define EOE_HDR_FRAME_NO (0xF << 12)
#define EOE_HDR_FRAME_NO_SET(x) (((x) & 0xF) << 12)
#define EOE_HDR_FRAME_NO_SET(x) ((uint16_t)(((x) & 0xF) << 12))
#define EOE_HDR_FRAME_NO_GET(x) (((x) >> 12) & 0xF)
/** EOE param */
@ -108,6 +108,8 @@
#define EOE_DNS_NAME_LENGTH 32
/** Ethernet address length not including VLAN */
#define EOE_ETHADDR_LENGTH 6
/** IPv4 address length */
#define EOE_IP4_LENGTH 4U /* sizeof(uint32_t) */
/** EOE ip4 address in network order */
struct eoe_ip4_addr {
@ -133,18 +135,18 @@ typedef struct
/** Current RX fragment number */
uint8_t rxfragmentno;
/** Complete RX frame size of current frame */
uint16_t rxframesize;
uint32_t rxframesize;
/** Current RX data offset in frame */
uint16_t rxframeoffset;
uint32_t rxframeoffset;
/** Current RX frame number */
uint16_t rxframeno;
/** Current TX fragment number */
uint8_t txfragmentno;
/** Complete TX frame size of current frame */
uint16_t txframesize;
uint32_t txframesize;
/** Current TX data offset in frame */
uint16_t txframeoffset;
uint32_t txframeoffset;
} _EOEvar;
/** EoE IP request structure */
@ -215,7 +217,7 @@ static void EOE_ip_byte_to_uint32 (uint8_t * byte_ip, eoe_ip4_addr_t * ip)
* @param[out] mac = variable to store mac in, should fit EOE_ETHADDR_LENGTH
* @return 0= if we succeed, -1 if not set
*/
int EOE_get_mac(uint8_t port, uint8_t mac[])
int EOE_ecat_get_mac(uint8_t port, uint8_t mac[])
{
int ret = -1;
int port_ix;
@ -504,7 +506,7 @@ static void EOE_get_ip (void)
uint16_t frameinfo1;
uint8_t port;
uint8_t flags;
uint8_t data_offset;
uint32_t data_offset;
int port_ix;
req_eoembx = (_EOE *) &MBX[0];
@ -516,15 +518,15 @@ static void EOE_get_ip (void)
if(port > EOE_NUMBER_OF_PORTS)
{
DPRINT("Invalid port\n");
frameinfo1 = EOE_HDR_FRAME_PORT_SET(port);
frameinfo1 |= EOE_INIT_RESP;
frameinfo1 |= EOE_HDR_LAST_FRAGMENT;
/* Return error response on given port */
EOE_no_data_response((EOE_HDR_FRAME_PORT_SET(port) |
EOE_INIT_RESP |
EOE_HDR_LAST_FRAGMENT),
EOE_no_data_response(frameinfo1,
EOE_RESULT_UNSPECIFIED_ERROR);
return;
}
/* Refresh settings if needed */
if(eoe_cfg->load_eth_settings != NULL)
{
@ -538,10 +540,10 @@ static void EOE_get_ip (void)
eoembx = (_EOE *) &MBX[mbxhandle * ESC_MBXSIZE];
eoembx->mbxheader.mbxtype = MBXEOE;
MBXcontrol[mbxhandle].state = MBXstate_outreq;
eoembx->eoeheader.frameinfo1 =
htoes(EOE_HDR_FRAME_TYPE_SET(EOE_GET_IP_PARAM_RESP) |
EOE_HDR_FRAME_PORT_SET(port) |
EOE_HDR_LAST_FRAGMENT);
frameinfo1 = EOE_HDR_FRAME_PORT_SET(port);
frameinfo1 |= EOE_HDR_FRAME_TYPE_SET(EOE_GET_IP_PARAM_RESP);
frameinfo1 |= EOE_HDR_LAST_FRAGMENT;
eoembx->eoeheader.frameinfo1 = htoes(frameinfo1);
eoembx->eoeheader.frameinfo2 = 0;
/* include mac in get ip request */
@ -552,55 +554,60 @@ static void EOE_get_ip (void)
memcpy(&eoembx->data[data_offset] ,
nic_ports[port_ix].mac.addr,
EOE_ETHADDR_LENGTH);
/* Add size of mac address */
data_offset += EOE_ETHADDR_LENGTH;
}
/* Add size of mac address */
data_offset += EOE_ETHADDR_LENGTH;
/* include ip in get ip request */
if(nic_ports[port_ix].ip_set)
{
flags |= EOE_PARAM_IP_INCLUDE;
EOE_ip_uint32_to_byte(&nic_ports[port_ix].ip,
&eoembx->data[data_offset]);
/* Add size of uint32 IP address */
data_offset += EOE_IP4_LENGTH;
}
/* Add size of uint32 IP address */
data_offset += 4;
/* include subnet in get ip request */
if(nic_ports[port_ix].subnet_set)
{
flags |= EOE_PARAM_SUBNET_IP_INCLUDE;
EOE_ip_uint32_to_byte(&nic_ports[port_ix].subnet,
&eoembx->data[data_offset]);
/* Add size of uint32 IP address */
data_offset += EOE_IP4_LENGTH;
}
/* Add size of uint32 IP address */
data_offset += 4;
/* include default gateway in get ip request */
if(nic_ports[port_ix].default_gateway_set)
{
flags |= EOE_PARAM_DEFAULT_GATEWAY_INCLUDE;
EOE_ip_uint32_to_byte(&nic_ports[port_ix].default_gateway,
&eoembx->data[data_offset]);
/* Add size of uint32 IP address */
data_offset += EOE_IP4_LENGTH;
}
/* Add size of uint32 IP address */
data_offset += 4;
/* include dns ip in get ip request */
if(nic_ports[port_ix].dns_ip_set)
{
flags |= EOE_PARAM_DNS_IP_INCLUDE;
EOE_ip_uint32_to_byte(&nic_ports[port_ix].dns_ip,
&eoembx->data[data_offset]);
/* Add size of uint32 IP address */
data_offset += EOE_IP4_LENGTH;
}
/* Add size of uint32 IP address */
data_offset += 4;
/* include dns name in get ip request */
if(nic_ports[port_ix].dns_name_set)
{
/* TwinCAT include EOE_DNS_NAME_LENGTH chars even if name is shorter */
flags |= EOE_PARAM_DNS_NAME_INCLUDE;
memcpy(&eoembx->data[data_offset],
nic_ports[port_ix].dns_name,
EOE_DNS_NAME_LENGTH);
/* Add size of dns name length */
data_offset += EOE_DNS_NAME_LENGTH;
}
/* Add size of dns name length */
data_offset += EOE_DNS_NAME_LENGTH;
eoembx->data[0] = flags;
eoembx->mbxheader.length = htoes (ESC_EOEHSIZE + data_offset);
@ -612,11 +619,10 @@ static void EOE_get_ip (void)
static void EOE_set_ip (void)
{
_EOE *eoembx;
uint16_t eoedatasize;
uint32_t eoedatasize, data_offset;
uint16_t frameinfo1;
uint8_t port;
uint8_t flags;
uint8_t data_offset;
uint16_t result;
int port_ix;
@ -631,10 +637,10 @@ static void EOE_set_ip (void)
{
DPRINT("Invalid port\n");
/* Return error response on given port */
EOE_no_data_response((EOE_HDR_FRAME_PORT_SET(port) |
EOE_INIT_RESP |
EOE_HDR_LAST_FRAGMENT),
EOE_RESULT_UNSPECIFIED_ERROR);
frameinfo1 = EOE_HDR_FRAME_PORT_SET(port);
frameinfo1 |= EOE_INIT_RESP;
frameinfo1 |= EOE_HDR_LAST_FRAGMENT;
EOE_no_data_response(frameinfo1, EOE_RESULT_UNSPECIFIED_ERROR);
return;
}
@ -646,55 +652,55 @@ static void EOE_set_ip (void)
&eoembx->data[data_offset],
EOE_ETHADDR_LENGTH);
nic_ports[port_ix].mac_set = 1;
/* Add size of mac address */
data_offset += EOE_ETHADDR_LENGTH;
}
/* Add size of mac address */
data_offset += EOE_ETHADDR_LENGTH;
/* ip included in set ip request? */
if(flags & EOE_PARAM_IP_INCLUDE)
{
EOE_ip_byte_to_uint32(&eoembx->data[data_offset],
&nic_ports[port_ix].ip);
nic_ports[port_ix].ip_set = 1;
/* Add size of uint32 IP address */
data_offset += EOE_IP4_LENGTH;
}
/* Add size of uint32 IP address */
data_offset += 4;
/* subnet included in set ip request? */
if(flags & EOE_PARAM_SUBNET_IP_INCLUDE)
{
EOE_ip_byte_to_uint32(&eoembx->data[data_offset],
&nic_ports[port_ix].subnet);
nic_ports[port_ix].subnet_set = 1;
/* Add size of uint32 IP address */
data_offset += EOE_IP4_LENGTH;
}
/* Add size of uint32 IP address */
data_offset += 4;
/* default gateway included in set ip request? */
if(flags & EOE_PARAM_DEFAULT_GATEWAY_INCLUDE)
{
EOE_ip_byte_to_uint32(&eoembx->data[data_offset],
&nic_ports[port_ix].default_gateway);
nic_ports[port_ix].default_gateway_set = 1;
/* Add size of uint32 IP address */
data_offset += EOE_IP4_LENGTH;
}
/* Add size of uint32 IP address */
data_offset += 4;
/* dns ip included in set ip request? */
if(flags & EOE_PARAM_DNS_IP_INCLUDE)
{
EOE_ip_byte_to_uint32(&eoembx->data[data_offset],
&nic_ports[port_ix].dns_ip);
nic_ports[port_ix].dns_ip_set = 1;
/* Add size of uint32 IP address */
data_offset += EOE_IP4_LENGTH;
}
/* Add size of uint32 IP address */
data_offset += 4;
/* dns name included in set ip request? */
if(flags & EOE_PARAM_DNS_NAME_INCLUDE)
{
uint16_t dns_len = MIN((eoedatasize - data_offset), EOE_DNS_NAME_LENGTH);
uint32_t dns_len = MIN((eoedatasize - data_offset), EOE_DNS_NAME_LENGTH);
memcpy(nic_ports[port_ix].dns_name,
&eoembx->data[data_offset],
dns_len);
nic_ports[port_ix].dns_name_set = 1;
data_offset += dns_len; /* expected 1- EOE_DNS_NAME_LENGTH; */
}
data_offset += EOE_DNS_NAME_LENGTH;
if(data_offset > eoedatasize)
{
@ -706,17 +712,17 @@ static void EOE_set_ip (void)
* you typically set the IP for the TCP/IP stack */
if(eoe_cfg->store_ethernet_settings != NULL)
{
result = eoe_cfg->store_ethernet_settings();
result = (uint16_t)eoe_cfg->store_ethernet_settings();
}
else
{
result = EOE_RESULT_NO_IP_SUPPORT;
}
}
EOE_no_data_response((EOE_HDR_FRAME_PORT_SET(port) |
EOE_INIT_RESP |
EOE_HDR_LAST_FRAGMENT),
result);
frameinfo1 = EOE_HDR_FRAME_PORT_SET(port);
frameinfo1 |= EOE_INIT_RESP;
frameinfo1 |= EOE_HDR_LAST_FRAGMENT;
EOE_no_data_response(frameinfo1, result);
}
/** EoE receive fragment handler.
@ -725,14 +731,14 @@ static void EOE_receive_fragment (void)
{
_EOE *eoembx;
eoembx = (_EOE *) &MBX[0];
uint16_t eoedatasize = etohs(eoembx->mbxheader.length) - ESC_EOEHSIZE;
uint32_t eoedatasize = etohs(eoembx->mbxheader.length) - ESC_EOEHSIZE;
uint16_t frameinfo1 = etohs(eoembx->eoeheader.frameinfo1);
uint16_t frameinfo2 = etohs(eoembx->eoeheader.frameinfo2);
/* Capture error case */
if(EOEvar.rxfragmentno != EOE_HDR_FRAG_NO_GET(frameinfo2))
{
DPRINT("Unexpected fragment number %d, expected: %d\n",
DPRINT("Unexpected fragment number %"PRIu32", expected: %"PRIu32"\n",
EOE_HDR_FRAG_NO_GET(frameinfo2), EOEvar.rxfragmentno);
/* Clean up existing saved data */
if(EOEvar.rxfragmentno != 0)
@ -757,22 +763,28 @@ static void EOE_receive_fragment (void)
EOEvar.rxframeoffset = 0;
EOEvar.rxframeno = EOE_HDR_FRAME_NO_GET(frameinfo2);
}
else
{
DPRINT("Receive buffer is invalid\n");
EOE_init_rx ();
return;
}
}
/* In frame fragment received */
else
{
uint16_t offset = (EOE_HDR_FRAME_OFFSET_GET(frameinfo2) << 5);
uint32_t offset = (EOE_HDR_FRAME_OFFSET_GET(frameinfo2) << 5);
/* Validate received fragment */
if(EOEvar.rxframeno != EOE_HDR_FRAME_NO_GET(frameinfo2))
{
DPRINT("Unexpected frame number %d, expected: %d\n",
DPRINT("Unexpected frame number %"PRIu32", expected: %"PRIu32"\n",
EOE_HDR_FRAME_NO_GET(frameinfo2), EOEvar.rxframeno);
EOE_init_rx ();
return;
}
else if(EOEvar.rxframeoffset != offset)
{
DPRINT("Unexpected frame offset %d, expected: %d\n",
DPRINT("Unexpected frame offset %"PRIu32", expected: %"PRIu32"\n",
offset, EOEvar.rxframeoffset);
EOE_init_rx ();
return;
@ -790,8 +802,7 @@ static void EOE_receive_fragment (void)
}
else
{
DPRINT("Size of data exceed available buffer size\n",
EOEvar.rxframeoffset);
DPRINT("Size of data exceed available buffer size\n");
EOE_init_rx ();
return;
}
@ -801,7 +812,7 @@ static void EOE_receive_fragment (void)
/* Remove time stamp, TODO support for time stamp? */
if(EOE_HDR_TIME_APPEND_GET(frameinfo1))
{
EOEvar.rxframeoffset -= 4;
EOEvar.rxframeoffset -= 4U;
}
EOEvar.rxebuf.len = EOEvar.rxframeoffset;
eoe_cfg->handle_recv_buffer(EOE_HDR_FRAME_PORT_GET(frameinfo1),
@ -819,7 +830,7 @@ static void EOE_send_fragment ()
_EOE *eoembx;
uint8_t mbxhandle;
int len;
int len_to_send;
uint32_t len_to_send;
uint16_t frameinfo1;
uint16_t frameinfo2;
static uint8_t frameno = 0;
@ -831,7 +842,7 @@ static void EOE_send_fragment ()
len = eoe_cfg->fetch_send_buffer(0, &EOEvar.txebuf);
if(len > 0)
{
EOEvar.txframesize = len;
EOEvar.txframesize = (uint32_t)len;
}
else
{
@ -843,7 +854,7 @@ static void EOE_send_fragment ()
mbxhandle = ESC_claimbuffer ();
if (mbxhandle)
{
len_to_send = EOEvar.txframesize - EOEvar.txframeoffset;
len_to_send = (EOEvar.txframesize - EOEvar.txframeoffset);
if((len_to_send + ESC_EOEHSIZE + ESC_MBXHSIZE) > ESC_MBXSIZE)
{
/* Adjust to len in whole 32 octet blocks to fit specification*/
@ -861,23 +872,26 @@ static void EOE_send_fragment ()
frameinfo1 = 0;
}
uint16_t tempframe2;
/* Set fragment number */
frameinfo2 = EOE_HDR_FRAG_NO_SET(EOEvar.txfragmentno);
/* Set complete size for fragment 0 or offset for in frame fragments */
if(EOEvar.txfragmentno > 0)
{
frameinfo2 |= (EOE_HDR_FRAME_OFFSET_SET((EOEvar.txframeoffset >> 5)));
tempframe2 = EOE_HDR_FRAME_OFFSET_SET((EOEvar.txframeoffset >> 5));
frameinfo2 |= tempframe2;
}
else
{
frameinfo2 |=
(EOE_HDR_FRAME_OFFSET_SET(((EOEvar.txframesize + 31) >> 5)));
tempframe2 = EOE_HDR_FRAME_OFFSET_SET(((EOEvar.txframesize + 31) >> 5));
frameinfo2 |= tempframe2;
frameno++;
}
/* Set frame number */
frameinfo2 = frameinfo2 | EOE_HDR_FRAME_NO_SET(frameno);
tempframe2 = EOE_HDR_FRAME_NO_SET(frameno);
frameinfo2 |= tempframe2;
eoembx = (_EOE *) &MBX[mbxhandle * ESC_MBXSIZE];
eoembx->mbxheader.length = htoes (len_to_send + ESC_EOEHSIZE);
@ -899,7 +913,11 @@ static void EOE_send_fragment ()
else
{
EOEvar.txframeoffset += len_to_send;
EOEvar.txfragmentno += 1;
EOEvar.txfragmentno++;
}
if(eoe_cfg->fragment_sent_event != NULL)
{
eoe_cfg->fragment_sent_event();
}
}
}

View File

@ -43,6 +43,8 @@ typedef struct eoe_cfg
void (*handle_recv_buffer) (uint8_t port, eoe_pbuf_t * ebuf);
/** Callback to fetch a buffer to send */
int (*fetch_send_buffer) (uint8_t port, eoe_pbuf_t * ebuf);
/** Callback to notify the application fragment sent */
void (*fragment_sent_event) (void);
} eoe_cfg_t;
int EOE_ecat_get_mac (uint8_t port, uint8_t mac[]);

Some files were not shown because too many files have changed in this diff Show More