29 #include <linux/module.h> 30 #include <linux/delay.h> 69 uint16_t ring_position,
70 uint16_t station_address
150 INIT_LIST_HEAD(&slave->
sii.
pdos);
185 list_del_init(&request->
list);
187 " slave about to be deleted.\n");
188 request->
state = EC_INT_REQUEST_FAILURE;
194 list_del_init(®->
list);
196 " slave about to be deleted.\n");
197 reg->
state = EC_INT_REQUEST_FAILURE;
203 list_del_init(&request->
list);
205 " slave about to be deleted.\n");
206 request->
state = EC_INT_REQUEST_FAILURE;
212 list_del_init(&request->
list);
214 " slave about to be deleted.\n");
215 request->
state = EC_INT_REQUEST_FAILURE;
222 list_del_init(&request->
list);
224 " slave about to be deleted.\n");
225 request->
state = EC_INT_REQUEST_FAILURE;
236 list_for_each_entry_safe(sdo, next_sdo, &slave->
sdo_dictionary, list) {
237 list_del(&sdo->
list);
253 list_for_each_entry_safe(pdo, next_pdo, &slave->
sii.
pdos, list) {
254 list_del(&pdo->
list);
296 EC_SLAVE_DBG(slave, 0,
"%s -> %s.\n", old_state, cur_state);
327 uint16_t *cat_word, cat_type, cat_size;
379 printk(KERN_CONT
"AoE");
384 printk(KERN_CONT
", ");
386 printk(KERN_CONT
"CoE");
391 printk(KERN_CONT
", ");
393 printk(KERN_CONT
"FoE");
398 printk(KERN_CONT
", ");
400 printk(KERN_CONT
"SoE");
405 printk(KERN_CONT
", ");
407 printk(KERN_CONT
"VoE");
410 printk(KERN_CONT
".\n");
413 EC_SLAVE_DBG(slave, 1,
"Slave announces to support unknown" 414 " mailbox protocols 0x%04X.",
419 EC_SLAVE_DBG(slave, 1,
"Slave announces to support no mailbox" 433 " Disabling mailbox communication.");
443 " First category header missing.\n");
454 " Category header incomplete.\n");
465 " Category data incomplete.\n");
514 EC_SLAVE_DBG(slave, 1,
"Unknown category type 0x%04X.\n",
518 cat_word += cat_size;
521 " Next category header missing.\n");
553 EC_SLAVE_ERR(slave,
"Failed to allocate string array memory.\n");
563 kmalloc(
sizeof(
char) * size + 1, GFP_KERNEL))) {
564 EC_SLAVE_ERR(slave,
"Failed to allocate string memory.\n");
568 memcpy(slave->
sii.
strings[i], data + offset + 1, size);
577 for (i--; i >= 0; i--)
602 if (data_size != 32) {
603 EC_SLAVE_ERR(slave,
"Wrong size of general category (%zu/32).\n",
613 for (i = 0; i < 4; i++)
615 (data[4] & (0x03 << (i * 2))) >> (i * 2);
650 unsigned int i, count, total_count;
658 EC_SLAVE_ERR(slave,
"Invalid SII sync manager category size %zu.\n",
663 count = data_size / 8;
669 " sync managers!\n");
672 memsize =
sizeof(
ec_sync_t) * total_count;
673 if (!(syncs = kmalloc(memsize, GFP_KERNEL))) {
675 " for sync managers.\n", memsize);
683 for (i = 0; i < count; i++, data += 8) {
685 sync = &syncs[index];
720 unsigned int entry_count, i;
722 while (data_size >= 8) {
723 if (!(pdo = kmalloc(
sizeof(
ec_pdo_t), GFP_KERNEL))) {
724 EC_SLAVE_ERR(slave,
"Failed to allocate PDO memory.\n");
744 for (i = 0; i < entry_count; i++) {
746 EC_SLAVE_ERR(slave,
"Failed to allocate PDO entry memory.\n");
772 EC_SLAVE_ERR(slave,
"Invalid SM index %i for PDO 0x%04X.",
802 EC_SLAVE_DBG(slave, 1,
"String %u not found.\n", index);
820 if (sync_index < slave->sii.sync_count) {
821 return &slave->
sii.
syncs[sync_index];
834 unsigned int *sdo_count,
835 unsigned int *entry_count
839 unsigned int sdos = 0, entries = 0;
845 list_for_each_entry(entry, &sdo->
entries, list) {
851 *entry_count = entries;
869 if (sdo->
index != index)
895 if (sdo->
index != index)
911 uint16_t sdo_position
988 list_for_each_entry(pdo_entry, &pdo->
entries, list) {
1016 list_for_each_entry(pdo, &sync->
pdos.
list, list) {
1030 unsigned int port_index
1038 EC_SLAVE_WARN(slave,
"%s(port_index=%u): Invalid port index!\n",
1039 __func__, port_index);
1043 port_index = prev_table[port_index];
1047 }
while (port_index);
1060 unsigned int port_index
1068 EC_SLAVE_WARN(slave,
"%s(port_index=%u): Invalid port index!\n",
1069 __func__, port_index);
1073 port_index = next_table[port_index];
1077 }
while (port_index);
1092 uint32_t rtt_sum = 0, rtt;
1095 while (port_index != 0) {
1096 unsigned int prev_index =
1118 unsigned int port_index;
1126 while (port_index != 0) {
1151 unsigned int port_index;
1153 uint32_t rtt, next_rtt_sum;
1160 while (port_index != 0) {
1165 unsigned int prev_port =
1173 (rtt - next_rtt_sum) / 2;
1175 (rtt - next_rtt_sum) / 2;
1179 " next_rtt_sum=%u delay=%u\n",
1201 EC_SLAVE_DBG(slave, 1,
"%s(delay = %u ns)\n", __func__, *delay);
ec_sii_general_flags_t general_flags
General flags.
Slave information interface general flags.
ec_internal_request_state_t state
Request state.
uint16_t ring_position
Ring position.
uint32_t revision_number
Revision number.
const ec_sdo_entry_t * ec_sdo_get_entry_const(const ec_sdo_t *sdo, uint8_t subindex)
Get an SDO entry from an SDO via its subindex.
uint16_t ec_slave_sdo_count(const ec_slave_t *slave)
Get the number of SDOs in the dictionary.
uint16_t boot_rx_mailbox_offset
Bootstrap rx mailbox address.
int ec_slave_analyze_sii_data(ec_slave_t *slave)
Analyzes SII data.
void ec_fsm_slave_clear(ec_fsm_slave_t *fsm)
Destructor.
ec_sii_t sii
Extracted SII data.
size_t word_count
Size of the SII contents in words.
uint16_t configured_tx_mailbox_size
Configured send mailbox size.
uint8_t enable_upload_at_startup
?.
void ec_slave_attach_pdo_names(ec_slave_t *slave)
Attach PDO names.
uint16_t base_build
Build number.
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
const ec_pdo_t * ec_pdo_list_find_pdo_const(const ec_pdo_list_t *pl, uint16_t index)
Finds a PDO with the given index and returns a const pointer.
uint8_t enable_not_lrw
Slave does not support LRW.
uint16_t configured_tx_mailbox_offset
Configured send mailbox offset.
size_t ec_state_string(uint8_t, char *, uint8_t)
Prints slave states in clear text.
ec_slave_port_t ports[EC_MAX_PORTS]
Ports.
#define EC_SII_WORD_OFFSET_ALIAS
Word offset of alias address.
ec_slave_state_t current_state
Current application state.
const ec_code_msg_t al_status_messages[]
Application layer status messages.
EtherCAT slave structure.
ec_internal_request_state_t state
SDO request state.
ec_sdo_t * ec_slave_get_sdo(ec_slave_t *slave, uint16_t index)
Get an SDO from the dictionary.
ec_slave_port_link_t link
Port link status.
Servo-Profile over EtherCAT.
#define EC_SLAVE_WARN(slave, fmt, args...)
Convenience macro for printing slave-specific warnings to syslog.
uint8_t enable_sdo
Enable SDO access.
struct list_head list
List of PDOs.
uint32_t serial_number
Serial number.
ec_sii_coe_details_t coe_details
CoE detail flags.
char * order
Order number.
int ec_pdo_set_name(ec_pdo_t *pdo, const char *name)
Set PDO name.
void ec_slave_find_names_for_pdo(ec_slave_t *, ec_pdo_t *)
Find name for a PDO and its entries.
ec_fsm_slave_t fsm
Slave state machine.
void ec_slave_set_state(ec_slave_t *slave, ec_slave_state_t new_state)
Sets the application state of a slave.
struct list_head reg_requests
Register access requests.
struct list_head list
List item.
void ec_pdo_init(ec_pdo_t *pdo)
PDO constructor.
const ec_pdo_t * ec_slave_find_pdo(const ec_slave_t *slave, uint16_t index)
Finds a mapped PDO.
int16_t current_on_ebus
Power consumption in mA.
ec_slave_t * ec_slave_find_next_dc_slave(ec_slave_t *)
Finds the next slave supporting DC delay measurement.
uint16_t boot_tx_mailbox_size
Bootstrap transmit mailbox size.
uint8_t signal_detected
Detected signal on RX port.
int ec_slave_fetch_sii_strings(ec_slave_t *, const uint8_t *, size_t)
Fetches data from a STRING category.
uint16_t alias
Configured station alias.
wait_queue_head_t request_queue
Wait queue for external requests from user space.
uint16_t station_address
Configured station address.
unsigned int sync_count
Number of sync managers.
void ec_slave_clear(ec_slave_t *slave)
Slave destructor.
struct list_head sdo_dictionary
SDO dictionary list.
uint16_t std_rx_mailbox_size
Standard receive mailbox size.
uint8_t base_type
Slave type.
Global definitions and macros.
uint16_t std_tx_mailbox_offset
Standard transmit mailbox address.
EtherCAT master structure.
void ec_pdo_clear(ec_pdo_t *pdo)
PDO destructor.
int8_t sync_index
Assigned sync manager.
uint16_t boot_tx_mailbox_offset
Bootstrap tx mailbox address.
uint16_t index
PDO entry index.
void ec_slave_sdo_dict_info(const ec_slave_t *slave, unsigned int *sdo_count, unsigned int *entry_count)
Counts the total number of SDOs and entries in the dictionary.
uint8_t loop_closed
Loop closed.
struct list_head sdo_requests
SDO access requests.
char * description
Description.
struct list_head soe_requests
SoE requests.
Slave information interface CANopen over EtherCAT details flags.
ec_slave_config_t * config
Current configuration.
unsigned int ec_slave_get_next_port(const ec_slave_t *, unsigned int)
Returns the next connected port of a given port.
char * ec_slave_sii_string(const ec_slave_t *, unsigned int)
Searches the string list for an index.
void ec_pdo_entry_clear(ec_pdo_entry_t *entry)
PDO entry destructor.
void ec_slave_clear_sync_managers(ec_slave_t *slave)
Clear the sync manager array.
uint32_t revision_number
Revision number.
uint8_t enable_sdo_info
SDO information service available.
uint8_t enable_sdo_complete_access
Complete access possible.
void ec_slave_calc_port_delays(ec_slave_t *slave)
Calculates the port transmission delays.
uint8_t sdo_dictionary_fetched
Dictionary has been fetched.
uint16_t mailbox_protocols
Supported mailbox protocols.
unsigned int debug_level
Master debug level.
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
int ec_pdo_list_add_pdo_copy(ec_pdo_list_t *pl, const ec_pdo_t *pdo)
Add the copy of an existing PDO to the list.
ec_slave_dc_range_t base_dc_range
DC range.
uint8_t bit_length
entry length in bit
uint16_t std_rx_mailbox_offset
Standard receive mailbox address.
uint8_t base_fmmu_bit_operation
FMMU bit operation is supported.
struct list_head list
List item.
uint32_t transmission_delay
DC system time transmission delay (offset from reference clock).
ec_device_index_t
Master devices.
uint16_t alias
Configured station alias.
ec_direction_t
Direction type for PDO assignment functions.
uint8_t base_fmmu_count
Number of supported FMMUs.
void ec_slave_calc_transmission_delays_rec(ec_slave_t *slave, uint32_t *delay)
Recursively calculates transmission delays.
uint16_t configured_rx_mailbox_offset
Configured receive mailbox offset.
File-Access over EtherCAT.
#define EC_READ_U32(DATA)
Read a 32-bit unsigned value from EtherCAT data.
struct list_head entries
List of PDO entries.
ec_slave_port_desc_t desc
Port descriptors.
unsigned int string_count
Number of SII strings.
ec_master_t * master
Master owning the slave.
void ec_pdo_entry_init(ec_pdo_entry_t *entry)
PDO entry constructor.
#define EC_SII_WORD_OFFSET_VENDOR
Word offset of vendor ID.
const ec_sdo_t * ec_slave_get_sdo_by_pos_const(const ec_slave_t *slave, uint16_t sdo_position)
Get an SDO from the dictionary, given its position in the list.
uint8_t has_dc_system_time
The slave supports the DC system time register.
char ** strings
Strings in SII categories.
ec_slave_state_t
State of an EtherCAT slave.
uint32_t vendor_id
Vendor ID.
uint8_t subindex
PDO entry subindex.
EtherCAT datagram structure.
uint8_t control_register
Control register value.
Values read by the master.
void ec_sync_clear(ec_sync_t *sync)
Destructor.
#define EC_FIRST_SII_CATEGORY_OFFSET
Word offset of first SII category.
uint8_t base_revision
Revision.
Ethernet-over-EtherCAT set IP parameter request.
const ec_sdo_t * ec_slave_get_sdo_const(const ec_slave_t *slave, uint16_t index)
Get an SDO from the dictionary.
uint16_t effective_alias
Effective alias address.
void ec_sii_page_clear(ec_sii_page_t *page)
Slave destructor.
struct list_head entries
List of entries.
ec_internal_request_state_t state
Request state.
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
struct list_head foe_requests
FoE requests.
uint8_t enable
Enable bit.
int ec_slave_fetch_sii_syncs(ec_slave_t *, const uint8_t *, size_t)
Fetches data from a SYNC MANAGER category.
#define EC_STATE_STRING_SIZE
Minimum size of a buffer used with ec_state_string().
uint16_t boot_rx_mailbox_size
Bootstrap receive mailbox size.
#define EC_MAX_PORTS
Maximum number of slave ports.
uint16_t * words
Complete SII image.
struct list_head list
List item.
void ec_fsm_slave_init(ec_fsm_slave_t *fsm, ec_slave_t *slave)
Constructor.
uint32_t product_code
Vendor-specific product code.
void ec_slave_init(ec_slave_t *slave, ec_master_t *master, ec_device_index_t dev_idx, uint16_t ring_position, uint16_t station_address)
Slave constructor.
ec_slave_t * next_slave
Connected slaves.
ec_sii_page_t sii_page
The SII contents, either fetched or taken from the cache.
uint32_t receive_time
Port receive times for delay measurement.
uint32_t ec_slave_calc_rtt_sum(const ec_slave_t *)
Calculates the sum of round-trip-times of connected ports 1-3.
ec_pdo_list_t pdos
Current PDO assignment.
void ec_slave_request_state(ec_slave_t *slave, ec_slave_state_t state)
Request a slave state and resets the error flag.
uint16_t physical_start_address
Physical start address.
unsigned long jiffies_preop
Time, the slave went to PREOP.
void ec_sii_page_init(ec_sii_page_t *page)
SII page constructor.
uint16_t configured_rx_mailbox_size
Configured receive mailbox size.
uint8_t base_dc_supported
Distributed clocks are supported.
void ec_sync_init_copy(ec_sync_t *sync, const ec_sync_t *other)
Copy constructor.
uint8_t physical_layer[EC_MAX_PORTS]
Port media.
struct list_head list
list item
void ec_sdo_clear(ec_sdo_t *sdo)
SDO destructor.
uint8_t base_sync_count
Number of supported sync managers.
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
EtherCAT slave configuration structure.
ec_internal_request_state_t state
FoE request state.
#define EC_READ_S16(DATA)
Read a 16-bit signed value from EtherCAT data.
ec_device_index_t device_index
Index of device the slave responds on.
void ec_slave_config_detach(ec_slave_config_t *sc)
Detaches the configuration from a slave object.
unsigned int ec_slave_get_previous_port(const ec_slave_t *, unsigned int)
Returns the previous connected port of a given port.
uint16_t default_length
Data length in bytes.
uint32_t product_code
Vendor-specific product code.
PREOP state (mailbox communication, no IO)
Values written by the master.
uint32_t serial_number
Serial number.
struct list_head list
List item.
unsigned int error_flag
Stop processing after an error.
ec_sync_t * syncs
SYNC MANAGER categories.
uint16_t std_tx_mailbox_size
Standard transmit mailbox size.
uint8_t enable_pdo_configuration
PDO configuration possible.
struct list_head list
List item.
ec_slave_state_t requested_state
Requested application state.
struct list_head eoe_requests
EoE set IP parameter requests.
uint8_t link_up
Link detected.
int ec_slave_fetch_sii_pdos(ec_slave_t *, const uint8_t *, size_t, ec_direction_t)
Fetches data from a [RT]xPDO category.
#define EC_MAX_SYNC_MANAGERS
Maximum number of sync managers per slave.
ec_internal_request_state_t state
Request state.
void ec_sync_init(ec_sync_t *sync, ec_slave_t *slave)
Constructor.
struct list_head list
List item.
int ec_slave_fetch_sii_general(ec_slave_t *, const uint8_t *, size_t)
Fetches data from a GENERAL category.
Sercos-over-EtherCAT request.
int ec_pdo_entry_set_name(ec_pdo_entry_t *entry, const char *name)
Set PDO entry name.
uint32_t vendor_id
Vendor ID.
uint32_t delay_to_next_dc
Delay to next slave with DC support behind this port [ns].
struct list_head pdos
SII [RT]XPDO categories.
unsigned int force_config
Force (re-)configuration.
struct list_head list
List item.
unsigned int has_general
General category present.
ec_sync_t * ec_slave_get_sync(ec_slave_t *slave, uint8_t sync_index)
Get the sync manager given an index.
uint8_t enable_pdo_assign
PDO mapping configurable.
unsigned int sii_parallel_words
How many SII words the slave can read at once.