Implemented going to bootstrap state BOOT.
--- a/NEWS Mon Jan 19 12:36:18 2009 +0000
+++ b/NEWS Mon Jan 19 14:46:55 2009 +0000
@@ -6,6 +6,12 @@
-------------------------------------------------------------------------------
+Changes since 1.4.0:
+
+* 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 version 1.4.0:
* Fixed race condition in jiffy-based frame timeout calculation.
--- a/master/cdev.c Mon Jan 19 12:36:18 2009 +0000
+++ b/master/cdev.c Mon Jan 19 14:46:55 2009 +0000
@@ -188,10 +188,14 @@
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;
--- a/master/ethernet.c Mon Jan 19 12:36:18 2009 +0000
+++ b/master/ethernet.c Mon Jan 19 14:46:55 2009 +0000
@@ -217,6 +217,7 @@
/**
Sends a frame or the next fragment.
+ \todo bootstrap mailboxes / use configured mailbox sizes
*/
int ec_eoe_send(ec_eoe_t *eoe /**< EoE handler */)
@@ -230,12 +231,11 @@
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;
}
--- a/master/fsm_change.c Mon Jan 19 12:36:18 2009 +0000
+++ b/master/fsm_change.c Mon Jan 19 14:46:55 2009 +0000
@@ -187,7 +187,7 @@
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 @@
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);
@@ -246,7 +246,7 @@
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);
@@ -270,7 +270,7 @@
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
@@ -286,7 +286,7 @@
// 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);
@@ -302,7 +302,7 @@
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);
@@ -323,7 +323,7 @@
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"},
@@ -494,7 +494,7 @@
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;
}
@@ -509,7 +509,7 @@
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);
--- a/master/fsm_coe.c Mon Jan 19 12:36:18 2009 +0000
+++ b/master/fsm_coe.c Mon Jan 19 14:46:55 2009 +0000
@@ -1089,7 +1089,7 @@
}
}
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;
--- a/master/fsm_foe.c Mon Jan 19 12:36:18 2009 +0000
+++ b/master/fsm_foe.c Mon Jan 19 14:46:55 2009 +0000
@@ -214,12 +214,13 @@
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 @@
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 @@
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;
--- a/master/fsm_master.c Mon Jan 19 12:36:18 2009 +0000
+++ b/master/fsm_master.c Mon Jan 19 14:46:55 2009 +0000
@@ -199,7 +199,7 @@
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 {
@@ -560,8 +560,8 @@
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)" : "");
--- a/master/fsm_slave_config.c Mon Jan 19 12:36:18 2009 +0000
+++ b/master/fsm_slave_config.c Mon Jan 19 14:46:55 2009 +0000
@@ -43,7 +43,7 @@
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_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 @@
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 @@
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);
memset(datagram->data, 0x00,
@@ -323,18 +345,18 @@
memset(datagram->data, 0x00, EC_SYNC_PAGE_SIZE * 2);
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);
}
@@ -374,27 +396,33 @@
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(
- 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);
+void ec_fsm_slave_config_enter_boot_preop(
+ ec_fsm_slave_config_t *fsm /**< slave state machine */
+ )
+{
+ 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.
- */
-void ec_fsm_slave_config_state_preop(
+/** Slave configuration state: BOOT/PREOP.
+ */
+void ec_fsm_slave_config_state_boot_preop(
ec_fsm_slave_config_t *fsm /**< slave state machine */
)
{
@@ -410,11 +438,13 @@
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) {
--- a/master/fsm_slave_scan.c Mon Jan 19 12:36:18 2009 +0000
+++ b/master/fsm_slave_scan.c Mon Jan 19 14:46:55 2009 +0000
@@ -236,7 +236,7 @@
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);
}
@@ -466,13 +466,21 @@
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);
--- a/master/globals.h Mon Jan 19 12:36:18 2009 +0000
+++ b/master/globals.h Mon Jan 19 14:46:55 2009 +0000
@@ -111,6 +111,8 @@
/**< 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,
@@ -222,7 +224,7 @@
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 *);
--- a/master/ioctl.h Mon Jan 19 12:36:18 2009 +0000
+++ b/master/ioctl.h Mon Jan 19 14:46:55 2009 +0000
@@ -101,10 +101,14 @@
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;
--- a/master/mailbox.c Mon Jan 19 12:36:18 2009 +0000
+++ b/master/mailbox.c Mon Jan 19 14:46:55 2009 +0000
@@ -52,6 +52,7 @@
)
{
size_t total_size;
+ uint16_t mailbox_offset, mailbox_size;
if (unlikely(!slave->sii.mailbox_protocols)) {
EC_ERR("Slave %u does not support mailbox communication!\n",
@@ -60,14 +61,22 @@
}
total_size = size + 6;
- 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 NULL;
}
if (ec_datagram_fpwr(datagram, slave->station_address,
- slave->sii.rx_mailbox_offset,
- slave->sii.rx_mailbox_size))
+ mailbox_offset, mailbox_size))
return NULL;
EC_WRITE_U16(datagram->data, size); // mailbox service data length
@@ -119,9 +128,20 @@
ec_datagram_t *datagram /**< datagram */
)
{
+ 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;
+ }
+
if (ec_datagram_fprd(datagram, slave->station_address,
- slave->sii.tx_mailbox_offset,
- slave->sii.tx_mailbox_size)) return -1;
+ mailbox_offset, mailbox_size))
+ return -1;
+
return 0;
}
@@ -157,13 +177,22 @@
)
{
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 > slave->sii.tx_mailbox_size - 6) {
+ if (data_size > mailbox_size - 6) {
EC_ERR("Corrupt mailbox response received from slave %u!\n",
slave->ring_position);
- ec_print_data(datagram->data, slave->sii.tx_mailbox_size);
+ ec_print_data(datagram->data, mailbox_size);
return NULL;
}
@@ -172,15 +201,16 @@
if (*type == 0x00) {
const ec_code_msg_t *mbox_msg;
- uint16_t code = EC_READ_U16(datagram->data + 8);
+ uint16_t code = EC_READ_U16(datagram->data + 8);
EC_ERR("Mailbox error response received from slave %u - ",
- slave->ring_position);
-
- for (mbox_msg = mbox_error_messages; mbox_msg->code; mbox_msg++) {
- if (mbox_msg->code != code) continue;
+ slave->ring_position);
+
+ for (mbox_msg = mbox_error_messages; mbox_msg->code; mbox_msg++) {
+ 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;
}
--- a/master/module.c Mon Jan 19 12:36:18 2009 +0000
+++ b/master/module.c Mon Jan 19 14:46:55 2009 +0000
@@ -357,8 +357,9 @@
/** 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;
@@ -369,24 +370,42 @@
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");
--- a/master/slave.c Mon Jan 19 12:36:18 2009 +0000
+++ b/master/slave.c Mon Jan 19 14:46:55 2009 +0000
@@ -90,15 +90,19 @@
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 @@
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);
}
--- a/master/slave.h Mon Jan 19 12:36:18 2009 +0000
+++ b/master/slave.h Mon Jan 19 14:46:55 2009 +0000
@@ -56,10 +56,14 @@
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
--- a/tool/Command.cpp Mon Jan 19 12:36:18 2009 +0000
+++ b/tool/Command.cpp Mon Jan 19 14:46:55 2009 +0000
@@ -284,6 +284,7 @@
switch (state) {
case 1: return "INIT";
case 2: return "PREOP";
+ case 3: return "BOOT";
case 4: return "SAFEOP";
case 8: return "OP";
default: return "???";
--- a/tool/CommandSlaves.cpp Mon Jan 19 12:36:18 2009 +0000
+++ b/tool/CommandSlaves.cpp Mon Jan 19 14:46:55 2009 +0000
@@ -216,12 +216,18 @@
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) {
--- a/tool/CommandStates.cpp Mon Jan 19 12:36:18 2009 +0000
+++ b/tool/CommandStates.cpp Mon Jan 19 14:46:55 2009 +0000
@@ -28,7 +28,7 @@
<< 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 @@
state = 0x01;
} else if (stateStr == "PREOP") {
state = 0x02;
+ } else if (stateStr == "BOOT") {
+ state = 0x03;
} else if (stateStr == "SAFEOP") {
state = 0x04;
} else if (stateStr == "OP") {