Compare commits

Invalid templates have been ignored

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

...

156 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
Hans-Erik Floryd c8675af12c bump version for release 2019-05-09 13:47:07 +02:00
nakarlsson df1ef3f076
Merge pull request #51 from hefloryd/feature/bugfix
Minor bugfixes
2019-04-05 18:58:20 +02:00
Hans-Erik Floryd 0bbc40096a bump patch version 2019-04-05 09:26:51 +02:00
Andreas Karlsson ef6e55a6e2 Return data type for SDOinfo for type array and return maxsub of index 0 for array and record, maxsub from object VAR 2019-04-04 15:07:26 +02:00
Hans-Erik Floryd 1917a6f72b fix infoerror abort code
The upper 16 bits of the infoerror abort code was invalid.
2019-04-04 15:07:26 +02:00
Hans-Erik Floryd 15e976f58e do not pack ESCvar
ESCvar contains stack state data and does not need to be packed.
2019-04-04 15:07:26 +02:00
Hans-Erik Floryd 8abbbb1fb8 fail state change if SM2 overlaps SM3
Add a check to verify that SM2 does not overlap SM3.
2019-04-04 15:07:26 +02:00
Hans-Erik Floryd c66a5efb32 fix access check when downloading to RxPDO or TxPDO
The access type field is a bitfield and may have additional bits
set. Use only read/write permission bits to verify access.
2019-04-04 15:07:26 +02:00
Hans-Erik Floryd 45f5c616ca remove unused state variable 2019-04-04 15:07:26 +02:00
Hans-Erik Floryd bdb212942b fix rt-kernel build 2019-04-04 15:07:26 +02:00
nakarlsson edcce5af0f
Merge pull request #48 from OpenEtherCATsociety/hotfix/ti_true_false_defines
Add define for TRUE/FALSE, needed include is missing in the AM335x TI…
2019-02-18 08:30:26 +01:00
Andreas Karlsson 830a7fb394 Add define for TRUE/FALSE, needed include is missing in the AM335x TI BSP 2019-02-18 08:26:24 +01:00
nakarlsson 7808b675e0
Merge pull request #46 from OpenEtherCATsociety/feature/eoe
generic EoE stack parts
2019-01-31 14:56:28 +01:00
Andreas Karlsson 973b774ddf Prototype application for rt-kernel running lwIP and EoE 2019-01-24 17:51:06 +01:00
Andreas Karlsson e38301eb5c draft/concept EoE 2019-01-24 17:41:07 +01:00
nakarlsson 23291ba465
Merge pull request #43 from xoduddk123/linux_lan9252_drv_cleanup
linux lan9252 driver source cleanup
2018-05-10 15:03:11 +02:00
xoduddk123 4e7f341298 linux lan9252 driver source cleanup
Change to misc driver
Change space to tab
Removing unnecessary functions
2018-04-13 12:31:42 +09:00
nakarlsson 4bf6be795b
Merge pull request #42 from nakarlsson/master
Add support for TIESC
2018-02-20 09:03:08 +01:00
rtlaka c08f90bb82 Acknowledge mailbox read by master on SM1 event instead of SM Status IntR 2018-02-19 11:17:31 +01:00
rtlaka 8711eb5968 Add support for tiesc, hal is created for tieschw, tiescbsp provided by TI 2018-02-12 20:03:08 +01:00
nakarlsson b2bfd419a5
Merge pull request #41 from nakarlsson/master
Only read SM Status and Activate in the dedicated functions
2018-01-31 13:27:05 +01:00
rtlaka ba3716ba52 Only read SM Status and Activate in the dedicated function for that purpose 2018-01-31 12:31:48 +01:00
magnjo 56a4dbf247 FoE EOF/file length detection. (#35)
* * Add length argument to FoE write_function().
* FOE_fclose() always call FoE write_function().

* Increment patch version.
2017-12-09 14:52:33 +01:00
Hans-Erik Floryd 49f488ece7
Merge pull request #34 from nakarlsson/master
add support for XMC DAVE toolchain
2017-11-23 16:02:34 +01:00
rtlaka e27c903b9d add support for XMC DAVE toolchain 2017-11-23 07:46:59 +01:00
113 changed files with 12808 additions and 4165 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 1)
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
@ -12,7 +12,7 @@ SOES is an EtherCAT slave stack written in c. Its purpose is to learn and
to use. All users are invited to study the source to get an understanding
how an EtherCAT slave functions.
Features as of 2.1.0:
Feature list:
- Address offset based HAL for easy ESC read/write access via any
interface
- Mailbox with data link layer
@ -20,14 +20,16 @@ Features as of 2.1.0:
- 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
TODO
- Update documentation
- Add EoE sample application

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,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

@ -0,0 +1,361 @@
#include <kern.h>
#include <xmc4.h>
#include <bsp.h>
#include "esc.h"
#include "esc_eoe.h"
#include "esc_hw.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 uint8_t mac_address[6] = {0x1E, 0x30, 0x6C, 0xA2, 0x45, 0x5E};
static void appl_get_buffer (eoe_pbuf_t * ebuf);
static void appl_free_buffer (eoe_pbuf_t * ebuf);
static int appl_load_eth_settings (void);
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);
/* Application variables */
_Objects Obj;
extern sem_t * ecat_isr_sem;
struct netif * net_add_interface (err_t (*netif_fn) (struct netif * netif))
{
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;
}
void cb_get_inputs (void)
{
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;
}
}
void cb_set_outputs (void)
{
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);
}
/* Clean up data if we have been in INIT state */
if ((*as == INIT_TO_PREOP) && (*an == ESCinit))
{
struct pbuf *p;
int i = 0;
while(mbox_fetch_tmo(pbuf_mbox, (void **)&p, 0) == 0)
{
pbuf_free(p);
i++;
}
if(i)
{
rprintf("Cleaned eoe pbuf: %d\n",i);
}
EOE_init();
}
}
/* Callback to allocate a buffer */
static void appl_get_buffer (eoe_pbuf_t * ebuf)
{
struct pbuf * p = pbuf_alloc(PBUF_RAW, PBUF_POOL_BUFSIZE, PBUF_POOL);
if(p != NULL)
{
ebuf->payload = p->payload;
ebuf->pbuf = p;
ebuf->len = p->len;
}
else
{
ebuf->payload = NULL;
ebuf->pbuf = NULL;
ebuf->len = p->len;
}
}
/* Callback to free a buffer */
static void appl_free_buffer (eoe_pbuf_t * ebuf)
{
if(ebuf->pbuf != NULL)
{
pbuf_free(ebuf->pbuf);
}
}
/* Callback to act on a received get IP request.
* From here we can retrieve locla IP and DNS information
*
*/
static int appl_load_eth_settings (void)
{
/*
* ip_addr_t ip;
* IP4_ADDR (&ip, 192, 168, 9, 200)
* ip.addr = ntohl(ip.addr);
* EOE_ecat_set_ip();
*/
return 0;
}
/* Callback to act on a received set IP request.
* Avalaible IP and DNS data depends on what the master provide.
* We only fetch what is needed to init lwIP
*/
static int appl_store_ethernet_settings (void)
{
int ret = 0;
ip_addr_t ip;
ip_addr_t netmask;
ip_addr_t gateway;
/* Fetch received IP information, IP returned in host uint32_t format */
if(EOE_ecat_get_ip (0, &ip.addr) == -1)
{
ret = -1;
}
else if(EOE_ecat_get_subnet (0, &netmask.addr) == -1)
{
ret = -1;
}
else if(EOE_ecat_get_gateway (0, &gateway.addr) == -1)
{
ret = -1;
}
else
{
ip.addr = htonl(ip.addr);
netmask.addr = htonl(netmask.addr);
gateway.addr = htonl(gateway.addr);
/* Configure TCP/IP network stack. DNS server and host name are not set. */
net_configure (found_if, &ip, &netmask, &gateway, NULL, CFG_HOSTNAME);
net_link_up (found_if);
if (netif_is_up (found_if))
{
rprintf ("netif up (%d.%d.%d.%d)\n",
ip4_addr1 (&found_if->ip_addr),
ip4_addr2 (&found_if->ip_addr),
ip4_addr3 (&found_if->ip_addr),
ip4_addr4 (&found_if->ip_addr));
}
else
{
rprintf ("netif down\n");
}
}
return ret;
}
/* Callback from the stack to handled a completed Ethernet frame. */
static void appl_handle_recv_buffer (uint8_t port, eoe_pbuf_t * ebuf)
{
struct pbuf * p = ebuf->pbuf;
p->len = p->tot_len = ebuf->len;
if(ebuf->pbuf != NULL)
{
/* Dummy code for bounce back a L2 frame of type 0x88A4U back to
* the EtherCAT master.
*/
struct eth_hdr *ethhdr;
uint16_t type;
ethhdr = p->payload;
type = htons(ethhdr->type);
if (type == 0x88A4U)
{
if(mbox_post_tmo(pbuf_mbox, p, 0))
{
pbuf_free (p);
rprintf("transmit_frame timeout full?\n");
}
else
{
sem_signal(ecat_isr_sem);
}
}
/* Normal procedure to pass the Ethernet frame to lwIP to handle */
else if (found_if->input (p, found_if) != 0)
{
pbuf_free (p);
}
}
}
/* Callback from the stack to fetch a posted Ethernet frame to send to the
* Master over EtherCAT
*/
static int appl_fetch_send_buffer (uint8_t port, eoe_pbuf_t * ebuf)
{
int ret;
struct pbuf *p;
if(mbox_fetch_tmo(pbuf_mbox, (void **)&p, 0))
{
ebuf->pbuf = NULL;
ebuf->payload = NULL;
ret = -1;
}
else
{
ebuf->pbuf = p;
ebuf->payload = p->payload;
ebuf->len = p->tot_len;
ret = ebuf->len;
}
return ret;
}
/* Util function for lwIP to post Ethernet frames to be sent over dummy
* EtherCAT network interface.
*/
static err_t transmit_frame (struct netif *netif, struct pbuf *p)
{
/* Try posting the buffer to the EoE stack send Q, the caller will try to
* free the buffer if we fail to post..
*/
if(mbox_post_tmo(pbuf_mbox, p, 0))
{
rprintf("transmit_frame timeout full?\n");
}
else
{
/* Create a pbuf ref to keep the buf alive until it is sent over EoE */
pbuf_ref(p);
sem_signal(ecat_isr_sem);
}
return ERR_OK;
}
/* Create an dummy lwIP EtherCAT interface */
err_t eoe_netif_init (struct netif * netif)
{
rprintf("EOE eoe_netif_init called\n");
/* Initialise netif */
netif->name[0] = 'e';
netif->name[1] = 'c';
netif->output = etharp_output;
netif->linkoutput = transmit_frame;
netif->mtu = 1500; /* maximum transfer unit */
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP;
netif->hwaddr_len = ETHARP_HWADDR_LEN;
memcpy (netif->hwaddr, mac_address, sizeof(netif->hwaddr));
return ERR_OK;
}
/* 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)
{
sem_signal(ecat_isr_sem);
}
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 = 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);
/* Set up dummy IF */
found_if = net_add_interface(eoe_netif_init);
if(found_if == NULL)
{
rprintf("OBS! Failed to create an EtherCAT network interface\n");
}
/* Init EoE */
EOE_config(&eoe_config);
rprintf ("Hello world\n");
ecat_slv_init (&config);
/* The stack is run from interrupt and a worker thread in esc_hw.c */
return 0;
}

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

@ -0,0 +1,50 @@
#ifndef __UTYPES_H__
#define __UTYPES_H__
#include "cc.h"
/* Object dictionary storage */
typedef struct
{
/* 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 */
/* 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.

File diff suppressed because it is too large Load Diff

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,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

@ -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

@ -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="k2gice" productCode="0x4291ce">
<Name>k2gice_n</Name>
<Vendor>
<Id>0x1337</Id>
<Name>rt-labs</Name>
</Vendor>
<Group>
<Type>k2gice_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>800CE08800000000</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>k2gice</DefaultValue>
<Length>6</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>0x4291ce</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>k2gice_t</Type>
<Name LcId="1033">am335xice_n</Name>
</Group>
</Groups>
<Devices>
<Device Physics="YY">
<Type ProductCode="#x4291ce" RevisionNo="0">k2gice</Type>
<Name LcId="1033">k2gice_n</Name>
<GroupType>k2gice_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(6)</Name>
<BitSize>48</BitSize>
</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>
</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(6)</Type>
<BitSize>48</BitSize>
<Info>
<DefaultString>k2gice</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>#x4291ce</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>800EE08800000000</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, 48, ATYPE_RO, acName1008, 0, "k2gice"},
};
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, 0x4291ce, 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,80 @@
#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>
/* Application variables */
_Objects Obj;
/**
* This function reads physical input values and assigns the corresponding members
*/
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
*/
void cb_set_outputs()
{
volatile uint8_t io_output;
io_output = Obj.LED;
Board_setDigOutput(io_output);
}
/* 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

@ -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,318 +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");
ESC_reset();
// 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

@ -41,7 +41,7 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MACHINE_FLAGS}" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MACHINE_FLAGS}" CACHE STRING "" FORCE)
# Default libs
set(RTK_LIBS "-l${BSP} -l${ARCH} -lkern -ldev -lsio -lblock -lfs -lusb -llwip -lptpd -leth -li2c -lrtc -lcan -lnand -lspi -lnor -lpwm -ladc -ltrace -lcounter -lc -lm")
set(RTK_LIBS "-l${BSP} -l${ARCH} -lkern -ldev -lsio -lblock -lfs -lusb -llwip -lptpd -leth -li2c -lrtc -lcan -lnand -lspi -lnor -lpwm -ladc -ltrace -lcounter -lc -lm -lshell")
set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -nostartfiles -T${RTK}/bsp/${BSP}/${BSP}.ld -Wl,--start-group <LINK_LIBRARIES> ${RTK_LIBS} -Wl,--end-group")
set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> -nostartfiles -T${RTK}/bsp/${BSP}/${BSP}.ld -Wl,--start-group <LINK_LIBRARIES> ${RTK_LIBS} -Wl,--end-group")

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

@ -1,184 +1,160 @@
/*
Datasheet : http://ww1.microchip.com/downloads/en/DeviceDoc/
00001909A.pdf
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/spi/spi.h>
#include <linux/uaccess.h>
/*
Datasheet : http://ww1.microchip.com/downloads/en/DeviceDoc/
00001909A.pdf
*/
#include <linux/miscdevice.h>
#define LAN9252_MAGIC 'l' //8bit=0~0xff 'l'an9252
#define TEST _IO(LAN9252_MAGIC, 0)
#define LAN9252_LOCK mutex_lock(&lan9252_mutex);
#define LAN9252_UNLOCK mutex_unlock(&lan9252_mutex);
#define LAN9252_LOCK mutex_lock(&lan9252_mutex);
#define LAN9252_UNLOCK mutex_unlock(&lan9252_mutex);
#define DEVICE_NAME "lan9252"
#define LAN9252_MAJOR 153
/* spi command */
#define FAST_READ 0x0B
#define FAST_READ_DUMMY 1
struct mutex lock;
static DEFINE_MUTEX(lan9252_mutex);
dev_t id;
static struct device *dev;
static struct class *lan9252_class;
static struct spi_device *lan9252_devices;
static struct spi_device *lan9252;
static int lan9252_ethercat_probe(struct spi_device *spi);
static int lan9252_ethercat_remove(struct spi_device *spi);
static int lan9252_open(struct inode *inode, struct file *filp)
static loff_t lan9252_llseek(struct file *file, loff_t address, int whence)
{
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__);
return 0;
}
int ret;
static int lan9252_release(struct inode *inode, struct file *filp)
{
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__);
return 0;
}
LAN9252_LOCK;
static loff_t lan9252_llseek(struct file *file, loff_t address,
int whence)
{
int status;
file->f_pos = address;
ret = file->f_pos;
LAN9252_LOCK;
LAN9252_UNLOCK;
file->f_pos = address;
status = file->f_pos;
LAN9252_UNLOCK;
return status;
return ret;
}
static int * lan9252_reg_addr_make(int address)
{
int temp;
static int lan9252_reg_addr[2];
int temp;
static int lan9252_reg_addr[2];
#ifdef DEBUG
int i;
int i;
#endif
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__);
temp = address & 0xff00;
lan9252_reg_addr[0] = temp >> 8;
temp = address & 0x00ff;
lan9252_reg_addr[1] = temp;
temp = address & 0xff00;
lan9252_reg_addr[0] = temp >> 8;
temp = address & 0x00ff;
lan9252_reg_addr[1] = temp;
#ifdef DEBUG
for (i=0; i<2; i++)
dev_dbg(&lan9252_devices->dev, "%s() lan9252_reg_addr[%d] = 0x%x\n",
__FUNCTION__, i, lan9252_reg_addr[i]);
for (i=0; i<2; i++)
dev_dbg(&lan9252->dev, "%s() lan9252_reg_addr[%d] = 0x%x\n",
__FUNCTION__, i, lan9252_reg_addr[i]);
#endif
return lan9252_reg_addr;
return lan9252_reg_addr;
}
/*
int lan9252_test(void);
Description : Check the connection status of LAN9252
Retrun Value
0 : success
other : fail
int lan9252_test(void);
Description : Check the connection status of LAN9252
Retrun Value
0 : success
other : fail
Register Type : SYSTEM CONTROL AND STATUS REGISTERS
Register Name(SYMBOL) : BYTE ORDER TEST REGISTER(BYTE_TEST)
Offset : 0x0064
Size : 32bit
Default : 0x87654321
Datasheet description : Chip-level reset/configuration
completion can be determined by first
polling the
Byte Order Test Register(BYTE_TEST).
Register Type : SYSTEM CONTROL AND STATUS REGISTERS
Register Name(SYMBOL) : BYTE ORDER TEST REGISTER(BYTE_TEST)
Offset : 0x0064
Size : 32bit
Default : 0x87654321
Datasheet description : Chip-level reset/configuration
completion can be determined by first
polling the
Byte Order Test Register(BYTE_TEST).
*/
static int lan9252_test(void)
{
u8 command[4];
u8 test_buffer[4];
int status=0;
u8 command[4];
u8 test_buffer[4];
int ret=0;
#ifdef DEBUG
int i;
int i;
#endif
command[0]=FAST_READ;
command[1]=0x00;
command[2]=0x64;
command[3]=FAST_READ_DUMMY;
command[0]=FAST_READ;
command[1]=0x00;
command[2]=0x64;
command[3]=FAST_READ_DUMMY;
ret = spi_write_then_read(lan9252, &command, sizeof(command),
test_buffer, sizeof(test_buffer));
if (ret < 0 ) {
dev_err(&lan9252->dev, "%s() spi_write_then_read failed "
"ret=%d\n", __FUNCTION__, ret);
return -1;
}
status = spi_write_then_read(lan9252_devices, &command,
sizeof(command), test_buffer, sizeof(test_buffer));
if (status < 0 ) {
dev_err(&lan9252_devices->dev, "%s() spi_write_then_read "
" failed status=%d\n", __FUNCTION__, status);
return -1;
}
ret = spi_write_then_read(lan9252, &command, sizeof(command),
test_buffer, sizeof(test_buffer));
if (ret < 0) {
dev_err(&lan9252->dev, "%s() spi_write_then_read failed "
"ret=%d\n", __FUNCTION__, ret);
return -1;
}
status = spi_write_then_read(lan9252_devices, &command,
sizeof(command), test_buffer, sizeof(test_buffer));
if (status < 0 ) {
dev_err(&lan9252_devices->dev, "%s() spi_write_then_read "
" failed status=%d\n", __FUNCTION__, status);
return -1;
}
#ifdef DEBUG
for (i=0; i<sizeof(test_buffer); i++)
dev_dbg(&lan9252_devices->dev, "%s() test_buffer[%d] = 0x%x\n",
__FUNCTION__, i, test_buffer[i]);
for (i=0; i<sizeof(test_buffer); i++)
dev_dbg(&lan9252->dev, "%s() test_buffer[%d] = 0x%x\n",
__FUNCTION__, i, test_buffer[i]);
#endif
if (test_buffer[0]==0x21 && test_buffer[1]==0x43 &&
test_buffer[2]==0x65 && test_buffer[3]==0x87)
return 0;
else
return -1;
if (test_buffer[0]==0x21 && test_buffer[1]==0x43 &&
test_buffer[2]==0x65 && test_buffer[3]==0x87)
return 0;
else
return -1;
}
static ssize_t lan9252_read(
struct file *file, char *buffer,
size_t read_buffer_size, loff_t *f_pos)
static ssize_t lan9252_read(struct file *file, char *buffer,
size_t read_buffer_size, loff_t *f_pos)
{
u8 command[4];
u8 *read_buffer;
int status=0;
int *lan9252_reg_read_addr;
u8 command[4];
u8 *read_buffer;
int ret = 0;
int *lan9252_reg_read_addr;
#ifdef DEBUG
int i;
int i;
#endif
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__);
LAN9252_LOCK;
LAN9252_LOCK;
if (read_buffer_size <= 0) {
dev_err(&lan9252_devices->dev, "read_buffer_size(%d) <= 0 \n",
dev_err(&lan9252->dev, "read_buffer_size(%d) <= 0 \n",
read_buffer_size);
goto out;
} else {
dev_dbg(&lan9252_devices->dev, "read_buffer_size = %d\n",
read_buffer_size);
dev_dbg(&lan9252->dev, "read_buffer_size = %d\n",
read_buffer_size);
}
read_buffer= (u8 *)kmalloc((read_buffer_size) *
sizeof(u32), GFP_KERNEL | GFP_DMA);
read_buffer= (u8 *)kmalloc((read_buffer_size) * sizeof(u32),
GFP_KERNEL | GFP_DMA);
if (!read_buffer) {
dev_err(&lan9252_devices->dev, "read_buffer kmalloc error\n");
status = -ENOMEM;
dev_err(&lan9252->dev, "write read_buffer kmalloc error\n");
ret = -ENOMEM;
goto out;
}
}
memset(read_buffer, 0, (read_buffer_size) * sizeof(u8));
memset(read_buffer, 0, (read_buffer_size) * sizeof(u8));
lan9252_reg_read_addr = lan9252_reg_addr_make(file->f_pos);
command[0] = FAST_READ;
@ -188,94 +164,88 @@ static ssize_t lan9252_read(
#ifdef DEBUG
for (i=0; i<4; i++)
dev_dbg(&lan9252_devices->dev, "%s() command[%d] = 0x%x\n",
__FUNCTION__, i, command[i]);
dev_dbg(&lan9252->dev, "%s() command[%d] = 0x%x\n",
__FUNCTION__, i, command[i]);
#endif
status = spi_write_then_read(lan9252_devices, &command,
sizeof(command), read_buffer,read_buffer_size);
if (status < 0 ) {
dev_err(&lan9252_devices->dev, "%s() spi_write_then_read "
"failed status=%d\n", __FUNCTION__, status);
ret = spi_write_then_read(lan9252, &command, sizeof(command),
read_buffer,read_buffer_size);
if (ret < 0) {
dev_err(&lan9252->dev, "%s() spi_write_then_read failed "
"ret=%d\n", __FUNCTION__, ret);
goto kfree_read_buffer;
}
#ifdef DEBUG
for (i=0; i<read_buffer_size; i++)
dev_dbg(&lan9252_devices->dev, "%s() read_buffer[%d] = 0x%x\n",
__FUNCTION__, i, read_buffer[i]);
dev_dbg(&lan9252->dev, "%s() read_buffer[%d] = 0x%x\n",
__FUNCTION__, i, read_buffer[i]);
#endif
if (copy_to_user(buffer, read_buffer, read_buffer_size)) {
dev_err(&lan9252_devices->dev, "%s() copy_to_user failed\n",
__FUNCTION__);
status = -EFAULT;
dev_err(&lan9252->dev, "%s() copy_to_user failed\n",
__FUNCTION__);
ret = -EFAULT;
goto kfree_read_buffer;
}
status = read_buffer_size;
ret = read_buffer_size;
kfree_read_buffer:
kfree(read_buffer);
out:
LAN9252_UNLOCK;
return status;
return ret;
}
static ssize_t lan9252_write(
struct file *file, const char *command_buff,
size_t command_buff_size, loff_t *f_pos)
static ssize_t lan9252_write(struct file *file, const char *command_buff,
size_t command_buff_size, loff_t *f_pos)
{
u8 *command;
int status=0;
int ret = 0;
#ifdef DEBUG
int i;
#endif
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__);
LAN9252_LOCK;
if (command_buff_size <= 0) {
dev_err(&lan9252_devices->dev, "command_buff_size(%d) <= 0 \n",
dev_err(&lan9252->dev, "command_buff_size(%d) <= 0 \n",
command_buff_size);
goto out;
} else {
dev_dbg(&lan9252_devices->dev, "command_buff_size = %d\n",
command_buff_size);
dev_dbg(&lan9252->dev, "command_buff_size = %d\n",
command_buff_size);
}
command = (u8 *)kmalloc((command_buff_size) *
sizeof(u8), GFP_KERNEL | GFP_DMA);
command = (u8 *)kmalloc((command_buff_size) * sizeof(u8),
GFP_KERNEL | GFP_DMA);
if (!command) {
dev_err(&lan9252_devices->dev, "write command buffer kmalloc"
" error\n");
status = -ENOMEM;
dev_err(&lan9252->dev, "write command kmalloc error\n");
ret = -ENOMEM;
goto out;
}
memset(command, 0, (command_buff_size) * sizeof(u8));
if (copy_from_user(command, command_buff, command_buff_size)) {
dev_err(&lan9252_devices->dev, "%s() copy_from_user failed\n",
__FUNCTION__);
status = -EFAULT;
dev_err(&lan9252->dev, "%s() copy_from_user failed\n",
__FUNCTION__);
ret = -EFAULT;
goto kfree_command;
}
#ifdef DEBUG
for(i=0;i<command_buff_size;i++)
dev_dbg(&lan9252_devices->dev, "command[%d]=0x%x\n", i,
command[i]);
dev_dbg(&lan9252->dev, "command[%d]=0x%x\n",i,command[i]);
#endif
status = spi_write_then_read(lan9252_devices, command,
command_buff_size, NULL, 0);
if (status < 0 ) {
dev_err(&lan9252_devices->dev, "%s() spi_write_then_read "
"failed status=%d\n", __FUNCTION__, status);
ret = spi_write_then_read(lan9252, command,
command_buff_size, NULL, 0);
if (ret < 0) {
dev_err(&lan9252->dev, "%s() spi_write_then_read failed "
"ret=%d\n", __FUNCTION__, ret);
goto kfree_command;
}
@ -284,29 +254,30 @@ kfree_command:
out:
LAN9252_UNLOCK;
return status;
return ret;
}
static long lan9252_ioctl(struct file *file, unsigned int cmd,
unsigned long argument)
unsigned long argument)
{
int status;
int ret;
LAN9252_LOCK;
switch (cmd) {
case TEST:
status=lan9252_test();
break;
LAN9252_LOCK;
default:
status=0;
break;
}
switch (cmd) {
case TEST:
ret = lan9252_test();
break;
LAN9252_UNLOCK;
default:
ret = 0;
break;
}
return status;
LAN9252_UNLOCK;
return ret;
}
@ -317,13 +288,11 @@ static const struct spi_device_id lan9252_id_table[] = {
MODULE_DEVICE_TABLE(spi, lan9252_id_table);
static const struct file_operations lan9252_fops = {
.owner = THIS_MODULE,
.open = lan9252_open,
.release = lan9252_release,
.llseek = lan9252_llseek,
.write = lan9252_write,
.read = lan9252_read,
.unlocked_ioctl = lan9252_ioctl,
.owner = THIS_MODULE,
.llseek = lan9252_llseek,
.write = lan9252_write,
.read = lan9252_read,
.unlocked_ioctl = lan9252_ioctl,
};
static struct spi_driver lan9252_ethercat_driver = {
@ -335,80 +304,47 @@ static struct spi_driver lan9252_ethercat_driver = {
.remove = lan9252_ethercat_remove,
};
struct miscdevice lan9252_miscdev = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &lan9252_fops,
};
static int lan9252_ethercat_probe(struct spi_device *spi)
{
int status;
dev_dbg(&spi->dev, "%s() called\n", __FUNCTION__);
int ret;
mutex_init(&lock);
lan9252_devices = spi;
lan9252 = spi;
if(lan9252_test())
dev_warn(&lan9252_devices->dev, "lan9252 not connected\n");
if(lan9252_test())
dev_warn(&spi->dev, "lan9252 not connected\n");
if (register_chrdev(LAN9252_MAJOR,
lan9252_ethercat_driver.driver.name, &lan9252_fops)) {
dev_err(&lan9252_devices->dev, "unable to get major %d for "
, LAN9252_MAJOR);
status = -ENODEV;
goto register_chrdev_fail;
}
ret = misc_register(&lan9252_miscdev);
if (ret)
goto misc_register_fail;
lan9252_class = class_create(THIS_MODULE,
lan9252_ethercat_driver.driver.name);
if (IS_ERR(lan9252_class)) {
status = PTR_ERR(lan9252_class);
goto class_create_fail;
}
id = MKDEV(LAN9252_MAJOR, 0);
dev = device_create(lan9252_class, NULL, id, NULL,
lan9252_ethercat_driver.driver.name);
if (IS_ERR(dev)) {
status = PTR_ERR(dev);
dev_err(dev, "device_create error %d\n", status);
goto device_create_fail;
}
dev_dbg(&lan9252_devices->dev, "spi->max_speed_hz=%d"
" spi->bits_per_word=%d spi->mode=%d\n", spi->max_speed_hz,
spi->bits_per_word, spi->mode);
dev_dbg(&lan9252_devices->dev, "spi->chip_select=%d spi->cs_gpio=%d\n",
spi->chip_select, spi->cs_gpio);
dev_info(&lan9252_devices->dev, "Probed\n");
dev_info(&spi->dev, "Probed\n");
return 0;
device_create_fail:
class_destroy(lan9252_class);
misc_register_fail:
dev_err(&spi->dev, "Probed failed : %d\n", ret);
class_create_fail:
unregister_chrdev(LAN9252_MAJOR,
lan9252_ethercat_driver.driver.name);
register_chrdev_fail:
dev_err(&lan9252_devices->dev, "Probed failed : %d\n", status);
return status;
return ret;
}
static int lan9252_ethercat_remove(struct spi_device *spi)
{
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__);
misc_deregister(&lan9252_miscdev);
device_destroy(lan9252_class, id);
class_destroy(lan9252_class);
unregister_chrdev(LAN9252_MAJOR,
lan9252_ethercat_driver.driver.name);
dev_info(&spi->dev, "Removed\n");
dev_info(&lan9252_devices->dev, "Removed\n");
return 0;
}
module_spi_driver(lan9252_ethercat_driver);
MODULE_AUTHOR("tykwon@m2i.co.kr");
MODULE_DESCRIPTION("Microchip LAN9252 Ethercat Driver");
MODULE_LICENSE("GPL v2");
MODULE_LICENSE("GPL");

View File

@ -6,8 +6,8 @@ Required properties:
- reg: SPI chip select.
Example:
ethercat: lan9252@1 {
compatible = "lan9252";
spi-max-frequency = <20000000>;
reg = <1>;
};
ethercat: lan9252@1 {
compatible = "lan9252";
spi-max-frequency = <20000000>;
reg = <1>;
};

View File

@ -7,8 +7,13 @@ add_library (soes
esc_coe.h
esc_foe.c
esc_foe.h
esc_eoe.c
esc_eoe.h
esc_eep.c
esc_eep.h
ecat_slv.c
ecat_slv.h
options.h
${HAL_SOURCES}
)
@ -19,5 +24,6 @@ install (FILES
esc.h
esc_coe.h
esc_foe.h
esc_eoe.h
esc_eep.h
DESTINATION include)

View File

@ -1,74 +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 "config.h"
#include "slave.h"
#include "esc_eoe.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 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)
{
@ -78,16 +139,9 @@ void APP_safeoutput (void)
{
(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.
/** Write local process data to Sync Manager 3, Master Inputs.
*/
void TXPDO_update (void)
{
@ -97,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)
{
@ -111,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.
*/
@ -124,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))
{
@ -154,44 +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_LEDgroup0();
cb_set_LEDgroup1();
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)
{
@ -205,13 +247,13 @@ void DIG_process (uint8_t flags)
if(CC_ATOMIC_GET(ESCvar.App.state) > 0)
{
/* Update inputs */
cb_get_Buttons();
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
@ -229,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)
{
@ -246,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.
@ -277,9 +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)
@ -288,6 +334,9 @@ void ecat_slv_poll (void)
}
}
/*
* Poll all events in a free-run application
*/
void ecat_slv (void)
{
ecat_slv_poll();
@ -295,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;
@ -321,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,28 +1,29 @@
#ifndef __SLAVE_H__
#define __SLAVE_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.Buttons
* This function is called when to get input values
*/
void cb_get_Buttons();
void cb_get_inputs();
/**
* This function sets output values according to Wb.LEDgroup0
* This function is called when to set outputs values
*/
void cb_set_LEDgroup0();
void cb_set_outputs();
/**
* This function sets output values according to Wb.LEDgroup1
/** Set the watchdog count value
*
* @param[in] watchdogcnt = new watchdog count value
*/
void cb_set_LEDgroup1();
/**
* This function is called after a SDO write of the object Cb.variableRW.
*/
void cb_post_write_variableRW(int subindex);
void APP_setwatchdog (int watchdogcnt);
#define DIG_PROCESS_INPUTS_FLAG 0x01
#define DIG_PROCESS_OUTPUTS_FLAG 0x02
@ -47,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
@ -71,4 +66,4 @@ void ecat_slv (void);
*/
void ecat_slv_init (esc_cfg_t * config);
#endif /* __SLAVE_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
@ -86,15 +128,15 @@ uint32_t ESC_ALeventread (void)
return htoel(alevent);
}
/** Read SM Status register 0x805(+ offset to SyncManager n) to acknowledge a
/** Read SM Activate register 0x806(+ offset to SyncManager n) to acknowledge a
* Sync Manager event Bit 3 in ALevent. The result is not used.
*
* @param[in] n = Read Sync Manager no. n
*/
void ESC_SMack (uint8_t n)
{
uint16_t dummy;
ESC_read (ESCREG_SM0STATUS + (n << 3), &dummy, 2);
uint8_t dummy;
ESC_read ((uint16_t)(ESCREG_SM0ACTIVATE + (n << 3)), &dummy, 1);
}
/** Read SM Status register 0x805(+ offset to SyncManager n) and save the
@ -105,18 +147,8 @@ void ESC_SMack (uint8_t n)
void ESC_SMstatus (uint8_t n)
{
_ESCsm2 *sm;
uint16_t temp;
sm = (_ESCsm2 *) & ESCvar.SM[n];
ESC_read (ESCREG_SM0STATUS + (n << 3), &temp, 2);
#if defined(EC_LITTLE_ENDIAN)
sm->ActESC = temp >> 8;
sm->Status = temp;
#endif
#if defined(EC_BIG_ENDIAN)
sm->ActESC = temp;
sm->Status = temp >> 8;
#endif
sm = (_ESCsm2 *)&ESCvar.SM[n];
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).
@ -126,8 +158,19 @@ void ESC_SMstatus (uint8_t n)
void ESC_SMwritepdi (uint8_t n)
{
_ESCsm2 *sm;
sm = (_ESCsm2 *) & ESCvar.SM[n];
ESC_write (ESCREG_SM0PDI + (n << 3), &(sm->ActPDI), 1);
sm = (_ESCsm2 *)&ESCvar.SM[n];
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.
@ -137,9 +180,14 @@ void ESC_SMwritepdi (uint8_t n)
void ESC_SMenable (uint8_t n)
{
_ESCsm2 *sm;
sm = (_ESCsm2 *) & ESCvar.SM[n];
sm->ActPDI &= ~ESCREG_SMENABLE_BIT;
sm = (_ESCsm2 *)&ESCvar.SM[n];
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.
*
@ -148,9 +196,14 @@ void ESC_SMenable (uint8_t n)
void ESC_SMdisable (uint8_t n)
{
_ESCsm2 *sm;
sm = (_ESCsm2 *) & ESCvar.SM[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.
*
@ -218,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
@ -320,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);
@ -337,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;
@ -354,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];
@ -370,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;
@ -398,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.
@ -414,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);
@ -439,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);
@ -487,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;
@ -545,15 +569,15 @@ uint8_t ESC_mbxprocess (void)
return 0;
}
/* SM0/1 access or SMn change event */
if (ESCvar.ALevent & ESCREG_ALEVENT_SM_MASK)
/* SM0/1 access */
if (ESCvar.ALevent & (ESCREG_ALEVENT_SM0 | ESCREG_ALEVENT_SM1))
{
ESC_SMstatus (0);
ESC_SMstatus (1);
}
/* outmbx read by master */
if (ESCvar.mbxoutpost && ESCvar.SM[1].IntR)
if (ESCvar.mbxoutpost && (ESCvar.ALevent & ESCREG_ALEVENT_SM1))
{
ESC_ackmbxread ();
/* dispose old backup */
@ -601,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;
@ -616,6 +640,8 @@ uint8_t ESC_mbxprocess (void)
if (mbxhandle)
{
ESC_writembx (mbxhandle);
/* Refresh SM status */
ESC_SMstatus (1);
/* change state */
MBXcontrol[mbxhandle].state = MBXstate_outpost;
ESCvar.mbxoutpost = mbxhandle;
@ -686,17 +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 */
@ -719,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
@ -759,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);
}
}
}
@ -790,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);
}
}
@ -804,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;
@ -912,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.
*
@ -950,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)
@ -973,7 +1147,6 @@ void ESC_state (void)
{
/* get station address */
ESC_address ();
COE_initDefaultSyncMgrPara ();
an = ESC_startmbx (ac);
break;
}
@ -1031,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)
{
@ -1075,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:
@ -1088,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)
@ -1112,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.
@ -1123,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
@ -36,11 +43,13 @@
#define ESCREG_EEDATA 0x0508
#define ESCREG_SM0 0x0800
#define ESCREG_SM0STATUS (ESCREG_SM0 + 5)
#define ESCREG_SM0ACTIVATE (ESCREG_SM0 + 6)
#define ESCREG_SM0PDI (ESCREG_SM0 + 7)
#define ESCREG_SM1 (ESCREG_SM0 + 0x08)
#define ESCREG_SM2 (ESCREG_SM0 + 0x10)
#define ESCREG_SM3 (ESCREG_SM0 + 0x18)
#define ESCREG_LOCALTIME 0x0910
#define ESCREG_LOCALTIME_OFFSET 0x0920
#define ESCREG_SYNC_ACT 0x0981
#define ESCREG_SYNC_ACT_ACTIVATED 0x01
#define ESCREG_SYNC_SYNC0_EN 0x02
@ -52,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
@ -93,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
@ -100,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
@ -117,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
@ -135,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
@ -146,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
@ -193,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
@ -206,10 +285,19 @@
#define FOE_WAIT_FOR_FINAL_ACK 2
#define FOE_WAIT_FOR_DATA 3
#define EOE_RESULT_SUCCESS 0x0000
#define EOE_RESULT_UNSPECIFIED_ERROR 0x0001
#define EOE_RESULT_UNSUPPORTED_FRAME_TYPE 0x0002
#define EOE_RESULT_NO_IP_SUPPORT 0x0201
#define EOE_RESULT_NO_DHCP_SUPPORT 0x0202
#define EOE_RESULT_NO_FILTER_SUPPORT 0x0401
#define APPSTATE_IDLE 0x00
#define APPSTATE_INPUT 0x01
#define APPSTATE_OUTPUT 0x02
#define PREALLOC_BUFFER_SIZE (PREALLOC_FACTOR * MBXSIZE)
typedef struct sm_cfg
{
uint16_t cfg_sma;
@ -224,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
@ -331,36 +431,47 @@ typedef struct CC_PACKED
} _ESCsmCompact;
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct CC_PACKED
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;
@ -378,33 +489,28 @@ typedef struct CC_PACKED
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;
#if defined(EC_LITTLE_ENDIAN)
uint8_t r1:1;
uint8_t toggle:1;
uint8_t r2:6;
#endif
uint8_t toggle;
#if defined(EC_BIG_ENDIAN)
uint8_t r2:6;
uint8_t toggle:1;
uint8_t r1:1;
#endif
int sm2mappings;
int sm3mappings;
uint8_t SMtestresult;
int16_t temp;
uint32_t PrevTime;
_ESCsm SM[4];
/* 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_END
CC_PACKED_BEGIN
typedef struct CC_PACKED
@ -473,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;
@ -485,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;
@ -541,6 +647,28 @@ typedef struct CC_PACKED
};
} _FOE;
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct CC_PACKED
{
uint16_t frameinfo1;
union
{
uint16_t frameinfo2;
uint16_t result;
};
} _EOEh;
CC_PACKED_END
CC_PACKED_BEGIN
typedef struct CC_PACKED
{
_MBXh mbxheader;
_EOEh eoeheader;
uint8_t data[0];
} _EOE;
CC_PACKED_END
/* state definition in mailbox
* 0 : idle
* 1 : claimed for inbox
@ -565,18 +693,20 @@ 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 ((uint32_t)sizeof(_EOEh))
#define ESC_EOE_DATA_SIZE (ESC_MBXSIZE - (ESC_MBXHSIZE +ESC_EOEHSIZE))
void ESC_config (esc_cfg_t * cfg);
void ESC_ALerror (uint16_t errornumber);
@ -585,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);
@ -611,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);

1075
soes/esc_eoe.c 100644

File diff suppressed because it is too large Load Diff

68
soes/esc_eoe.h 100644
View File

@ -0,0 +1,68 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
/** \file
* \brief
* Headerfile for esc_eoe.c
*/
#ifndef __esc_eoe__
#define __esc_eoe__
#include <cc.h>
typedef struct eoe_pbuf
{
/** Pointer to frame buffer type used by a TCP/IP stack. (Not mandatory) */
void * pbuf;
/** Pointer to frame buffer to send or read from */
uint8_t * payload;
/** Length of data in frame buffer */
size_t len;
} eoe_pbuf_t;
typedef struct eoe_cfg
{
/** Callback function to get a frame buffer for storage of received frame */
void (*get_buffer) (eoe_pbuf_t * ebuf);
/** Callback function to free a frame buffer */
void (*free_buffer) (eoe_pbuf_t * ebuf);
/** Callback function to read local settings and update EtherCAT variables
* to be delivered to the EtherCAT Master
*/
int (*load_eth_settings) (void);
/** Callback function to read settings provided by the EtherCAT master
* and store to local settings.
*/
int (*store_ethernet_settings) (void);
/** Callback to frame receive function in TCP(IP stack,
* caller should free the buffer
* */
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[]);
int EOE_ecat_get_ip (uint8_t port, uint32_t * ip);
int EOE_ecat_get_subnet (uint8_t port, uint32_t * subnet);
int EOE_ecat_get_gateway (uint8_t port, uint32_t * default_gateway);
int EOE_ecat_get_dns_ip (uint8_t port, uint32_t * dns_ip);
int EOE_ecat_get_dns_name (uint8_t port, char * dns_name);
int EOE_ecat_set_mac (uint8_t port, uint8_t mac[]);
int EOE_ecat_set_ip (uint8_t port, uint32_t ip);
int EOE_ecat_set_subnet (uint8_t port, uint32_t subnet);
int EOE_ecat_set_gateway (uint8_t port, uint32_t default_gateway);
int EOE_ecat_set_dns_ip (uint8_t port, uint32_t dns_ip);
int EOE_ecat_set_dns_name (uint8_t port, char * dns_name);
void EOE_config (eoe_cfg_t * cfg);
void EOE_init (void);
void ESC_eoeprocess (void);
void ESC_eoeprocess_tx (void);
#endif

View File

@ -26,20 +26,16 @@
/** Variable holding current filename read at FOE Open.
*/
char foe_file_name[FOE_FN_MAX + 1];
static char foe_file_name[FOE_FN_MAX + 1];
/** Main FoE configuration pointer data array. Structure i allocated and filled
* by the application defining what preferences it require.
/** Main FoE configuration pointer data array. Structure is allocated and filled
* by the application defining what preferences it requires.
*/
static foe_cfg_t * foe_cfg;
/** Collection of files possible to receive by FoE. Structure i allocated and
* filled by the application defining what preferences it require.
*/
static foe_writefile_cfg_t * foe_files;
/** Pointer to current file configuration item used by FoE.
*/
static foe_writefile_cfg_t * foe_file;
static foe_file_cfg_t * foe_file;
/** Main FoE status data array. Structure gets filled with current status
* variables during FoE usage.
*/
@ -54,7 +50,7 @@ static _FOEvar FOEvar;
* @return 0= if we succeed, FOE_ERR_NOTFOUND something wrong with filename or
* password
*/
int FOE_fopen (char *name, uint8_t num_chars, uint32_t pass, uint8_t op)
static uint32_t FOE_fopen (char *name, uint8_t num_chars, uint32_t pass, uint8_t op)
{
uint32_t i;
@ -73,10 +69,21 @@ int FOE_fopen (char *name, uint8_t num_chars, uint32_t pass, uint8_t op)
/* Figure out what file they're talking about. */
for (i = 0; i < foe_cfg->n_files; i++)
{
if ((0 == strncmp (foe_file_name, foe_files[i].name, num_chars)) &&
(pass == foe_files[i].filepass))
if (0 == strncmp (foe_file_name, foe_cfg->files[i].name, num_chars))
{
foe_file = &foe_files[i];
if (pass != foe_cfg->files[i].filepass)
{
return FOE_ERR_NORIGHTS;
}
if (op == FOE_OP_WRQ &&
(foe_cfg->files[i].write_only_in_boot) &&
(ESCvar.ALstatus != ESCboot))
{
return FOE_ERR_NOTINBOOTSTRAP;
}
foe_file = &foe_cfg->files[i];
foe_file->address_offset = 0;
foe_file->total_size = 0;
switch (op)
@ -84,13 +91,13 @@ int FOE_fopen (char *name, uint8_t num_chars, uint32_t pass, uint8_t op)
case FOE_OP_RRQ:
{
FOEvar.fposition = 0;
FOEvar.fend = foe_files[i].max_data;
FOEvar.fend = foe_cfg->files[i].max_data;
return 0;
}
case FOE_OP_WRQ:
{
FOEvar.fposition = 0;
FOEvar.fend = foe_files[i].max_data;
FOEvar.fend = foe_cfg->files[i].max_data;
return 0;
}
}
@ -111,14 +118,14 @@ int FOE_fopen (char *name, uint8_t num_chars, uint32_t pass, uint8_t op)
* @return Number of copied bytes.
*/
uint16_t FOE_fread (uint8_t * data, uint16_t maxlength)
static uint32_t FOE_fread (uint8_t * data, uint32_t maxlength)
{
uint16_t ncopied = 0;
uint32_t ncopied = 0;
while (maxlength && (FOEvar.fend - FOEvar.fposition))
{
maxlength--;
*(data++) = fbuffer[FOEvar.fposition++];
*(data++) = foe_cfg->fbuffer[FOEvar.fposition++];
ncopied++;
}
@ -137,9 +144,9 @@ uint16_t FOE_fread (uint8_t * data, uint16_t maxlength)
* @return Number of copied bytes.
*/
uint16_t FOE_fwrite (uint8_t *data, uint16_t length)
static uint32_t FOE_fwrite (uint8_t *data, uint32_t length)
{
uint16_t ncopied = 0;
uint32_t ncopied = 0;
uint32_t failed = 0;
DPRINT("FOE_fwrite\n");
@ -150,17 +157,24 @@ uint16_t FOE_fwrite (uint8_t *data, uint16_t length)
foe_cfg->fbuffer[FOEvar.fbufposition++] = *(data++);
if(FOEvar.fbufposition >= foe_cfg->buffer_size)
{
failed = foe_file->write_function (foe_file, foe_cfg->fbuffer);
failed = foe_file->write_function (foe_file, foe_cfg->fbuffer, FOEvar.fbufposition);
FOEvar.fbufposition = 0;
foe_file->address_offset += foe_cfg->buffer_size;
}
FOEvar.fposition++;
ncopied++;
if(failed)
{
DPRINT("Failed FOE_fwrite ncopied=%"PRIu32"\n", ncopied);
}
else
{
ncopied++;
}
}
foe_file->total_size += ncopied;
DPRINT("FOE_fwrite END with : %d\n",ncopied);
DPRINT("FOE_fwrite END with : %"PRIu32"\n",ncopied);
return ncopied;
}
@ -170,25 +184,16 @@ uint16_t FOE_fwrite (uint8_t *data, uint16_t length)
*
* @return Number of copied bytes on success, 0= if failed.
*/
uint32_t FOE_fclose (void)
static uint32_t FOE_fclose (void)
{
uint32_t i;
uint32_t failed = 0;
DPRINT("FOE_fclose\n");
if (FOEvar.fbufposition)
{
failed = foe_file->write_function (foe_file, foe_cfg->fbuffer, FOEvar.fbufposition);
foe_file->address_offset += FOEvar.fbufposition;
FOEvar.fbufposition = 0;
DPRINT("FOE_fclose EXTRA write\n");
for(i = FOEvar.fbufposition; i < foe_cfg->buffer_size; i++)
{
foe_cfg->fbuffer[FOEvar.fbufposition++] = foe_cfg->empty_write;
}
failed = foe_file->write_function (foe_file, foe_cfg->fbuffer);
FOEvar.fbufposition = 0;
foe_file->address_offset += foe_cfg->buffer_size;
DPRINT("FOE_fclose EXTRA write ended\n");
}
return failed;
}
@ -209,7 +214,7 @@ void FOE_init ()
*
* @param[in] code = abort code
*/
void FOE_abort (uint32_t code)
static void FOE_abort (uint32_t code)
{
_FOE *foembx;
uint8_t mbxhandle;
@ -229,7 +234,7 @@ void FOE_abort (uint32_t code)
}
/* Nothing we can do if we can't get an outbound mailbox. */
}
DPRINT("FOE_abort: 0x%X\n", code);
DPRINT("FOE_abort: 0x%"PRIX32"\n", code);
FOE_init ();
}
@ -244,21 +249,21 @@ void FOE_abort (uint32_t code)
* @return Number of data bytes written or an error number. Error numbers
* will be greater than FOE_DATA_SIZE.
*/
int FOE_send_data_packet ()
static uint32_t FOE_send_data_packet ()
{
_FOE *foembx;
uint16_t data_len;
uint32_t data_len;
uint8_t mbxhandle;
mbxhandle = ESC_claimbuffer ();
if (mbxhandle)
{
foembx = (_FOE *) &MBX[mbxhandle * ESC_MBXSIZE];
data_len = FOE_fread (foembx->data, FOE_DATA_SIZE);
data_len = FOE_fread (foembx->data, ESC_FOE_DATA_SIZE);
foembx->foeheader.opcode = FOE_OP_DATA;
foembx->foeheader.packetnumber = htoel (FOEvar.foepacket);
FOEvar.foepacket++;
foembx->mbxheader.length = htoes (data_len + FOEHSIZE);
foembx->mbxheader.length = htoes (data_len + ESC_FOEHSIZE);
foembx->mbxheader.mbxtype = MBXFOE;
/* Mark the outbound mailbox as filled. */
MBXcontrol[mbxhandle].state = MBXstate_outreq;
@ -275,7 +280,7 @@ int FOE_send_data_packet ()
* @return 0= or error number.
*/
int FOE_send_ack ()
static uint32_t FOE_send_ack ()
{
_FOE *foembx;
uint8_t mbxhandle;
@ -308,12 +313,12 @@ int FOE_send_ack ()
* On error we will send FOE Abort.
*
*/
void FOE_read ()
static void FOE_read ()
{
_FOE *foembx;
uint32_t data_len;
uint32_t password;
int res;
uint32_t res;
uint8_t data_len;
if (FOEvar.foestate != FOE_READY)
{
@ -324,7 +329,7 @@ void FOE_read ()
FOE_init ();
foembx = (_FOE *) &MBX[0];
/* Get the length of the file name in octets. */
data_len = etohs (foembx->mbxheader.length) - FOEHSIZE;
data_len = (uint8_t)(etohs (foembx->mbxheader.length) - ESC_FOEHSIZE);
password = etohl (foembx->foeheader.password);
res = FOE_fopen (foembx->filename, data_len, password, FOE_OP_RRQ);
@ -335,7 +340,7 @@ void FOE_read ()
* Attempt to send the packet
*/
res = FOE_send_data_packet ();
if (res <= (int)FOE_DATA_SIZE)
if (res <= ESC_FOE_DATA_SIZE)
{
FOEvar.foestate = FOE_WAIT_FOR_ACK;
}
@ -349,20 +354,13 @@ void FOE_read ()
FOE_abort (res);
}
}
#else
void FOE_read()
{
FOE_abort(FOE_ERR_NOTDEFINED);
}
#endif
#ifdef FOE_READ_SUPPORTED
/** FoE data ack handler. Will continue sending next frame until finished.
* On error we will send FOE Abort.
*/
void FOE_ack ()
static void FOE_ack ()
{
int res;
uint32_t res;
/* Make sure we're able to take this. */
if (FOEvar.foestate == FOE_WAIT_FOR_FINAL_ACK)
@ -377,7 +375,7 @@ void FOE_ack ()
return;
}
res = FOE_send_data_packet ();
if (res < (int) FOE_DATA_SIZE)
if (res < ESC_FOE_DATA_SIZE)
{
FOEvar.foestate = FOE_WAIT_FOR_FINAL_ACK;
}
@ -392,12 +390,12 @@ void FOE_ack ()
* receive data. On error we will send FOE Abort.
*
*/
void FOE_write ()
static void FOE_write ()
{
_FOE *foembx;
uint32_t data_len;
uint32_t password;
int res;
uint32_t res;
uint8_t data_len;
if (FOEvar.foestate != FOE_READY)
{
@ -407,12 +405,12 @@ void FOE_write ()
FOE_init ();
foembx = (_FOE *) &MBX[0];
data_len = etohs (foembx->mbxheader.length) - ESC_FOEHSIZE;
data_len = (uint8_t)(etohs (foembx->mbxheader.length) - ESC_FOEHSIZE);
password = etohl (foembx->foeheader.password);
/* Get an address we can write the file to, if possible. */
res = FOE_fopen (foembx->filename, data_len, password, FOE_OP_WRQ);
DPRINT("FOE_write\n");
DPRINT("%s %sOK, file \"%s\"\n", __func__, (res == 0) ? "" : "N", foe_file_name);
if (res == 0)
{
res = FOE_send_ack ();
@ -430,16 +428,16 @@ void FOE_write ()
FOE_abort (res);
}
}
/** FoE data request handler. Validates and reads data until we're finsihed. Every
* read frame follwed by an Ack frame. On error we will send FOE Abort.
/** FoE data request handler. Validates and reads data until we're finished. Every
* read frame followed by an Ack frame. On error we will send FOE Abort.
*
*/
void FOE_data ()
static void FOE_data ()
{
_FOE *foembx;
uint32_t packet;
uint16_t data_len, ncopied;
int res;
uint32_t data_len, ncopied;
uint32_t res;
if(FOEvar.foestate != FOE_WAIT_FOR_DATA)
{
@ -453,7 +451,9 @@ void FOE_data ()
if (packet != FOEvar.foepacket)
{
DPRINT("FOE_data packet error,packet: %d foeheader.packet: %d\n",packet,FOEvar.foepacket);
DPRINT("FOE_data packet error, packet: %"PRIu32", foeheader.packet: %"PRIu32"\n",
packet,
FOEvar.foepacket);
FOE_abort (FOE_ERR_PACKETNO);
}
else if (data_len == 0)
@ -481,7 +481,7 @@ void FOE_data ()
DPRINT("FOE_data data_len == FOE_DATA_SIZE\n");
if (ncopied != data_len)
{
DPRINT("FOE_data only %d of %d copied\n",ncopied, data_len);
DPRINT("FOE_data only %"PRIu32" of %"PRIu32" copied\n",ncopied, data_len);
FOE_abort (FOE_ERR_PROGERROR);
}
res = FOE_send_ack ();
@ -508,11 +508,11 @@ void FOE_data ()
}
#ifdef FOE_READ_SUPPORTED
/** FoE read request buys handler. Send an Ack of last frame again. On error
/** FoE read request busy handler. Send an Ack of last frame again. On error
* we will send FOE Abort.
*
*/
void FOE_busy ()
static void FOE_busy ()
{
/* Only valid if we're servicing a read request. */
if (FOEvar.foestate != FOE_WAIT_FOR_ACK)
@ -532,7 +532,7 @@ void FOE_busy ()
/** FoE error requesthandler. Send an FOE Abort.
*
*/
void FOE_error ()
static void FOE_error ()
{
/* Master panic! abort the transfer. */
FOE_abort (0);
@ -543,14 +543,10 @@ void FOE_error ()
*
* @param[in] cfg = Pointer to by the Application static declared
* configuration variable holding application specific details.
* @param[in] cfg_files = Pointer to by the Application static declared
* configuration variable holding file specific details for files to be handled
* by FoE
*/
void FOE_config (foe_cfg_t * cfg, foe_writefile_cfg_t * cfg_files)
void FOE_config (foe_cfg_t * cfg)
{
foe_cfg = cfg;
foe_files = cfg_files;
}
/** Main FoE function checking the status on current mailbox buffers carrying

View File

@ -14,10 +14,10 @@
#include <cc.h>
/** Maximum number of characters allowed in a file name. */
#define FOE_FN_MAX 15
#define FOE_FN_MAX 31
typedef struct foe_writefile_cfg foe_writefile_cfg_t;
struct foe_writefile_cfg
typedef struct foe_file_cfg foe_file_cfg_t;
struct foe_file_cfg
{
/** Name of file to receive from master */
const char * name;
@ -31,22 +31,24 @@ struct foe_writefile_cfg
uint32_t total_size;
/** FoE password */
uint32_t filepass;
/** This file can be written only in BOOT state. Intended for FW files */
uint8_t write_only_in_boot;
/** for feature use */
uint32_t padding:24;
/** Pointer to application foe write function */
uint32_t (*write_function) (foe_writefile_cfg_t * self, uint8_t * data);
uint32_t (*write_function) (foe_file_cfg_t * self, uint8_t * data, size_t length);
};
typedef struct foe_cfg
{
/** Allocate static in caller func to fit buffer_size */
uint8_t * fbuffer;
/** Write this to fill-up, ex. 0xFF for "non write" */
uint8_t empty_write;
/** Buffer size before we flush to destination */
uint32_t buffer_size;
/** Number of files used in firmware update */
uint32_t n_files;
/** Pointer to files configured to be used by FoE */
foe_writefile_cfg_t * files;
foe_file_cfg_t * files;
} foe_cfg_t;
typedef struct CC_PACKED
@ -68,7 +70,7 @@ typedef struct CC_PACKED
} _FOEvar;
/* Initializes FoE state. */
void FOE_config (foe_cfg_t * cfg, foe_writefile_cfg_t * cfg_files);
void FOE_config (foe_cfg_t * cfg);
void FOE_init (void);
void ESC_foeprocess (void);

View File

@ -16,7 +16,7 @@
#include <stdlib.h>
#include <unistd.h>
#define BIT(x) 1 << (x)
#define BIT(x) (1U << (x))
#define ESC_CMD_SERIAL_WRITE 0x02
#define ESC_CMD_SERIAL_READ 0x03
@ -59,15 +59,15 @@ static int lan9252 = -1;
static void lan9252_write_32 (uint16_t address, uint32_t val)
{
uint8_t data[7];
int n;
ssize_t n;
data[0] = ESC_CMD_SERIAL_WRITE;
data[1] = ((address >> 8) & 0xFF);
data[2] = (address & 0xFF);
data[3] = (val & 0xFF);
data[4] = ((val >> 8) & 0xFF);
data[5] = ((val >> 16) & 0xFF);
data[6] = ((val >> 24) & 0xFF);
data[1] = (uint8_t)((address >> 8) & 0xFF);
data[2] = (uint8_t)(address & 0xFF);
data[3] = (uint8_t)(val & 0xFF);
data[4] = (uint8_t)((val >> 8) & 0xFF);
data[5] = (uint8_t)((val >> 16) & 0xFF);
data[6] = (uint8_t)((val >> 24) & 0xFF);
/* Write data */
n = write (lan9252, data, sizeof(data));
@ -80,17 +80,17 @@ static uint32_t lan9252_read_32 (uint32_t address)
uint8_t data[2];
uint8_t result[4];
uint16_t lseek_addr;
int n;
ssize_t n;
data[0] = ((address >>8) & 0xFF);
data[1] = (address & 0xFF);
lseek_addr=((uint16_t)data[0] << 8) | data[1];
lseek (lan9252, lseek_addr, SEEK_SET);
lseek_addr=(uint16_t)((data[0] << 8) | data[1]);
lseek (lan9252, lseek_addr, SEEK_SET);
n = read (lan9252, result, sizeof(result));
(void)n;
return ((result[3] << 24) |
return (uint32_t)((result[3] << 24) |
(result[2] << 16) |
(result[1] << 8) |
result[0]);
@ -101,7 +101,9 @@ static void ESC_read_csr (uint16_t address, void *buf, uint16_t len)
{
uint32_t value;
value = (ESC_CSR_CMD_READ | ESC_CSR_CMD_SIZE(len) | address);
value = ESC_CSR_CMD_READ;
value |= (uint32_t)ESC_CSR_CMD_SIZE(len);
value |= address;
lan9252_write_32(ESC_CSR_CMD_REG, value);
do
@ -120,7 +122,9 @@ static void ESC_write_csr (uint16_t address, void *buf, uint16_t len)
memcpy((uint8_t*)&value, buf,len);
lan9252_write_32(ESC_CSR_DATA_REG, value);
value = (ESC_CSR_CMD_WRITE | ESC_CSR_CMD_SIZE(len) | address);
value = ESC_CSR_CMD_WRITE;
value |= (uint32_t)ESC_CSR_CMD_SIZE(len);
value |= address;
lan9252_write_32(ESC_CSR_CMD_REG, value);
do
@ -137,10 +141,10 @@ static void ESC_read_pram (uint16_t address, void *buf, uint16_t len)
uint16_t byte_offset = 0;
uint8_t fifo_cnt, first_byte_position, temp_len;
uint8_t *buffer;
int i, array_size, size;
size_t i, array_size, size;
float quotient,remainder;
uint32_t temp;
int n;
ssize_t n;
value = ESC_PRAM_CMD_ABORT;
lan9252_write_32(ESC_PRAM_RD_CMD_REG, value);
@ -150,7 +154,7 @@ static void ESC_read_pram (uint16_t address, void *buf, uint16_t len)
value = lan9252_read_32(ESC_PRAM_RD_CMD_REG);
}while(value & ESC_PRAM_CMD_BUSY);
value = ESC_PRAM_SIZE(len) | ESC_PRAM_ADDR(address);
value = (uint32_t)(ESC_PRAM_SIZE(len) | ESC_PRAM_ADDR(address));
lan9252_write_32(ESC_PRAM_RD_ADDR_LEN_REG, value);
value = ESC_PRAM_CMD_BUSY;
@ -162,7 +166,7 @@ static void ESC_read_pram (uint16_t address, void *buf, uint16_t len)
}while((value & ESC_PRAM_CMD_AVAIL) == 0);
/* Fifo count */
fifo_cnt = ESC_PRAM_CMD_CNT(value);
fifo_cnt = (uint8_t)ESC_PRAM_CMD_CNT(value);
/* Read first value from FIFO */
value = lan9252_read_32(ESC_PRAM_RD_FIFO_REG);
@ -172,27 +176,27 @@ static void ESC_read_pram (uint16_t address, void *buf, uint16_t len)
* according to LAN9252 datasheet and MicroChip SDK code
*/
first_byte_position = (address & 0x03);
temp_len = ((4 - first_byte_position) > len) ? len : (4 - first_byte_position);
temp_len = ((4 - first_byte_position) > len) ? (uint8_t)len : (uint8_t)(4 - first_byte_position);
memcpy(temp_buf ,((uint8_t *)&value + first_byte_position), temp_len);
len -= temp_len;
byte_offset += temp_len;
len = (uint16_t)(len - temp_len);
byte_offset = (uint16_t)(byte_offset + temp_len);
/* Continue reading until we have read len */
if (len > 0){
quotient = len/4;
remainder = len%4;
quotient = (float)(len/4);
remainder = (float)(len%4);
if (remainder == 0)
array_size = quotient;
array_size = (size_t)quotient;
else
array_size = quotient+1;
array_size = (size_t)quotient+1;
size = 4*array_size;
buffer = (uint8_t *)malloc(size);
buffer[0] = size;
buffer[0] = (uint8_t)size;
memset(buffer,0,size);
lseek (lan9252, ESC_PRAM_RD_FIFO_REG, SEEK_SET);
@ -203,13 +207,13 @@ static void ESC_read_pram (uint16_t address, void *buf, uint16_t len)
{
for (i=0; i<size; i=i+4) {
temp_len = (len > 4) ? 4: len;
temp_len = (len > 4) ? 4: (uint8_t)len;
temp = buffer[i] | (buffer[i+1] << 8) | (buffer[i+2] << 16) | (buffer[i+3] << 24);
temp = (uint32_t)(buffer[i] | (buffer[i+1] << 8) | (buffer[i+2] << 16) | (buffer[i+3] << 24));
memcpy(temp_buf + byte_offset ,&temp, temp_len);
fifo_cnt--;
len -= temp_len;
byte_offset += temp_len;
len = (uint16_t)(len - temp_len);
byte_offset = (uint16_t)(byte_offset + temp_len);
}
}
free(buffer);
@ -224,9 +228,9 @@ static void ESC_write_pram (uint16_t address, void *buf, uint16_t len)
uint16_t byte_offset = 0;
uint8_t fifo_cnt, first_byte_position, temp_len;
uint8_t *buffer;
int i, array_size, size;
size_t i, array_size, size;
float quotient,remainder;
int n;
ssize_t n;
value = ESC_PRAM_CMD_ABORT;
lan9252_write_32(ESC_PRAM_WR_CMD_REG, value);
@ -236,7 +240,7 @@ static void ESC_write_pram (uint16_t address, void *buf, uint16_t len)
value = lan9252_read_32(ESC_PRAM_WR_CMD_REG);
}while(value & ESC_PRAM_CMD_BUSY);
value = ESC_PRAM_SIZE(len) | ESC_PRAM_ADDR(address);
value = (uint32_t)(ESC_PRAM_SIZE(len) | ESC_PRAM_ADDR(address));
lan9252_write_32(ESC_PRAM_WR_ADDR_LEN_REG, value);
value = ESC_PRAM_CMD_BUSY;
@ -248,37 +252,37 @@ static void ESC_write_pram (uint16_t address, void *buf, uint16_t len)
}while((value & ESC_PRAM_CMD_AVAIL) == 0);
/* Fifo count */
fifo_cnt = ESC_PRAM_CMD_CNT(value);
fifo_cnt = (uint8_t)ESC_PRAM_CMD_CNT(value);
/* Find out first byte position and adjust the copy from that
* according to LAN9252 datasheet
*/
first_byte_position = (address & 0x03);
temp_len = ((4 - first_byte_position) > len) ? len : (4 - first_byte_position);
temp_len = ((4 - first_byte_position) > len) ? (uint8_t)len : (uint8_t)(4 - first_byte_position);
memcpy(((uint8_t *)&value + first_byte_position), temp_buf, temp_len);
/* Write first value from FIFO */
lan9252_write_32(ESC_PRAM_WR_FIFO_REG, value);
len -= temp_len;
byte_offset += temp_len;
len = (uint16_t)(len - temp_len);
byte_offset = (uint16_t)(byte_offset + temp_len);
fifo_cnt--;
if (len > 0){
quotient = len/4;
remainder = len%4;
remainder = (float)(len%4);
if (remainder == 0)
array_size = quotient;
array_size = (size_t)quotient;
else
array_size = quotient+1;
array_size = (size_t)quotient+1;
size = 3+4*array_size;
buffer = (uint8_t *)malloc(size);
buffer[0] = size;
buffer[0] = (uint8_t)size;
memset(buffer,0,size);
buffer[0] = ESC_CMD_SERIAL_WRITE;
@ -287,17 +291,17 @@ static void ESC_write_pram (uint16_t address, void *buf, uint16_t len)
while(len > 0)
{
for (i=3; i<size; i=i+4) {
temp_len = (len > 4) ? 4 : len;
temp_len = (len > 4) ? 4 : (uint8_t)len;
memcpy((uint8_t *)&value, (temp_buf + byte_offset), temp_len);
buffer[i] = (value & 0xFF);
buffer[i+1] = ((value >> 8) & 0xFF);
buffer[i+2] = ((value >> 16) & 0xFF);
buffer[i+3] = ((value >> 24) & 0xFF);
buffer[i] = (uint8_t)(value & 0xFF);
buffer[i+1] = (uint8_t)((value >> 8) & 0xFF);
buffer[i+2] = (uint8_t)((value >> 16) & 0xFF);
buffer[i+3] = (uint8_t)((value >> 24) & 0xFF);
fifo_cnt--;
len -= temp_len;
byte_offset += temp_len;
len = (uint16_t)(len - temp_len);
byte_offset= (uint16_t)(byte_offset + temp_len);
}
}
n = write (lan9252, buffer, size);
@ -351,9 +355,9 @@ void ESC_read (uint16_t address, void *buf, uint16_t len)
ESC_read_csr(address, temp_buf, size);
/* next address */
len -= size;
temp_buf += size;
address += size;
len = (uint16_t)(len - size);
temp_buf = (uint8_t *)(temp_buf + size);
address = (uint16_t)(address + size);
}
}
/* To mimic the ET1100 always providing AlEvent on every read or write */
@ -406,9 +410,9 @@ void ESC_write (uint16_t address, void *buf, uint16_t len)
ESC_write_csr(address, temp_buf, size);
/* next address */
len -= size;
temp_buf += size;
address += size;
len = (uint16_t)(len - size);
temp_buf = (uint8_t *)(temp_buf + size);
address = (uint16_t)(address + size);
}
}

View File

@ -0,0 +1,602 @@
/*
* 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 for LAN9252 through BCM2835 SPI on Raspberry PI.
*
* Function to read and write commands to the ESC. Used to read/write ESC
* registers and memory.
*/
#include "esc.h"
#include "esc_hw.h"
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <bcm2835.h>
#define BIT(x) (1U << (x))
#define ESC_CMD_SERIAL_WRITE 0x02
#define ESC_CMD_SERIAL_READ 0x03
#define ESC_CMD_RESET_CTL 0x01F8 // reset register
#define ESC_CMD_HW_CFG 0x0074 // hardware configuration register
#define ESC_CMD_BYTE_TEST 0x0064 // byte order test register
#define ESC_CMD_ID_REV 0x0050 // chip ID and revision
#define ESC_CMD_IRQ_CFG 0x0054 // interrupt configuration
#define ESC_CMD_INT_EN 0x005C // interrupt enable
#define ESC_RESET_DIGITAL 0x00000001
#define ESC_RESET_ETHERCAT 0x00000040
#define ESC_RESET_CTRL_RST (ESC_RESET_DIGITAL & ESC_RESET_ETHERCAT)
#define ESC_HW_CFG_READY 0x08000000
#define ESC_BYTE_TEST_OK 0x87654321
#define ESC_PRAM_RD_FIFO_REG 0x0000
#define ESC_PRAM_WR_FIFO_REG 0x0020
#define ESC_PRAM_RD_ADDR_LEN_REG 0x0308
#define ESC_PRAM_RD_CMD_REG 0x030C
#define ESC_PRAM_WR_ADDR_LEN_REG 0x0310
#define ESC_PRAM_WR_CMD_REG 0x0314
#define ESC_PRAM_CMD_BUSY 0x80000000
#define ESC_PRAM_CMD_ABORT 0x40000000
#define ESC_PRAM_CMD_AVAIL 0x00000001
#define ESC_PRAM_CMD_CNT(x) (((x) >> 8) & 0x1F)
#define ESC_PRAM_SIZE(x) ((x) << 16)
#define ESC_PRAM_ADDR(x) ((x) << 0)
#define ESC_CSR_DATA_REG 0x0300
#define ESC_CSR_CMD_REG 0x0304
#define ESC_CSR_CMD_BUSY 0x80000000
#define ESC_CSR_CMD_READ (0x80000000 | 0x40000000)
#define ESC_CSR_CMD_WRITE 0x80000000
#define ESC_CSR_CMD_SIZE(x) ((x) << 16)
/* bcm2835 spi single write */
static void bcm2835_spi_write_32 (uint16_t address, uint32_t val)
{
char data[7];
data[0] = ESC_CMD_SERIAL_WRITE;
data[1] = ((address >> 8) & 0xFF);
data[2] = (address & 0xFF);
data[3] = (val & 0xFF);
data[4] = ((val >> 8) & 0xFF);
data[5] = ((val >> 16) & 0xFF);
data[6] = ((val >> 24) & 0xFF);
/* Write data */
bcm2835_spi_transfern(data, 7);
}
/* bcm2835 spi single read */
static uint32_t bcm2835_spi_read_32 (uint16_t address)
{
char data[7];
data[0] = ESC_CMD_SERIAL_READ;
data[1] = ((address >> 8) & 0xFF);
data[2] = (address & 0xFF);
/* Read data */
bcm2835_spi_transfern(data, 7);
return ((data[6] << 24) |
(data[5] << 16) |
(data[4] << 8) |
data[3]);
}
/* ESC read CSR function */
static void ESC_read_csr (uint16_t address, void *buf, uint16_t len)
{
uint32_t value;
value = (ESC_CSR_CMD_READ | ESC_CSR_CMD_SIZE(len) | address);
bcm2835_spi_write_32(ESC_CSR_CMD_REG, value);
do
{
value = bcm2835_spi_read_32(ESC_CSR_CMD_REG);
} while(value & ESC_CSR_CMD_BUSY);
value = bcm2835_spi_read_32(ESC_CSR_DATA_REG);
memcpy(buf, (uint8_t *)&value, len);
}
/* ESC write CSR function */
static void ESC_write_csr (uint16_t address, void *buf, uint16_t len)
{
uint32_t value;
memcpy((uint8_t*)&value, buf,len);
bcm2835_spi_write_32(ESC_CSR_DATA_REG, value);
value = (ESC_CSR_CMD_WRITE | ESC_CSR_CMD_SIZE(len) | address);
bcm2835_spi_write_32(ESC_CSR_CMD_REG, value);
do
{
value = bcm2835_spi_read_32(ESC_CSR_CMD_REG);
} while(value & ESC_CSR_CMD_BUSY);
}
/* ESC read process data ram function */
static void ESC_read_pram (uint16_t address, void *buf, uint16_t len)
{
uint32_t value;
uint8_t * temp_buf = buf;
uint16_t quotient, remainder, byte_offset = 0;
uint8_t fifo_cnt, fifo_size, fifo_range, first_byte_position, temp_len;
uint8_t *buffer = NULL;
int i, size;
bcm2835_spi_write_32(ESC_PRAM_RD_CMD_REG, ESC_PRAM_CMD_ABORT);
do
{
value = bcm2835_spi_read_32(ESC_PRAM_RD_CMD_REG);
}while(value & ESC_PRAM_CMD_BUSY);
bcm2835_spi_write_32(ESC_PRAM_RD_ADDR_LEN_REG, (ESC_PRAM_SIZE(len) | ESC_PRAM_ADDR(address)));
bcm2835_spi_write_32(ESC_PRAM_RD_CMD_REG, ESC_PRAM_CMD_BUSY);
/* Find out first byte position and adjust the copy from that
* according to LAN9252 datasheet and MicroChip SDK code
*/
first_byte_position = (address & 0x03);
/* Transfer data */
while (len > 0)
{
/* Wait for read availabiliy */
if (byte_offset > 0)
{
quotient = len/4;
remainder = len - quotient*4;
}
else
{
quotient = (len + first_byte_position)/4;
remainder = (len + first_byte_position) - quotient*4;
}
if (remainder != 0)
{
quotient++;
}
fifo_range = MIN(quotient,16);
do
{
value = bcm2835_spi_read_32(ESC_PRAM_RD_CMD_REG);
}while(!(value & ESC_PRAM_CMD_AVAIL) || (ESC_PRAM_CMD_CNT(value) < fifo_range));
/* Fifo size */
fifo_size = ESC_PRAM_CMD_CNT(value);
/* Transfer data size */
size = 3+4*fifo_size;
/* Allocate buffer */
buffer = (uint8_t *)realloc(buffer, size);
/* Reset fifo count */
fifo_cnt = fifo_size;
/* Reset buffer */
memset(buffer,0,size);
buffer[0] = ESC_CMD_SERIAL_READ;
buffer[1] = ((ESC_PRAM_RD_FIFO_REG >>8) & 0xFF);
buffer[2] = ( ESC_PRAM_RD_FIFO_REG & 0xFF);
/* Transfer batch of data */
bcm2835_spi_transfern((char *)buffer, size);
i = 3;
while (fifo_cnt > 0 && len > 0)
{
value = buffer[i] | (buffer[i+1] << 8) | (buffer[i+2] << 16) | (buffer[i+3] << 24);
if (byte_offset > 0)
{
temp_len = (len > 4) ? 4: len;
memcpy(temp_buf + byte_offset ,&value, temp_len);
}
else
{
temp_len = (len > (4 - first_byte_position)) ? (4 - first_byte_position) : len;
memcpy(temp_buf ,((uint8_t *)&value + first_byte_position), temp_len);
}
i += 4;
fifo_cnt--;
len -= temp_len;
byte_offset += temp_len;
}
}
free(buffer);
}
/* ESC write process data ram function */
static void ESC_write_pram (uint16_t address, void *buf, uint16_t len)
{
uint32_t value;
uint8_t * temp_buf = buf;
uint16_t quotient, remainder, byte_offset = 0;
uint8_t fifo_cnt, fifo_size, fifo_range, first_byte_position, temp_len;
uint8_t *buffer = NULL;
int i, size;
bcm2835_spi_write_32(ESC_PRAM_WR_CMD_REG, ESC_PRAM_CMD_ABORT);
do
{
value = bcm2835_spi_read_32(ESC_PRAM_WR_CMD_REG);
}while(value & ESC_PRAM_CMD_BUSY);
bcm2835_spi_write_32(ESC_PRAM_WR_ADDR_LEN_REG, (ESC_PRAM_SIZE(len) | ESC_PRAM_ADDR(address)));
bcm2835_spi_write_32(ESC_PRAM_WR_CMD_REG, ESC_PRAM_CMD_BUSY);
/* Find out first byte position and adjust the copy from that
* according to LAN9252 datasheet and MicroChip SDK code
*/
first_byte_position = (address & 0x03);
/* Transfer data */
while (len > 0)
{
/* Wait for write availabiliy */
if (byte_offset > 0)
{
quotient = len/4;
remainder = len - quotient*4;
}
else
{
quotient = (len + first_byte_position)/4;
remainder = (len + first_byte_position) - quotient*4;
}
if (remainder != 0)
{
quotient++;
}
fifo_range = MIN(quotient,16);
do
{
value = bcm2835_spi_read_32(ESC_PRAM_WR_CMD_REG);
}while(!(value & ESC_PRAM_CMD_AVAIL) || (ESC_PRAM_CMD_CNT(value) < fifo_range));
/* Fifo size */
fifo_size = ESC_PRAM_CMD_CNT(value);
/* Transfer data size */
size = 3+4*fifo_size;
/* Allocate buffer */
buffer = (uint8_t *)realloc(buffer, size);
/* Reset fifo count */
fifo_cnt = fifo_size;
/* Reset buffer */
memset(buffer,0,size);
buffer[0] = ESC_CMD_SERIAL_WRITE;
buffer[1] = ((ESC_PRAM_WR_FIFO_REG >> 8) & 0xFF);
buffer[2] = (ESC_PRAM_WR_FIFO_REG & 0xFF);
i = 3;
while (fifo_cnt > 0 && len > 0)
{
value = 0;
if (byte_offset > 0)
{
temp_len = (len > 4) ? 4: len;
memcpy(&value, (temp_buf + byte_offset), temp_len);
}
else
{
temp_len = (len > (4 - first_byte_position)) ? (4 - first_byte_position) : len;
memcpy(((uint8_t *)&value + first_byte_position), temp_buf, temp_len);
}
buffer[i] = (value & 0xFF);
buffer[i+1] = ((value >> 8) & 0xFF);
buffer[i+2] = ((value >> 16) & 0xFF);
buffer[i+3] = ((value >> 24) & 0xFF);
i += 4;
fifo_cnt--;
len -= temp_len;
byte_offset += temp_len;
}
/* Transfer batch of data */
bcm2835_spi_transfern((char *)buffer, size);
}
free(buffer);
}
/** 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)
{
/* Select Read function depending on address, process data ram or not */
if (address >= 0x1000)
{
ESC_read_pram(address, buf, len);
}
else
{
uint16_t size;
uint8_t *temp_buf = (uint8_t *)buf;
while(len > 0)
{
/* We write maximum 4 bytes at the time */
size = (len > 4) ? 4 : len;
/* Make size aligned to address according to LAN9252 datasheet
* Table 12-14 EtherCAT CSR Address VS size and MicroChip SDK code
*/
/* If we got an odd address size is 1 , 01b 11b is captured */
if(address & BIT(0))
{
size = 1;
}
/* If address 1xb and size != 1 and 3 , allow size 2 else size 1 */
else if (address & BIT(1))
{
size = (size & BIT(0)) ? 1 : 2;
}
/* size 3 not valid */
else if (size == 3)
{
size = 1;
}
/* else size is kept AS IS */
ESC_read_csr(address, temp_buf, size);
/* next address */
len -= size;
temp_buf += size;
address += size;
}
}
/* To mimic the ET1100 always providing AlEvent on every read or write */
ESC_read_csr(ESCREG_ALEVENT,(void *)&ESCvar.ALevent,sizeof(ESCvar.ALevent));
ESCvar.ALevent = etohs (ESCvar.ALevent);
}
/** 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)
{
/* Select Write function depending on address, process data ram or not */
if (address >= 0x1000)
{
ESC_write_pram(address, buf, len);
}
else
{
uint16_t size;
uint8_t *temp_buf = (uint8_t *)buf;
while(len > 0)
{
/* We write maximum 4 bytes at the time */
size = (len > 4) ? 4 : len;
/* Make size aligned to address according to LAN9252 datasheet
* Table 12-14 EtherCAT CSR Address VS size and MicroChip SDK code
*/
/* If we got an odd address size is 1 , 01b 11b is captured */
if(address & BIT(0))
{
size = 1;
}
/* If address 1xb and size != 1 and 3 , allow size 2 else size 1 */
else if (address & BIT(1))
{
size = (size & BIT(0)) ? 1 : 2;
}
/* size 3 not valid */
else if (size == 3)
{
size = 1;
}
/* else size is kept AS IS */
ESC_write_csr(address, temp_buf, size);
/* next address */
len -= size;
temp_buf += size;
address += size;
}
}
/* To mimic the ET1x00 always providing AlEvent on every read or write */
ESC_read_csr(ESCREG_ALEVENT,(void *)&ESCvar.ALevent,sizeof(ESCvar.ALevent));
ESCvar.ALevent = etohs (ESCvar.ALevent);
}
/* Un-used due to evb-lan9252-digio not havning any possability to
* reset except over SPI.
*/
void ESC_reset (void)
{
}
void ESC_init (const esc_cfg_t * config)
{
bool rpi4 = false, cs1 = false;
uint32_t value;
uint32_t counter = 0;
uint32_t timeout = 1000; // wait 100msec
const char * user_arg = (char *)config->user_arg;
size_t arg_len = strlen(user_arg)+1;
char * arg_str = (char *)calloc(arg_len, sizeof(char));
strncpy(arg_str,user_arg,arg_len);
char * delim = " ,.-";
char * token = strtok(arg_str,delim);
// parse user arguments
while (token != NULL)
{
if (strncmp(token,"cs1",3) == 0)
{
cs1 = true; // select CS1 pin
}
else if (strncmp(token,"rpi4",4) == 0)
{
rpi4 = true; // select clock divider for raspberry pi 4 or newer
}
token = strtok(NULL,delim);
}
free(arg_str);
// start initialization
if (bcm2835_init())
{
if (bcm2835_spi_begin())
{
// Set SPI bit order
bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);
// Set SPI data mode BCM2835_SPI_MODE0 = 0, CPOL = 0, CPHA = 0,
// Clock idle low, data is clocked in on rising edge, output data (change) on falling edge
bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);
if (rpi4)
{
// Raspberry 4 due to a higher CPU speed this value is to change to: BCM2835_SPI_CLOCK_DIVIDER_32
bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_32);
DPRINT("bcm2835_spi_setClockDivider set to 32 \n");
}
else
{
// Set SPI clock speed BCM2835_SPI_CLOCK_DIVIDER_16 = 16, 16 = 64ns = 15.625MHz
bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_16);
DPRINT("bcm2835_spi_setClockDivider set to 16 \n");
}
if (cs1)
{
// Enable management of CS1 pin
bcm2835_spi_chipSelect(BCM2835_SPI_CS1);
// Enable CS1 and set polarity
bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS1, LOW);
DPRINT("bcm2835_spi_chipSelect set to CS1 \n");
}
else
{
// Enable management of CS0 pin
bcm2835_spi_chipSelect(BCM2835_SPI_CS0);
// enable CS0 and set polarity
bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW);
DPRINT("bcm2835_spi_chipSelect set to CS0 \n");
}
// Reset the ecat core here due to evb-lan9252-digio not having any GPIO for that purpose.
bcm2835_spi_write_32(ESC_CMD_RESET_CTL,ESC_RESET_CTRL_RST);
// Wait until reset command has been executed
do
{
usleep(100);
counter++;
value = bcm2835_spi_read_32(ESC_CMD_RESET_CTL);
} while ((value & ESC_RESET_CTRL_RST) && (counter < timeout));
// Perform byte test
do
{
usleep(100);
counter++;
value = bcm2835_spi_read_32(ESC_CMD_BYTE_TEST);
} while ((value != ESC_BYTE_TEST_OK) && (counter < timeout));
// Check hardware is ready
do
{
usleep(100);
counter++;
value = bcm2835_spi_read_32(ESC_CMD_HW_CFG);
} while (!(value & ESC_HW_CFG_READY) && (counter < timeout));
// Check if timeout occured
if (counter < timeout)
{
// Read the chip identification and revision
value = bcm2835_spi_read_32(ESC_CMD_ID_REV);
DPRINT("Detected chip %x Rev %u \n", ((value >> 16) & 0xFFFF), (value & 0xFFFF));
// Set AL event mask
value = (ESCREG_ALEVENT_CONTROL |
ESCREG_ALEVENT_SMCHANGE |
ESCREG_ALEVENT_SM0 |
ESCREG_ALEVENT_SM1 );
ESC_ALeventmaskwrite(value);
}
else
{
DPRINT("Timeout occurred during reset \n");
bcm2835_spi_end();
bcm2835_close();
}
}
else
{
DPRINT("bcm2835_spi_begin failed. Are you running as root?\n");
bcm2835_close();
}
}
else
{
DPRINT("bcm2835_init failed. Are you running as root?\n");
}
}
void ESC_interrupt_enable (uint32_t mask)
{
// Enable interrupt for SYNC0 or SM2 or SM3
uint32_t user_int_mask = ESCREG_ALEVENT_DC_SYNC0 |
ESCREG_ALEVENT_SM2 |
ESCREG_ALEVENT_SM3;
if (mask & user_int_mask)
{
ESC_ALeventmaskwrite(ESC_ALeventmaskread() | (mask & user_int_mask));
}
// Set LAN9252 interrupt pin driver as push-pull active high
bcm2835_spi_write_32(ESC_CMD_IRQ_CFG, 0x00000111);
// Enable LAN9252 interrupt
bcm2835_spi_write_32(ESC_CMD_INT_EN, 0x00000001);
}
void ESC_interrupt_disable (uint32_t mask)
{
// Enable interrupt for SYNC0 or SM2 or SM3
uint32_t user_int_mask = ESCREG_ALEVENT_DC_SYNC0 |
ESCREG_ALEVENT_SM2 |
ESCREG_ALEVENT_SM3;
if (mask & user_int_mask)
{
// Disable interrupt from SYNC0
ESC_ALeventmaskwrite(ESC_ALeventmaskread() & ~(mask & user_int_mask));
}
// Disable LAN9252 interrupt
bcm2835_spi_write_32(ESC_CMD_INT_EN, 0x00000000);
}

View File

@ -0,0 +1,17 @@
/*
* 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__
void ESC_interrupt_enable (uint32_t mask);
void ESC_interrupt_disable (uint32_t mask);
#endif

View File

@ -16,6 +16,8 @@
#include <string.h>
#include <gpio.h>
#define MAX_READ_SIZE 128
#define ESC_CMD_READ 0x02
#define ESC_CMD_READWS 0x03
#define ESC_CMD_WRITE 0x04
@ -24,7 +26,7 @@
#define ESC_NEXT 0x00
static int et1100 = -1;
static uint8_t read_termination[MAX(sizeof(Wb), 128)] = { 0 };
static uint8_t read_termination[MAX_READ_SIZE] = { 0 };
#define GPIO_ECAT_RESET 1 /* specific function to hold ESC reset on startup
* when emulating EEPROM
@ -56,7 +58,7 @@ static void esc_address (uint16_t address, uint8_t command)
*/
void ESC_read (uint16_t address, void *buf, uint16_t len)
{
ASSERT(len <= sizeof(read_termination));
ASSERT(len <= MAX_READ_SIZE);
/* Select device. */
spi_select (et1100);
@ -69,7 +71,7 @@ void ESC_read (uint16_t address, void *buf, uint16_t len)
* Read (and write termination bytes).
*/
spi_bidirectionally_transfer (et1100, buf, read_termination +
(sizeof(read_termination) - len), len);
(MAX_READ_SIZE - len), len);
/* Un-select device. */
spi_unselect (et1100);
@ -122,5 +124,5 @@ void ESC_init (const esc_cfg_t * config)
{
const char * spi_name = (char *)config->user_arg;
et1100 = open (spi_name, O_RDWR, 0);
read_termination[sizeof(read_termination) - 1] = 0xFF;
read_termination[MAX_READ_SIZE - 1] = 0xFF;
}

View File

@ -10,21 +10,23 @@
* Function to read and write commands to the ESC. Used to read/write ESC
* registers and memory.
*/
#include <kern.h>
#include <kern/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"
#include "ecat_slv.h"
#include "esc_hw_eep.h"
#define ESCADDR(x) (((uint8_t *) ECAT0_BASE) + x)
/* Global sem to make it possible to kick worker from the application */
sem_t * ecat_isr_sem;
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;
@ -81,6 +83,25 @@ 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);
/* Used to perform PHY reset after ECAT module have been released as
* described in 16.3.2.3 final section;
* "In some case PHYs may be released from reset after releasing the ECAT
* module, the pin for nPHY_RESET can be used as an I/O and shell be
* switched later to the alternate output function".
* Works well with relax boards.
*/
static const gpio_cfg_t gpio_cfg[] =
{
{ ECAT0_PHY_RESET,
ECAT0_PHY_RESET_GPIO_AF,
GPIO_STRONG_SOFT,
GPIO_PAD_ENABLED,
GPIO_POWS_DISABLED,
GPIO_SW },
};
/* Re-configure the pin to correct alternate output function */
gpio_configure (gpio_cfg, NELEMENTS (gpio_cfg));
}
/* EtherCAT module clock gating and assert reset API (Disables ECAT)*/
@ -175,7 +196,6 @@ void ESC_interrupt_disable (uint32_t mask)
mask &= ~ESCREG_ALEVENT_DC_LATCH;
UASSERT(0,EARG);
}
ecat0->AL_EVENT_MASK &= ~mask;
}
@ -193,6 +213,22 @@ void ESC_eep_handler(void)
*/
static void sync0_isr (void * arg)
{
/* Subtract the sync counter to check the pace compared to the SM IRQ */
if((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0)
{
CC_ATOMIC_SUB(ESCvar.synccounter, 1);
}
/* Check so we're inside the limit */
if((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_ALstatusgotoerror((ESCsafeop | ESCerror), ALERR_SYNCERROR);
CC_ATOMIC_SET(ESCvar.synccounter, 0);
}
}
DIG_process(DIG_PROCESS_APP_HOOK_FLAG | DIG_PROCESS_INPUTS_FLAG);
read_ack = ecat0->DC_SYNC0_STAT;
}
@ -203,13 +239,13 @@ static void sync0_isr (void * arg)
*/
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));
CC_ATOMIC_SET(ESCvar.Time, etohl(ecat0->READMode_DC_SYS_TIME[0]));
if(ESCvar.ALevent & ESCREG_ALEVENT_SM2)
/* Handle SM2 & SM3 interrupt */
if(ESCvar.ALevent & (ESCREG_ALEVENT_SM2 | ESCREG_ALEVENT_SM3))
{
/* Is DC active or not */
if(ESCvar.dcsync == 0)
{
DIG_process(DIG_PROCESS_OUTPUTS_FLAG | DIG_PROCESS_APP_HOOK_FLAG |
@ -217,10 +253,16 @@ static void ecat_isr (void * arg)
}
else
{
/* Add the sync counter to check the pace compared to the SM IRQ */
if((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0)
{
CC_ATOMIC_ADD(ESCvar.synccounter, 1);
}
DIG_process(DIG_PROCESS_OUTPUTS_FLAG);
}
}
/* Handle low prio interrupts */
if(ESCvar.ALevent & (ESCREG_ALEVENT_CONTROL | ESCREG_ALEVENT_SMCHANGE
| ESCREG_ALEVENT_SM0 | ESCREG_ALEVENT_SM1 | ESCREG_ALEVENT_EEP))
{
@ -229,16 +271,40 @@ static void ecat_isr (void * arg)
| ESCREG_ALEVENT_SM0 | ESCREG_ALEVENT_SM1 | ESCREG_ALEVENT_EEP);
sem_signal(ecat_isr_sem);
}
/* SM watchdog */
if(ESCvar.ALevent & ESCREG_ALEVENT_WD)
{
uint16_t wd;
/* Ack the WD IRQ */
wd = ecat0->WD_STAT_PDATA;
/* Check if the WD have expired and if we're in OP */
if(((wd & 0x1) == 0) &&
((CC_ATOMIC_GET(ESCvar.App.state) & APPSTATE_OUTPUT) > 0))
{
ESC_ALstatusgotoerror((ESCsafeop | ESCerror), ALERR_WATCHDOG);
ecat0->AL_EVENT_MASK &= ~ESCREG_ALEVENT_WD;
}
}
}
/* Function for PDI ISR serving task */
/* Function for low prio PDI interrupts and flushing of EEPROM RAM buffer
* to flash.
*/
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);
/* Do while to handle write of eeprom, the write to flash is delayed */
do
{
/* Update time, used by emulated eeprom handler to measure idle time */
CC_ATOMIC_SET(ESCvar.Time, etohl(ecat0->READMode_DC_SYS_TIME[0]));
ecat_slv_worker(ESCREG_ALEVENT_CONTROL | ESCREG_ALEVENT_SMCHANGE
| ESCREG_ALEVENT_SM0 | ESCREG_ALEVENT_SM1 | ESCREG_ALEVENT_EEP);
}while(eep_write_pending);
}
}

View File

@ -11,7 +11,7 @@
#ifndef __esc_hw__
#define __esc_hw__
#include <kern.h>
#include <kern/kern.h>
/* ================================================================================ */
/* ================ ECAT [ECAT0] ================ */
/* ================================================================================ */

View File

@ -63,6 +63,7 @@ static eep_block_t *cleanup_unused_sect(eep_block_t *block);
static int32_t is_sector_empty(uint32_t *addr);
uint8_t eep_write_pending;
/** Initialize EEPROM emulation (load default data, validate checksums, ...).
*
@ -135,6 +136,7 @@ void EEP_hw_process (void)
/* update block pointer and reset write state */
eep_curr_block = eep_next_block;
eep_next_block = NULL;
eep_write_pending = 0;
}
return;
@ -204,6 +206,7 @@ int8_t EEP_write (uint32_t addr, uint8_t *data, uint16_t count)
eep_buf_dirty = 1;
eep_write_req = 0;
eep_last_write = ESCvar.Time;
eep_write_pending = 1;
return 0;
}

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