46 #define EC_MBOX_TYPE_SOE 0x05
59 #define EC_SOE_SIZE 0x04
63 #define EC_SOE_HEADER_SIZE (EC_MBOX_HEADER_SIZE + EC_SOE_SIZE)
67 #define EC_SOE_RESPONSE_TIMEOUT 1000
96 for (error_msg = soe_error_codes; error_msg->
code; error_msg++) {
97 if (error_msg->
code == error_code) {
104 EC_SLAVE_ERR(slave,
"Unknown SoE error 0x%04X.\n", error_code);
161 int datagram_used = 0;
168 return datagram_used;
171 fsm->
state(fsm, datagram);
182 return datagram_used;
212 printk(
" IDN 0x%04X failed.\n", request->
idn);
236 return PTR_ERR(data);
266 EC_SLAVE_DBG(slave, 1,
"Reading IDN 0x%04X of drive %u.\n", request->
idn,
295 unsigned long diff_ms;
307 EC_SLAVE_ERR(slave,
"Failed to receive SoE read request: ");
328 " failed after %lu ms: ", diff_ms);
358 EC_SLAVE_ERR(slave,
"Failed to receive SoE mailbox check datagram: ");
367 " datagram failed: ");
374 unsigned long diff_ms =
379 EC_SLAVE_ERR(slave,
"Timeout after %lu ms while waiting for"
380 " read response.\n", diff_ms);
407 uint8_t *data, mbox_prot, header, opcode, incomplete, error_flag,
409 size_t rec_size, data_size;
419 EC_SLAVE_ERR(slave,
"Failed to receive SoE read response datagram: ");
427 EC_SLAVE_ERR(slave,
"Reception of SoE read response failed: ");
447 EC_SLAVE_ERR(slave,
"Received mailbox protocol 0x%02X as response.\n",
455 EC_SLAVE_ERR(slave,
"Received currupted SoE read response"
456 " (%zu bytes)!\n", rec_size);
463 opcode = header & 0x7;
464 incomplete = (header >> 3) & 1;
465 error_flag = (header >> 4) & 1;
468 EC_SLAVE_ERR(slave,
"Received no read response (opcode %x).\n",
487 value_included = (
EC_READ_U8(data + 1) >> 6) & 1;
488 if (!value_included) {
497 data + EC_SOE_SIZE, data_size)) {
504 EC_SLAVE_DBG(slave, 1,
"SoE data incomplete. Waiting for fragment"
534 uint8_t incomplete, *data;
535 size_t max_fragment_size, remaining_size;
536 uint16_t fragments_left;
540 incomplete = remaining_size > max_fragment_size;
541 fsm->
fragment_size = incomplete ? max_fragment_size : remaining_size;
582 EC_SLAVE_DBG(slave, 1,
"Writing IDN 0x%04X of drive %u (%zu byte).\n",
593 EC_SLAVE_ERR(slave,
"Mailbox size (%u) too small for SoE write.\n",
615 unsigned long diff_ms;
624 EC_SLAVE_ERR(slave,
"Failed to receive SoE write request: ");
642 " failed after %lu ms: ", diff_ms);
682 EC_SLAVE_ERR(slave,
"Failed to receive SoE write request datagram: ");
690 EC_SLAVE_ERR(slave,
"Reception of SoE write request datagram: ");
697 unsigned long diff_ms =
701 EC_SLAVE_ERR(slave,
"Timeout after %lu ms while waiting"
702 " for write response.\n", diff_ms);
730 uint8_t *data, mbox_prot, opcode, error_flag;
742 " response datagram: ");
750 EC_SLAVE_ERR(slave,
"Reception of SoE write response failed: ");
770 EC_SLAVE_ERR(slave,
"Received mailbox protocol 0x%02X as response.\n",
778 EC_SLAVE_ERR(slave,
"Received corrupted SoE write response"
779 " (%zu bytes)!\n", rec_size);
788 " (opcode %x).\n", opcode);
796 if (idn != req->
idn) {
798 " wrong IDN 0x%04x.\n", idn);
809 " - error flag set, but received size is %zu.\n",
void ec_fsm_soe_read_start(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ START.
void ec_fsm_soe_end(ec_fsm_soe_t *, ec_datagram_t *)
State: END.
ec_soe_opcodes
SoE operations.
#define EC_FSM_RETRIES
Number of state machine retries on datagram timeout.
void(* state)(ec_fsm_soe_t *, ec_datagram_t *)
CoE state function.
void ec_fsm_soe_write_start(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE START.
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.
ec_sii_t sii
Extracted SII data.
uint8_t * ec_slave_mbox_fetch(const ec_slave_t *slave, const ec_datagram_t *datagram, uint8_t *type, size_t *size)
Processes received mailbox data.
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.
ec_soe_request_t * request
SoE request.
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.
void ec_fsm_soe_read_request(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ REQUEST.
#define EC_SOE_HEADER_SIZE
SoE header size.
#define EC_WRITE_U8(DATA, VAL)
Write an 8-bit unsigned value to EtherCAT data.
uint16_t error_code
SoE error code.
uint16_t working_counter
Working counter.
#define EC_MBOX_TYPE_SOE
Mailbox type for SoE.
uint8_t drive_no
Drive number.
Sent (still in the queue).
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.
Global definitions and macros.
EtherCAT master structure.
Initial state of a new datagram.
void ec_fsm_soe_write_response(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE RESPONSE.
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.
#define EC_WRITE_U16(DATA, VAL)
Write a 16-bit unsigned value to EtherCAT data.
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.
void ec_fsm_soe_write_request(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE REQUEST.
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.
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_datagram_print_state(const ec_datagram_t *datagram)
Prints the state of a datagram.
void ec_fsm_soe_read_check(ec_fsm_soe_t *, ec_datagram_t *)
CoE state: READ CHECK.
Servo-Profile over EtherCAT.
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.
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.
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.
int ec_slave_mbox_check(const ec_datagram_t *datagram)
Processes a mailbox state checking datagram.
void ec_fsm_soe_read_response(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ RESPONSE.
void ec_fsm_soe_error(ec_fsm_soe_t *, ec_datagram_t *)
State: ERROR.
Sercos-over-EtherCAT request.
void ec_fsm_soe_write_check(ec_fsm_soe_t *, ec_datagram_t *)
CoE state: WRITE CHECK.