55 #define EC_SOE_SIZE 0x04 59 #define EC_SOE_HEADER_SIZE (EC_MBOX_HEADER_SIZE + EC_SOE_SIZE) 63 #define EC_SOE_RESPONSE_TIMEOUT 1000 94 for (error_msg = soe_error_codes; error_msg->
code; error_msg++) {
95 if (error_msg->
code == error_code) {
102 EC_SLAVE_ERR(slave,
"Unknown SoE error 0x%04X.\n", error_code);
162 fsm->
state(fsm, datagram);
195 printk(KERN_CONT
"Writing");
197 printk(KERN_CONT
"Reading");
200 printk(KERN_CONT
" IDN 0x%04X failed.\n", request->
idn);
224 return PTR_ERR(data);
254 EC_SLAVE_DBG(slave, 1,
"Reading IDN 0x%04X of drive %u.\n", request->
idn,
258 EC_SLAVE_ERR(slave,
"Slave cannot process SoE read request." 259 " SII data not available.\n");
291 unsigned long diff_ms;
303 EC_SLAVE_ERR(slave,
"Failed to receive SoE read request: ");
324 " failed after %lu ms: ", diff_ms);
363 EC_SLAVE_ERR(slave,
"Failed to receive SoE mailbox check datagram: ");
373 " datagram failed: ");
380 unsigned long diff_ms = 0;
386 fsm->
state(fsm, datagram);
396 EC_SLAVE_ERR(slave,
"Timeout after %lu ms while waiting for" 397 " read response.\n", diff_ms);
432 EC_SLAVE_ERR(slave,
"Failed to receive SoE read response datagram: ");
443 EC_SLAVE_ERR(slave,
"Reception of SoE read response failed: ");
451 fsm->
state(fsm, datagram);
469 uint8_t *data, mbox_prot, header, opcode, incomplete, error_flag,
471 size_t rec_size, data_size;
501 if (mbox_prot != EC_MBOX_TYPE_SOE) {
503 EC_SLAVE_ERR(slave,
"Received mailbox protocol 0x%02X as response.\n",
511 EC_SLAVE_ERR(slave,
"Received currupted SoE read response" 512 " (%zu bytes)!\n", rec_size);
519 opcode = header & 0x7;
520 incomplete = (header >> 3) & 1;
521 error_flag = (header >> 4) & 1;
524 EC_SLAVE_ERR(slave,
"Received no read response (opcode %x).\n",
543 value_included = (
EC_READ_U8(data + 1) >> 6) & 1;
544 if (!value_included) {
553 data + EC_SOE_SIZE, data_size)) {
560 EC_SLAVE_DBG(slave, 1,
"SoE data incomplete. Waiting for fragment" 590 uint8_t incomplete, *data;
591 size_t max_fragment_size, remaining_size;
592 uint16_t fragments_left;
596 incomplete = remaining_size > max_fragment_size;
597 fsm->
fragment_size = incomplete ? max_fragment_size : remaining_size;
638 EC_SLAVE_DBG(slave, 1,
"Writing IDN 0x%04X of drive %u (%zu byte).\n",
642 EC_SLAVE_ERR(slave,
"Slave cannot process SoE write request." 643 " SII data not available.\n");
657 EC_SLAVE_ERR(slave,
"Mailbox size (%u) too small for SoE write.\n",
679 unsigned long diff_ms;
688 EC_SLAVE_ERR(slave,
"Failed to receive SoE write request: ");
706 " failed after %lu ms: ", diff_ms);
755 EC_SLAVE_ERR(slave,
"Failed to receive SoE write request datagram: ");
764 EC_SLAVE_ERR(slave,
"Reception of SoE write request datagram: ");
771 unsigned long diff_ms = 0;
777 fsm->
state(fsm, datagram);
786 EC_SLAVE_ERR(slave,
"Timeout after %lu ms while waiting" 787 " for write response.\n", diff_ms);
823 " response datagram: ");
834 EC_SLAVE_ERR(slave,
"Reception of SoE write response failed: ");
842 fsm->
state(fsm, datagram);
861 uint8_t *data, mbox_prot, opcode, error_flag;
892 if (mbox_prot != EC_MBOX_TYPE_SOE) {
894 EC_SLAVE_ERR(slave,
"Received mailbox protocol 0x%02X as response.\n",
902 EC_SLAVE_ERR(slave,
"Received corrupted SoE write response" 903 " (%zu bytes)!\n", rec_size);
912 " (opcode %x).\n", opcode);
920 if (idn != req->
idn) {
922 " wrong IDN 0x%04x.\n", idn);
933 " - error flag set, but received size is %zu.\n",
#define EC_FSM_RETRIES
Number of state machine retries on datagram timeout.
Finite state machines for the Sercos over EtherCAT protocol.
uint8_t * ec_slave_mbox_prepare_send(const ec_slave_t *slave, ec_datagram_t *datagram, uint8_t type, size_t size)
Prepares a mailbox-send datagram.
unsigned long jiffies_sent
Jiffies, when the datagram was sent.
unsigned long jiffies_sent
Jiffies, when the upload/download request was sent.
size_t fragment_size
Size of the current fragment.
uint8_t * data
Pointer to SDO data.
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
Servo-Profile over EtherCAT.
void ec_fsm_soe_write_response_data(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE RESPONSE DATA.
void ec_fsm_soe_end(ec_fsm_soe_t *, ec_datagram_t *)
State: END.
ec_soe_request_t * request
SoE request.
void ec_fsm_soe_error(ec_fsm_soe_t *, ec_datagram_t *)
State: ERROR.
int ec_slave_mbox_prepare_fetch(const ec_slave_t *slave, ec_datagram_t *datagram)
Prepares a datagram to fetch mailbox data.
int ec_fsm_soe_prepare_read(ec_fsm_soe_t *fsm, ec_datagram_t *datagram)
Prepare a read operation.
#define EC_SOE_HEADER_SIZE
SoE header size.
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
uint8_t * ec_slave_mbox_fetch(const ec_slave_t *slave, ec_mbox_data_t *response_data, uint8_t *type, size_t *size)
Processes received mailbox data.
uint16_t error_code
SoE error code.
void ec_fsm_soe_read_response(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ RESPONSE.
uint16_t working_counter
Working counter.
uint8_t drive_no
Drive number.
const char * message
Message belonging to code.
void ec_print_soe_error(const ec_slave_t *slave, uint16_t error_code)
Outputs an SoE error code.
void ec_fsm_soe_write_check(ec_fsm_soe_t *, ec_datagram_t *)
CoE state: WRITE CHECK.
Global definitions and macros.
void ec_fsm_soe_read_check(ec_fsm_soe_t *, ec_datagram_t *)
CoE state: READ CHECK.
void ec_fsm_soe_read_response_data(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ RESPONSE DATA.
EtherCAT master structure.
ec_sii_image_t * sii_image
Current complete SII image.
void ec_fsm_soe_transfer(ec_fsm_soe_t *fsm, ec_slave_t *slave, ec_soe_request_t *request)
Starts to transfer an IDN to/from a slave.
int ec_fsm_soe_success(const ec_fsm_soe_t *fsm)
Returns, if the state machine terminated with success.
ec_datagram_state_t state
State.
#define EC_SOE_RESPONSE_TIMEOUT
SoE response timeout [ms].
uint16_t mailbox_protocols
Supported mailbox protocols.
size_t data_size
Size of SDO data.
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.
void(* state)(ec_fsm_soe_t *, ec_datagram_t *)
CoE state function.
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
void ec_fsm_soe_write_response(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE RESPONSE.
ec_direction_t dir
Direction.
ec_master_t * master
Master owning the slave.
off_t offset
IDN data offset during fragmented write.
EtherCAT CoE state machines.
int ec_read_mbox_locked(ec_slave_t *slave)
Return the current mailbox lock status and lock it if not locked.
unsigned int retries
retries upon datagram timeout
int ec_soe_request_append_data(ec_soe_request_t *req, const uint8_t *source, size_t size)
Copies SoE data from an external source.
void ec_print_data(const uint8_t *, size_t)
Outputs frame contents for debugging purposes.
void ec_read_mbox_lock_clear(ec_slave_t *slave)
Clears the mailbox lock.
void ec_fsm_soe_read_start(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ START.
int ec_slave_mbox_prepare_check(const ec_slave_t *slave, ec_datagram_t *datagram)
Prepares a datagram for checking the mailbox state.
#define EC_READ_U16(DATA)
Read a 16-bit unsigned value from EtherCAT data.
ec_datagram_t * datagram
Datagram used in the previous step.
void ec_fsm_soe_read_request(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ REQUEST.
void ec_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
const ec_code_msg_t soe_error_codes[]
SoE error codes.
unsigned long jiffies_start
Timestamp.
uint16_t configured_rx_mailbox_size
Configured receive mailbox size.
void ec_fsm_soe_init(ec_fsm_soe_t *fsm)
Constructor.
void ec_fsm_soe_clear(ec_fsm_soe_t *fsm)
Destructor.
#define EC_READ_U8(DATA)
Read an 8-bit unsigned value from EtherCAT data.
ec_sii_t sii
Extracted SII data.
uint16_t idn
Sercos ID-Number.
void ec_fsm_soe_write_next_fragment(ec_fsm_soe_t *fsm, ec_datagram_t *datagram)
Write next fragment.
int ec_fsm_soe_exec(ec_fsm_soe_t *fsm, ec_datagram_t *datagram)
Executes the current state of the state machine.
Unused and should not be queued (dequeued).
void ec_fsm_soe_print_error(ec_fsm_soe_t *fsm)
Output information about a failed SoE transfer.
Values written by the master.
ec_slave_t * slave
slave the FSM runs on
#define EC_SOE_SIZE
Size of all SoE headers.
unsigned long jiffies_received
Jiffies, when the datagram was received.
ec_mbox_data_t mbox_soe_data
Received mailbox data for SoE.
size_t payload_size
Size of the mailbox response payload data.
int ec_slave_mbox_check(const ec_datagram_t *datagram)
Processes a mailbox state checking datagram.
void ec_fsm_soe_write_start(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE START.
Sercos-over-EtherCAT request.
void ec_fsm_soe_write_request(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE REQUEST.