equal
deleted
inserted
replaced
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 } |