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 } |