216 "Failed to receive station address datagram: ");
254 EC_SLAVE_ERR(slave,
"Failed to receive AL state datagram: ");
271 EC_SLAVE_WARN(slave,
"Slave has state error bit set (%s)!\n",
300 EC_SLAVE_ERR(slave,
"Failed to receive base data datagram: ");
319 EC_SLAVE_WARN(slave,
"Slave has more FMMUs (%u) than the master can" 326 EC_SLAVE_WARN(slave,
"Slave provides more sync managers (%u)" 327 " than the master can handle (%u).\n",
334 slave->
ports[i].
desc = (octet >> (2 * i)) & 0x03;
372 EC_SLAVE_ERR(slave,
"Failed to receive system time datagram: ");
379 EC_SLAVE_DBG(slave, 1,
"Slave has the System Time register.\n");
381 EC_SLAVE_DBG(slave, 1,
"Slave has no System Time register; delay " 382 "measurement only.\n");
386 EC_SLAVE_ERR(slave,
"Failed to determine, if system time register is " 418 EC_SLAVE_ERR(slave,
"Failed to receive system time datagram: ");
426 EC_SLAVE_ERR(slave,
"Failed to get DC receive times: ");
490 EC_SLAVE_DBG(slave, 1,
"Assigning SII access to EtherCAT.\n");
541 EC_SLAVE_ERR(slave,
"Failed to receive DL status datagram: ");
557 dl_status & (1 << (4 + i)) ? 1 : 0;
559 dl_status & (1 << (8 + i * 2)) ? 1 : 0;
561 dl_status & (1 << (9 + i * 2)) ? 1 : 0;
596 EC_SLAVE_WARN(slave,
"Failed to receive SII assignment datagram: ");
599 goto continue_with_sii_size;
608 continue_with_sii_size:
630 unsigned int words_fitting;
632 uint32_t vendor, product, revision, serial;
642 EC_SLAVE_ERR(slave,
"Failed to fetch SII identification.\n");
688 "Identification 0x%08X / 0x%08X / 0x%08X / 0x%08X\n",
689 vendor, product, revision, serial);
692 product, revision, serial, slave->
sii.
alias);
696 EC_SLAVE_DBG(slave, 1,
"Found matching SII page in cache.\n");
700 EC_SLAVE_ERR(slave,
"Failed to copy cached SII page.\n");
710 EC_SLAVE_ERR(slave,
"Failed to analyze category data.\n");
717 ec_fsm_slave_scan_enter_regalias(fsm);
728 EC_SLAVE_DBG(slave, 1,
"No matching SII page found in cache.\n");
744 uint16_t cat_type, cat_size;
745 size_t word_count = 0;
753 EC_SLAVE_ERR(slave,
"Failed to determine SII content size:" 754 " Reading word offset 0x%04x failed. Assuming %u words.\n",
763 if (cat_type != 0xFFFF) {
764 off_t next_offset = 2UL + fsm->
sii_offset + cat_size;
766 EC_SLAVE_DBG(slave, 1,
"Found category type %u with size %u." 767 " Proceeding to offset %zd.\n",
768 cat_type, cat_size, (ssize_t)next_offset);
788 EC_SLAVE_ERR(slave,
"Failed to allocate %zu words of SII data.\n",
815 unsigned int words_fitting;
847 EC_SLAVE_ERR(slave,
"Failed to analyze category data.\n");
856 ec_fsm_slave_scan_enter_regalias(fsm);
872 void ec_fsm_slave_scan_enter_regalias(
880 EC_SLAVE_DBG(slave, 1,
"Reading alias from register.\n");
884 fsm->
state = ec_fsm_slave_scan_state_regalias;
891 void ec_fsm_slave_scan_state_regalias(
903 EC_SLAVE_ERR(slave,
"Failed to receive register alias datagram: ");
909 EC_SLAVE_DBG(slave, 1,
"Failed to read register alias.\n");
912 EC_SLAVE_DBG(slave, 1,
"Read alias %u from register.\n",
923 #endif // defined EC_REGALIAS 943 " to do mailbox com (%s), setting to PREOP.\n", str);
952 " sync manager configuration.\n");
992 uint16_t tx_offset, tx_size, rx_offset, rx_size;
1000 " configuration datagram: ");
1018 if (rx_size == 0xffff) {
1021 EC_SLAVE_ERR(slave,
"Invalid RX mailbox size (%u) configured." 1022 " Disabling mailbox communication.", rx_size);
1026 if (tx_size == 0xffff) {
1029 EC_SLAVE_ERR(slave,
"Invalid TX mailbox size (%u) configured." 1030 " Disabling mailbox communication.", tx_size);
1076 " (fixed PDO assignment/configuration).\n");
1082 EC_SLAVE_DBG(slave, 1,
"Scanning PDO assignment and mapping.\n");
#define EC_FSM_RETRIES
Number of state machine retries on datagram timeout.
ec_slave_t * slave
Slave the FSM runs on.
uint16_t ring_position
Ring position.
#define EC_SYNC_PAGE_SIZE
Size of a sync manager configuration page.
void ec_fsm_slave_scan_enter_assign_sii(ec_fsm_slave_scan_t *)
Enter slave scan state ASSIGN_SII.
int ec_slave_analyze_sii_data(ec_slave_t *slave)
Analyzes SII data.
#define EC_SLAVE_STATE_MASK
Slave state mask.
int ec_sii_page_copy(ec_sii_page_t *page, const ec_sii_page_t *from)
Copy contents from other page.
ec_sii_t sii
Extracted SII data.
int ec_fsm_pdo_exec(ec_fsm_pdo_t *fsm, ec_datagram_t *datagram)
Executes the current state of the state machine.
Neither read nor write via CoE.
size_t word_count
Size of the SII contents in words.
void ec_fsm_slave_config_start(ec_fsm_slave_config_t *fsm, ec_slave_t *slave)
Start slave configuration state machine.
ec_datagram_t * datagram
Datagram used in the state machine.
ec_sii_page_origin_t origin
Page origin.
uint16_t configured_tx_mailbox_size
Configured send mailbox size.
uint16_t base_build
Build number.
ec_pdo_mode_t
PDO handling mode.
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
OP (mailbox communication and input/output update)
uint16_t configured_tx_mailbox_offset
Configured send mailbox offset.
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.
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.
uint8_t sii_ident[EC_NUM_SII_IDENT_WORDS *2]
Temporary storage for slave identification objects.
ec_slave_port_link_t link
Port link status.
void ec_fsm_slave_scan_state_preop(ec_fsm_slave_scan_t *)
Slave scan state: PREOP.
#define EC_SLAVE_WARN(slave, fmt, args...)
Convenience macro for printing slave-specific warnings to syslog.
void ec_fsm_slave_scan_state_assign_sii(ec_fsm_slave_scan_t *)
Slave scan state: ASSIGN_SII.
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
void ec_fsm_slave_scan_state_dc_times(ec_fsm_slave_scan_t *)
Slave scan state: DC TIMES.
uint16_t working_counter
Working counter.
void ec_fsm_slave_scan_enter_sii_ident(ec_fsm_slave_scan_t *)
Enter slave scan state SII ident.
void ec_fsm_slave_scan_state_start(ec_fsm_slave_scan_t *)
Slave scan state: START.
ec_slave_config_t * ec_master_find_config_for_slave(ec_master_t *master, const ec_slave_t *slave)
Finds the slave configuration that will be attached to the given slave.
Acknowledge/Error bit (no actual state)
uint8_t signal_detected
Detected signal on RX port.
Sent (still in the queue).
void ec_fsm_sii_init(ec_fsm_sii_t *fsm, ec_datagram_t *datagram)
Constructor.
ec_pdo_mode_t pdo_config_mode
Whether/how to read resp.
EtherCAT slave scanning state machine.
uint16_t station_address
Configured station address.
#define EC_MAX_SII_SIZE
Maximum SII size in words, to avoid infinite reading.
#define EC_MAX_FMMUS
Maximum number of FMMUs per slave.
uint8_t base_type
Slave type.
int ec_fsm_slave_scan_exec(ec_fsm_slave_scan_t *fsm)
Executes the current state of the state machine.
Global definitions and macros.
void ec_fsm_slave_scan_state_sii_ident(ec_fsm_slave_scan_t *)
Slave scan state: SII ident.
EtherCAT master structure.
SAFEOP (mailbox communication and input update)
ec_fsm_slave_config_t * fsm_slave_config
Slave configuration state machine to use.
uint8_t loop_closed
Loop closed.
ec_sii_page_t * ec_master_find_cached_sii_page(const ec_master_t *master, uint32_t vendor_id, uint32_t product_code, uint32_t revision, uint32_t serial, uint16_t alias)
Find a matching cached SII page.
void ec_fsm_slave_scan_state_pdos(ec_fsm_slave_scan_t *)
Slave scan state: PDOS.
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_zero(ec_datagram_t *datagram)
Fills the datagram payload memory with zeros.
unsigned int read_word_count
Number of words that have been read.
ec_datagram_state_t state
State.
ec_pdo_mode_t pdo_assign_mode
Whether/how to read resp.
Slave information interface memory page.
ec_fsm_pdo_t * fsm_pdo
PDO configuration state machine to use.
void ec_fsm_slave_scan_state_base(ec_fsm_slave_scan_t *)
Slave scan state: BASE.
int ec_master_cache_sii_page(ec_master_t *master, const ec_sii_page_t *page)
Add an SII page to the cache.
Use configured addresses.
uint16_t mailbox_protocols
Supported mailbox protocols.
void ec_fsm_slave_scan_state_sii_data(ec_fsm_slave_scan_t *)
Slave scan state: SII DATA.
ec_fsm_sii_t fsm_sii
SII state machine.
unsigned int debug_level
Master debug level.
#define EC_SLAVE_ERR(slave, fmt, args...)
Convenience macro for printing slave-specific errors to syslog.
void ec_datagram_print_wc_error(const ec_datagram_t *datagram)
Evaluates the working counter of a single-cast datagram.
ec_slave_dc_range_t base_dc_range
DC range.
uint8_t base_fmmu_bit_operation
FMMU bit operation is supported.
int ec_sii_page_alloc(ec_sii_page_t *page, size_t word_count)
Free page memory.
void ec_fsm_pdo_start_reading(ec_fsm_pdo_t *fsm, ec_slave_t *slave, ec_pdo_mode_t assign_mode, ec_pdo_mode_t config_mode)
Start reading the PDO configuration.
void ec_fsm_slave_scan_enter_pdos(ec_fsm_slave_scan_t *)
Enter slave scan state PDOS.
int ec_fsm_slave_scan_running(const ec_fsm_slave_scan_t *)
uint16_t alias
Configured station alias.
void ec_fsm_slave_scan_state_sync(ec_fsm_slave_scan_t *)
Slave scan state: SYNC.
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
uint8_t base_fmmu_count
Number of supported FMMUs.
uint16_t configured_rx_mailbox_offset
Configured receive mailbox offset.
#define EC_READ_U32(DATA)
Read a 32-bit unsigned value from EtherCAT data.
ec_slave_port_desc_t desc
Port descriptors.
Finite state machine for scanning an EtherCAT slave.
ec_master_t * master
Master owning the slave.
#define EC_SII_WORD_OFFSET_VENDOR
Word offset of vendor ID.
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.
uint8_t has_dc_system_time
The slave supports the DC system time register.
unsigned int retries
Retries on datagram timeout.
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.
PDO configuration state machine.
#define EC_FIRST_SII_CATEGORY_OFFSET
Word offset of first SII category.
uint8_t base_revision
Revision.
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_clear(ec_fsm_sii_t *fsm)
Destructor.
int ec_fsm_pdo_success(const ec_fsm_pdo_t *fsm)
Get execution result.
Write the configured state via CoE every time the slave is configured, without reading the current st...
uint16_t effective_alias
Effective alias address.
uint8_t value[8]
raw SII value (32 bit / 64 bit)
void ec_fsm_slave_scan_state_datalink(ec_fsm_slave_scan_t *)
Slave scan state: DATALINK.
unsigned int sii_caching
SII caching mode.
int ec_fsm_sii_exec(ec_fsm_sii_t *fsm)
Executes the SII state machine.
int ec_fsm_sii_success(ec_fsm_sii_t *fsm)
Returns, if the master startup state machine terminated with success.
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
Finite state machine to configure an EtherCAT slave.
void ec_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
#define EC_STATE_STRING_SIZE
Minimum size of a buffer used with ec_state_string().
#define EC_MAX_PORTS
Maximum number of slave ports.
uint16_t * words
Complete SII image.
#define EC_PDO_MODE_DEFAULT
Default PDO handling mode: read via CoE while scanning, and unconditionally (re-)write via CoE every ...
int ec_fsm_slave_config_exec(ec_fsm_slave_config_t *fsm)
Executes the current state of the state machine.
void(* state)(ec_fsm_slave_scan_t *)
State function.
void ec_fsm_slave_scan_state_error(ec_fsm_slave_scan_t *)
State: ERROR.
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.
uint16_t sii_offset
SII offset in words.
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 configured_rx_mailbox_size
Configured receive mailbox size.
uint8_t base_dc_supported
Distributed clocks are supported.
void ec_fsm_slave_scan_start(ec_fsm_slave_scan_t *fsm, ec_slave_t *slave)
Start slave scan state machine.
uint8_t * data
Datagram payload.
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.
int ec_fsm_slave_config_success(const ec_fsm_slave_config_t *fsm)
void ec_fsm_slave_scan_clear(ec_fsm_slave_scan_t *fsm)
Destructor.
EtherCAT slave configuration structure.
void ec_fsm_slave_scan_state_end(ec_fsm_slave_scan_t *)
State: END.
void ec_fsm_slave_scan_state_dc_cap(ec_fsm_slave_scan_t *)
Slave scan state: DC CAPABILITIES.
void ec_fsm_slave_scan_enter_sii_size(ec_fsm_slave_scan_t *)
Enter slave scan state SII_SIZE.
PREOP state (mailbox communication, no IO)
void ec_fsm_slave_scan_enter_preop(ec_fsm_slave_scan_t *)
Enter slave scan state PREOP.
unsigned int error_flag
Stop processing after an error.
void ec_fsm_slave_scan_state_address(ec_fsm_slave_scan_t *)
Slave scan state: ADDRESS.
void ec_fsm_slave_scan_state_state(ec_fsm_slave_scan_t *)
Slave scan state: STATE.
uint8_t link_up
Link detected.
#define EC_MAX_SYNC_MANAGERS
Maximum number of sync managers per slave.
void ec_fsm_slave_scan_enter_datalink(ec_fsm_slave_scan_t *)
Slave scan entry function: DATALINK.
void ec_fsm_slave_scan_state_sii_size(ec_fsm_slave_scan_t *)
Slave scan state: SII SIZE.
int ec_fsm_slave_scan_success(const ec_fsm_slave_scan_t *fsm)