47 #define EC_SOE_SIZE 0x04 51 #define EC_SOE_HEADER_SIZE (EC_MBOX_HEADER_SIZE + EC_SOE_SIZE) 55 #define EC_SOE_RESPONSE_TIMEOUT 1000 93 if (error_msg->
code == error_code) {
100 EC_SLAVE_ERR(slave,
"Unknown SoE error 0x%04X.\n", error_code);
157 int datagram_used = 0;
164 return datagram_used;
167 fsm->
state(fsm, datagram);
178 return datagram_used;
203 printk(KERN_CONT
"Writing");
205 printk(KERN_CONT
"Reading");
208 printk(KERN_CONT
" IDN 0x%04X failed.\n", request->
idn);
232 return PTR_ERR(data);
262 EC_SLAVE_DBG(slave, 1,
"Reading IDN 0x%04X of drive %u.\n", request->
idn,
291 unsigned long diff_ms;
303 EC_SLAVE_ERR(slave,
"Failed to receive SoE read request: ");
324 " failed after %lu ms: ", diff_ms);
354 EC_SLAVE_ERR(slave,
"Failed to receive SoE mailbox check datagram: ");
363 " datagram failed: ");
370 unsigned long diff_ms =
375 EC_SLAVE_ERR(slave,
"Timeout after %lu ms while waiting for" 376 " read response.\n", diff_ms);
403 uint8_t *data, mbox_prot, header, opcode, incomplete, error_flag,
405 size_t rec_size, data_size;
415 EC_SLAVE_ERR(slave,
"Failed to receive SoE read response datagram: ");
423 EC_SLAVE_ERR(slave,
"Reception of SoE read response failed: ");
441 if (mbox_prot != EC_MBOX_TYPE_SOE) {
443 EC_SLAVE_ERR(slave,
"Received mailbox protocol 0x%02X as response.\n",
451 EC_SLAVE_ERR(slave,
"Received currupted SoE read response" 452 " (%zu bytes)!\n", rec_size);
459 opcode = header & 0x7;
460 incomplete = (header >> 3) & 1;
461 error_flag = (header >> 4) & 1;
464 EC_SLAVE_ERR(slave,
"Received no read response (opcode %x).\n",
483 value_included = (
EC_READ_U8(data + 1) >> 6) & 1;
484 if (!value_included) {
500 EC_SLAVE_DBG(slave, 1,
"SoE data incomplete. Waiting for fragment" 530 uint8_t incomplete, *data;
531 size_t max_fragment_size, remaining_size;
532 uint16_t fragments_left;
536 incomplete = remaining_size > max_fragment_size;
537 fsm->
fragment_size = incomplete ? max_fragment_size : remaining_size;
577 EC_SLAVE_DBG(slave, 1,
"Writing IDN 0x%04X of drive %u (%zu byte).\n",
588 EC_SLAVE_ERR(slave,
"Mailbox size (%u) too small for SoE write.\n",
611 unsigned long diff_ms;
620 EC_SLAVE_ERR(slave,
"Failed to receive SoE write request: ");
638 " failed after %lu ms: ", diff_ms);
679 EC_SLAVE_ERR(slave,
"Failed to receive SoE write request datagram: ");
687 EC_SLAVE_ERR(slave,
"Reception of SoE write request datagram: ");
694 unsigned long diff_ms =
698 EC_SLAVE_ERR(slave,
"Timeout after %lu ms while waiting" 699 " for write response.\n", diff_ms);
727 uint8_t *data, mbox_prot, opcode, error_flag;
739 " response datagram: ");
747 EC_SLAVE_ERR(slave,
"Reception of SoE write response failed: ");
765 if (mbox_prot != EC_MBOX_TYPE_SOE) {
767 EC_SLAVE_ERR(slave,
"Received mailbox protocol 0x%02X as response.\n",
775 EC_SLAVE_ERR(slave,
"Received corrupted SoE write response" 776 " (%zu bytes)!\n", rec_size);
785 " (opcode %x).\n", opcode);
793 if (idn != req->
idn) {
795 " wrong IDN 0x%04x.\n", idn);
806 " - 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.
uint16_t error_code
SoE error code.
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.
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.
#define EC_SLAVE_DBG(slave, level, fmt, args...)
Convenience macro for printing slave-specific debug messages to syslog.
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.
ec_direction_t dir
Direction.
int ec_slave_mbox_prepare_fetch(const ec_slave_t *slave, ec_datagram_t *datagram)
Prepares a datagram to fetch mailbox data.
Servo-Profile over EtherCAT.
int ec_fsm_soe_prepare_read(ec_fsm_soe_t *, ec_datagram_t *)
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.
void ec_fsm_soe_read_response(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: READ RESPONSE.
uint16_t working_counter
Working counter.
Sent (still in the queue).
size_t data_size
Size of SDO data.
const char * message
Message belonging to code.
void ec_print_soe_error(const ec_slave_t *, uint16_t)
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.
EtherCAT master structure.
Initial state of a new datagram.
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.
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_master_t * master
Master owning the slave.
off_t offset
IDN data offset during fragmented write.
EtherCAT CoE state machines.
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_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.
uint8_t drive_no
Drive number.
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.
void ec_fsm_soe_write_next_fragment(ec_fsm_soe_t *, ec_datagram_t *)
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.
unsigned long jiffies_sent
Jiffies, when the upload/download request was sent.
void ec_fsm_soe_print_error(ec_fsm_soe_t *)
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.
uint16_t idn
Sercos ID-Number.
Sercos-over-EtherCAT request.
unsigned long jiffies_received
Jiffies, when the datagram was received.
uint8_t * data
Pointer to SDO 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.
void ec_fsm_soe_write_request(ec_fsm_soe_t *, ec_datagram_t *)
SoE state: WRITE REQUEST.