diff -r 473ec2246ec1 -r fbbd4e54e031 master/fsm_master.c --- a/master/fsm_master.c Fri Mar 09 14:00:32 2007 +0000 +++ b/master/fsm_master.c Fri Mar 09 15:11:29 2007 +0000 @@ -316,6 +316,63 @@ /*****************************************************************************/ /** + * Check for pending SDO requests and process one. + * \return non-zero, if an SDO request is processed. + */ + +int ec_fsm_master_action_process_sdo( + ec_fsm_master_t *fsm /**< master state machine */ + ) +{ + ec_master_t *master = fsm->master; + ec_sdo_request_t *request; + ec_slave_t *slave; + + // search the first request to be processed + while (1) { + down(&master->sdo_sem); + if (list_empty(&master->sdo_requests)) { + up(&master->sdo_sem); + break; + } + // get first request + request = + list_entry(master->sdo_requests.next, ec_sdo_request_t, list); + list_del_init(&request->list); // dequeue + request->state = EC_REQ_BUSY; + up(&master->sdo_sem); + + slave = request->sdo->slave; + if (slave->current_state == EC_SLAVE_STATE_INIT || + slave->online_state == EC_SLAVE_OFFLINE || + slave->error_flag) { + EC_ERR("Discarding SDO request, slave %i not ready.\n", + slave->ring_position); + request->state = EC_REQ_ERROR; + wake_up(&master->sdo_queue); + continue; + } + + // found pending SDO request. execute it! + if (master->debug_level) + EC_DBG("Processing SDO request for slave %i...\n", + slave->ring_position); + + // start uploading SDO + fsm->slave = slave; + fsm->sdo_request = request; + fsm->state = ec_fsm_master_state_sdo_request; + ec_fsm_coe_upload(&fsm->fsm_coe, slave, fsm->sdo_request); + ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately + return 1; + } + + return 0; +} + +/*****************************************************************************/ + +/** Master action: PROC_STATES. Processes the slave states. */ @@ -359,31 +416,12 @@ // Check, if EoE processing has to be started ec_master_eoe_start(master); + // Check for a pending SDO request + if (ec_fsm_master_action_process_sdo(fsm)) + return; + if (master->mode == EC_MASTER_MODE_IDLE) { - // Check for a pending SDO request - if (master->sdo_seq_master != master->sdo_seq_user) { - if (master->debug_level) - EC_DBG("Processing SDO request...\n"); - slave = master->sdo_request->sdo->slave; - if (slave->current_state == EC_SLAVE_STATE_INIT - || slave->online_state == EC_SLAVE_OFFLINE) { - EC_ERR("Failed to process SDO request, slave %i not ready.\n", - slave->ring_position); - master->sdo_request->return_code = -1; - master->sdo_seq_master++; - } - else { - // start uploading SDO - fsm->slave = slave; - fsm->sdo_request = master->sdo_request; - fsm->state = ec_fsm_master_state_sdo_request; - ec_fsm_coe_upload(&fsm->fsm_coe, slave, fsm->sdo_request); - ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately - return; - } - } - // check, if slaves have an SDO dictionary to read out. list_for_each_entry(slave, &master->slaves, list) { if (!(slave->sii_mailbox_protocols & EC_MBOX_COE) @@ -827,16 +865,25 @@ if (ec_fsm_coe_exec(&fsm->fsm_coe)) return; if (!ec_fsm_coe_success(&fsm->fsm_coe)) { - request->return_code = -1; - master->sdo_seq_master++; - fsm->state = ec_fsm_master_state_error; - return; - } - - // SDO dictionary fetching finished - - request->return_code = 1; - master->sdo_seq_master++; + EC_DBG("Failed to process SDO request for slave %i.\n", + fsm->slave->ring_position); + request->state = EC_REQ_ERROR; + wake_up(&master->sdo_queue); + fsm->state = ec_fsm_master_state_error; + return; + } + + // SDO request finished + request->state = EC_REQ_COMPLETED; + wake_up(&master->sdo_queue); + + if (master->debug_level) + EC_DBG("Finished SDO request for slave %i.\n", + fsm->slave->ring_position); + + // check for another SDO request + if (ec_fsm_master_action_process_sdo(fsm)) + return; // processing another request fsm->state = ec_fsm_master_state_end; }