Generic EtherCAT Slave
This library of EtherCAT Slaves can never contain all available slaves
on the market. To enable custom slaves, this generic EtherCAT slave is
provided.
A mask configuration parameter, EtherCAT Slave Configuration,
is used to setup the slave. It is a Matlab struct.
Behind the scenes, the other preconfigured slaves use the same
SFunction as the generic slave, but with the comfort of not having to
specify a structure.
Apart from the common slave options,
the configuration structure has to be specified.
At the top level, the structure has the fields
- slave.SlaveConfig used to specify the EtherCAT setup
in a fashion similar to the EtherCATInfo slave description xml
supplied by the manufacturor.
- slave.PortConfig used to specify the Simulink block
inputs and outputs, based on SlaveConfig
In the following sections, these two fields are described.
SlaveConfig
SlaveConfig describes the slave as required by the EtherCAT Master
communication process to configure the slave in the network. This
information is available in the EtherCATInfo xml description file
supplied by the manufacturor.
SlaveConfig by itself is a structure with the fields:
- vendor: Vendor Id
- product: Product Code
- description (optional): Description string
- sm: SyncManager configuration
- sdo: CAN over EtherCAT slave specific configuration
- dc: Distributed clock setup
- soe: (OBSOLETE) Sercos configuration
slave.SlaveConfig.vendor = 2;
slave.SlaveConfig.product = hex2dec('bb93052')
slave.SlaveConfig.description = 'EL3001' % optional
SyncManager Configuration
SyncManager configuration specifies PDO's that are mapped into a
SyncManager and the Entries it contains. Once a PDO Entry is
specified, it can be assigned to a block input or output port.
The SyncManager is specified by assigning
slave.SlaveConfig.sm a cell array with as many elements as
the slave has SyncManagers that need to be configured.
The elements of the cell array are cell arrays themselves that
have three elements: {SmIndex, SmDirection, SmPDO}
where:
- SmIndex: Zero based index number of the
<Sm> xml element in the EtherCATInfo xml file
- SmDirection: SyncManager direction as seen by the
master: 0 = Output (for RxPdo); 1 = Input (for
TxPdo);
- SmPDO: Cell array of PDO's that are mapped to the
SyncManager
for example:
slave.SlaveConfig.sm = {Sm2, Sm3};
Sm2 = {2, 0, Sm2PDO} % SyncManager Index 2, Output
Sm3 = {3, 1, Sm3PDO} % SyncManager Index 3, Input
The third element of a SyncManager cell array is another cell array
with one element for every PDO that will be included in it. This array
has two elements: {PdoIndex, PdoEntries} where:
- PdoIndex: PDO index number
- PdoEntries: PDO index number
for example:
Sm3PDO = {TxPDO1, TxPDO2}
TxPDO1 = {hex2dec('1a00') Entries_1a00}
TxPDO2 = {hex2dec('1a01') Entries_1a01}
The second element of a PDO specification lists the Entries of a PDO.
This is a Nx3 numeric array with one row for every Entry. The columns
of this array specify
- Entry Index
- Entry SubIndex
- BitLen
The values are obtained directly from the EtherCATInfo xml file.
Entries_1a00 = [hex2dec('6000') 1 1;
hex2dec('6000') 2 1;
hex2dec('6000') 3 2;
hex2dec('6000') 5 2;
hex2dec('6000') 7 1;
0 0 7; % 7 space bits
hex2dec('1800') 7 1;
hex2dec('1800') 9 1;
hex2dec('1800') 17 16]
Note how a space Entry is specified with an Entry Index of 0. In this
case only the BitLen is required, the SubIndex is ignored and can have
any value.
CAN over EtherCAT configuration
CAN over EtherCAT is a protocol which is used to configure slaves. The
required configuration options are set using the synchronous data
objects cell array slave.SlaveConfig.sdo.
This cell or numeric array has 4 columns and as many rows as there
are options to be configured. The rows can be specified to configure
either a single value or the whole SDO at once.
Specify a single SDO value: This mode directly configures a
single SDO. The column elements specify:
- SDO Index
- SDO SubIndex
- Data type: 8, 16, 32, 64: uintX_t
-8, -16, -32, -64: intX_t
0.32: single
0.64: double
- Value
To specify a value array of uint8, DataType must be 0 and value
is a numeric array or a string.
- SDO Index
- SDO SubIndex
- 0
- Either a string, or an array of values interpreted as uint8
Complete SDO access: This is the same as value array above,
except that SubIndex is -1 as well:
- SDO Index
- -1
- 0
- Either a string, or an array of values interpreted as uint8
For example:
slave.SlaveConfig.sdo = { hex2dec('8000'),6,8,1;
hex2dec('8001'),0,0,'save';
hex2dec('8002'),-1,0,[64,65,66,67];
hex2dec('8003'),3,0,[64,65,66,67] };
When there are no special values (like arrays, string, compete access,
etc), the cell array can be replace by a Nx4 numeric array.
Distributed Clocks configuration
Distributed Clocks allows the slaves to be synchronized in the range
of nanoseconds. Distributed clocks is specified by assigning
slave.SlaveConfig.dc either a single value or a vector with
10 elements.
Vector specification: the elements specify:
- Assign Activate
- Cycle Time Sync0
- Cycle Time Sync0 Factor
- Shift Time Sync0
- Shift Time Sync0 Factor
- Shift Time Sync0 Input
- Cycle Time Sync1
- Cycle Time Sync1 Factor
- Shift Time Sync1
- Shift Time Sync1 Factor
A single value just sets Assign Activate.
For example:
slave.SlaveConfig.dc = hex2dec('320');
slave.SlaveConfig.dc = [hex2dec('320'), 0, 1, 0, 0, 1, 0, 0, 0, 15000];
Sercos over EtherCAT
This obsolete configuration sends Sercos messages over EtherCAT. The
required configuration options are set using the cell array
slave.SlaveConfig.soe.
This cell array has 2 columns and as many rows as there are
options to be configured:
- SDO Index
- Either a string, or an array of values interpreted as uint8
For example:
slave.SlaveConfig.soe = { hex2dec('8001'),'save';
hex2dec('8002'),[64,65,66,67] };
PortConfig
PortConfig describes the input and output ports of a block. PortConfig
is a struct with the fields input and output.
Output Port specification
slave.PortConfig.output is a structure vector with the
fields:
- pdo Nx4 array specifying which PDO entries are mapped
to the port. PDO Entries may be referenced as often as required,
on the same or on another port, even with different data types.
- pdo_data_type Data Type interpretation of the PDO Entry
(required if pdo is not empty)
- big_endian PDO Entry is in big endian format (optional)
- full_scale Used to normalize the PDO Entry to unity.
filter (optional)
- gain see below (optional)
- offset see below (optional)
- filter Time constant of a first order low pass filter.
(optional)
- portname Human-readable name of the port. Will be displayed in the block. (optional)
The number of elements of slave.SlaveConfig.output determines
how many output ports a block has. For example: the block with
slave.PortConfig.output(1).pdo = [ 0 0 0 0 ];
slave.PortConfig.output(2).pdo = [ 0 1 0 0;
0 1 1 0;
0 1 1 1 ];
will have 2 scalar output ports. Port 2 is a vector with 3 elements.
The PDO specification is a zero-based Nx4 array of index address
of a PDO Entry. The columns specify:
- SyncManager Index. This index addresses the SyncManager
element of the slave.SlaveConfig.sm cell vector.
Only input SyncManagers (element 2 of the SyncManager field is 1)
should be addressed. Addressing a SyncManager with direction
output (0) will result in a warning.
- PDO Index. This index addresses the PDO element of the third
element of the SyncManager cell vector.
- Entry Index. This index addresses the Entry row of the second
element of the PDO cell vector.
- Element Index. This index addresses the data type element of
the PDO Entry. (eg. if a Entry has BitLen=8 and it is interpreted
as a boolean, Element Index can be [0..7])
The indices are zero-based.
The port will have as many elements as pdo has rows (N).
pdo_data_type is a value that specifies which data type
to interpret the PDO Entry as. Valid values are:
Value | Data Type |
uint(1) | Boolean |
uint(2) | Bit2 |
uint(3) | Bit3 |
uint(4) | Bit4 |
uint(5) | Bit5 |
uint(6) | Bit6 |
uint(7) | Bit7 |
uint(8) | Unsigned8 |
uint(16) | Unsigned16 |
uint(24) | Unsigned24 |
uint(32) | Unsigned32 |
uint(40) | Unsigned40 |
uint(48) | Unsigned48 |
uint(56) | Unsigned56 |
uint(64) | Unsigned64 |
sint(08) | Integer8 |
sint(16) | Integer16 |
sint(32) | Integer32 |
sint(64) | Integer64 |
float('single') | Real32 |
float('double') | Real64 |
The data type must match the PDO Entry's BitLen. The remainder of
division BitLen / mantissa_bits must be zero. Specifying
a data type with fewer bits than BitLen will create a vector. For
example, if BitLen=64 and pdo_data_type=1001 (boolean), the PDO Entry
will have 64 elements. Placing all booleans on one output will have:
slave.PortConfig.output(3).pdo_data_type = 1001;
slave.PortConfig.output(3).pdo = [ 0,0,0,0;
0,0,0,1;
...
0,0,0,63 ];
Output port 3 will have 64 boolean elements;
full_scale is intended to normalize the PDO Entry value
to unity so that scaling can be performed naturally. For example,
full_scale has the value 2^15 for int16.
Gain, offset, filter and
full_scale apply the following operation:
output = filter((PDO_Entry / full_scale) * gain + offset);
Gain, offset and filter can be
spedified using either:
- vector or scalar: This creates an anonymous parameter
- struct('name', name, 'value', value): Creates a parameter
accessible during runtime for the port
- struct('parameter', idx): Uses block parameter at idx as a
vector
- struct('parameter', idx, 'element', idx): Uses the scalar
block parameter element idx
- cell array {'name', value}: Alternative to the second
option
Parameters can either be a scalar or a vector, where the vector
size must match the port width.
Specifying any of gain, offset, full_scale or filter causes the
output's data type to be set to double.
gain, offset, full_scale or filter may assigned a 2 element cell
array {'NameString', ValueArray}. The variable will be
available as a parameter, allowing values to be changed at run-time.
Not specifying any of gain, offset, full_scale or filter will set
the data type to the PDO Entries raw data type, possibly promoting the
value to the next superiour type. Unsigned64 and Integer64 are
represented as Real64 because they are not available in Simulink
Coder.
Input Port specification
This is very similar to Output Port specification with the following
exceptions:
- There is no filter
- Input port signals may have fewer elements as there are rows
in pdo
The signal's data type must either match pdo_data_type or be
Real64.
Gain, offset and full_scale apply the
following operation:
PDO_Entry = (input * gain + offset) * full_scale;
Block Parameter Config
This is a very difficult feature to use. It creates a block parameter
that can be accessed from any port as a parameter during runtime when
specifying PortConfig's gain, offset and filter options when specified
using struct('parameter', idx, 'element', idx) in PortConfig.
The parameter specification is a name value map as a list of
structs using struct('name', ..., 'value, ...).
A much more complex specification references model wide parameters
from the "Model Workspace". The difficulty lies in the way it is
specified. You need to edit the generic slave (option "Look under
mask") and append the "Model Workspace" names after the sixth
"S-Function parameters". They are then referenced using:
struct('name', ..., 'mask_index', 6+x)
For further instructions see the mex file itself or examples from
the installation ;)