Merge pull request #103 from MechaMagpie/etherberry

Etherberry support
pull/106/head
Hans-Erik Floryd 2021-09-06 16:44:29 +02:00 committed by GitHub
commit 4549d0af9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 2690 additions and 6 deletions

View File

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

View File

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

View File

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

View File

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

Binary file not shown.

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@ -1,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)

View File

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

View File

@ -0,0 +1,17 @@
/*
* Licensed under the GNU General Public License version 2 with exceptions. See
* LICENSE file in the project root for full license information
*/
/** \file
* \brief
* ESC hardware specifoc EEPROM emulation functions.
*/
#ifndef __esc_hw__
#define __esc_hw__
void ESC_interrupt_enable (uint32_t mask);
void ESC_interrupt_disable (uint32_t mask);
#endif