├── .gitignore ├── LICENSE ├── README.md ├── cia402device ├── .gitignore ├── .vscode │ └── extensions.json ├── README.md ├── include │ └── README ├── lib │ ├── README │ └── cia402device │ │ ├── cia402device.c │ │ └── cia402device.h ├── platformio.ini ├── src │ └── main.c └── test │ ├── README │ └── test_lib │ └── test_cia402device.c ├── docs ├── 001-intro.md ├── 002-lan9252-board-design.md ├── 003-lan9252-board-tests.md ├── 004-lan9252-with-coe-stack.md ├── 005-lan9252-rev2.md ├── 006-ax58100-board.md ├── 007-linuxcnc-setup.md ├── 008-ax58100-board-rev2.md ├── 009-software-tools.md ├── 010-twincat-3-1-setup.md ├── Benchmarks.md ├── _config.yml ├── html │ ├── ax58100_stmbl_ibom.html │ ├── ax58100rev1_ibom.html │ ├── ax58100rev2_ibom.html │ ├── lan9252rev1_ibom.html │ └── lan9252rev2_ibom.html ├── img │ ├── EEPROM_generator.gif │ ├── EEPROM_generator_ax58100.gif │ ├── ax58100_rev1_bottom.jpg │ ├── ax58100_rev1_top.jpg │ ├── ax58100_rev2_bottom.jpg │ ├── ax58100_rev2_top.jpg │ ├── ax58100_stmbl_bottom.jpg │ ├── ax58100_stmbl_top.jpg │ ├── ax58100spi_rev1_PCB.jpg │ ├── ax58100spi_rev1_assembled.jpg │ ├── ax58100spi_rev1_stm32f4disco.jpg │ ├── ax58100spi_rev1_stm32f4disco_configured.jpg │ ├── cia402_transition_table.jpg │ ├── cia402dummytwincat.jpg │ ├── lan9252_rev1_bottom.png │ ├── lan9252_rev1_stm32f1_bluepill.jpg │ ├── lan9252_rev1_top.png │ ├── lan9252_rev2_bottom.jpg │ ├── lan9252_rev2_top.jpg │ ├── lan9252spi_rev1.jpg │ ├── lan9252spi_rev1_arduino_corrected.jpg │ ├── lan9252spi_rev1_arduino_first_try.jpg │ ├── lan9252spi_rev1_assembled.jpg │ ├── lan9252spi_rev1_bootup.jpg │ ├── lan9252spi_rev1_stm32f4disco.jpg │ ├── twincat_activate_axis.gif │ ├── twincat_add_axis.gif │ ├── twincat_add_rtdevice.gif │ ├── twincat_enable_DC.gif │ ├── twincat_enable_configuration.gif │ ├── twincat_install_rtdriver.gif │ └── twincat_launch.gif └── index.md └── examples ├── EasyCAT_SPL ├── .gitignore ├── README.md ├── boards │ └── f407zg.json ├── esi │ └── DS402_PDOs_EasyCatProject │ │ ├── DS402_PDOs_EasyCatProject.bin │ │ ├── DS402_PDOs_EasyCatProject.h │ │ ├── DS402_PDOs_EasyCatProject.prj │ │ └── DS402_PDOs_EasyCatProject.xml ├── include │ ├── ECAT_App.h │ ├── README │ └── delay.h ├── lib │ ├── BSP │ │ ├── stm32f4_discovery.c │ │ ├── stm32f4_discovery.h │ │ ├── stm32f4xx_conf.h │ │ └── system_stm32f4xx.c │ ├── EasyCAT │ │ ├── DS402_PDOs.h │ │ ├── EasyCAT.c │ │ ├── EasyCAT.h │ │ ├── LAN9252spi.c │ │ └── LAN9252spi.h │ └── README ├── platformio.ini ├── src │ ├── ECAT_App.c │ ├── delay.c │ └── main.c └── test │ └── README ├── EasyCAT_arduino ├── .gitignore ├── .vscode │ └── extensions.json ├── README.md ├── boards │ └── f407zg.json ├── esi │ └── DS402_PDOs_EasyCatProject │ │ ├── DS402_PDOs_EasyCatProject.bin │ │ ├── DS402_PDOs_EasyCatProject.h │ │ ├── DS402_PDOs_EasyCatProject.prj │ │ └── DS402_PDOs_EasyCatProject.xml ├── include │ ├── README │ └── main.h ├── lib │ ├── EasyCAT │ │ ├── DS402_PDOs_EasyCatProject.h │ │ ├── EasyCAT.cpp │ │ ├── EasyCAT.h │ │ ├── LAN9252spi.cpp │ │ ├── LAN9252spi.h │ │ └── keywords.txt │ └── README ├── platformio.ini ├── src │ └── main.cpp └── test │ └── README ├── SOES_CIA402_AX58100 ├── .gitignore ├── .vscode │ └── extensions.json ├── AX58100.md ├── LICENSE ├── README.md ├── include │ ├── README │ ├── ecatapp.h │ └── pdo_override.h ├── lib │ ├── README │ ├── bsp │ │ ├── delay.c │ │ ├── delay.h │ │ ├── stm32f4_discovery.c │ │ ├── stm32f4_discovery.h │ │ ├── stm32f4xx_conf.h │ │ ├── system_stm32f4xx.c │ │ ├── usart.c │ │ └── usart.h │ ├── cia402device │ │ ├── cia402device.c │ │ └── cia402device.h │ ├── soes-esi │ │ ├── STMBL_ECAT.xml │ │ ├── ecat_options.h │ │ ├── eeprom.bin │ │ ├── eeprom.hex │ │ ├── esi.json │ │ ├── objectlist.c │ │ └── utypes.h │ ├── soes │ │ ├── CMakeLists.txt │ │ ├── Doxyfile │ │ ├── doc │ │ │ ├── images │ │ │ │ ├── esi_pdo.png │ │ │ │ └── sii_pdo.png │ │ │ ├── soes.dox │ │ │ └── tutorial.txt │ │ ├── ecat_slv.c │ │ ├── ecat_slv.h │ │ ├── esc.c │ │ ├── esc.h │ │ ├── esc_coe.c │ │ ├── esc_coe.h │ │ ├── esc_eep.c │ │ ├── esc_eep.h │ │ ├── esc_eoe.c │ │ ├── esc_eoe.h │ │ ├── esc_foe.c │ │ ├── esc_foe.h │ │ ├── hal │ │ │ └── ax58100 │ │ │ │ └── esc_hw.c │ │ ├── include │ │ │ └── sys │ │ │ │ └── gcc │ │ │ │ └── cc.h │ │ └── options.h │ └── soes_hal_bsp │ │ ├── cc.h │ │ ├── esc_irq.c │ │ ├── esc_irq.h │ │ ├── rst.c │ │ ├── rst.h │ │ ├── spi.c │ │ └── spi.h ├── patch_esi.py ├── platformio.ini ├── src │ ├── ecatapp.c │ ├── main.c │ └── pdo_override.c └── test │ └── README ├── SOES_LAN9252 ├── .gitignore ├── .vscode │ └── extensions.json ├── Benchmarks.md ├── LICENSE ├── README.md ├── include │ └── README ├── lib │ ├── README │ ├── bsp │ │ ├── delay.c │ │ ├── delay.h │ │ ├── stm32f4_discovery.c │ │ ├── stm32f4_discovery.h │ │ ├── stm32f4xx_conf.h │ │ ├── system_stm32f4xx.c │ │ ├── usart.c │ │ └── usart.h │ ├── soes-esi │ │ ├── LAN9252_SPI_demo.xml │ │ ├── cc.h │ │ ├── ecat_options.h │ │ ├── eeprom.bin │ │ ├── eeprom.hex │ │ ├── esi.json │ │ ├── objectlist.c │ │ └── utypes.h │ └── soes │ │ ├── CMakeLists.txt │ │ ├── Doxyfile │ │ ├── doc │ │ ├── images │ │ │ ├── esi_pdo.png │ │ │ └── sii_pdo.png │ │ ├── soes.dox │ │ └── tutorial.txt │ │ ├── ecat_slv.c │ │ ├── ecat_slv.h │ │ ├── esc.c │ │ ├── esc.h │ │ ├── esc_coe.c │ │ ├── esc_coe.h │ │ ├── esc_eep.c │ │ ├── esc_eep.h │ │ ├── esc_eoe.c │ │ ├── esc_eoe.h │ │ ├── esc_foe.c │ │ ├── esc_foe.h │ │ ├── hal │ │ └── stm32-lan9252 │ │ │ ├── esc_hw.c │ │ │ ├── rst.c │ │ │ ├── rst.h │ │ │ ├── spi.c │ │ │ └── spi.h │ │ └── options.h ├── platformio.ini ├── src │ └── main.c └── test │ └── README ├── SOES_arduino ├── .gitignore ├── .vscode │ └── extensions.json ├── LICENSE ├── README.md ├── include │ └── README ├── lib │ ├── README │ ├── soes-esi │ │ ├── LAN9252_SPI_demo.xml │ │ ├── cc.h │ │ ├── ecat_options.h │ │ ├── eeprom.bin │ │ ├── eeprom.hex │ │ ├── esi.json │ │ ├── objectlist.c │ │ └── utypes.h │ └── soes │ │ ├── CMakeLists.txt │ │ ├── Doxyfile │ │ ├── doc │ │ ├── images │ │ │ ├── esi_pdo.png │ │ │ └── sii_pdo.png │ │ ├── soes.dox │ │ └── tutorial.txt │ │ ├── ecat_slv.c │ │ ├── ecat_slv.h │ │ ├── esc.c │ │ ├── esc.h │ │ ├── esc_coe.c │ │ ├── esc_coe.h │ │ ├── esc_eep.c │ │ ├── esc_eep.h │ │ ├── esc_eoe.c │ │ ├── esc_eoe.h │ │ ├── esc_foe.c │ │ ├── esc_foe.h │ │ ├── hal │ │ └── arduino-lan9252 │ │ │ ├── esc_hw.c │ │ │ ├── spi.cpp │ │ │ ├── spi.h │ │ │ └── spi.hpp │ │ └── options.h ├── platformio.ini ├── src │ └── main.cpp └── test │ └── README └── SOES_arduino_avr ├── .vscode ├── c_cpp_properties.json ├── extensions.json └── launch.json ├── README.md ├── include ├── README └── main.h ├── lib ├── README ├── soes-esi │ ├── .project │ ├── cc.h │ ├── cia402.bin │ ├── cia402.xml │ ├── cia402_objectlist.c │ ├── cia402patched.bin │ ├── ecat_options.h │ └── utypes.h └── soes │ ├── CMakeLists.txt │ ├── Doxyfile │ ├── doc │ ├── images │ │ ├── esi_pdo.png │ │ └── sii_pdo.png │ ├── soes.dox │ └── tutorial.txt │ ├── ecat_slv.c │ ├── ecat_slv.h │ ├── esc.c │ ├── esc.h │ ├── esc_coe.c │ ├── esc_coe.h │ ├── esc_eep.c │ ├── esc_eep.h │ ├── esc_eoe.c │ ├── esc_eoe.h │ ├── esc_foe.c │ ├── esc_foe.h │ ├── hal │ └── arduino-lan9252 │ │ ├── esc_hw.c │ │ ├── spi.cpp │ │ ├── spi.h │ │ └── spi.hpp │ └── options.h ├── platformio.ini ├── src └── main.cpp └── test └── README /.gitignore: -------------------------------------------------------------------------------- 1 | # Platformio 2 | .pio 3 | .vscode/.browse.c_cpp.db* 4 | .vscode/c_cpp_properties.json 5 | .vscode/launch.json 6 | .vscode/ipch 7 | 8 | # EasyCAT 9 | log_configuration.txt 10 | log_programmer.txt 11 | 12 | # Eclipse 13 | .metadata/ 14 | 15 | # For PCBs designed using KiCad: http://www.kicad-pcb.org/ 16 | 17 | # Temporary files 18 | *.000 19 | *.bak 20 | *.bck 21 | *.kicad_pcb-bak 22 | *~ 23 | _autosave-* 24 | *.tmp 25 | 26 | # Netlist files (exported from Eeschema) 27 | *.net 28 | 29 | # Autorouter files (exported from Pcbnew) 30 | .dsn 31 | 32 | # Exported BOM files 33 | *.xml 34 | *.csv 35 | *.esx -------------------------------------------------------------------------------- /cia402device/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .pioenvs 3 | .piolibdeps 4 | .vscode/.browse.c_cpp.db* 5 | .vscode/c_cpp_properties.json 6 | .vscode/launch.json 7 | .vscode/settings.json 8 | .vscode/ipch 9 | -------------------------------------------------------------------------------- /cia402device/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "platformio.platformio-ide" 6 | ], 7 | "unwantedRecommendations": [ 8 | "ms-vscode.cpptools-extension-pack" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /cia402device/README.md: -------------------------------------------------------------------------------- 1 | # CiA 402 device 2 | 3 | This project is tested open source implementation of CANOpen CiA402 profile (motion control). 4 | Axis struct has states, transitions and action flags, its up for application to act on these. 5 | 6 | ```c 7 | cia402_axis_t cia402axis; // create instance of motion control axis 8 | cia402_initialize(&cia402axis, &OD.Status_Word, &mockOD.ALstatus); // initalize 9 | // ... 10 | while (true) { // in main loop 11 | // ... // read PDOs from CANbus, EtherCAT... 12 | cia402_state_machine(&cia402axis, controlword); // process SM 13 | 14 | if (axis.flags.axis_func_enabled) { /* implement your drive following command */ } 15 | if (axis->flags.hv_power_applied) { /* enable HV power if applicable */ } 16 | if (axis->flags.brake_applied) { /* release brake if applicable */ } 17 | 18 | if(/* application detected error condition */) { 19 | cia402axis.state = FAULT_REACTION_ACTIVE; // trigger fault reaction 20 | cia402_state_machine(&cia402axis, controlword); // process SM 21 | } 22 | } 23 | ``` 24 | 25 | Unit tests can be ran natively on PC (for this one needs to [install GCC and add it to PATH](https://piolabs.com/blog/insights/unit-testing-part-2.html)) 26 | 27 | 28 | ### TODO 29 | 30 | - structure unit tests like this https://ucgosu.pl/2018/04/unity-framework-testowy-w-c/ 31 | - test coverage https://piolabs.com/blog/insights/test-coverage-on-unit-testing.html https://github.com/Strooom/demoTestCoverage https://embetronicx.com/tutorials/unit_testing/unit-testing-in-c-testing-with-unity/ 32 | - run tests on target HW: STM32F40x https://piolabs.com/blog/insights/unit-testing-part-2.html 33 | 34 | 35 | How to build PlatformIO based project 36 | ===================================== 37 | 38 | 1. [Install PlatformIO Core](https://docs.platformio.org/page/core.html) 39 | 2. Download [development platform with examples](https://github.com/platformio/platform-native/archive/develop.zip) 40 | 3. Extract ZIP archive 41 | 4. Run these commands: 42 | 43 | ```shell 44 | # Change directory to example 45 | $ cd platform-native/examples/hello-world 46 | 47 | # Build project 48 | $ pio run 49 | 50 | # Execute program 51 | $ pio run --target exec 52 | # or using embedded's "upload" target 53 | $ pio run --target upload 54 | 55 | # Clean build files 56 | $ pio run --target clean 57 | ``` 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /cia402device/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /cia402device/lib/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project specific (private) libraries. 3 | PlatformIO will compile them to static libraries and link into executable file. 4 | 5 | The source code of each library should be placed in a an own separate directory 6 | ("lib/your_library_name/[here are source files]"). 7 | 8 | For example, see a structure of the following two libraries `Foo` and `Bar`: 9 | 10 | |--lib 11 | | | 12 | | |--Bar 13 | | | |--docs 14 | | | |--examples 15 | | | |--src 16 | | | |- Bar.c 17 | | | |- Bar.h 18 | | | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html 19 | | | 20 | | |--Foo 21 | | | |- Foo.c 22 | | | |- Foo.h 23 | | | 24 | | |- README --> THIS FILE 25 | | 26 | |- platformio.ini 27 | |--src 28 | |- main.c 29 | 30 | and a contents of `src/main.c`: 31 | ``` 32 | #include 33 | #include 34 | 35 | int main (void) 36 | { 37 | ... 38 | } 39 | 40 | ``` 41 | 42 | PlatformIO Library Dependency Finder will find automatically dependent 43 | libraries scanning project source files. 44 | 45 | More information about PlatformIO Library Dependency Finder 46 | - https://docs.platformio.org/page/librarymanager/ldf.html 47 | -------------------------------------------------------------------------------- /cia402device/platformio.ini: -------------------------------------------------------------------------------- 1 | [platformio] 2 | name = CANOpen CiA402 profile: motion control 3 | description = Open source implementation of CANOpen CiA402 profile (motion control), with tests. 4 | 5 | [env:native] 6 | platform = native 7 | lib_ldf_mode = deep 8 | build_flags = 9 | -D unitTesting 10 | -lgcov 11 | --coverage 12 | 13 | test_framework = unity 14 | test_filter = test_* 15 | 16 | check_src_filters = 17 | lib/* 18 | test/* 19 | -------------------------------------------------------------------------------- /cia402device/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "cia402device.h" 3 | 4 | uint16_t mockOD_Status_Word; 5 | uint16_t mockOD_ALstatus; 6 | 7 | cia402_axis_t cia402axis; 8 | 9 | int main() 10 | { 11 | printf("Hello World from PlatformIO!\n"); 12 | cia402_initialize(&cia402axis, &mockOD_Status_Word, &mockOD_ALstatus); 13 | cia402axis.state = READY_TO_SWITCH_ON; 14 | cia402axis.transition = -1; 15 | uint16_t controlword = CIA402_CONTROLWORD_SWITCH_ON_COMMAND; 16 | cia402_state_machine(&cia402axis, controlword); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /cia402device/test/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for PIO Unit Testing and project tests. 3 | 4 | Unit Testing is a software testing method by which individual units of 5 | source code, sets of one or more MCU program modules together with associated 6 | control data, usage procedures, and operating procedures, are tested to 7 | determine whether they are fit for use. Unit testing finds problems early 8 | in the development cycle. 9 | 10 | More information about PIO Unit Testing: 11 | - https://docs.platformio.org/page/plus/unit-testing.html 12 | -------------------------------------------------------------------------------- /docs/002-lan9252-board-design.md: -------------------------------------------------------------------------------- 1 | # LAN9252-SPI adapter board design 2 | 3 | Starting point was [this open source project](https://github.com/yuqlid/EtherCAT_shield_v1). Stripped schematic to bare minimum, based on EVB-LAN9252-SPI. Left only SQI PDI, then minified board area. Two layers, almost all components on single side for easier assembly and embedding into target devices. 4 | 5 | ![lan9252spi_rev1_top](img/lan9252_rev1_top.png "LAN9252-SPI rev 1 render top") 6 | 7 | ![lan9252spi_rev1_bottom](img/lan9252_rev1_bottom.png "LAN9252-SPI rev 1 render bottom") 8 | 9 | Adapter board, first revision, straight from KiCad. 10 | 11 | [IBOM can be found here](https://kubabuda.github.io/ecat_servo/html/lan9252rev1_ibom.html) 12 | 13 | Looks good. Board came out similar to EasyCAT Pro. Breakout header is compatible, additionally alongside it has full SQI exposed. Also EEPROM chip is THT in socket for simple swap if ESI flashing goes wrong and bricks device. Now forward to board house of choice, and wait for PCBs to arrive. 14 | 15 | Spoiler alert: it worked good enough for what I needed, for practical use you better wait for something better or buy EasyCAT PRO 16 | 17 | [Next: Testing LAN9252 board](https://kubabuda.github.io/ecat_servo/003-lan9252-board-tests) 18 | 19 | [Back to the table of contents](https://kubabuda.github.io/ecat_servo) -------------------------------------------------------------------------------- /docs/005-lan9252-rev2.md: -------------------------------------------------------------------------------- 1 | # LAN9252-SPI board, second revision 2 | 3 | In the meantime some things to correct were found in first revision of SPI adapter 4 | 5 | 6 | ![lan9252spi_rev2_top](img/lan9252_rev2_top.jpg "LAN9252-SPI rev 2 render top") 7 | 8 | ![lan9252spi_rev2_bottom](img/lan9252_rev2_bottom.jpg "LAN9252-SPI rev 2 render bottom") 9 | 10 | [IBOM can be found here](https://kubabuda.github.io/ecat_servo/html/lan9252rev2_ibom.html) 11 | 12 | Design is ready to order and test, but due to performance benchmark results different approach was selected 13 | 14 | 15 | 16 | [Next: AX58100 board](https://kubabuda.github.io/ecat_servo/006-ax58100-board) 17 | 18 | [Prev: CoE stack work on LAN9252](https://kubabuda.github.io/ecat_servo/004-lan9252-with-coe-stack) 19 | 20 | [Back to the table of contents](https://kubabuda.github.io/ecat_servo) 21 | -------------------------------------------------------------------------------- /docs/007-linuxcnc-setup.md: -------------------------------------------------------------------------------- 1 | # Working with LinuxCNC 2 | 3 | LinuxCNC does not support Ethercat natively, probably due to licensing reasons. To get [EtherCAT driver](https://github.com/aschiffler/linuxcnc/) you have to build it and setup with IgH EtherLab that functions as master. To make life easier, prebuilt [OS image](https://github.com/grotius-cnc/LINUX_RTOS) can be used. 4 | 5 | Configuration: 6 | 7 | Looks like dummy servodrive is working. Time to configure Distributed Clock. We can either set `0x0980` to 0x01, to assign sync unit to PDI (and let device slave finish configuration), or do all the sync configuration on master side. 8 | 9 | [TODO] link configuration 10 | 11 | [CiA402 HAL component](https://github.com/dbraun1981/hal-cia402) 12 | 13 | 14 | 15 | [Next: AX58100 rev 2, STMBL adapter](https://kubabuda.github.io/ecat_servo/008-ax58100-board-rev2) 16 | 17 | [Prev: AX58100 board](https://kubabuda.github.io/ecat_servo/006-ax58100-board) 18 | 19 | [Back to the table of contents](https://kubabuda.github.io/ecat_servo) 20 | -------------------------------------------------------------------------------- /docs/008-ax58100-board-rev2.md: -------------------------------------------------------------------------------- 1 | # AX58100 board rev 2 2 | 3 | Again, laundry list of bugs and missing features on current HW was found: 4 | 5 | - Port silkscreen labels are reversed, of course. Just compare PCB renders and photos with stickers on RJ45s 6 | - Switch to 4 layer PCB for better noise protection and simplified, cleaner routing 7 | - Differential pairs routing between ESC and RJ45 should really use matched length and impedance 8 | - SPI signal traces should be checked 9 | - adapter for target device, like STMBL, will be needed (with 5V -> 3V adapter and SWD connector for STM32) 10 | - I2C resistors can be 4K7 to simplify BOM 11 | - Add 4K7 pullup resistor to ESC_FUNC pin 12 | - ditch RESET button, or use more common footprint 13 | - rework board layout: RJ45 should be side to side for easier housing design, chassis clearance is to be improved 14 | 15 | Things that would be nice for next revision: 16 | 17 | - EEP_LOADED and ERR status LEDs: get them on such small board 18 | - ESD protection chip for RJ45 connectors: source anything good and available 19 | 20 | ![ax58100_rev2_top](img/ax58100_rev2_top.jpg "AX58100 rev 2, bottom render") 21 | ![ax58100_rev2_bottom](img/ax58100_rev2_bottom.jpg "AX58100 rev 2, bottom render") 22 | 23 | [IBOM can be found here](https://kubabuda.github.io/ecat_servo/html/ax58100rev2_ibom.html) 24 | 25 | STMBL adapter based on that revision: 26 | 27 | ![ax58100_stmbl_top](img/ax58100_stmbl_top.jpg "AX58100 STMBL, bottom render") 28 | ![ax58100_stmbl_bottom](img/ax58100_stmbl_bottom.jpg "AX58100 STMBL, bottom render") 29 | 30 | [IBOM can be found here](https://kubabuda.github.io/ecat_servo/html/ax58100_stmbl_ibom.html) 31 | 32 | 33 | 34 | [Next: Woring with EtherCAT devives](https://kubabuda.github.io/ecat_servo/009-software-tools) 35 | 36 | [Prev: LinuxCNC setup](https://kubabuda.github.io/ecat_servo/007-linuxcnc-setup) 37 | 38 | [Back to the table of contents](https://kubabuda.github.io/ecat_servo) 39 | -------------------------------------------------------------------------------- /docs/Benchmarks.md: -------------------------------------------------------------------------------- 1 | # Benchmarking 2 | 3 | Data format on all benchmarks is CiA DS402 PDOs. That is 6B each - RxPDO { uint16t; int32_t }; RxPDO { uint16t; int32_t } 4 | 5 | ## EasyCAT 6 | 7 | Measured is PDI communication cycle time (`EASYCAT.MainTask();`) from start to return. 8 | 9 | | ESC | SSC | MCU | SPI driver | SPI speed | value [us] | 10 | | ------- | --------- |:-------:|:----------:|:---------:|:----------:| 11 | | LAN9252 | EasyCAT | AtM328P | Arduino | 8000000 | 196 | 12 | | LAN9252 | EasyCAT | STM32F4 | Arduino | 8000000 | 210 | 13 | | LAN9252 | EasyCAT | STM32F4 | Arduino | 42000000 | 118 | 14 | | LAN9252 | EasyCAT | STM32F4 | Arduino | 42000000 | 107 | 15 | | LAN9252 | EasyCAT | STM32F4 | SPL | 42000000 | 123 | SPI prescaler 16 16 | | LAN9252 | EasyCAT | STM32F4 | SPL | 42000000 | 35 | SPI prescaler 2 17 | 18 | ## SOES 19 | 20 | Measured is how long does polled `ecat_slv();` take from start to return. No interrupts, should be more deterministic and consistent. 21 | 22 | ### LAN9252 23 | 24 | STM32F405 at 168 MHz, SPI1 at 42 MHz, SPL driver 25 | 26 | - Cables connected, ECAT master not connected: `[ESC benchmark] 0028 us (028 top)` 27 | - ECAT master connected, slv in OP: `[ESC benchmark] 0072 us (0280 top)` 28 | 29 | STM32F103 SPI1 at 18 MHz, Arduino driver 30 | 31 | - Cables connected, ECAT master not connected: `[ESC benchmark] 226 us (391 top)` 32 | - ECAT master connected, slv in OP: `[ESC benchmark] 581 us (2393 top) [ESC benchmark] 943 us (2393 top)` 33 | 34 | ### AX58100 35 | 36 | Polling (blocking SPI). SPI1 at 42 MHz 37 | 38 | - Cables connected, ECAT master not connected: `[ESC benchmark] 0006 us (0006 top)` 39 | - ECAT master connected, slv in OP: `[ESC benchmark] 0015 us (0059 top)` 40 | - ECAT master connected, slv in OP, network startup hiscore reset: `[ESC benchmark] 0015 us (0024 top)` 41 | 42 | Added CiA402 loopback, SPI1 at 42 MHz: 43 | 44 | - ECAT master connected, slv in OP, network startup hiscore reset: `[ESC benchmark] 0017 us (0025 top)` 45 | 46 | DMA SPI + CiA402 loopback. Prescaler 2 (42 MHz), SPI reads from ESC are **unstable - transmission errors** 47 | 48 | - ECAT master connected, slv in OP: `[ESC benchmark] 0017 us (0063 top)` 49 | - ECAT master connected, slv in OP, network startup hiscore reset: `[ESC benchmark] 0017 us (0025 top)` 50 | 51 | DMA SPI + CiA402 loopback. Prescaler 4 (21 MHz: 2x slower clock), **2 us slower** 52 | 53 | - Cables connected, ECAT master not connected: `[ESC benchmark] 0009 us (0009 top)` 54 | - ECAT master connected, slv in OP: `[ESC benchmark] 0019 us (0073 top)` 55 | - ECAT master connected, slv in OP, network startup hiscore reset: `[ESC benchmark] 0019 us (0030 top)` 56 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-midnight -------------------------------------------------------------------------------- /docs/img/EEPROM_generator.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/EEPROM_generator.gif -------------------------------------------------------------------------------- /docs/img/EEPROM_generator_ax58100.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/EEPROM_generator_ax58100.gif -------------------------------------------------------------------------------- /docs/img/ax58100_rev1_bottom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/ax58100_rev1_bottom.jpg -------------------------------------------------------------------------------- /docs/img/ax58100_rev1_top.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/ax58100_rev1_top.jpg -------------------------------------------------------------------------------- /docs/img/ax58100_rev2_bottom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/ax58100_rev2_bottom.jpg -------------------------------------------------------------------------------- /docs/img/ax58100_rev2_top.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/ax58100_rev2_top.jpg -------------------------------------------------------------------------------- /docs/img/ax58100_stmbl_bottom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/ax58100_stmbl_bottom.jpg -------------------------------------------------------------------------------- /docs/img/ax58100_stmbl_top.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/ax58100_stmbl_top.jpg -------------------------------------------------------------------------------- /docs/img/ax58100spi_rev1_PCB.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/ax58100spi_rev1_PCB.jpg -------------------------------------------------------------------------------- /docs/img/ax58100spi_rev1_assembled.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/ax58100spi_rev1_assembled.jpg -------------------------------------------------------------------------------- /docs/img/ax58100spi_rev1_stm32f4disco.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/ax58100spi_rev1_stm32f4disco.jpg -------------------------------------------------------------------------------- /docs/img/ax58100spi_rev1_stm32f4disco_configured.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/ax58100spi_rev1_stm32f4disco_configured.jpg -------------------------------------------------------------------------------- /docs/img/cia402_transition_table.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/cia402_transition_table.jpg -------------------------------------------------------------------------------- /docs/img/cia402dummytwincat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/cia402dummytwincat.jpg -------------------------------------------------------------------------------- /docs/img/lan9252_rev1_bottom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/lan9252_rev1_bottom.png -------------------------------------------------------------------------------- /docs/img/lan9252_rev1_stm32f1_bluepill.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/lan9252_rev1_stm32f1_bluepill.jpg -------------------------------------------------------------------------------- /docs/img/lan9252_rev1_top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/lan9252_rev1_top.png -------------------------------------------------------------------------------- /docs/img/lan9252_rev2_bottom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/lan9252_rev2_bottom.jpg -------------------------------------------------------------------------------- /docs/img/lan9252_rev2_top.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/lan9252_rev2_top.jpg -------------------------------------------------------------------------------- /docs/img/lan9252spi_rev1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/lan9252spi_rev1.jpg -------------------------------------------------------------------------------- /docs/img/lan9252spi_rev1_arduino_corrected.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/lan9252spi_rev1_arduino_corrected.jpg -------------------------------------------------------------------------------- /docs/img/lan9252spi_rev1_arduino_first_try.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/lan9252spi_rev1_arduino_first_try.jpg -------------------------------------------------------------------------------- /docs/img/lan9252spi_rev1_assembled.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/lan9252spi_rev1_assembled.jpg -------------------------------------------------------------------------------- /docs/img/lan9252spi_rev1_bootup.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/lan9252spi_rev1_bootup.jpg -------------------------------------------------------------------------------- /docs/img/lan9252spi_rev1_stm32f4disco.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/lan9252spi_rev1_stm32f4disco.jpg -------------------------------------------------------------------------------- /docs/img/twincat_activate_axis.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/twincat_activate_axis.gif -------------------------------------------------------------------------------- /docs/img/twincat_add_axis.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/twincat_add_axis.gif -------------------------------------------------------------------------------- /docs/img/twincat_add_rtdevice.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/twincat_add_rtdevice.gif -------------------------------------------------------------------------------- /docs/img/twincat_enable_DC.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/twincat_enable_DC.gif -------------------------------------------------------------------------------- /docs/img/twincat_enable_configuration.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/twincat_enable_configuration.gif -------------------------------------------------------------------------------- /docs/img/twincat_install_rtdriver.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/twincat_install_rtdriver.gif -------------------------------------------------------------------------------- /docs/img/twincat_launch.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/docs/img/twincat_launch.gif -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # ECAT servo drive 2 | 3 | This is documentation for [ECAT servo](https://github.com/kubabuda/ecat_servo), free CiA402 CoE (CAN over EtherCAT) implementation. 4 | 5 | [Hackaday.io project is here](https://hackaday.io/project/181058-ecatservo) for more convinient discussion 6 | 7 | # Progress log 8 | 9 | [1. Introduction, state of art, project targets](https://kubabuda.github.io/ecat_servo/001-intro) 10 | 11 | [2. LAN9252-SPI PCB design](https://kubabuda.github.io/ecat_servo/002-lan9252-board-design) 12 | 13 | [3. Testing LAN9252 board](https://kubabuda.github.io/ecat_servo/003-lan9252-board-tests) 14 | 15 | [4. Making CoE stack work on LAN9252](https://kubabuda.github.io/ecat_servo/004-lan9252-with-coe-stack) 16 | 17 | [5. LAN9252 PCB rev 2](https://kubabuda.github.io/ecat_servo/005-lan9252-rev2) 18 | 19 | [6. AX58100 board](https://kubabuda.github.io/ecat_servo/006-ax58100-board) 20 | 21 | [7. LinuxCNC setup](https://kubabuda.github.io/ecat_servo/007-linuxcnc-setup) 22 | 23 | [8. AX58100 board rev 2](https://kubabuda.github.io/ecat_servo/008-ax58100-board-rev2) 24 | 25 | [9. Software tools for EtherCAT devices development](https://kubabuda.github.io/ecat_servo/009-software-tools) 26 | 27 | [10. TwinCAT crash course](https://kubabuda.github.io/ecat_servo/010-twincat-3-1-setup) 28 | 29 | 30 | ## Disclaimer 31 | 32 | The EtherCAT Technology, the trade name and logo "EtherCAT" are the intellectual property of, and protected by Beckhoff Automation GmbH. 33 | -------------------------------------------------------------------------------- /examples/EasyCAT_SPL/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/settings.json 6 | .vscode/ipch 7 | 8 | # EasyCAT 9 | log_configuration.txt 10 | log_programmer.txt 11 | 12 | # Eclipse 13 | .metadata -------------------------------------------------------------------------------- /examples/EasyCAT_SPL/README.md: -------------------------------------------------------------------------------- 1 | # EasyCAT on STM32F4 2 | 3 | # Using EasyCAT (LAN9252 EtherCAT board with SPI) library without Arduino 4 | 5 | This is EasyCAT project with PDI code (SPI reads/writes to LAN9252 ESC) using StdPeriph drivers instead of Arduino 6 | 7 | ## MCU pinout 8 | 9 | ### Ecat devkit F407ZG 10 | 11 | Devkit board uses SPI1 default pinout: 12 | 13 | | SPI1 | STM32 pin | LAN9252 | 14 | | ---- |:---------:|:-------:| 15 | | CSN | PA4 | D5 | 16 | | SCK | PA5 | D9 | 17 | | MISO | PA6 | D1/SIO1 | 18 | | MOSI | PA7 | D0/SIO0 | 19 | 20 | ### STMBL 21 | 22 | STMBL is using SPI1 alternative functions 23 | 24 | | SPI1 | STM32 pin | LAN9252 | 25 | | ---- |:---------:|:-------:| 26 | | * | PD0/PD1 | D5 | 27 | | SCK | PB3 | D5 | 28 | | MISO | PB4 | D9 | 29 | | MOSI | PB5 | D1/SIO1 | 30 | 31 | * Hardware CS is not exposed, you can use PD0, PD1 (CAN_RX, CAN_TX) for that 32 | 33 | # MISC 🤷 34 | 35 | - on STM32F407xx PE8 is used by EasyCAT as CS by default as it is mapped to Arduino digital pin 9 (default value for software SCS). To use PA4, HW NSS, pass it to EasyCAT constructor 36 | 37 | - Seems like EasyCATs EasyConfigurator does sort variables in PDOs by size from biggest to smallest as it pleases, regardless of variables order on UI. This is probably to pack variables and minimize PDO size overall but for matching exact order of variables reordering in .h, .xml + generating .bin from .xml will be needed 38 | 39 | - LAN9252 is picky when it comes to power supply. Its glitching without separate 3.3V regulator and Nano 5V line seems to be too weak for powering that regulator and few LEDs ¯\_(ツ)_/¯ 40 | 41 | - Removed SPI transaction in each MainTask, will fail if SPI1 is used for something else 42 | 43 | - reading one indirect access register takes ~ 25us, in loop slave needs to read 2. Not great. 44 | 45 | ### Debug configuration 46 | 47 | - Devkit board without reset line exposed, cannot use F4 Disco which is setting `reset_config srst_only` so cloned .json definition and changed `openocd_target` 48 | 49 | # Benchmarking 50 | 51 | Measured is PDI communication cycle time (`EASYCAT.MainTask();`) on CiA DS402 PDOs. That is 6B each - RxPDO { uint16t; int32_t }; RxPDO { uint16t; int32_t } 52 | 53 | | ESC | SSC | MCU | SPI driver | SPI speed | value [us] | 54 | | ------- | --------- |:-------:|:----------:|:---------:|:----------:| 55 | | LAN9252 | EasyCAT | AtM328P | Arduino | 8000000 | 196 | 56 | | LAN9252 | EasyCAT | STM32F4 | Arduino | 8000000 | 210 | 57 | | LAN9252 | EasyCAT | STM32F4 | Arduino | 42000000 | 118 | 58 | | LAN9252 | EasyCAT.c | STM32F4 | Arduino | 42000000 | 107 | 59 | | LAN9252 | EasyCAT | STM32F4 | SPL | 5250000 | 123 | SPI prescaler 16 60 | | LAN9252 | EasyCAT | STM32F4 | SPL | 42000000 | 35 | SPI prescaler 2 61 | -------------------------------------------------------------------------------- /examples/EasyCAT_SPL/boards/f407zg.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "core": "stm32", 4 | "cpu": "cortex-m4", 5 | "extra_flags": "-DSTM32F4 -DSTM32F407xx -DSTM32F40_41xxx -DARDUINO_STM32DiscoveryF407 -DBOARD_discovery_f4", 6 | "f_cpu": "168000000L", 7 | "ldscript": "stm32f405x6.ld", 8 | "mcu": "stm32f407zgt6", 9 | "variant": "DISCO_F407VG" 10 | }, 11 | "debug": { 12 | "default_tools": [ 13 | "stlink" 14 | ], 15 | "jlink_device": "STM32F407VG", 16 | "openocd_target": "stm32f4x", 17 | "svd_path": "STM32F40x.svd" 18 | }, 19 | "frameworks": [ 20 | "arduino", 21 | "mbed", 22 | "cmsis", 23 | "spl", 24 | "libopencm3", 25 | "stm32cube" 26 | ], 27 | "name": "ST STM32F4DISCOVERY", 28 | "upload": { 29 | "maximum_ram_size": 196608, 30 | "maximum_size": 1048576, 31 | "protocol": "stlink", 32 | "protocols": [ 33 | "jlink", 34 | "stlink", 35 | "blackmagic", 36 | "mbed" 37 | ] 38 | }, 39 | "url": "http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1848/PF252419", 40 | "vendor": "ST" 41 | } 42 | -------------------------------------------------------------------------------- /examples/EasyCAT_SPL/esi/DS402_PDOs_EasyCatProject/DS402_PDOs_EasyCatProject.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/examples/EasyCAT_SPL/esi/DS402_PDOs_EasyCatProject/DS402_PDOs_EasyCatProject.bin -------------------------------------------------------------------------------- /examples/EasyCAT_SPL/esi/DS402_PDOs_EasyCatProject/DS402_PDOs_EasyCatProject.h: -------------------------------------------------------------------------------- 1 | #ifndef CUSTOM_PDO_NAME_H 2 | #define CUSTOM_PDO_NAME_H 3 | 4 | //-------------------------------------------------------------------// 5 | // // 6 | // This file has been created by the Easy Configurator tool // 7 | // // 8 | // Easy Configurator project DS402_PDOs_EasyCatProject.prj 9 | // // 10 | //-------------------------------------------------------------------// 11 | 12 | 13 | #define CUST_BYTE_NUM_OUT 6 14 | #define CUST_BYTE_NUM_IN 6 15 | #define TOT_BYTE_NUM_ROUND_OUT 8 16 | #define TOT_BYTE_NUM_ROUND_IN 8 17 | 18 | 19 | typedef union //---- output buffer ---- 20 | { 21 | uint8_t Byte [TOT_BYTE_NUM_ROUND_OUT]; 22 | struct 23 | { 24 | int32_t Position_0x607A; 25 | uint16_t ControlWord_0x6040; 26 | }Cust; 27 | } PROCBUFFER_OUT; 28 | 29 | 30 | typedef union //---- input buffer ---- 31 | { 32 | uint8_t Byte [TOT_BYTE_NUM_ROUND_IN]; 33 | struct 34 | { 35 | int32_t ActualPosition_0x6064; 36 | uint16_t StatusWord_0x6041; 37 | }Cust; 38 | } PROCBUFFER_IN; 39 | 40 | #endif -------------------------------------------------------------------------------- /examples/EasyCAT_SPL/esi/DS402_PDOs_EasyCatProject/DS402_PDOs_EasyCatProject.prj: -------------------------------------------------------------------------------- 1 | DS402_PDOs_EasyCatProject 2 | OUTPUTS_TAG 3 | Position_0x607A 4 | int32_t 5 | ControlWord_0x6040 6 | uint16_t 7 | INPUTS_TAG 8 | ActualPosition_0x6064 9 | int32_t 10 | StatusWord_0x6041 11 | uint16_t 12 | INFO_TAG 13 | 0x0000079A 14 | AB&T 15 | 0xABE00001 16 | 0x00000001 17 | DS402_PDOs 18 | END_TAG 19 | -------------------------------------------------------------------------------- /examples/EasyCAT_SPL/include/ECAT_App.h: -------------------------------------------------------------------------------- 1 | #ifndef __ECAT_App_H__ 2 | #define __ECAT_App_H__ 3 | 4 | #include 5 | 6 | 7 | void ECAT_AppSetup(); 8 | void ECAT_Application(); 9 | 10 | uint32_t ECAT_PDIcommBenchmark_us(); 11 | 12 | #endif // #ifndef __ECAT_App_H__ -------------------------------------------------------------------------------- /examples/EasyCAT_SPL/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /examples/EasyCAT_SPL/include/delay.h: -------------------------------------------------------------------------------- 1 | #ifndef __DELAY_H__ 2 | #define __DELAY_H__ 3 | 4 | #include "stm32f4xx.h" 5 | 6 | uint32_t Delay_init(void); 7 | 8 | void SysTick_Handler(); 9 | 10 | void delay_ms(int time); 11 | 12 | uint32_t millis(); 13 | uint32_t micros(); 14 | 15 | #endif // __DELAY_H__ 16 | -------------------------------------------------------------------------------- /examples/EasyCAT_SPL/lib/EasyCAT/DS402_PDOs.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef CUSTOM_PDO_NAME_H 4 | #define CUSTOM_PDO_NAME_H 5 | 6 | //-------------------------------------------------------------------// 7 | // // 8 | // This file has been created by the Easy Configurator tool // 9 | // // 10 | // Easy Configurator project DS402_PDOs_EasyCatProject.prj 11 | // // 12 | //-------------------------------------------------------------------// 13 | 14 | 15 | #define CUST_BYTE_NUM_OUT 6 16 | #define CUST_BYTE_NUM_IN 6 17 | #define TOT_BYTE_NUM_ROUND_OUT 8 18 | #define TOT_BYTE_NUM_ROUND_IN 8 19 | 20 | 21 | typedef union //---- output buffer ---- 22 | { 23 | uint8_t Byte [TOT_BYTE_NUM_ROUND_OUT]; 24 | struct 25 | { 26 | int32_t Position_0x6064; 27 | uint16_t ControlWord_0x6040; 28 | }Cust; 29 | } PROCBUFFER_OUT; 30 | 31 | 32 | typedef union //---- input buffer ---- 33 | { 34 | uint8_t Byte [TOT_BYTE_NUM_ROUND_IN]; 35 | struct 36 | { 37 | int32_t ActualPosition_0x6064; 38 | uint16_t StatusWord_0x6041; 39 | }Cust; 40 | } PROCBUFFER_IN; 41 | 42 | #endif -------------------------------------------------------------------------------- /examples/EasyCAT_SPL/lib/EasyCAT/LAN9252spi.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef LAN9252_SPI_H 3 | #define LAN9252_SPI_H 4 | 5 | #include 6 | 7 | //---- LAN9252 registers -------------------------------------------------------------------------- 8 | 9 | //---- access to EtherCAT registers ------------------- 10 | 11 | #define ECAT_CSR_DATA 0x0300 // EtherCAT CSR Interface Data Register 12 | #define ECAT_CSR_CMD 0x0304 // EtherCAT CSR Interface Command Register 13 | 14 | //---- LAN9252 flags ------------------------------------------------------------------------------ 15 | 16 | #define ECAT_CSR_BUSY 0x80 17 | #define PRAM_ABORT 0x40000000 18 | #define PRAM_BUSY 0x80 19 | #define PRAM_AVAIL 0x01 20 | #define READY 0x08 21 | #define DIGITAL_RST 0x00000001 22 | 23 | //---- LAN9252 SPI commands ----------------------------------------------------------------------- 24 | 25 | #define COMM_SPI_READ 0x03 26 | #define COMM_SPI_WRITE 0x02 27 | 28 | #define DUMMY_BYTE 0xFF 29 | 30 | //---- STM32F4 SPI settings ----------------------------------------------------------------------- 31 | 32 | #if defined (STM32F4) 33 | 34 | #define SPIX_ESC SPI1 35 | #define ESC_RCC_APB2PERIPH_SPIX RCC_APB2Periph_SPI1 36 | #define ESC_GPIOX_AF_SPIx GPIO_AF_SPI1 37 | 38 | 39 | #define ESC_RCC_APB1PERIPH_GPIOX_CTRL RCC_AHB1Periph_GPIOA 40 | #define ESC_GPIOX_CTRL GPIOA 41 | 42 | #define ESC_GPIO_Pin_SCK GPIO_Pin_5 43 | #define ESC_GPIO_PinSourceSCK 5 44 | 45 | #define ESC_GPIO_Pin_MISO GPIO_Pin_6 46 | #define ESC_GPIO_PinSource_MISO 6 47 | 48 | #define ESC_GPIO_Pin_MOSI GPIO_Pin_7 49 | #define ESC_GPIO_PinSource_MOSI 7 50 | 51 | #define ESC_RCC_APB1PERIPH_GPIOX_CS RCC_AHB1Periph_GPIOA 52 | #define ESC_GPIOX_CS GPIOA 53 | 54 | #define ESC_GPIO_Pin_CS GPIO_Pin_4 55 | 56 | 57 | #else 58 | #error "Architecture not supported" 59 | #endif 60 | 61 | 62 | void SPISetup(); 63 | void SPIEnd(); 64 | 65 | void SPIWriteRegisterDirect(unsigned short address, unsigned long dataOut); 66 | unsigned long SPIReadRegisterDirect(unsigned short address, unsigned char Len); 67 | 68 | void SPIWriteRegisterIndirect(unsigned long sataOut, unsigned short address, unsigned char Len); 69 | unsigned long SPIReadRegisterIndirect(unsigned short address, unsigned char Len); 70 | 71 | void SPIReadProcRamFifo(); 72 | void SPIWriteProcRamFifo(); 73 | 74 | 75 | #endif // LAN9252_SPI_H 76 | -------------------------------------------------------------------------------- /examples/EasyCAT_SPL/lib/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project specific (private) libraries. 3 | PlatformIO will compile them to static libraries and link into executable file. 4 | 5 | The source code of each library should be placed in a an own separate directory 6 | ("lib/your_library_name/[here are source files]"). 7 | 8 | For example, see a structure of the following two libraries `Foo` and `Bar`: 9 | 10 | |--lib 11 | | | 12 | | |--Bar 13 | | | |--docs 14 | | | |--examples 15 | | | |--src 16 | | | |- Bar.c 17 | | | |- Bar.h 18 | | | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html 19 | | | 20 | | |--Foo 21 | | | |- Foo.c 22 | | | |- Foo.h 23 | | | 24 | | |- README --> THIS FILE 25 | | 26 | |- platformio.ini 27 | |--src 28 | |- main.c 29 | 30 | and a contents of `src/main.c`: 31 | ``` 32 | #include 33 | #include 34 | 35 | int main (void) 36 | { 37 | ... 38 | } 39 | 40 | ``` 41 | 42 | PlatformIO Library Dependency Finder will find automatically dependent 43 | libraries scanning project source files. 44 | 45 | More information about PlatformIO Library Dependency Finder 46 | - https://docs.platformio.org/page/librarymanager/ldf.html 47 | -------------------------------------------------------------------------------- /examples/EasyCAT_SPL/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | ; default_envs = disco_f407vg 13 | default_envs = f407zg 14 | 15 | [env] 16 | platform = ststm32 ; @6.0.0 17 | framework = spl 18 | debug_tool = stlink 19 | 20 | [env:f407zg] 21 | board = f407zg 22 | build_flags = 23 | -D F407Z_ECAT_DEVKIT_HW 24 | 25 | [env:disco_f407vg] 26 | board = disco_f407vg 27 | build_flags = 28 | -D STM32DISCO_F4 29 | -------------------------------------------------------------------------------- /examples/EasyCAT_SPL/src/ECAT_App.c: -------------------------------------------------------------------------------- 1 | #include "ECAT_App.h" 2 | #include "EasyCAT.h" 3 | #include "delay.h" 4 | #include "stm32f4_discovery.h" 5 | 6 | 7 | static uint32_t previousMs = 0; 8 | 9 | 10 | void ECAT_AppSetup() 11 | { 12 | // setup LED pins 13 | for (uint8_t i = 0; i < OUTPUT_BITS_COUNT; i++) 14 | { 15 | STM_EVAL_LEDInit(outPins[i]); 16 | } 17 | 18 | if (EasyCAT_Init(ASYNC) != true) 19 | { 20 | const Led_TypeDef errorLed = LED6; 21 | // initialization failed, blink LED until reset 22 | STM_EVAL_LEDInit(errorLed); 23 | 24 | while (1) 25 | { 26 | STM_EVAL_LEDToggle(errorLed); 27 | delay_ms(1000); 28 | } 29 | } 30 | previousMs = millis(); 31 | } 32 | 33 | 34 | uint32_t ECAT_PDIcommBenchmark_us() 35 | { 36 | // benchmark start 37 | uint32_t start = micros(); 38 | 39 | // The EasyCAT cycle and the Master cycle are asynchronous 40 | EasyCAT_MainTask(); 41 | // ECAT_Application(); 42 | 43 | // benchmark stop 44 | uint32_t stop = micros(); 45 | uint32_t elapsedUs = stop - start; 46 | 47 | return elapsedUs; 48 | } 49 | 50 | 51 | //---- user application ------------------------------------------------------------------------------ 52 | 53 | #define ECAT_APP_CYCLE_TIME_MS 10 54 | 55 | void ECAT_Application () 56 | { 57 | EasyCAT_MainTask(); 58 | 59 | unsigned long nowMs = millis(); 60 | 61 | if (nowMs - previousMs >= ECAT_APP_CYCLE_TIME_MS) 62 | { 63 | previousMs = nowMs; 64 | 65 | // read slave RxPDO 66 | for (uint8_t i = 0; i < OUTPUT_BITS_COUNT; i++) 67 | { 68 | if (EasyCAT_BufferOut.Cust.Position_0x6064 & (1 << i)) 69 | { 70 | STM_EVAL_LEDOn(outPins[i]); 71 | } 72 | else { 73 | STM_EVAL_LEDOff(outPins[i]); 74 | } 75 | } 76 | 77 | // write to slave TxPDO 78 | 79 | // dummy value, so that value will be seen constantly changing by ecat master 80 | uint32_t actualPosition = EasyCAT_BufferIn.Cust.ActualPosition_0x6064 + 1; 81 | EasyCAT_BufferIn.Cust.ActualPosition_0x6064 = actualPosition; 82 | } 83 | } -------------------------------------------------------------------------------- /examples/EasyCAT_SPL/src/delay.c: -------------------------------------------------------------------------------- 1 | #include "delay.h" 2 | 3 | 4 | static uint32_t ticksPerUs = 168; // max STM32F40x freq by default 5 | 6 | volatile uint32_t timer_ms = 0; 7 | 8 | 9 | void SysTick_Handler() 10 | { 11 | timer_ms++; 12 | /* Reset tick counter */ 13 | DWT->CYCCNT = 0; 14 | } 15 | 16 | 17 | uint32_t Delay_init(void) { 18 | uint32_t c; 19 | 20 | /* Calculate ticks per us factor */ 21 | ticksPerUs = (SystemCoreClock / 1000000); 22 | 23 | /* Enable TRC */ 24 | CoreDebug->DEMCR &= ~0x01000000; 25 | CoreDebug->DEMCR |= 0x01000000; 26 | 27 | /* Enable counter */ 28 | DWT->CTRL &= ~0x00000001; 29 | DWT->CTRL |= 0x00000001; 30 | 31 | /* Reset counter */ 32 | DWT->CYCCNT = 0; 33 | 34 | /* Check if DWT has started */ 35 | c = DWT->CYCCNT; 36 | 37 | /* 2 dummys */ 38 | __ASM volatile ("NOP"); 39 | __ASM volatile ("NOP"); 40 | 41 | /* Return difference, if result is zero, DWT has not started */ 42 | return (DWT->CYCCNT - c); 43 | } 44 | 45 | 46 | uint32_t micros() 47 | { 48 | return timer_ms * 1000 + ((DWT->CYCCNT / ticksPerUs) % 1000); 49 | } 50 | 51 | 52 | uint32_t millis() 53 | { 54 | return timer_ms; 55 | } 56 | 57 | 58 | void delay_ms(int time) 59 | { 60 | uint32_t timer_end = millis() + time; 61 | while(millis() < timer_end); 62 | } 63 | -------------------------------------------------------------------------------- /examples/EasyCAT_SPL/src/main.c: -------------------------------------------------------------------------------- 1 | #ifndef HSE_VALUE 2 | /*!< Value of the External oscillator in Hz 3 | * To work, needs to be declared before SPL "stm32f4xx.h" 4 | */ 5 | #define HSE_VALUE ((uint32_t)8000000) 6 | 7 | #endif // HSE_VALUE 8 | 9 | #include "stm32f4_discovery.h" 10 | #include "stm32f4xx.h" 11 | #include "delay.h" 12 | #include "ECAT_App.h" 13 | 14 | 15 | volatile uint32_t howLongUs; 16 | 17 | int main(void) 18 | { 19 | SysTick_Config(SystemCoreClock / 1000); 20 | Delay_init(); 21 | ECAT_AppSetup(); 22 | 23 | while (1) 24 | { 25 | // ECAT_PDIcommBenchmark_us(); 26 | ECAT_Application(); 27 | } 28 | } -------------------------------------------------------------------------------- /examples/EasyCAT_SPL/test/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for PlatformIO Unit Testing and project tests. 3 | 4 | Unit Testing is a software testing method by which individual units of 5 | source code, sets of one or more MCU program modules together with associated 6 | control data, usage procedures, and operating procedures, are tested to 7 | determine whether they are fit for use. Unit testing finds problems early 8 | in the development cycle. 9 | 10 | More information about PlatformIO Unit Testing: 11 | - https://docs.platformio.org/page/plus/unit-testing.html 12 | -------------------------------------------------------------------------------- /examples/EasyCAT_arduino/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | 7 | # EasyCAT 8 | log_configuration.txt 9 | log_programmer.txt 10 | 11 | # Eclipse 12 | .metadata/ -------------------------------------------------------------------------------- /examples/EasyCAT_arduino/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "platformio.platformio-ide" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /examples/EasyCAT_arduino/README.md: -------------------------------------------------------------------------------- 1 | # EasyCAT with PlatformIO 2 | 3 | ## Using LAN9252 EtherCAT board with SPI with AVR and STM32 4 | 5 | This is EasyCAT project with PDI code (SPI reads/writes to LAN9252 ESC) separated for easier SPI drivers swap. 6 | It will work on Atmega 328 as well as on STM32F4 7 | 8 | ## MCU pinout 9 | 10 | ### ecat devkit F407ZG 11 | 12 | Devkit board uses SPI1 default pinout: 13 | 14 | | SPI1 | STM32 pin | LAN9252 | 15 | | ---- |:---------:|:-------:| 16 | | CSN | PA4 | D5 | 17 | | SCK | PA5 | D9 | 18 | | MISO | PA6 | D1/SIO1 | 19 | | MOSI | PA7 | D0/SIO0 | 20 | 21 | ### Arduino Nano 22 | 23 | | SPI | Arduino | LAN9252 | 24 | | ---- |:-------:|:-------:| 25 | | CSN | 9 | D5 | 26 | | SCK | 13 | D9 | 27 | | MISO | 12 | D1/SIO1 | 28 | | MOSI | 11 | D0/SIO0 | 29 | 30 | # Status 31 | 32 | - AVR Arduino - everything works just fine (even tho ATmega was working on 5V and LAN9252 is not 5V tolerant, 3.6V max), obviously this is not recommended - use voltage levels shifter between AVR and LAN252. 33 | - port to STM32Duino is working too 34 | 35 | # Results - benchmarks 36 | 37 | Measured is PDI communication cycle time (`EASYCAT.MainTask();`) on CiA DS402 PDOs. That is 6B each - RxPDO { uint16t; int32_t }; RxPDO { uint16t; int32_t } 38 | 39 | | ESC | SSC | MCU | SPI driver | SPI speed | value [us] | 40 | | ------- | --------- |:-------:|:----------:|:---------:|:----------:| 41 | | LAN9252 | EasyCAT | AtM328P | Arduino | 8000000 | 196 | 42 | | LAN9252 | EasyCAT | STM32F4 | Arduino | 8000000 | 210 | 43 | | LAN9252 | EasyCAT | STM32F4 | Arduino | 42000000 | 118 | 44 | | LAN9252 | EasyCAT.c | STM32F4 | Arduino | 42000000 | 107 | -------------------------------------------------------------------------------- /examples/EasyCAT_arduino/boards/f407zg.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "core": "stm32", 4 | "cpu": "cortex-m4", 5 | "extra_flags": "-DSTM32F4 -DSTM32F407xx -DSTM32F40_41xxx -DARDUINO_STM32DiscoveryF407 -DBOARD_discovery_f4", 6 | "f_cpu": "168000000L", 7 | "ldscript": "stm32f405x6.ld", 8 | "mcu": "stm32f407zgt6", 9 | "variant": "DISCO_F407VG" 10 | }, 11 | "debug": { 12 | "default_tools": [ 13 | "stlink" 14 | ], 15 | "jlink_device": "STM32F407VG", 16 | "openocd_target": "stm32f4x", 17 | "svd_path": "STM32F40x.svd" 18 | }, 19 | "frameworks": [ 20 | "arduino", 21 | "mbed", 22 | "cmsis", 23 | "spl", 24 | "libopencm3", 25 | "stm32cube" 26 | ], 27 | "name": "ST STM32F4DISCOVERY", 28 | "upload": { 29 | "maximum_ram_size": 196608, 30 | "maximum_size": 1048576, 31 | "protocol": "stlink", 32 | "protocols": [ 33 | "jlink", 34 | "stlink", 35 | "blackmagic", 36 | "mbed" 37 | ] 38 | }, 39 | "url": "http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1848/PF252419", 40 | "vendor": "ST" 41 | } 42 | -------------------------------------------------------------------------------- /examples/EasyCAT_arduino/esi/DS402_PDOs_EasyCatProject/DS402_PDOs_EasyCatProject.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/examples/EasyCAT_arduino/esi/DS402_PDOs_EasyCatProject/DS402_PDOs_EasyCatProject.bin -------------------------------------------------------------------------------- /examples/EasyCAT_arduino/esi/DS402_PDOs_EasyCatProject/DS402_PDOs_EasyCatProject.h: -------------------------------------------------------------------------------- 1 | #ifndef CUSTOM_PDO_NAME_H 2 | #define CUSTOM_PDO_NAME_H 3 | 4 | //-------------------------------------------------------------------// 5 | // // 6 | // This file has been created by the Easy Configurator tool // 7 | // // 8 | // Easy Configurator project DS402_PDOs_EasyCatProject.prj 9 | // // 10 | //-------------------------------------------------------------------// 11 | 12 | 13 | #define CUST_BYTE_NUM_OUT 6 14 | #define CUST_BYTE_NUM_IN 6 15 | #define TOT_BYTE_NUM_ROUND_OUT 8 16 | #define TOT_BYTE_NUM_ROUND_IN 8 17 | 18 | 19 | typedef union //---- output buffer ---- 20 | { 21 | uint8_t Byte [TOT_BYTE_NUM_ROUND_OUT]; 22 | struct 23 | { 24 | int32_t Position_0x607A; 25 | uint16_t ControlWord_0x6040; 26 | }Cust; 27 | } PROCBUFFER_OUT; 28 | 29 | 30 | typedef union //---- input buffer ---- 31 | { 32 | uint8_t Byte [TOT_BYTE_NUM_ROUND_IN]; 33 | struct 34 | { 35 | int32_t ActualPosition_0x6064; 36 | uint16_t StatusWord_0x6041; 37 | }Cust; 38 | } PROCBUFFER_IN; 39 | 40 | #endif -------------------------------------------------------------------------------- /examples/EasyCAT_arduino/esi/DS402_PDOs_EasyCatProject/DS402_PDOs_EasyCatProject.prj: -------------------------------------------------------------------------------- 1 | DS402_PDOs_EasyCatProject 2 | OUTPUTS_TAG 3 | Position_0x607A 4 | int32_t 5 | ControlWord_0x6040 6 | uint16_t 7 | INPUTS_TAG 8 | ActualPosition_0x6064 9 | int32_t 10 | StatusWord_0x6041 11 | uint16_t 12 | INFO_TAG 13 | 0x0000079A 14 | AB&T 15 | 0xABE00001 16 | 0x00000001 17 | DS402_PDOs 18 | END_TAG 19 | -------------------------------------------------------------------------------- /examples/EasyCAT_arduino/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /examples/EasyCAT_arduino/include/main.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAIN_H__ 2 | #define __MAIN_H__ 3 | 4 | #include 5 | 6 | #ifdef F407Z_ECAT_DEVKIT_HW 7 | 8 | const char SpiCS_Pin = PA4; 9 | 10 | const int BitOut0 = PC15; // digital output bit 0 11 | const int BitOut1 = PC14; // digital output bit 1 12 | const int BitOut2 = PC13; // digital output bit 2 13 | const int BitOut3 = PE6; // digital output bit 3 14 | const int BitOut4 = PE5; // digital output bit 4 15 | const int BitOut5 = PE4; // digital output bit 5 16 | const int BitOut6 = PE3; // digital output bit 6 17 | const int BitOut7 = PE2; // digital output bit 7 18 | 19 | #elif defined(STM32DISCO_F4) 20 | 21 | const char SpiCS_Pin = PA4; 22 | 23 | const int BitOut0 = PD13; // digital output bit 0 24 | const int BitOut1 = PD12; // digital output bit 1 25 | const int BitOut2 = PD14; // digital output bit 2 26 | const int BitOut3 = PD15; // digital output bit 3 27 | const int BitOut4 = PD11; // digital output bit 4 - dummy, no LED there 28 | const int BitOut5 = PD11; // digital output bit 5 - dummy, no LED there 29 | const int BitOut6 = PD11; // digital output bit 6 - dummy, no LED there 30 | const int BitOut7 = PD11; // digital output bit 7 - dummy, no LED there 31 | 32 | #elif defined(ARDUINO_NANO) 33 | 34 | const char SpiCS_Pin = 10; 35 | 36 | const int BitOut0 = 2; // digital output bit 0 37 | const int BitOut1 = 3; // digital output bit 1 38 | const int BitOut2 = 4; // digital output bit 2 39 | const int BitOut3 = 5; // digital output bit 3 40 | const int BitOut4 = 6; // digital output bit 4 41 | const int BitOut5 = 7; // digital output bit 5 42 | const int BitOut6 = 8; // digital output bit 6 43 | const int BitOut7 = 9; // digital output bit 7 44 | 45 | #else 46 | #error "Selected PIO env has no hardware configuration" 47 | #endif 48 | 49 | void Application(); 50 | 51 | #endif // #ifndef __MAIN_H__ -------------------------------------------------------------------------------- /examples/EasyCAT_arduino/lib/EasyCAT/DS402_PDOs_EasyCatProject.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef CUSTOM_PDO_NAME_H 4 | #define CUSTOM_PDO_NAME_H 5 | 6 | //-------------------------------------------------------------------// 7 | // // 8 | // This file has been created by the Easy Configurator tool // 9 | // // 10 | // Easy Configurator project DS402_PDOs_EasyCatProject.prj 11 | // // 12 | //-------------------------------------------------------------------// 13 | 14 | 15 | #define CUST_BYTE_NUM_OUT 6 16 | #define CUST_BYTE_NUM_IN 6 17 | #define TOT_BYTE_NUM_ROUND_OUT 8 18 | #define TOT_BYTE_NUM_ROUND_IN 8 19 | 20 | 21 | typedef union //---- output buffer ---- 22 | { 23 | uint8_t Byte [TOT_BYTE_NUM_ROUND_OUT]; 24 | struct 25 | { 26 | int32_t Position_0x6064; 27 | uint16_t ControlWord_0x6040; 28 | }Cust; 29 | } PROCBUFFER_OUT; 30 | 31 | 32 | typedef union //---- input buffer ---- 33 | { 34 | uint8_t Byte [TOT_BYTE_NUM_ROUND_IN]; 35 | struct 36 | { 37 | int32_t ActualPosition_0x6064; 38 | uint16_t StatusWord_0x6041; 39 | }Cust; 40 | } PROCBUFFER_IN; 41 | 42 | #endif -------------------------------------------------------------------------------- /examples/EasyCAT_arduino/lib/EasyCAT/LAN9252spi.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef LAN9252_SPI_H 3 | #define LAN9252_SPI_H 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #if defined(ARDUINO_ARCH_AVR) 10 | #define SpiSpeed 8000000 11 | 12 | #elif defined (STM32F4) 13 | 14 | #define SpiSpeed 42000000 15 | 16 | #else 17 | #error "Architecture not supported" 18 | #endif 19 | 20 | 21 | void SPISetup(unsigned char scsPin); 22 | void SPIEnd(); 23 | 24 | void SPIWriteRegisterDirect(unsigned short address, unsigned long dataOut); 25 | unsigned long SPIReadRegisterDirect(unsigned short address, unsigned char Len); 26 | 27 | void SPIWriteRegisterIndirect(unsigned long sataOut, unsigned short address, unsigned char Len); 28 | unsigned long SPIReadRegisterIndirect(unsigned short address, unsigned char Len); 29 | 30 | void SPIReadProcRamFifo(); 31 | void SPIWriteProcRamFifo(); 32 | 33 | //------------------------------------------------------------------------------------------------- 34 | 35 | 36 | #if defined(ARDUINO_ARCH_AVR) // -- AVR architecture (Uno - Mega) --------- 37 | 38 | inline static void SPI_TransferTx(unsigned char Data) { \ 39 | SPDR = Data; \ 40 | asm volatile("nop"); 41 | while (!(SPSR & _BV(SPIF))) ; \ 42 | }; 43 | 44 | inline static void SPI_TransferTxLast(unsigned char Data) { \ 45 | SPDR = Data; \ 46 | asm volatile("nop"); 47 | while (!(SPSR & _BV(SPIF))) ; \ 48 | }; 49 | 50 | inline static unsigned char SPI_TransferRx(unsigned char Data) { \ 51 | SPDR = Data; \ 52 | asm volatile("nop"); 53 | while (!(SPSR & _BV(SPIF))) ; \ 54 | return SPDR; }; 55 | 56 | #else //-- standard transfer for others architectures 57 | 58 | inline static void SPI_TransferTx (unsigned char Data) {SPI.transfer(Data); }; 59 | inline static void SPI_TransferTxLast (unsigned char Data) {SPI.transfer(Data); }; 60 | inline static unsigned char SPI_TransferRx (unsigned char Data) {return SPI.transfer(Data); }; 61 | 62 | #endif 63 | 64 | 65 | #endif // LAN9252_SPI_H 66 | -------------------------------------------------------------------------------- /examples/EasyCAT_arduino/lib/EasyCAT/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Datatypes (KEYWORD1) 3 | ####################################### 4 | 5 | EASYCAT KEYWORD1 6 | 7 | ####################################### 8 | # Methods and Functions (KEYWORD2) 9 | ####################################### 10 | 11 | Init KEYWORD2 12 | MainTask KEYWORD2 13 | Init KEYWORD2 14 | 15 | ####################################### 16 | # Constants (LITERAL1) 17 | ####################################### 18 | 19 | BufferOut LITERAL1 20 | BufferIn LITERAL1 21 | 22 | Cust LITERAL1 23 | CUSTOM LITERAL1 24 | NORT LITERAL1 25 | BYTE_NUM LITERAL1 26 | CUST_BYTE_NUM_IN LITERAL1 27 | CUST_BYTE_NUM_OUT LITERAL1 -------------------------------------------------------------------------------- /examples/EasyCAT_arduino/lib/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project specific (private) libraries. 3 | PlatformIO will compile them to static libraries and link into executable file. 4 | 5 | The source code of each library should be placed in a an own separate directory 6 | ("lib/your_library_name/[here are source files]"). 7 | 8 | For example, see a structure of the following two libraries `Foo` and `Bar`: 9 | 10 | |--lib 11 | | | 12 | | |--Bar 13 | | | |--docs 14 | | | |--examples 15 | | | |--src 16 | | | |- Bar.c 17 | | | |- Bar.h 18 | | | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html 19 | | | 20 | | |--Foo 21 | | | |- Foo.c 22 | | | |- Foo.h 23 | | | 24 | | |- README --> THIS FILE 25 | | 26 | |- platformio.ini 27 | |--src 28 | |- main.c 29 | 30 | and a contents of `src/main.c`: 31 | ``` 32 | #include 33 | #include 34 | 35 | int main (void) 36 | { 37 | ... 38 | } 39 | 40 | ``` 41 | 42 | PlatformIO Library Dependency Finder will find automatically dependent 43 | libraries scanning project source files. 44 | 45 | More information about PlatformIO Library Dependency Finder 46 | - https://docs.platformio.org/page/librarymanager/ldf.html 47 | -------------------------------------------------------------------------------- /examples/EasyCAT_arduino/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | default_envs = nanoatmega328 ;disco_f407vg 13 | 14 | [env:f407zg] 15 | platform = ststm32 ; @6.0.0 16 | framework = arduino ; spl 17 | board = f407zg 18 | debug_tool = stlink 19 | build_flags = 20 | -D F407Z_ECAT_DEVKIT_HW 21 | 22 | [env:disco_f407vg] 23 | platform = ststm32 24 | framework = arduino 25 | board = disco_f407vg 26 | debug_tool = stlink 27 | build_flags = 28 | -D STM32DISCO_F4 29 | 30 | [env:nanoatmega328] 31 | platform = atmelavr 32 | board = nanoatmega328 33 | framework = arduino 34 | build_flags = 35 | -D ARDUINO_NANO 36 | -------------------------------------------------------------------------------- /examples/EasyCAT_arduino/test/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for PlatformIO Unit Testing and project tests. 3 | 4 | Unit Testing is a software testing method by which individual units of 5 | source code, sets of one or more MCU program modules together with associated 6 | control data, usage procedures, and operating procedures, are tested to 7 | determine whether they are fit for use. Unit testing finds problems early 8 | in the development cycle. 9 | 10 | More information about PlatformIO Unit Testing: 11 | - https://docs.platformio.org/page/plus/unit-testing.html 12 | -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/settings.json 6 | .vscode/ipch 7 | 8 | # EasyCAT 9 | log_configuration.txt 10 | log_programmer.txt 11 | 12 | # Eclipse 13 | .metadata -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "platformio.platformio-ide" 6 | ], 7 | "unwantedRecommendations": [ 8 | "ms-vscode.cpptools-extension-pack" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/AX58100.md: -------------------------------------------------------------------------------- 1 | ## AX58100 2 | 3 | There are differences between AX58100 and ET1100 when it comes to configuration. 4 | 5 | ### As per datasheet: 6 | 7 | - SCS_FUNC: Pullup high with 4K7 resistor is required for SPI operation 8 | 9 | - Config Data: run `python3 .\patch_esi.py` to patch SDK generated `.bin` file for AX58100 10 | 11 | - Watch SCS_ESC polarity and SPI mode 12 | 13 | - NRST up 14 | 15 | ### ESC Configuration Area 16 | 17 | | Word | 0x0 | 0x1 | 0x2 | 0x3 | 0x4 | 0x5 | 0x6 | 0x7 | 18 | | Function| PDI | PDI | SYNC | Ext PDI | Conf. | Reservd | Reservd | Checksum| 19 | | Function| Control | Config | Length | Config | stat add| Reservd | Reservd | Checksum| 20 | | Reg [0x]|0140:0141|0150:0151|0982:0983|0152:0153|0012:0013| | | | |0x1C:0x1F| 21 | | Index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | 22 | | 0x00000 | 04 | 0F | 00 | 44 | 10 | 27 | 00 | F0 | 00 | 00 | 50 | 00 | 00 | 01 | EC | 00 | 23 | 24 | esi.bin can be edited directly in SDK, in structured way. 25 | 26 | ### As per Nucleo F3 demo ESI 27 | 28 | ```xml 29 | 30 | 2048 31 | 050603440a00000000001a000000 32 | 0010800000118000 33 | 34 | ``` 35 | 05 06 03 44 0A 00 00 00 00 00 1A 00 00 00 15 00 36 | 050603440A00000000001A0000001500 37 | 38 | ### As per Nucleo H7 demo ESI 39 | 40 | ```xml 41 | 42 | 2048 43 | 050E03440A00000000001A000000 44 | 0010800080108000 45 | 46 | ``` 47 | 48 | For debugging checksum validation can be disabled by checksum value of 0x88A4. Obv. not for production, and SDK doesnt like it anyway - it still throws validation error 49 | 50 | # MISC 51 | 52 | - To visually diff binary file: 53 | 54 | ```bash 55 | diff <(xxd cia402.bin) <(xxd cia402patched.bin) 56 | ``` 57 | 58 | - If slv_poll is the only thing in main(), sync manager watchdog kicks ESC right back into SAFEOP 59 | - USB cable to power ESC on Discovery adapter is required 60 | 61 | 62 | # STATUS 63 | 64 | With .bin generated by SDK and manually patched, and EVB port 0 connected to laptop: 65 | 66 | - Writing .bin to EEPROM works. After disconnecting and reboot, reading EEPROM outputs binary identical to input 67 | - EEP_DONE is high - .bin seems to be OK 68 | - After STM32 Discovery is connected, LED_ERR is low - no application error 69 | - Slave with STM32 is reaching OP. 70 | - Slave stays OP 30 min without issues 71 | - DC mode is supported with stack in mixed mode -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/LICENSE: -------------------------------------------------------------------------------- 1 | SOES Simple Open EtherCAT Slave 2 | 3 | Copyright (C) 2007-2017 Arthur Ketels 4 | Copyright (C) 2012-2017 rt-labs 5 | 6 | SOES is free software; you can redistribute it and/or modify it under 7 | the terms of the GNU General Public License version 2 as published by the Free 8 | Software Foundation. 9 | 10 | SOES is distributed in the hope that it will be useful, but WITHOUT ANY 11 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | for more details. 14 | 15 | As a special exception, if other files instantiate templates or use macros 16 | or inline functions from this file, or you compile this file and link it 17 | with other works to produce a work based on this file, this file does not 18 | by itself cause the resulting work to be covered by the GNU General Public 19 | License. However the source code for this file must still be made available 20 | in accordance with section (3) of the GNU General Public License. 21 | 22 | This exception does not invalidate any other reasons why a work based on 23 | this file might be covered by the GNU General Public License. 24 | 25 | The EtherCAT Technology, the trade name and logo "EtherCAT" are the intellectual 26 | property of, and protected by Beckhoff Automation GmbH. 27 | -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/include/ecatapp.h: -------------------------------------------------------------------------------- 1 | #ifndef __ECATAPP_H__ 2 | #define __ECATAPP_H__ 3 | 4 | 5 | // update ESCvar.ALevent by reading anything over PDI 6 | #define ESC_updateALevent() ESC_read (ESCREG_LOCALTIME, (void *) &ESCvar.Time, sizeof (ESCvar.Time)); 7 | 8 | /* application setup */ 9 | void ecatapp_init(void); 10 | 11 | /* app loop, call periodically */ 12 | void ecatapp_loop(void); 13 | 14 | 15 | #endif // __ECATAPP_H__ -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/include/pdo_override.h: -------------------------------------------------------------------------------- 1 | #ifndef __PDO_OVERRIDE_H__ 2 | #define __PDO_OVERRIDE_H__ 3 | 4 | 5 | /* DMA for SPI1 RX, TX 6 | Stream 0 is already used for ADC 7 | Stream 5 is used for sserial */ 8 | 9 | #define ESC_CMD_READ 0x02 10 | #define ESC_CMD_READ_WAIT_STATE 0x03 11 | #define ESC_CMD_WRITE 0x04 12 | 13 | #define READ_END_BYTE 0xFF 14 | 15 | #define ADDR_SIZE 2 // 2 bytes mode: addr < 3 | cmd 16 | #define WAIT_SIZE 1 // Wait State byte, single 17 | #define RX_PADDING_SIZE 8 - ADDR_SIZE - WAIT_SIZE 18 | #define TX_PADDING_SIZE 8 - ADDR_SIZE // COE_pdo(Un)pack wants buffers aligned to 64 bit grid 19 | // when address is setting, read is ALevent that it is not going to COE 20 | // so buffers are larger by offset so COE part starts on even address 21 | #define PDO_SIZE sizeof(Obj.Control_Word) + sizeof(Obj.Target_position) // SM2_sml 22 | #define PDO_TR_SIZE PDO_SIZE + ADDR_SIZE + WAIT_SIZE 23 | 24 | enum DMA_PDI_transmission_state_t { NOT_STARTED = 0, IN_PROGRESS = 1 } typedef DMA_PDI_transmission_state_t; 25 | 26 | 27 | void init_override(void); 28 | void rxpdo_override(void); 29 | void txpdo_override(void); 30 | 31 | void on_rxpdo_transfer_finished(void); 32 | void on_txpdo_transfer_finished(void); 33 | 34 | 35 | #endif // __PDO_OVERRIDE_H__ -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/lib/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project specific (private) libraries. 3 | PlatformIO will compile them to static libraries and link into executable file. 4 | 5 | The source code of each library should be placed in a an own separate directory 6 | ("lib/your_library_name/[here are source files]"). 7 | 8 | For example, see a structure of the following two libraries `Foo` and `Bar`: 9 | 10 | |--lib 11 | | | 12 | | |--Bar 13 | | | |--docs 14 | | | |--examples 15 | | | |--src 16 | | | |- Bar.c 17 | | | |- Bar.h 18 | | | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html 19 | | | 20 | | |--Foo 21 | | | |- Foo.c 22 | | | |- Foo.h 23 | | | 24 | | |- README --> THIS FILE 25 | | 26 | |- platformio.ini 27 | |--src 28 | |- main.c 29 | 30 | and a contents of `src/main.c`: 31 | ``` 32 | #include 33 | #include 34 | 35 | int main (void) 36 | { 37 | ... 38 | } 39 | 40 | ``` 41 | 42 | PlatformIO Library Dependency Finder will find automatically dependent 43 | libraries scanning project source files. 44 | 45 | More information about PlatformIO Library Dependency Finder 46 | - https://docs.platformio.org/page/librarymanager/ldf.html 47 | -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/lib/bsp/delay.c: -------------------------------------------------------------------------------- 1 | #include "delay.h" 2 | 3 | 4 | static uint32_t ticksPerUs = MAX_FREQ_TICKS_PER_US; // max STM32F40x freq by default 5 | volatile uint32_t timer_ms = 0; 6 | 7 | 8 | void SysTick_Handler() 9 | { 10 | timer_ms++; 11 | } 12 | 13 | 14 | uint32_t delay_init(void) { 15 | uint32_t c; 16 | 17 | /* Calculate ticks per us factor */ 18 | ticksPerUs = (SystemCoreClock / 1000000); 19 | 20 | /* Enable TRC */ 21 | CoreDebug->DEMCR &= ~0x01000000; 22 | CoreDebug->DEMCR |= 0x01000000; 23 | 24 | /* Enable counter */ 25 | DWT->CTRL &= ~0x00000001; 26 | DWT->CTRL |= 0x00000001; 27 | 28 | /* Reset counter */ 29 | DWT->CYCCNT = 0; 30 | 31 | /* Check if DWT has started */ 32 | c = DWT->CYCCNT; 33 | 34 | /* 2 dummys */ 35 | __ASM volatile ("NOP"); 36 | __ASM volatile ("NOP"); 37 | 38 | /* Return difference, if result is zero, DWT has not started */ 39 | return (DWT->CYCCNT - c); 40 | } 41 | 42 | 43 | uint32_t millis() 44 | { 45 | return timer_ms; 46 | } 47 | 48 | 49 | void delay_ms(int time) 50 | { 51 | uint32_t timer_end = millis() + time; 52 | while(millis() < timer_end); 53 | } 54 | 55 | 56 | void stopwatch_start(stopwatch_t * stopwatch) 57 | { 58 | stopwatch->start = DWT->CYCCNT; 59 | } 60 | 61 | 62 | uint32_t stopwatch_now_us(stopwatch_t * stopwatch) 63 | { 64 | return (DWT->CYCCNT - stopwatch->start) / ticksPerUs; 65 | } 66 | 67 | 68 | int8_t test_stopwatch() { 69 | delay_init(); 70 | stopwatch_t st01, st02; 71 | 72 | stopwatch_start(&st01); 73 | delay_ms(1); 74 | stopwatch_start(&st02); 75 | delay_ms(1); 76 | volatile uint32_t elapsed_02_us = stopwatch_now_us(&st02); 77 | delay_ms(1); 78 | volatile uint32_t elapsed_01_us = stopwatch_now_us(&st02); 79 | 80 | if (elapsed_02_us >= elapsed_01_us) 81 | { 82 | return -1; 83 | } 84 | else 85 | { 86 | return 0; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/lib/bsp/delay.h: -------------------------------------------------------------------------------- 1 | #ifndef __DELAY_H__ 2 | #define __DELAY_H__ 3 | 4 | #include "stm32f4xx.h" 5 | 6 | 7 | #define MAX_FREQ_TICKS_PER_US 168 8 | 9 | 10 | void SysTick_Handler(); 11 | 12 | 13 | uint32_t delay_init(void); 14 | void delay_ms(int time); 15 | uint32_t millis(); 16 | 17 | 18 | typedef struct stopwatch_t 19 | { 20 | uint32_t start; 21 | } stopwatch_t; 22 | 23 | 24 | // works with 1 tick resolution for up to 25.5 seconds measurements at 168 MHz 25 | void stopwatch_start(stopwatch_t *); 26 | uint32_t stopwatch_now_us(stopwatch_t *); 27 | 28 | int8_t test_stopwatch(); 29 | 30 | #endif // __DELAY_H__ 31 | -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/lib/bsp/usart.h: -------------------------------------------------------------------------------- 1 | #ifndef __USART_H__ 2 | #define __USART_H__ 3 | 4 | #include 5 | 6 | #include "stm32f4xx_conf.h" 7 | 8 | 9 | 10 | // USART6, TX - PC6 11 | #define APP_USART USART6 12 | #define APP_USART_CLK RCC_APB2Periph_USART6 13 | #define APP_USART_TX_PIN GPIO_Pin_6 14 | #define APP_USART_TX_GPIO_PORT GPIOC 15 | #define APP_USART_TX_GPIO_CLK RCC_AHB1Periph_GPIOC 16 | #define APP_USART_TX_SOURCE GPIO_PinSource6 17 | #define APP_USART_TX_AF GPIO_AF_USART6 18 | #define APP_USART_RX_PIN GPIO_Pin_7 19 | #define APP_USART_RX_GPIO_PORT GPIOC 20 | #define APP_USART_RX_GPIO_CLK RCC_AHB1Periph_GPIOC 21 | #define APP_USART_RX_SOURCE GPIO_PinSource7 22 | #define APP_USART_RX_AF GPIO_AF_USART6 23 | #define APP_USART_IRQn USART6_IRQn 24 | 25 | 26 | void APP_USART_Init(); 27 | void APP_USART_Send(char *c); 28 | char * STR5(uint32_t val); 29 | char * HEX4B(uint32_t val); 30 | char * DEC4B(uint32_t val); 31 | 32 | #endif // __USART_H__ -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/lib/soes-esi/ecat_options.h: -------------------------------------------------------------------------------- 1 | #ifndef __ECAT_OPTIONS_H__ 2 | #define __ECAT_OPTIONS_H__ 3 | 4 | #define USE_FOE 0 5 | #define USE_EOE 0 6 | 7 | #define MBXSIZE 512 8 | #define MBXSIZEBOOT 512 9 | #define MBXBUFFERS 3 10 | 11 | #define MBX0_sma 0x1000 12 | #define MBX0_sml MBXSIZE 13 | #define MBX0_sme MBX0_sma+MBX0_sml-1 14 | #define MBX0_smc 0x26 15 | #define MBX1_sma MBX0_sma+MBX0_sml 16 | #define MBX1_sml MBXSIZE 17 | #define MBX1_sme MBX1_sma+MBX1_sml-1 18 | #define MBX1_smc 0x22 19 | 20 | #define MBX0_sma_b 0x1000 21 | #define MBX0_sml_b MBXSIZEBOOT 22 | #define MBX0_sme_b MBX0_sma_b+MBX0_sml_b-1 23 | #define MBX0_smc_b 0x26 24 | #define MBX1_sma_b MBX0_sma_b+MBX0_sml_b 25 | #define MBX1_sml_b MBXSIZEBOOT 26 | #define MBX1_sme_b MBX1_sma_b+MBX1_sml_b-1 27 | #define MBX1_smc_b 0x22 28 | 29 | #define SM2_sma 0x1600 30 | #define SM2_smc 0x24 31 | #define SM2_act 1 32 | #define SM3_sma 0x1A00 33 | #define SM3_smc 0x20 34 | #define SM3_act 1 35 | 36 | #define MAX_MAPPINGS_SM2 2 37 | #define MAX_MAPPINGS_SM3 2 38 | 39 | #define MAX_RXPDO_SIZE 512 40 | #define MAX_TXPDO_SIZE 512 41 | 42 | #endif /* __ECAT_OPTIONS_H__ */ 43 | -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/lib/soes-esi/eeprom.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/examples/SOES_CIA402_AX58100/lib/soes-esi/eeprom.bin -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/lib/soes-esi/utypes.h: -------------------------------------------------------------------------------- 1 | #ifndef __UTYPES_H__ 2 | #define __UTYPES_H__ 3 | 4 | #include "cc.h" 5 | 6 | /* Object dictionary storage */ 7 | 8 | typedef struct 9 | { 10 | /* Identity */ 11 | 12 | uint32_t serial; 13 | 14 | /* Inputs */ 15 | 16 | uint16_t Status_Word; 17 | uint32_t Position_actual; 18 | 19 | /* Outputs */ 20 | 21 | uint16_t Control_Word; 22 | uint32_t Target_position; 23 | 24 | /* Parameters */ 25 | 26 | uint8_t Error_register; 27 | struct 28 | { 29 | uint32_t Local_Error_Reaction; 30 | uint32_t SyncErrorCounterLimit; 31 | } Error_Settings; 32 | struct 33 | { 34 | uint16_t Sync_mode; 35 | uint32_t CycleTime; 36 | uint32_t ShiftTime; 37 | uint16_t Sync_modes_supported; 38 | uint32_t Minimum_Cycle_Time; 39 | } Sync_Manager_2_Parameters; 40 | struct 41 | { 42 | uint16_t Sync_mode; 43 | uint32_t CycleTime; 44 | uint32_t ShiftTime; 45 | uint16_t Sync_modes_supported; 46 | uint32_t Minimum_Cycle_Time; 47 | } Sync_Manager_3_Parameters; 48 | int8_t Modes_of_operation; 49 | int8_t Mode_of_operation_display; 50 | uint32_t Supported_drive_modes; 51 | } _Objects; 52 | 53 | extern _Objects Obj; 54 | 55 | #endif /* __UTYPES_H__ */ 56 | -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/lib/soes/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # NOTE: add headers to make them show up in an IDE 3 | add_library (soes 4 | esc.c 5 | esc.h 6 | esc_coe.c 7 | esc_coe.h 8 | esc_foe.c 9 | esc_foe.h 10 | esc_eoe.c 11 | esc_eoe.h 12 | esc_eep.c 13 | esc_eep.h 14 | ecat_slv.c 15 | ecat_slv.h 16 | options.h 17 | ${HAL_SOURCES} 18 | ) 19 | 20 | include_directories(${HAL_INCLUDES}) 21 | 22 | install (TARGETS soes DESTINATION bin) 23 | install (FILES 24 | esc.h 25 | esc_coe.h 26 | esc_foe.h 27 | esc_eoe.h 28 | esc_eep.h 29 | DESTINATION include) 30 | -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/lib/soes/doc/images/esi_pdo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/examples/SOES_CIA402_AX58100/lib/soes/doc/images/esi_pdo.png -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/lib/soes/doc/images/sii_pdo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/examples/SOES_CIA402_AX58100/lib/soes/doc/images/sii_pdo.png -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/lib/soes/doc/soes.dox: -------------------------------------------------------------------------------- 1 | /** 2 | * \mainpage Simple Open EtherCAT Slave or SOES 3 | * 4 | * \section start Tutorial 5 | * For a tutorial on SOES See tutorial.txt 6 | * 7 | * \section overview Overview 8 | * SOES is an EtherCAT slave stack written in c. Its purpose is to learn and 9 | * to use. All users are invited to study the source to get an understanding 10 | * how an EtherCAT slave function 11 | * 12 | * Features as of 1.0.0 : 13 | * - Address offset based HAL for easy ESC read/write access via any interface 14 | * - Mailbox with data link layer 15 | * - CoE 16 | * - Object dictionary 17 | * - SDO read and write for all sizes including segmented transfers 18 | * - Easy portable C-code suited for embedded applications 19 | * - Fixed PDO mapping 20 | * - FoE with bootstrap template 21 | * - Support for Little and Big endian targets. 22 | * - Polling for interrupts 23 | * 24 | * \section legal Legal notice 25 | * SOES Simple Open EtherCAT Slave \n 26 | * Copyright (C) 2007-2013 Arthur Ketels \n 27 | * Copyright (C) 2012-2013 rt-labs \n 28 | * 29 | * SOES is free software; you can redistribute it and/or modify it under 30 | * the terms of the GNU General Public License version 2 as published by the Free 31 | * Software Foundation. 32 | * 33 | * SOES is distributed in the hope that it will be useful, but WITHOUT ANY 34 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or 35 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 36 | * for more details. 37 | * 38 | * As a special exception, if other files instantiate templates or use macros 39 | * or inline functions from this file, or you compile this file and link it 40 | * with other works to produce a work based on this file, this file does not 41 | * by itself cause the resulting work to be covered by the GNU General Public 42 | * License. However the source code for this file must still be made available 43 | * in accordance with section (3) of the GNU General Public License. 44 | * 45 | * This exception does not invalidate any other reasons why a work based on 46 | * this file might be covered by the GNU General Public License. 47 | * 48 | * The EtherCAT Technology, the trade name and logo "EtherCAT" are the intellectual 49 | * property of, and protected by Beckhoff Automation GmbH. 50 | */ 51 | -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/lib/soes/ecat_slv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | #ifndef __ECAT_SLV_H__ 7 | #define __ECAT_SLV_H__ 8 | 9 | #include "options.h" 10 | #include "esc.h" 11 | 12 | /** 13 | * This function is called when to get input values 14 | */ 15 | void cb_get_inputs(); 16 | 17 | /** 18 | * This function is called when to set outputs values 19 | */ 20 | void cb_set_outputs(); 21 | 22 | /** Set the watchdog count value 23 | * 24 | * @param[in] watchdogcnt = new watchdog count value 25 | */ 26 | void APP_setwatchdog (int watchdogcnt); 27 | 28 | #define DIG_PROCESS_INPUTS_FLAG 0x01 29 | #define DIG_PROCESS_OUTPUTS_FLAG 0x02 30 | #define DIG_PROCESS_WD_FLAG 0x04 31 | #define DIG_PROCESS_APP_HOOK_FLAG 0x08 32 | /** Implements the watch-dog counter to count if we should make a state change 33 | * due to missing incoming SM2 events. Updates local I/O and run the application 34 | * in the following order, call read EtherCAT outputs, execute user provided 35 | * application hook and call write EtherCAT inputs. 36 | * 37 | * @param[in] flags = User input what to execute 38 | */ 39 | void DIG_process (uint8_t flags); 40 | 41 | /** 42 | * Handler for SM change, SM0/1, AL CONTROL and EEPROM events, the application 43 | * control what interrupts that should be served and re-activated with 44 | * event mask argument 45 | * 46 | * @param[in] event_mask = Event mask for interrupts to serve and re-activate 47 | * after served 48 | */ 49 | void ecat_slv_worker (uint32_t event_mask); 50 | 51 | /** 52 | * Poll SM0/1, EEPROM and AL CONTROL events in a SM/DC synchronization 53 | * application 54 | */ 55 | void ecat_slv_poll (void); 56 | 57 | /** 58 | * Poll all events in a free-run application 59 | */ 60 | void ecat_slv (void); 61 | 62 | /** 63 | * Initialize the slave stack 64 | * 65 | * @param[in] config = User input how to configure the stack 66 | */ 67 | void ecat_slv_init (esc_cfg_t * config); 68 | 69 | #endif /* __ECAT_SLV_H__ */ 70 | -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/lib/soes/esc_eep.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | /** \file 7 | * \brief 8 | * ESI EEPROM emulator module. 9 | */ 10 | 11 | #include "cc.h" 12 | #include "esc.h" 13 | #include "esc_eep.h" 14 | 15 | #include 16 | 17 | static uint8_t eep_buf[8]; 18 | 19 | /** EPP periodic task of ESC side EEPROM emulation. 20 | * 21 | */ 22 | void EEP_process (void) 23 | { 24 | eep_stat_t stat; 25 | 26 | /* check for eeprom event */ 27 | if ((ESCvar.ALevent & ESCREG_ALEVENT_EEP) == 0) { 28 | return; 29 | } 30 | 31 | while (1) { 32 | /* read eeprom status */ 33 | ESC_read (ESCREG_EECONTSTAT, &stat, sizeof (eep_stat_t)); 34 | stat.contstat.reg = etohs(stat.contstat.reg); 35 | stat.addr = etohl(stat.addr); 36 | 37 | /* check busy flag, exit if job finished */ 38 | if (!stat.contstat.bits.busy) { 39 | return; 40 | } 41 | 42 | /* clear error bits */ 43 | stat.contstat.bits.csumErr = 0; 44 | stat.contstat.bits.eeLoading = 0; 45 | stat.contstat.bits.ackErr = 0; 46 | stat.contstat.bits.wrErr = 0; 47 | 48 | /* process commands */ 49 | switch (stat.contstat.bits.cmdReg) { 50 | case EEP_CMD_IDLE: 51 | break; 52 | 53 | case EEP_CMD_READ: 54 | case EEP_CMD_RELOAD: 55 | /* handle read request */ 56 | if (EEP_read (stat.addr * 2U /* sizeof(uint16_t) */, eep_buf, EEP_READ_SIZE) != 0) { 57 | stat.contstat.bits.ackErr = 1; 58 | } else { 59 | ESC_write (ESCREG_EEDATA, eep_buf, EEP_READ_SIZE); 60 | } 61 | break; 62 | 63 | case EEP_CMD_WRITE: 64 | /* handle write request */ 65 | ESC_read (ESCREG_EEDATA, eep_buf, EEP_WRITE_SIZE); 66 | if (EEP_write (stat.addr * 2U /* sizeof(uint16_t) */, eep_buf, EEP_WRITE_SIZE) != 0) { 67 | stat.contstat.bits.ackErr = 1; 68 | } 69 | break; 70 | 71 | default: 72 | stat.contstat.bits.ackErr = 1; 73 | } 74 | 75 | /* acknowledge command */ 76 | stat.contstat.reg = htoes(stat.contstat.reg); 77 | ESC_write (ESCREG_EECONTSTAT, &stat.contstat.reg, sizeof(uint16_t)); 78 | } 79 | } 80 | 81 | -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/lib/soes/esc_eep.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | /** \file 7 | * \brief 8 | * Headerfile for esc_eep.c 9 | */ 10 | 11 | #ifndef __esc_eep__ 12 | #define __esc_eep__ 13 | 14 | #include 15 | #include "esc.h" 16 | 17 | /* EEPROM commands */ 18 | #define EEP_CMD_IDLE 0x0 19 | #define EEP_CMD_READ 0x1 20 | #define EEP_CMD_WRITE 0x2 21 | #define EEP_CMD_RELOAD 0x4 22 | 23 | /* read/write size */ 24 | #define EEP_READ_SIZE 8 25 | #define EEP_WRITE_SIZE 2 26 | 27 | /* CONSTAT register content */ 28 | typedef struct CC_PACKED 29 | { 30 | union { 31 | uint16_t reg; 32 | struct { 33 | uint8_t wrEnable:1; 34 | uint8_t reserved:4; 35 | uint8_t eeEmulated:1; 36 | uint8_t eightByteRead:1; 37 | uint8_t twoByteAddr:1; 38 | 39 | uint8_t cmdReg:3; 40 | uint8_t csumErr:1; 41 | uint8_t eeLoading:1; 42 | uint8_t ackErr:1; 43 | uint8_t wrErr:1; 44 | uint8_t busy:1; 45 | } bits; 46 | } contstat; 47 | 48 | uint32_t addr; 49 | } eep_stat_t; 50 | 51 | /** 52 | * ECAT EEPROM configuration area data structure 53 | */ 54 | typedef union eep_config 55 | { 56 | struct 57 | { 58 | uint16_t pdi_control; 59 | uint16_t pdi_configuration; 60 | uint16_t sync_impulse_len; 61 | uint16_t pdi_configuration2; 62 | uint16_t configured_station_alias; 63 | uint8_t reserved[4]; 64 | uint16_t checksum; 65 | }; 66 | uint32_t dword[4]; /**< Four 32 bit double word equivalent to 8 16 bit configuration area word. */ 67 | }eep_config_t; 68 | 69 | /* periodic task */ 70 | void EEP_process (void); 71 | 72 | /* From hardware file */ 73 | void EEP_init (void); 74 | int8_t EEP_read (uint32_t addr, uint8_t *data, uint16_t size); 75 | int8_t EEP_write (uint32_t addr, uint8_t *data, uint16_t size); 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/lib/soes/esc_eoe.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | /** \file 7 | * \brief 8 | * Headerfile for esc_eoe.c 9 | */ 10 | 11 | #ifndef __esc_eoe__ 12 | #define __esc_eoe__ 13 | 14 | #include 15 | 16 | typedef struct eoe_pbuf 17 | { 18 | /** Pointer to frame buffer type used by a TCP/IP stack. (Not mandatory) */ 19 | void * pbuf; 20 | /** Pointer to frame buffer to send or read from */ 21 | uint8_t * payload; 22 | /** Length of data in frame buffer */ 23 | size_t len; 24 | } eoe_pbuf_t; 25 | 26 | typedef struct eoe_cfg 27 | { 28 | /** Callback function to get a frame buffer for storage of received frame */ 29 | void (*get_buffer) (eoe_pbuf_t * ebuf); 30 | /** Callback function to free a frame buffer */ 31 | void (*free_buffer) (eoe_pbuf_t * ebuf); 32 | /** Callback function to read local settings and update EtherCAT variables 33 | * to be delivered to the EtherCAT Master 34 | */ 35 | int (*load_eth_settings) (void); 36 | /** Callback function to read settings provided by the EtherCAT master 37 | * and store to local settings. 38 | */ 39 | int (*store_ethernet_settings) (void); 40 | /** Callback to frame receive function in TCP(IP stack, 41 | * caller should free the buffer 42 | * */ 43 | void (*handle_recv_buffer) (uint8_t port, eoe_pbuf_t * ebuf); 44 | /** Callback to fetch a buffer to send */ 45 | int (*fetch_send_buffer) (uint8_t port, eoe_pbuf_t * ebuf); 46 | /** Callback to notify the application fragment sent */ 47 | void (*fragment_sent_event) (void); 48 | } eoe_cfg_t; 49 | 50 | int EOE_ecat_get_mac (uint8_t port, uint8_t mac[]); 51 | int EOE_ecat_get_ip (uint8_t port, uint32_t * ip); 52 | int EOE_ecat_get_subnet (uint8_t port, uint32_t * subnet); 53 | int EOE_ecat_get_gateway (uint8_t port, uint32_t * default_gateway); 54 | int EOE_ecat_get_dns_ip (uint8_t port, uint32_t * dns_ip); 55 | int EOE_ecat_get_dns_name (uint8_t port, char * dns_name); 56 | int EOE_ecat_set_mac (uint8_t port, uint8_t mac[]); 57 | int EOE_ecat_set_ip (uint8_t port, uint32_t ip); 58 | int EOE_ecat_set_subnet (uint8_t port, uint32_t subnet); 59 | int EOE_ecat_set_gateway (uint8_t port, uint32_t default_gateway); 60 | int EOE_ecat_set_dns_ip (uint8_t port, uint32_t dns_ip); 61 | int EOE_ecat_set_dns_name (uint8_t port, char * dns_name); 62 | 63 | void EOE_config (eoe_cfg_t * cfg); 64 | void EOE_init (void); 65 | void ESC_eoeprocess (void); 66 | void ESC_eoeprocess_tx (void); 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/lib/soes/esc_foe.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | /** \file 7 | * \brief 8 | * Headerfile for esc_foe.c 9 | */ 10 | 11 | #ifndef __esc_foe__ 12 | #define __esc_foe__ 13 | 14 | #include 15 | 16 | /** Maximum number of characters allowed in a file name. */ 17 | #define FOE_FN_MAX 31 18 | 19 | typedef struct foe_file_cfg foe_file_cfg_t; 20 | struct foe_file_cfg 21 | { 22 | /** Name of file to receive from master */ 23 | const char * name; 24 | /** Size of file,sizeof data we can recv */ 25 | uint32_t max_data; 26 | /** Where to store the data initially */ 27 | uint32_t dest_start_address; 28 | /** Current address during write of file */ 29 | uint32_t address_offset; 30 | /** Calculated size of file received */ 31 | uint32_t total_size; 32 | /** FoE password */ 33 | uint32_t filepass; 34 | /** This file can be written only in BOOT state. Intended for FW files */ 35 | uint8_t write_only_in_boot; 36 | /** for feature use */ 37 | uint32_t padding:24; 38 | /** Pointer to application foe write function */ 39 | uint32_t (*write_function) (foe_file_cfg_t * self, uint8_t * data, size_t length); 40 | }; 41 | 42 | typedef struct foe_cfg 43 | { 44 | /** Allocate static in caller func to fit buffer_size */ 45 | uint8_t * fbuffer; 46 | /** Buffer size before we flush to destination */ 47 | uint32_t buffer_size; 48 | /** Number of files used in firmware update */ 49 | uint32_t n_files; 50 | /** Pointer to files configured to be used by FoE */ 51 | foe_file_cfg_t * files; 52 | } foe_cfg_t; 53 | 54 | typedef struct CC_PACKED 55 | { 56 | /** Current FoE state, ex. Waiting for ACK, Waiting for DATA */ 57 | uint8_t foestate; 58 | /** Current file buffer position, evaluated against foe file buffer size 59 | * when to flush 60 | */ 61 | uint16_t fbufposition; 62 | /** Frame number in read or write sequence */ 63 | uint32_t foepacket; 64 | /** Current position in file to be handled by FoE request */ 65 | uint32_t fposition; 66 | /** Previous position in file to be handled by FoE request */ 67 | uint32_t fprevposition; 68 | /** End position of allocated disk space for FoE requested file */ 69 | uint32_t fend; 70 | } _FOEvar; 71 | 72 | /* Initializes FoE state. */ 73 | void FOE_config (foe_cfg_t * cfg); 74 | void FOE_init (void); 75 | void ESC_foeprocess (void); 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/lib/soes/include/sys/gcc/cc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | #ifndef CC_H 7 | #define CC_H 8 | 9 | #ifdef __cplusplus 10 | extern "C" 11 | { 12 | #endif 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #ifdef __linux__ 20 | #include 21 | #else 22 | #include 23 | #endif 24 | 25 | #ifndef MIN 26 | #define MIN(a,b) (((a)<(b))?(a):(b)) 27 | #endif 28 | 29 | #ifndef MAX 30 | #define MAX(a,b) (((a)>(b))?(a):(b)) 31 | #endif 32 | 33 | #define CC_PACKED_BEGIN 34 | #define CC_PACKED_END 35 | #define CC_PACKED __attribute__((packed)) 36 | #define CC_ALIGNED(n) __attribute__((aligned (n))) 37 | 38 | #ifdef __rtk__ 39 | #include 40 | #define CC_ASSERT(exp) ASSERT (exp) 41 | #else 42 | #define CC_ASSERT(exp) assert (exp) 43 | #endif 44 | #define CC_STATIC_ASSERT(exp) _Static_assert (exp, "") 45 | 46 | #define CC_DEPRECATED __attribute__((deprecated)) 47 | 48 | #define CC_SWAP32(x) __builtin_bswap32 (x) 49 | #define CC_SWAP16(x) __builtin_bswap16 (x) 50 | 51 | #define CC_ATOMIC_SET(var,val) __atomic_store_n(&var,val,__ATOMIC_SEQ_CST) 52 | #define CC_ATOMIC_GET(var) __atomic_load_n(&var,__ATOMIC_SEQ_CST) 53 | #define CC_ATOMIC_ADD(var,val) __atomic_add_fetch(&var,val,__ATOMIC_SEQ_CST) 54 | #define CC_ATOMIC_SUB(var,val) __atomic_sub_fetch(&var,val,__ATOMIC_SEQ_CST) 55 | #define CC_ATOMIC_AND(var,val) __atomic_and_fetch(&var,val,__ATOMIC_SEQ_CST) 56 | #define CC_ATOMIC_OR(var,val) __atomic_or_fetch(&var,val,__ATOMIC_SEQ_CST) 57 | 58 | #if BYTE_ORDER == BIG_ENDIAN 59 | #define htoes(x) CC_SWAP16 ((uint16_t)(x)) 60 | #define htoel(x) CC_SWAP32 ((uint32_t)(x)) 61 | #else 62 | #define htoes(x) ((uint16_t)(x)) 63 | #define htoel(x) ((uint32_t)(x)) 64 | #endif 65 | 66 | #define etohs(x) htoes (x) 67 | #define etohl(x) htoel (x) 68 | 69 | #if BYTE_ORDER == LITTLE_ENDIAN 70 | #define EC_LITTLE_ENDIAN 71 | #else 72 | #define EC_BIG_ENDIAN 73 | #endif 74 | 75 | #ifdef ESC_DEBUG 76 | #ifdef __rtk__ 77 | #include 78 | #define DPRINT(...) rprintp ("soes: "__VA_ARGS__) 79 | #else 80 | #include 81 | #define DPRINT(...) printf ("soes: "__VA_ARGS__) 82 | #endif 83 | #else 84 | #define DPRINT(...) 85 | #endif 86 | 87 | #ifdef __cplusplus 88 | } 89 | #endif 90 | 91 | #endif /* CC_H */ 92 | -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/lib/soes_hal_bsp/cc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | #ifndef CC_H 7 | #define CC_H 8 | 9 | #ifdef __cplusplus 10 | extern "C" 11 | { 12 | #endif 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #ifdef __linux__ 20 | #include 21 | #else 22 | #include 23 | #endif 24 | 25 | #ifndef MIN 26 | #define MIN(a,b) (((a)<(b))?(a):(b)) 27 | #endif 28 | 29 | #ifndef MAX 30 | #define MAX(a,b) (((a)>(b))?(a):(b)) 31 | #endif 32 | 33 | #define CC_PACKED_BEGIN 34 | #define CC_PACKED_END 35 | #define CC_PACKED __attribute__((packed)) 36 | #define CC_ALIGNED(n) __attribute__((aligned (n))) 37 | 38 | #ifdef __rtk__ 39 | #include 40 | #define CC_ASSERT(exp) ASSERT (exp) 41 | #else 42 | #define CC_ASSERT(exp) assert (exp) 43 | #endif 44 | #define CC_STATIC_ASSERT(exp) _Static_assert (exp, "") 45 | 46 | #define CC_DEPRECATED __attribute__((deprecated)) 47 | 48 | #define CC_SWAP32(x) __builtin_bswap32 (x) 49 | #define CC_SWAP16(x) __builtin_bswap16 (x) 50 | 51 | #define CC_ATOMIC_SET(var,val) __atomic_store_n(&var,val,__ATOMIC_SEQ_CST) 52 | #define CC_ATOMIC_GET(var) __atomic_load_n(&var,__ATOMIC_SEQ_CST) 53 | #define CC_ATOMIC_ADD(var,val) __atomic_add_fetch(&var,val,__ATOMIC_SEQ_CST) 54 | #define CC_ATOMIC_SUB(var,val) __atomic_sub_fetch(&var,val,__ATOMIC_SEQ_CST) 55 | #define CC_ATOMIC_AND(var,val) __atomic_and_fetch(&var,val,__ATOMIC_SEQ_CST) 56 | #define CC_ATOMIC_OR(var,val) __atomic_or_fetch(&var,val,__ATOMIC_SEQ_CST) 57 | 58 | #if BYTE_ORDER == BIG_ENDIAN 59 | #define htoes(x) CC_SWAP16 ((uint16_t)(x)) 60 | #define htoel(x) CC_SWAP32 ((uint32_t)(x)) 61 | #else 62 | #define htoes(x) ((uint16_t)(x)) 63 | #define htoel(x) ((uint32_t)(x)) 64 | #endif 65 | 66 | #define etohs(x) htoes (x) 67 | #define etohl(x) htoel (x) 68 | 69 | #if BYTE_ORDER == LITTLE_ENDIAN 70 | #define EC_LITTLE_ENDIAN 71 | #else 72 | #define EC_BIG_ENDIAN 73 | #endif 74 | 75 | #ifdef ESC_DEBUG 76 | #ifdef __rtk__ 77 | #include 78 | #define DPRINT(...) rprintp ("soes: "__VA_ARGS__) 79 | #else 80 | #include 81 | #define DPRINT(...) printf ("soes: "__VA_ARGS__) 82 | #endif 83 | #else 84 | #define DPRINT(...) 85 | #endif 86 | 87 | #ifdef __cplusplus 88 | } 89 | #endif 90 | 91 | #endif /* CC_H */ 92 | -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/lib/soes_hal_bsp/esc_irq.h: -------------------------------------------------------------------------------- 1 | #ifndef __ESC_IRQ_H__ 2 | #define __ESC_IRQ_H__ 3 | 4 | #include 5 | 6 | 7 | void ESC_interrupt_enable (uint32_t mask); 8 | void ESC_interrupt_disable (uint32_t mask); 9 | 10 | void EXTILine1_Config (void); 11 | void EXTILine3_Config (void); 12 | 13 | void EXTILine1_Disable (void); 14 | void EXTILine3_Disable (void); 15 | 16 | // Returns SYNC0 cycle time 17 | uint32_t ESC_enable_DC (void); 18 | 19 | #endif // __ESC_IRQ_H__ -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/lib/soes_hal_bsp/rst.c: -------------------------------------------------------------------------------- 1 | #include "rst.h" 2 | 3 | 4 | void rst_setup(void) 5 | { 6 | /* Setup NRST as GPIO out and pull it high */ 7 | GPIO_InitTypeDef gpio; 8 | 9 | RCC_AHB1PeriphClockCmd(ESC_RCC_APB1PERIPH_GPIOX_RSTN, ENABLE); 10 | 11 | gpio.GPIO_Pin = ESC_GPIO_Pin_RSTN; 12 | gpio.GPIO_Mode = GPIO_Mode_OUT; 13 | gpio.GPIO_Speed = GPIO_Speed_50MHz; 14 | gpio.GPIO_OType = GPIO_OType_PP; 15 | gpio.GPIO_PuPd = GPIO_PuPd_UP; 16 | GPIO_Init(ESC_GPIOX_RSTN, &gpio); 17 | 18 | rst_high(); 19 | } 20 | 21 | void rst_low(void) 22 | { /* Set RSTN line low */ 23 | GPIO_ResetBits(ESC_GPIOX_RSTN, ESC_GPIO_Pin_RSTN); 24 | } 25 | 26 | void rst_high(void) 27 | { 28 | /* Set RSTN line high */ 29 | GPIO_SetBits(ESC_GPIOX_RSTN, ESC_GPIO_Pin_RSTN); 30 | } 31 | 32 | void rst_check_start(void) 33 | { 34 | /* Setup NRST as GPIO input and pull it high */ 35 | GPIO_InitTypeDef gpio; 36 | 37 | RCC_AHB1PeriphClockCmd(ESC_RCC_APB1PERIPH_GPIOX_RSTN, ENABLE); 38 | 39 | gpio.GPIO_Pin = ESC_GPIO_Pin_RSTN; 40 | gpio.GPIO_Mode = GPIO_Mode_IN; 41 | gpio.GPIO_Speed = GPIO_Speed_50MHz; 42 | gpio.GPIO_PuPd = GPIO_PuPd_NOPULL; 43 | GPIO_Init(ESC_GPIOX_RSTN, &gpio); 44 | } 45 | 46 | uint8_t is_esc_reset(void) 47 | { 48 | /* Check if ESC pulled RSTN line up */ 49 | return GPIO_ReadInputDataBit(ESC_GPIOX_RSTN, ESC_GPIO_Pin_RSTN) == Bit_SET; 50 | } 51 | 52 | -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/lib/soes_hal_bsp/rst.h: -------------------------------------------------------------------------------- 1 | #ifndef __HAL_NRST_H__ 2 | #define __HAL_NRST_H__ 3 | 4 | #include 5 | #include "stm32f4xx_conf.h" 6 | 7 | #define ESC_RCC_APB1PERIPH_GPIOX_RSTN RCC_AHB1Periph_GPIOA 8 | #define ESC_GPIOX_RSTN GPIOA 9 | #define ESC_GPIO_Pin_RSTN GPIO_Pin_2 10 | 11 | 12 | void rst_setup(void); 13 | void rst_low(void); 14 | void rst_high(void); 15 | 16 | void rst_check_start(void); 17 | uint8_t is_esc_reset(void); 18 | 19 | #endif /* __HAL_NRST_H__ */ 20 | -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/lib/soes_hal_bsp/spi.h: -------------------------------------------------------------------------------- 1 | #ifndef SRC_APP_SPI_H_ 2 | #define SRC_APP_SPI_H_ 3 | 4 | #include 5 | #include "stm32f4xx_conf.h" 6 | 7 | 8 | #define SCS_LOW 0 9 | #define SCS_HIGH 1 10 | 11 | #if defined (STM32F4) 12 | 13 | #define SPIX_ESC SPI1 14 | #define ESC_RCC_APB2PERIPH_SPIX RCC_APB2Periph_SPI1 15 | #define ESC_GPIOX_AF_SPIx GPIO_AF_SPI1 16 | 17 | #define ESC_RCC_APB1PERIPH_GPIOX_CTRL RCC_AHB1Periph_GPIOA 18 | #define ESC_GPIOX_CTRL GPIOA 19 | 20 | #define ESC_GPIO_Pin_SCK GPIO_Pin_5 21 | #define ESC_GPIO_PinSourceSCK GPIO_PinSource5 22 | 23 | #define ESC_GPIO_Pin_MISO GPIO_Pin_6 24 | #define ESC_GPIO_PinSource_MISO GPIO_PinSource6 25 | 26 | #define ESC_GPIO_Pin_MOSI GPIO_Pin_7 27 | #define ESC_GPIO_PinSource_MOSI GPIO_PinSource7 28 | 29 | #define ESC_RCC_APB1PERIPH_GPIOX_CS RCC_AHB1Periph_GPIOA 30 | #define ESC_GPIOX_CS GPIOA 31 | #define ESC_GPIO_Pin_CS GPIO_Pin_4 32 | 33 | #else 34 | #error "Platform not supported" 35 | #endif 36 | 37 | #if defined (LAN9252) 38 | #define SPIX_ESC_SCS SPI_NSS_Soft 39 | #define SCS_ACTIVE_POLARITY SCS_LOW 40 | // Mode 0 per EasyCAT Arduino code 41 | #define SPIX_ESC_CPOL SPI_CPOL_Low 42 | #define SPIX_ESC_CPHA SPI_CPHA_1Edge 43 | #elif defined (AX58100) 44 | #define SPIX_ESC_SCS SPI_NSS_Soft 45 | #define SCS_ACTIVE_POLARITY SCS_LOW 46 | // Mode 0 per SDK settings 47 | #define SPIX_ESC_CPOL SPI_CPOL_Low 48 | #define SPIX_ESC_CPHA SPI_CPHA_1Edge 49 | #else 50 | #error "No supported ESC specified" 51 | #endif 52 | 53 | 54 | #define DUMMY_BYTE 0xFF 55 | #define tout 5000 56 | 57 | void spi_setup(void); 58 | void spi_select (int8_t board); 59 | void spi_unselect (int8_t board); 60 | void spi_write (int8_t board, uint8_t *data, uint8_t size); 61 | void spi_read (int8_t board, uint8_t *result, uint8_t size); 62 | void spi_bidirectionally_transfer (int8_t board, uint8_t *result, uint8_t *data, uint8_t size); 63 | 64 | 65 | #endif /* SRC_APP_SPI_H_ */ 66 | -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [env:disco_f4] 12 | platform = ststm32@6.0.0 13 | framework = spl 14 | debug_tool = stlink 15 | board = disco_f407vg 16 | 17 | build_flags = 18 | -D HSE_VALUE=8000000U 19 | -D AX58100 20 | 21 | monitor_speed = 115200 -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/src/main.c: -------------------------------------------------------------------------------- 1 | #include "stm32f4xx.h" 2 | #include "stm32f4_discovery.h" 3 | #include "delay.h" 4 | #include "usart.h" 5 | 6 | #include "esc.h" 7 | #include "ecat_slv.h" 8 | #include "ecatapp.h" 9 | 10 | 11 | // uint32_t ecatapp_benchmark_us(void); 12 | 13 | 14 | int main(void) 15 | { 16 | SysTick_Config(SystemCoreClock / 1000); 17 | APP_USART_Init(); 18 | delay_init(); 19 | STM_EVAL_PBInit(BUTTON_MODE_GPIO); 20 | printf("\r\n[ESC Setup] %s \r\n", "Strted"); 21 | ecatapp_init(); 22 | printf("\r\n[ESC Setup] Done, ready \r\n\n"); 23 | 24 | 25 | while (1) 26 | { 27 | // ecatapp_benchmark_us(); 28 | ecatapp_loop(); 29 | } 30 | } 31 | 32 | // uint32_t ecatapp_benchmark_us() 33 | // { 34 | // // benchmark start 35 | // stopwatch_t st; 36 | // stopwatch_start(&st); 37 | 38 | // ecatapp_loop(); 39 | 40 | // // benchmark stop 41 | // volatile uint32_t elapsed_us = stopwatch_now_us(&st); 42 | // static volatile uint32_t hiscore = 0; 43 | 44 | // if (elapsed_us > hiscore) 45 | // { 46 | // hiscore = elapsed_us; 47 | // } 48 | 49 | // if (STM_EVAL_IsPressed()) 50 | // { 51 | // printf("PDI irq = %s \r\n", HEX4B(pdi_irq_flag)); 52 | // } 53 | 54 | // return elapsed_us; 55 | // } 56 | -------------------------------------------------------------------------------- /examples/SOES_CIA402_AX58100/test/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for PlatformIO Unit Testing and project tests. 3 | 4 | Unit Testing is a software testing method by which individual units of 5 | source code, sets of one or more MCU program modules together with associated 6 | control data, usage procedures, and operating procedures, are tested to 7 | determine whether they are fit for use. Unit testing finds problems early 8 | in the development cycle. 9 | 10 | More information about PlatformIO Unit Testing: 11 | - https://docs.platformio.org/page/plus/unit-testing.html 12 | -------------------------------------------------------------------------------- /examples/SOES_LAN9252/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/settings.json 6 | .vscode/ipch 7 | 8 | # EasyCAT 9 | log_configuration.txt 10 | log_programmer.txt 11 | 12 | # Eclipse 13 | .metadata -------------------------------------------------------------------------------- /examples/SOES_LAN9252/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "platformio.platformio-ide" 6 | ], 7 | "unwantedRecommendations": [ 8 | "ms-vscode.cpptools-extension-pack" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /examples/SOES_LAN9252/Benchmarks.md: -------------------------------------------------------------------------------- 1 | # What is measured 2 | 3 | Polled `ecat_slv()`, results are spewn on serial port. No interrupts, should be more deterministic and consistent 4 | 5 | STM32F407 at 168 MHz, SPI1 at 42 MHz 6 | 7 | # LAN9252 8 | 9 | - Cables connected, ECAT master not connected: `[ESC benchmark] 0028 us (028 top)` 10 | - ECAT master connected, slv in OP: `[ESC benchmark] 0072 us (0280 top)` -------------------------------------------------------------------------------- /examples/SOES_LAN9252/LICENSE: -------------------------------------------------------------------------------- 1 | SOES Simple Open EtherCAT Slave 2 | 3 | Copyright (C) 2007-2017 Arthur Ketels 4 | Copyright (C) 2012-2017 rt-labs 5 | 6 | SOES is free software; you can redistribute it and/or modify it under 7 | the terms of the GNU General Public License version 2 as published by the Free 8 | Software Foundation. 9 | 10 | SOES is distributed in the hope that it will be useful, but WITHOUT ANY 11 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | for more details. 14 | 15 | As a special exception, if other files instantiate templates or use macros 16 | or inline functions from this file, or you compile this file and link it 17 | with other works to produce a work based on this file, this file does not 18 | by itself cause the resulting work to be covered by the GNU General Public 19 | License. However the source code for this file must still be made available 20 | in accordance with section (3) of the GNU General Public License. 21 | 22 | This exception does not invalidate any other reasons why a work based on 23 | this file might be covered by the GNU General Public License. 24 | 25 | The EtherCAT Technology, the trade name and logo "EtherCAT" are the intellectual 26 | property of, and protected by Beckhoff Automation GmbH. 27 | -------------------------------------------------------------------------------- /examples/SOES_LAN9252/README.md: -------------------------------------------------------------------------------- 1 | # SOES on STM32 2 | 3 | This is example project using SOES with LAN9252 and STM32F4 4 | 5 | ## LAN9252 EtherCAT board with STM32F4 over SPI 6 | 7 | ## MCU pinout 8 | 9 | Discovery F407 adapter pinout 10 | 11 | | SPI1 | STM32 pin | LAN9252 | 12 | | ---- |:---------:|:-------:| 13 | | * | PD0/PD1 | D5 | 14 | | SCK | PB3 | D5 | 15 | | MISO | PB4 | D9 | 16 | | MOSI | PB5 | D1/SIO1 | 17 | 18 | STMBL is using SPI1 alternative functions. Hardware CS is not exposed, you can use PD0, PD1 (CAN_RX, CAN_TX) for that 19 | 20 | # Benchmarks 21 | 22 | What is measured: polled `ecat_slv()`, results are spewn on serial port. No interrupts, should be more deterministic and consistent. STM32F407 at 168 MHz, SPI1 at 42 MHz 23 | 24 | - Cables connected, ECAT master not connected: `[ESC benchmark] 0028 us (028 top)` 25 | - ECAT master connected, slv in OP: `[ESC benchmark] 0072 us (0280 top)` 26 | -------------------------------------------------------------------------------- /examples/SOES_LAN9252/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /examples/SOES_LAN9252/lib/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project specific (private) libraries. 3 | PlatformIO will compile them to static libraries and link into executable file. 4 | 5 | The source code of each library should be placed in a an own separate directory 6 | ("lib/your_library_name/[here are source files]"). 7 | 8 | For example, see a structure of the following two libraries `Foo` and `Bar`: 9 | 10 | |--lib 11 | | | 12 | | |--Bar 13 | | | |--docs 14 | | | |--examples 15 | | | |--src 16 | | | |- Bar.c 17 | | | |- Bar.h 18 | | | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html 19 | | | 20 | | |--Foo 21 | | | |- Foo.c 22 | | | |- Foo.h 23 | | | 24 | | |- README --> THIS FILE 25 | | 26 | |- platformio.ini 27 | |--src 28 | |- main.c 29 | 30 | and a contents of `src/main.c`: 31 | ``` 32 | #include 33 | #include 34 | 35 | int main (void) 36 | { 37 | ... 38 | } 39 | 40 | ``` 41 | 42 | PlatformIO Library Dependency Finder will find automatically dependent 43 | libraries scanning project source files. 44 | 45 | More information about PlatformIO Library Dependency Finder 46 | - https://docs.platformio.org/page/librarymanager/ldf.html 47 | -------------------------------------------------------------------------------- /examples/SOES_LAN9252/lib/bsp/delay.c: -------------------------------------------------------------------------------- 1 | #include "delay.h" 2 | 3 | 4 | static uint32_t ticksPerUs = MAX_FREQ_TICKS_PER_US; // max STM32F40x freq by default 5 | volatile uint32_t timer_ms = 0; 6 | 7 | 8 | void SysTick_Handler() 9 | { 10 | timer_ms++; 11 | } 12 | 13 | 14 | uint32_t delay_init(void) { 15 | uint32_t c; 16 | 17 | /* Calculate ticks per us factor */ 18 | ticksPerUs = (SystemCoreClock / 1000000); 19 | 20 | /* Enable TRC */ 21 | CoreDebug->DEMCR &= ~0x01000000; 22 | CoreDebug->DEMCR |= 0x01000000; 23 | 24 | /* Enable counter */ 25 | DWT->CTRL &= ~0x00000001; 26 | DWT->CTRL |= 0x00000001; 27 | 28 | /* Reset counter */ 29 | DWT->CYCCNT = 0; 30 | 31 | /* Check if DWT has started */ 32 | c = DWT->CYCCNT; 33 | 34 | /* 2 dummys */ 35 | __ASM volatile ("NOP"); 36 | __ASM volatile ("NOP"); 37 | 38 | /* Return difference, if result is zero, DWT has not started */ 39 | return (DWT->CYCCNT - c); 40 | } 41 | 42 | 43 | uint32_t millis() 44 | { 45 | return timer_ms; 46 | } 47 | 48 | 49 | void delay_ms(int time) 50 | { 51 | uint32_t timer_end = millis() + time; 52 | while(millis() < timer_end); 53 | } 54 | 55 | 56 | void stopwatch_start(stopwatch_t * stopwatch) 57 | { 58 | stopwatch->start = DWT->CYCCNT; 59 | } 60 | 61 | 62 | uint32_t stopwatch_now_us(stopwatch_t * stopwatch) 63 | { 64 | return (DWT->CYCCNT - stopwatch->start) / ticksPerUs; 65 | } 66 | 67 | 68 | int8_t test_stopwatch() { 69 | delay_init(); 70 | stopwatch_t st01, st02; 71 | 72 | stopwatch_start(&st01); 73 | delay_ms(1); 74 | stopwatch_start(&st02); 75 | delay_ms(1); 76 | volatile uint32_t elapsed_02_us = stopwatch_now_us(&st02); 77 | delay_ms(1); 78 | volatile uint32_t elapsed_01_us = stopwatch_now_us(&st02); 79 | 80 | if (elapsed_02_us >= elapsed_01_us) 81 | { 82 | return -1; 83 | } 84 | else 85 | { 86 | return 0; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /examples/SOES_LAN9252/lib/bsp/delay.h: -------------------------------------------------------------------------------- 1 | #ifndef __DELAY_H__ 2 | #define __DELAY_H__ 3 | 4 | #include "stm32f4xx.h" 5 | 6 | 7 | #define MAX_FREQ_TICKS_PER_US 168 8 | 9 | 10 | void SysTick_Handler(); 11 | 12 | 13 | uint32_t delay_init(void); 14 | void delay_ms(int time); 15 | uint32_t millis(); 16 | 17 | 18 | typedef struct stopwatch_t 19 | { 20 | uint32_t start; 21 | } stopwatch_t; 22 | 23 | 24 | // works with 1 tick resolution for up to 25.5 seconds measurements at 168 MHz 25 | void stopwatch_start(stopwatch_t *); 26 | uint32_t stopwatch_now_us(stopwatch_t *); 27 | 28 | int8_t test_stopwatch(); 29 | 30 | #endif // __DELAY_H__ 31 | -------------------------------------------------------------------------------- /examples/SOES_LAN9252/lib/bsp/usart.h: -------------------------------------------------------------------------------- 1 | #ifndef __USART_H__ 2 | #define __USART_H__ 3 | 4 | #include 5 | 6 | #include "stm32f4xx_conf.h" 7 | 8 | 9 | 10 | // USART6, TX - PC6 11 | #define APP_USART USART6 12 | #define APP_USART_CLK RCC_APB2Periph_USART6 13 | #define APP_USART_TX_PIN GPIO_Pin_6 14 | #define APP_USART_TX_GPIO_PORT GPIOC 15 | #define APP_USART_TX_GPIO_CLK RCC_AHB1Periph_GPIOC 16 | #define APP_USART_TX_SOURCE GPIO_PinSource6 17 | #define APP_USART_TX_AF GPIO_AF_USART6 18 | #define APP_USART_RX_PIN GPIO_Pin_7 19 | #define APP_USART_RX_GPIO_PORT GPIOC 20 | #define APP_USART_RX_GPIO_CLK RCC_AHB1Periph_GPIOC 21 | #define APP_USART_RX_SOURCE GPIO_PinSource7 22 | #define APP_USART_RX_AF GPIO_AF_USART6 23 | #define APP_USART_IRQn USART6_IRQn 24 | 25 | 26 | void APP_USART_Init(); 27 | void APP_USART_Send(char *c); 28 | char * STR5(uint32_t val); 29 | 30 | #endif // __USART_H__ -------------------------------------------------------------------------------- /examples/SOES_LAN9252/lib/soes-esi/cc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | #ifndef CC_H 7 | #define CC_H 8 | 9 | #ifdef __cplusplus 10 | extern "C" 11 | { 12 | #endif 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #ifdef __linux__ 19 | #include 20 | #else 21 | #include 22 | #endif 23 | 24 | #ifndef MIN 25 | #define MIN(a,b) (((a)<(b))?(a):(b)) 26 | #endif 27 | 28 | #ifndef MAX 29 | #define MAX(a,b) (((a)>(b))?(a):(b)) 30 | #endif 31 | 32 | #define CC_PACKED_BEGIN 33 | #define CC_PACKED_END 34 | #define CC_PACKED __attribute__((packed)) 35 | 36 | #ifdef __rtk__ 37 | #define CC_ASSERT(exp) ASSERT (exp) 38 | #else 39 | #define CC_ASSERT(exp) assert (exp) 40 | #endif 41 | #define CC_STATIC_ASSERT(exp) _Static_assert (exp, "") 42 | 43 | #define CC_DEPRECATED __attribute__((deprecated)) 44 | 45 | #define CC_SWAP32(x) __builtin_bswap32 (x) 46 | #define CC_SWAP16(x) __builtin_bswap16 (x) 47 | 48 | #define CC_ATOMIC_SET(var,val) __atomic_store_n(&var,val,__ATOMIC_SEQ_CST) 49 | #define CC_ATOMIC_GET(var) __atomic_load_n(&var,__ATOMIC_SEQ_CST) 50 | #define CC_ATOMIC_ADD(var,val) __atomic_add_fetch(&var,val,__ATOMIC_SEQ_CST) 51 | #define CC_ATOMIC_SUB(var,val) __atomic_sub_fetch(&var,val,__ATOMIC_SEQ_CST) 52 | #define CC_ATOMIC_AND(var,val) __atomic_and_fetch(&var,val,__ATOMIC_SEQ_CST) 53 | #define CC_ATOMIC_OR(var,val) __atomic_or_fetch(&var,val,__ATOMIC_SEQ_CST) 54 | 55 | #if BYTE_ORDER == BIG_ENDIAN 56 | #define htoes(x) CC_SWAP16 (x) 57 | #define htoel(x) CC_SWAP32 (x) 58 | #else 59 | #define htoes(x) (x) 60 | #define htoel(x) (x) 61 | #endif 62 | 63 | #define etohs(x) htoes (x) 64 | #define etohl(x) htoel (x) 65 | 66 | #if BYTE_ORDER == LITTLE_ENDIAN 67 | #define EC_LITTLE_ENDIAN 68 | #else 69 | #define EC_BIG_ENDIAN 70 | #endif 71 | 72 | #ifdef ESC_DEBUG 73 | #ifdef __rtk__ 74 | #include 75 | #define DPRINT(...) rprintp ("soes: "__VA_ARGS__) 76 | #else 77 | #include 78 | #define DPRINT(...) printf ("soes: "__VA_ARGS__) 79 | #endif 80 | #else 81 | #define DPRINT(...) 82 | #endif 83 | 84 | #ifdef __cplusplus 85 | } 86 | #endif 87 | 88 | #endif /* CC_H */ 89 | -------------------------------------------------------------------------------- /examples/SOES_LAN9252/lib/soes-esi/ecat_options.h: -------------------------------------------------------------------------------- 1 | #ifndef __ECAT_OPTIONS_H__ 2 | #define __ECAT_OPTIONS_H__ 3 | 4 | #define USE_FOE 0 5 | #define USE_EOE 0 6 | 7 | #define MBXSIZE 512 8 | #define MBXSIZEBOOT 512 9 | #define MBXBUFFERS 3 10 | 11 | #define MBX0_sma 0x1000 12 | #define MBX0_sml MBXSIZE 13 | #define MBX0_sme MBX0_sma+MBX0_sml-1 14 | #define MBX0_smc 0x26 15 | #define MBX1_sma MBX0_sma+MBX0_sml 16 | #define MBX1_sml MBXSIZE 17 | #define MBX1_sme MBX1_sma+MBX1_sml-1 18 | #define MBX1_smc 0x22 19 | 20 | #define MBX0_sma_b 0x1000 21 | #define MBX0_sml_b MBXSIZEBOOT 22 | #define MBX0_sme_b MBX0_sma_b+MBX0_sml_b-1 23 | #define MBX0_smc_b 0x26 24 | #define MBX1_sma_b MBX0_sma_b+MBX0_sml_b 25 | #define MBX1_sml_b MBXSIZEBOOT 26 | #define MBX1_sme_b MBX1_sma_b+MBX1_sml_b-1 27 | #define MBX1_smc_b 0x22 28 | 29 | #define SM2_sma 0x1600 30 | #define SM2_smc 0x24 31 | #define SM2_act 1 32 | #define SM3_sma 0x1A00 33 | #define SM3_smc 0x20 34 | #define SM3_act 1 35 | 36 | #define MAX_MAPPINGS_SM2 2 37 | #define MAX_MAPPINGS_SM3 5 38 | 39 | #define MAX_RXPDO_SIZE 512 40 | #define MAX_TXPDO_SIZE 512 41 | 42 | #endif /* __ECAT_OPTIONS_H__ */ 43 | -------------------------------------------------------------------------------- /examples/SOES_LAN9252/lib/soes-esi/eeprom.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/examples/SOES_LAN9252/lib/soes-esi/eeprom.bin -------------------------------------------------------------------------------- /examples/SOES_LAN9252/lib/soes-esi/esi.json: -------------------------------------------------------------------------------- 1 | { 2 | "form": { 3 | "VendorName": "Unspecified", 4 | "VendorID": "0x000", 5 | "ProductCode": "0x00ab123", 6 | "ProfileNo": "5001", 7 | "RevisionNumber": "0x001", 8 | "SerialNumber": "0x001", 9 | "HWversion": "0.0.1", 10 | "SWversion": "0.0.1", 11 | "EEPROMsize": "2048", 12 | "RxMailboxOffset": "0x1000", 13 | "TxMailboxOffset": "0x1200", 14 | "MailboxSize": "512", 15 | "SM2Offset": "0x1600", 16 | "SM3Offset": "0x1A00", 17 | "TextGroupType": "DigIn", 18 | "TextGroupName5": "Digital input/output", 19 | "ImageName": "IMGCBY", 20 | "TextDeviceType": "IODemoApp", 21 | "TextDeviceName": "LAN9252 SPI demo", 22 | "Port0Physical": "Y", 23 | "Port1Physical": "Y", 24 | "Port2Physical": " ", 25 | "Port3Physical": " ", 26 | "ESC": "LAN9252", 27 | "SPImode": "0", 28 | "CoeDetailsEnableSDO": "EnableSDO", 29 | "CoeDetailsEnableSDOInfo": "EnableSDOInfo", 30 | "CoeDetailsEnablePDOAssign": "EnablePDOAssign", 31 | "CoeDetailsEnablePDOConfiguration": "EnablePDOConfiguration", 32 | "CoeDetailsEnableUploadAtStartup": "EnableUploadAtStartup", 33 | "CoeDetailsEnableSDOCompleteAccess": "EnableSDOCompleteAccess" 34 | }, 35 | "od": { 36 | "sdo": {}, 37 | "txpdo": { 38 | "6000": { 39 | "otype": "VAR", 40 | "name": "Key1", 41 | "access": "RO", 42 | "pdo_mappings": [ 43 | "txpdo" 44 | ], 45 | "dtype": "BOOLEAN", 46 | "value": "0", 47 | "data": "&Obj.Key1" 48 | }, 49 | "6001": { 50 | "otype": "VAR", 51 | "name": "Key2", 52 | "access": "RO", 53 | "pdo_mappings": [ 54 | "txpdo" 55 | ], 56 | "dtype": "BOOLEAN", 57 | "value": "0", 58 | "data": "&Obj.Key2" 59 | }, 60 | "6002": { 61 | "otype": "VAR", 62 | "name": "Counter", 63 | "access": "RO", 64 | "pdo_mappings": [ 65 | "txpdo" 66 | ], 67 | "dtype": "UNSIGNED32", 68 | "value": "0", 69 | "data": "&Obj.Counter" 70 | } 71 | }, 72 | "rxpdo": { 73 | "7000": { 74 | "otype": "VAR", 75 | "name": "LedIn", 76 | "access": "RO", 77 | "pdo_mappings": [ 78 | "rxpdo" 79 | ], 80 | "dtype": "BOOLEAN", 81 | "value": "0", 82 | "data": "&Obj.LedIn" 83 | } 84 | } 85 | }, 86 | "dc": [] 87 | } -------------------------------------------------------------------------------- /examples/SOES_LAN9252/lib/soes-esi/utypes.h: -------------------------------------------------------------------------------- 1 | #ifndef __UTYPES_H__ 2 | #define __UTYPES_H__ 3 | 4 | #include "cc.h" 5 | 6 | /* Object dictionary storage */ 7 | 8 | typedef struct 9 | { 10 | /* Identity */ 11 | 12 | uint32_t serial; 13 | 14 | /* Inputs */ 15 | 16 | uint8_t Key1; 17 | uint8_t Key2; 18 | uint32_t Counter; 19 | 20 | /* Outputs */ 21 | 22 | uint8_t LedIn; 23 | 24 | } _Objects; 25 | 26 | extern _Objects Obj; 27 | 28 | #endif /* __UTYPES_H__ */ 29 | -------------------------------------------------------------------------------- /examples/SOES_LAN9252/lib/soes/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # NOTE: add headers to make them show up in an IDE 3 | add_library (soes 4 | esc.c 5 | esc.h 6 | esc_coe.c 7 | esc_coe.h 8 | esc_foe.c 9 | esc_foe.h 10 | esc_eoe.c 11 | esc_eoe.h 12 | esc_eep.c 13 | esc_eep.h 14 | ecat_slv.c 15 | ecat_slv.h 16 | options.h 17 | ${HAL_SOURCES} 18 | ) 19 | 20 | include_directories(${HAL_INCLUDES}) 21 | 22 | install (TARGETS soes DESTINATION bin) 23 | install (FILES 24 | esc.h 25 | esc_coe.h 26 | esc_foe.h 27 | esc_eoe.h 28 | esc_eep.h 29 | DESTINATION include) 30 | -------------------------------------------------------------------------------- /examples/SOES_LAN9252/lib/soes/doc/images/esi_pdo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/examples/SOES_LAN9252/lib/soes/doc/images/esi_pdo.png -------------------------------------------------------------------------------- /examples/SOES_LAN9252/lib/soes/doc/images/sii_pdo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/examples/SOES_LAN9252/lib/soes/doc/images/sii_pdo.png -------------------------------------------------------------------------------- /examples/SOES_LAN9252/lib/soes/doc/soes.dox: -------------------------------------------------------------------------------- 1 | /** 2 | * \mainpage Simple Open EtherCAT Slave or SOES 3 | * 4 | * \section start Tutorial 5 | * For a tutorial on SOES See tutorial.txt 6 | * 7 | * \section overview Overview 8 | * SOES is an EtherCAT slave stack written in c. Its purpose is to learn and 9 | * to use. All users are invited to study the source to get an understanding 10 | * how an EtherCAT slave function 11 | * 12 | * Features as of 1.0.0 : 13 | * - Address offset based HAL for easy ESC read/write access via any interface 14 | * - Mailbox with data link layer 15 | * - CoE 16 | * - Object dictionary 17 | * - SDO read and write for all sizes including segmented transfers 18 | * - Easy portable C-code suited for embedded applications 19 | * - Fixed PDO mapping 20 | * - FoE with bootstrap template 21 | * - Support for Little and Big endian targets. 22 | * - Polling for interrupts 23 | * 24 | * \section legal Legal notice 25 | * SOES Simple Open EtherCAT Slave \n 26 | * Copyright (C) 2007-2013 Arthur Ketels \n 27 | * Copyright (C) 2012-2013 rt-labs \n 28 | * 29 | * SOES is free software; you can redistribute it and/or modify it under 30 | * the terms of the GNU General Public License version 2 as published by the Free 31 | * Software Foundation. 32 | * 33 | * SOES is distributed in the hope that it will be useful, but WITHOUT ANY 34 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or 35 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 36 | * for more details. 37 | * 38 | * As a special exception, if other files instantiate templates or use macros 39 | * or inline functions from this file, or you compile this file and link it 40 | * with other works to produce a work based on this file, this file does not 41 | * by itself cause the resulting work to be covered by the GNU General Public 42 | * License. However the source code for this file must still be made available 43 | * in accordance with section (3) of the GNU General Public License. 44 | * 45 | * This exception does not invalidate any other reasons why a work based on 46 | * this file might be covered by the GNU General Public License. 47 | * 48 | * The EtherCAT Technology, the trade name and logo "EtherCAT" are the intellectual 49 | * property of, and protected by Beckhoff Automation GmbH. 50 | */ 51 | -------------------------------------------------------------------------------- /examples/SOES_LAN9252/lib/soes/ecat_slv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | #ifndef __ECAT_SLV_H__ 7 | #define __ECAT_SLV_H__ 8 | 9 | #include "options.h" 10 | #include "esc.h" 11 | 12 | /** 13 | * This function is called when to get input values 14 | */ 15 | void cb_get_inputs(); 16 | 17 | /** 18 | * This function is called when to set outputs values 19 | */ 20 | void cb_set_outputs(); 21 | 22 | /** Set the watchdog count value 23 | * 24 | * @param[in] watchdogcnt = new watchdog count value 25 | */ 26 | void APP_setwatchdog (int watchdogcnt); 27 | 28 | #define DIG_PROCESS_INPUTS_FLAG 0x01 29 | #define DIG_PROCESS_OUTPUTS_FLAG 0x02 30 | #define DIG_PROCESS_WD_FLAG 0x04 31 | #define DIG_PROCESS_APP_HOOK_FLAG 0x08 32 | /** Implements the watch-dog counter to count if we should make a state change 33 | * due to missing incoming SM2 events. Updates local I/O and run the application 34 | * in the following order, call read EtherCAT outputs, execute user provided 35 | * application hook and call write EtherCAT inputs. 36 | * 37 | * @param[in] flags = User input what to execute 38 | */ 39 | void DIG_process (uint8_t flags); 40 | 41 | /** 42 | * Handler for SM change, SM0/1, AL CONTROL and EEPROM events, the application 43 | * control what interrupts that should be served and re-activated with 44 | * event mask argument 45 | * 46 | * @param[in] event_mask = Event mask for interrupts to serve and re-activate 47 | * after served 48 | */ 49 | void ecat_slv_worker (uint32_t event_mask); 50 | 51 | /** 52 | * Poll SM0/1, EEPROM and AL CONTROL events in a SM/DC synchronization 53 | * application 54 | */ 55 | void ecat_slv_poll (void); 56 | 57 | /** 58 | * Poll all events in a free-run application 59 | */ 60 | void ecat_slv (void); 61 | 62 | /** 63 | * Initialize the slave stack 64 | * 65 | * @param[in] config = User input how to configure the stack 66 | */ 67 | void ecat_slv_init (esc_cfg_t * config); 68 | 69 | #endif /* __ECAT_SLV_H__ */ 70 | -------------------------------------------------------------------------------- /examples/SOES_LAN9252/lib/soes/esc_eep.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | /** \file 7 | * \brief 8 | * ESI EEPROM emulator module. 9 | */ 10 | 11 | #include "cc.h" 12 | #include "esc.h" 13 | #include "esc_eep.h" 14 | 15 | #include 16 | 17 | static uint8_t eep_buf[8]; 18 | 19 | /** EPP periodic task of ESC side EEPROM emulation. 20 | * 21 | */ 22 | void EEP_process (void) 23 | { 24 | eep_stat_t stat; 25 | 26 | /* check for eeprom event */ 27 | if ((ESCvar.ALevent & ESCREG_ALEVENT_EEP) == 0) { 28 | return; 29 | } 30 | 31 | while (1) { 32 | /* read eeprom status */ 33 | ESC_read (ESCREG_EECONTSTAT, &stat, sizeof (eep_stat_t)); 34 | stat.contstat.reg = etohs(stat.contstat.reg); 35 | stat.addr = etohl(stat.addr); 36 | 37 | /* check busy flag, exit if job finished */ 38 | if (!stat.contstat.bits.busy) { 39 | return; 40 | } 41 | 42 | /* clear error bits */ 43 | stat.contstat.bits.csumErr = 0; 44 | stat.contstat.bits.eeLoading = 0; 45 | stat.contstat.bits.ackErr = 0; 46 | stat.contstat.bits.wrErr = 0; 47 | 48 | /* process commands */ 49 | switch (stat.contstat.bits.cmdReg) { 50 | case EEP_CMD_IDLE: 51 | break; 52 | 53 | case EEP_CMD_READ: 54 | case EEP_CMD_RELOAD: 55 | /* handle read request */ 56 | if (EEP_read (stat.addr * sizeof(uint16_t), eep_buf, EEP_READ_SIZE) != 0) { 57 | stat.contstat.bits.ackErr = 1; 58 | } else { 59 | ESC_write (ESCREG_EEDATA, eep_buf, EEP_READ_SIZE); 60 | } 61 | break; 62 | 63 | case EEP_CMD_WRITE: 64 | /* handle write request */ 65 | ESC_read (ESCREG_EEDATA, eep_buf, EEP_WRITE_SIZE); 66 | if (EEP_write (stat.addr * sizeof(uint16_t), eep_buf, EEP_WRITE_SIZE) != 0) { 67 | stat.contstat.bits.ackErr = 1; 68 | } 69 | break; 70 | 71 | default: 72 | stat.contstat.bits.ackErr = 1; 73 | } 74 | 75 | /* acknowledge command */ 76 | stat.contstat.reg = htoes(stat.contstat.reg); 77 | ESC_write (ESCREG_EECONTSTAT, &stat.contstat.reg, sizeof(uint16_t)); 78 | } 79 | } 80 | 81 | -------------------------------------------------------------------------------- /examples/SOES_LAN9252/lib/soes/esc_eep.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | /** \file 7 | * \brief 8 | * Headerfile for esc_eep.c 9 | */ 10 | 11 | #ifndef __esc_eep__ 12 | #define __esc_eep__ 13 | 14 | #include 15 | #include "esc.h" 16 | 17 | /* EEPROM commands */ 18 | #define EEP_CMD_IDLE 0x0 19 | #define EEP_CMD_READ 0x1 20 | #define EEP_CMD_WRITE 0x2 21 | #define EEP_CMD_RELOAD 0x3 22 | 23 | /* read/write size */ 24 | #define EEP_READ_SIZE 8 25 | #define EEP_WRITE_SIZE 2 26 | 27 | /* CONSTAT register content */ 28 | typedef struct CC_PACKED 29 | { 30 | union { 31 | uint16_t reg; 32 | struct { 33 | uint8_t wrEnable:1; 34 | uint8_t reserved:4; 35 | uint8_t eeEmulated:1; 36 | uint8_t eightByteRead:1; 37 | uint8_t twoByteAddr:1; 38 | 39 | uint8_t cmdReg:3; 40 | uint8_t csumErr:1; 41 | uint8_t eeLoading:1; 42 | uint8_t ackErr:1; 43 | uint8_t wrErr:1; 44 | uint8_t busy:1; 45 | } bits; 46 | } contstat; 47 | 48 | uint32_t addr; 49 | } eep_stat_t; 50 | 51 | /** 52 | * ECAT EEPROM configuration area data structure 53 | */ 54 | typedef union eep_config 55 | { 56 | struct 57 | { 58 | uint16_t pdi_control; 59 | uint16_t pdi_configuration; 60 | uint16_t sync_impulse_len; 61 | uint16_t pdi_configuration2; 62 | uint16_t configured_station_alias; 63 | uint8_t reserved[4]; 64 | uint16_t checksum; 65 | }; 66 | uint32_t dword[4]; /**< Four 32 bit double word equivalent to 8 16 bit configuration area word. */ 67 | }eep_config_t; 68 | 69 | /* periodic task */ 70 | void EEP_process (void); 71 | 72 | /* From hardware file */ 73 | void EEP_init (void); 74 | int8_t EEP_read (uint32_t addr, uint8_t *data, uint16_t size); 75 | int8_t EEP_write (uint32_t addr, uint8_t *data, uint16_t size); 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /examples/SOES_LAN9252/lib/soes/esc_eoe.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | /** \file 7 | * \brief 8 | * Headerfile for esc_eoe.c 9 | */ 10 | 11 | #ifndef __esc_eoe__ 12 | #define __esc_eoe__ 13 | 14 | #include 15 | 16 | typedef struct eoe_pbuf 17 | { 18 | /** Pointer to frame buffer type used by a TCP/IP stack. (Not mandatory) */ 19 | void * pbuf; 20 | /** Pointer to frame buffer to send or read from */ 21 | uint8_t * payload; 22 | /** Length of data in frame buffer */ 23 | size_t len; 24 | } eoe_pbuf_t; 25 | 26 | typedef struct eoe_cfg 27 | { 28 | /** Callback function to get a frame buffer for storage of received frame */ 29 | void (*get_buffer) (eoe_pbuf_t * ebuf); 30 | /** Callback function to free a frame buffer */ 31 | void (*free_buffer) (eoe_pbuf_t * ebuf); 32 | /** Callback function to read local settings and update EtherCAT variables 33 | * to be delivered to the EtherCAT Master 34 | */ 35 | int (*load_eth_settings) (void); 36 | /** Callback function to read settings provided by the EtherCAT master 37 | * and store to local settings. 38 | */ 39 | int (*store_ethernet_settings) (void); 40 | /** Callback to frame receive function in TCP(IP stack, 41 | * caller should free the buffer 42 | * */ 43 | void (*handle_recv_buffer) (uint8_t port, eoe_pbuf_t * ebuf); 44 | /** Callback to fetch a buffer to send */ 45 | int (*fetch_send_buffer) (uint8_t port, eoe_pbuf_t * ebuf); 46 | /** Callback to notify the application fragment sent */ 47 | void (*fragment_sent_event) (void); 48 | } eoe_cfg_t; 49 | 50 | int EOE_ecat_get_mac (uint8_t port, uint8_t mac[]); 51 | int EOE_ecat_get_ip (uint8_t port, uint32_t * ip); 52 | int EOE_ecat_get_subnet (uint8_t port, uint32_t * subnet); 53 | int EOE_ecat_get_gateway (uint8_t port, uint32_t * default_gateway); 54 | int EOE_ecat_get_dns_ip (uint8_t port, uint32_t * dns_ip); 55 | int EOE_ecat_get_dns_name (uint8_t port, char * dns_name); 56 | int EOE_ecat_set_mac (uint8_t port, uint8_t mac[]); 57 | int EOE_ecat_set_ip (uint8_t port, uint32_t ip); 58 | int EOE_ecat_set_subnet (uint8_t port, uint32_t subnet); 59 | int EOE_ecat_set_gateway (uint8_t port, uint32_t default_gateway); 60 | int EOE_ecat_set_dns_ip (uint8_t port, uint32_t dns_ip); 61 | int EOE_ecat_set_dns_name (uint8_t port, char * dns_name); 62 | 63 | void EOE_config (eoe_cfg_t * cfg); 64 | void EOE_init (void); 65 | void ESC_eoeprocess (void); 66 | void ESC_eoeprocess_tx (void); 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /examples/SOES_LAN9252/lib/soes/esc_foe.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | /** \file 7 | * \brief 8 | * Headerfile for esc_foe.c 9 | */ 10 | 11 | #ifndef __esc_foe__ 12 | #define __esc_foe__ 13 | 14 | #include 15 | 16 | /** Maximum number of characters allowed in a file name. */ 17 | #define FOE_FN_MAX 31 18 | 19 | typedef struct foe_file_cfg foe_file_cfg_t; 20 | struct foe_file_cfg 21 | { 22 | /** Name of file to receive from master */ 23 | const char * name; 24 | /** Size of file,sizeof data we can recv */ 25 | uint32_t max_data; 26 | /** Where to store the data initially */ 27 | uint32_t dest_start_address; 28 | /** Current address during write of file */ 29 | uint32_t address_offset; 30 | /** Calculated size of file received */ 31 | uint32_t total_size; 32 | /** FoE password */ 33 | uint32_t filepass; 34 | /** This file can be written only in BOOT state. Intended for FW files */ 35 | uint8_t write_only_in_boot; 36 | /** for feature use */ 37 | uint32_t padding:24; 38 | /** Pointer to application foe write function */ 39 | uint32_t (*write_function) (foe_file_cfg_t * self, uint8_t * data, size_t length); 40 | }; 41 | 42 | typedef struct foe_cfg 43 | { 44 | /** Allocate static in caller func to fit buffer_size */ 45 | uint8_t * fbuffer; 46 | /** Buffer size before we flush to destination */ 47 | uint32_t buffer_size; 48 | /** Number of files used in firmware update */ 49 | uint32_t n_files; 50 | /** Pointer to files configured to be used by FoE */ 51 | foe_file_cfg_t * files; 52 | } foe_cfg_t; 53 | 54 | typedef struct CC_PACKED 55 | { 56 | /** Current FoE state, ex. Waiting for ACK, Waiting for DATA */ 57 | uint8_t foestate; 58 | /** Current file buffer position, evaluated against foe file buffer size 59 | * when to flush 60 | */ 61 | uint16_t fbufposition; 62 | /** Frame number in read or write sequence */ 63 | uint32_t foepacket; 64 | /** Current position in file to be handled by FoE request */ 65 | uint32_t fposition; 66 | /** Previous position in file to be handled by FoE request */ 67 | uint32_t fprevposition; 68 | /** End position of allocated disk space for FoE requested file */ 69 | uint32_t fend; 70 | } _FOEvar; 71 | 72 | /* Initializes FoE state. */ 73 | void FOE_config (foe_cfg_t * cfg); 74 | void FOE_init (void); 75 | void ESC_foeprocess (void); 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /examples/SOES_LAN9252/lib/soes/hal/stm32-lan9252/rst.c: -------------------------------------------------------------------------------- 1 | #include "rst.h" 2 | 3 | 4 | void rst_setup(void) 5 | { 6 | /* Setup NRST as GPIO out and pull it high */ 7 | GPIO_InitTypeDef gpio; 8 | 9 | RCC_AHB1PeriphClockCmd(ESC_RCC_APB1PERIPH_GPIOX_RSTN, ENABLE); 10 | 11 | gpio.GPIO_Pin = ESC_GPIO_Pin_RSTN; 12 | gpio.GPIO_Mode = GPIO_Mode_OUT; 13 | gpio.GPIO_Speed = GPIO_Speed_50MHz; 14 | gpio.GPIO_OType = GPIO_OType_PP; 15 | gpio.GPIO_PuPd = GPIO_PuPd_UP; 16 | GPIO_Init(ESC_GPIOX_RSTN, &gpio); 17 | 18 | rst_high(); 19 | } 20 | 21 | void rst_low(void) 22 | { /* Set RSTN line low */ 23 | GPIO_ResetBits(ESC_GPIOX_RSTN, ESC_GPIO_Pin_RSTN); 24 | } 25 | 26 | void rst_high(void) 27 | { 28 | /* Set RSTN line high */ 29 | GPIO_SetBits(ESC_GPIOX_RSTN, ESC_GPIO_Pin_RSTN); 30 | } 31 | 32 | void rst_check_start(void) 33 | { 34 | /* Setup NRST as GPIO input and pull it high */ 35 | GPIO_InitTypeDef gpio; 36 | 37 | RCC_AHB1PeriphClockCmd(ESC_RCC_APB1PERIPH_GPIOX_RSTN, ENABLE); 38 | 39 | gpio.GPIO_Pin = ESC_GPIO_Pin_RSTN; 40 | gpio.GPIO_Mode = GPIO_Mode_IN; 41 | gpio.GPIO_Speed = GPIO_Speed_50MHz; 42 | gpio.GPIO_PuPd = GPIO_PuPd_NOPULL; 43 | GPIO_Init(ESC_GPIOX_RSTN, &gpio); 44 | } 45 | 46 | uint8_t is_esc_reset(void) 47 | { 48 | /* Check if ESC pulled RSTN line up */ 49 | return GPIO_ReadInputDataBit(ESC_GPIOX_RSTN, ESC_GPIO_Pin_RSTN) == Bit_SET; 50 | } 51 | 52 | -------------------------------------------------------------------------------- /examples/SOES_LAN9252/lib/soes/hal/stm32-lan9252/rst.h: -------------------------------------------------------------------------------- 1 | #ifndef __HAL_NRST_H__ 2 | #define __HAL_NRST_H__ 3 | 4 | #include 5 | #include "stm32f4xx_conf.h" 6 | 7 | #define ESC_RCC_APB1PERIPH_GPIOX_RSTN RCC_AHB1Periph_GPIOA 8 | #define ESC_GPIOX_RSTN GPIOA 9 | #define ESC_GPIO_Pin_RSTN GPIO_Pin_2 10 | 11 | 12 | void rst_setup(void); 13 | void rst_low(void); 14 | void rst_high(void); 15 | 16 | void rst_check_start(void); 17 | uint8_t is_esc_reset(void); 18 | 19 | #endif /* __HAL_NRST_H__ */ 20 | -------------------------------------------------------------------------------- /examples/SOES_LAN9252/lib/soes/hal/stm32-lan9252/spi.h: -------------------------------------------------------------------------------- 1 | #ifndef SRC_APP_SPI_H_ 2 | #define SRC_APP_SPI_H_ 3 | 4 | #include 5 | #include "stm32f4xx_conf.h" 6 | 7 | 8 | #define SCS_LOW 0 9 | #define SCS_HIGH 1 10 | 11 | #if defined (STM32F4) 12 | 13 | #define SPIX_ESC SPI1 14 | #define ESC_RCC_APB2PERIPH_SPIX RCC_APB2Periph_SPI1 15 | #define ESC_GPIOX_AF_SPIx GPIO_AF_SPI1 16 | 17 | #define ESC_RCC_APB1PERIPH_GPIOX_CTRL RCC_AHB1Periph_GPIOA 18 | #define ESC_GPIOX_CTRL GPIOA 19 | 20 | #define ESC_GPIO_Pin_SCK GPIO_Pin_5 21 | #define ESC_GPIO_PinSourceSCK 5 22 | 23 | #define ESC_GPIO_Pin_MISO GPIO_Pin_6 24 | #define ESC_GPIO_PinSource_MISO 6 25 | 26 | #define ESC_GPIO_Pin_MOSI GPIO_Pin_7 27 | #define ESC_GPIO_PinSource_MOSI 7 28 | 29 | #define ESC_RCC_APB1PERIPH_GPIOX_CS RCC_AHB1Periph_GPIOA 30 | #define ESC_GPIOX_CS GPIOA 31 | #define ESC_GPIO_Pin_CS GPIO_Pin_4 32 | 33 | #else 34 | #error "Platform not supported" 35 | #endif 36 | 37 | #if defined (LAN9252) 38 | #define SPIX_ESC_SCS SPI_NSS_Soft 39 | #define SCS_ACTIVE_POLARITY SCS_LOW 40 | #define SPIX_ESC_CPOL SPI_CPOL_Low 41 | #define SPIX_ESC_CPHA SPI_CPHA_1Edge 42 | #else 43 | #error "No supported ESC specified" 44 | #endif 45 | 46 | 47 | #define DUMMY_BYTE 0xFF 48 | #define tout 5000 49 | 50 | void spi_setup(void); 51 | void spi_select (int8_t board); 52 | void spi_unselect (int8_t board); 53 | void write (int8_t board, uint8_t *data, uint8_t size); 54 | void read (int8_t board, uint8_t *result, uint8_t size); 55 | void spi_bidirectionally_transfer (int8_t board, uint8_t *result, uint8_t *data, uint8_t size); 56 | 57 | 58 | #endif /* SRC_APP_SPI_H_ */ 59 | -------------------------------------------------------------------------------- /examples/SOES_LAN9252/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [env:disco_f4] 12 | platform = ststm32@6.0.0 13 | framework = spl 14 | ; debug_tool = stlink 15 | debug_tool = blackmagic 16 | debug_port = "COM7" 17 | upload_port = "COM7" 18 | upload_protocol = blackmagic 19 | 20 | board = disco_f407vg 21 | 22 | build_flags = 23 | -D HSE_VALUE=8000000U 24 | -D LAN9252 25 | 26 | monitor_speed = 115200 -------------------------------------------------------------------------------- /examples/SOES_LAN9252/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "stm32f4xx.h" 3 | #include "stm32f4_discovery.h" 4 | #include "delay.h" 5 | #include "usart.h" 6 | 7 | #include "esc.h" 8 | #include "ecat_slv.h" 9 | #include "utypes.h" 10 | 11 | 12 | /* CANopen Object Dictionary */ 13 | _Objects Obj; 14 | 15 | 16 | /* Application hook declaration */ 17 | void ecatapp(); 18 | 19 | 20 | /* SOES configuration */ 21 | static esc_cfg_t config = { 22 | .user_arg = "/dev/lan9252", 23 | .use_interrupt = 0, 24 | .watchdog_cnt = 500, 25 | .set_defaults_hook = NULL, 26 | .pre_state_change_hook = NULL, 27 | .post_state_change_hook = NULL, 28 | .application_hook = NULL, 29 | .safeoutput_override = NULL, 30 | .pre_object_download_hook = NULL, 31 | .post_object_download_hook = NULL, 32 | .rxpdo_override = NULL, 33 | .txpdo_override = NULL, 34 | .esc_hw_interrupt_enable = NULL, 35 | .esc_hw_interrupt_disable = NULL, 36 | .esc_hw_eep_handler = NULL, 37 | .esc_check_dc_handler = NULL, 38 | }; 39 | 40 | 41 | void esc_pdi_debug() 42 | { 43 | // Read few core CSR registers to verify PDI is working 44 | uint8_t value = 0; 45 | printf("\r\n[ESC debug] "); 46 | 47 | ESC_read(0x0000, (void*) &value, sizeof(uint8_t)); 48 | printf("Type [0x0000]: %s, ", STR5(value)); 49 | ESC_read(0x0001, (void*) &value, sizeof(uint8_t)); 50 | printf("Revision [0x0001]: %s, ", STR5(value)); 51 | ESC_read(0x0004, (void*) &value, sizeof(uint8_t)); 52 | printf("FMMU count [0x0004]: %s, ", STR5(value)); 53 | ESC_read(0x0005, (void*) &value, sizeof(uint8_t)); 54 | printf("Sync Managers count [0x0005]: %s, ", STR5(value)); 55 | ESC_read(0x0006, (void*) &value, sizeof(uint8_t)); 56 | printf("RAM size [0x0006]: %s, \r\n", STR5(value)); 57 | 58 | printf("\r\n"); 59 | } 60 | 61 | 62 | //---- user application ------------------------------------------------------------------------------ 63 | 64 | void cb_get_inputs() 65 | { 66 | // write to slave TxPDO 67 | // dummy value, so that sawtooth value profile will be seen constantly changing by ecat master 68 | Obj.Counter++; 69 | } 70 | 71 | void cb_set_outputs() 72 | { 73 | // read slave RxPDO 74 | if (Obj.LedIn) 75 | { 76 | STM_EVAL_LEDOn(outPins[0]); 77 | } 78 | else 79 | { 80 | STM_EVAL_LEDOff(outPins[0]); 81 | } 82 | } 83 | 84 | 85 | int main(void) 86 | { 87 | SysTick_Config(SystemCoreClock / 1000); 88 | APP_USART_Init(); 89 | delay_init(); 90 | printf("\r\n[ESC Setup] %s \r\n", "Started"); 91 | // setup LED pins 92 | STM_EVAL_LEDInit(outPins[0]); 93 | ecat_slv_init(&config); 94 | printf("\r\n[ESC Setup] Done, ready \r\n\n"); 95 | esc_pdi_debug(); 96 | 97 | while (1) 98 | { 99 | ecat_slv(); 100 | 101 | if (ESCvar.ALerror) { 102 | printf("\rAL Error %d\r\n", ESCvar.ALerror); 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /examples/SOES_LAN9252/test/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for PlatformIO Unit Testing and project tests. 3 | 4 | Unit Testing is a software testing method by which individual units of 5 | source code, sets of one or more MCU program modules together with associated 6 | control data, usage procedures, and operating procedures, are tested to 7 | determine whether they are fit for use. Unit testing finds problems early 8 | in the development cycle. 9 | 10 | More information about PlatformIO Unit Testing: 11 | - https://docs.platformio.org/page/plus/unit-testing.html 12 | -------------------------------------------------------------------------------- /examples/SOES_arduino/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/settings.json 6 | .vscode/ipch 7 | 8 | # EasyCAT 9 | log_configuration.txt 10 | log_programmer.txt 11 | 12 | # Eclipse 13 | .metadata -------------------------------------------------------------------------------- /examples/SOES_arduino/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "platformio.platformio-ide" 6 | ], 7 | "unwantedRecommendations": [ 8 | "ms-vscode.cpptools-extension-pack" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /examples/SOES_arduino/LICENSE: -------------------------------------------------------------------------------- 1 | SOES Simple Open EtherCAT Slave 2 | 3 | Copyright (C) 2007-2017 Arthur Ketels 4 | Copyright (C) 2012-2017 rt-labs 5 | 6 | SOES is free software; you can redistribute it and/or modify it under 7 | the terms of the GNU General Public License version 2 as published by the Free 8 | Software Foundation. 9 | 10 | SOES is distributed in the hope that it will be useful, but WITHOUT ANY 11 | WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 | for more details. 14 | 15 | As a special exception, if other files instantiate templates or use macros 16 | or inline functions from this file, or you compile this file and link it 17 | with other works to produce a work based on this file, this file does not 18 | by itself cause the resulting work to be covered by the GNU General Public 19 | License. However the source code for this file must still be made available 20 | in accordance with section (3) of the GNU General Public License. 21 | 22 | This exception does not invalidate any other reasons why a work based on 23 | this file might be covered by the GNU General Public License. 24 | 25 | The EtherCAT Technology, the trade name and logo "EtherCAT" are the intellectual 26 | property of, and protected by Beckhoff Automation GmbH. 27 | -------------------------------------------------------------------------------- /examples/SOES_arduino/README.md: -------------------------------------------------------------------------------- 1 | # SOES as Arduino library 2 | 3 | This project shows using SOES library with Arduino (STM32Duino) on ubiqutous STM32F103 "BluePill" board. 4 | 5 | - ESC is LAN9252 connected over SPI 6 | - example application is CiA 402 dummy servo drive. 7 | 8 | 9 | ## MCU pinout 10 | 11 | STM32F103 BluePill 12 | 13 | | SPI1 | STM32 pin | PDI | LAN9252 | 14 | | ---- |:---------:|:----:|:-------:| 15 | | * | PA4 | SCS | D5 | 16 | | SCK | PA5 | SCK | D5 | 17 | | MISO | PA6 | MISO | D9 | 18 | | MOSI | PA7 | MOSI | D1/SIO1 | 19 | | UART1| 20 | | TX | PA09 21 | | RX | PA10 22 | 23 | # Benchmark 24 | 25 | - Cables connected, ECAT master not connected: `[ESC benchmark] 226 us (391 top)` 26 | - ECAT master connected, slv in OP: `[ESC benchmark] 581 us (2393 top) [ESC benchmark] 943 us (2393 top)` 27 | 28 | Good enough for sensor or dummy servodrive, looks like not enough for real life motion control usage. -------------------------------------------------------------------------------- /examples/SOES_arduino/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /examples/SOES_arduino/lib/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project specific (private) libraries. 3 | PlatformIO will compile them to static libraries and link into executable file. 4 | 5 | The source code of each library should be placed in a an own separate directory 6 | ("lib/your_library_name/[here are source files]"). 7 | 8 | For example, see a structure of the following two libraries `Foo` and `Bar`: 9 | 10 | |--lib 11 | | | 12 | | |--Bar 13 | | | |--docs 14 | | | |--examples 15 | | | |--src 16 | | | |- Bar.c 17 | | | |- Bar.h 18 | | | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html 19 | | | 20 | | |--Foo 21 | | | |- Foo.c 22 | | | |- Foo.h 23 | | | 24 | | |- README --> THIS FILE 25 | | 26 | |- platformio.ini 27 | |--src 28 | |- main.c 29 | 30 | and a contents of `src/main.c`: 31 | ``` 32 | #include 33 | #include 34 | 35 | int main (void) 36 | { 37 | ... 38 | } 39 | 40 | ``` 41 | 42 | PlatformIO Library Dependency Finder will find automatically dependent 43 | libraries scanning project source files. 44 | 45 | More information about PlatformIO Library Dependency Finder 46 | - https://docs.platformio.org/page/librarymanager/ldf.html 47 | -------------------------------------------------------------------------------- /examples/SOES_arduino/lib/soes-esi/cc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | #ifndef CC_H 7 | #define CC_H 8 | 9 | #ifdef __cplusplus 10 | extern "C" 11 | { 12 | #endif 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #ifdef __linux__ 19 | #include 20 | #else 21 | #include 22 | #endif 23 | 24 | #ifndef MIN 25 | #define MIN(a,b) (((a)<(b))?(a):(b)) 26 | #endif 27 | 28 | #ifndef MAX 29 | #define MAX(a,b) (((a)>(b))?(a):(b)) 30 | #endif 31 | 32 | #define CC_PACKED_BEGIN 33 | #define CC_PACKED_END 34 | #define CC_PACKED __attribute__((packed)) 35 | 36 | #ifdef __rtk__ 37 | #define CC_ASSERT(exp) ASSERT (exp) 38 | #else 39 | #define CC_ASSERT(exp) assert (exp) 40 | #endif 41 | #define CC_STATIC_ASSERT(exp) _Static_assert (exp, "") 42 | 43 | #define CC_DEPRECATED __attribute__((deprecated)) 44 | 45 | #define CC_SWAP32(x) __builtin_bswap32 (x) 46 | #define CC_SWAP16(x) __builtin_bswap16 (x) 47 | 48 | #define CC_ATOMIC_SET(var,val) __atomic_store_n(&var,val,__ATOMIC_SEQ_CST) 49 | #define CC_ATOMIC_GET(var) __atomic_load_n(&var,__ATOMIC_SEQ_CST) 50 | #define CC_ATOMIC_ADD(var,val) __atomic_add_fetch(&var,val,__ATOMIC_SEQ_CST) 51 | #define CC_ATOMIC_SUB(var,val) __atomic_sub_fetch(&var,val,__ATOMIC_SEQ_CST) 52 | #define CC_ATOMIC_AND(var,val) __atomic_and_fetch(&var,val,__ATOMIC_SEQ_CST) 53 | #define CC_ATOMIC_OR(var,val) __atomic_or_fetch(&var,val,__ATOMIC_SEQ_CST) 54 | 55 | #if BYTE_ORDER == BIG_ENDIAN 56 | #define htoes(x) CC_SWAP16 (x) 57 | #define htoel(x) CC_SWAP32 (x) 58 | #else 59 | #define htoes(x) (x) 60 | #define htoel(x) (x) 61 | #endif 62 | 63 | #define etohs(x) htoes (x) 64 | #define etohl(x) htoel (x) 65 | 66 | #if BYTE_ORDER == LITTLE_ENDIAN 67 | #define EC_LITTLE_ENDIAN 68 | #else 69 | #define EC_BIG_ENDIAN 70 | #endif 71 | 72 | #ifdef ESC_DEBUG 73 | #ifdef __rtk__ 74 | #include 75 | #define DPRINT(...) rprintp ("soes: "__VA_ARGS__) 76 | #else 77 | #include 78 | #define DPRINT(...) printf ("soes: "__VA_ARGS__) 79 | #endif 80 | #else 81 | #define DPRINT(...) 82 | #endif 83 | 84 | #ifdef __cplusplus 85 | } 86 | #endif 87 | 88 | #endif /* CC_H */ 89 | -------------------------------------------------------------------------------- /examples/SOES_arduino/lib/soes-esi/ecat_options.h: -------------------------------------------------------------------------------- 1 | #ifndef __ECAT_OPTIONS_H__ 2 | #define __ECAT_OPTIONS_H__ 3 | 4 | #define USE_FOE 0 5 | #define USE_EOE 0 6 | 7 | #define MBXSIZE 512 8 | #define MBXSIZEBOOT 512 9 | #define MBXBUFFERS 3 10 | 11 | #define MBX0_sma 0x1000 12 | #define MBX0_sml MBXSIZE 13 | #define MBX0_sme MBX0_sma+MBX0_sml-1 14 | #define MBX0_smc 0x26 15 | #define MBX1_sma MBX0_sma+MBX0_sml 16 | #define MBX1_sml MBXSIZE 17 | #define MBX1_sme MBX1_sma+MBX1_sml-1 18 | #define MBX1_smc 0x22 19 | 20 | #define MBX0_sma_b 0x1000 21 | #define MBX0_sml_b MBXSIZEBOOT 22 | #define MBX0_sme_b MBX0_sma_b+MBX0_sml_b-1 23 | #define MBX0_smc_b 0x26 24 | #define MBX1_sma_b MBX0_sma_b+MBX0_sml_b 25 | #define MBX1_sml_b MBXSIZEBOOT 26 | #define MBX1_sme_b MBX1_sma_b+MBX1_sml_b-1 27 | #define MBX1_smc_b 0x22 28 | 29 | #define SM2_sma 0x1600 30 | #define SM2_smc 0x24 31 | #define SM2_act 1 32 | #define SM3_sma 0x1A00 33 | #define SM3_smc 0x20 34 | #define SM3_act 1 35 | 36 | #define MAX_MAPPINGS_SM2 2 37 | #define MAX_MAPPINGS_SM3 5 38 | 39 | #define MAX_RXPDO_SIZE 512 40 | #define MAX_TXPDO_SIZE 512 41 | 42 | #endif /* __ECAT_OPTIONS_H__ */ 43 | -------------------------------------------------------------------------------- /examples/SOES_arduino/lib/soes-esi/eeprom.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/examples/SOES_arduino/lib/soes-esi/eeprom.bin -------------------------------------------------------------------------------- /examples/SOES_arduino/lib/soes-esi/esi.json: -------------------------------------------------------------------------------- 1 | { 2 | "form": { 3 | "VendorName": "Unspecified", 4 | "VendorID": "0x000", 5 | "ProductCode": "0x00ab123", 6 | "ProfileNo": "5001", 7 | "RevisionNumber": "0x001", 8 | "SerialNumber": "0x001", 9 | "HWversion": "0.0.1", 10 | "SWversion": "0.0.1", 11 | "EEPROMsize": "2048", 12 | "RxMailboxOffset": "0x1000", 13 | "TxMailboxOffset": "0x1200", 14 | "MailboxSize": "512", 15 | "SM2Offset": "0x1600", 16 | "SM3Offset": "0x1A00", 17 | "TextGroupType": "DigIn", 18 | "TextGroupName5": "Digital input/output", 19 | "ImageName": "IMGCBY", 20 | "TextDeviceType": "IODemoApp", 21 | "TextDeviceName": "LAN9252 SPI demo", 22 | "Port0Physical": "Y", 23 | "Port1Physical": "Y", 24 | "Port2Physical": " ", 25 | "Port3Physical": " ", 26 | "ESC": "LAN9252", 27 | "SPImode": "0", 28 | "CoeDetailsEnableSDO": "EnableSDO", 29 | "CoeDetailsEnableSDOInfo": "EnableSDOInfo", 30 | "CoeDetailsEnablePDOAssign": "EnablePDOAssign", 31 | "CoeDetailsEnablePDOConfiguration": "EnablePDOConfiguration", 32 | "CoeDetailsEnableUploadAtStartup": "EnableUploadAtStartup", 33 | "CoeDetailsEnableSDOCompleteAccess": "EnableSDOCompleteAccess" 34 | }, 35 | "od": { 36 | "sdo": {}, 37 | "txpdo": { 38 | "6000": { 39 | "otype": "VAR", 40 | "name": "Key1", 41 | "access": "RO", 42 | "pdo_mappings": [ 43 | "txpdo" 44 | ], 45 | "dtype": "BOOLEAN", 46 | "value": "0", 47 | "data": "&Obj.Key1" 48 | }, 49 | "6001": { 50 | "otype": "VAR", 51 | "name": "Key2", 52 | "access": "RO", 53 | "pdo_mappings": [ 54 | "txpdo" 55 | ], 56 | "dtype": "BOOLEAN", 57 | "value": "0", 58 | "data": "&Obj.Key2" 59 | }, 60 | "6002": { 61 | "otype": "VAR", 62 | "name": "Counter", 63 | "access": "RO", 64 | "pdo_mappings": [ 65 | "txpdo" 66 | ], 67 | "dtype": "UNSIGNED32", 68 | "value": "0", 69 | "data": "&Obj.Counter" 70 | } 71 | }, 72 | "rxpdo": { 73 | "7000": { 74 | "otype": "VAR", 75 | "name": "LedIn", 76 | "access": "RO", 77 | "pdo_mappings": [ 78 | "rxpdo" 79 | ], 80 | "dtype": "BOOLEAN", 81 | "value": "0", 82 | "data": "&Obj.LedIn" 83 | } 84 | } 85 | }, 86 | "dc": [] 87 | } -------------------------------------------------------------------------------- /examples/SOES_arduino/lib/soes-esi/utypes.h: -------------------------------------------------------------------------------- 1 | #ifndef __UTYPES_H__ 2 | #define __UTYPES_H__ 3 | 4 | #include "cc.h" 5 | 6 | /* Object dictionary storage */ 7 | 8 | typedef struct 9 | { 10 | /* Identity */ 11 | 12 | uint32_t serial; 13 | 14 | /* Inputs */ 15 | 16 | uint8_t Key1; 17 | uint8_t Key2; 18 | uint32_t Counter; 19 | 20 | /* Outputs */ 21 | 22 | uint8_t LedIn; 23 | 24 | } _Objects; 25 | 26 | extern _Objects Obj; 27 | 28 | #endif /* __UTYPES_H__ */ 29 | -------------------------------------------------------------------------------- /examples/SOES_arduino/lib/soes/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # NOTE: add headers to make them show up in an IDE 3 | add_library (soes 4 | esc.c 5 | esc.h 6 | esc_coe.c 7 | esc_coe.h 8 | esc_foe.c 9 | esc_foe.h 10 | esc_eoe.c 11 | esc_eoe.h 12 | esc_eep.c 13 | esc_eep.h 14 | ecat_slv.c 15 | ecat_slv.h 16 | options.h 17 | ${HAL_SOURCES} 18 | ) 19 | 20 | include_directories(${HAL_INCLUDES}) 21 | 22 | install (TARGETS soes DESTINATION bin) 23 | install (FILES 24 | esc.h 25 | esc_coe.h 26 | esc_foe.h 27 | esc_eoe.h 28 | esc_eep.h 29 | DESTINATION include) 30 | -------------------------------------------------------------------------------- /examples/SOES_arduino/lib/soes/doc/images/esi_pdo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/examples/SOES_arduino/lib/soes/doc/images/esi_pdo.png -------------------------------------------------------------------------------- /examples/SOES_arduino/lib/soes/doc/images/sii_pdo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/examples/SOES_arduino/lib/soes/doc/images/sii_pdo.png -------------------------------------------------------------------------------- /examples/SOES_arduino/lib/soes/doc/soes.dox: -------------------------------------------------------------------------------- 1 | /** 2 | * \mainpage Simple Open EtherCAT Slave or SOES 3 | * 4 | * \section start Tutorial 5 | * For a tutorial on SOES See tutorial.txt 6 | * 7 | * \section overview Overview 8 | * SOES is an EtherCAT slave stack written in c. Its purpose is to learn and 9 | * to use. All users are invited to study the source to get an understanding 10 | * how an EtherCAT slave function 11 | * 12 | * Features as of 1.0.0 : 13 | * - Address offset based HAL for easy ESC read/write access via any interface 14 | * - Mailbox with data link layer 15 | * - CoE 16 | * - Object dictionary 17 | * - SDO read and write for all sizes including segmented transfers 18 | * - Easy portable C-code suited for embedded applications 19 | * - Fixed PDO mapping 20 | * - FoE with bootstrap template 21 | * - Support for Little and Big endian targets. 22 | * - Polling for interrupts 23 | * 24 | * \section legal Legal notice 25 | * SOES Simple Open EtherCAT Slave \n 26 | * Copyright (C) 2007-2013 Arthur Ketels \n 27 | * Copyright (C) 2012-2013 rt-labs \n 28 | * 29 | * SOES is free software; you can redistribute it and/or modify it under 30 | * the terms of the GNU General Public License version 2 as published by the Free 31 | * Software Foundation. 32 | * 33 | * SOES is distributed in the hope that it will be useful, but WITHOUT ANY 34 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or 35 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 36 | * for more details. 37 | * 38 | * As a special exception, if other files instantiate templates or use macros 39 | * or inline functions from this file, or you compile this file and link it 40 | * with other works to produce a work based on this file, this file does not 41 | * by itself cause the resulting work to be covered by the GNU General Public 42 | * License. However the source code for this file must still be made available 43 | * in accordance with section (3) of the GNU General Public License. 44 | * 45 | * This exception does not invalidate any other reasons why a work based on 46 | * this file might be covered by the GNU General Public License. 47 | * 48 | * The EtherCAT Technology, the trade name and logo "EtherCAT" are the intellectual 49 | * property of, and protected by Beckhoff Automation GmbH. 50 | */ 51 | -------------------------------------------------------------------------------- /examples/SOES_arduino/lib/soes/ecat_slv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | #ifndef __ECAT_SLV_H__ 7 | #define __ECAT_SLV_H__ 8 | 9 | #include "options.h" 10 | #include "esc.h" 11 | 12 | /** 13 | * This function is called when to get input values 14 | */ 15 | void cb_get_inputs(); 16 | 17 | /** 18 | * This function is called when to set outputs values 19 | */ 20 | void cb_set_outputs(); 21 | 22 | /** Set the watchdog count value 23 | * 24 | * @param[in] watchdogcnt = new watchdog count value 25 | */ 26 | void APP_setwatchdog (int watchdogcnt); 27 | 28 | #define DIG_PROCESS_INPUTS_FLAG 0x01 29 | #define DIG_PROCESS_OUTPUTS_FLAG 0x02 30 | #define DIG_PROCESS_WD_FLAG 0x04 31 | #define DIG_PROCESS_APP_HOOK_FLAG 0x08 32 | /** Implements the watch-dog counter to count if we should make a state change 33 | * due to missing incoming SM2 events. Updates local I/O and run the application 34 | * in the following order, call read EtherCAT outputs, execute user provided 35 | * application hook and call write EtherCAT inputs. 36 | * 37 | * @param[in] flags = User input what to execute 38 | */ 39 | void DIG_process (uint8_t flags); 40 | 41 | /** 42 | * Handler for SM change, SM0/1, AL CONTROL and EEPROM events, the application 43 | * control what interrupts that should be served and re-activated with 44 | * event mask argument 45 | * 46 | * @param[in] event_mask = Event mask for interrupts to serve and re-activate 47 | * after served 48 | */ 49 | void ecat_slv_worker (uint32_t event_mask); 50 | 51 | /** 52 | * Poll SM0/1, EEPROM and AL CONTROL events in a SM/DC synchronization 53 | * application 54 | */ 55 | void ecat_slv_poll (void); 56 | 57 | /** 58 | * Poll all events in a free-run application 59 | */ 60 | void ecat_slv (void); 61 | 62 | /** 63 | * Initialize the slave stack 64 | * 65 | * @param[in] config = User input how to configure the stack 66 | */ 67 | void ecat_slv_init (esc_cfg_t * config); 68 | 69 | #endif /* __ECAT_SLV_H__ */ 70 | -------------------------------------------------------------------------------- /examples/SOES_arduino/lib/soes/esc_eep.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | /** \file 7 | * \brief 8 | * ESI EEPROM emulator module. 9 | */ 10 | 11 | #include "cc.h" 12 | #include "esc.h" 13 | #include "esc_eep.h" 14 | 15 | #include 16 | 17 | static uint8_t eep_buf[8]; 18 | 19 | /** EPP periodic task of ESC side EEPROM emulation. 20 | * 21 | */ 22 | void EEP_process (void) 23 | { 24 | eep_stat_t stat; 25 | 26 | /* check for eeprom event */ 27 | if ((ESCvar.ALevent & ESCREG_ALEVENT_EEP) == 0) { 28 | return; 29 | } 30 | 31 | while (1) { 32 | /* read eeprom status */ 33 | ESC_read (ESCREG_EECONTSTAT, &stat, sizeof (eep_stat_t)); 34 | stat.contstat.reg = etohs(stat.contstat.reg); 35 | stat.addr = etohl(stat.addr); 36 | 37 | /* check busy flag, exit if job finished */ 38 | if (!stat.contstat.bits.busy) { 39 | return; 40 | } 41 | 42 | /* clear error bits */ 43 | stat.contstat.bits.csumErr = 0; 44 | stat.contstat.bits.eeLoading = 0; 45 | stat.contstat.bits.ackErr = 0; 46 | stat.contstat.bits.wrErr = 0; 47 | 48 | /* process commands */ 49 | switch (stat.contstat.bits.cmdReg) { 50 | case EEP_CMD_IDLE: 51 | break; 52 | 53 | case EEP_CMD_READ: 54 | case EEP_CMD_RELOAD: 55 | /* handle read request */ 56 | if (EEP_read (stat.addr * sizeof(uint16_t), eep_buf, EEP_READ_SIZE) != 0) { 57 | stat.contstat.bits.ackErr = 1; 58 | } else { 59 | ESC_write (ESCREG_EEDATA, eep_buf, EEP_READ_SIZE); 60 | } 61 | break; 62 | 63 | case EEP_CMD_WRITE: 64 | /* handle write request */ 65 | ESC_read (ESCREG_EEDATA, eep_buf, EEP_WRITE_SIZE); 66 | if (EEP_write (stat.addr * sizeof(uint16_t), eep_buf, EEP_WRITE_SIZE) != 0) { 67 | stat.contstat.bits.ackErr = 1; 68 | } 69 | break; 70 | 71 | default: 72 | stat.contstat.bits.ackErr = 1; 73 | } 74 | 75 | /* acknowledge command */ 76 | stat.contstat.reg = htoes(stat.contstat.reg); 77 | ESC_write (ESCREG_EECONTSTAT, &stat.contstat.reg, sizeof(uint16_t)); 78 | } 79 | } 80 | 81 | -------------------------------------------------------------------------------- /examples/SOES_arduino/lib/soes/esc_eep.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | /** \file 7 | * \brief 8 | * Headerfile for esc_eep.c 9 | */ 10 | 11 | #ifndef __esc_eep__ 12 | #define __esc_eep__ 13 | 14 | #include 15 | #include "esc.h" 16 | 17 | /* EEPROM commands */ 18 | #define EEP_CMD_IDLE 0x0 19 | #define EEP_CMD_READ 0x1 20 | #define EEP_CMD_WRITE 0x2 21 | #define EEP_CMD_RELOAD 0x3 22 | 23 | /* read/write size */ 24 | #define EEP_READ_SIZE 8 25 | #define EEP_WRITE_SIZE 2 26 | 27 | /* CONSTAT register content */ 28 | typedef struct CC_PACKED 29 | { 30 | union { 31 | uint16_t reg; 32 | struct { 33 | uint8_t wrEnable:1; 34 | uint8_t reserved:4; 35 | uint8_t eeEmulated:1; 36 | uint8_t eightByteRead:1; 37 | uint8_t twoByteAddr:1; 38 | 39 | uint8_t cmdReg:3; 40 | uint8_t csumErr:1; 41 | uint8_t eeLoading:1; 42 | uint8_t ackErr:1; 43 | uint8_t wrErr:1; 44 | uint8_t busy:1; 45 | } bits; 46 | } contstat; 47 | 48 | uint32_t addr; 49 | } eep_stat_t; 50 | 51 | /** 52 | * ECAT EEPROM configuration area data structure 53 | */ 54 | typedef union eep_config 55 | { 56 | struct 57 | { 58 | uint16_t pdi_control; 59 | uint16_t pdi_configuration; 60 | uint16_t sync_impulse_len; 61 | uint16_t pdi_configuration2; 62 | uint16_t configured_station_alias; 63 | uint8_t reserved[4]; 64 | uint16_t checksum; 65 | }; 66 | uint32_t dword[4]; /**< Four 32 bit double word equivalent to 8 16 bit configuration area word. */ 67 | }eep_config_t; 68 | 69 | /* periodic task */ 70 | void EEP_process (void); 71 | 72 | /* From hardware file */ 73 | void EEP_init (void); 74 | int8_t EEP_read (uint32_t addr, uint8_t *data, uint16_t size); 75 | int8_t EEP_write (uint32_t addr, uint8_t *data, uint16_t size); 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /examples/SOES_arduino/lib/soes/esc_eoe.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | /** \file 7 | * \brief 8 | * Headerfile for esc_eoe.c 9 | */ 10 | 11 | #ifndef __esc_eoe__ 12 | #define __esc_eoe__ 13 | 14 | #include 15 | 16 | typedef struct eoe_pbuf 17 | { 18 | /** Pointer to frame buffer type used by a TCP/IP stack. (Not mandatory) */ 19 | void * pbuf; 20 | /** Pointer to frame buffer to send or read from */ 21 | uint8_t * payload; 22 | /** Length of data in frame buffer */ 23 | size_t len; 24 | } eoe_pbuf_t; 25 | 26 | typedef struct eoe_cfg 27 | { 28 | /** Callback function to get a frame buffer for storage of received frame */ 29 | void (*get_buffer) (eoe_pbuf_t * ebuf); 30 | /** Callback function to free a frame buffer */ 31 | void (*free_buffer) (eoe_pbuf_t * ebuf); 32 | /** Callback function to read local settings and update EtherCAT variables 33 | * to be delivered to the EtherCAT Master 34 | */ 35 | int (*load_eth_settings) (void); 36 | /** Callback function to read settings provided by the EtherCAT master 37 | * and store to local settings. 38 | */ 39 | int (*store_ethernet_settings) (void); 40 | /** Callback to frame receive function in TCP(IP stack, 41 | * caller should free the buffer 42 | * */ 43 | void (*handle_recv_buffer) (uint8_t port, eoe_pbuf_t * ebuf); 44 | /** Callback to fetch a buffer to send */ 45 | int (*fetch_send_buffer) (uint8_t port, eoe_pbuf_t * ebuf); 46 | /** Callback to notify the application fragment sent */ 47 | void (*fragment_sent_event) (void); 48 | } eoe_cfg_t; 49 | 50 | int EOE_ecat_get_mac (uint8_t port, uint8_t mac[]); 51 | int EOE_ecat_get_ip (uint8_t port, uint32_t * ip); 52 | int EOE_ecat_get_subnet (uint8_t port, uint32_t * subnet); 53 | int EOE_ecat_get_gateway (uint8_t port, uint32_t * default_gateway); 54 | int EOE_ecat_get_dns_ip (uint8_t port, uint32_t * dns_ip); 55 | int EOE_ecat_get_dns_name (uint8_t port, char * dns_name); 56 | int EOE_ecat_set_mac (uint8_t port, uint8_t mac[]); 57 | int EOE_ecat_set_ip (uint8_t port, uint32_t ip); 58 | int EOE_ecat_set_subnet (uint8_t port, uint32_t subnet); 59 | int EOE_ecat_set_gateway (uint8_t port, uint32_t default_gateway); 60 | int EOE_ecat_set_dns_ip (uint8_t port, uint32_t dns_ip); 61 | int EOE_ecat_set_dns_name (uint8_t port, char * dns_name); 62 | 63 | void EOE_config (eoe_cfg_t * cfg); 64 | void EOE_init (void); 65 | void ESC_eoeprocess (void); 66 | void ESC_eoeprocess_tx (void); 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /examples/SOES_arduino/lib/soes/esc_foe.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | /** \file 7 | * \brief 8 | * Headerfile for esc_foe.c 9 | */ 10 | 11 | #ifndef __esc_foe__ 12 | #define __esc_foe__ 13 | 14 | #include 15 | 16 | /** Maximum number of characters allowed in a file name. */ 17 | #define FOE_FN_MAX 31 18 | 19 | typedef struct foe_file_cfg foe_file_cfg_t; 20 | struct foe_file_cfg 21 | { 22 | /** Name of file to receive from master */ 23 | const char * name; 24 | /** Size of file,sizeof data we can recv */ 25 | uint32_t max_data; 26 | /** Where to store the data initially */ 27 | uint32_t dest_start_address; 28 | /** Current address during write of file */ 29 | uint32_t address_offset; 30 | /** Calculated size of file received */ 31 | uint32_t total_size; 32 | /** FoE password */ 33 | uint32_t filepass; 34 | /** This file can be written only in BOOT state. Intended for FW files */ 35 | uint8_t write_only_in_boot; 36 | /** for feature use */ 37 | uint32_t padding:24; 38 | /** Pointer to application foe write function */ 39 | uint32_t (*write_function) (foe_file_cfg_t * self, uint8_t * data, size_t length); 40 | }; 41 | 42 | typedef struct foe_cfg 43 | { 44 | /** Allocate static in caller func to fit buffer_size */ 45 | uint8_t * fbuffer; 46 | /** Buffer size before we flush to destination */ 47 | uint32_t buffer_size; 48 | /** Number of files used in firmware update */ 49 | uint32_t n_files; 50 | /** Pointer to files configured to be used by FoE */ 51 | foe_file_cfg_t * files; 52 | } foe_cfg_t; 53 | 54 | typedef struct CC_PACKED 55 | { 56 | /** Current FoE state, ex. Waiting for ACK, Waiting for DATA */ 57 | uint8_t foestate; 58 | /** Current file buffer position, evaluated against foe file buffer size 59 | * when to flush 60 | */ 61 | uint16_t fbufposition; 62 | /** Frame number in read or write sequence */ 63 | uint32_t foepacket; 64 | /** Current position in file to be handled by FoE request */ 65 | uint32_t fposition; 66 | /** Previous position in file to be handled by FoE request */ 67 | uint32_t fprevposition; 68 | /** End position of allocated disk space for FoE requested file */ 69 | uint32_t fend; 70 | } _FOEvar; 71 | 72 | /* Initializes FoE state. */ 73 | void FOE_config (foe_cfg_t * cfg); 74 | void FOE_init (void); 75 | void ESC_foeprocess (void); 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /examples/SOES_arduino/lib/soes/hal/arduino-lan9252/spi.cpp: -------------------------------------------------------------------------------- 1 | #include "spi.hpp" 2 | // #include 3 | #include 4 | 5 | 6 | char SCS = ESC_GPIO_Pin_CS; 7 | 8 | 9 | void spi_setup(void) 10 | { 11 | SPI.begin(); 12 | pinMode(SCS, OUTPUT); 13 | spi_unselect(0); 14 | delay(100); 15 | SPI.beginTransaction(SPISettings(SPIX_ESC_SPEED, MSBFIRST, SPI_MODE0)); 16 | 17 | } 18 | 19 | void spi_select (int8_t board) 20 | { 21 | // Soft CSN 22 | #if SCS_ACTIVE_POLARITY == SCS_LOW 23 | digitalWrite(SCS, LOW); 24 | #endif 25 | } 26 | 27 | void spi_unselect (int8_t board) 28 | { 29 | // Soft CSN 30 | #if SCS_ACTIVE_POLARITY == SCS_LOW 31 | digitalWrite(SCS, HIGH); 32 | #endif 33 | } 34 | 35 | inline static uint8_t spi_transfer_byte(uint8_t byte) 36 | { 37 | return SPI.transfer(byte); 38 | // AVR will need handling last byte transfer difference, 39 | // but then again they pobably wont even fit EtherCAT stack in RAM 40 | // so no need to care for now 41 | } 42 | 43 | void write (int8_t board, uint8_t *data, uint8_t size) 44 | { 45 | for(int i = 0; i < size; ++i) 46 | { 47 | spi_transfer_byte(data[i]); 48 | } 49 | } 50 | 51 | void read (int8_t board, uint8_t *result, uint8_t size) 52 | { 53 | for(int i = 0; i < size; ++i) 54 | { 55 | result[i] = spi_transfer_byte(DUMMY_BYTE); 56 | } 57 | } 58 | 59 | 60 | void spi_bidirectionally_transfer (int8_t board, uint8_t *result, uint8_t *data, uint8_t size) 61 | { 62 | for(int i = 0; i < size; ++i) 63 | { 64 | result[i] = spi_transfer_byte(data[i]); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /examples/SOES_arduino/lib/soes/hal/arduino-lan9252/spi.h: -------------------------------------------------------------------------------- 1 | #ifndef SRC_APP_SPI_H_ 2 | #define SRC_APP_SPI_H_ 3 | 4 | #include 5 | 6 | 7 | void spi_setup(void); 8 | void spi_select (int8_t board); 9 | void spi_unselect (int8_t board); 10 | void write (int8_t board, uint8_t *data, uint8_t size); 11 | void read (int8_t board, uint8_t *result, uint8_t size); 12 | void spi_bidirectionally_transfer (int8_t board, uint8_t *result, uint8_t *data, uint8_t size); 13 | 14 | 15 | #endif /* SRC_APP_SPI_H_ */ 16 | -------------------------------------------------------------------------------- /examples/SOES_arduino/lib/soes/hal/arduino-lan9252/spi.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SRC_APP_SPI_H_ 2 | #define SRC_APP_SPI_H_ 3 | 4 | #include 5 | 6 | #define SCS_LOW 0 7 | #define SCS_HIGH 1 8 | #define SCS_ACTIVE_POLARITY SCS_LOW 9 | 10 | #define SPIX_ESC SPI1 11 | #define SPIX_ESC_SPEED 18000000 12 | #define ESC_GPIO_Pin_CS PA4 13 | 14 | 15 | #define DUMMY_BYTE 0xFF 16 | 17 | 18 | extern "C" void spi_setup(void); 19 | extern "C" void spi_select (int8_t board); 20 | extern "C" void spi_unselect (int8_t board); 21 | extern "C" void write (int8_t board, uint8_t *data, uint8_t size); 22 | extern "C" void read (int8_t board, uint8_t *result, uint8_t size); 23 | extern "C" void spi_bidirectionally_transfer (int8_t board, uint8_t *result, uint8_t *data, uint8_t size); 24 | 25 | 26 | #endif /* SRC_APP_SPI_H_ */ 27 | -------------------------------------------------------------------------------- /examples/SOES_arduino/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | [env:bluepill_f103c8] 12 | platform = ststm32 13 | board = bluepill_f103c8 14 | framework = arduino 15 | 16 | upload_protocol = blackmagic 17 | debug_tool = blackmagic 18 | upload_port = COM9 ;\\.\COM17 19 | debug_port = COM9 20 | 21 | build_flags = 22 | -D SERIAL_SPEED=115200 23 | -D LAN9252 24 | 25 | monitor_speed = 115200 26 | monitor_port = COM5 27 | -------------------------------------------------------------------------------- /examples/SOES_arduino/test/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for PlatformIO Unit Testing and project tests. 3 | 4 | Unit Testing is a software testing method by which individual units of 5 | source code, sets of one or more MCU program modules together with associated 6 | control data, usage procedures, and operating procedures, are tested to 7 | determine whether they are fit for use. Unit testing finds problems early 8 | in the development cycle. 9 | 10 | More information about PlatformIO Unit Testing: 11 | - https://docs.platformio.org/page/plus/unit-testing.html 12 | -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See http://go.microsoft.com/fwlink/?LinkId=827846 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "platformio.platformio-ide" 6 | ], 7 | "unwantedRecommendations": [ 8 | "ms-vscode.cpptools-extension-pack" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // AUTOMATICALLY GENERATED FILE. PLEASE DO NOT MODIFY IT MANUALLY 2 | // 3 | // PIO Unified Debugger 4 | // 5 | // Documentation: https://docs.platformio.org/page/plus/debugging.html 6 | // Configuration: https://docs.platformio.org/page/projectconf/section_env_debug.html 7 | 8 | { 9 | "version": "0.2.0", 10 | "configurations": [ 11 | { 12 | "type": "platformio-debug", 13 | "request": "launch", 14 | "name": "PIO Debug", 15 | "executable": "d:/EtherCAT/ecat_servo_arduino/SOES_arduino_avr/.pio/build/ATmega2560/firmware.elf", 16 | "projectEnvName": "ATmega2560", 17 | "toolchainBinDir": "C:/Users/user/.platformio/packages/toolchain-atmelavr/bin", 18 | "internalConsoleOptions": "openOnSessionStart", 19 | "preLaunchTask": { 20 | "type": "PlatformIO", 21 | "task": "Pre-Debug" 22 | } 23 | }, 24 | { 25 | "type": "platformio-debug", 26 | "request": "launch", 27 | "name": "PIO Debug (skip Pre-Debug)", 28 | "executable": "d:/EtherCAT/ecat_servo_arduino/SOES_arduino_avr/.pio/build/ATmega2560/firmware.elf", 29 | "projectEnvName": "ATmega2560", 30 | "toolchainBinDir": "C:/Users/user/.platformio/packages/toolchain-atmelavr/bin", 31 | "internalConsoleOptions": "openOnSessionStart" 32 | }, 33 | { 34 | "type": "platformio-debug", 35 | "request": "launch", 36 | "name": "PIO Debug (without uploading)", 37 | "executable": "d:/EtherCAT/ecat_servo_arduino/SOES_arduino_avr/.pio/build/ATmega2560/firmware.elf", 38 | "projectEnvName": "ATmega2560", 39 | "toolchainBinDir": "C:/Users/user/.platformio/packages/toolchain-atmelavr/bin", 40 | "internalConsoleOptions": "openOnSessionStart", 41 | "loadMode": "manual" 42 | } 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/README.md: -------------------------------------------------------------------------------- 1 | # SOES with PlatformIO 2 | 3 | ## Using LAN9252 EtherCAT board over SPI with AVR 4 | 5 | This is SOES project compiled for Arduino board with ATMega (AVR) microcontroller. First version of SOES was originally targetting ATmega1281 (8 KB SRAM) 6 | CoE data structures eat about 7 KB of RAM. Without wild hacks I dont see practical way to shrink it to under 2KB so unfortunately Arduino UNO (ATMega328) is out of question. Arduino Mega (ATMega 2560) has enough memory, but few changes were needed 7 | 8 | ## Changes to STM32 project: 9 | - `esi/cc.h` uses atomic macros from ``, not `` 10 | - clean `esc_cfg_t config` initialization: all fields need to be referenced in initialization to avoid error `sorry, unimplemented: non-trivial designated initializers not supported` 11 | 12 | ### TODO 13 | - test on actual hardware: Arduino Mega with ATMega2560 14 | - in `soes/hal` for AVR project, Arduino `SPI.h` header is not available. avr-g++ is older compiler, maybe nested setup (CPP library SPI in C library SOES in CPP project) is not available. Instead of diving into pio internals, just declare and use SPI registers 15 | - resolve build warnings 16 | 17 | ## MCU pinout 18 | 19 | ### Arduino Mega 20 | 21 | | SPI | Arduino | LAN9252 | 22 | | ---- |:-------:|:-------:| 23 | | CSN | 9 | D5 | 24 | | SCK | 13 | D9 | 25 | | MISO | 12 | D1/SIO1 | 26 | | MOSI | 11 | D0/SIO0 | 27 | 28 | # Status 29 | 30 | - AVR Arduino - compiles, eats 7KB RAM, SPI driver is not connected 31 | Remember to use levels shifter between AVR and LAN252. 32 | 33 | # Results - benchmarks - TODO 34 | 35 | Measured is PDI communication cycle time (`EASYCAT.MainTask();`) on CiA DS402 PDOs. That is 6B each - RxPDO { uint16t; int32_t }; RxPDO { uint16t; int32_t } 36 | 37 | | ESC | SSC | MCU | SPI driver | SPI speed | value [us] | 38 | | ------- | --------- |:-------:|:----------:|:---------:|:----------:| 39 | | LAN9252 | SOES | AtM328P | Arduino | 8000000 | [TODO] | 40 | -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/include/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project header files. 3 | 4 | A header file is a file containing C declarations and macro definitions 5 | to be shared between several project source files. You request the use of a 6 | header file in your project source file (C, C++, etc) located in `src` folder 7 | by including it, with the C preprocessing directive `#include'. 8 | 9 | ```src/main.c 10 | 11 | #include "header.h" 12 | 13 | int main (void) 14 | { 15 | ... 16 | } 17 | ``` 18 | 19 | Including a header file produces the same results as copying the header file 20 | into each source file that needs it. Such copying would be time-consuming 21 | and error-prone. With a header file, the related declarations appear 22 | in only one place. If they need to be changed, they can be changed in one 23 | place, and programs that include the header file will automatically use the 24 | new version when next recompiled. The header file eliminates the labor of 25 | finding and changing all the copies as well as the risk that a failure to 26 | find one copy will result in inconsistencies within a program. 27 | 28 | In C, the usual convention is to give header files names that end with `.h'. 29 | It is most portable to use only letters, digits, dashes, and underscores in 30 | header file names, and at most one dot. 31 | 32 | Read more about using header files in official GCC documentation: 33 | 34 | * Include Syntax 35 | * Include Operation 36 | * Once-Only Headers 37 | * Computed Includes 38 | 39 | https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html 40 | -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/include/main.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAIN_H__ 2 | #define __MAIN_H__ 3 | 4 | #include 5 | 6 | #if defined(ARDUINO_MEGA) 7 | 8 | const char SpiCS_Pin = 10; // TODO set right pinout for Mega 9 | 10 | const int BitOut0 = 2; // digital output bit 0 11 | const int BitOut1 = 3; // digital output bit 1 12 | const int BitOut2 = 4; // digital output bit 2 13 | const int BitOut3 = 5; // digital output bit 3 14 | const int BitOut4 = 6; // digital output bit 4 15 | const int BitOut5 = 7; // digital output bit 5 16 | const int BitOut6 = 8; // digital output bit 6 17 | const int BitOut7 = 9; // digital output bit 7 18 | 19 | #else 20 | #error "Selected PIO env has no hardware configuration" 21 | #endif 22 | 23 | void Application(); 24 | 25 | #endif // #ifndef __MAIN_H__ -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/lib/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for project specific (private) libraries. 3 | PlatformIO will compile them to static libraries and link into executable file. 4 | 5 | The source code of each library should be placed in a an own separate directory 6 | ("lib/your_library_name/[here are source files]"). 7 | 8 | For example, see a structure of the following two libraries `Foo` and `Bar`: 9 | 10 | |--lib 11 | | | 12 | | |--Bar 13 | | | |--docs 14 | | | |--examples 15 | | | |--src 16 | | | |- Bar.c 17 | | | |- Bar.h 18 | | | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html 19 | | | 20 | | |--Foo 21 | | | |- Foo.c 22 | | | |- Foo.h 23 | | | 24 | | |- README --> THIS FILE 25 | | 26 | |- platformio.ini 27 | |--src 28 | |- main.c 29 | 30 | and a contents of `src/main.c`: 31 | ``` 32 | #include 33 | #include 34 | 35 | int main (void) 36 | { 37 | ... 38 | } 39 | 40 | ``` 41 | 42 | PlatformIO Library Dependency Finder will find automatically dependent 43 | libraries scanning project source files. 44 | 45 | More information about PlatformIO Library Dependency Finder 46 | - https://docs.platformio.org/page/librarymanager/ldf.html 47 | -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/lib/soes-esi/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | soes-esi 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/lib/soes-esi/cia402.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/examples/SOES_arduino_avr/lib/soes-esi/cia402.bin -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/lib/soes-esi/cia402patched.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/examples/SOES_arduino_avr/lib/soes-esi/cia402patched.bin -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/lib/soes-esi/ecat_options.h: -------------------------------------------------------------------------------- 1 | #ifndef __ECAT_OPTIONS_H__ 2 | #define __ECAT_OPTIONS_H__ 3 | 4 | #define USE_FOE 0 5 | #define USE_EOE 0 6 | 7 | #define MBXSIZE 512 8 | #define MBXSIZEBOOT 512 9 | #define MBXBUFFERS 3 10 | 11 | #define MBX0_sma 0x1000 12 | #define MBX0_sml MBXSIZE 13 | #define MBX0_sme MBX0_sma+MBX0_sml-1 14 | #define MBX0_smc 0x26 15 | #define MBX1_sma MBX0_sma+MBX0_sml 16 | #define MBX1_sml MBXSIZE 17 | #define MBX1_sme MBX1_sma+MBX1_sml-1 18 | #define MBX1_smc 0x22 19 | 20 | #define MBX0_sma_b 0x1000 21 | #define MBX0_sml_b MBXSIZEBOOT 22 | #define MBX0_sme_b MBX0_sma_b+MBX0_sml_b-1 23 | #define MBX0_smc_b 0x26 24 | #define MBX1_sma_b MBX0_sma_b+MBX0_sml_b 25 | #define MBX1_sml_b MBXSIZEBOOT 26 | #define MBX1_sme_b MBX1_sma_b+MBX1_sml_b-1 27 | #define MBX1_smc_b 0x22 28 | 29 | #define SM2_sma 0x1400 30 | #define SM2_smc 0x24 31 | #define SM2_act 1 32 | #define SM3_sma 0x1A00 33 | #define SM3_smc 0x20 34 | #define SM3_act 1 35 | 36 | #define MAX_MAPPINGS_SM2 2 37 | #define MAX_MAPPINGS_SM3 2 38 | 39 | #define MAX_RXPDO_SIZE 512 40 | #define MAX_TXPDO_SIZE 512 41 | 42 | #endif /* __ECAT_OPTIONS_H__ */ 43 | -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/lib/soes-esi/utypes.h: -------------------------------------------------------------------------------- 1 | #ifndef __UTYPES_H__ 2 | #define __UTYPES_H__ 3 | 4 | #include "cc.h" 5 | 6 | /* Object dictionary storage */ 7 | 8 | typedef struct 9 | { 10 | /* Identity */ 11 | 12 | uint32_t serial; 13 | 14 | /* Inputs */ 15 | 16 | uint16_t Status_Word; 17 | uint32_t Position_actual; 18 | 19 | /* Outputs */ 20 | 21 | uint16_t Control_Word; 22 | uint32_t Target_position; 23 | 24 | /* Parameters */ 25 | 26 | uint8_t Error_register; 27 | struct 28 | { 29 | uint32_t Local_Error_Reaction; 30 | uint16_t SyncErrorCounterLimit; 31 | } ErrorSettings; 32 | struct 33 | { 34 | uint16_t Sync_mode; 35 | uint32_t CycleTime; 36 | uint32_t ShiftTime; 37 | uint16_t Sync_modes_supported; 38 | uint32_t Minimum_Cycle_Time; 39 | uint32_t Calc_and_Copy_Time; 40 | uint32_t Minimum_Delay_Time; 41 | uint16_t GetCycleTime; 42 | uint32_t DelayTime; 43 | uint32_t Sync0CycleTime; 44 | uint16_t SM_event_missed_counter; 45 | uint16_t CycleTimeTooSmallCnt; 46 | uint16_t Shift_too_short_counter; 47 | uint16_t RxPDOToggleFailed; 48 | uint32_t Minimum_Cycle_Distance; 49 | uint32_t Maximum_Cycle_Distance; 50 | uint32_t Minimum_SM_Sync_Distance; 51 | uint32_t Maximum_SM_Sync_Distance; 52 | uint8_t SyncError; 53 | } Sync_Manager_2_Parameters; 54 | struct 55 | { 56 | uint16_t Sync_mode; 57 | uint32_t CycleTime; 58 | uint32_t ShiftTime; 59 | uint16_t Sync_modes_supported; 60 | uint32_t Minimum_Cycle_Time; 61 | uint32_t Calc_and_Copy_Time; 62 | uint32_t Minimum_Delay_Time; 63 | uint16_t GetCycleTime; 64 | uint32_t DelayTime; 65 | uint32_t Sync0CycleTime; 66 | uint16_t SM_event_missed_counter; 67 | uint16_t CycleTimeTooSmallCnt; 68 | uint16_t Shift_too_short_counter; 69 | uint16_t RxPDOToggleFailed; 70 | uint32_t Minimum_Cycle_Distance; 71 | uint32_t Maximum_Cycle_Distance; 72 | uint32_t Minimum_SM_Sync_Distance; 73 | uint32_t Maximum_SM_Sync_Distance; 74 | uint8_t SyncError; 75 | } Sync_Manager_3_Parameters; 76 | int8_t Modes_of_operation; 77 | int8_t Mode_of_operation_display; 78 | uint32_t Supported_drive_modes; 79 | 80 | } _Objects; 81 | 82 | extern _Objects Obj; 83 | 84 | #endif /* __UTYPES_H__ */ 85 | -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/lib/soes/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # NOTE: add headers to make them show up in an IDE 3 | add_library (soes 4 | esc.c 5 | esc.h 6 | esc_coe.c 7 | esc_coe.h 8 | esc_foe.c 9 | esc_foe.h 10 | esc_eoe.c 11 | esc_eoe.h 12 | esc_eep.c 13 | esc_eep.h 14 | ecat_slv.c 15 | ecat_slv.h 16 | options.h 17 | ${HAL_SOURCES} 18 | ) 19 | 20 | include_directories(${HAL_INCLUDES}) 21 | 22 | install (TARGETS soes DESTINATION bin) 23 | install (FILES 24 | esc.h 25 | esc_coe.h 26 | esc_foe.h 27 | esc_eoe.h 28 | esc_eep.h 29 | DESTINATION include) 30 | -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/lib/soes/doc/images/esi_pdo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/examples/SOES_arduino_avr/lib/soes/doc/images/esi_pdo.png -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/lib/soes/doc/images/sii_pdo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kubabuda/ecat_servo/6d523100d500cb54b51d47e53ae64e3c849d2496/examples/SOES_arduino_avr/lib/soes/doc/images/sii_pdo.png -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/lib/soes/doc/soes.dox: -------------------------------------------------------------------------------- 1 | /** 2 | * \mainpage Simple Open EtherCAT Slave or SOES 3 | * 4 | * \section start Tutorial 5 | * For a tutorial on SOES See tutorial.txt 6 | * 7 | * \section overview Overview 8 | * SOES is an EtherCAT slave stack written in c. Its purpose is to learn and 9 | * to use. All users are invited to study the source to get an understanding 10 | * how an EtherCAT slave function 11 | * 12 | * Features as of 1.0.0 : 13 | * - Address offset based HAL for easy ESC read/write access via any interface 14 | * - Mailbox with data link layer 15 | * - CoE 16 | * - Object dictionary 17 | * - SDO read and write for all sizes including segmented transfers 18 | * - Easy portable C-code suited for embedded applications 19 | * - Fixed PDO mapping 20 | * - FoE with bootstrap template 21 | * - Support for Little and Big endian targets. 22 | * - Polling for interrupts 23 | * 24 | * \section legal Legal notice 25 | * SOES Simple Open EtherCAT Slave \n 26 | * Copyright (C) 2007-2013 Arthur Ketels \n 27 | * Copyright (C) 2012-2013 rt-labs \n 28 | * 29 | * SOES is free software; you can redistribute it and/or modify it under 30 | * the terms of the GNU General Public License version 2 as published by the Free 31 | * Software Foundation. 32 | * 33 | * SOES is distributed in the hope that it will be useful, but WITHOUT ANY 34 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or 35 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 36 | * for more details. 37 | * 38 | * As a special exception, if other files instantiate templates or use macros 39 | * or inline functions from this file, or you compile this file and link it 40 | * with other works to produce a work based on this file, this file does not 41 | * by itself cause the resulting work to be covered by the GNU General Public 42 | * License. However the source code for this file must still be made available 43 | * in accordance with section (3) of the GNU General Public License. 44 | * 45 | * This exception does not invalidate any other reasons why a work based on 46 | * this file might be covered by the GNU General Public License. 47 | * 48 | * The EtherCAT Technology, the trade name and logo "EtherCAT" are the intellectual 49 | * property of, and protected by Beckhoff Automation GmbH. 50 | */ 51 | -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/lib/soes/ecat_slv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | #ifndef __ECAT_SLV_H__ 7 | #define __ECAT_SLV_H__ 8 | 9 | #include "options.h" 10 | #include "esc.h" 11 | 12 | /** 13 | * This function is called when to get input values 14 | */ 15 | void cb_get_inputs(); 16 | 17 | /** 18 | * This function is called when to set outputs values 19 | */ 20 | void cb_set_outputs(); 21 | 22 | /** Set the watchdog count value 23 | * 24 | * @param[in] watchdogcnt = new watchdog count value 25 | */ 26 | void APP_setwatchdog (int watchdogcnt); 27 | 28 | #define DIG_PROCESS_INPUTS_FLAG 0x01 29 | #define DIG_PROCESS_OUTPUTS_FLAG 0x02 30 | #define DIG_PROCESS_WD_FLAG 0x04 31 | #define DIG_PROCESS_APP_HOOK_FLAG 0x08 32 | /** Implements the watch-dog counter to count if we should make a state change 33 | * due to missing incoming SM2 events. Updates local I/O and run the application 34 | * in the following order, call read EtherCAT outputs, execute user provided 35 | * application hook and call write EtherCAT inputs. 36 | * 37 | * @param[in] flags = User input what to execute 38 | */ 39 | void DIG_process (uint8_t flags); 40 | 41 | /** 42 | * Handler for SM change, SM0/1, AL CONTROL and EEPROM events, the application 43 | * control what interrupts that should be served and re-activated with 44 | * event mask argument 45 | * 46 | * @param[in] event_mask = Event mask for interrupts to serve and re-activate 47 | * after served 48 | */ 49 | void ecat_slv_worker (uint32_t event_mask); 50 | 51 | /** 52 | * Poll SM0/1, EEPROM and AL CONTROL events in a SM/DC synchronization 53 | * application 54 | */ 55 | void ecat_slv_poll (void); 56 | 57 | /** 58 | * Poll all events in a free-run application 59 | */ 60 | void ecat_slv (void); 61 | 62 | /** 63 | * Initialize the slave stack 64 | * 65 | * @param[in] config = User input how to configure the stack 66 | */ 67 | void ecat_slv_init (esc_cfg_t * config); 68 | 69 | #endif /* __ECAT_SLV_H__ */ 70 | -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/lib/soes/esc_eep.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | /** \file 7 | * \brief 8 | * ESI EEPROM emulator module. 9 | */ 10 | 11 | #include "cc.h" 12 | #include "esc.h" 13 | #include "esc_eep.h" 14 | 15 | #include 16 | 17 | static uint8_t eep_buf[8]; 18 | 19 | /** EPP periodic task of ESC side EEPROM emulation. 20 | * 21 | */ 22 | void EEP_process (void) 23 | { 24 | eep_stat_t stat; 25 | 26 | /* check for eeprom event */ 27 | if ((ESCvar.ALevent & ESCREG_ALEVENT_EEP) == 0) { 28 | return; 29 | } 30 | 31 | while (1) { 32 | /* read eeprom status */ 33 | ESC_read (ESCREG_EECONTSTAT, &stat, sizeof (eep_stat_t)); 34 | stat.contstat.reg = etohs(stat.contstat.reg); 35 | stat.addr = etohl(stat.addr); 36 | 37 | /* check busy flag, exit if job finished */ 38 | if (!stat.contstat.bits.busy) { 39 | return; 40 | } 41 | 42 | /* clear error bits */ 43 | stat.contstat.bits.csumErr = 0; 44 | stat.contstat.bits.eeLoading = 0; 45 | stat.contstat.bits.ackErr = 0; 46 | stat.contstat.bits.wrErr = 0; 47 | 48 | /* process commands */ 49 | switch (stat.contstat.bits.cmdReg) { 50 | case EEP_CMD_IDLE: 51 | break; 52 | 53 | case EEP_CMD_READ: 54 | case EEP_CMD_RELOAD: 55 | /* handle read request */ 56 | if (EEP_read (stat.addr * sizeof(uint16_t), eep_buf, EEP_READ_SIZE) != 0) { 57 | stat.contstat.bits.ackErr = 1; 58 | } else { 59 | ESC_write (ESCREG_EEDATA, eep_buf, EEP_READ_SIZE); 60 | } 61 | break; 62 | 63 | case EEP_CMD_WRITE: 64 | /* handle write request */ 65 | ESC_read (ESCREG_EEDATA, eep_buf, EEP_WRITE_SIZE); 66 | if (EEP_write (stat.addr * sizeof(uint16_t), eep_buf, EEP_WRITE_SIZE) != 0) { 67 | stat.contstat.bits.ackErr = 1; 68 | } 69 | break; 70 | 71 | default: 72 | stat.contstat.bits.ackErr = 1; 73 | } 74 | 75 | /* acknowledge command */ 76 | stat.contstat.reg = htoes(stat.contstat.reg); 77 | ESC_write (ESCREG_EECONTSTAT, &stat.contstat.reg, sizeof(uint16_t)); 78 | } 79 | } 80 | 81 | -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/lib/soes/esc_eep.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | /** \file 7 | * \brief 8 | * Headerfile for esc_eep.c 9 | */ 10 | 11 | #ifndef __esc_eep__ 12 | #define __esc_eep__ 13 | 14 | #include 15 | #include "esc.h" 16 | 17 | /* EEPROM commands */ 18 | #define EEP_CMD_IDLE 0x0 19 | #define EEP_CMD_READ 0x1 20 | #define EEP_CMD_WRITE 0x2 21 | #define EEP_CMD_RELOAD 0x3 22 | 23 | /* read/write size */ 24 | #define EEP_READ_SIZE 8 25 | #define EEP_WRITE_SIZE 2 26 | 27 | /* CONSTAT register content */ 28 | typedef struct CC_PACKED 29 | { 30 | union { 31 | uint16_t reg; 32 | struct { 33 | uint8_t wrEnable:1; 34 | uint8_t reserved:4; 35 | uint8_t eeEmulated:1; 36 | uint8_t eightByteRead:1; 37 | uint8_t twoByteAddr:1; 38 | 39 | uint8_t cmdReg:3; 40 | uint8_t csumErr:1; 41 | uint8_t eeLoading:1; 42 | uint8_t ackErr:1; 43 | uint8_t wrErr:1; 44 | uint8_t busy:1; 45 | } bits; 46 | } contstat; 47 | 48 | uint32_t addr; 49 | } eep_stat_t; 50 | 51 | /** 52 | * ECAT EEPROM configuration area data structure 53 | */ 54 | typedef union eep_config 55 | { 56 | struct 57 | { 58 | uint16_t pdi_control; 59 | uint16_t pdi_configuration; 60 | uint16_t sync_impulse_len; 61 | uint16_t pdi_configuration2; 62 | uint16_t configured_station_alias; 63 | uint8_t reserved[4]; 64 | uint16_t checksum; 65 | }; 66 | uint32_t dword[4]; /**< Four 32 bit double word equivalent to 8 16 bit configuration area word. */ 67 | }eep_config_t; 68 | 69 | /* periodic task */ 70 | void EEP_process (void); 71 | 72 | /* From hardware file */ 73 | void EEP_init (void); 74 | int8_t EEP_read (uint32_t addr, uint8_t *data, uint16_t size); 75 | int8_t EEP_write (uint32_t addr, uint8_t *data, uint16_t size); 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/lib/soes/esc_eoe.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | /** \file 7 | * \brief 8 | * Headerfile for esc_eoe.c 9 | */ 10 | 11 | #ifndef __esc_eoe__ 12 | #define __esc_eoe__ 13 | 14 | #include 15 | 16 | typedef struct eoe_pbuf 17 | { 18 | /** Pointer to frame buffer type used by a TCP/IP stack. (Not mandatory) */ 19 | void * pbuf; 20 | /** Pointer to frame buffer to send or read from */ 21 | uint8_t * payload; 22 | /** Length of data in frame buffer */ 23 | size_t len; 24 | } eoe_pbuf_t; 25 | 26 | typedef struct eoe_cfg 27 | { 28 | /** Callback function to get a frame buffer for storage of received frame */ 29 | void (*get_buffer) (eoe_pbuf_t * ebuf); 30 | /** Callback function to free a frame buffer */ 31 | void (*free_buffer) (eoe_pbuf_t * ebuf); 32 | /** Callback function to read local settings and update EtherCAT variables 33 | * to be delivered to the EtherCAT Master 34 | */ 35 | int (*load_eth_settings) (void); 36 | /** Callback function to read settings provided by the EtherCAT master 37 | * and store to local settings. 38 | */ 39 | int (*store_ethernet_settings) (void); 40 | /** Callback to frame receive function in TCP(IP stack, 41 | * caller should free the buffer 42 | * */ 43 | void (*handle_recv_buffer) (uint8_t port, eoe_pbuf_t * ebuf); 44 | /** Callback to fetch a buffer to send */ 45 | int (*fetch_send_buffer) (uint8_t port, eoe_pbuf_t * ebuf); 46 | /** Callback to notify the application fragment sent */ 47 | void (*fragment_sent_event) (void); 48 | } eoe_cfg_t; 49 | 50 | int EOE_ecat_get_mac (uint8_t port, uint8_t mac[]); 51 | int EOE_ecat_get_ip (uint8_t port, uint32_t * ip); 52 | int EOE_ecat_get_subnet (uint8_t port, uint32_t * subnet); 53 | int EOE_ecat_get_gateway (uint8_t port, uint32_t * default_gateway); 54 | int EOE_ecat_get_dns_ip (uint8_t port, uint32_t * dns_ip); 55 | int EOE_ecat_get_dns_name (uint8_t port, char * dns_name); 56 | int EOE_ecat_set_mac (uint8_t port, uint8_t mac[]); 57 | int EOE_ecat_set_ip (uint8_t port, uint32_t ip); 58 | int EOE_ecat_set_subnet (uint8_t port, uint32_t subnet); 59 | int EOE_ecat_set_gateway (uint8_t port, uint32_t default_gateway); 60 | int EOE_ecat_set_dns_ip (uint8_t port, uint32_t dns_ip); 61 | int EOE_ecat_set_dns_name (uint8_t port, char * dns_name); 62 | 63 | void EOE_config (eoe_cfg_t * cfg); 64 | void EOE_init (void); 65 | void ESC_eoeprocess (void); 66 | void ESC_eoeprocess_tx (void); 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/lib/soes/esc_foe.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed under the GNU General Public License version 2 with exceptions. See 3 | * LICENSE file in the project root for full license information 4 | */ 5 | 6 | /** \file 7 | * \brief 8 | * Headerfile for esc_foe.c 9 | */ 10 | 11 | #ifndef __esc_foe__ 12 | #define __esc_foe__ 13 | 14 | #include 15 | 16 | /** Maximum number of characters allowed in a file name. */ 17 | #define FOE_FN_MAX 31 18 | 19 | typedef struct foe_file_cfg foe_file_cfg_t; 20 | struct foe_file_cfg 21 | { 22 | /** Name of file to receive from master */ 23 | const char * name; 24 | /** Size of file,sizeof data we can recv */ 25 | uint32_t max_data; 26 | /** Where to store the data initially */ 27 | uint32_t dest_start_address; 28 | /** Current address during write of file */ 29 | uint32_t address_offset; 30 | /** Calculated size of file received */ 31 | uint32_t total_size; 32 | /** FoE password */ 33 | uint32_t filepass; 34 | /** This file can be written only in BOOT state. Intended for FW files */ 35 | uint8_t write_only_in_boot; 36 | /** for feature use */ 37 | uint32_t padding:24; 38 | /** Pointer to application foe write function */ 39 | uint32_t (*write_function) (foe_file_cfg_t * self, uint8_t * data, size_t length); 40 | }; 41 | 42 | typedef struct foe_cfg 43 | { 44 | /** Allocate static in caller func to fit buffer_size */ 45 | uint8_t * fbuffer; 46 | /** Buffer size before we flush to destination */ 47 | uint32_t buffer_size; 48 | /** Number of files used in firmware update */ 49 | uint32_t n_files; 50 | /** Pointer to files configured to be used by FoE */ 51 | foe_file_cfg_t * files; 52 | } foe_cfg_t; 53 | 54 | typedef struct CC_PACKED 55 | { 56 | /** Current FoE state, ex. Waiting for ACK, Waiting for DATA */ 57 | uint8_t foestate; 58 | /** Current file buffer position, evaluated against foe file buffer size 59 | * when to flush 60 | */ 61 | uint16_t fbufposition; 62 | /** Frame number in read or write sequence */ 63 | uint32_t foepacket; 64 | /** Current position in file to be handled by FoE request */ 65 | uint32_t fposition; 66 | /** Previous position in file to be handled by FoE request */ 67 | uint32_t fprevposition; 68 | /** End position of allocated disk space for FoE requested file */ 69 | uint32_t fend; 70 | } _FOEvar; 71 | 72 | /* Initializes FoE state. */ 73 | void FOE_config (foe_cfg_t * cfg); 74 | void FOE_init (void); 75 | void ESC_foeprocess (void); 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/lib/soes/hal/arduino-lan9252/spi.cpp: -------------------------------------------------------------------------------- 1 | #include "spi.hpp" 2 | #include 3 | 4 | // #include here (CPP library in C library in CPP project) is not working for AVR project 5 | // is working but its arduino-avr core, not library 6 | 7 | 8 | char SCS = ESC_GPIO_Pin_CS; 9 | // const char SpiCS_Pin = 10; 10 | 11 | #define SPI_DDR DDRB 12 | #define CS PINB2 13 | #define MOSI PINB3 14 | #define MISO PINB4 15 | #define SCK PINB5 16 | 17 | void spi_setup(void) 18 | { 19 | // SPI.begin(); 20 | pinMode(SCS, OUTPUT); 21 | // spi_unselect(0); 22 | // delay(100); 23 | // SPI.beginTransaction(SPISettings(SPIX_ESC_SPEED, MSBFIRST, SPI_MODE0)); 24 | // set CS, MOSI and SCK to output 25 | SPI_DDR |= (1 << CS) | (1 << MOSI) | (1 << SCK); 26 | 27 | // enable SPI, set as master, and clock to fosc/128 28 | SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0); 29 | 30 | } 31 | 32 | void spi_select (int8_t board) 33 | { 34 | // Soft CSN 35 | // #if SCS_ACTIVE_POLARITY == SCS_LOW 36 | // digitalWrite(SCS, LOW); 37 | // #endif 38 | } 39 | 40 | void spi_unselect (int8_t board) 41 | { 42 | // Soft CSN 43 | // #if SCS_ACTIVE_POLARITY == SCS_LOW 44 | // digitalWrite(SCS, HIGH); 45 | // #endif 46 | } 47 | 48 | inline static uint8_t spi_transfer_byte(uint8_t byte) 49 | { 50 | return 0;//SPI.transfer(byte); 51 | // AVR will need handling last byte transfer difference, 52 | // but then again they pobably wont even fit EtherCAT stack in RAM 53 | // so no need to care for now 54 | } 55 | 56 | void write (int8_t board, uint8_t *data, uint8_t size) 57 | { 58 | for(int i = 0; i < size; ++i) 59 | { 60 | spi_transfer_byte(data[i]); 61 | } 62 | } 63 | 64 | void read (int8_t board, uint8_t *result, uint8_t size) 65 | { 66 | for(int i = 0; i < size; ++i) 67 | { 68 | result[i] = spi_transfer_byte(DUMMY_BYTE); 69 | } 70 | } 71 | 72 | 73 | void spi_bidirectionally_transfer (int8_t board, uint8_t *result, uint8_t *data, uint8_t size) 74 | { 75 | for(int i = 0; i < size; ++i) 76 | { 77 | result[i] = spi_transfer_byte(data[i]); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/lib/soes/hal/arduino-lan9252/spi.h: -------------------------------------------------------------------------------- 1 | #ifndef SRC_APP_SPI_H_ 2 | #define SRC_APP_SPI_H_ 3 | 4 | #include 5 | 6 | 7 | void spi_setup(void); 8 | void spi_select (int8_t board); 9 | void spi_unselect (int8_t board); 10 | void write (int8_t board, uint8_t *data, uint8_t size); 11 | void read (int8_t board, uint8_t *result, uint8_t size); 12 | void spi_bidirectionally_transfer (int8_t board, uint8_t *result, uint8_t *data, uint8_t size); 13 | 14 | 15 | #endif /* SRC_APP_SPI_H_ */ 16 | -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/lib/soes/hal/arduino-lan9252/spi.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SRC_APP_SPI_H_ 2 | #define SRC_APP_SPI_H_ 3 | 4 | #include 5 | 6 | #define SCS_LOW 0 7 | #define SCS_HIGH 1 8 | #define SCS_ACTIVE_POLARITY SCS_LOW 9 | 10 | #define SPIX_ESC SPI1 11 | #define SPIX_ESC_SPEED 18000000 12 | #define ESC_GPIO_Pin_CS A4 13 | 14 | 15 | #define DUMMY_BYTE 0xFF 16 | 17 | 18 | extern "C" void spi_setup(void); 19 | extern "C" void spi_select (int8_t board); 20 | extern "C" void spi_unselect (int8_t board); 21 | extern "C" void write (int8_t board, uint8_t *data, uint8_t size); 22 | extern "C" void read (int8_t board, uint8_t *result, uint8_t size); 23 | extern "C" void spi_bidirectionally_transfer (int8_t board, uint8_t *result, uint8_t *data, uint8_t size); 24 | 25 | 26 | #endif /* SRC_APP_SPI_H_ */ 27 | -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; https://docs.platformio.org/page/projectconf.html 10 | 11 | 12 | [env:ATmega2560] 13 | platform = atmelavr 14 | board = ATmega2560 15 | framework = arduino 16 | build_flags = 17 | -D ARDUINO_MEGA -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | #ifdef __cplusplus 4 | extern "C" { 5 | #endif // __cplusplus 6 | 7 | #include "esc.h" 8 | #include "ecat_slv.h" 9 | #include "utypes.h" 10 | 11 | #ifdef __cplusplus 12 | } 13 | #endif // __cplusplus 14 | 15 | 16 | /* CANopen Object Dictionary */ 17 | _Objects Obj; 18 | 19 | 20 | /* Application hook declaration */ 21 | void ecatapp(); 22 | 23 | 24 | /* SOES configuration */ 25 | static esc_cfg_t config = { 26 | .user_arg = NULL, 27 | .use_interrupt = 0, 28 | .watchdog_cnt = 500, 29 | .skip_default_initialization = false, 30 | .set_defaults_hook = NULL, 31 | .pre_state_change_hook = NULL, 32 | .post_state_change_hook = NULL, 33 | .application_hook = ecatapp, 34 | .safeoutput_override = NULL, 35 | .pre_object_download_hook = NULL, 36 | .post_object_download_hook = NULL, 37 | .pre_object_upload_hook = NULL, 38 | .post_object_upload_hook = NULL, 39 | .rxpdo_override = NULL, 40 | .txpdo_override = NULL, 41 | .esc_hw_interrupt_enable = NULL, 42 | .esc_hw_interrupt_disable = NULL, 43 | .esc_hw_eep_handler = NULL, 44 | .esc_check_dc_handler = NULL, 45 | }; 46 | 47 | 48 | const uint8_t USER_BUTTON_PIN = 9; 49 | 50 | 51 | 52 | unsigned long previousMs = 0; 53 | 54 | const int OUTPUTS_COUNT = 8; 55 | 56 | const int outPins[8] = { 57 | BitOut0, BitOut1, BitOut2, BitOut3, BitOut4, BitOut5, BitOut6, BitOut7 58 | }; 59 | 60 | 61 | //---- setup --------------------------------------------------------------------------------------- 62 | 63 | void setup() 64 | { 65 | Serial.begin(9600); 66 | Serial.print("Initialization..."); 67 | ecat_slv_init(&config); 68 | 69 | for (size_t i = 0; i < OUTPUTS_COUNT; i++) 70 | { 71 | int outPin = outPins[i]; 72 | pinMode(outPin, OUTPUT); 73 | } 74 | 75 | 76 | } 77 | 78 | 79 | //---- main loop ---------------------------------------------------------------------------------------- 80 | 81 | void loop() 82 | { 83 | ecat_slv(); 84 | 85 | if (ESCvar.ALerror) { 86 | printf("\rAL Error %d", ESCvar.ALerror); 87 | } 88 | } 89 | 90 | 91 | //---- user application ------------------------------------------------------------------------------ 92 | 93 | void ecatapp() 94 | { 95 | static uint32_t next_status_print_ms = 200; 96 | 97 | if ((digitalRead(USER_BUTTON_PIN) == LOW) & (millis() > next_status_print_ms)) 98 | { 99 | Serial.write("\r\nPosition %lu\r\n", Obj.Target_position); 100 | next_status_print_ms = millis() + 200; 101 | } 102 | } 103 | 104 | 105 | void cb_get_inputs() 106 | { 107 | 108 | } 109 | 110 | void cb_set_outputs() 111 | { 112 | 113 | } 114 | -------------------------------------------------------------------------------- /examples/SOES_arduino_avr/test/README: -------------------------------------------------------------------------------- 1 | 2 | This directory is intended for PlatformIO Unit Testing and project tests. 3 | 4 | Unit Testing is a software testing method by which individual units of 5 | source code, sets of one or more MCU program modules together with associated 6 | control data, usage procedures, and operating procedures, are tested to 7 | determine whether they are fit for use. Unit testing finds problems early 8 | in the development cycle. 9 | 10 | More information about PlatformIO Unit Testing: 11 | - https://docs.platformio.org/page/plus/unit-testing.html 12 | --------------------------------------------------------------------------------