201 "Failed to receive station address datagram: ");
239 EC_SLAVE_ERR(slave,
"Failed to receive AL state datagram: ");
256 EC_SLAVE_WARN(slave,
"Slave has state error bit set (%s)!\n",
285 EC_SLAVE_ERR(slave,
"Failed to receive base data datagram: ");
304 EC_SLAVE_WARN(slave,
"Slave has more FMMUs (%u) than the master can"
311 EC_SLAVE_WARN(slave,
"Slave provides more sync managers (%u)"
312 " than the master can handle (%u).\n",
319 slave->
ports[i].
desc = (octet >> (2 * i)) & 0x03;
357 EC_SLAVE_ERR(slave,
"Failed to receive system time datagram: ");
364 EC_SLAVE_DBG(slave, 1,
"Slave has the System Time register.\n");
366 EC_SLAVE_DBG(slave, 1,
"Slave has no System Time register; delay "
367 "measurement only.\n");
371 EC_SLAVE_ERR(slave,
"Failed to determine, if system time register is "
403 EC_SLAVE_ERR(slave,
"Failed to receive system time datagram: ");
411 EC_SLAVE_ERR(slave,
"Failed to get DC receive times: ");
475 EC_SLAVE_DBG(slave, 1,
"Assigning SII access to EtherCAT.\n");
506 EC_SLAVE_ERR(slave,
"Failed to receive DL status datagram: ");
522 dl_status & (1 << (4 + i)) ? 1 : 0;
524 dl_status & (1 << (8 + i * 2)) ? 1 : 0;
526 dl_status & (1 << (9 + i * 2)) ? 1 : 0;
556 EC_SLAVE_WARN(slave,
"Failed to receive SII assignment datagram: ");
559 goto continue_with_sii_size;
568continue_with_sii_size:
585 uint16_t cat_type, cat_size;
593 EC_SLAVE_ERR(slave,
"Failed to determine SII content size:"
594 " Reading word offset 0x%04x failed. Assuming %u words.\n",
603 if (cat_type != 0xFFFF) {
604 off_t next_offset = 2UL + fsm->
sii_offset + cat_size;
606 EC_SLAVE_DBG(slave, 1,
"Found category type %u with size %u."
607 " Proceeding to offset %zd.\n",
608 cat_type, cat_size, (ssize_t)next_offset);
633 (uint16_t *) kmalloc(slave->
sii_nwords * 2, GFP_KERNEL))) {
634 EC_SLAVE_ERR(slave,
"Failed to allocate %zu words of SII data.\n",
661 uint16_t *cat_word, cat_type, cat_size;
730 printk(KERN_CONT
"AoE");
735 printk(KERN_CONT
", ");
737 printk(KERN_CONT
"CoE");
742 printk(KERN_CONT
", ");
744 printk(KERN_CONT
"FoE");
749 printk(KERN_CONT
", ");
751 printk(KERN_CONT
"SoE");
756 printk(KERN_CONT
", ");
758 printk(KERN_CONT
"VoE");
761 printk(KERN_CONT
".\n");
764 EC_SLAVE_DBG(slave, 1,
"Slave announces to support unknown"
765 " mailbox protocols 0x%04X.",
770 EC_SLAVE_DBG(slave, 1,
"Slave announces to support no mailbox"
784 " Disabling mailbox communication.");
795 " First category header missing.\n");
806 " Category header incomplete.\n");
816 " Category data incomplete.\n");
849 EC_SLAVE_DBG(slave, 1,
"Unknown category type 0x%04X.\n",
853 cat_word += cat_size;
856 " Next category header missing.\n");
862 ec_fsm_slave_scan_enter_regalias(fsm);
873 EC_SLAVE_ERR(slave,
"Failed to analyze category data.\n");
884void ec_fsm_slave_scan_enter_regalias(
892 EC_SLAVE_DBG(slave, 1,
"Reading alias from register.\n");
896 fsm->
state = ec_fsm_slave_scan_state_regalias;
903void ec_fsm_slave_scan_state_regalias(
915 EC_SLAVE_ERR(slave,
"Failed to receive register alias datagram: ");
921 EC_SLAVE_DBG(slave, 1,
"Failed to read register alias.\n");
924 EC_SLAVE_DBG(slave, 1,
"Read alias %u from register.\n",
955 " to do mailbox com (%s), setting to PREOP.\n", str);
964 " sync manager configuration.\n");
1004 uint16_t tx_offset, tx_size, rx_offset, rx_size;
1012 " configuration datagram: ");
1030 if (rx_size == 0xffff) {
1033 EC_SLAVE_ERR(slave,
"Invalid RX mailbox size (%u) configured."
1034 " Disabling mailbox communication.", rx_size);
1038 if (tx_size == 0xffff) {
1041 EC_SLAVE_ERR(slave,
"Invalid TX mailbox size (%u) configured."
1042 " Disabling mailbox communication.", tx_size);
1072 EC_SLAVE_DBG(slave, 1,
"Scanning PDO assignment and mapping.\n");
void ec_datagram_print_wc_error(const ec_datagram_t *datagram)
Evaluates the working counter of a single-cast datagram.
void ec_datagram_zero(ec_datagram_t *datagram)
Fills the datagram payload memory with zeros.
int ec_datagram_apwr(ec_datagram_t *datagram, uint16_t ring_position, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT APWR datagram.
void ec_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
int ec_datagram_fpwr(ec_datagram_t *datagram, uint16_t configured_address, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT FPWR datagram.
int ec_datagram_fprd(ec_datagram_t *datagram, uint16_t configured_address, uint16_t mem_address, size_t data_size)
Initializes an EtherCAT FPRD datagram.
@ EC_DATAGRAM_RECEIVED
Received (dequeued).
@ EC_DATAGRAM_TIMED_OUT
Timed out (dequeued).
@ EC_DATAGRAM_SENT
Sent (still in the queue).
@ EC_DATAGRAM_QUEUED
Queued for sending.
void ec_fsm_pdo_start_reading(ec_fsm_pdo_t *fsm, ec_slave_t *slave)
Start reading the PDO configuration.
int ec_fsm_pdo_exec(ec_fsm_pdo_t *fsm, ec_datagram_t *datagram)
Executes the current state of the state machine.
int ec_fsm_pdo_success(const ec_fsm_pdo_t *fsm)
Get execution result.
struct ec_fsm_pdo ec_fsm_pdo_t
int ec_fsm_sii_success(ec_fsm_sii_t *fsm)
Returns, if the master startup state machine terminated with success.
void ec_fsm_sii_clear(ec_fsm_sii_t *fsm)
Destructor.
int ec_fsm_sii_exec(ec_fsm_sii_t *fsm)
Executes the SII state machine.
void ec_fsm_sii_read(ec_fsm_sii_t *fsm, ec_slave_t *slave, uint16_t word_offset, ec_fsm_sii_addressing_t mode)
Initializes the SII read state machine.
void ec_fsm_sii_init(ec_fsm_sii_t *fsm, ec_datagram_t *datagram)
Constructor.
@ EC_FSM_SII_USE_CONFIGURED_ADDRESS
Use configured addresses.
int ec_fsm_slave_config_success(const ec_fsm_slave_config_t *fsm)
void ec_fsm_slave_config_start(ec_fsm_slave_config_t *fsm, ec_slave_t *slave)
Start slave configuration state machine.
int ec_fsm_slave_config_exec(ec_fsm_slave_config_t *fsm)
Executes the current state of the state machine.
struct ec_fsm_slave_config ec_fsm_slave_config_t
void ec_fsm_slave_scan_state_start(ec_fsm_slave_scan_t *)
Slave scan state: START.
void ec_fsm_slave_scan_enter_datalink(ec_fsm_slave_scan_t *)
Slave scan entry function: DATALINK.
void ec_fsm_slave_scan_state_end(ec_fsm_slave_scan_t *)
State: END.
void ec_fsm_slave_scan_state_preop(ec_fsm_slave_scan_t *)
Slave scan state: PREOP.
void ec_fsm_slave_scan_state_sii_size(ec_fsm_slave_scan_t *)
Slave scan state: SII SIZE.
void ec_fsm_slave_scan_state_base(ec_fsm_slave_scan_t *)
Slave scan state: BASE.
void ec_fsm_slave_scan_state_assign_sii(ec_fsm_slave_scan_t *)
Slave scan state: ASSIGN_SII.
void ec_fsm_slave_scan_enter_assign_sii(ec_fsm_slave_scan_t *)
Enter slave scan state ASSIGN_SII.
int ec_fsm_slave_scan_running(const ec_fsm_slave_scan_t *)
void ec_fsm_slave_scan_state_state(ec_fsm_slave_scan_t *)
Slave scan state: STATE.
void ec_fsm_slave_scan_enter_pdos(ec_fsm_slave_scan_t *)
Enter slave scan state PDOS.
void ec_fsm_slave_scan_start(ec_fsm_slave_scan_t *fsm, ec_slave_t *slave)
Start slave scan state machine.
void ec_fsm_slave_scan_state_datalink(ec_fsm_slave_scan_t *)
Slave scan state: DATALINK.
void ec_fsm_slave_scan_init(ec_fsm_slave_scan_t *fsm, ec_datagram_t *datagram, ec_fsm_slave_config_t *fsm_slave_config, ec_fsm_pdo_t *fsm_pdo)
Constructor.
void ec_fsm_slave_scan_enter_sii_size(ec_fsm_slave_scan_t *)
Enter slave scan state SII_SIZE.
void ec_fsm_slave_scan_state_dc_times(ec_fsm_slave_scan_t *)
Slave scan state: DC TIMES.
void ec_fsm_slave_scan_state_sync(ec_fsm_slave_scan_t *)
Slave scan state: SYNC.
void ec_fsm_slave_scan_state_pdos(ec_fsm_slave_scan_t *)
Slave scan state: PDOS.
void ec_fsm_slave_scan_state_dc_cap(ec_fsm_slave_scan_t *)
Slave scan state: DC CAPABILITIES.
void ec_fsm_slave_scan_clear(ec_fsm_slave_scan_t *fsm)
Destructor.
void ec_fsm_slave_scan_state_address(ec_fsm_slave_scan_t *)
Slave scan state: ADDRESS.
void ec_fsm_slave_scan_state_sii_data(ec_fsm_slave_scan_t *)
Slave scan state: SII DATA.
int ec_fsm_slave_scan_exec(ec_fsm_slave_scan_t *fsm)
Executes the current state of the state machine.
void ec_fsm_slave_scan_state_error(ec_fsm_slave_scan_t *)
State: ERROR.
int ec_fsm_slave_scan_success(const ec_fsm_slave_scan_t *fsm)
void ec_fsm_slave_scan_enter_preop(ec_fsm_slave_scan_t *)
Enter slave scan state PREOP.
EtherCAT slave scanning state machine.
struct ec_fsm_slave_scan ec_fsm_slave_scan_t
Global definitions and macros.
#define EC_MAX_SII_SIZE
Maximum SII size in words, to avoid infinite reading.
#define EC_SYNC_PAGE_SIZE
Size of a sync manager configuration page.
@ EC_SLAVE_STATE_PREOP
PREOP state (mailbox communication, no IO)
@ EC_SLAVE_STATE_OP
OP (mailbox communication and input/output update)
@ EC_SLAVE_STATE_SAFEOP
SAFEOP (mailbox communication and input update)
@ EC_SLAVE_STATE_ACK_ERR
Acknowledge/Error bit (no actual state)
#define EC_STATE_STRING_SIZE
Minimum size of a buffer used with ec_state_string().
#define EC_FSM_RETRIES
Number of state machine retries on datagram timeout.
#define EC_SLAVE_STATE_MASK
Slave state mask.
@ EC_MBOX_FOE
File-Access over EtherCAT.
@ EC_MBOX_COE
CANopen over EtherCAT.
@ EC_MBOX_VOE
Vendor specific.
@ EC_MBOX_SOE
Servo-Profile over EtherCAT.
@ EC_MBOX_AOE
ADS over EtherCAT.
#define EC_FIRST_SII_CATEGORY_OFFSET
Word offset of first SII category.
size_t ec_state_string(uint8_t, char *, uint8_t)
Prints slave states in clear text.
#define EC_MAX_FMMUS
Maximum number of FMMUs per slave.
struct ec_slave ec_slave_t
#define EC_MAX_PORTS
Maximum number of slave ports.
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
#define EC_MAX_SYNC_MANAGERS
Maximum number of sync managers per slave.
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
#define EC_READ_U32(DATA)
Read a 32-bit unsigned value from EtherCAT data.
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
@ EC_DIR_INPUT
Values read by the master.
@ EC_DIR_OUTPUT
Values written by the master.
EtherCAT master structure.
void ec_slave_request_state(ec_slave_t *slave, ec_slave_state_t state)
Request a slave state and resets the error flag.
void ec_slave_clear_sync_managers(ec_slave_t *slave)
Clear the sync manager array.
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.
int ec_slave_fetch_sii_strings(ec_slave_t *slave, const uint8_t *data, size_t data_size)
Fetches data from a STRING category.
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.
int ec_slave_fetch_sii_general(ec_slave_t *slave, const uint8_t *data, size_t data_size)
Fetches data from a GENERAL category.
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
#define EC_SLAVE_WARN(slave, fmt, args...)
Convenience macro for printing slave-specific warnings to syslog.
EtherCAT slave configuration structure.
uint16_t working_counter
Working counter.
ec_datagram_state_t state
State.
uint8_t * data
Datagram payload.
uint8_t value[4]
raw SII value (32bit)
unsigned int retries
Retries on datagram timeout.
ec_fsm_slave_config_t * fsm_slave_config
Slave configuration state machine to use.
ec_slave_t * slave
Slave the FSM runs on.
void(* state)(ec_fsm_slave_scan_t *)
State function.
ec_fsm_sii_t fsm_sii
SII state machine.
uint16_t sii_offset
SII offset in words.
ec_datagram_t * datagram
Datagram used in the state machine.
ec_fsm_pdo_t * fsm_pdo
PDO configuration state machine to use.
unsigned int debug_level
Master debug level.
uint16_t std_rx_mailbox_offset
Standard receive mailbox address.
uint16_t alias
Configured station alias.
uint32_t serial_number
Serial number.
uint16_t std_tx_mailbox_size
Standard transmit mailbox size.
uint16_t boot_tx_mailbox_size
Bootstrap transmit mailbox size.
uint32_t product_code
Vendor-specific product code.
uint16_t mailbox_protocols
Supported mailbox protocols.
uint16_t boot_tx_mailbox_offset
Bootstrap transmit mailbox address.
uint16_t std_tx_mailbox_offset
Standard transmit mailbox address.
uint16_t boot_rx_mailbox_size
Bootstrap receive mailbox size.
uint32_t revision_number
Revision number.
uint16_t std_rx_mailbox_size
Standard receive mailbox size.
uint16_t boot_rx_mailbox_offset
Bootstrap receive mailbox address.
uint32_t vendor_id
Vendor ID.
uint8_t signal_detected
Detected signal on RX port.
uint8_t link_up
Link detected.
uint8_t loop_closed
Loop closed.
uint32_t receive_time
Port receive times for delay measurement.
ec_slave_port_link_t link
Port link status.
ec_slave_port_desc_t desc
Port descriptors.
uint16_t configured_rx_mailbox_size
Configured receive mailbox size.
ec_sii_t sii
Extracted SII data.
ec_slave_port_t ports[EC_MAX_PORTS]
Ports.
uint8_t base_dc_supported
Distributed clocks are supported.
uint16_t ring_position
Ring position.
uint16_t configured_tx_mailbox_offset
Configured send mailbox offset.
uint16_t * sii_words
Complete SII image.
uint8_t base_fmmu_bit_operation
FMMU bit operation is supported.
uint8_t base_fmmu_count
Number of supported FMMUs.
uint8_t base_revision
Revision.
ec_slave_state_t current_state
Current application state.
uint8_t has_dc_system_time
The slave supports the DC system time register.
uint16_t configured_tx_mailbox_size
Configured send mailbox size.
uint16_t configured_rx_mailbox_offset
Configured receive mailbox offset.
ec_slave_dc_range_t base_dc_range
DC range.
uint8_t base_type
Slave type.
uint16_t effective_alias
Effective alias address.
size_t sii_nwords
Size of the SII contents in words.
uint8_t base_sync_count
Number of supported sync managers.
ec_master_t * master
Master owning the slave.
uint16_t station_address
Configured station address.
unsigned int error_flag
Stop processing after an error.
uint16_t base_build
Build number.