diff --git a/master/fsm_coe.c b/master/fsm_coe.c index 9e5feaf1..21f3ce23 100644 --- a/master/fsm_coe.c +++ b/master/fsm_coe.c @@ -1024,6 +1024,7 @@ void ec_fsm_coe_down_start(ec_fsm_coe_t *fsm /**< finite state machine */) ec_print_data(data, 10 + request->data_size); } + fsm->request->jiffies_sent = jiffies; fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_down_request; } @@ -1052,6 +1053,19 @@ void ec_fsm_coe_down_request(ec_fsm_coe_t *fsm /**< finite state machine */) } if (datagram->working_counter != 1) { + if (!datagram->working_counter) { + unsigned long diff_ms = + (jiffies - fsm->request->jiffies_sent) * 1000 / HZ; + if (diff_ms < fsm->request->response_timeout) { + if (fsm->slave->master->debug_level) { + EC_DBG("Slave %u did no respond to Sdo download request. " + "Retrying after %u ms...\n", + slave->ring_position, (u32) diff_ms); + // no response; send request datagram again + return; + } + } + } fsm->state = ec_fsm_coe_error; EC_ERR("Reception of CoE download request failed on slave %u: ", slave->ring_position); @@ -1253,6 +1267,7 @@ void ec_fsm_coe_up_start(ec_fsm_coe_t *fsm /**< finite state machine */) ec_print_data(data, 10); } + fsm->request->jiffies_sent = jiffies; fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_up_request; } @@ -1281,6 +1296,19 @@ void ec_fsm_coe_up_request(ec_fsm_coe_t *fsm /**< finite state machine */) } if (datagram->working_counter != 1) { + if (!datagram->working_counter) { + unsigned long diff_ms = + (jiffies - fsm->request->jiffies_sent) * 1000 / HZ; + if (diff_ms < fsm->request->response_timeout) { + if (fsm->slave->master->debug_level) { + EC_DBG("Slave %u did no respond to Sdo upload request. " + "Retrying after %u ms...\n", + slave->ring_position, (u32) diff_ms); + // no response; send request datagram again + return; + } + } + } fsm->state = ec_fsm_coe_error; EC_ERR("Reception of CoE upload request failed on slave %u: ", slave->ring_position); diff --git a/master/fsm_coe_map.c b/master/fsm_coe_map.c index ba3fed2a..3a46020a 100644 --- a/master/fsm_coe_map.c +++ b/master/fsm_coe_map.c @@ -44,10 +44,6 @@ #include "sdo_request.h" #include "fsm_coe_map.h" -/** Retry reading the number of assigned Pdos if this time is not elapsed. - */ -#define EC_FSM_COE_MAP_TIMEOUT 5 - /*****************************************************************************/ void ec_fsm_coe_map_state_start(ec_fsm_coe_map_t *); @@ -186,8 +182,8 @@ void ec_fsm_coe_map_action_next_dir( ec_pdo_list_clear_pdos(&fsm->pdos); ec_sdo_request_address(&fsm->request, fsm->sync_sdo_index, 0); + fsm->request.response_timeout = 10000; ecrt_sdo_request_read(&fsm->request); - fsm->jiffies_start = jiffies; fsm->state = ec_fsm_coe_map_state_pdo_count; ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately @@ -214,15 +210,6 @@ void ec_fsm_coe_map_state_pdo_count( if (ec_fsm_coe_exec(fsm->fsm_coe)) return; if (!ec_fsm_coe_success(fsm->fsm_coe)) { - if (jiffies - fsm->jiffies_start < HZ * EC_FSM_COE_MAP_TIMEOUT) { - if (fsm->slave->master->debug_level) - EC_DBG("Failed to read number of assigned Pdos from " - "slave %u. Retrying...\n", fsm->slave->ring_position); - ecrt_sdo_request_read(&fsm->request); - ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); - ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately - return; - } EC_ERR("Failed to read number of assigned Pdos from slave %u.\n", fsm->slave->ring_position); fsm->state = ec_fsm_coe_map_state_error; @@ -252,6 +239,7 @@ void ec_fsm_coe_map_action_next_pdo( if (fsm->sync_subindex <= fsm->sync_subindices) { ec_sdo_request_address(&fsm->request, fsm->sync_sdo_index, fsm->sync_subindex); + fsm->request.response_timeout = 0; ecrt_sdo_request_read(&fsm->request); fsm->state = ec_fsm_coe_map_state_pdo; ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); @@ -309,6 +297,7 @@ void ec_fsm_coe_map_state_pdo( list_add_tail(&fsm->pdo->list, &fsm->pdos.list); ec_sdo_request_address(&fsm->request, fsm->pdo->index, 0); + fsm->request.response_timeout = 0; ecrt_sdo_request_read(&fsm->request); fsm->state = ec_fsm_coe_map_state_pdo_entry_count; ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); @@ -356,6 +345,7 @@ void ec_fsm_coe_map_action_next_pdo_entry( { if (fsm->pdo_subindex <= fsm->pdo_subindices) { ec_sdo_request_address(&fsm->request, fsm->pdo->index, fsm->pdo_subindex); + fsm->request.response_timeout = 0; ecrt_sdo_request_read(&fsm->request); fsm->state = ec_fsm_coe_map_state_pdo_entry; ec_fsm_coe_transfer(fsm->fsm_coe, fsm->slave, &fsm->request); diff --git a/master/fsm_coe_map.h b/master/fsm_coe_map.h index fb71b879..297fec02 100644 --- a/master/fsm_coe_map.h +++ b/master/fsm_coe_map.h @@ -72,8 +72,6 @@ struct ec_fsm_coe_map ec_sdo_t *pdo_sdo; /**< Current Pdo Sdo. */ uint8_t pdo_subindices; /**< Number of Pdo entries. */ uint16_t pdo_subindex; /**< Current subindex in Pdo Sdo. */ - - unsigned long jiffies_start; /**< Timestamp. */ }; /*****************************************************************************/ diff --git a/master/sdo_request.c b/master/sdo_request.c index 0e4e8d2d..df2b81b2 100644 --- a/master/sdo_request.c +++ b/master/sdo_request.c @@ -70,7 +70,8 @@ void ec_sdo_request_init( req->mem_size = 0; req->data_size = 0; req->dir = EC_DIR_OUTPUT; - req->timeout = 0; // no timeout + req->issue_timeout = 0; // no timeout + req->response_timeout = 0; // immediate response required req->state = EC_REQUEST_INIT; } @@ -170,8 +171,8 @@ int ec_sdo_request_copy_data( */ int ec_sdo_request_timed_out(const ec_sdo_request_t *req /**< Sdo request. */) { - return req->timeout - && jiffies - req->start_jiffies > HZ * req->timeout / 1000; + return req->issue_timeout + && jiffies - req->jiffies_start > HZ * req->issue_timeout / 1000; } /***************************************************************************** @@ -180,7 +181,7 @@ int ec_sdo_request_timed_out(const ec_sdo_request_t *req /**< Sdo request. */) void ecrt_sdo_request_timeout(ec_sdo_request_t *req, uint32_t timeout) { - req->timeout = timeout; + req->issue_timeout = timeout; } /*****************************************************************************/ @@ -210,7 +211,7 @@ void ecrt_sdo_request_read(ec_sdo_request_t *req) { req->dir = EC_DIR_INPUT; req->state = EC_REQUEST_QUEUED; - req->start_jiffies = jiffies; + req->jiffies_start = jiffies; } /*****************************************************************************/ @@ -219,7 +220,7 @@ void ecrt_sdo_request_write(ec_sdo_request_t *req) { req->dir = EC_DIR_OUTPUT; req->state = EC_REQUEST_QUEUED; - req->start_jiffies = jiffies; + req->jiffies_start = jiffies; } /*****************************************************************************/ diff --git a/master/sdo_request.h b/master/sdo_request.h index 688a04a3..fcf2029b 100644 --- a/master/sdo_request.h +++ b/master/sdo_request.h @@ -58,12 +58,17 @@ struct ec_sdo_request { uint8_t *data; /**< Pointer to Sdo data. */ size_t mem_size; /**< Size of Sdo data memory. */ size_t data_size; /**< Size of Sdo data. */ - uint32_t timeout; /**< Timeout in ms. */ + uint32_t issue_timeout; /**< Maximum time in ms, the processing of the + request may take. */ + uint32_t response_timeout; /**< Maximum time in ms, the transfer is + retried, if the slave does not respond. */ ec_direction_t dir; /**< Direction. EC_DIR_OUTPUT means downloading to the slave, EC_DIR_INPUT means uploading from the slave. */ ec_request_state_t state; /**< Sdo request state. */ - unsigned long start_jiffies; /**< Jiffies, when the request was issued. */ + unsigned long jiffies_start; /**< Jiffies, when the request was issued. */ + unsigned long jiffies_sent; /**< Jiffies, when the upload/download + request was sent. */ }; /*****************************************************************************/