master/fsm_master.c
changeset 610 29489a43ecee
parent 607 7b1daa325c5f
child 612 aede068f9a74
equal deleted inserted replaced
609:611d738a1392 610:29489a43ecee
   183 
   183 
   184     if (datagram->state != EC_DATAGRAM_RECEIVED) { // EC_DATAGRAM_ERROR
   184     if (datagram->state != EC_DATAGRAM_RECEIVED) { // EC_DATAGRAM_ERROR
   185         // link is down
   185         // link is down
   186         fsm->slaves_responding = 0;
   186         fsm->slaves_responding = 0;
   187         list_for_each_entry(slave, &master->slaves, list) {
   187         list_for_each_entry(slave, &master->slaves, list) {
   188             slave->online = 0;
   188             ec_slave_set_online_state(slave, EC_SLAVE_OFFLINE);
   189         }
   189         }
   190         fsm->state = ec_fsm_master_state_error;
   190         fsm->state = ec_fsm_master_state_error;
   191         return;
   191         return;
   192     }
   192     }
   193 
   193 
   300         list_del_init(&request->list); // dequeue
   300         list_del_init(&request->list); // dequeue
   301         request->state = EC_EEPROM_REQ_BUSY;
   301         request->state = EC_EEPROM_REQ_BUSY;
   302         up(&master->eeprom_sem);
   302         up(&master->eeprom_sem);
   303 
   303 
   304         slave = request->slave;
   304         slave = request->slave;
   305         if (!slave->online || slave->error_flag) {
   305         if (slave->online_state == EC_SLAVE_OFFLINE || slave->error_flag) {
   306             EC_ERR("Discarding EEPROM data, slave %i not ready.\n",
   306             EC_ERR("Discarding EEPROM data, slave %i not ready.\n",
   307                     slave->ring_position);
   307                     slave->ring_position);
   308             request->state = EC_EEPROM_REQ_ERROR;
   308             request->state = EC_EEPROM_REQ_ERROR;
   309             wake_up(&master->eeprom_queue);
   309             wake_up(&master->eeprom_queue);
   310             continue;
   310             continue;
   342     char old_state[EC_STATE_STRING_SIZE], new_state[EC_STATE_STRING_SIZE];
   342     char old_state[EC_STATE_STRING_SIZE], new_state[EC_STATE_STRING_SIZE];
   343 
   343 
   344     // check if any slaves are not in the state, they're supposed to be
   344     // check if any slaves are not in the state, they're supposed to be
   345     list_for_each_entry(slave, &master->slaves, list) {
   345     list_for_each_entry(slave, &master->slaves, list) {
   346         if (slave->error_flag
   346         if (slave->error_flag
   347             || !slave->online
   347             || slave->online_state == EC_SLAVE_OFFLINE
   348             || slave->requested_state == EC_SLAVE_STATE_UNKNOWN
   348             || slave->requested_state == EC_SLAVE_STATE_UNKNOWN
   349             || (slave->current_state == slave->requested_state
   349             || (slave->current_state == slave->requested_state
   350                 && slave->self_configured)) continue;
   350                 && slave->self_configured)) continue;
   351 
   351 
   352         if (master->debug_level) {
   352         if (master->debug_level) {
   378         if (master->sdo_seq_master != master->sdo_seq_user) {
   378         if (master->sdo_seq_master != master->sdo_seq_user) {
   379             if (master->debug_level)
   379             if (master->debug_level)
   380                 EC_DBG("Processing SDO request...\n");
   380                 EC_DBG("Processing SDO request...\n");
   381             slave = master->sdo_request->sdo->slave;
   381             slave = master->sdo_request->sdo->slave;
   382             if (slave->current_state == EC_SLAVE_STATE_INIT
   382             if (slave->current_state == EC_SLAVE_STATE_INIT
   383                 || !slave->online) {
   383                 || slave->online_state == EC_SLAVE_OFFLINE) {
   384                 EC_ERR("Failed to process SDO request, slave %i not ready.\n",
   384                 EC_ERR("Failed to process SDO request, slave %i not ready.\n",
   385                        slave->ring_position);
   385                        slave->ring_position);
   386                 master->sdo_request->return_code = -1;
   386                 master->sdo_request->return_code = -1;
   387                 master->sdo_seq_master++;
   387                 master->sdo_seq_master++;
   388             }
   388             }
   401         list_for_each_entry(slave, &master->slaves, list) {
   401         list_for_each_entry(slave, &master->slaves, list) {
   402             if (!(slave->sii_mailbox_protocols & EC_MBOX_COE)
   402             if (!(slave->sii_mailbox_protocols & EC_MBOX_COE)
   403                 || slave->sdo_dictionary_fetched
   403                 || slave->sdo_dictionary_fetched
   404                 || slave->current_state == EC_SLAVE_STATE_INIT
   404                 || slave->current_state == EC_SLAVE_STATE_INIT
   405                 || jiffies - slave->jiffies_preop < EC_WAIT_SDO_DICT * HZ
   405                 || jiffies - slave->jiffies_preop < EC_WAIT_SDO_DICT * HZ
   406                 || !slave->online
   406                 || slave->online_state == EC_SLAVE_OFFLINE
   407                 || slave->error_flag) continue;
   407                 || slave->error_flag) continue;
   408 
   408 
   409             if (master->debug_level) {
   409             if (master->debug_level) {
   410                 EC_DBG("Fetching SDO dictionary from slave %i.\n",
   410                 EC_DBG("Fetching SDO dictionary from slave %i.\n",
   411                        slave->ring_position);
   411                        slave->ring_position);
   457 
   457 
   458     // check, if a bus validation has to be done
   458     // check, if a bus validation has to be done
   459     if (fsm->validate) {
   459     if (fsm->validate) {
   460         fsm->validate = 0;
   460         fsm->validate = 0;
   461         list_for_each_entry(slave, &master->slaves, list) {
   461         list_for_each_entry(slave, &master->slaves, list) {
   462             if (slave->online) continue;
   462             if (slave->online_state == EC_SLAVE_ONLINE) continue;
   463 
   463 
   464             // At least one slave is offline. validate!
   464             // At least one slave is offline. validate!
   465             EC_INFO("Validating bus.\n");
   465             EC_INFO("Validating bus.\n");
   466             fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
   466             fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
   467             fsm->state = ec_fsm_master_state_validate_vendor;
   467             fsm->state = ec_fsm_master_state_validate_vendor;
   483 
   483 
   484 void ec_fsm_master_state_read_states(ec_fsm_master_t *fsm /**< master state machine */)
   484 void ec_fsm_master_state_read_states(ec_fsm_master_t *fsm /**< master state machine */)
   485 {
   485 {
   486     ec_slave_t *slave = fsm->slave;
   486     ec_slave_t *slave = fsm->slave;
   487     ec_datagram_t *datagram = fsm->datagram;
   487     ec_datagram_t *datagram = fsm->datagram;
   488     uint8_t new_state;
       
   489 
   488 
   490     if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
   489     if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
   491         ec_master_queue_datagram(fsm->master, fsm->datagram);
   490         ec_master_queue_datagram(fsm->master, fsm->datagram);
   492         return;
   491         return;
   493     }
   492     }
   499         return;
   498         return;
   500     }
   499     }
   501 
   500 
   502     // did the slave not respond to its station address?
   501     // did the slave not respond to its station address?
   503     if (datagram->working_counter != 1) {
   502     if (datagram->working_counter != 1) {
   504         if (slave->online) {
   503         ec_slave_set_online_state(slave, EC_SLAVE_OFFLINE);
   505             slave->online = 0;
       
   506             if (slave->master->debug_level)
       
   507                 EC_DBG("Slave %i: offline.\n", slave->ring_position);
       
   508         }
       
   509         ec_fsm_master_action_next_slave_state(fsm);
   504         ec_fsm_master_action_next_slave_state(fsm);
   510         return;
   505         return;
   511     }
   506     }
   512 
   507 
   513     // slave responded
   508     // slave responded
   514     new_state = EC_READ_U8(datagram->data);
   509     ec_slave_set_state(slave, EC_READ_U8(datagram->data)); // set app state first
   515     if (!slave->online) { // slave was offline before
   510     ec_slave_set_online_state(slave, EC_SLAVE_ONLINE);
   516         slave->online = 1;
       
   517         slave->error_flag = 0; // clear error flag
       
   518         slave->current_state = new_state;
       
   519         if (slave->master->debug_level) {
       
   520             char cur_state[EC_STATE_STRING_SIZE];
       
   521             ec_state_string(slave->current_state, cur_state);
       
   522             EC_DBG("Slave %i: online (%s).\n",
       
   523                    slave->ring_position, cur_state);
       
   524         }
       
   525     }
       
   526     else if (new_state != slave->current_state) {
       
   527         if (slave->master->debug_level) {
       
   528             char old_state[EC_STATE_STRING_SIZE],
       
   529                 cur_state[EC_STATE_STRING_SIZE];
       
   530             ec_state_string(slave->current_state, old_state);
       
   531             ec_state_string(new_state, cur_state);
       
   532             EC_DBG("Slave %i: %s -> %s.\n",
       
   533                    slave->ring_position, old_state, cur_state);
       
   534         }
       
   535         slave->current_state = new_state;
       
   536     }
       
   537 
   511 
   538     // check, if new slave state has to be acknowledged
   512     // check, if new slave state has to be acknowledged
   539     if (slave->current_state & EC_SLAVE_STATE_ACK_ERR && !slave->error_flag) {
   513     if (slave->current_state & EC_SLAVE_STATE_ACK_ERR && !slave->error_flag) {
   540         ec_fsm_change_ack(&fsm->fsm_change, slave);
   514         ec_fsm_change_ack(&fsm->fsm_change, slave);
   541         ec_fsm_change_exec(&fsm->fsm_change);
   515         ec_fsm_change_exec(&fsm->fsm_change);
   612 
   586 
   613 void ec_fsm_master_action_addresses(ec_fsm_master_t *fsm /**< master state machine */)
   587 void ec_fsm_master_action_addresses(ec_fsm_master_t *fsm /**< master state machine */)
   614 {
   588 {
   615     ec_datagram_t *datagram = fsm->datagram;
   589     ec_datagram_t *datagram = fsm->datagram;
   616 
   590 
   617     while (fsm->slave->online) {
   591     while (fsm->slave->online_state == EC_SLAVE_ONLINE) {
   618         if (fsm->slave->list.next == &fsm->master->slaves) { // last slave?
   592         if (fsm->slave->list.next == &fsm->master->slaves) { // last slave?
   619             fsm->state = ec_fsm_master_state_start;
   593             fsm->state = ec_fsm_master_state_start;
   620             fsm->state(fsm); // execute immediately
   594             fsm->state(fsm); // execute immediately
   621             return;
   595             return;
   622         }
   596         }