mirror of
https://github.com/OpenEtherCATsociety/SOEM.git
synced 2026-10-02 12:24:03 +08:00
Add basic ENI support
Change-Id: I6abcb3b4a1248acadbbe2ed93fcd901304320d02
This commit is contained in:
committed by
Hans-Erik Floryd
parent
08064ae3fa
commit
2eec21727e
+19
@@ -0,0 +1,19 @@
|
||||
/** \file
|
||||
|
||||
\section eni Basic ENI support
|
||||
|
||||
With the supplied Python script "eniconv.py", it is possible to extract the CoE
|
||||
initialization commands from an ENI file, and make them available to SOEM, as a
|
||||
C file that can be compiled and linked together with the SOEM application.
|
||||
The generated C file defines the (extern) variable "ec_eni", which can be used
|
||||
to initializethe "ENI" field of the appropriate "ecx_contextt" instance, before
|
||||
calling the "ec_config_map" function (or equivalent, depending on the
|
||||
application).
|
||||
|
||||
Currently, the main goal of this is to support PDO mapping and assignment.
|
||||
This means that some information that is mandatory in an ENI file is simply
|
||||
ignored by the conversion program. The included "sample-eni.xml" minimal ENI
|
||||
file example has been provided, together with the generated "sample-eni.c" file,
|
||||
for a quick review of what gets extracted, and how it ends up as C data.
|
||||
|
||||
*/
|
||||
@@ -0,0 +1,101 @@
|
||||
#include "osal.h"
|
||||
#include "oshw.h"
|
||||
#include "ethercattype.h"
|
||||
#include "ethercatmain.h"
|
||||
|
||||
static uint8 s1_coeData[6] = {
|
||||
0,
|
||||
2, 26,
|
||||
5, 26,
|
||||
2
|
||||
};
|
||||
|
||||
static ec_enicoecmdt s1_coeCmds[4] = {
|
||||
{
|
||||
// Clear SM3 PDO count
|
||||
.Transition = ECT_ESMTRANS_PS,
|
||||
.CA = FALSE,
|
||||
.Ccs = 2,
|
||||
.Index = 0x1C13,
|
||||
.SubIdx = 0,
|
||||
.Timeout = 3000,
|
||||
.DataSize = 1,
|
||||
.Data = (s1_coeData + 0)
|
||||
},
|
||||
{
|
||||
// SM3 RxPDO #1: 0x1A02
|
||||
.Transition = ECT_ESMTRANS_PS,
|
||||
.CA = FALSE,
|
||||
.Ccs = 2,
|
||||
.Index = 0x1C13,
|
||||
.SubIdx = 1,
|
||||
.Timeout = 3000,
|
||||
.DataSize = 2,
|
||||
.Data = (s1_coeData + 1)
|
||||
},
|
||||
{
|
||||
// SM3 RxPDO #2: 0x1A05
|
||||
.Transition = ECT_ESMTRANS_PS,
|
||||
.CA = FALSE,
|
||||
.Ccs = 2,
|
||||
.Index = 0x1C13,
|
||||
.SubIdx = 2,
|
||||
.Timeout = 3000,
|
||||
.DataSize = 2,
|
||||
.Data = (s1_coeData + 3)
|
||||
},
|
||||
{
|
||||
// Set SM3 PDO count
|
||||
.Transition = ECT_ESMTRANS_PS,
|
||||
.CA = FALSE,
|
||||
.Ccs = 2,
|
||||
.Index = 0x1C13,
|
||||
.SubIdx = 0,
|
||||
.Timeout = 3000,
|
||||
.DataSize = 1,
|
||||
.Data = (s1_coeData + 5)
|
||||
}
|
||||
};
|
||||
|
||||
static uint8 s2_coeData[8] = {
|
||||
3, 0, 1, 22, 7, 22, 28, 22
|
||||
};
|
||||
|
||||
static ec_enicoecmdt s2_coeCmds[1] = {
|
||||
{
|
||||
// SM2 PDO assignment, using CA
|
||||
.Transition = ECT_ESMTRANS_PS,
|
||||
.CA = TRUE,
|
||||
.Ccs = 2,
|
||||
.Index = 0x1C12,
|
||||
.SubIdx = 0,
|
||||
.Timeout = 3000,
|
||||
.DataSize = 8,
|
||||
.Data = (s2_coeData + 0)
|
||||
}
|
||||
};
|
||||
|
||||
static ec_enislavet eniSlave[2] = {
|
||||
{
|
||||
.Slave = 1,
|
||||
.VendorId = 1,
|
||||
.ProductCode = 4660,
|
||||
.RevisionNo = 0,
|
||||
.CoECmds = s1_coeCmds,
|
||||
.CoECmdCount = 4
|
||||
},
|
||||
{
|
||||
.Slave = 2,
|
||||
.VendorId = 1,
|
||||
.ProductCode = 16799146,
|
||||
.RevisionNo = 0,
|
||||
.CoECmds = s2_coeCmds,
|
||||
.CoECmdCount = 1
|
||||
}
|
||||
};
|
||||
|
||||
ec_enit ec_eni = {
|
||||
.slave = eniSlave,
|
||||
.slavecount = 2
|
||||
};
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
<?xml version="1.0"?>
|
||||
<EtherCATConfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="EtherCATConfig.xsd" Version="1.3">
|
||||
<Config>
|
||||
<Master>
|
||||
<Info>
|
||||
<Name><![CDATA[SOEM sample master]]></Name>
|
||||
<Destination>ffffffffffff</Destination>
|
||||
<Source>010101010101</Source>
|
||||
</Info>
|
||||
</Master>
|
||||
<Slave>
|
||||
<Info>
|
||||
<Name><![CDATA[Sample device A]]></Name>
|
||||
<VendorId>1</VendorId>
|
||||
<ProductCode>0x1234</ProductCode>
|
||||
<RevisionNo>0</RevisionNo>
|
||||
<SerialNo>0</SerialNo>
|
||||
</Info>
|
||||
<Mailbox>
|
||||
<Send>
|
||||
<Start>0x1000</Start>
|
||||
<Length>128</Length>
|
||||
</Send>
|
||||
<Receive>
|
||||
<Start>0x1100</Start>
|
||||
<Length>128</Length>
|
||||
<PollTime>5</PollTime>
|
||||
</Receive>
|
||||
<Protocol>CoE</Protocol>
|
||||
<CoE>
|
||||
<InitCmds>
|
||||
<InitCmd>
|
||||
<Comment><![CDATA[Clear SM3 PDO count]]></Comment>
|
||||
<Transition>PS</Transition>
|
||||
<Timeout>3</Timeout>
|
||||
<Ccs>2</Ccs>
|
||||
<Index>0x1c13</Index>
|
||||
<SubIndex>0</SubIndex>
|
||||
<Data>00</Data>
|
||||
</InitCmd>
|
||||
<InitCmd>
|
||||
<Comment><![CDATA[SM3 RxPDO #1: 0x1A02]]></Comment>
|
||||
<Transition>PS</Transition>
|
||||
<Timeout>3</Timeout>
|
||||
<Ccs>2</Ccs>
|
||||
<Index>0x1c13</Index>
|
||||
<SubIndex>1</SubIndex>
|
||||
<Data>021a</Data>
|
||||
</InitCmd>
|
||||
<InitCmd>
|
||||
<Comment><![CDATA[SM3 RxPDO #2: 0x1A05]]></Comment>
|
||||
<Transition>PS</Transition>
|
||||
<Timeout>3</Timeout>
|
||||
<Ccs>2</Ccs>
|
||||
<Index>0x1c13</Index>
|
||||
<SubIndex>2</SubIndex>
|
||||
<Data>051a</Data>
|
||||
</InitCmd>
|
||||
<InitCmd>
|
||||
<Comment><![CDATA[Set SM3 PDO count]]></Comment>
|
||||
<Transition>PS</Transition>
|
||||
<Timeout>3</Timeout>
|
||||
<Ccs>2</Ccs>
|
||||
<Index>0x1c13</Index>
|
||||
<SubIndex>0</SubIndex>
|
||||
<Data>02</Data>
|
||||
</InitCmd>
|
||||
</InitCmds>
|
||||
</CoE>
|
||||
</Mailbox>
|
||||
</Slave>
|
||||
<Slave>
|
||||
<Info>
|
||||
<Name><![CDATA[Sample device B]]></Name>
|
||||
<VendorId>1</VendorId>
|
||||
<ProductCode>0x10055aa</ProductCode>
|
||||
<RevisionNo>0</RevisionNo>
|
||||
<SerialNo>0</SerialNo>
|
||||
</Info>
|
||||
<Mailbox>
|
||||
<Send>
|
||||
<Start>0x1000</Start>
|
||||
<Length>256</Length>
|
||||
</Send>
|
||||
<Receive>
|
||||
<Start>0x1200</Start>
|
||||
<Length>256</Length>
|
||||
<PollTime>5</PollTime>
|
||||
</Receive>
|
||||
<Protocol>CoE</Protocol>
|
||||
<CoE>
|
||||
<InitCmds>
|
||||
<InitCmd CompleteAccess="1">
|
||||
<Comment><![CDATA[SM2 PDO assignment, using CA]]></Comment>
|
||||
<Transition>PS</Transition>
|
||||
<Timeout>3</Timeout>
|
||||
<Ccs>2</Ccs>
|
||||
<Index>0x1c12</Index>
|
||||
<SubIndex>0</SubIndex>
|
||||
<Data>0300011607161c16</Data>
|
||||
</InitCmd>
|
||||
</InitCmds>
|
||||
</CoE>
|
||||
</Mailbox>
|
||||
</Slave>
|
||||
</Config>
|
||||
</EtherCATConfig>
|
||||
@@ -339,6 +339,60 @@ typedef struct ec_group
|
||||
ec_mbxqueuet mbxtxqueue;
|
||||
} ec_groupt;
|
||||
|
||||
#define ECT_ESMTRANS_IP 0x0001
|
||||
#define ECT_ESMTRANS_PS 0x0002
|
||||
#define ECT_ESMTRANS_PI 0x0004
|
||||
#define ECT_ESMTRANS_SP 0x0008
|
||||
#define ECT_ESMTRANS_SO 0x0010
|
||||
#define ECT_ESMTRANS_SI 0x0020
|
||||
#define ECT_ESMTRANS_OS 0x0040
|
||||
#define ECT_ESMTRANS_OP 0x0080
|
||||
#define ECT_ESMTRANS_OI 0x0100
|
||||
#define ECT_ESMTRANS_IB 0x0200
|
||||
#define ECT_ESMTRANS_BI 0x0400
|
||||
#define ECT_ESMTRANS_II 0x0800
|
||||
#define ECT_ESMTRANS_PP 0x1000
|
||||
#define ECT_ESMTRANS_SS 0x2000
|
||||
|
||||
/** ENI CoE command structure */
|
||||
typedef struct ec_enicoecmd
|
||||
{
|
||||
/** transition(s) during which command should be sent */
|
||||
uint16 Transition;
|
||||
/** complete access flag */
|
||||
boolean CA;
|
||||
/** ccs (1 = read, 2 = write) */
|
||||
uint8 Ccs;
|
||||
/** object index */
|
||||
uint16 Index;
|
||||
/** object subindex */
|
||||
uint8 SubIdx;
|
||||
/** timeout in us */
|
||||
int Timeout;
|
||||
/** size in bytes of parameter buffer */
|
||||
int DataSize;
|
||||
/** pointer to parameter buffer */
|
||||
void *Data;
|
||||
} ec_enicoecmdt;
|
||||
|
||||
/** ENI slave structure */
|
||||
typedef struct ec_enislave
|
||||
{
|
||||
uint16 Slave;
|
||||
uint32 VendorId;
|
||||
uint32 ProductCode;
|
||||
uint32 RevisionNo;
|
||||
ec_enicoecmdt *CoECmds;
|
||||
int CoECmdCount;
|
||||
} ec_enislavet;
|
||||
|
||||
/** ENI structure */
|
||||
typedef struct ec_eni
|
||||
{
|
||||
ec_enislavet *slave;
|
||||
int slavecount;
|
||||
} ec_enit;
|
||||
|
||||
/** SII FMMU structure */
|
||||
typedef struct ec_eepromFMMU
|
||||
{
|
||||
@@ -487,6 +541,8 @@ struct ecx_context
|
||||
ec_eepromFMMUt *eepFMMU;
|
||||
/** internal, mailbox pool */
|
||||
ec_mbxpoolt *mbxpool;
|
||||
/** network information hook */
|
||||
ec_enit *ENI;
|
||||
/** registered FoE hook */
|
||||
int (*FOEhook)(uint16 slave, int packetnumber, int datasize);
|
||||
/** registered EoE hook */
|
||||
@@ -522,6 +578,7 @@ int ecx_mbxhandler(ecx_contextt *context, uint8 group, int limit);
|
||||
int ecx_mbxempty(ecx_contextt *context, uint16 slave, int timeout);
|
||||
int ecx_mbxsend(ecx_contextt *context, uint16 slave, ec_mbxbuft *mbx, int timeout);
|
||||
int ecx_mbxreceive(ecx_contextt *context, uint16 slave, ec_mbxbuft **mbx, int timeout);
|
||||
int ecx_mbxENIinitcmds(ecx_contextt *context, uint16 slave, uint16_t transition);
|
||||
void ecx_esidump(ecx_contextt *context, uint16 slave, uint8 *esibuf);
|
||||
uint32 ecx_readeeprom(ecx_contextt *context, uint16 slave, uint16 eeproma, int timeout);
|
||||
int ecx_writeeeprom(ecx_contextt *context, uint16 slave, uint16 eeproma, uint16 data, int timeout);
|
||||
|
||||
Executable
+231
File diff suppressed because it is too large
Load Diff
@@ -525,6 +525,10 @@ static int ecx_map_coe_soe(ecx_contextt *context, uint16 slave, int thread_n)
|
||||
EC_PRINT(" >Slave %d, configadr %x, state %2.2x\n",
|
||||
slave, context->slavelist[slave].configadr, context->slavelist[slave].state);
|
||||
|
||||
if (context->ENI)
|
||||
{
|
||||
(void)ecx_mbxENIinitcmds(context, slave, ECT_ESMTRANS_PS);
|
||||
}
|
||||
/* execute slave configuration hook Pre-Op to Safe-OP */
|
||||
if (context->slavelist[slave].PO2SOconfig) /* only if registered */
|
||||
{
|
||||
@@ -1642,6 +1646,10 @@ int ecx_reconfig_slave(ecx_contextt *context, uint16 slave, int timeout)
|
||||
state = ecx_statecheck(context, slave, EC_STATE_PRE_OP, EC_TIMEOUTSTATE); /* check state change pre-op */
|
||||
if (state == EC_STATE_PRE_OP)
|
||||
{
|
||||
if (context->ENI)
|
||||
{
|
||||
(void)ecx_mbxENIinitcmds(context, slave, ECT_ESMTRANS_PS);
|
||||
}
|
||||
/* execute slave configuration hook Pre-Op to Safe-OP */
|
||||
if (context->slavelist[slave].PO2SOconfig) /* only if registered */
|
||||
{
|
||||
|
||||
@@ -1644,6 +1644,73 @@ int ecx_mbxreceive(ecx_contextt *context, uint16 slave, ec_mbxbuft **mbx, int ti
|
||||
return wkc;
|
||||
}
|
||||
|
||||
/** Send ENI mailbox protocol initcmds to a slave for a given transition.
|
||||
* Currently, only CoE commands are supported.
|
||||
* @param[in] context = context struct
|
||||
* @param[in] slave = Slave number
|
||||
* @param[in] transition = transition (ECT_ESMTRANS_*) for which to send commands
|
||||
* @return 1 on success, 0 on failure
|
||||
*/
|
||||
int ecx_mbxENIinitcmds(ecx_contextt *context, uint16 slave, uint16_t transition)
|
||||
{
|
||||
int slavecount = (context->ENI ? context->ENI->slavecount : 0);
|
||||
|
||||
if (slavecount > 0)
|
||||
{
|
||||
int i;
|
||||
ec_enislavet *eni_slave = context->ENI->slave;
|
||||
|
||||
for (i = 0; i < (slavecount - 1); ++i, ++eni_slave)
|
||||
{
|
||||
if (slave <= eni_slave->Slave)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (slave == eni_slave->Slave)
|
||||
{
|
||||
if ((eni_slave->VendorId == context->slavelist[slave].eep_man) &&
|
||||
(eni_slave->ProductCode == context->slavelist[slave].eep_id) &&
|
||||
(eni_slave->RevisionNo == context->slavelist[slave].eep_rev))
|
||||
{
|
||||
int wkc;
|
||||
|
||||
if (context->slavelist[slave].mbx_proto & ECT_MBXPROT_COE)
|
||||
{
|
||||
ec_enicoecmdt *cmd = eni_slave->CoECmds;
|
||||
for (i = 0; i < eni_slave->CoECmdCount; ++i, ++cmd)
|
||||
{
|
||||
if (cmd->Transition & transition)
|
||||
{
|
||||
if (cmd->Ccs == 2)
|
||||
{
|
||||
wkc = ecx_SDOwrite(context, slave, cmd->Index, cmd->SubIdx,
|
||||
cmd->CA, cmd->DataSize, cmd->Data, cmd->Timeout);
|
||||
if (wkc < 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (cmd->Ccs == 1)
|
||||
{
|
||||
int size = cmd->DataSize;
|
||||
|
||||
wkc = ecx_SDOread(context, slave, cmd->Index, cmd->SubIdx,
|
||||
cmd->CA, &size, cmd->Data, cmd->Timeout);
|
||||
if (wkc < 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Dump complete EEPROM data from slave in buffer.
|
||||
* @param[in] context = context struct
|
||||
* @param[in] slave = Slave number
|
||||
|
||||
Reference in New Issue
Block a user