Add lan9252 for Linux (#28)
- Add kernel device driver drivers/linux/lan9252 - Add lan9252 file for linux applications/linux_lan9252demo soes/hal/linux-lan9252 - Fix linux compatibility for cc.h #ifdef __linux__pull/22/merge
parent
deb4d3743f
commit
eda5a1dc76
|
@ -0,0 +1,35 @@
|
|||
#ifndef __CONFIG_H__
|
||||
#define __CONFIG_H__
|
||||
|
||||
#include <cc.h>
|
||||
|
||||
#define MBXSIZE 128
|
||||
#define MBXSIZEBOOT 128
|
||||
#define MBXBUFFERS 3
|
||||
|
||||
#define MBX0_sma 0x1000
|
||||
#define MBX0_sml MBXSIZE
|
||||
#define MBX0_sme MBX0_sma+MBX0_sml-1
|
||||
#define MBX0_smc 0x26
|
||||
#define MBX1_sma MBX0_sma+MBX0_sml
|
||||
#define MBX1_sml MBXSIZE
|
||||
#define MBX1_sme MBX1_sma+MBX1_sml-1
|
||||
#define MBX1_smc 0x22
|
||||
|
||||
#define MBX0_sma_b 0x1000
|
||||
#define MBX0_sml_b MBXSIZEBOOT
|
||||
#define MBX0_sme_b MBX0_sma_b+MBX0_sml_b-1
|
||||
#define MBX0_smc_b 0x26
|
||||
#define MBX1_sma_b MBX0_sma_b+MBX0_sml_b
|
||||
#define MBX1_sml_b MBXSIZEBOOT
|
||||
#define MBX1_sme_b MBX1_sma_b+MBX1_sml_b-1
|
||||
#define MBX1_smc_b 0x22
|
||||
|
||||
#define SM2_sma 0x1100
|
||||
#define SM2_smc 0x24
|
||||
#define SM2_act 1
|
||||
#define SM3_sma 0x1180
|
||||
#define SM3_smc 0x20
|
||||
#define SM3_act 1
|
||||
|
||||
#endif /* __CONFIG_H__ */
|
|
@ -0,0 +1,47 @@
|
|||
#include <stdio.h>
|
||||
|
||||
/**
|
||||
* This function reads physical input values and assigns the corresponding members
|
||||
* of Rb.Buttons
|
||||
*/
|
||||
void cb_get_Buttons()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This function writes physical output values from the corresponding members of
|
||||
* Wb.LEDs
|
||||
*/
|
||||
|
||||
|
||||
void cb_set_LEDs()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function is called after a SDO write of the object Cb.Parameters.
|
||||
*/
|
||||
void cb_post_write_Parameters(int subindex)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void main_run(void * arg)
|
||||
{
|
||||
soes_init();
|
||||
|
||||
while(1) {
|
||||
soes();
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("Hello Main\n");
|
||||
main_run(NULL);
|
||||
return 0;
|
||||
}
|
||||
|
Binary file not shown.
|
@ -0,0 +1,265 @@
|
|||
#include <stddef.h>
|
||||
#include "utypes.h"
|
||||
#include "soes/esc.h"
|
||||
#include "soes/esc_coe.h"
|
||||
#include "soes/esc_foe.h"
|
||||
#include "slave.h"
|
||||
|
||||
#ifndef EEP_EMULATION
|
||||
#define EEP_EMULATION 0 /* Set to 1 for EEPROM emulation */
|
||||
#endif
|
||||
|
||||
#define WATCHDOG_RESET_VALUE 150
|
||||
#define DEFAULTTXPDOMAP 0x1a00
|
||||
#define DEFAULTRXPDOMAP 0x1600
|
||||
#define DEFAULTTXPDOITEMS 1
|
||||
#define DEFAULTRXPDOITEMS 1
|
||||
|
||||
volatile _ESCvar ESCvar;
|
||||
_MBX MBX[MBXBUFFERS];
|
||||
_MBXcontrol MBXcontrol[MBXBUFFERS];
|
||||
uint8_t MBXrun=0;
|
||||
uint16_t SM2_sml,SM3_sml;
|
||||
_Rbuffer Rb;
|
||||
_Wbuffer Wb;
|
||||
_Cbuffer Cb;
|
||||
_App App;
|
||||
uint16_t TXPDOsize,RXPDOsize;
|
||||
uint16_t txpdomap = DEFAULTTXPDOMAP;
|
||||
uint16_t rxpdomap = DEFAULTRXPDOMAP;
|
||||
uint8_t txpdoitems = DEFAULTTXPDOITEMS;
|
||||
uint8_t rxpdoitems = DEFAULTTXPDOITEMS;
|
||||
|
||||
static unsigned int watchdog = WATCHDOG_RESET_VALUE;
|
||||
static void (*application_loop_callback)(void) = NULL;
|
||||
|
||||
/** Mandatory: Hook called from the slave stack SDO Download handler to act on
|
||||
* user specified Index and Sub-index.
|
||||
*
|
||||
* @param[in] index = index of SDO download request to handle
|
||||
* @param[in] sub-index = sub-index of SDO download request to handle
|
||||
*/
|
||||
void ESC_objecthandler (uint16_t index, uint8_t subindex)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0x1c12:
|
||||
{
|
||||
if (rxpdoitems > 1)
|
||||
{
|
||||
rxpdoitems = 1;
|
||||
}
|
||||
if ((rxpdomap != 0x1600) && (rxpdomap != 0x1601)
|
||||
&& (rxpdomap != 0x0000))
|
||||
{
|
||||
rxpdomap = 0x1600;
|
||||
}
|
||||
RXPDOsize = SM2_sml = sizeRXPDO();
|
||||
break;
|
||||
}
|
||||
case 0x1c13:
|
||||
{
|
||||
if (txpdoitems > 1)
|
||||
{
|
||||
txpdoitems = 1;
|
||||
}
|
||||
if ((txpdomap != 0x1A00) && (txpdomap != 0x1A01)
|
||||
&& (rxpdomap != 0x0000))
|
||||
{
|
||||
txpdomap = 0x1A00;
|
||||
}
|
||||
TXPDOsize = SM3_sml = sizeTXPDO();
|
||||
break;
|
||||
}
|
||||
/* Handle post-write of parameter values */
|
||||
case 0x8000:
|
||||
{
|
||||
cb_post_write_Parameters(subindex);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Mandatory: Hook called from the slave stack ESC_stopoutputs to act on state changes
|
||||
* forcing us to stop outputs. Here we can set them to a safe state.
|
||||
* set
|
||||
*/
|
||||
void APP_safeoutput (void)
|
||||
{
|
||||
DPRINT ("APP_safeoutput\n");
|
||||
|
||||
// Set safe values for Wb.LEDs
|
||||
Wb.LEDs.LED0 = 0;
|
||||
Wb.LEDs.LED1 = 0;
|
||||
|
||||
}
|
||||
|
||||
/** Mandatory: Write local process data to Sync Manager 3, Master Inputs.
|
||||
*/
|
||||
void TXPDO_update (void)
|
||||
{
|
||||
ESC_write (SM3_sma, &Rb, TXPDOsize);
|
||||
}
|
||||
/** Mandatory: Read Sync Manager 2 to local process data, Master Outputs.
|
||||
*/
|
||||
void RXPDO_update (void)
|
||||
{
|
||||
ESC_read (SM2_sma, &Wb, RXPDOsize);
|
||||
}
|
||||
|
||||
/** Mandatory: Function to update local I/O, call read ethercat outputs, call
|
||||
* write ethercat inputs. Implement watch-dog counter to count-out if we have
|
||||
* made state change affecting the App.state.
|
||||
*/
|
||||
void DIG_process (void)
|
||||
{
|
||||
if (watchdog > 0)
|
||||
{
|
||||
watchdog--;
|
||||
}
|
||||
if (App.state & APPSTATE_OUTPUT)
|
||||
{
|
||||
/* SM2 trigger ? */
|
||||
if (ESCvar.ALevent & ESCREG_ALEVENT_SM2)
|
||||
{
|
||||
ESCvar.ALevent &= ~ESCREG_ALEVENT_SM2;
|
||||
RXPDO_update();
|
||||
watchdog = WATCHDOG_RESET_VALUE;
|
||||
|
||||
/* Set outputs */
|
||||
cb_set_LEDs();
|
||||
}
|
||||
if (watchdog == 0)
|
||||
{
|
||||
DPRINT("DIG_process watchdog expired\n");
|
||||
ESC_stopoutput();
|
||||
/* watchdog, invalid outputs */
|
||||
ESC_ALerror (ALERR_WATCHDOG);
|
||||
/* goto safe-op with error bit set */
|
||||
ESC_ALstatus (ESCsafeop | ESCerror);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
watchdog = WATCHDOG_RESET_VALUE;
|
||||
}
|
||||
if (App.state)
|
||||
{
|
||||
/* Update inputs */
|
||||
cb_get_Buttons();
|
||||
TXPDO_update();
|
||||
}
|
||||
}
|
||||
|
||||
/********** TODO: Generic code beyond this point ***************/
|
||||
|
||||
static const char *spi_name = "/dev/lan9252";
|
||||
|
||||
/** Optional: Hook called after state change for application specific
|
||||
* actions for specific state changes.
|
||||
*/
|
||||
void post_state_change_hook (uint8_t * as, uint8_t * an)
|
||||
{
|
||||
#if 0
|
||||
/* Add specific step change hooks here */
|
||||
if ((*as == BOOT_TO_INIT) && (*an == ESCinit))
|
||||
{
|
||||
boot_inithook();
|
||||
}
|
||||
else if((*as == INIT_TO_BOOT) && (*an & ESCerror ) == 0)
|
||||
{
|
||||
init_boothook();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Set callback run once every loop in the SOES application loop.
|
||||
*/
|
||||
void set_application_loop_hook(void (*callback)(void))
|
||||
{
|
||||
application_loop_callback = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* SOES main function. It should be called periodically.
|
||||
* Reads the EtherCAT state and status. Responsible for I/O updates.
|
||||
*/
|
||||
void soes (void)
|
||||
{
|
||||
/* On init restore PDO mappings to default size */
|
||||
if((ESCvar.ALstatus & 0x0f) == ESCinit)
|
||||
{
|
||||
txpdomap = DEFAULTTXPDOMAP;
|
||||
rxpdomap = DEFAULTRXPDOMAP;
|
||||
txpdoitems = DEFAULTTXPDOITEMS;
|
||||
rxpdoitems = DEFAULTTXPDOITEMS;
|
||||
}
|
||||
|
||||
/* Read local time from ESC */
|
||||
ESC_read (ESCREG_LOCALTIME, (void *) &ESCvar.Time, sizeof (ESCvar.Time));
|
||||
ESCvar.Time = etohl (ESCvar.Time);
|
||||
|
||||
/* Check the state machine */
|
||||
ESC_state();
|
||||
|
||||
/* Check mailboxes */
|
||||
if (ESC_mbxprocess())
|
||||
{
|
||||
ESC_coeprocess();
|
||||
ESC_foeprocess();
|
||||
ESC_xoeprocess();
|
||||
}
|
||||
DIG_process();
|
||||
#if EEP_EMULATION
|
||||
EEP_process ();
|
||||
EEP_hw_process();
|
||||
#endif /* EEP_EMULATION */
|
||||
|
||||
if (application_loop_callback != NULL)
|
||||
{
|
||||
(application_loop_callback)();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the SOES stack.
|
||||
*/
|
||||
void soes_init (void)
|
||||
{
|
||||
DPRINT ("SOES (Simple Open EtherCAT Slave)\n");
|
||||
|
||||
TXPDOsize = SM3_sml = sizeTXPDO();
|
||||
RXPDOsize = SM2_sml = sizeRXPDO();
|
||||
|
||||
/* Setup post config hooks */
|
||||
static esc_cfg_t config =
|
||||
{
|
||||
.pre_state_change_hook = NULL,
|
||||
.post_state_change_hook = post_state_change_hook
|
||||
};
|
||||
ESC_config ((esc_cfg_t *)&config);
|
||||
|
||||
ESC_reset();
|
||||
ESC_init ((void *)spi_name);
|
||||
|
||||
/* wait until ESC is started up */
|
||||
while ((ESCvar.DLstatus & 0x0001) == 0)
|
||||
{
|
||||
ESC_read (ESCREG_DLSTATUS, (void *) &ESCvar.DLstatus,
|
||||
sizeof (ESCvar.DLstatus));
|
||||
ESCvar.DLstatus = etohs (ESCvar.DLstatus);
|
||||
}
|
||||
|
||||
/* Init FoE */
|
||||
FOE_init();
|
||||
|
||||
/* reset ESC to init state */
|
||||
ESC_ALstatus (ESCinit);
|
||||
ESC_ALerror (ALERR_NONE);
|
||||
ESC_stopmbx();
|
||||
ESC_stopinput();
|
||||
ESC_stopoutput();
|
||||
}
|
|
@ -0,0 +1,298 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Slave id="evb9252_dig" productCode="1234">
|
||||
<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>
|
||||
<ConfigData>8002000000000000</ConfigData>
|
||||
<BootStrap>0010800080108000</BootStrap>
|
||||
</Eeprom>
|
||||
<Dictionary>
|
||||
<Item>
|
||||
<Name>Device Type</Name>
|
||||
<Index>0x1000</Index>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x01901389</DefaultValue>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Device Name</Name>
|
||||
<Index>0x1008</Index>
|
||||
<DataType>VISIBLE_STRING</DataType>
|
||||
<DefaultValue>evb9252_dig</DefaultValue>
|
||||
</Item>
|
||||
<Item>
|
||||
<Name>Hardware Version</Name>
|
||||
<Index>0x1009</Index>
|
||||
<DataType>VISIBLE_STRING</DataType>
|
||||
<DefaultValue>1.0</DefaultValue>
|
||||
</Item>
|
||||
<Item>
|
||||
<Name>Software Version</Name>
|
||||
<Index>0x100A</Index>
|
||||
<DataType>VISIBLE_STRING</DataType>
|
||||
<DefaultValue>1.0</DefaultValue>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Identity Object</Name>
|
||||
<Index>0x1018</Index>
|
||||
<DataType>RECORD</DataType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Vendor ID</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x1337</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Product Code</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>1234</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Revision Number</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Serial Number</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x00000000</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>LEDs</Name>
|
||||
<Index>0x1600</Index>
|
||||
<DataType>RECORD</DataType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>2</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>LED0</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x70000108</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>LED1</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x70000208</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Buttons</Name>
|
||||
<Index>0x1A00</Index>
|
||||
<DataType>RECORD</DataType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Button1</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0x60000108</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Sync Manager Communication Type</Name>
|
||||
<Index>0x1C00</Index>
|
||||
<DataType>ARRAY</DataType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Communications Type SM0</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Communications Type SM1</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>2</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Communications Type SM2</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>3</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Communications Type SM3</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Sync Manager 2 PDO Assignment</Name>
|
||||
<Index>0x1C12</Index>
|
||||
<DataType>ARRAY</DataType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>PDO Mapping</Name>
|
||||
<DataType>UNSIGNED16</DataType>
|
||||
<DefaultValue>0x1600</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Sync Manager 3 PDO Assignment</Name>
|
||||
<Index>0x1C13</Index>
|
||||
<DataType>ARRAY</DataType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>PDO Mapping</Name>
|
||||
<DataType>UNSIGNED16</DataType>
|
||||
<DefaultValue>0x1A00</DefaultValue>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Buttons</Name>
|
||||
<Index>0x6000</Index>
|
||||
<DataType>RECORD</DataType>
|
||||
<Variable>Buttons</Variable>
|
||||
<VariableType>Input</VariableType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Button1</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<Access>RO</Access>
|
||||
<Variable>Button1</Variable>
|
||||
<VariableType>Input</VariableType>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>LEDs</Name>
|
||||
<Index>0x7000</Index>
|
||||
<DataType>RECORD</DataType>
|
||||
<Variable>LEDs</Variable>
|
||||
<VariableType>Output</VariableType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>2</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>LED0</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<Access>RO</Access>
|
||||
<Variable>LED0</Variable>
|
||||
<VariableType>Output</VariableType>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>LED1</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<Access>RO</Access>
|
||||
<Variable>LED1</Variable>
|
||||
<VariableType>Output</VariableType>
|
||||
</SubItem>
|
||||
</Item>
|
||||
<Item Managed="true">
|
||||
<Name>Parameters</Name>
|
||||
<Index>0x8000</Index>
|
||||
<DataType>RECORD</DataType>
|
||||
<Variable>Parameters</Variable>
|
||||
<VariableType>Parameter</VariableType>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<DataType>UNSIGNED8</DataType>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Multiplier</Name>
|
||||
<DataType>UNSIGNED32</DataType>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
<Access>RW</Access>
|
||||
<Variable>Multiplier</Variable>
|
||||
<VariableType>Parameter</VariableType>
|
||||
</SubItem>
|
||||
</Item>
|
||||
</Dictionary>
|
||||
<RxPdo>
|
||||
<Index>0x1600</Index>
|
||||
<Container>LEDs</Container>
|
||||
<Name>LEDs</Name>
|
||||
<Entry>
|
||||
<Index>0x7000</Index>
|
||||
<SubIndex>1</SubIndex>
|
||||
<Variable>LED0</Variable>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Index>0x7000</Index>
|
||||
<SubIndex>2</SubIndex>
|
||||
<Variable>LED1</Variable>
|
||||
</Entry>
|
||||
</RxPdo>
|
||||
<TxPdo>
|
||||
<Index>0x1A00</Index>
|
||||
<Container>Buttons</Container>
|
||||
<Name>Buttons</Name>
|
||||
<Entry>
|
||||
<Index>0x6000</Index>
|
||||
<SubIndex>1</SubIndex>
|
||||
<Variable>Button1</Variable>
|
||||
</Entry>
|
||||
</TxPdo>
|
||||
<Input>
|
||||
<Name>Buttons</Name>
|
||||
<Type>RECORD</Type>
|
||||
<Member>
|
||||
<Name>Button1</Name>
|
||||
<Type>UNSIGNED8</Type>
|
||||
</Member>
|
||||
</Input>
|
||||
<Output>
|
||||
<Name>LEDs</Name>
|
||||
<Type>RECORD</Type>
|
||||
<Member>
|
||||
<Name>LED0</Name>
|
||||
<Type>UNSIGNED8</Type>
|
||||
</Member>
|
||||
<Member>
|
||||
<Name>LED1</Name>
|
||||
<Type>UNSIGNED8</Type>
|
||||
</Member>
|
||||
</Output>
|
||||
<Parameter>
|
||||
<Name>Parameters</Name>
|
||||
<Type>RECORD</Type>
|
||||
<Member>
|
||||
<Name>Multiplier</Name>
|
||||
<Type>UNSIGNED32</Type>
|
||||
</Member>
|
||||
</Parameter>
|
||||
</Slave>
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef __SLAVE_H__
|
||||
#define __SLAVE_H__
|
||||
|
||||
#include "utypes.h"
|
||||
|
||||
/**
|
||||
* This function reads physical input values and assigns the corresponding members
|
||||
* of Rb.Buttons
|
||||
*/
|
||||
void cb_get_Buttons();
|
||||
|
||||
/**
|
||||
* This function writes physical output values from the corresponding members of
|
||||
* Wb.LEDs
|
||||
*/
|
||||
void cb_set_LEDs();
|
||||
|
||||
/**
|
||||
* This function is called after a SDO write of the object Cb.Parameters.
|
||||
*/
|
||||
void cb_post_write_Parameters(int subindex);
|
||||
|
||||
/**
|
||||
* This function sets an application loop callback function.
|
||||
*/
|
||||
void set_application_loop_hook(void (*callback)(void));
|
||||
|
||||
/**
|
||||
* Main function for SOES application
|
||||
*/
|
||||
void soes (void);
|
||||
|
||||
/**
|
||||
* Initialize the SOES stack
|
||||
*/
|
||||
void soes_init (void);
|
||||
|
||||
#endif /* __SLAVE_H__ */
|
|
@ -0,0 +1,691 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<EtherCATInfo>
|
||||
<Vendor>
|
||||
<Id>#x1337</Id>
|
||||
<Name LcId="1033">rt-labs AB</Name>
|
||||
</Vendor>
|
||||
<Descriptions>
|
||||
<Groups>
|
||||
<Group>
|
||||
<Type>lan9252_spi</Type>
|
||||
<Name LcId="1033">lan9252</Name>
|
||||
</Group>
|
||||
</Groups>
|
||||
<Devices>
|
||||
<Device Physics="YY">
|
||||
<Type ProductCode="1234" RevisionNo="0">evb9252_dig</Type>
|
||||
<Name LcId="1033">lan9252</Name>
|
||||
<GroupType>lan9252_spi</GroupType>
|
||||
<Profile>
|
||||
<ProfileNo>5001</ProfileNo>
|
||||
<AddInfo>400</AddInfo>
|
||||
<Dictionary>
|
||||
<DataTypes>
|
||||
<DataType>
|
||||
<Name>DT1018</Name>
|
||||
<BitSize>144</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<SubIdx>1</SubIdx>
|
||||
<Name>Vendor ID</Name>
|
||||
<Type>UDINT</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<BitOffs>16</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<SubIdx>2</SubIdx>
|
||||
<Name>Product Code</Name>
|
||||
<Type>UDINT</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<BitOffs>48</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<SubIdx>3</SubIdx>
|
||||
<Name>Revision Number</Name>
|
||||
<Type>UDINT</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<BitOffs>80</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<SubIdx>4</SubIdx>
|
||||
<Name>Serial Number</Name>
|
||||
<Type>UDINT</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<BitOffs>112</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>DT1600</Name>
|
||||
<BitSize>80</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<SubIdx>1</SubIdx>
|
||||
<Name>LED0</Name>
|
||||
<Type>UDINT</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<BitOffs>16</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<SubIdx>2</SubIdx>
|
||||
<Name>LED1</Name>
|
||||
<Type>UDINT</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<BitOffs>48</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>DT1A00</Name>
|
||||
<BitSize>48</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<SubIdx>1</SubIdx>
|
||||
<Name>Button1</Name>
|
||||
<Type>UDINT</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<BitOffs>16</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>DT1C00ARR</Name>
|
||||
<BaseType>USINT</BaseType>
|
||||
<BitSize>32</BitSize>
|
||||
<ArrayInfo>
|
||||
<LBound>1</LBound>
|
||||
<Elements>4</Elements>
|
||||
</ArrayInfo>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>DT1C00</Name>
|
||||
<BitSize>48</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Elements</Name>
|
||||
<Type>DT1C00ARR</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<BitOffs>16</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>DT1C12ARR</Name>
|
||||
<BaseType>UINT</BaseType>
|
||||
<BitSize>16</BitSize>
|
||||
<ArrayInfo>
|
||||
<LBound>1</LBound>
|
||||
<Elements>1</Elements>
|
||||
</ArrayInfo>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>DT1C12</Name>
|
||||
<BitSize>32</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Elements</Name>
|
||||
<Type>DT1C12ARR</Type>
|
||||
<BitSize>16</BitSize>
|
||||
<BitOffs>16</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>DT1C13ARR</Name>
|
||||
<BaseType>UINT</BaseType>
|
||||
<BitSize>16</BitSize>
|
||||
<ArrayInfo>
|
||||
<LBound>1</LBound>
|
||||
<Elements>1</Elements>
|
||||
</ArrayInfo>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>DT1C13</Name>
|
||||
<BitSize>32</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Elements</Name>
|
||||
<Type>DT1C13ARR</Type>
|
||||
<BitSize>16</BitSize>
|
||||
<BitOffs>16</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>DT6000</Name>
|
||||
<BitSize>24</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<SubIdx>1</SubIdx>
|
||||
<Name>Button1</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>16</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>DT7000</Name>
|
||||
<BitSize>32</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<SubIdx>1</SubIdx>
|
||||
<Name>LED0</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>16</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<SubIdx>2</SubIdx>
|
||||
<Name>LED1</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>24</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>DT8000</Name>
|
||||
<BitSize>48</BitSize>
|
||||
<SubItem>
|
||||
<SubIdx>0</SubIdx>
|
||||
<Name>Number of Elements</Name>
|
||||
<Type>USINT</Type>
|
||||
<BitSize>8</BitSize>
|
||||
<BitOffs>0</BitOffs>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<SubIdx>1</SubIdx>
|
||||
<Name>Multiplier</Name>
|
||||
<Type>UDINT</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<BitOffs>16</BitOffs>
|
||||
<Flags>
|
||||
<Access>rw</Access>
|
||||
</Flags>
|
||||
</SubItem>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>STRING(3)</Name>
|
||||
<BitSize>24</BitSize>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>STRING(11)</Name>
|
||||
<BitSize>88</BitSize>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>UDINT</Name>
|
||||
<BitSize>32</BitSize>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>UINT</Name>
|
||||
<BitSize>16</BitSize>
|
||||
</DataType>
|
||||
<DataType>
|
||||
<Name>USINT</Name>
|
||||
<BitSize>8</BitSize>
|
||||
</DataType>
|
||||
</DataTypes>
|
||||
<Objects>
|
||||
<Object>
|
||||
<Index>#x1000</Index>
|
||||
<Name>Device Type</Name>
|
||||
<Type>UDINT</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<Info>
|
||||
<DefaultValue>#x01901389</DefaultValue>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
<Category>m</Category>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x1008</Index>
|
||||
<Name>Device Name</Name>
|
||||
<Type>STRING(11)</Type>
|
||||
<BitSize>88</BitSize>
|
||||
<Info>
|
||||
<DefaultString>evb9252_dig</DefaultString>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x1009</Index>
|
||||
<Name>Hardware Version</Name>
|
||||
<Type>STRING(3)</Type>
|
||||
<BitSize>24</BitSize>
|
||||
<Info>
|
||||
<DefaultString>1.0</DefaultString>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
<Category>o</Category>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x100A</Index>
|
||||
<Name>Software Version</Name>
|
||||
<Type>STRING(3)</Type>
|
||||
<BitSize>24</BitSize>
|
||||
<Info>
|
||||
<DefaultString>1.0</DefaultString>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x1018</Index>
|
||||
<Name>Identity Object</Name>
|
||||
<Type>DT1018</Type>
|
||||
<BitSize>144</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Info>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Vendor ID</Name>
|
||||
<Info>
|
||||
<DefaultValue>#x1337</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Product Code</Name>
|
||||
<Info>
|
||||
<DefaultValue>1234</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Revision Number</Name>
|
||||
<Info>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Serial Number</Name>
|
||||
<Info>
|
||||
<DefaultValue>#x00000000</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x1600</Index>
|
||||
<Name>LEDs</Name>
|
||||
<Type>DT1600</Type>
|
||||
<BitSize>80</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Info>
|
||||
<DefaultValue>2</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>LED0</Name>
|
||||
<Info>
|
||||
<DefaultValue>#x70000108</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>LED1</Name>
|
||||
<Info>
|
||||
<DefaultValue>#x70000208</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x1A00</Index>
|
||||
<Name>Buttons</Name>
|
||||
<Type>DT1A00</Type>
|
||||
<BitSize>48</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Button1</Name>
|
||||
<Info>
|
||||
<DefaultValue>#x60000108</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x1C00</Index>
|
||||
<Name>Sync Manager Communication Type</Name>
|
||||
<Type>DT1C00</Type>
|
||||
<BitSize>48</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Info>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Communications Type SM0</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Communications Type SM1</Name>
|
||||
<Info>
|
||||
<DefaultValue>2</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Communications Type SM2</Name>
|
||||
<Info>
|
||||
<DefaultValue>3</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Communications Type SM3</Name>
|
||||
<Info>
|
||||
<DefaultValue>4</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x1C12</Index>
|
||||
<Name>Sync Manager 2 PDO Assignment</Name>
|
||||
<Type>DT1C12</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>PDO Mapping</Name>
|
||||
<Info>
|
||||
<DefaultValue>#x1600</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x1C13</Index>
|
||||
<Name>Sync Manager 3 PDO Assignment</Name>
|
||||
<Type>DT1C13</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>PDO Mapping</Name>
|
||||
<Info>
|
||||
<DefaultValue>#x1A00</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x6000</Index>
|
||||
<Name>Buttons</Name>
|
||||
<Type>DT6000</Type>
|
||||
<BitSize>24</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Button1</Name>
|
||||
<Info>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x7000</Index>
|
||||
<Name>LEDs</Name>
|
||||
<Type>DT7000</Type>
|
||||
<BitSize>32</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Info>
|
||||
<DefaultValue>2</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>LED0</Name>
|
||||
<Info>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>LED1</Name>
|
||||
<Info>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
<Object>
|
||||
<Index>#x8000</Index>
|
||||
<Name>Parameters</Name>
|
||||
<Type>DT8000</Type>
|
||||
<BitSize>48</BitSize>
|
||||
<Info>
|
||||
<SubItem>
|
||||
<Name>Number of Elements</Name>
|
||||
<Info>
|
||||
<DefaultValue>1</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
<SubItem>
|
||||
<Name>Multiplier</Name>
|
||||
<Info>
|
||||
<DefaultValue>0</DefaultValue>
|
||||
</Info>
|
||||
</SubItem>
|
||||
</Info>
|
||||
<Flags>
|
||||
<Access>ro</Access>
|
||||
</Flags>
|
||||
</Object>
|
||||
</Objects>
|
||||
</Dictionary>
|
||||
</Profile>
|
||||
<Fmmu>Outputs</Fmmu>
|
||||
<Fmmu>Inputs</Fmmu>
|
||||
<Sm ControlByte="#x26" DefaultSize="128" Enable="1" StartAddress="#x1000">MBoxOut</Sm>
|
||||
<Sm ControlByte="#x22" DefaultSize="128" Enable="1" StartAddress="#x1080">MBoxIn</Sm>
|
||||
<Sm ControlByte="#x24" Enable="1" StartAddress="#x1100">Outputs</Sm>
|
||||
<Sm ControlByte="#x20" Enable="1" StartAddress="#x1180">Inputs</Sm>
|
||||
<RxPdo Fixed="true" Mandatory="true" Sm="2">
|
||||
<Index>#x1600</Index>
|
||||
<Name>LEDs</Name>
|
||||
<Entry>
|
||||
<Index>#x7000</Index>
|
||||
<SubIndex>1</SubIndex>
|
||||
<BitLen>8</BitLen>
|
||||
<Name>LED0</Name>
|
||||
<DataType>USINT</DataType>
|
||||
</Entry>
|
||||
<Entry>
|
||||
<Index>#x7000</Index>
|
||||
<SubIndex>2</SubIndex>
|
||||
<BitLen>8</BitLen>
|
||||
<Name>LED1</Name>
|
||||
<DataType>USINT</DataType>
|
||||
</Entry>
|
||||
</RxPdo>
|
||||
<TxPdo Fixed="true" Mandatory="true" Sm="3">
|
||||
<Index>#x1A00</Index>
|
||||
<Name>Buttons</Name>
|
||||
<Entry>
|
||||
<Index>#x6000</Index>
|
||||
<SubIndex>1</SubIndex>
|
||||
<BitLen>8</BitLen>
|
||||
<Name>Button1</Name>
|
||||
<DataType>USINT</DataType>
|
||||
</Entry>
|
||||
</TxPdo>
|
||||
<Mailbox DataLinkLayer="true">
|
||||
<CoE CompleteAccess="false" PdoUpload="true" SdoInfo="true"/>
|
||||
<FoE/>
|
||||
</Mailbox>
|
||||
<Eeprom>
|
||||
<ByteSize>256</ByteSize>
|
||||
<ConfigData>8002000000000000</ConfigData>
|
||||
<BootStrap>0010800080108000</BootStrap>
|
||||
</Eeprom>
|
||||
</Device>
|
||||
</Devices>
|
||||
</Descriptions>
|
||||
</EtherCATInfo>
|
|
@ -0,0 +1,135 @@
|
|||
#include "soes/esc_coe.h"
|
||||
#include "utypes.h"
|
||||
#include <stddef.h>
|
||||
|
||||
static const char acName1000[] = "Device Type";
|
||||
static const char acName1000_0[] = "Device Type";
|
||||
static const char acName1008[] = "Device Name";
|
||||
static const char acName1008_0[] = "Device Name";
|
||||
static const char acName1009[] = "Hardware Version";
|
||||
static const char acName1009_0[] = "Hardware Version";
|
||||
static const char acName100A[] = "Software Version";
|
||||
static const char acName100A_0[] = "Software Version";
|
||||
static const char acName1018[] = "Identity Object";
|
||||
static const char acName1018_00[] = "Number of Elements";
|
||||
static const char acName1018_01[] = "Vendor ID";
|
||||
static const char acName1018_02[] = "Product Code";
|
||||
static const char acName1018_03[] = "Revision Number";
|
||||
static const char acName1018_04[] = "Serial Number";
|
||||
static const char acName1600[] = "LEDs";
|
||||
static const char acName1600_00[] = "Number of Elements";
|
||||
static const char acName1600_01[] = "LED0";
|
||||
static const char acName1600_02[] = "LED1";
|
||||
static const char acName1A00[] = "Buttons";
|
||||
static const char acName1A00_00[] = "Number of Elements";
|
||||
static const char acName1A00_01[] = "Button1";
|
||||
static const char acName1C00[] = "Sync Manager Communication Type";
|
||||
static const char acName1C00_00[] = "Number of Elements";
|
||||
static const char acName1C00_01[] = "Communications Type SM0";
|
||||
static const char acName1C00_02[] = "Communications Type SM1";
|
||||
static const char acName1C00_03[] = "Communications Type SM2";
|
||||
static const char acName1C00_04[] = "Communications Type SM3";
|
||||
static const char acName1C12[] = "Sync Manager 2 PDO Assignment";
|
||||
static const char acName1C12_00[] = "Number of Elements";
|
||||
static const char acName1C12_01[] = "PDO Mapping";
|
||||
static const char acName1C13[] = "Sync Manager 3 PDO Assignment";
|
||||
static const char acName1C13_00[] = "Number of Elements";
|
||||
static const char acName1C13_01[] = "PDO Mapping";
|
||||
static const char acName6000[] = "Buttons";
|
||||
static const char acName6000_00[] = "Number of Elements";
|
||||
static const char acName6000_01[] = "Button1";
|
||||
static const char acName7000[] = "LEDs";
|
||||
static const char acName7000_00[] = "Number of Elements";
|
||||
static const char acName7000_01[] = "LED0";
|
||||
static const char acName7000_02[] = "LED1";
|
||||
static const char acName8000[] = "Parameters";
|
||||
static const char acName8000_00[] = "Number of Elements";
|
||||
static const char acName8000_01[] = "Multiplier";
|
||||
|
||||
const _objd SDO1000[] =
|
||||
{
|
||||
{0x0, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1000_0, 0x01901389, NULL},
|
||||
};
|
||||
const _objd SDO1008[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 88, ATYPE_RO, acName1008_0, 0, "evb9252_dig"},
|
||||
};
|
||||
const _objd SDO1009[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName1009_0, 0, "1.0"},
|
||||
};
|
||||
const _objd SDO100A[] =
|
||||
{
|
||||
{0x0, DTYPE_VISIBLE_STRING, 24, ATYPE_RO, acName100A_0, 0, "1.0"},
|
||||
};
|
||||
const _objd SDO1018[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1018_00, 4, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_01, 0x1337, NULL},
|
||||
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_02, 1234, NULL},
|
||||
{0x03, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_03, 0, NULL},
|
||||
{0x04, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1018_04, 0x00000000, NULL},
|
||||
};
|
||||
const _objd SDO1600[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1600_00, 2, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_01, 0x70000108, NULL},
|
||||
{0x02, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1600_02, 0x70000208, NULL},
|
||||
};
|
||||
const _objd SDO1A00[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName1A00_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RO, acName1A00_01, 0x60000108, NULL},
|
||||
};
|
||||
const _objd 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, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName6000_01, 0, &Rb.Buttons.Button1},
|
||||
};
|
||||
const _objd SDO7000[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_00, 2, NULL},
|
||||
{0x01, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_01, 0, &Wb.LEDs.LED0},
|
||||
{0x02, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName7000_02, 0, &Wb.LEDs.LED1},
|
||||
};
|
||||
const _objd SDO8000[] =
|
||||
{
|
||||
{0x00, DTYPE_UNSIGNED8, 8, ATYPE_RO, acName8000_00, 1, NULL},
|
||||
{0x01, DTYPE_UNSIGNED32, 32, ATYPE_RW, acName8000_01, 0, &Cb.Parameters.Multiplier},
|
||||
};
|
||||
|
||||
const _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, 2, 0, acName1600, SDO1600},
|
||||
{0x1A00, OTYPE_RECORD, 1, 0, acName1A00, SDO1A00},
|
||||
{0x1C00, OTYPE_ARRAY, 4, 0, acName1C00, SDO1C00},
|
||||
{0x1C12, OTYPE_ARRAY, 1, 0, acName1C12, SDO1C12},
|
||||
{0x1C13, OTYPE_ARRAY, 1, 0, acName1C13, SDO1C13},
|
||||
{0x6000, OTYPE_RECORD, 1, 0, acName6000, SDO6000},
|
||||
{0x7000, OTYPE_RECORD, 2, 0, acName7000, SDO7000},
|
||||
{0x8000, OTYPE_RECORD, 1, 0, acName8000, SDO8000},
|
||||
{0xffff, 0xff, 0xff, 0xff, NULL, NULL}
|
||||
};
|
|
@ -0,0 +1,47 @@
|
|||
#ifndef __UTYPES_H__
|
||||
#define __UTYPES_H__
|
||||
|
||||
#include <cc.h>
|
||||
|
||||
CC_PACKED_BEGIN
|
||||
typedef struct
|
||||
{
|
||||
CC_PACKED_BEGIN
|
||||
struct
|
||||
{
|
||||
uint8_t Button1;
|
||||
} CC_PACKED Buttons;
|
||||
CC_PACKED_END
|
||||
} CC_PACKED _Rbuffer;
|
||||
CC_PACKED_END
|
||||
|
||||
CC_PACKED_BEGIN
|
||||
typedef struct
|
||||
{
|
||||
CC_PACKED_BEGIN
|
||||
struct
|
||||
{
|
||||
uint8_t LED0;
|
||||
uint8_t LED1;
|
||||
} CC_PACKED LEDs;
|
||||
CC_PACKED_END
|
||||
} CC_PACKED _Wbuffer;
|
||||
CC_PACKED_END
|
||||
|
||||
CC_PACKED_BEGIN
|
||||
typedef struct
|
||||
{
|
||||
CC_PACKED_BEGIN
|
||||
struct
|
||||
{
|
||||
uint32_t Multiplier;
|
||||
} CC_PACKED Parameters;
|
||||
CC_PACKED_END
|
||||
} CC_PACKED _Cbuffer;
|
||||
CC_PACKED_END
|
||||
|
||||
extern _Rbuffer Rb;
|
||||
extern _Wbuffer Wb;
|
||||
extern _Cbuffer Cb;
|
||||
|
||||
#endif /* __UTYPES_H__ */
|
|
@ -0,0 +1,4 @@
|
|||
config LAN9252
|
||||
tristate "Microchip LAN9252(ethercat slave controller) support"
|
||||
help
|
||||
SPI driver for Microchip LAN9252 ethercat slave controller interface.
|
|
@ -0,0 +1 @@
|
|||
obj-$(CONFIG_LAN9252) += lan9252.o
|
|
@ -0,0 +1,414 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
/*
|
||||
Datasheet : http://ww1.microchip.com/downloads/en/DeviceDoc/
|
||||
00001909A.pdf
|
||||
*/
|
||||
|
||||
#define LAN9252_MAGIC 'l' //8bit=0~0xff 'l'an9252
|
||||
#define TEST _IO(LAN9252_MAGIC, 0)
|
||||
|
||||
#define LAN9252_LOCK mutex_lock(&lan9252_mutex);
|
||||
#define LAN9252_UNLOCK mutex_unlock(&lan9252_mutex);
|
||||
|
||||
#define DEVICE_NAME "lan9252"
|
||||
#define LAN9252_MAJOR 153
|
||||
|
||||
#define FAST_READ 0x0B
|
||||
#define FAST_READ_DUMMY 1
|
||||
|
||||
struct mutex lock;
|
||||
static DEFINE_MUTEX(lan9252_mutex);
|
||||
|
||||
dev_t id;
|
||||
static struct device *dev;
|
||||
static struct class *lan9252_class;
|
||||
static struct spi_device *lan9252_devices;
|
||||
|
||||
static int lan9252_ethercat_probe(struct spi_device *spi);
|
||||
static int lan9252_ethercat_remove(struct spi_device *spi);
|
||||
|
||||
static int lan9252_open(struct inode *inode, struct file *filp)
|
||||
{
|
||||
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lan9252_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static loff_t lan9252_llseek(struct file *file, loff_t address,
|
||||
int whence)
|
||||
{
|
||||
int status;
|
||||
|
||||
LAN9252_LOCK;
|
||||
|
||||
file->f_pos = address;
|
||||
|
||||
status = file->f_pos;
|
||||
|
||||
LAN9252_UNLOCK;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int * lan9252_reg_addr_make(int address)
|
||||
{
|
||||
|
||||
int temp;
|
||||
static int lan9252_reg_addr[2];
|
||||
#ifdef DEBUG
|
||||
int i;
|
||||
#endif
|
||||
|
||||
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__);
|
||||
|
||||
temp = address & 0xff00;
|
||||
lan9252_reg_addr[0] = temp >> 8;
|
||||
temp = address & 0x00ff;
|
||||
lan9252_reg_addr[1] = temp;
|
||||
|
||||
#ifdef DEBUG
|
||||
for (i=0; i<2; i++)
|
||||
dev_dbg(&lan9252_devices->dev, "%s() lan9252_reg_addr[%d] = 0x%x\n",
|
||||
__FUNCTION__, i, lan9252_reg_addr[i]);
|
||||
#endif
|
||||
|
||||
return lan9252_reg_addr;
|
||||
}
|
||||
|
||||
/*
|
||||
int lan9252_test(void);
|
||||
Description : Check the connection status of LAN9252
|
||||
Retrun Value
|
||||
0 : success
|
||||
other : fail
|
||||
|
||||
Register Type : SYSTEM CONTROL AND STATUS REGISTERS
|
||||
Register Name(SYMBOL) : BYTE ORDER TEST REGISTER(BYTE_TEST)
|
||||
Offset : 0x0064
|
||||
Size : 32bit
|
||||
Default : 0x87654321
|
||||
Datasheet description : Chip-level reset/configuration
|
||||
completion can be determined by first
|
||||
polling the
|
||||
Byte Order Test Register(BYTE_TEST).
|
||||
*/
|
||||
static int lan9252_test(void)
|
||||
{
|
||||
u8 command[4];
|
||||
u8 test_buffer[4];
|
||||
int status=0;
|
||||
#ifdef DEBUG
|
||||
int i;
|
||||
#endif
|
||||
command[0]=FAST_READ;
|
||||
command[1]=0x00;
|
||||
command[2]=0x64;
|
||||
command[3]=FAST_READ_DUMMY;
|
||||
|
||||
|
||||
status = spi_write_then_read(lan9252_devices, &command,
|
||||
sizeof(command), test_buffer, sizeof(test_buffer));
|
||||
if (status < 0 ) {
|
||||
dev_err(&lan9252_devices->dev, "%s() spi_write_then_read "
|
||||
" failed status=%d\n", __FUNCTION__, status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = spi_write_then_read(lan9252_devices, &command,
|
||||
sizeof(command), test_buffer, sizeof(test_buffer));
|
||||
if (status < 0 ) {
|
||||
dev_err(&lan9252_devices->dev, "%s() spi_write_then_read "
|
||||
" failed status=%d\n", __FUNCTION__, status);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
for (i=0; i<sizeof(test_buffer); i++)
|
||||
dev_dbg(&lan9252_devices->dev, "%s() test_buffer[%d] = 0x%x\n",
|
||||
__FUNCTION__, i, test_buffer[i]);
|
||||
#endif
|
||||
|
||||
if (test_buffer[0]==0x21 && test_buffer[1]==0x43 &&
|
||||
test_buffer[2]==0x65 && test_buffer[3]==0x87)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
static ssize_t lan9252_read(
|
||||
struct file *file, char *buffer,
|
||||
size_t read_buffer_size, loff_t *f_pos)
|
||||
{
|
||||
u8 command[4];
|
||||
u8 *read_buffer;
|
||||
int status=0;
|
||||
int *lan9252_reg_read_addr;
|
||||
#ifdef DEBUG
|
||||
int i;
|
||||
#endif
|
||||
|
||||
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__);
|
||||
|
||||
LAN9252_LOCK;
|
||||
|
||||
if (read_buffer_size <= 0) {
|
||||
dev_err(&lan9252_devices->dev, "read_buffer_size(%d) <= 0 \n",
|
||||
read_buffer_size);
|
||||
goto out;
|
||||
} else {
|
||||
dev_dbg(&lan9252_devices->dev, "read_buffer_size = %d\n",
|
||||
read_buffer_size);
|
||||
}
|
||||
|
||||
read_buffer= (u8 *)kmalloc((read_buffer_size) *
|
||||
sizeof(u32), GFP_KERNEL | GFP_DMA);
|
||||
if (!read_buffer) {
|
||||
dev_err(&lan9252_devices->dev, "read_buffer kmalloc error\n");
|
||||
status = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(read_buffer, 0, (read_buffer_size) * sizeof(u8));
|
||||
|
||||
lan9252_reg_read_addr = lan9252_reg_addr_make(file->f_pos);
|
||||
command[0] = FAST_READ;
|
||||
command[1] = lan9252_reg_read_addr[0];
|
||||
command[2] = lan9252_reg_read_addr[1];
|
||||
command[3] = FAST_READ_DUMMY;
|
||||
|
||||
#ifdef DEBUG
|
||||
for (i=0; i<4; i++)
|
||||
dev_dbg(&lan9252_devices->dev, "%s() command[%d] = 0x%x\n",
|
||||
__FUNCTION__, i, command[i]);
|
||||
#endif
|
||||
|
||||
status = spi_write_then_read(lan9252_devices, &command,
|
||||
sizeof(command), read_buffer,read_buffer_size);
|
||||
if (status < 0 ) {
|
||||
dev_err(&lan9252_devices->dev, "%s() spi_write_then_read "
|
||||
"failed status=%d\n", __FUNCTION__, status);
|
||||
goto kfree_read_buffer;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
for (i=0; i<read_buffer_size; i++)
|
||||
dev_dbg(&lan9252_devices->dev, "%s() read_buffer[%d] = 0x%x\n",
|
||||
__FUNCTION__, i, read_buffer[i]);
|
||||
#endif
|
||||
|
||||
if (copy_to_user(buffer, read_buffer, read_buffer_size)) {
|
||||
dev_err(&lan9252_devices->dev, "%s() copy_to_user failed\n",
|
||||
__FUNCTION__);
|
||||
status = -EFAULT;
|
||||
goto kfree_read_buffer;
|
||||
}
|
||||
|
||||
status = read_buffer_size;
|
||||
|
||||
kfree_read_buffer:
|
||||
kfree(read_buffer);
|
||||
|
||||
out:
|
||||
LAN9252_UNLOCK;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t lan9252_write(
|
||||
struct file *file, const char *command_buff,
|
||||
size_t command_buff_size, loff_t *f_pos)
|
||||
{
|
||||
u8 *command;
|
||||
int status=0;
|
||||
#ifdef DEBUG
|
||||
int i;
|
||||
#endif
|
||||
|
||||
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__);
|
||||
|
||||
LAN9252_LOCK;
|
||||
|
||||
if (command_buff_size <= 0) {
|
||||
dev_err(&lan9252_devices->dev, "command_buff_size(%d) <= 0 \n",
|
||||
command_buff_size);
|
||||
goto out;
|
||||
} else {
|
||||
dev_dbg(&lan9252_devices->dev, "command_buff_size = %d\n",
|
||||
command_buff_size);
|
||||
}
|
||||
|
||||
command = (u8 *)kmalloc((command_buff_size) *
|
||||
sizeof(u8), GFP_KERNEL | GFP_DMA);
|
||||
if (!command) {
|
||||
dev_err(&lan9252_devices->dev, "write command buffer kmalloc"
|
||||
" error\n");
|
||||
status = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memset(command, 0, (command_buff_size) * sizeof(u8));
|
||||
|
||||
if (copy_from_user(command, command_buff, command_buff_size)) {
|
||||
dev_err(&lan9252_devices->dev, "%s() copy_from_user failed\n",
|
||||
__FUNCTION__);
|
||||
status = -EFAULT;
|
||||
goto kfree_command;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
for(i=0;i<command_buff_size;i++)
|
||||
dev_dbg(&lan9252_devices->dev, "command[%d]=0x%x\n", i,
|
||||
command[i]);
|
||||
#endif
|
||||
|
||||
status = spi_write_then_read(lan9252_devices, command,
|
||||
command_buff_size, NULL, 0);
|
||||
if (status < 0 ) {
|
||||
dev_err(&lan9252_devices->dev, "%s() spi_write_then_read "
|
||||
"failed status=%d\n", __FUNCTION__, status);
|
||||
goto kfree_command;
|
||||
}
|
||||
|
||||
kfree_command:
|
||||
kfree(command);
|
||||
|
||||
out:
|
||||
LAN9252_UNLOCK;
|
||||
return status;
|
||||
}
|
||||
|
||||
static long lan9252_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long argument)
|
||||
{
|
||||
int status;
|
||||
|
||||
LAN9252_LOCK;
|
||||
|
||||
switch (cmd) {
|
||||
case TEST:
|
||||
status=lan9252_test();
|
||||
break;
|
||||
|
||||
default:
|
||||
status=0;
|
||||
break;
|
||||
}
|
||||
|
||||
LAN9252_UNLOCK;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static const struct spi_device_id lan9252_id_table[] = {
|
||||
{ "lan9252", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, lan9252_id_table);
|
||||
|
||||
static const struct file_operations lan9252_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = lan9252_open,
|
||||
.release = lan9252_release,
|
||||
.llseek = lan9252_llseek,
|
||||
.write = lan9252_write,
|
||||
.read = lan9252_read,
|
||||
.unlocked_ioctl = lan9252_ioctl,
|
||||
};
|
||||
|
||||
static struct spi_driver lan9252_ethercat_driver = {
|
||||
.driver = {
|
||||
.name = DEVICE_NAME,
|
||||
},
|
||||
.id_table = lan9252_id_table,
|
||||
.probe = lan9252_ethercat_probe,
|
||||
.remove = lan9252_ethercat_remove,
|
||||
};
|
||||
|
||||
static int lan9252_ethercat_probe(struct spi_device *spi)
|
||||
{
|
||||
int status;
|
||||
|
||||
dev_dbg(&spi->dev, "%s() called\n", __FUNCTION__);
|
||||
|
||||
mutex_init(&lock);
|
||||
|
||||
lan9252_devices = spi;
|
||||
|
||||
if(lan9252_test())
|
||||
dev_warn(&lan9252_devices->dev, "lan9252 not connected\n");
|
||||
|
||||
if (register_chrdev(LAN9252_MAJOR,
|
||||
lan9252_ethercat_driver.driver.name, &lan9252_fops)) {
|
||||
dev_err(&lan9252_devices->dev, "unable to get major %d for "
|
||||
, LAN9252_MAJOR);
|
||||
status = -ENODEV;
|
||||
goto register_chrdev_fail;
|
||||
}
|
||||
|
||||
lan9252_class = class_create(THIS_MODULE,
|
||||
lan9252_ethercat_driver.driver.name);
|
||||
if (IS_ERR(lan9252_class)) {
|
||||
status = PTR_ERR(lan9252_class);
|
||||
goto class_create_fail;
|
||||
}
|
||||
|
||||
id = MKDEV(LAN9252_MAJOR, 0);
|
||||
dev = device_create(lan9252_class, NULL, id, NULL,
|
||||
lan9252_ethercat_driver.driver.name);
|
||||
if (IS_ERR(dev)) {
|
||||
status = PTR_ERR(dev);
|
||||
dev_err(dev, "device_create error %d\n", status);
|
||||
goto device_create_fail;
|
||||
|
||||
}
|
||||
|
||||
dev_dbg(&lan9252_devices->dev, "spi->max_speed_hz=%d"
|
||||
" spi->bits_per_word=%d spi->mode=%d\n", spi->max_speed_hz,
|
||||
spi->bits_per_word, spi->mode);
|
||||
dev_dbg(&lan9252_devices->dev, "spi->chip_select=%d spi->cs_gpio=%d\n",
|
||||
spi->chip_select, spi->cs_gpio);
|
||||
|
||||
dev_info(&lan9252_devices->dev, "Probed\n");
|
||||
|
||||
return 0;
|
||||
|
||||
device_create_fail:
|
||||
class_destroy(lan9252_class);
|
||||
|
||||
class_create_fail:
|
||||
unregister_chrdev(LAN9252_MAJOR,
|
||||
lan9252_ethercat_driver.driver.name);
|
||||
|
||||
register_chrdev_fail:
|
||||
dev_err(&lan9252_devices->dev, "Probed failed : %d\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int lan9252_ethercat_remove(struct spi_device *spi)
|
||||
{
|
||||
dev_dbg(&lan9252_devices->dev, "%s() called\n", __FUNCTION__);
|
||||
|
||||
device_destroy(lan9252_class, id);
|
||||
class_destroy(lan9252_class);
|
||||
unregister_chrdev(LAN9252_MAJOR,
|
||||
lan9252_ethercat_driver.driver.name);
|
||||
|
||||
dev_info(&lan9252_devices->dev, "Removed\n");
|
||||
return 0;
|
||||
}
|
||||
module_spi_driver(lan9252_ethercat_driver);
|
||||
|
||||
MODULE_AUTHOR("tykwon@m2i.co.kr");
|
||||
MODULE_DESCRIPTION("Microchip LAN9252 Ethercat Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
|
@ -0,0 +1,13 @@
|
|||
* Microchip LAN9252 stand-alone EtherCAT slave controller device tree bindings
|
||||
|
||||
Required properties:
|
||||
- compatible: Should be "lan9252".
|
||||
- spi-max-frequency : Max spi frequency to use
|
||||
- reg: SPI chip select.
|
||||
|
||||
Example:
|
||||
ethercat: lan9252@1 {
|
||||
compatible = "lan9252";
|
||||
spi-max-frequency = <20000000>;
|
||||
reg = <1>;
|
||||
};
|
|
@ -0,0 +1,461 @@
|
|||
/*
|
||||
* SOES Simple Open EtherCAT Slave
|
||||
*
|
||||
* Copyright (C) 2007-2017 Arthur Ketels
|
||||
* Copyright (C) 2012-2017 rt-labs.
|
||||
*
|
||||
* SOES is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License version 2 as published by the Free
|
||||
* Software Foundation.
|
||||
*
|
||||
* SOES is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* for more details.
|
||||
*
|
||||
* As a special exception, if other files instantiate templates or use macros
|
||||
* or inline functions from this file, or you compile this file and link it
|
||||
* with other works to produce a work based on this file, this file does not
|
||||
* by itself cause the resulting work to be covered by the GNU General Public
|
||||
* License. However the source code for this file must still be made available
|
||||
* in accordance with section (3) of the GNU General Public License.
|
||||
*
|
||||
* This exception does not invalidate any other reasons why a work based on
|
||||
* this file might be covered by the GNU General Public License.
|
||||
*
|
||||
* The EtherCAT Technology, the trade name and logo "EtherCAT" are the intellectual
|
||||
* property of, and protected by Beckhoff Automation GmbH.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief
|
||||
* ESC hardware layer functions for LAN9252.
|
||||
*
|
||||
* Function to read and write commands to the ESC. Used to read/write ESC
|
||||
* registers and memory.
|
||||
*/
|
||||
#include "utypes.h"
|
||||
#include "esc.h"
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define BIT(x) 1 << (x)
|
||||
|
||||
#define ESC_CMD_SERIAL_WRITE 0x02
|
||||
#define ESC_CMD_SERIAL_READ 0x03
|
||||
#define ESC_CMD_FAST_READ 0x0B
|
||||
#define ESC_CMD_RESET_SQI 0xFF
|
||||
|
||||
#define ESC_CMD_FAST_READ_DUMMY 1
|
||||
#define ESC_CMD_ADDR_INC BIT(6)
|
||||
|
||||
#define ESC_PRAM_RD_FIFO_REG 0x000
|
||||
#define ESC_PRAM_WR_FIFO_REG 0x020
|
||||
#define ESC_PRAM_RD_ADDR_LEN_REG 0x308
|
||||
#define ESC_PRAM_RD_CMD_REG 0x30C
|
||||
#define ESC_PRAM_WR_ADDR_LEN_REG 0x310
|
||||
#define ESC_PRAM_WR_CMD_REG 0x314
|
||||
|
||||
#define ESC_PRAM_CMD_BUSY BIT(31)
|
||||
#define ESC_PRAM_CMD_ABORT BIT(30)
|
||||
|
||||
#define ESC_PRAM_CMD_CNT(x) ((x >> 8) & 0x1F)
|
||||
#define ESC_PRAM_CMD_AVAIL BIT(0)
|
||||
|
||||
#define ESC_PRAM_SIZE(x) ((x) << 16)
|
||||
#define ESC_PRAM_ADDR(x) ((x) << 0)
|
||||
|
||||
#define ESC_CSR_DATA_REG 0x300
|
||||
#define ESC_CSR_CMD_REG 0x304
|
||||
|
||||
#define ESC_CSR_CMD_BUSY BIT(31)
|
||||
#define ESC_CSR_CMD_READ (BIT(31) | BIT(30))
|
||||
#define ESC_CSR_CMD_WRITE BIT(31)
|
||||
#define ESC_CSR_CMD_SIZE(x) (x << 16)
|
||||
|
||||
#define ESC_RESET_CTRL_REG 0x1F8
|
||||
#define ESC_RESET_CTRL_RST BIT(6)
|
||||
|
||||
static int lan9252 = -1;
|
||||
|
||||
/* lan9252 singel write */
|
||||
static void lan9252_write_32 (uint16_t address, uint32_t val)
|
||||
{
|
||||
uint8_t 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 */
|
||||
write (lan9252, data, sizeof(data));
|
||||
}
|
||||
|
||||
/* lan9252 single read */
|
||||
static uint32_t lan9252_read_32 (uint32_t address)
|
||||
{
|
||||
uint8_t data[2];
|
||||
uint8_t result[4];
|
||||
uint16_t lseek_addr;
|
||||
|
||||
data[0] = ((address >>8) & 0xFF);
|
||||
data[1] = (address & 0xFF);
|
||||
|
||||
lseek_addr=((uint16_t)data[0] << 8) | data[1];
|
||||
lseek (lan9252, lseek_addr, SEEK_SET);
|
||||
read (lan9252, result, sizeof(result));
|
||||
|
||||
return ((result[3] << 24) |
|
||||
(result[2] << 16) |
|
||||
(result[1] << 8) |
|
||||
result[0]);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
lan9252_write_32(ESC_CSR_CMD_REG, value);
|
||||
|
||||
do
|
||||
{
|
||||
value = lan9252_read_32(ESC_CSR_CMD_REG);
|
||||
} while(value & ESC_CSR_CMD_BUSY);
|
||||
|
||||
value = lan9252_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);
|
||||
lan9252_write_32(ESC_CSR_DATA_REG, value);
|
||||
value = (ESC_CSR_CMD_WRITE | ESC_CSR_CMD_SIZE(len) | address);
|
||||
lan9252_write_32(ESC_CSR_CMD_REG, value);
|
||||
|
||||
do
|
||||
{
|
||||
value = lan9252_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 byte_offset = 0;
|
||||
uint8_t fifo_cnt, first_byte_position, temp_len, data[2];
|
||||
uint8_t *buffer;
|
||||
int i, array_size, size;
|
||||
float quotient,remainder;
|
||||
uint32_t temp;
|
||||
|
||||
value = ESC_PRAM_CMD_ABORT;
|
||||
lan9252_write_32(ESC_PRAM_RD_CMD_REG, value);
|
||||
|
||||
do
|
||||
{
|
||||
value = lan9252_read_32(ESC_PRAM_RD_CMD_REG);
|
||||
}while(value & ESC_PRAM_CMD_BUSY);
|
||||
|
||||
value = ESC_PRAM_SIZE(len) | ESC_PRAM_ADDR(address);
|
||||
lan9252_write_32(ESC_PRAM_RD_ADDR_LEN_REG, value);
|
||||
|
||||
value = ESC_PRAM_CMD_BUSY;
|
||||
lan9252_write_32(ESC_PRAM_RD_CMD_REG, value);
|
||||
|
||||
do
|
||||
{
|
||||
value = lan9252_read_32(ESC_PRAM_RD_CMD_REG);
|
||||
}while((value & ESC_PRAM_CMD_AVAIL) == 0);
|
||||
|
||||
/* Fifo count */
|
||||
fifo_cnt = ESC_PRAM_CMD_CNT(value);
|
||||
|
||||
/* Read first value from FIFO */
|
||||
value = lan9252_read_32(ESC_PRAM_RD_FIFO_REG);
|
||||
fifo_cnt--;
|
||||
|
||||
/* Find out first byte position and adjust the copy from that
|
||||
* according to LAN9252 datasheet and MicroChip SDK code
|
||||
*/
|
||||
first_byte_position = (address & 0x03);
|
||||
temp_len = ((4 - first_byte_position) > len) ? len : (4 - first_byte_position);
|
||||
|
||||
memcpy(temp_buf ,((uint8_t *)&value + first_byte_position), temp_len);
|
||||
len -= temp_len;
|
||||
byte_offset += temp_len;
|
||||
|
||||
/* Continue reading until we have read len */
|
||||
if (len > 0){
|
||||
|
||||
quotient = len/4;
|
||||
remainder = len%4;
|
||||
|
||||
if (remainder == 0)
|
||||
array_size = quotient;
|
||||
else
|
||||
array_size = quotient+1;
|
||||
|
||||
size = 4*array_size;
|
||||
|
||||
buffer = (uint8_t *)malloc(size);
|
||||
buffer[0] = size;
|
||||
memset(buffer,0,size);
|
||||
|
||||
lseek (lan9252, ESC_PRAM_RD_FIFO_REG, SEEK_SET);
|
||||
read (lan9252, buffer, size);
|
||||
|
||||
while(len > 0)
|
||||
{
|
||||
|
||||
for (i=0; i<size; i=i+4) {
|
||||
temp_len = (len > 4) ? 4: len;
|
||||
|
||||
temp = buffer[i] | (buffer[i+1] << 8) | (buffer[i+2] << 16) | (buffer[i+3] << 24);
|
||||
memcpy(temp_buf + byte_offset ,&temp, temp_len);
|
||||
fifo_cnt--;
|
||||
len -= temp_len;
|
||||
byte_offset += temp_len;
|
||||
}
|
||||
}
|
||||
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 byte_offset = 0;
|
||||
uint8_t fifo_cnt, first_byte_position, temp_len, data[3];
|
||||
uint8_t *buffer;
|
||||
int i, array_size, size;
|
||||
float quotient,remainder;
|
||||
|
||||
value = ESC_PRAM_CMD_ABORT;
|
||||
lan9252_write_32(ESC_PRAM_WR_CMD_REG, value);
|
||||
|
||||
do
|
||||
{
|
||||
value = lan9252_read_32(ESC_PRAM_WR_CMD_REG);
|
||||
}while(value & ESC_PRAM_CMD_BUSY);
|
||||
|
||||
value = ESC_PRAM_SIZE(len) | ESC_PRAM_ADDR(address);
|
||||
lan9252_write_32(ESC_PRAM_WR_ADDR_LEN_REG, value);
|
||||
|
||||
value = ESC_PRAM_CMD_BUSY;
|
||||
lan9252_write_32(ESC_PRAM_WR_CMD_REG, value);
|
||||
|
||||
do
|
||||
{
|
||||
value = lan9252_read_32(ESC_PRAM_WR_CMD_REG);
|
||||
}while((value & ESC_PRAM_CMD_AVAIL) == 0);
|
||||
|
||||
/* Fifo count */
|
||||
fifo_cnt = ESC_PRAM_CMD_CNT(value);
|
||||
|
||||
/* Find out first byte position and adjust the copy from that
|
||||
* according to LAN9252 datasheet
|
||||
*/
|
||||
first_byte_position = (address & 0x03);
|
||||
temp_len = ((4 - first_byte_position) > len) ? len : (4 - first_byte_position);
|
||||
|
||||
memcpy(((uint8_t *)&value + first_byte_position), temp_buf, temp_len);
|
||||
|
||||
/* Write first value from FIFO */
|
||||
lan9252_write_32(ESC_PRAM_WR_FIFO_REG, value);
|
||||
|
||||
len -= temp_len;
|
||||
byte_offset += temp_len;
|
||||
fifo_cnt--;
|
||||
|
||||
if (len > 0){
|
||||
|
||||
quotient = len/4;
|
||||
remainder = len%4;
|
||||
|
||||
if (remainder == 0)
|
||||
array_size = quotient;
|
||||
else
|
||||
array_size = quotient+1;
|
||||
|
||||
size = 3+4*array_size;
|
||||
|
||||
buffer = (uint8_t *)malloc(size);
|
||||
buffer[0] = size;
|
||||
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);
|
||||
while(len > 0)
|
||||
{
|
||||
for (i=3; i<size; i=i+4) {
|
||||
temp_len = (len > 4) ? 4 : len;
|
||||
|
||||
memcpy((uint8_t *)&value, (temp_buf + byte_offset), temp_len);
|
||||
buffer[i] = (value & 0xFF);
|
||||
buffer[i+1] = ((value >> 8) & 0xFF);
|
||||
buffer[i+2] = ((value >> 16) & 0xFF);
|
||||
buffer[i+3] = ((value >> 24) & 0xFF);
|
||||
|
||||
fifo_cnt--;
|
||||
len -= temp_len;
|
||||
byte_offset += temp_len;
|
||||
}
|
||||
}
|
||||
write (lan9252, 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 void * arg)
|
||||
{
|
||||
uint32_t value;
|
||||
const char * spi_name = (char *)arg;
|
||||
lan9252 = open (spi_name, O_RDWR, 0);
|
||||
|
||||
/* Reset the ecat core here due to evb-lan9252-digio not having any GPIO
|
||||
* for that purpose.
|
||||
*/
|
||||
lan9252_write_32(ESC_RESET_CTRL_REG,ESC_RESET_CTRL_RST);
|
||||
do
|
||||
{
|
||||
value = lan9252_read_32(ESC_CSR_CMD_REG);
|
||||
} while(value & ESC_RESET_CTRL_RST);
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -8,7 +8,11 @@ extern "C"
|
|||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <machine/endian.h>
|
||||
#ifdef __linux__
|
||||
#include <endian.h>
|
||||
#else
|
||||
#include <machine/endian.h>
|
||||
#endif
|
||||
|
||||
#define CC_PACKED_BEGIN
|
||||
#define CC_PACKED_END
|
||||
|
|
Loading…
Reference in New Issue