# HG changeset patch # User Florian Pose # Date 1232376415 0 # Node ID 63e4bc91864052e18e661a77a24257f2652c41eb # Parent fae3a1759126ef91b0fe038f615fe37bab95b005 Implemented going to bootstrap state BOOT. diff -r fae3a1759126 -r 63e4bc918640 NEWS --- 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. diff -r fae3a1759126 -r 63e4bc918640 master/cdev.c --- 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; diff -r fae3a1759126 -r 63e4bc918640 master/ethernet.c --- 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; } diff -r fae3a1759126 -r 63e4bc918640 master/fsm_change.c --- 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); diff -r fae3a1759126 -r 63e4bc918640 master/fsm_coe.c --- 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; diff -r fae3a1759126 -r 63e4bc918640 master/fsm_foe.c --- 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; diff -r fae3a1759126 -r 63e4bc918640 master/fsm_master.c --- 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)" : ""); diff -r fae3a1759126 -r 63e4bc918640 master/fsm_slave_config.c --- 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) { diff -r fae3a1759126 -r 63e4bc918640 master/fsm_slave_scan.c --- 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); diff -r fae3a1759126 -r 63e4bc918640 master/globals.h --- 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 *); diff -r fae3a1759126 -r 63e4bc918640 master/ioctl.h --- 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; diff -r fae3a1759126 -r 63e4bc918640 master/mailbox.c --- 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; } diff -r fae3a1759126 -r 63e4bc918640 master/module.c --- 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"); diff -r fae3a1759126 -r 63e4bc918640 master/slave.c --- 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); } diff -r fae3a1759126 -r 63e4bc918640 master/slave.h --- 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 diff -r fae3a1759126 -r 63e4bc918640 tool/Command.cpp --- 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 "???"; diff -r fae3a1759126 -r 63e4bc918640 tool/CommandSlaves.cpp --- 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::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) { diff -r fae3a1759126 -r 63e4bc918640 tool/CommandStates.cpp --- 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 " << 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") {