merge -c1619 branches/1.4-foe: Implemented going to bootstrap state BOOT.
This commit is contained in:
parent
8d45915fc4
commit
5d4b915317
3
NEWS
3
NEWS
|
|
@ -19,6 +19,9 @@ Changes since 1.4.0:
|
|||
physical device.
|
||||
* Improved error case return codes of many functions.
|
||||
* Added 8139too driver for 2.6.25.
|
||||
* Implemented the File Access over EtherCAT (FoE) mailbox protocol.
|
||||
* Going to the Bootstrap state is now supported by the state machines and the
|
||||
command-line tool.
|
||||
|
||||
Changes in 1.4.0:
|
||||
|
||||
|
|
|
|||
|
|
@ -226,10 +226,14 @@ int ec_cdev_ioctl_slave(
|
|||
data.revision_number = slave->sii.revision_number;
|
||||
data.serial_number = slave->sii.serial_number;
|
||||
data.alias = slave->sii.alias;
|
||||
data.rx_mailbox_offset = slave->sii.rx_mailbox_offset;
|
||||
data.rx_mailbox_size = slave->sii.rx_mailbox_size;
|
||||
data.tx_mailbox_offset = slave->sii.tx_mailbox_offset;
|
||||
data.tx_mailbox_size = slave->sii.tx_mailbox_size;
|
||||
data.boot_rx_mailbox_offset = slave->sii.boot_rx_mailbox_offset;
|
||||
data.boot_rx_mailbox_size = slave->sii.boot_rx_mailbox_size;
|
||||
data.boot_tx_mailbox_offset = slave->sii.boot_tx_mailbox_offset;
|
||||
data.boot_tx_mailbox_size = slave->sii.boot_tx_mailbox_size;
|
||||
data.std_rx_mailbox_offset = slave->sii.std_rx_mailbox_offset;
|
||||
data.std_rx_mailbox_size = slave->sii.std_rx_mailbox_size;
|
||||
data.std_tx_mailbox_offset = slave->sii.std_tx_mailbox_offset;
|
||||
data.std_tx_mailbox_size = slave->sii.std_tx_mailbox_size;
|
||||
data.mailbox_protocols = slave->sii.mailbox_protocols;
|
||||
data.has_general_category = slave->sii.has_general;
|
||||
data.coe_details = slave->sii.coe_details;
|
||||
|
|
|
|||
|
|
@ -218,6 +218,7 @@ void ec_eoe_flush(ec_eoe_t *eoe /**< EoE handler */)
|
|||
|
||||
/**
|
||||
Sends a frame or the next fragment.
|
||||
\todo bootstrap mailboxes / use configured mailbox sizes
|
||||
*/
|
||||
|
||||
int ec_eoe_send(ec_eoe_t *eoe /**< EoE handler */)
|
||||
|
|
@ -231,12 +232,11 @@ int ec_eoe_send(ec_eoe_t *eoe /**< EoE handler */)
|
|||
|
||||
remaining_size = eoe->tx_frame->skb->len - eoe->tx_offset;
|
||||
|
||||
if (remaining_size <= eoe->slave->sii.tx_mailbox_size - 10) {
|
||||
if (remaining_size <= eoe->slave->sii.std_tx_mailbox_size - 10) {
|
||||
current_size = remaining_size;
|
||||
last_fragment = 1;
|
||||
}
|
||||
else {
|
||||
current_size = ((eoe->slave->sii.tx_mailbox_size - 10) / 32) * 32;
|
||||
} else {
|
||||
current_size = ((eoe->slave->sii.std_tx_mailbox_size - 10) / 32) * 32;
|
||||
last_fragment = 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ void ec_fsm_change_state_check(ec_fsm_change_t *fsm
|
|||
if (datagram->working_counter == 0) {
|
||||
if (datagram->jiffies_received - fsm->jiffies_start >= 3 * HZ) {
|
||||
char state_str[EC_STATE_STRING_SIZE];
|
||||
ec_state_string(fsm->requested_state, state_str);
|
||||
ec_state_string(fsm->requested_state, state_str, 0);
|
||||
fsm->state = ec_fsm_change_state_error;
|
||||
EC_ERR("Failed to set state %s on slave %u: ",
|
||||
state_str, fsm->slave->ring_position);
|
||||
|
|
@ -204,7 +204,7 @@ void ec_fsm_change_state_check(ec_fsm_change_t *fsm
|
|||
|
||||
if (unlikely(datagram->working_counter > 1)) {
|
||||
char state_str[EC_STATE_STRING_SIZE];
|
||||
ec_state_string(fsm->requested_state, state_str);
|
||||
ec_state_string(fsm->requested_state, state_str, 0);
|
||||
fsm->state = ec_fsm_change_state_error;
|
||||
EC_ERR("Failed to set state %s on slave %u: ",
|
||||
state_str, fsm->slave->ring_position);
|
||||
|
|
@ -247,7 +247,7 @@ void ec_fsm_change_state_status(ec_fsm_change_t *fsm
|
|||
|
||||
if (datagram->working_counter != 1) {
|
||||
char req_state[EC_STATE_STRING_SIZE];
|
||||
ec_state_string(fsm->requested_state, req_state);
|
||||
ec_state_string(fsm->requested_state, req_state, 0);
|
||||
fsm->state = ec_fsm_change_state_error;
|
||||
EC_ERR("Failed to check state %s on slave %u: ",
|
||||
req_state, slave->ring_position);
|
||||
|
|
@ -271,7 +271,7 @@ void ec_fsm_change_state_status(ec_fsm_change_t *fsm
|
|||
if (slave->current_state != fsm->old_state) { // state changed
|
||||
char req_state[EC_STATE_STRING_SIZE], cur_state[EC_STATE_STRING_SIZE];
|
||||
|
||||
ec_state_string(slave->current_state, cur_state);
|
||||
ec_state_string(slave->current_state, cur_state, 0);
|
||||
|
||||
if ((slave->current_state & 0x0F) != (fsm->old_state & 0x0F)) {
|
||||
// Slave spontaneously changed its state just before the new state
|
||||
|
|
@ -287,7 +287,7 @@ void ec_fsm_change_state_status(ec_fsm_change_t *fsm
|
|||
// state change error
|
||||
|
||||
slave->error_flag = 1;
|
||||
ec_state_string(fsm->requested_state, req_state);
|
||||
ec_state_string(fsm->requested_state, req_state, 0);
|
||||
|
||||
EC_ERR("Failed to set %s state, slave %u refused state change (%s).\n",
|
||||
req_state, slave->ring_position, cur_state);
|
||||
|
|
@ -304,7 +304,7 @@ void ec_fsm_change_state_status(ec_fsm_change_t *fsm
|
|||
if (datagram->jiffies_received - fsm->jiffies_start >= HZ) { // 1s
|
||||
// timeout while checking
|
||||
char state_str[EC_STATE_STRING_SIZE];
|
||||
ec_state_string(fsm->requested_state, state_str);
|
||||
ec_state_string(fsm->requested_state, state_str, 0);
|
||||
fsm->state = ec_fsm_change_state_error;
|
||||
EC_ERR("Timeout while setting state %s on slave %u.\n",
|
||||
state_str, slave->ring_position);
|
||||
|
|
@ -326,7 +326,7 @@ void ec_fsm_change_state_status(ec_fsm_change_t *fsm
|
|||
|
||||
const ec_code_msg_t al_status_messages[] = {
|
||||
{0x0001, "Unspecified error"},
|
||||
{0x0011, "Invalud requested state change"},
|
||||
{0x0011, "Invalid requested state change"},
|
||||
{0x0012, "Unknown requested state"},
|
||||
{0x0013, "Bootstrap not supported"},
|
||||
{0x0014, "No valid firmware"},
|
||||
|
|
@ -498,7 +498,7 @@ void ec_fsm_change_state_check_ack(ec_fsm_change_t *fsm
|
|||
|
||||
if (!(slave->current_state & EC_SLAVE_STATE_ACK_ERR)) {
|
||||
char state_str[EC_STATE_STRING_SIZE];
|
||||
ec_state_string(slave->current_state, state_str);
|
||||
ec_state_string(slave->current_state, state_str, 0);
|
||||
if (fsm->mode == EC_FSM_CHANGE_MODE_FULL) {
|
||||
fsm->state = ec_fsm_change_state_error;
|
||||
}
|
||||
|
|
@ -513,7 +513,7 @@ void ec_fsm_change_state_check_ack(ec_fsm_change_t *fsm
|
|||
if (datagram->jiffies_received - fsm->jiffies_start >= HZ) { // 1s
|
||||
// timeout while checking
|
||||
char state_str[EC_STATE_STRING_SIZE];
|
||||
ec_state_string(slave->current_state, state_str);
|
||||
ec_state_string(slave->current_state, state_str, 0);
|
||||
fsm->state = ec_fsm_change_state_error;
|
||||
EC_ERR("Timeout while acknowledging state %s on slave %u.\n",
|
||||
state_str, slave->ring_position);
|
||||
|
|
|
|||
|
|
@ -1095,7 +1095,7 @@ void ec_fsm_coe_down_start(ec_fsm_coe_t *fsm /**< finite state machine */)
|
|||
}
|
||||
}
|
||||
else { // request->data_size > 4, use normal transfer type
|
||||
if (slave->sii.rx_mailbox_size < 6 + 10 + request->data_size) {
|
||||
if (slave->sii.std_rx_mailbox_size < 6 + 10 + request->data_size) {
|
||||
EC_ERR("SDO fragmenting not supported yet!\n");
|
||||
fsm->state = ec_fsm_coe_error;
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -214,12 +214,13 @@ int ec_foe_prepare_data_send( ec_fsm_foe_t *fsm ) {
|
|||
|
||||
remaining_size = fsm->tx_buffer_size - fsm->tx_buffer_offset;
|
||||
|
||||
if (remaining_size < fsm->slave->sii.tx_mailbox_size - EC_MBOX_HEADER_SIZE - EC_FOE_HEADER_SIZE) {
|
||||
if (remaining_size < fsm->slave->sii.std_tx_mailbox_size
|
||||
- EC_MBOX_HEADER_SIZE - EC_FOE_HEADER_SIZE) {
|
||||
current_size = remaining_size;
|
||||
fsm->tx_last_packet = 1;
|
||||
}
|
||||
else {
|
||||
current_size = fsm->slave->sii.tx_mailbox_size - EC_MBOX_HEADER_SIZE - EC_FOE_HEADER_SIZE;
|
||||
} else {
|
||||
current_size = fsm->slave->sii.std_tx_mailbox_size
|
||||
- EC_MBOX_HEADER_SIZE - EC_FOE_HEADER_SIZE;
|
||||
}
|
||||
|
||||
if (!(data = ec_slave_mbox_prepare_send(fsm->slave, fsm->datagram,
|
||||
|
|
@ -788,12 +789,12 @@ void ec_fsm_foe_state_data_read ( ec_fsm_foe_t *fsm ) {
|
|||
|
||||
fsm->rx_last_packet =
|
||||
(rec_size + EC_MBOX_HEADER_SIZE + EC_FOE_HEADER_SIZE
|
||||
!= fsm->slave->sii.rx_mailbox_size);
|
||||
!= fsm->slave->sii.std_rx_mailbox_size);
|
||||
|
||||
if (fsm->rx_last_packet ||
|
||||
(slave->sii.rx_mailbox_size - EC_MBOX_HEADER_SIZE
|
||||
- EC_FOE_HEADER_SIZE + fsm->rx_buffer_offset) <= fsm->rx_buffer_size) {
|
||||
// either it was the last packet or a new packet will fit into the delivered buffer
|
||||
(slave->sii.std_rx_mailbox_size - EC_MBOX_HEADER_SIZE
|
||||
- EC_FOE_HEADER_SIZE + fsm->rx_buffer_offset) <= fsm->rx_buffer_size) {
|
||||
// either it was the last packet or a new packet will fit into the delivered buffer
|
||||
#ifdef myDEBUG
|
||||
printk ("last_packet=true\n");
|
||||
#endif
|
||||
|
|
@ -811,7 +812,7 @@ void ec_fsm_foe_state_data_read ( ec_fsm_foe_t *fsm ) {
|
|||
printk (" rx_buffer_size = %d\n", fsm->rx_buffer_size);
|
||||
printk (" rx_buffer_offset= %d\n", fsm->rx_buffer_offset);
|
||||
printk (" rec_size = %d\n", rec_size);
|
||||
printk (" rx_mailbox_size = %d\n", slave->sii.rx_mailbox_size);
|
||||
printk (" rx_mailbox_size = %d\n", slave->sii.std_rx_mailbox_size);
|
||||
printk (" rx_last_packet = %d\n", fsm->rx_last_packet);
|
||||
// fsm->state = ec_fsm_state_wait_next_read;
|
||||
fsm->request->result = FOE_READY;
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ void ec_fsm_master_state_broadcast(
|
|||
if (states != fsm->slave_states) { // slave states changed?
|
||||
char state_str[EC_STATE_STRING_SIZE];
|
||||
fsm->slave_states = states;
|
||||
ec_state_string(fsm->slave_states, state_str);
|
||||
ec_state_string(fsm->slave_states, state_str, 1);
|
||||
EC_INFO("Slave states: %s.\n", state_str);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -622,8 +622,8 @@ void ec_fsm_master_action_configure(
|
|||
if (master->debug_level) {
|
||||
char old_state[EC_STATE_STRING_SIZE],
|
||||
new_state[EC_STATE_STRING_SIZE];
|
||||
ec_state_string(slave->current_state, old_state);
|
||||
ec_state_string(slave->requested_state, new_state);
|
||||
ec_state_string(slave->current_state, old_state, 0);
|
||||
ec_state_string(slave->requested_state, new_state, 0);
|
||||
EC_DBG("Changing state of slave %u from %s to %s%s.\n",
|
||||
slave->ring_position, old_state, new_state,
|
||||
slave->force_config ? " (forced)" : "");
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ void ec_fsm_slave_config_state_start(ec_fsm_slave_config_t *);
|
|||
void ec_fsm_slave_config_state_init(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_clear_fmmus(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_mbox_sync(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_preop(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_boot_preop(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_sdo_conf(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_pdo_sync(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_state_pdo_conf(ec_fsm_slave_config_t *);
|
||||
|
|
@ -53,7 +53,7 @@ void ec_fsm_slave_config_state_op(ec_fsm_slave_config_t *);
|
|||
|
||||
void ec_fsm_slave_config_enter_init(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_enter_mbox_sync(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_enter_preop(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_enter_boot_preop(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_enter_sdo_conf(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_enter_pdo_conf(ec_fsm_slave_config_t *);
|
||||
void ec_fsm_slave_config_enter_pdo_sync(ec_fsm_slave_config_t *);
|
||||
|
|
@ -289,7 +289,7 @@ void ec_fsm_slave_config_enter_mbox_sync(
|
|||
if (master->debug_level)
|
||||
EC_DBG("Slave %u does not support mailbox communication.\n",
|
||||
slave->ring_position);
|
||||
ec_fsm_slave_config_enter_preop(fsm);
|
||||
ec_fsm_slave_config_enter_boot_preop(fsm);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -298,7 +298,29 @@ void ec_fsm_slave_config_enter_mbox_sync(
|
|||
slave->ring_position);
|
||||
}
|
||||
|
||||
if (slave->sii.sync_count >= 2) { // mailbox configuration provided
|
||||
if (slave->requested_state == EC_SLAVE_STATE_BOOT) {
|
||||
ec_sync_t sync;
|
||||
|
||||
ec_datagram_fpwr(datagram, slave->station_address, 0x0800,
|
||||
EC_SYNC_PAGE_SIZE * 2);
|
||||
memset(datagram->data, 0x00, EC_SYNC_PAGE_SIZE * 2);
|
||||
|
||||
ec_sync_init(&sync, slave);
|
||||
sync.physical_start_address = slave->sii.boot_rx_mailbox_offset;
|
||||
sync.control_register = 0x26;
|
||||
sync.enable = 1;
|
||||
ec_sync_page(&sync, 0, slave->sii.boot_rx_mailbox_size,
|
||||
EC_DIR_INVALID, // use default direction
|
||||
datagram->data);
|
||||
|
||||
ec_sync_init(&sync, slave);
|
||||
sync.physical_start_address = slave->sii.boot_tx_mailbox_offset;
|
||||
sync.control_register = 0x22;
|
||||
sync.enable = 1;
|
||||
ec_sync_page(&sync, 1, slave->sii.boot_tx_mailbox_size,
|
||||
EC_DIR_INVALID, // use default direction
|
||||
datagram->data + EC_SYNC_PAGE_SIZE);
|
||||
} else if (slave->sii.sync_count >= 2) { // mailbox configuration provided
|
||||
ec_datagram_fpwr(datagram, slave->station_address, 0x0800,
|
||||
EC_SYNC_PAGE_SIZE * slave->sii.sync_count);
|
||||
ec_datagram_zero(datagram);
|
||||
|
|
@ -322,18 +344,18 @@ void ec_fsm_slave_config_enter_mbox_sync(
|
|||
ec_datagram_zero(datagram);
|
||||
|
||||
ec_sync_init(&sync, slave);
|
||||
sync.physical_start_address = slave->sii.rx_mailbox_offset;
|
||||
sync.physical_start_address = slave->sii.std_rx_mailbox_offset;
|
||||
sync.control_register = 0x26;
|
||||
sync.enable = 1;
|
||||
ec_sync_page(&sync, 0, slave->sii.rx_mailbox_size,
|
||||
ec_sync_page(&sync, 0, slave->sii.std_rx_mailbox_size,
|
||||
EC_DIR_INVALID, // use default direction
|
||||
datagram->data);
|
||||
|
||||
ec_sync_init(&sync, slave);
|
||||
sync.physical_start_address = slave->sii.tx_mailbox_offset;
|
||||
sync.physical_start_address = slave->sii.std_tx_mailbox_offset;
|
||||
sync.control_register = 0x22;
|
||||
sync.enable = 1;
|
||||
ec_sync_page(&sync, 1, slave->sii.tx_mailbox_size,
|
||||
ec_sync_page(&sync, 1, slave->sii.std_tx_mailbox_size,
|
||||
EC_DIR_INVALID, // use default direction
|
||||
datagram->data + EC_SYNC_PAGE_SIZE);
|
||||
}
|
||||
|
|
@ -373,27 +395,33 @@ void ec_fsm_slave_config_state_mbox_sync(
|
|||
return;
|
||||
}
|
||||
|
||||
ec_fsm_slave_config_enter_preop(fsm);
|
||||
ec_fsm_slave_config_enter_boot_preop(fsm);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Request PREOP state.
|
||||
*/
|
||||
void ec_fsm_slave_config_enter_preop(
|
||||
void ec_fsm_slave_config_enter_boot_preop(
|
||||
ec_fsm_slave_config_t *fsm /**< slave state machine */
|
||||
)
|
||||
{
|
||||
fsm->state = ec_fsm_slave_config_state_preop;
|
||||
ec_fsm_change_start(fsm->fsm_change, fsm->slave, EC_SLAVE_STATE_PREOP);
|
||||
fsm->state = ec_fsm_slave_config_state_boot_preop;
|
||||
|
||||
if (fsm->slave->requested_state != EC_SLAVE_STATE_BOOT) {
|
||||
ec_fsm_change_start(fsm->fsm_change, fsm->slave, EC_SLAVE_STATE_PREOP);
|
||||
} else { // BOOT
|
||||
ec_fsm_change_start(fsm->fsm_change, fsm->slave, EC_SLAVE_STATE_BOOT);
|
||||
}
|
||||
|
||||
ec_fsm_change_exec(fsm->fsm_change); // execute immediately
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Slave configuration state: PREOP.
|
||||
/** Slave configuration state: BOOT/PREOP.
|
||||
*/
|
||||
void ec_fsm_slave_config_state_preop(
|
||||
void ec_fsm_slave_config_state_boot_preop(
|
||||
ec_fsm_slave_config_t *fsm /**< slave state machine */
|
||||
)
|
||||
{
|
||||
|
|
@ -409,11 +437,13 @@ void ec_fsm_slave_config_state_preop(
|
|||
return;
|
||||
}
|
||||
|
||||
// slave is now in PREOP
|
||||
// slave is now in BOOT/PREOP
|
||||
slave->jiffies_preop = fsm->datagram->jiffies_received;
|
||||
|
||||
if (master->debug_level) {
|
||||
EC_DBG("Slave %u is now in PREOP.\n", slave->ring_position);
|
||||
EC_DBG("Slave %u is now in %s.\n", slave->ring_position,
|
||||
slave->requested_state != EC_SLAVE_STATE_BOOT
|
||||
? "PREOP" : "BOOT");
|
||||
}
|
||||
|
||||
if (slave->current_state == slave->requested_state) {
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ void ec_fsm_slave_scan_state_state(
|
|||
slave->current_state = EC_READ_U8(datagram->data);
|
||||
if (slave->current_state & EC_SLAVE_STATE_ACK_ERR) {
|
||||
char state_str[EC_STATE_STRING_SIZE];
|
||||
ec_state_string(slave->current_state, state_str);
|
||||
ec_state_string(slave->current_state, state_str, 0);
|
||||
EC_WARN("Slave %u has state error bit set (%s)!\n",
|
||||
slave->ring_position, state_str);
|
||||
}
|
||||
|
|
@ -469,13 +469,21 @@ void ec_fsm_slave_scan_state_sii_data(ec_fsm_slave_scan_t *fsm /**< slave state
|
|||
EC_READ_U32(slave->sii_words + 0x000C);
|
||||
slave->sii.serial_number =
|
||||
EC_READ_U32(slave->sii_words + 0x000E);
|
||||
slave->sii.rx_mailbox_offset =
|
||||
slave->sii.boot_rx_mailbox_offset =
|
||||
EC_READ_U16(slave->sii_words + 0x0014);
|
||||
slave->sii.boot_rx_mailbox_size =
|
||||
EC_READ_U16(slave->sii_words + 0x0015);
|
||||
slave->sii.boot_tx_mailbox_offset =
|
||||
EC_READ_U16(slave->sii_words + 0x0016);
|
||||
slave->sii.boot_tx_mailbox_size =
|
||||
EC_READ_U16(slave->sii_words + 0x0017);
|
||||
slave->sii.std_rx_mailbox_offset =
|
||||
EC_READ_U16(slave->sii_words + 0x0018);
|
||||
slave->sii.rx_mailbox_size =
|
||||
slave->sii.std_rx_mailbox_size =
|
||||
EC_READ_U16(slave->sii_words + 0x0019);
|
||||
slave->sii.tx_mailbox_offset =
|
||||
slave->sii.std_tx_mailbox_offset =
|
||||
EC_READ_U16(slave->sii_words + 0x001A);
|
||||
slave->sii.tx_mailbox_size =
|
||||
slave->sii.std_tx_mailbox_size =
|
||||
EC_READ_U16(slave->sii_words + 0x001B);
|
||||
slave->sii.mailbox_protocols =
|
||||
EC_READ_U16(slave->sii_words + 0x001C);
|
||||
|
|
|
|||
|
|
@ -115,6 +115,8 @@ typedef enum {
|
|||
/**< INIT state (no mailbox communication, no IO) */
|
||||
EC_SLAVE_STATE_PREOP = 0x02,
|
||||
/**< PREOP state (mailbox communication, no IO) */
|
||||
EC_SLAVE_STATE_BOOT = 0x03,
|
||||
/**< Bootstrap state (mailbox communication, firmware update) */
|
||||
EC_SLAVE_STATE_SAFEOP = 0x04,
|
||||
/**< SAFEOP (mailbox communication and input update) */
|
||||
EC_SLAVE_STATE_OP = 0x08,
|
||||
|
|
@ -226,7 +228,7 @@ extern char *ec_master_version_str;
|
|||
|
||||
void ec_print_data(const uint8_t *, size_t);
|
||||
void ec_print_data_diff(const uint8_t *, const uint8_t *, size_t);
|
||||
size_t ec_state_string(uint8_t, char *);
|
||||
size_t ec_state_string(uint8_t, char *, uint8_t);
|
||||
ssize_t ec_mac_print(const uint8_t *, char *);
|
||||
int ec_mac_is_zero(const uint8_t *);
|
||||
|
||||
|
|
|
|||
|
|
@ -135,10 +135,14 @@ typedef struct {
|
|||
uint32_t revision_number;
|
||||
uint32_t serial_number;
|
||||
uint16_t alias;
|
||||
uint16_t rx_mailbox_offset;
|
||||
uint16_t rx_mailbox_size;
|
||||
uint16_t tx_mailbox_offset;
|
||||
uint16_t tx_mailbox_size;
|
||||
uint16_t boot_rx_mailbox_offset;
|
||||
uint16_t boot_rx_mailbox_size;
|
||||
uint16_t boot_tx_mailbox_offset;
|
||||
uint16_t boot_tx_mailbox_size;
|
||||
uint16_t std_rx_mailbox_offset;
|
||||
uint16_t std_rx_mailbox_size;
|
||||
uint16_t std_tx_mailbox_offset;
|
||||
uint16_t std_tx_mailbox_size;
|
||||
uint16_t mailbox_protocols;
|
||||
uint8_t has_general_category;
|
||||
ec_sii_coe_details_t coe_details;
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ uint8_t *ec_slave_mbox_prepare_send(const ec_slave_t *slave, /**< slave */
|
|||
{
|
||||
size_t total_size;
|
||||
int ret;
|
||||
uint16_t mailbox_offset, mailbox_size;
|
||||
|
||||
if (unlikely(!slave->sii.mailbox_protocols)) {
|
||||
EC_ERR("Slave %u does not support mailbox communication!\n",
|
||||
|
|
@ -61,14 +62,22 @@ uint8_t *ec_slave_mbox_prepare_send(const ec_slave_t *slave, /**< slave */
|
|||
}
|
||||
|
||||
total_size = EC_MBOX_HEADER_SIZE + size;
|
||||
if (unlikely(total_size > slave->sii.rx_mailbox_size)) {
|
||||
|
||||
if (slave->current_state != EC_SLAVE_STATE_BOOT) {
|
||||
mailbox_offset = slave->sii.std_rx_mailbox_offset;
|
||||
mailbox_size = slave->sii.std_rx_mailbox_size;
|
||||
} else {
|
||||
mailbox_offset = slave->sii.boot_rx_mailbox_offset;
|
||||
mailbox_size = slave->sii.boot_rx_mailbox_size;
|
||||
}
|
||||
|
||||
if (unlikely(total_size > mailbox_size)) {
|
||||
EC_ERR("Data size does not fit in mailbox!\n");
|
||||
return ERR_PTR(-EOVERFLOW);
|
||||
}
|
||||
|
||||
ret = ec_datagram_fpwr(datagram, slave->station_address,
|
||||
slave->sii.rx_mailbox_offset,
|
||||
slave->sii.rx_mailbox_size);
|
||||
mailbox_offset, mailbox_size);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
|
|
@ -123,9 +132,19 @@ int ec_slave_mbox_prepare_fetch(const ec_slave_t *slave, /**< slave */
|
|||
ec_datagram_t *datagram /**< datagram */
|
||||
)
|
||||
{
|
||||
int ret = ec_datagram_fprd(datagram, slave->station_address,
|
||||
slave->sii.tx_mailbox_offset,
|
||||
slave->sii.tx_mailbox_size);
|
||||
int ret;
|
||||
uint16_t mailbox_offset, mailbox_size;
|
||||
|
||||
if (slave->current_state != EC_SLAVE_STATE_BOOT) {
|
||||
mailbox_offset = slave->sii.std_tx_mailbox_offset;
|
||||
mailbox_size = slave->sii.std_tx_mailbox_size;
|
||||
} else {
|
||||
mailbox_offset = slave->sii.boot_tx_mailbox_offset;
|
||||
mailbox_size = slave->sii.boot_tx_mailbox_size;
|
||||
}
|
||||
|
||||
ret = ec_datagram_fprd(datagram, slave->station_address,
|
||||
mailbox_offset, mailbox_size);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -164,13 +183,22 @@ uint8_t *ec_slave_mbox_fetch(const ec_slave_t *slave, /**< slave */
|
|||
)
|
||||
{
|
||||
size_t data_size;
|
||||
uint16_t mailbox_offset, mailbox_size;
|
||||
|
||||
if (slave->current_state != EC_SLAVE_STATE_BOOT) {
|
||||
mailbox_offset = slave->sii.std_tx_mailbox_offset;
|
||||
mailbox_size = slave->sii.std_tx_mailbox_size;
|
||||
} else {
|
||||
mailbox_offset = slave->sii.boot_tx_mailbox_offset;
|
||||
mailbox_size = slave->sii.boot_tx_mailbox_size;
|
||||
}
|
||||
|
||||
data_size = EC_READ_U16(datagram->data);
|
||||
|
||||
if (data_size + EC_MBOX_HEADER_SIZE > slave->sii.tx_mailbox_size) {
|
||||
if (data_size + EC_MBOX_HEADER_SIZE > mailbox_size) {
|
||||
EC_ERR("Corrupt mailbox response received from slave %u!\n",
|
||||
slave->ring_position);
|
||||
ec_print_data(datagram->data, slave->sii.tx_mailbox_size);
|
||||
slave->ring_position);
|
||||
ec_print_data(datagram->data, mailbox_size);
|
||||
return ERR_PTR(-EPROTO);
|
||||
}
|
||||
|
||||
|
|
@ -185,9 +213,10 @@ uint8_t *ec_slave_mbox_fetch(const ec_slave_t *slave, /**< slave */
|
|||
slave->ring_position);
|
||||
|
||||
for (mbox_msg = mbox_error_messages; mbox_msg->code; mbox_msg++) {
|
||||
if (mbox_msg->code != code) continue;
|
||||
if (mbox_msg->code != code)
|
||||
continue;
|
||||
printk("Code 0x%04X: \"%s\".\n",
|
||||
mbox_msg->code, mbox_msg->message);
|
||||
mbox_msg->code, mbox_msg->message);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -358,8 +358,9 @@ void ec_print_data_diff(const uint8_t *d1, /**< first data */
|
|||
/** Prints slave states in clear text.
|
||||
*/
|
||||
size_t ec_state_string(uint8_t states, /**< slave states */
|
||||
char *buffer /**< target buffer
|
||||
char *buffer, /**< target buffer
|
||||
(min. EC_STATE_STRING_SIZE bytes) */
|
||||
uint8_t multi /**< Show multi-state mask. */
|
||||
)
|
||||
{
|
||||
off_t off = 0;
|
||||
|
|
@ -370,24 +371,42 @@ size_t ec_state_string(uint8_t states, /**< slave states */
|
|||
return off;
|
||||
}
|
||||
|
||||
if (states & EC_SLAVE_STATE_INIT) {
|
||||
off += sprintf(buffer + off, "INIT");
|
||||
if (multi) { // multiple slaves
|
||||
if (states & EC_SLAVE_STATE_INIT) {
|
||||
off += sprintf(buffer + off, "INIT");
|
||||
first = 0;
|
||||
}
|
||||
if (states & EC_SLAVE_STATE_PREOP) {
|
||||
if (!first) off += sprintf(buffer + off, ", ");
|
||||
off += sprintf(buffer + off, "PREOP");
|
||||
first = 0;
|
||||
}
|
||||
if (states & EC_SLAVE_STATE_SAFEOP) {
|
||||
if (!first) off += sprintf(buffer + off, ", ");
|
||||
off += sprintf(buffer + off, "SAFEOP");
|
||||
first = 0;
|
||||
}
|
||||
if (states & EC_SLAVE_STATE_OP) {
|
||||
if (!first) off += sprintf(buffer + off, ", ");
|
||||
off += sprintf(buffer + off, "OP");
|
||||
}
|
||||
} else { // single slave
|
||||
if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_INIT) {
|
||||
off += sprintf(buffer + off, "INIT");
|
||||
} else if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_PREOP) {
|
||||
off += sprintf(buffer + off, "PREOP");
|
||||
} else if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_BOOT) {
|
||||
off += sprintf(buffer + off, "BOOT");
|
||||
} else if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_SAFEOP) {
|
||||
off += sprintf(buffer + off, "SAFEOP");
|
||||
} else if ((states & EC_SLAVE_STATE_MASK) == EC_SLAVE_STATE_OP) {
|
||||
off += sprintf(buffer + off, "OP");
|
||||
} else {
|
||||
off += sprintf(buffer + off, "(invalid)");
|
||||
}
|
||||
first = 0;
|
||||
}
|
||||
if (states & EC_SLAVE_STATE_PREOP) {
|
||||
if (!first) off += sprintf(buffer + off, ", ");
|
||||
off += sprintf(buffer + off, "PREOP");
|
||||
first = 0;
|
||||
}
|
||||
if (states & EC_SLAVE_STATE_SAFEOP) {
|
||||
if (!first) off += sprintf(buffer + off, ", ");
|
||||
off += sprintf(buffer + off, "SAFEOP");
|
||||
first = 0;
|
||||
}
|
||||
if (states & EC_SLAVE_STATE_OP) {
|
||||
if (!first) off += sprintf(buffer + off, ", ");
|
||||
off += sprintf(buffer + off, "OP");
|
||||
}
|
||||
|
||||
if (states & EC_SLAVE_STATE_ACK_ERR) {
|
||||
if (!first) off += sprintf(buffer + off, " + ");
|
||||
off += sprintf(buffer + off, "ERROR");
|
||||
|
|
|
|||
|
|
@ -90,15 +90,19 @@ void ec_slave_init(
|
|||
slave->sii_words = NULL;
|
||||
slave->sii_nwords = 0;
|
||||
|
||||
slave->sii.alias = 0;
|
||||
slave->sii.vendor_id = 0;
|
||||
slave->sii.product_code = 0;
|
||||
slave->sii.revision_number = 0;
|
||||
slave->sii.serial_number = 0;
|
||||
slave->sii.rx_mailbox_offset = 0;
|
||||
slave->sii.rx_mailbox_size = 0;
|
||||
slave->sii.tx_mailbox_offset = 0;
|
||||
slave->sii.tx_mailbox_size = 0;
|
||||
slave->sii.alias = 0x0000;
|
||||
slave->sii.vendor_id = 0x00000000;
|
||||
slave->sii.product_code = 0x00000000;
|
||||
slave->sii.revision_number = 0x00000000;
|
||||
slave->sii.serial_number = 0x00000000;
|
||||
slave->sii.boot_rx_mailbox_offset = 0x0000;
|
||||
slave->sii.boot_rx_mailbox_size = 0x0000;
|
||||
slave->sii.boot_tx_mailbox_offset = 0x0000;
|
||||
slave->sii.boot_tx_mailbox_size = 0x0000;
|
||||
slave->sii.std_rx_mailbox_offset = 0x0000;
|
||||
slave->sii.std_rx_mailbox_size = 0x0000;
|
||||
slave->sii.std_tx_mailbox_offset = 0x0000;
|
||||
slave->sii.std_tx_mailbox_size = 0x0000;
|
||||
slave->sii.mailbox_protocols = 0;
|
||||
|
||||
slave->sii.strings = NULL;
|
||||
|
|
@ -199,8 +203,8 @@ void ec_slave_set_state(ec_slave_t *slave, /**< EtherCAT slave */
|
|||
if (slave->master->debug_level) {
|
||||
char old_state[EC_STATE_STRING_SIZE],
|
||||
cur_state[EC_STATE_STRING_SIZE];
|
||||
ec_state_string(slave->current_state, old_state);
|
||||
ec_state_string(new_state, cur_state);
|
||||
ec_state_string(slave->current_state, old_state, 0);
|
||||
ec_state_string(new_state, cur_state, 0);
|
||||
EC_DBG("Slave %u: %s -> %s.\n",
|
||||
slave->ring_position, old_state, cur_state);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,10 +54,14 @@ typedef struct {
|
|||
uint32_t product_code; /**< Vendor-specific product code. */
|
||||
uint32_t revision_number; /**< Revision number. */
|
||||
uint32_t serial_number; /**< Serial number. */
|
||||
uint16_t rx_mailbox_offset; /**< Mailbox address (master to slave). */
|
||||
uint16_t rx_mailbox_size; /**< Mailbox size (master to slave). */
|
||||
uint16_t tx_mailbox_offset; /**< Mailbox address (slave to master). */
|
||||
uint16_t tx_mailbox_size; /**< Mailbox size (slave to master). */
|
||||
uint16_t boot_rx_mailbox_offset; /**< Bootstrap receive mailbox address. */
|
||||
uint16_t boot_rx_mailbox_size; /**< Bootstrap receive mailbox size. */
|
||||
uint16_t boot_tx_mailbox_offset; /**< Bootstrap transmit mailbox address. */
|
||||
uint16_t boot_tx_mailbox_size; /**< Bootstrap transmit mailbox size. */
|
||||
uint16_t std_rx_mailbox_offset; /**< Standard receive mailbox address. */
|
||||
uint16_t std_rx_mailbox_size; /**< Standard receive mailbox size. */
|
||||
uint16_t std_tx_mailbox_offset; /**< Standard transmit mailbox address. */
|
||||
uint16_t std_tx_mailbox_size; /**< Standard transmit mailbox size. */
|
||||
uint16_t mailbox_protocols; /**< Supported mailbox protocols. */
|
||||
|
||||
// Strings
|
||||
|
|
|
|||
|
|
@ -284,6 +284,7 @@ string Command::alStateString(uint8_t state)
|
|||
switch (state) {
|
||||
case 1: return "INIT";
|
||||
case 2: return "PREOP";
|
||||
case 3: return "BOOT";
|
||||
case 4: return "SAFEOP";
|
||||
case 8: return "OP";
|
||||
default: return "???";
|
||||
|
|
|
|||
|
|
@ -216,12 +216,18 @@ void CommandSlaves::showSlaves(
|
|||
list<string>::const_iterator protoIter;
|
||||
|
||||
cout << "Mailboxes:" << endl
|
||||
<< " RX: 0x"
|
||||
<< hex << setw(4) << si->rx_mailbox_offset << "/"
|
||||
<< dec << si->rx_mailbox_size
|
||||
<< " Bootstrap RX: 0x"
|
||||
<< hex << setw(4) << si->boot_rx_mailbox_offset << "/"
|
||||
<< dec << si->boot_rx_mailbox_size
|
||||
<< ", TX: 0x"
|
||||
<< hex << setw(4) << si->tx_mailbox_offset << "/"
|
||||
<< dec << si->tx_mailbox_size << endl
|
||||
<< hex << setw(4) << si->boot_tx_mailbox_offset << "/"
|
||||
<< dec << si->boot_tx_mailbox_size << endl
|
||||
<< " Standard RX: 0x"
|
||||
<< hex << setw(4) << si->std_rx_mailbox_offset << "/"
|
||||
<< dec << si->std_rx_mailbox_size
|
||||
<< ", TX: 0x"
|
||||
<< hex << setw(4) << si->std_tx_mailbox_offset << "/"
|
||||
<< dec << si->std_tx_mailbox_size << endl
|
||||
<< " Supported protocols: ";
|
||||
|
||||
if (si->mailbox_protocols & EC_MBOX_AOE) {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ string CommandStates::helpString() const
|
|||
<< getBriefDescription() << endl
|
||||
<< endl
|
||||
<< "Arguments:" << endl
|
||||
<< " STATE can be 'INIT', 'PREOP', 'SAFEOP', or 'OP'." << endl
|
||||
<< " STATE can be 'INIT', 'PREOP', 'BOOT', 'SAFEOP', or 'OP'." << endl
|
||||
<< endl
|
||||
<< "Command-specific options:" << endl
|
||||
<< " --alias -a <alias>" << endl
|
||||
|
|
@ -63,6 +63,8 @@ void CommandStates::execute(MasterDevice &m, const StringVector &args)
|
|||
state = 0x01;
|
||||
} else if (stateStr == "PREOP") {
|
||||
state = 0x02;
|
||||
} else if (stateStr == "BOOT") {
|
||||
state = 0x03;
|
||||
} else if (stateStr == "SAFEOP") {
|
||||
state = 0x04;
|
||||
} else if (stateStr == "OP") {
|
||||
|
|
|
|||
Loading…
Reference in New Issue