diff --git a/applications/raspberry_lan9252demo/CMakeLists.txt b/applications/raspberry_lan9252demo/CMakeLists.txt new file mode 100644 index 0000000..020dcf2 --- /dev/null +++ b/applications/raspberry_lan9252demo/CMakeLists.txt @@ -0,0 +1,8 @@ + +add_executable (soes-demo + main.c + slave_objectlist.c + ) +target_link_libraries(soes-demo LINK_PUBLIC soes bcm2835) +install (TARGETS soes-demo DESTINATION sbin) +install (PROGRAMS S60soes DESTINATION /etc/init.d) diff --git a/applications/raspberry_lan9252demo/S60soes b/applications/raspberry_lan9252demo/S60soes new file mode 100755 index 0000000..ba54622 --- /dev/null +++ b/applications/raspberry_lan9252demo/S60soes @@ -0,0 +1,40 @@ +#!/bin/sh +# +# soes Starts soes. +# + +start() { + printf "Starting soes: " + /usr/sbin/soes-demo & + touch /var/lock/soes-demo + echo "OK" +} +stop() { + printf "Stopping soes: " + killall soes-demo + rm -f /var/lock/soes-demo + echo "OK" +} +restart() { + stop + start +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart|reload) + restart + ;; + *) + echo "Usage: $0 {start|stop|restart}" + exit 1 +esac + +exit $? + + diff --git a/applications/raspberry_lan9252demo/ecat_options.h b/applications/raspberry_lan9252demo/ecat_options.h new file mode 100644 index 0000000..a41a7b6 --- /dev/null +++ b/applications/raspberry_lan9252demo/ecat_options.h @@ -0,0 +1,42 @@ +#ifndef __ECAT_OPTIONS_H__ +#define __ECAT_OPTIONS_H__ + +#define USE_FOE 1 +#define USE_EOE 0 + +#define MBXSIZE 128 +#define MBXSIZEBOOT 128 +#define MBXBUFFERS 3 + +#define MBX0_sma 0x1000 +#define MBX0_sml MBXSIZE +#define MBX0_sme MBX0_sma+MBX0_sml-1 +#define MBX0_smc 0x26 +#define MBX1_sma MBX0_sma+MBX0_sml +#define MBX1_sml MBXSIZE +#define MBX1_sme MBX1_sma+MBX1_sml-1 +#define MBX1_smc 0x22 + +#define MBX0_sma_b 0x1000 +#define MBX0_sml_b MBXSIZEBOOT +#define MBX0_sme_b MBX0_sma_b+MBX0_sml_b-1 +#define MBX0_smc_b 0x26 +#define MBX1_sma_b MBX0_sma_b+MBX0_sml_b +#define MBX1_sml_b MBXSIZEBOOT +#define MBX1_sme_b MBX1_sma_b+MBX1_sml_b-1 +#define MBX1_smc_b 0x22 + +#define SM2_sma 0x1100 +#define SM2_smc 0x24 +#define SM2_act 1 +#define SM3_sma 0x1180 +#define SM3_smc 0x20 +#define SM3_act 1 + +#define MAX_MAPPINGS_SM2 7 +#define MAX_MAPPINGS_SM3 7 + +#define MAX_RXPDO_SIZE 42 +#define MAX_TXPDO_SIZE 42 + +#endif /* __ECAT_OPTIONS_H__ */ diff --git a/applications/raspberry_lan9252demo/main.c b/applications/raspberry_lan9252demo/main.c new file mode 100644 index 0000000..02799c9 --- /dev/null +++ b/applications/raspberry_lan9252demo/main.c @@ -0,0 +1,108 @@ +#include +#include "ecat_slv.h" +#include "utypes.h" +#include + +/* Application variables */ +_Objects Obj; + +#define GPIO21 RPI_BPLUS_GPIO_J8_40 +#define GPIO20 RPI_BPLUS_GPIO_J8_38 +#define GPIO16 RPI_BPLUS_GPIO_J8_36 +#define GPIO12 RPI_BPLUS_GPIO_J8_32 +#define GPIO24 RPI_BPLUS_GPIO_J8_18 +#define GPIO23 RPI_BPLUS_GPIO_J8_16 +#define GPIO26 RPI_BPLUS_GPIO_J8_37 +#define GPIO19 RPI_BPLUS_GPIO_J8_35 +#define GPIO13 RPI_BPLUS_GPIO_J8_33 +#define GPIO06 RPI_BPLUS_GPIO_J8_31 +#define GPIO05 RPI_BPLUS_GPIO_J8_29 +#define GPIO22 RPI_BPLUS_GPIO_J8_15 + +void cb_get_inputs (void) +{ + // Assume LEDs connected to 3.3v + bcm2835_gpio_write(GPIO21, (Obj.LEDs.LED0 ? LOW : HIGH)); + bcm2835_gpio_write(GPIO20, (Obj.LEDs.LED1 ? LOW : HIGH)); + bcm2835_gpio_write(GPIO16, (Obj.LEDs.LED2 ? LOW : HIGH)); + bcm2835_gpio_write(GPIO12, (Obj.LEDs.LED3 ? LOW : HIGH)); + bcm2835_gpio_write(GPIO24, (Obj.LEDs.LED4 ? LOW : HIGH)); + bcm2835_gpio_write(GPIO23, (Obj.LEDs.LED5 ? LOW : HIGH)); +} + +void cb_set_outputs (void) +{ + // Assume Buttons connected to 3.3v + Obj.Buttons.Button0 = bcm2835_gpio_lev(GPIO26); + Obj.Buttons.Button0 = bcm2835_gpio_lev(GPIO19); + Obj.Buttons.Button0 = bcm2835_gpio_lev(GPIO13); + Obj.Buttons.Button0 = bcm2835_gpio_lev(GPIO06); + Obj.Buttons.Button0 = bcm2835_gpio_lev(GPIO05); + Obj.Buttons.Button0 = bcm2835_gpio_lev(GPIO22); +} + +void GPIO_init (void) +{ + bcm2835_init(); + // Assume LEDs connected to 3.3v side of header + bcm2835_gpio_fsel(GPIO21, BCM2835_GPIO_FSEL_OUTP); + bcm2835_gpio_fsel(GPIO20, BCM2835_GPIO_FSEL_OUTP); + bcm2835_gpio_fsel(GPIO16, BCM2835_GPIO_FSEL_OUTP); + bcm2835_gpio_fsel(GPIO12, BCM2835_GPIO_FSEL_OUTP); + bcm2835_gpio_fsel(GPIO24, BCM2835_GPIO_FSEL_OUTP); + bcm2835_gpio_fsel(GPIO23, BCM2835_GPIO_FSEL_OUTP); + // Assume buttons connected to 5v side of header + // Do not bridge to 5v, the ports might burn + bcm2835_gpio_fsel(GPIO26, BCM2835_GPIO_FSEL_INPT); + bcm2835_gpio_fsel(GPIO19, BCM2835_GPIO_FSEL_INPT); + bcm2835_gpio_fsel(GPIO13, BCM2835_GPIO_FSEL_INPT); + bcm2835_gpio_fsel(GPIO06, BCM2835_GPIO_FSEL_INPT); + bcm2835_gpio_fsel(GPIO05, BCM2835_GPIO_FSEL_INPT); + bcm2835_gpio_fsel(GPIO22, BCM2835_GPIO_FSEL_INPT); + bcm2835_gpio_set_pud(GPIO26, BCM2835_GPIO_PUD_DOWN); + bcm2835_gpio_set_pud(GPIO19, BCM2835_GPIO_PUD_DOWN); + bcm2835_gpio_set_pud(GPIO13, BCM2835_GPIO_PUD_DOWN); + bcm2835_gpio_set_pud(GPIO06, BCM2835_GPIO_PUD_DOWN); + bcm2835_gpio_set_pud(GPIO05, BCM2835_GPIO_PUD_DOWN); + bcm2835_gpio_set_pud(GPIO22, BCM2835_GPIO_PUD_DOWN); +} + +int main_run (void * arg) +{ + static esc_cfg_t config = + { + .user_arg = "rpi3,cs0", + .use_interrupt = 0, + .watchdog_cnt = 150, + .set_defaults_hook = NULL, + .pre_state_change_hook = NULL, + .post_state_change_hook = NULL, + .application_hook = NULL, + .safeoutput_override = NULL, + .pre_object_download_hook = NULL, + .post_object_download_hook = NULL, + .rxpdo_override = NULL, + .txpdo_override = NULL, + .esc_hw_interrupt_enable = NULL, + .esc_hw_interrupt_disable = NULL, + .esc_hw_eep_handler = NULL, + .esc_check_dc_handler = NULL, + }; + + printf ("Hello Main\n"); + GPIO_init(); + ecat_slv_init (&config); + while (1) + { + ecat_slv(); + } + + return 0; +} + +int main (void) +{ + printf ("Hello Main\n"); + main_run (NULL); + return 0; +} diff --git a/applications/raspberry_lan9252demo/slave.bin b/applications/raspberry_lan9252demo/slave.bin new file mode 100644 index 0000000..154b2e4 Binary files /dev/null and b/applications/raspberry_lan9252demo/slave.bin differ diff --git a/applications/raspberry_lan9252demo/slave.esx b/applications/raspberry_lan9252demo/slave.esx new file mode 100644 index 0000000..a123cc8 --- /dev/null +++ b/applications/raspberry_lan9252demo/slave.esx @@ -0,0 +1,532 @@ + + + lan9252 + + 0x1337 + rt-labs AB + + + lan9252_spi + lan9252 + + Outputs + Inputs + MBoxOut + MBoxIn + Outputs + Inputs + + + + + + 8002000000000000 + 0010800080108000 + + + + 0x1000 + Device Type + UNSIGNED32 + 0x01901389 + + + 0x1008 + Device Name + VISIBLE_STRING + evb9252_dig + 11 + + + 0x1009 + Hardware Version + VISIBLE_STRING + 1.0 + + + 0x100A + Software Version + VISIBLE_STRING + 1.0 + + + 0x1018 + Identity Object + RECORD + + 0x00 + Max SubIndex + UNSIGNED8 + 4 + + + 0x01 + Vendor ID + UNSIGNED32 + 0x1337 + + + 0x02 + Product Code + UNSIGNED32 + 1234 + + + 0x03 + Revision Number + UNSIGNED32 + 0 + + + 0x04 + Serial Number + UNSIGNED32 + 0x00000000 + + + + 0x1600 + LEDs + RECORD + + 0x00 + Max SubIndex + UNSIGNED8 + 9 + + + 0x01 + LED0 + UNSIGNED32 + 0x70000108 + + + 0x02 + LED1 + UNSIGNED32 + 0x70000208 + + + 0x03 + New Member + UNSIGNED32 + 0x70000301 + + + 0x04 + New Member + UNSIGNED32 + 0x70000401 + + + 0x05 + New Member + UNSIGNED32 + 0x70000501 + + + 0x06 + New Member + UNSIGNED32 + 0x70000601 + + + 0x07 + New Member + UNSIGNED32 + 0x70000701 + + + 0x08 + New Member + UNSIGNED32 + 0x70000801 + + + 0x09 + Padding 9 + UNSIGNED32 + 0x00000002 + + + + 0x1A00 + Buttons + RECORD + + 0x00 + Max SubIndex + UNSIGNED8 + 1 + + + 0x01 + Button1 + UNSIGNED32 + 0x60000108 + + + + 0x1C00 + Sync Manager Communication Type + ARRAY + + 0x00 + Max SubIndex + UNSIGNED8 + 4 + + + 0x01 + Communications Type SM0 + UNSIGNED8 + 1 + + + 0x02 + Communications Type SM1 + UNSIGNED8 + 2 + + + 0x03 + Communications Type SM2 + UNSIGNED8 + 3 + + + 0x04 + Communications Type SM3 + UNSIGNED8 + 4 + + + + 0x1C12 + Sync Manager 2 PDO Assignment + ARRAY + + 0x00 + Max SubIndex + UNSIGNED8 + 1 + + + 0x01 + PDO Mapping + UNSIGNED16 + 0x1600 + + + + 0x1C13 + Sync Manager 3 PDO Assignment + ARRAY + + 0x00 + Max SubIndex + UNSIGNED8 + 1 + + + 0x01 + PDO Mapping + UNSIGNED16 + 0x1A00 + + + + 0x6000 + Buttons + RECORD + Buttons + Input + + 0x00 + Max SubIndex + UNSIGNED8 + 1 + + + 0x01 + RO + Button1 + UNSIGNED8 + 0 + Button1 + Input + + + + 0x7000 + LEDs + RECORD + LEDs + Output + + 0x00 + Max SubIndex + UNSIGNED8 + 8 + + + 0x01 + RO + LED0 + UNSIGNED8 + 0 + LED0 + Output + + + 0x02 + RO + LED1 + UNSIGNED8 + 0 + LED1 + Output + + + 0x03 + RO + New Member + BOOLEAN + 0 + RX + New_Member + Output + + + 0x04 + RO + New Member + BOOLEAN + 0 + RX + New_Member + Output + + + 0x05 + RO + New Member + BOOLEAN + 0 + RX + New_Member + Output + + + 0x06 + RO + New Member + BOOLEAN + 0 + RX + New_Member + Output + + + 0x07 + RO + New Member + BOOLEAN + 0 + RX + New_Member + Output + + + 0x08 + RO + New Member + BOOLEAN + 0 + RX + New_Member + Output + + + + 0x8000 + Parameters + RECORD + Parameters + Parameter + + 0x00 + Max SubIndex + UNSIGNED8 + 1 + + + 0x01 + RW + Multiplier + UNSIGNED32 + 0 + Multiplier + Parameter + + + + + 0x1C12 + + 0x01 + 0x1600 + + + + 0x1C13 + + 0x01 + 0x1A00 + + + + 0x1600 + LEDs + + 0x1 + 0x7000 + 0x01 + LED0 + + + 0x2 + 0x7000 + 0x02 + LED1 + + + 0x3 + 0x7000 + 0x03 + LED2 + + + 0x4 + 0x7000 + 0x04 + LED3 + + + 0x5 + 0x7000 + 0x05 + LED4 + + + 0x6 + 0x7000 + 0x06 + LED5 + + + 0x09 + + + + 0x1A00 + Buttons + + 0x1 + 0x6000 + 0x01 + Button0 + + + + 0x6000 + Buttons + RECORD + + 0x01 + RO + Button0 + BOOLEAN + 0 + TX + + + 0x02 + Button1 + TX + + + 0x03 + Button2 + TX + + + 0x04 + Button3 + TX + + + 0x05 + Button4 + TX + + + 0x06 + Button5 + TX + + + + 0x7000 + LEDs + RECORD + + 0x01 + RO + LED0 + BOOLEAN + 0 + RX + + + 0x02 + RO + LED1 + BOOLEAN + 0 + RX + + + 0x03 + LED2 + RX + + + 0x04 + LED3 + RX + + + 0x05 + LED4 + RX + + + 0x06 + LED5 + RX + + + + 0x8000 + Parameters + RECORD + + 0x01 + RW + Multiplier + UNSIGNED32 + 0 + + + diff --git a/applications/raspberry_lan9252demo/slave.xml b/applications/raspberry_lan9252demo/slave.xml new file mode 100644 index 0000000..8e27f5a --- /dev/null +++ b/applications/raspberry_lan9252demo/slave.xml @@ -0,0 +1,1100 @@ + + + + #x1337 + rt-labs AB + + + + + lan9252_spi + lan9252 + + + + + evb9252_dig + lan9252 + lan9252_spi + + 5001 + 400 + + + + DT1018 + 144 + + 0 + Max SubIndex + USINT + 8 + 0 + + ro + + + + 1 + Vendor ID + UDINT + 32 + 16 + + ro + + + + 2 + Product Code + UDINT + 32 + 48 + + ro + + + + 3 + Revision Number + UDINT + 32 + 80 + + ro + + + + 4 + Serial Number + UDINT + 32 + 112 + + ro + + + + + DT1600 + 240 + + 0 + Max SubIndex + USINT + 8 + 0 + + ro + + + + 1 + LED0 + UDINT + 32 + 16 + + ro + + + + 2 + LED1 + UDINT + 32 + 48 + + ro + + + + 3 + LED2 + UDINT + 32 + 80 + + ro + + + + 4 + LED3 + UDINT + 32 + 112 + + ro + + + + 5 + LED4 + UDINT + 32 + 144 + + ro + + + + 6 + LED5 + UDINT + 32 + 176 + + ro + + + + 7 + Padding 7 + UDINT + 32 + 208 + + ro + + + + + DT1A00 + 240 + + 0 + Max SubIndex + USINT + 8 + 0 + + ro + + + + 1 + Button0 + UDINT + 32 + 16 + + ro + + + + 2 + Button1 + UDINT + 32 + 48 + + ro + + + + 3 + Button2 + UDINT + 32 + 80 + + ro + + + + 4 + Button3 + UDINT + 32 + 112 + + ro + + + + 5 + Button4 + UDINT + 32 + 144 + + ro + + + + 6 + Button5 + UDINT + 32 + 176 + + ro + + + + 7 + Padding 7 + UDINT + 32 + 208 + + ro + + + + + DT1C00ARR + USINT + 32 + + 1 + 4 + + + + DT1C00 + 48 + + 0 + Max SubIndex + USINT + 8 + 0 + + ro + + + + Elements + DT1C00ARR + 32 + 16 + + ro + + + + + DT1C12ARR + UINT + 16 + + 1 + 1 + + + + DT1C12 + 32 + + 0 + Max SubIndex + USINT + 8 + 0 + + ro + + + + Elements + DT1C12ARR + 16 + 16 + + ro + + + + + DT1C13ARR + UINT + 16 + + 1 + 1 + + + + DT1C13 + 32 + + 0 + Max SubIndex + USINT + 8 + 0 + + ro + + + + Elements + DT1C13ARR + 16 + 16 + + ro + + + + + DT6000 + 64 + + 0 + Max SubIndex + USINT + 8 + 0 + + ro + + + + 1 + Button0 + BOOL + 1 + 16 + + ro + T + + + + 2 + Button1 + BOOL + 1 + 24 + + ro + T + + + + 3 + Button2 + BOOL + 1 + 32 + + ro + T + + + + 4 + Button3 + BOOL + 1 + 40 + + ro + T + + + + 5 + Button4 + BOOL + 1 + 48 + + ro + T + + + + 6 + Button5 + BOOL + 1 + 56 + + ro + T + + + + + DT7000 + 64 + + 0 + Max SubIndex + USINT + 8 + 0 + + ro + + + + 1 + LED0 + BOOL + 1 + 16 + + ro + R + + + + 2 + LED1 + BOOL + 1 + 24 + + ro + R + + + + 3 + LED2 + BOOL + 1 + 32 + + ro + R + + + + 4 + LED3 + BOOL + 1 + 40 + + ro + R + + + + 5 + LED4 + BOOL + 1 + 48 + + ro + R + + + + 6 + LED5 + BOOL + 1 + 56 + + ro + R + + + + + DT8000 + 48 + + 0 + Max SubIndex + USINT + 8 + 0 + + ro + + + + 1 + Multiplier + UDINT + 32 + 16 + + rw + + + + + BOOL + 1 + + + STRING(11) + 88 + + + UDINT + 32 + + + UINT + 16 + + + STRING(0) + 0 + + + USINT + 8 + + + + + #x1000 + Device Type + UDINT + 32 + + #x01901389 + + + ro + m + + + + #x1008 + Device Name + STRING(11) + 88 + + evb9252_dig + + + ro + + + + #x1009 + Hardware Version + STRING(0) + 0 + + 1.0 + + + ro + o + + + + #x100A + Software Version + STRING(0) + 0 + + 1.0 + + + ro + + + + #x1018 + Identity Object + DT1018 + 144 + + + Max SubIndex + + 4 + + + + Vendor ID + + #x1337 + + + + Product Code + + 1234 + + + + Revision Number + + 0 + + + + Serial Number + + #x00000000 + + + + + ro + + + + #x1600 + LEDs + DT1600 + 240 + + + Max SubIndex + + 7 + + + + LED0 + + #x70000101 + + + + LED1 + + #x70000201 + + + + LED2 + + #x70000301 + + + + LED3 + + #x70000401 + + + + LED4 + + #x70000501 + + + + LED5 + + #x70000601 + + + + Padding 7 + + #x00000002 + + + + + ro + + + + #x1A00 + Buttons + DT1A00 + 240 + + + Max SubIndex + + 7 + + + + Button0 + + #x60000101 + + + + Button1 + + #x60000201 + + + + Button2 + + #x60000301 + + + + Button3 + + #x60000401 + + + + Button4 + + #x60000501 + + + + Button5 + + #x60000601 + + + + Padding 7 + + #x00000002 + + + + + ro + + + + #x1C00 + Sync Manager Communication Type + DT1C00 + 48 + + + Max SubIndex + + 4 + + + + Communications Type SM0 + + 1 + + + + Communications Type SM1 + + 2 + + + + Communications Type SM2 + + 3 + + + + Communications Type SM3 + + 4 + + + + + ro + + + + #x1C12 + Sync Manager 2 PDO Assignment + DT1C12 + 32 + + + Max SubIndex + + 1 + + + + PDO Mapping + + #x1600 + + + + + ro + + + + #x1C13 + Sync Manager 3 PDO Assignment + DT1C13 + 32 + + + Max SubIndex + + 1 + + + + PDO Mapping + + #x1A00 + + + + + ro + + + + #x6000 + Buttons + DT6000 + 64 + + + Max SubIndex + + 6 + + + + Button0 + + 0 + + + + Button1 + + 0 + + + + Button2 + + 0 + + + + Button3 + + 0 + + + + Button4 + + 0 + + + + Button5 + + 0 + + + + + ro + + + + #x7000 + LEDs + DT7000 + 64 + + + Max SubIndex + + 6 + + + + LED0 + + 0 + + + + LED1 + + 0 + + + + LED2 + + 0 + + + + LED3 + + 0 + + + + LED4 + + 0 + + + + LED5 + + 0 + + + + + ro + + + + #x8000 + Parameters + DT8000 + 48 + + + Max SubIndex + + 1 + + + + Multiplier + + 0 + + + + + ro + + + + + + Outputs + Inputs + MBoxOut + MBoxIn + Outputs + Inputs + + #x1600 + LEDs + + #x7000 + #x1 + 1 + LED0 + BOOL + + + #x7000 + #x2 + 1 + LED1 + BOOL + + + #x7000 + #x3 + 1 + LED2 + BOOL + + + #x7000 + #x4 + 1 + LED3 + BOOL + + + #x7000 + #x5 + 1 + LED4 + BOOL + + + #x7000 + #x6 + 1 + LED5 + BOOL + + + 0 + 0 + 2 + + + + #x1A00 + Buttons + + #x6000 + #x1 + 1 + Button0 + BOOL + + + #x6000 + #x2 + 1 + Button1 + BOOL + + + #x6000 + #x3 + 1 + Button2 + BOOL + + + #x6000 + #x4 + 1 + Button3 + BOOL + + + #x6000 + #x5 + 1 + Button4 + BOOL + + + #x6000 + #x6 + 1 + Button5 + BOOL + + + 0 + 0 + 2 + + + + + + + + 256 + 8002000000000000 + 0010800080108000 + + + + + \ No newline at end of file diff --git a/applications/raspberry_lan9252demo/slave_objectlist.c b/applications/raspberry_lan9252demo/slave_objectlist.c new file mode 100644 index 0000000..d9135ef --- /dev/null +++ b/applications/raspberry_lan9252demo/slave_objectlist.c @@ -0,0 +1,179 @@ +#include "esc_coe.h" +#include "utypes.h" +#include + +#ifndef HW_REV +#define HW_REV "1.0" +#endif + +#ifndef SW_REV +#define SW_REV "1.0" +#endif + +static const char acName1000[] = "Device Type"; +static const char acName1008[] = "Device Name"; +static const char acName1009[] = "Hardware Version"; +static const char acName100A[] = "Software Version"; +static const char acName1018[] = "Identity Object"; +static const char acName1018_00[] = "Max SubIndex"; +static const char acName1018_01[] = "Vendor ID"; +static const char acName1018_02[] = "Product Code"; +static const char acName1018_03[] = "Revision Number"; +static const char acName1018_04[] = "Serial Number"; +static const char acName1600[] = "LEDs"; +static const char acName1600_00[] = "Max SubIndex"; +static const char acName1600_01[] = "LED0"; +static const char acName1600_02[] = "LED1"; +static const char acName1600_03[] = "LED2"; +static const char acName1600_04[] = "LED3"; +static const char acName1600_05[] = "LED4"; +static const char acName1600_06[] = "LED5"; +static const char acName1600_07[] = "Padding 7"; +static const char acName1A00[] = "Buttons"; +static const char acName1A00_00[] = "Max SubIndex"; +static const char acName1A00_01[] = "Button0"; +static const char acName1A00_02[] = "Button1"; +static const char acName1A00_03[] = "Button2"; +static const char acName1A00_04[] = "Button3"; +static const char acName1A00_05[] = "Button4"; +static const char acName1A00_06[] = "Button5"; +static const char acName1A00_07[] = "Padding 7"; +static const char acName1C00[] = "Sync Manager Communication Type"; +static const char acName1C00_00[] = "Max SubIndex"; +static const char acName1C00_01[] = "Communications Type SM0"; +static const char acName1C00_02[] = "Communications Type SM1"; +static const char acName1C00_03[] = "Communications Type SM2"; +static const char acName1C00_04[] = "Communications Type SM3"; +static const char acName1C12[] = "Sync Manager 2 PDO Assignment"; +static const char acName1C12_00[] = "Max SubIndex"; +static const char acName1C12_01[] = "PDO Mapping"; +static const char acName1C13[] = "Sync Manager 3 PDO Assignment"; +static const char acName1C13_00[] = "Max SubIndex"; +static const char acName1C13_01[] = "PDO Mapping"; +static const char acName6000[] = "Buttons"; +static const char acName6000_00[] = "Max SubIndex"; +static const char acName6000_01[] = "Button0"; +static const char acName6000_02[] = "Button1"; +static const char acName6000_03[] = "Button2"; +static const char acName6000_04[] = "Button3"; +static const char acName6000_05[] = "Button4"; +static const char acName6000_06[] = "Button5"; +static const char acName7000[] = "LEDs"; +static const char acName7000_00[] = "Max SubIndex"; +static const char acName7000_01[] = "LED0"; +static const char acName7000_02[] = "LED1"; +static const char acName7000_03[] = "LED2"; +static const char acName7000_04[] = "LED3"; +static const char acName7000_05[] = "LED4"; +static const char acName7000_06[] = "LED5"; +static const char acName8000[] = "Parameters"; +static const char acName8000_00[] = "Max SubIndex"; +static const char acName8000_01[] = "Multiplier"; + +const _objd SDO1000[] = +{ + {0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000, 0x01901389, NULL}, +}; +const _objd SDO1008[] = +{ + {0x0, DTYPE_VISIBLE_STRING, 88, ATYPE_RO, acName1008, 0, "evb9252_dig"}, +}; +const _objd SDO1009[] = +{ + {0x0, DTYPE_VISIBLE_STRING, 0, ATYPE_RO, acName1009, 0, HW_REV}, +}; +const _objd SDO100A[] = +{ + {0x0, DTYPE_VISIBLE_STRING, 0, ATYPE_RO, acName100A, 0, SW_REV}, +}; +const _objd SDO1018[] = +{ + {0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1018_00, 4, NULL}, + {0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_01, 0x1337, NULL}, + {0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_02, 1234, NULL}, + {0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_03, 0, NULL}, + {0x04, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_04, 0x00000000, &Obj.serial}, +}; +const _objd SDO1600[] = +{ + {0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1600_00, 7, NULL}, + {0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_01, 0x70000101, NULL}, + {0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_02, 0x70000201, NULL}, + {0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_03, 0x70000301, NULL}, + {0x04, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_04, 0x70000401, NULL}, + {0x05, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_05, 0x70000501, NULL}, + {0x06, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_06, 0x70000601, NULL}, + {0x07, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_07, 0x00000002, NULL}, +}; +const _objd SDO1A00[] = +{ + {0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1A00_00, 7, NULL}, + {0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_01, 0x60000101, NULL}, + {0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_02, 0x60000201, NULL}, + {0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_03, 0x60000301, NULL}, + {0x04, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_04, 0x60000401, NULL}, + {0x05, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_05, 0x60000501, NULL}, + {0x06, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_06, 0x60000601, NULL}, + {0x07, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_07, 0x00000002, NULL}, +}; +const _objd SDO1C00[] = +{ + {0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_00, 4, NULL}, + {0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_01, 1, NULL}, + {0x02, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_02, 2, NULL}, + {0x03, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_03, 3, NULL}, + {0x04, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C00_04, 4, NULL}, +}; +const _objd SDO1C12[] = +{ + {0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C12_00, 1, NULL}, + {0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C12_01, 0x1600, NULL}, +}; +const _objd SDO1C13[] = +{ + {0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1C13_00, 1, NULL}, + {0x01, DTYPE_UNSIGNED16, 16, ATYPE_RO, acName1C13_01, 0x1A00, NULL}, +}; +const _objd SDO6000[] = +{ + {0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6000_00, 6, NULL}, + {0x01, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_TXPDO, acName6000_01, 0, &Obj.Buttons.Button0}, + {0x02, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_TXPDO, acName6000_02, 0, &Obj.Buttons.Button1}, + {0x03, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_TXPDO, acName6000_03, 0, &Obj.Buttons.Button2}, + {0x04, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_TXPDO, acName6000_04, 0, &Obj.Buttons.Button3}, + {0x05, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_TXPDO, acName6000_05, 0, &Obj.Buttons.Button4}, + {0x06, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_TXPDO, acName6000_06, 0, &Obj.Buttons.Button5}, +}; +const _objd SDO7000[] = +{ + {0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_00, 6, NULL}, + {0x01, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_RXPDO, acName7000_01, 0, &Obj.LEDs.LED0}, + {0x02, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_RXPDO, acName7000_02, 0, &Obj.LEDs.LED1}, + {0x03, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_RXPDO, acName7000_03, 0, &Obj.LEDs.LED2}, + {0x04, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_RXPDO, acName7000_04, 0, &Obj.LEDs.LED3}, + {0x05, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_RXPDO, acName7000_05, 0, &Obj.LEDs.LED4}, + {0x06, DTYPE_BOOLEAN, 1, ATYPE_RO | ATYPE_RXPDO, acName7000_06, 0, &Obj.LEDs.LED5}, +}; +const _objd SDO8000[] = +{ + {0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName8000_00, 1, NULL}, + {0x01, DTYPE_UNSIGNED32, 32, ATYPE_RW, acName8000_01, 0, &Obj.Parameters.Multiplier}, +}; + +const _objectlist SDOobjects[] = +{ + {0x1000, OTYPE_VAR, 0, 0, acName1000, SDO1000}, + {0x1008, OTYPE_VAR, 0, 0, acName1008, SDO1008}, + {0x1009, OTYPE_VAR, 0, 0, acName1009, SDO1009}, + {0x100A, OTYPE_VAR, 0, 0, acName100A, SDO100A}, + {0x1018, OTYPE_RECORD, 4, 0, acName1018, SDO1018}, + {0x1600, OTYPE_RECORD, 7, 0, acName1600, SDO1600}, + {0x1A00, OTYPE_RECORD, 7, 0, acName1A00, SDO1A00}, + {0x1C00, OTYPE_ARRAY, 4, 0, acName1C00, SDO1C00}, + {0x1C12, OTYPE_ARRAY, 1, 0, acName1C12, SDO1C12}, + {0x1C13, OTYPE_ARRAY, 1, 0, acName1C13, SDO1C13}, + {0x6000, OTYPE_RECORD, 6, 0, acName6000, SDO6000}, + {0x7000, OTYPE_RECORD, 6, 0, acName7000, SDO7000}, + {0x8000, OTYPE_RECORD, 1, 0, acName8000, SDO8000}, + {0xffff, 0xff, 0xff, 0xff, NULL, NULL} +}; diff --git a/applications/raspberry_lan9252demo/utypes.h b/applications/raspberry_lan9252demo/utypes.h new file mode 100644 index 0000000..8ab38c4 --- /dev/null +++ b/applications/raspberry_lan9252demo/utypes.h @@ -0,0 +1,49 @@ +#ifndef __UTYPES_H__ +#define __UTYPES_H__ + +#include "cc.h" + +/* Object dictionary storage */ + +typedef struct +{ + /* Identity */ + + uint32_t serial; + + /* Inputs */ + + struct + { + uint8_t Button0; + uint8_t Button1; + uint8_t Button2; + uint8_t Button3; + uint8_t Button4; + uint8_t Button5; + } Buttons; + + /* Outputs */ + + struct + { + uint8_t LED0; + uint8_t LED1; + uint8_t LED2; + uint8_t LED3; + uint8_t LED4; + uint8_t LED5; + } LEDs; + + /* Parameters */ + + struct + { + uint32_t Multiplier; + } Parameters; + +} _Objects; + +extern _Objects Obj; + +#endif /* __UTYPES_H__ */ diff --git a/cmake/Linux.cmake b/cmake/Linux.cmake index 13e0cdd..1665b32 100644 --- a/cmake/Linux.cmake +++ b/cmake/Linux.cmake @@ -1,14 +1,20 @@ - -set(SOES_DEMO applications/linux_lan9252demo) +if(RPI_VARIANT) + set (SOES_DEMO applications/raspberry_lan9252demo) + set(HAL_SOURCES + ${SOES_SOURCE_DIR}/soes/hal/raspberrypi-lan9252/esc_hw.c + ${SOES_SOURCE_DIR}/soes/hal/raspberrypi-lan9252/esc_hw.h + ) +else() + set(SOES_DEMO applications/linux_lan9252demo) + set(HAL_SOURCES + ${SOES_SOURCE_DIR}/soes/hal/linux-lan9252/esc_hw.c + ) +endif() include_directories( ${SOES_SOURCE_DIR}/soes/include/sys/gcc ${SOES_SOURCE_DIR}/${SOES_DEMO} ) -set(HAL_SOURCES - ${SOES_SOURCE_DIR}/soes/hal/linux-lan9252/esc_hw.c - ) - # Common compile flags add_compile_options(-Wall -Wextra -Wno-unused-parameter -Werror) diff --git a/soes/hal/raspberrypi-lan9252/esc_hw.c b/soes/hal/raspberrypi-lan9252/esc_hw.c new file mode 100644 index 0000000..a98cfc9 --- /dev/null +++ b/soes/hal/raspberrypi-lan9252/esc_hw.c @@ -0,0 +1,603 @@ +/* + * Licensed under the GNU General Public License version 2 with exceptions. See + * LICENSE file in the project root for full license information + */ + +/** \file + * \brief + * ESC hardware layer functions for LAN9252 through BCM2835 SPI on Raspberry PI. + * + * Function to read and write commands to the ESC. Used to read/write ESC + * registers and memory. + */ +#include "esc.h" +#include "esc_hw.h" +#include +#include +#include +#include +#include + +#define BIT(x) (1U << (x)) + +#define ESC_CMD_SERIAL_WRITE 0x02 +#define ESC_CMD_SERIAL_READ 0x03 + +#define ESC_CMD_RESET_CTL 0x01F8 // reset register +#define ESC_CMD_HW_CFG 0x0074 // hardware configuration register +#define ESC_CMD_BYTE_TEST 0x0064 // byte order test register +#define ESC_CMD_ID_REV 0x0050 // chip ID and revision +#define ESC_CMD_IRQ_CFG 0x0054 // interrupt configuration +#define ESC_CMD_INT_EN 0x005C // interrupt enable + +#define ESC_RESET_DIGITAL 0x00000001 +#define ESC_RESET_ETHERCAT 0x00000040 +#define ESC_RESET_CTRL_RST (ESC_RESET_DIGITAL & ESC_RESET_ETHERCAT) +#define ESC_HW_CFG_READY 0x08000000 +#define ESC_BYTE_TEST_OK 0x87654321 + +#define ESC_PRAM_RD_FIFO_REG 0x0000 +#define ESC_PRAM_WR_FIFO_REG 0x0020 +#define ESC_PRAM_RD_ADDR_LEN_REG 0x0308 +#define ESC_PRAM_RD_CMD_REG 0x030C +#define ESC_PRAM_WR_ADDR_LEN_REG 0x0310 +#define ESC_PRAM_WR_CMD_REG 0x0314 + +#define ESC_PRAM_CMD_BUSY 0x80000000 +#define ESC_PRAM_CMD_ABORT 0x40000000 +#define ESC_PRAM_CMD_AVAIL 0x00000001 +#define ESC_PRAM_CMD_CNT(x) (((x) >> 8) & 0x1F) +#define ESC_PRAM_SIZE(x) ((x) << 16) +#define ESC_PRAM_ADDR(x) ((x) << 0) + +#define ESC_CSR_DATA_REG 0x0300 +#define ESC_CSR_CMD_REG 0x0304 + +#define ESC_CSR_CMD_BUSY 0x80000000 +#define ESC_CSR_CMD_READ (0x80000000 | 0x40000000) +#define ESC_CSR_CMD_WRITE 0x80000000 +#define ESC_CSR_CMD_SIZE(x) ((x) << 16) + +/* bcm2835 spi single write */ +static void bcm2835_spi_write_32 (uint16_t address, uint32_t val) +{ + char data[7]; + + data[0] = ESC_CMD_SERIAL_WRITE; + data[1] = ((address >> 8) & 0xFF); + data[2] = (address & 0xFF); + data[3] = (val & 0xFF); + data[4] = ((val >> 8) & 0xFF); + data[5] = ((val >> 16) & 0xFF); + data[6] = ((val >> 24) & 0xFF); + + /* Write data */ + bcm2835_spi_transfern(data, 7); +} + +/* bcm2835 spi single read */ +static uint32_t bcm2835_spi_read_32 (uint16_t address) +{ + char data[7]; + + data[0] = ESC_CMD_SERIAL_READ; + data[1] = ((address >> 8) & 0xFF); + data[2] = (address & 0xFF); + + /* Read data */ + bcm2835_spi_transfern(data, 7); + + return ((data[6] << 24) | + (data[5] << 16) | + (data[4] << 8) | + data[3]); +} + +/* ESC read CSR function */ +static void ESC_read_csr (uint16_t address, void *buf, uint16_t len) +{ + uint32_t value; + + value = (ESC_CSR_CMD_READ | ESC_CSR_CMD_SIZE(len) | address); + bcm2835_spi_write_32(ESC_CSR_CMD_REG, value); + + do + { + value = bcm2835_spi_read_32(ESC_CSR_CMD_REG); + } while(value & ESC_CSR_CMD_BUSY); + + value = bcm2835_spi_read_32(ESC_CSR_DATA_REG); + memcpy(buf, (uint8_t *)&value, len); +} + +/* ESC write CSR function */ +static void ESC_write_csr (uint16_t address, void *buf, uint16_t len) +{ + uint32_t value; + + memcpy((uint8_t*)&value, buf,len); + bcm2835_spi_write_32(ESC_CSR_DATA_REG, value); + value = (ESC_CSR_CMD_WRITE | ESC_CSR_CMD_SIZE(len) | address); + bcm2835_spi_write_32(ESC_CSR_CMD_REG, value); + + do + { + value = bcm2835_spi_read_32(ESC_CSR_CMD_REG); + } while(value & ESC_CSR_CMD_BUSY); +} + +/* ESC read process data ram function */ +static void ESC_read_pram (uint16_t address, void *buf, uint16_t len) +{ + uint32_t value; + uint8_t * temp_buf = buf; + uint16_t quotient, remainder, byte_offset = 0; + uint8_t fifo_cnt, fifo_size, fifo_range, first_byte_position, temp_len; + uint8_t *buffer = NULL; + int i, size; + + bcm2835_spi_write_32(ESC_PRAM_RD_CMD_REG, ESC_PRAM_CMD_ABORT); + do + { + value = bcm2835_spi_read_32(ESC_PRAM_RD_CMD_REG); + }while(value & ESC_PRAM_CMD_BUSY); + + bcm2835_spi_write_32(ESC_PRAM_RD_ADDR_LEN_REG, (ESC_PRAM_SIZE(len) | ESC_PRAM_ADDR(address))); + + bcm2835_spi_write_32(ESC_PRAM_RD_CMD_REG, ESC_PRAM_CMD_BUSY); + + /* Find out first byte position and adjust the copy from that + * according to LAN9252 datasheet and MicroChip SDK code + */ + first_byte_position = (address & 0x03); + + /* Transfer data */ + while (len > 0) + { + /* Wait for read availabiliy */ + if (byte_offset > 0) + { + quotient = len/4; + remainder = len - quotient*4; + } + else + { + quotient = (len + first_byte_position)/4; + remainder = (len + first_byte_position) - quotient*4; + } + if (remainder != 0) + { + quotient++; + } + fifo_range = MIN(quotient,16); + do + { + value = bcm2835_spi_read_32(ESC_PRAM_RD_CMD_REG); + }while(!(value & ESC_PRAM_CMD_AVAIL) || (ESC_PRAM_CMD_CNT(value) < fifo_range)); + + /* Fifo size */ + fifo_size = ESC_PRAM_CMD_CNT(value); + + /* Transfer data size */ + size = 3+4*fifo_size; + + /* Allocate buffer */ + buffer = (uint8_t *)realloc(buffer, size); + + /* Reset fifo count */ + fifo_cnt = fifo_size; + + /* Reset buffer */ + memset(buffer,0,size); + buffer[0] = ESC_CMD_SERIAL_READ; + buffer[1] = ((ESC_PRAM_RD_FIFO_REG >>8) & 0xFF); + buffer[2] = ( ESC_PRAM_RD_FIFO_REG & 0xFF); + + /* Transfer batch of data */ + bcm2835_spi_transfern((char *)buffer, size); + + i = 3; + while (fifo_cnt > 0 && len > 0) + { + value = buffer[i] | (buffer[i+1] << 8) | (buffer[i+2] << 16) | (buffer[i+3] << 24); + + if (byte_offset > 0) + { + temp_len = (len > 4) ? 4: len; + memcpy(temp_buf + byte_offset ,&value, temp_len); + } + else + { + temp_len = (len > (4 - first_byte_position)) ? (4 - first_byte_position) : len; + memcpy(temp_buf ,((uint8_t *)&value + first_byte_position), temp_len); + } + + i += 4; + fifo_cnt--; + len -= temp_len; + byte_offset += temp_len; + } + } + free(buffer); +} + +/* ESC write process data ram function */ +static void ESC_write_pram (uint16_t address, void *buf, uint16_t len) +{ + uint32_t value; + uint8_t * temp_buf = buf; + uint16_t quotient, remainder, byte_offset = 0; + uint8_t fifo_cnt, fifo_size, fifo_range, first_byte_position, temp_len; + uint8_t *buffer = NULL; + int i, size; + + bcm2835_spi_write_32(ESC_PRAM_WR_CMD_REG, ESC_PRAM_CMD_ABORT); + do + { + value = bcm2835_spi_read_32(ESC_PRAM_WR_CMD_REG); + }while(value & ESC_PRAM_CMD_BUSY); + + bcm2835_spi_write_32(ESC_PRAM_WR_ADDR_LEN_REG, (ESC_PRAM_SIZE(len) | ESC_PRAM_ADDR(address))); + + bcm2835_spi_write_32(ESC_PRAM_WR_CMD_REG, ESC_PRAM_CMD_BUSY); + + /* Find out first byte position and adjust the copy from that + * according to LAN9252 datasheet and MicroChip SDK code + */ + first_byte_position = (address & 0x03); + + /* Transfer data */ + while (len > 0) + { + /* Wait for write availabiliy */ + if (byte_offset > 0) + { + quotient = len/4; + remainder = len - quotient*4; + } + else + { + quotient = (len + first_byte_position)/4; + remainder = (len + first_byte_position) - quotient*4; + } + if (remainder != 0) + { + quotient++; + } + fifo_range = MIN(quotient,16); + do + { + value = bcm2835_spi_read_32(ESC_PRAM_WR_CMD_REG); + }while(!(value & ESC_PRAM_CMD_AVAIL) || (ESC_PRAM_CMD_CNT(value) < fifo_range)); + + /* Fifo size */ + fifo_size = ESC_PRAM_CMD_CNT(value); + + /* Transfer data size */ + size = 3+4*fifo_size; + + /* Allocate buffer */ + buffer = (uint8_t *)realloc(buffer, size); + + /* Reset fifo count */ + fifo_cnt = fifo_size; + + /* Reset buffer */ + memset(buffer,0,size); + buffer[0] = ESC_CMD_SERIAL_WRITE; + buffer[1] = ((ESC_PRAM_WR_FIFO_REG >> 8) & 0xFF); + buffer[2] = (ESC_PRAM_WR_FIFO_REG & 0xFF); + + i = 3; + while (fifo_cnt > 0 && len > 0) + { + value = 0; + if (byte_offset > 0) + { + temp_len = (len > 4) ? 4: len; + memcpy(&value, (temp_buf + byte_offset), temp_len); + } + else + { + temp_len = (len > (4 - first_byte_position)) ? (4 - first_byte_position) : len; + memcpy(((uint8_t *)&value + first_byte_position), temp_buf, temp_len); + } + + buffer[i] = (value & 0xFF); + buffer[i+1] = ((value >> 8) & 0xFF); + buffer[i+2] = ((value >> 16) & 0xFF); + buffer[i+3] = ((value >> 24) & 0xFF); + + i += 4; + fifo_cnt--; + len -= temp_len; + byte_offset += temp_len; + } + + /* Transfer batch of data */ + bcm2835_spi_transfern((char *)buffer, size); + } + free(buffer); +} + +/** ESC read function used by the Slave stack. + * + * @param[in] address = address of ESC register to read + * @param[out] buf = pointer to buffer to read in + * @param[in] len = number of bytes to read + */ +void ESC_read (uint16_t address, void *buf, uint16_t len) +{ + /* Select Read function depending on address, process data ram or not */ + if (address >= 0x1000) + { + ESC_read_pram(address, buf, len); + } + else + { + uint16_t size; + uint8_t *temp_buf = (uint8_t *)buf; + + while(len > 0) + { + /* We write maximum 4 bytes at the time */ + size = (len > 4) ? 4 : len; + /* Make size aligned to address according to LAN9252 datasheet + * Table 12-14 EtherCAT CSR Address VS size and MicroChip SDK code + */ + /* If we got an odd address size is 1 , 01b 11b is captured */ + if(address & BIT(0)) + { + size = 1; + } + /* If address 1xb and size != 1 and 3 , allow size 2 else size 1 */ + else if (address & BIT(1)) + { + size = (size & BIT(0)) ? 1 : 2; + } + /* size 3 not valid */ + else if (size == 3) + { + size = 1; + } + /* else size is kept AS IS */ + ESC_read_csr(address, temp_buf, size); + + /* next address */ + len -= size; + temp_buf += size; + address += size; + } + } + /* To mimic the ET1100 always providing AlEvent on every read or write */ + ESC_read_csr(ESCREG_ALEVENT,(void *)&ESCvar.ALevent,sizeof(ESCvar.ALevent)); + ESCvar.ALevent = etohs (ESCvar.ALevent); + +} + +/** ESC write function used by the Slave stack. + * + * @param[in] address = address of ESC register to write + * @param[out] buf = pointer to buffer to write from + * @param[in] len = number of bytes to write + */ +void ESC_write (uint16_t address, void *buf, uint16_t len) +{ + /* Select Write function depending on address, process data ram or not */ + if (address >= 0x1000) + { + ESC_write_pram(address, buf, len); + } + else + { + uint16_t size; + uint8_t *temp_buf = (uint8_t *)buf; + + while(len > 0) + { + /* We write maximum 4 bytes at the time */ + size = (len > 4) ? 4 : len; + /* Make size aligned to address according to LAN9252 datasheet + * Table 12-14 EtherCAT CSR Address VS size and MicroChip SDK code + */ + /* If we got an odd address size is 1 , 01b 11b is captured */ + if(address & BIT(0)) + { + size = 1; + } + /* If address 1xb and size != 1 and 3 , allow size 2 else size 1 */ + else if (address & BIT(1)) + { + size = (size & BIT(0)) ? 1 : 2; + } + /* size 3 not valid */ + else if (size == 3) + { + size = 1; + } + /* else size is kept AS IS */ + ESC_write_csr(address, temp_buf, size); + + /* next address */ + len -= size; + temp_buf += size; + address += size; + } + } + + /* To mimic the ET1x00 always providing AlEvent on every read or write */ + ESC_read_csr(ESCREG_ALEVENT,(void *)&ESCvar.ALevent,sizeof(ESCvar.ALevent)); + ESCvar.ALevent = etohs (ESCvar.ALevent); +} + +/* Un-used due to evb-lan9252-digio not havning any possability to + * reset except over SPI. + */ +void ESC_reset (void) +{ + +} + +void ESC_init (const esc_cfg_t * config) +{ + bool rpi4 = false, cs1 = false; + uint32_t value; + uint32_t counter = 0; + uint32_t timeout = 1000; // wait 100msec + const char * user_arg = (char *)config->user_arg; + size_t arg_len = strlen(user_arg)+1; + char * arg_str = (char *)calloc(arg_len, sizeof(char)); + strncpy(arg_str,user_arg,arg_len); + char * delim = " ,.-"; + char * token = strtok(arg_str,delim); + + // parse user arguments + while (token != NULL) + { + if (strncmp(token,"cs1",3) == 0) + { + cs1 = true; // select CS1 pin + } + else if (strncmp(token,"rpi4",4) == 0) + { + rpi4 = true; // select clock divider for raspberry pi 4 or newer + } + token = strtok(NULL,delim); + } + free(arg_str); + + // start initialization + if (bcm2835_init()) + { + if (bcm2835_spi_begin()) + { + // Set SPI bit order + bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST); + // Set SPI data mode BCM2835_SPI_MODE0 = 0, CPOL = 0, CPHA = 0, + // Clock idle low, data is clocked in on rising edge, output data (change) on falling edge + bcm2835_spi_setDataMode(BCM2835_SPI_MODE0); + if (rpi4) + { + // Raspberry 4 due to a higher CPU speed this value is to change to: BCM2835_SPI_CLOCK_DIVIDER_32 + bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_32); + DPRINT("bcm2835_spi_setClockDivider set to 32 \n"); + } + else + { + // Set SPI clock speed BCM2835_SPI_CLOCK_DIVIDER_16 = 16, 16 = 64ns = 15.625MHz + bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_16); + DPRINT("bcm2835_spi_setClockDivider set to 16 \n"); + } + if (cs1) + { + // Enable management of CS1 pin + bcm2835_spi_chipSelect(BCM2835_SPI_CS1); + // Enable CS1 and set polarity + bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS1, LOW); + DPRINT("bcm2835_spi_chipSelect set to CS1 \n"); + } + else + { + // Enable management of CS0 pin + bcm2835_spi_chipSelect(BCM2835_SPI_CS0); + // enable CS0 and set polarity + bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW); + DPRINT("bcm2835_spi_chipSelect set to CS0 \n"); + } + + // Reset the ecat core here due to evb-lan9252-digio not having any GPIO for that purpose. + bcm2835_spi_write_32(ESC_CMD_RESET_CTL,ESC_RESET_CTRL_RST); + + // Wait until reset command has been executed + do + { + usleep(100); + counter++; + value = bcm2835_spi_read_32(ESC_CMD_RESET_CTL); + } while ((value & ESC_RESET_CTRL_RST) && (counter < timeout)); + + // Perform byte test + do + { + usleep(100); + counter++; + value = bcm2835_spi_read_32(ESC_CMD_BYTE_TEST); + } while ((value != ESC_BYTE_TEST_OK) && (counter < timeout)); + + // Check hardware is ready + do + { + usleep(100); + counter++; + value = bcm2835_spi_read_32(ESC_CMD_HW_CFG); + } while (!(value & ESC_HW_CFG_READY) && (counter < timeout)); + + // Check if timeout occured + if (counter < timeout) + { + // Read the chip identification and revision + value = bcm2835_spi_read_32(ESC_CMD_ID_REV); + DPRINT("Detected chip %x Rev %u \n", ((value >> 16) & 0xFFFF), (value & 0xFFFF)); + + // Set AL event mask + value = (ESCREG_ALEVENT_CONTROL | + ESCREG_ALEVENT_SMCHANGE | + ESCREG_ALEVENT_SM0 | + ESCREG_ALEVENT_SM1 ); + ESC_ALeventmaskwrite(value); + } + else + { + DPRINT("Timeout occurred during reset \n"); + bcm2835_spi_end(); + bcm2835_close(); + } + } + else + { + DPRINT("bcm2835_spi_begin failed. Are you running as root?\n"); + bcm2835_close(); + } + } + else + { + DPRINT("bcm2835_init failed. Are you running as root?\n"); + } +} + +void ESC_interrupt_enable (uint32_t mask) +{ + if (ESCREG_ALEVENT_DC_SYNC0 & mask) + { + // Enable interrupt from SYNC0 + ESC_ALeventmaskwrite(ESC_ALeventmaskread() | ESCREG_ALEVENT_DC_SYNC0); + } + if (ESCREG_ALEVENT_SM2 & mask) + { + // Enable interrupt from SYNC0 + ESC_ALeventmaskwrite(ESC_ALeventmaskread() | ESCREG_ALEVENT_SM2); + } + + // Set LAN9252 interrupt pin driver as push-pull active high + bcm2835_spi_write_32(ESC_CMD_IRQ_CFG, 0x00000111); + + // Enable LAN9252 interrupt + bcm2835_spi_write_32(ESC_CMD_INT_EN, 0x00000001); +} + +void ESC_interrupt_disable (uint32_t mask) +{ + if (ESCREG_ALEVENT_DC_SYNC0 & mask) + { + // Disable interrupt from SYNC0 + ESC_ALeventmaskwrite(ESC_ALeventmaskread() & ~(ESCREG_ALEVENT_DC_SYNC0)); + } + if (ESCREG_ALEVENT_SM2 & mask) + { + // Disable interrupt from SM2 + ESC_ALeventmaskwrite(ESC_ALeventmaskread() & ~(ESCREG_ALEVENT_SM2)); + } + + // Disable LAN9252 interrupt + bcm2835_spi_write_32(ESC_CMD_INT_EN, 0x00000000); +} diff --git a/soes/hal/raspberrypi-lan9252/esc_hw.h b/soes/hal/raspberrypi-lan9252/esc_hw.h new file mode 100644 index 0000000..29c4ae1 --- /dev/null +++ b/soes/hal/raspberrypi-lan9252/esc_hw.h @@ -0,0 +1,17 @@ +/* + * Licensed under the GNU General Public License version 2 with exceptions. See + * LICENSE file in the project root for full license information + */ + + /** \file + * \brief + * ESC hardware specifoc EEPROM emulation functions. + */ + +#ifndef __esc_hw__ +#define __esc_hw__ + +void ESC_interrupt_enable (uint32_t mask); +void ESC_interrupt_disable (uint32_t mask); + +#endif