37 #include <linux/module.h> 38 #include <linux/delay.h> 66 uint16_t ring_position,
67 uint16_t station_address
115 #ifdef EC_LOOP_CONTROL 116 slave->
ports[i].state = EC_SLAVE_PORT_DOWN;
117 slave->
ports[i].link_detection_jiffies = 0;
172 sii_image->words = NULL;
204 INIT_LIST_HEAD(&sii_image->
sii.
pdos);
259 list_del_init(&request->
list);
261 " slave about to be deleted.\n");
262 request->
state = EC_INT_REQUEST_FAILURE;
268 list_del_init(®->
list);
270 " slave about to be deleted.\n");
271 reg->
state = EC_INT_REQUEST_FAILURE;
277 list_del_init(&request->
list);
279 " slave about to be deleted.\n");
280 request->
state = EC_INT_REQUEST_FAILURE;
286 list_del_init(&request->
list);
288 " slave about to be deleted.\n");
289 request->
state = EC_INT_REQUEST_FAILURE;
295 list_del_init(&request->
list);
297 " slave about to be deleted.\n");
298 request->
state = EC_INT_REQUEST_FAILURE;
304 list_del_init(&request->
list);
306 " slave about to be deleted.\n");
307 request->
state = EC_INT_REQUEST_FAILURE;
313 list_del_init(&request->
list);
315 " slave about to be deleted.\n");
316 request->
state = EC_INT_REQUEST_FAILURE;
326 list_for_each_entry_safe(sdo, next_sdo, &slave->
sdo_dictionary, list) {
327 list_del(&sdo->
list);
383 state = new_state & (1 << (4 + i)) ? 1 : 0;
385 EC_SLAVE_DBG(slave, 1,
"Port %u link status changed to %s.\n",
386 i, state ?
"up" :
"down");
391 state = new_state & (1 << (8 + i * 2)) ? 1 : 0;
393 EC_SLAVE_DBG(slave, 1,
"Port %u loop status changed to %s.\n",
394 i, state ?
"closed" :
"open");
399 state = new_state & (1 << (9 + i * 2)) ? 1 : 0;
401 EC_SLAVE_DBG(slave, 1,
"Port %u signal status changed to %s.\n",
402 i, state ?
"yes" :
"no");
424 EC_SLAVE_DBG(slave, 0,
"%s -> %s.\n", old_state, cur_state);
485 EC_SLAVE_ERR(slave,
"Failed to allocate string array memory.\n");
495 kmalloc(
sizeof(
char) * size + 1, GFP_KERNEL))) {
496 EC_SLAVE_ERR(slave,
"Failed to allocate string memory.\n");
509 for (i--; i >= 0; i--)
534 if (data_size != 32) {
535 EC_SLAVE_ERR(slave,
"Wrong size of general category (%zu/32).\n",
550 for (i = 0; i < 4; i++)
552 (data[4] & (0x03 << (i * 2))) >> (i * 2);
587 unsigned int i, count, total_count;
595 EC_SLAVE_ERR(slave,
"Invalid SII sync manager category size %zu.\n",
605 count = data_size / 8;
611 " sync managers!\n");
614 memsize =
sizeof(
ec_sync_t) * total_count;
615 if (!(syncs = kmalloc(memsize, GFP_KERNEL))) {
617 " for sync managers.\n", memsize);
625 for (i = 0; i < count; i++, data += 8) {
627 sync = &syncs[index];
662 unsigned int entry_count, i;
669 while (data_size >= 8) {
670 if (!(pdo = kmalloc(
sizeof(
ec_pdo_t), GFP_KERNEL))) {
671 EC_SLAVE_ERR(slave,
"Failed to allocate PDO memory.\n");
691 for (i = 0; i < entry_count; i++) {
693 EC_SLAVE_ERR(slave,
"Failed to allocate PDO entry memory.\n");
719 EC_SLAVE_ERR(slave,
"Invalid SM index %i for PDO 0x%04X.",
754 EC_SLAVE_DBG(slave, 1,
"String %u not found.\n", index);
778 if (sync_index < slave->sii_image->sii.sync_count) {
792 unsigned int *sdo_count,
793 unsigned int *entry_count
797 unsigned int sdos = 0, entries = 0;
803 list_for_each_entry(entry, &sdo->
entries, list) {
809 *entry_count = entries;
827 if (sdo->
index != index)
853 if (sdo->
index != index)
869 uint16_t sdo_position
951 list_for_each_entry(pdo_entry, &pdo->
entries, list) {
984 list_for_each_entry(pdo, &sync->
pdos.
list, list) {
998 unsigned int port_index
1006 EC_SLAVE_WARN(slave,
"%s(port_index=%u): Invalid port index!\n",
1007 __func__, port_index);
1011 port_index = prev_table[port_index];
1028 unsigned int port_index
1036 EC_SLAVE_WARN(slave,
"%s(port_index=%u): Invalid port index!\n",
1037 __func__, port_index);
1041 port_index = prev_table[port_index];
1059 unsigned int port_index
1067 EC_SLAVE_WARN(slave,
"%s(port_index=%u): Invalid port index!\n",
1068 __func__, port_index);
1072 port_index = next_table[port_index];
1097 EC_SLAVE_DBG(slave, 1,
"DC not supported; assuming upstream port 0.\n");
1108 if (diff < 0 || replace) {
1127 uint32_t rtt_sum = 0, rtt;
1131 unsigned int prev_index =
1155 unsigned int port_index;
1188 unsigned int port_index;
1190 uint32_t rtt, next_rtt_sum;
1202 unsigned int prev_port =
1214 (rtt - next_rtt_sum) / 2;
1216 (rtt - next_rtt_sum) / 2;
1220 " next_rtt_sum=%u delay=%u\n",
1242 EC_SLAVE_DBG(slave, 1,
"%s(delay = %u ns)\n", __func__, *delay);
ec_sii_general_flags_t general_flags
General flags.
ec_mbox_data_t mbox_eoe_frag_data
Received mailbox data for EoE, type frame fragment.
struct list_head mbg_requests
EoE set IP parameter requests.
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.
uint8_t upstream_port
Index of master-facing port.
void ec_slave_calc_upstream_port(ec_slave_t *slave)
Calculates which of ports 0-3 appears to be the upstream one.
uint16_t ec_slave_sdo_count(const ec_slave_t *slave)
Get the number of SDOs in the dictionary.
struct rt_mutex mbox_sem
Semaphore protecting the check_mbox variable.
uint16_t boot_rx_mailbox_offset
Bootstrap receive mailbox address.
ec_internal_request_state_t state
Request state.
void ec_fsm_slave_clear(ec_fsm_slave_t *fsm)
Destructor.
uint16_t configured_tx_mailbox_size
Configured send mailbox size.
unsigned int ec_slave_get_previous_port(ec_slave_t *slave, unsigned int port_index)
Returns the previous connected port of a given port.
void ec_mbox_data_init(ec_mbox_data_t *mbox_data)
Initialize mailbox response data.
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.
EtherCAT Mailbox Gateway request.
struct list_head list
List item.
#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.
unsigned int reboot
Request reboot.
ec_mbox_data_t mbox_eoe_init_data
Received mailbox data for EoE, type eoe init reponse.
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.
ec_slave_state_t current_state
Current application state.
Complete slave information interface data image.
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_mbox_data_t mbox_mbg_data
Received mailbox data for MBox Gateway.
ec_mbox_data_t mbox_foe_data
Received mailbox data for FoE.
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.
#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.
ec_internal_request_state_t state
Request state.
void ec_slave_find_names_for_pdo(ec_slave_t *slave, ec_pdo_t *pdo)
Find name for a PDO and its entries.
ec_fsm_slave_t fsm
Slave state machine.
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.
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 *slave, const uint8_t *data, size_t data_size)
Fetches data from a STRING category.
void ec_slave_set_dl_status(ec_slave_t *slave, uint16_t new_state)
Sets the data-link state of a slave.
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 transmit 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.
ec_sii_image_t * sii_image
Current complete SII image.
struct list_head soe_requests
SoE requests.
Slave information interface CANopen over EtherCAT details flags.
ec_slave_config_t * config
Current configuration.
void ec_slave_sii_image_init(ec_sii_image_t *sii_image)
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.
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 ec_slave_get_previous_normal_port(ec_slave_t *slave, unsigned int port_index)
Returns the previous connected & unbypassed port of a given port.
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.
struct list_head list
List item.
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.
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.
void ec_slave_request_reboot(ec_slave_t *slave)
Request a slave reboot (some slaves will ignore this).
struct list_head entries
List of PDO entries.
uint32_t effective_product_code
Effective product code.
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.
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.
uint8_t subindex
PDO entry subindex.
struct list_head list
List item.
EtherCAT datagram structure.
uint8_t control_register
Control register value.
int ec_read_mbox_locked(ec_slave_t *slave)
Return the current mailbox lock status and lock it if not locked.
CANopen dictionary request.
void ec_sync_clear(ec_sync_t *sync)
Destructor.
uint8_t base_revision
Revision.
uint32_t effective_vendor_id
Effective vendor ID.
struct list_head list
List item.
Ethernet-over-EtherCAT set IP parameter request.
uint16_t * vendor_words
First 16 words of SII image.
void ec_read_mbox_lock_clear(ec_slave_t *slave)
Clears the mailbox lock.
const ec_sdo_t * ec_slave_get_sdo_const(const ec_slave_t *slave, uint16_t index)
Get an SDO from the dictionary.
uint8_t valid_mbox_data
Received mailbox data is valid.
ec_slave_t * ec_slave_find_next_dc_slave(ec_slave_t *slave)
Finds the next slave supporting DC delay measurement.
uint16_t effective_alias
Effective alias address.
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.
void ec_mbox_data_clear(ec_mbox_data_t *mbox_data)
Free internal memory for mailbox response data.
uint8_t enable
Enable bit.
int ec_slave_fetch_sii_syncs(ec_slave_t *slave, const uint8_t *data, size_t data_size)
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.
uint32_t effective_serial_number
Effective serial number.
struct list_head list
List item.
void ec_fsm_slave_init(ec_fsm_slave_t *fsm, ec_slave_t *slave)
Constructor.
uint8_t read_mbox_busy
Flag set during a mailbox read request.
uint8_t bypassed
Packets are bypassing this port (eg.
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.
uint32_t receive_time
Port receive times for delay measurement.
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.
ec_mbox_data_t mbox_voe_data
Received mailbox data for VoE.
unsigned long jiffies_preop
Time, the slave went to PREOP.
uint16_t configured_rx_mailbox_size
Configured receive mailbox size.
uint8_t base_dc_supported
Distributed clocks are supported.
uint32_t ec_slave_calc_rtt_sum(ec_slave_t *slave)
Calculates the sum of round-trip-times of connected ports 1-3.
char * ec_slave_sii_string(ec_slave_t *, unsigned int)
Searches the string list for an index.
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.
struct list_head dict_requests
Dictionary read requests.
unsigned int ec_slave_get_next_port(ec_slave_t *slave, unsigned int port_index)
Returns the next connected port of a given port.
EtherCAT slave configuration structure.
ec_sii_t sii
Extracted SII data.
#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.
uint16_t default_length
Data length in bytes.
uint32_t product_code
Vendor-specific product code.
PREOP state (mailbox communication, no IO)
struct list_head list
List item.
size_t nwords
Size of the SII contents in words.
uint8_t scan_required
Scan required.
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.
uint32_t effective_revision_number
Effective revision number.
uint8_t link_up
Link detected.
int ec_slave_fetch_sii_pdos(ec_slave_t *slave, const uint8_t *data, size_t data_size, ec_direction_t dir)
Fetches data from a [RT]xPDO category.
uint16_t last_al_error
Last AL state error code.
#define EC_MAX_SYNC_MANAGERS
Maximum number of sync managers per slave.
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 *slave, const uint8_t *data, size_t data_size)
Fetches data from a GENERAL category.
void ec_slave_set_al_status(ec_slave_t *slave, ec_slave_state_t new_state)
Sets the application state of a slave.
ec_mbox_data_t mbox_coe_data
Received mailbox data for CoE.
int ec_pdo_entry_set_name(ec_pdo_entry_t *entry, const char *name)
Set PDO entry name.
ec_mbox_data_t mbox_soe_data
Received mailbox data for SoE.
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.
ec_internal_request_state_t state
FoE request state.
unsigned int has_general
General category present.
Sercos-over-EtherCAT request.
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.
ec_internal_request_state_t state
SDO request state.