master/fsm_master.c
changeset 650 c68995623e94
parent 649 a4d3fffdaed7
child 652 15cff76b66c7
equal deleted inserted replaced
649:a4d3fffdaed7 650:c68995623e94
    72         )
    72         )
    73 {
    73 {
    74     fsm->master = master;
    74     fsm->master = master;
    75     fsm->datagram = datagram;
    75     fsm->datagram = datagram;
    76     fsm->state = ec_fsm_master_state_start;
    76     fsm->state = ec_fsm_master_state_start;
       
    77     fsm->idle = 0;
    77     fsm->slaves_responding = 0;
    78     fsm->slaves_responding = 0;
    78     fsm->topology_change_pending = 0;
    79     fsm->topology_change_pending = 0;
    79     fsm->slave_states = EC_SLAVE_STATE_UNKNOWN;
    80     fsm->slave_states = EC_SLAVE_STATE_UNKNOWN;
    80     fsm->validate = 0;
    81     fsm->validate = 0;
    81     fsm->tainted = 0;
    82     fsm->tainted = 0;
   124 }
   125 }
   125 
   126 
   126 /*****************************************************************************/
   127 /*****************************************************************************/
   127 
   128 
   128 /**
   129 /**
   129    \return false, if state machine has terminated
   130  * \return false, if state machine has terminated
   130 */
   131  */
   131 
   132 
   132 int ec_fsm_master_running(ec_fsm_master_t *fsm /**< master state machine */)
   133 int ec_fsm_master_running(
       
   134         const ec_fsm_master_t *fsm /**< master state machine */
       
   135         )
   133 {
   136 {
   134     return fsm->state != ec_fsm_master_state_end
   137     return fsm->state != ec_fsm_master_state_end
   135         && fsm->state != ec_fsm_master_state_error;
   138         && fsm->state != ec_fsm_master_state_error;
       
   139 }
       
   140 
       
   141 /*****************************************************************************/
       
   142 
       
   143 /**
       
   144  * \return true, if the state machine is in an idle phase
       
   145  */
       
   146 
       
   147 int ec_fsm_master_idle(
       
   148         const ec_fsm_master_t *fsm /**< master state machine */
       
   149         )
       
   150 {
       
   151     return fsm->idle;
   136 }
   152 }
   137 
   153 
   138 /******************************************************************************
   154 /******************************************************************************
   139  *  master state machine
   155  *  master state machine
   140  *****************************************************************************/
   156  *****************************************************************************/
   144    Starts with getting slave count and slave states.
   160    Starts with getting slave count and slave states.
   145 */
   161 */
   146 
   162 
   147 void ec_fsm_master_state_start(ec_fsm_master_t *fsm)
   163 void ec_fsm_master_state_start(ec_fsm_master_t *fsm)
   148 {
   164 {
       
   165     fsm->idle = 1;
   149     ec_datagram_brd(fsm->datagram, 0x0130, 2);
   166     ec_datagram_brd(fsm->datagram, 0x0130, 2);
   150     fsm->state = ec_fsm_master_state_broadcast;
   167     fsm->state = ec_fsm_master_state_broadcast;
   151 }
   168 }
   152 
   169 
   153 /*****************************************************************************/
   170 /*****************************************************************************/
   165     ec_master_t *master = fsm->master;
   182     ec_master_t *master = fsm->master;
   166 
   183 
   167     if (datagram->state == EC_DATAGRAM_TIMED_OUT)
   184     if (datagram->state == EC_DATAGRAM_TIMED_OUT)
   168         return; // always retry
   185         return; // always retry
   169 
   186 
   170     if (datagram->state != EC_DATAGRAM_RECEIVED) { // EC_DATAGRAM_ERROR
   187     if (datagram->state != EC_DATAGRAM_RECEIVED) { // link is down
   171         // link is down
       
   172         fsm->slaves_responding = 0;
   188         fsm->slaves_responding = 0;
   173         list_for_each_entry(slave, &master->slaves, list) {
   189         list_for_each_entry(slave, &master->slaves, list) {
   174             ec_slave_set_online_state(slave, EC_SLAVE_OFFLINE);
   190             ec_slave_set_online_state(slave, EC_SLAVE_OFFLINE);
   175         }
   191         }
   176         fsm->state = ec_fsm_master_state_error;
   192         fsm->state = ec_fsm_master_state_error;
   208     // topology change in idle mode: clear all slaves and scan the bus
   224     // topology change in idle mode: clear all slaves and scan the bus
   209     if (fsm->topology_change_pending &&
   225     if (fsm->topology_change_pending &&
   210             master->mode == EC_MASTER_MODE_IDLE) {
   226             master->mode == EC_MASTER_MODE_IDLE) {
   211         fsm->topology_change_pending = 0;
   227         fsm->topology_change_pending = 0;
   212         fsm->tainted = 0;
   228         fsm->tainted = 0;
       
   229         fsm->idle = 0;
   213 
   230 
   214         ec_master_eoe_stop(master);
   231         ec_master_eoe_stop(master);
   215         ec_master_destroy_slaves(master);
   232         ec_master_destroy_slaves(master);
   216 
   233 
   217         master->slave_count = datagram->working_counter;
   234         master->slave_count = datagram->working_counter;
   357         if (master->debug_level)
   374         if (master->debug_level)
   358             EC_DBG("Processing SDO request for slave %i...\n",
   375             EC_DBG("Processing SDO request for slave %i...\n",
   359                     slave->ring_position);
   376                     slave->ring_position);
   360 
   377 
   361         // start uploading SDO
   378         // start uploading SDO
       
   379         fsm->idle = 0;
   362         fsm->slave = slave;
   380         fsm->slave = slave;
   363         fsm->sdo_request = request;
   381         fsm->sdo_request = request;
   364         fsm->state = ec_fsm_master_state_sdo_request;
   382         fsm->state = ec_fsm_master_state_sdo_request;
   365         ec_fsm_coe_upload(&fsm->fsm_coe, slave, fsm->sdo_request);
   383         ec_fsm_coe_upload(&fsm->fsm_coe, slave, fsm->sdo_request);
   366         ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately
   384         ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately
   404                 EC_DBG("Reconfiguring slave %i (%s).\n",
   422                 EC_DBG("Reconfiguring slave %i (%s).\n",
   405                        slave->ring_position, old_state);
   423                        slave->ring_position, old_state);
   406             }
   424             }
   407         }
   425         }
   408 
   426 
       
   427         fsm->idle = 0;
   409         fsm->slave = slave;
   428         fsm->slave = slave;
   410         fsm->state = ec_fsm_master_state_configure_slave;
   429         fsm->state = ec_fsm_master_state_configure_slave;
   411         ec_fsm_slave_start_conf(&fsm->fsm_slave, slave);
   430         ec_fsm_slave_start_conf(&fsm->fsm_slave, slave);
   412         ec_fsm_slave_exec(&fsm->fsm_slave); // execute immediately
   431         ec_fsm_slave_exec(&fsm->fsm_slave); // execute immediately
   413         return;
   432         return;
   437             }
   456             }
   438 
   457 
   439             slave->sdo_dictionary_fetched = 1;
   458             slave->sdo_dictionary_fetched = 1;
   440 
   459 
   441             // start fetching SDO dictionary
   460             // start fetching SDO dictionary
       
   461             fsm->idle = 0;
   442             fsm->slave = slave;
   462             fsm->slave = slave;
   443             fsm->state = ec_fsm_master_state_sdodict;
   463             fsm->state = ec_fsm_master_state_sdodict;
   444             ec_fsm_coe_dictionary(&fsm->fsm_coe, slave);
   464             ec_fsm_coe_dictionary(&fsm->fsm_coe, slave);
   445             ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately
   465             ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately
   446             return;
   466             return;
   467     ec_slave_t *slave = fsm->slave;
   487     ec_slave_t *slave = fsm->slave;
   468 
   488 
   469     // is there another slave to query?
   489     // is there another slave to query?
   470     if (slave->list.next != &master->slaves) {
   490     if (slave->list.next != &master->slaves) {
   471         // process next slave
   491         // process next slave
       
   492         fsm->idle = 1;
   472         fsm->slave = list_entry(slave->list.next, ec_slave_t, list);
   493         fsm->slave = list_entry(slave->list.next, ec_slave_t, list);
   473         ec_datagram_nprd(fsm->datagram, fsm->slave->station_address,
   494         ec_datagram_nprd(fsm->datagram, fsm->slave->station_address,
   474                          0x0130, 2);
   495                          0x0130, 2);
   475         fsm->retries = EC_FSM_RETRIES;
   496         fsm->retries = EC_FSM_RETRIES;
   476         fsm->state = ec_fsm_master_state_read_states;
   497         fsm->state = ec_fsm_master_state_read_states;
   485         list_for_each_entry(slave, &master->slaves, list) {
   506         list_for_each_entry(slave, &master->slaves, list) {
   486             if (slave->online_state == EC_SLAVE_ONLINE) continue;
   507             if (slave->online_state == EC_SLAVE_ONLINE) continue;
   487 
   508 
   488             // At least one slave is offline. validate!
   509             // At least one slave is offline. validate!
   489             EC_INFO("Validating bus.\n");
   510             EC_INFO("Validating bus.\n");
       
   511             fsm->idle = 0;
   490             fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
   512             fsm->slave = list_entry(master->slaves.next, ec_slave_t, list);
   491             fsm->state = ec_fsm_master_state_validate_vendor;
   513             fsm->state = ec_fsm_master_state_validate_vendor;
   492             ec_fsm_sii_read(&fsm->fsm_sii, slave, 0x0008, EC_FSM_SII_POSITION);
   514             ec_fsm_sii_read(&fsm->fsm_sii, slave, 0x0008, EC_FSM_SII_POSITION);
   493             ec_fsm_sii_exec(&fsm->fsm_sii); // execute immediately
   515             ec_fsm_sii_exec(&fsm->fsm_sii); // execute immediately
   494             return;
   516             return;
   531     ec_slave_set_state(slave, EC_READ_U8(datagram->data)); // set app state first
   553     ec_slave_set_state(slave, EC_READ_U8(datagram->data)); // set app state first
   532     ec_slave_set_online_state(slave, EC_SLAVE_ONLINE);
   554     ec_slave_set_online_state(slave, EC_SLAVE_ONLINE);
   533 
   555 
   534     // check, if new slave state has to be acknowledged
   556     // check, if new slave state has to be acknowledged
   535     if (slave->current_state & EC_SLAVE_STATE_ACK_ERR && !slave->error_flag) {
   557     if (slave->current_state & EC_SLAVE_STATE_ACK_ERR && !slave->error_flag) {
       
   558         fsm->idle = 0;
   536         fsm->state = ec_fsm_master_state_acknowledge;
   559         fsm->state = ec_fsm_master_state_acknowledge;
   537         ec_fsm_change_ack(&fsm->fsm_change, slave);
   560         ec_fsm_change_ack(&fsm->fsm_change, slave);
   538         ec_fsm_change_exec(&fsm->fsm_change);
   561         ec_fsm_change_exec(&fsm->fsm_change);
   539         return;
   562         return;
   540     }
   563     }