56 void ec_fsm_master_state_scan_slave(ec_fsm_master_t *); |
56 void ec_fsm_master_state_scan_slave(ec_fsm_master_t *); |
57 void ec_fsm_master_state_write_sii(ec_fsm_master_t *); |
57 void ec_fsm_master_state_write_sii(ec_fsm_master_t *); |
58 void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *); |
58 void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *); |
59 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *); |
59 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *); |
60 void ec_fsm_master_state_reg_request(ec_fsm_master_t *); |
60 void ec_fsm_master_state_reg_request(ec_fsm_master_t *); |
61 void ec_fsm_master_state_foe_request(ec_fsm_master_t *); |
|
62 |
61 |
63 |
62 |
64 /*****************************************************************************/ |
63 /*****************************************************************************/ |
65 |
64 |
66 /** Constructor. |
65 /** Constructor. |
80 fsm->topology_change_pending = 0; |
79 fsm->topology_change_pending = 0; |
81 fsm->slave_states = EC_SLAVE_STATE_UNKNOWN; |
80 fsm->slave_states = EC_SLAVE_STATE_UNKNOWN; |
82 |
81 |
83 // init sub-state-machines |
82 // init sub-state-machines |
84 ec_fsm_coe_init(&fsm->fsm_coe, fsm->datagram); |
83 ec_fsm_coe_init(&fsm->fsm_coe, fsm->datagram); |
85 ec_fsm_foe_init(&fsm->fsm_foe, fsm->datagram); |
|
86 ec_fsm_pdo_init(&fsm->fsm_pdo, &fsm->fsm_coe); |
84 ec_fsm_pdo_init(&fsm->fsm_pdo, &fsm->fsm_coe); |
87 ec_fsm_change_init(&fsm->fsm_change, fsm->datagram); |
85 ec_fsm_change_init(&fsm->fsm_change, fsm->datagram); |
88 ec_fsm_slave_config_init(&fsm->fsm_slave_config, fsm->datagram, |
86 ec_fsm_slave_config_init(&fsm->fsm_slave_config, fsm->datagram, |
89 &fsm->fsm_change, &fsm->fsm_coe, &fsm->fsm_pdo); |
87 &fsm->fsm_change, &fsm->fsm_coe, &fsm->fsm_pdo); |
90 ec_fsm_slave_scan_init(&fsm->fsm_slave_scan, fsm->datagram, |
88 ec_fsm_slave_scan_init(&fsm->fsm_slave_scan, fsm->datagram, |
100 ec_fsm_master_t *fsm /**< Master state machine. */ |
98 ec_fsm_master_t *fsm /**< Master state machine. */ |
101 ) |
99 ) |
102 { |
100 { |
103 // clear sub-state machines |
101 // clear sub-state machines |
104 ec_fsm_coe_clear(&fsm->fsm_coe); |
102 ec_fsm_coe_clear(&fsm->fsm_coe); |
105 ec_fsm_foe_clear(&fsm->fsm_foe); |
|
106 ec_fsm_pdo_clear(&fsm->fsm_pdo); |
103 ec_fsm_pdo_clear(&fsm->fsm_pdo); |
107 ec_fsm_change_clear(&fsm->fsm_change); |
104 ec_fsm_change_clear(&fsm->fsm_change); |
108 ec_fsm_slave_config_clear(&fsm->fsm_slave_config); |
105 ec_fsm_slave_config_clear(&fsm->fsm_slave_config); |
109 ec_fsm_slave_scan_clear(&fsm->fsm_slave_scan); |
106 ec_fsm_slave_scan_clear(&fsm->fsm_slave_scan); |
110 ec_fsm_sii_clear(&fsm->fsm_sii); |
107 ec_fsm_sii_clear(&fsm->fsm_sii); |
454 } |
451 } |
455 } |
452 } |
456 return 0; |
453 return 0; |
457 } |
454 } |
458 |
455 |
459 /*****************************************************************************/ |
456 |
460 |
457 /*****************************************************************************/ |
461 /** Check for pending FoE requests and process one. |
458 |
462 * |
459 /** Master action: IDLE. |
463 * \return non-zero, if an FoE request is processed. |
460 * |
464 */ |
461 * Does secondary work. |
465 int ec_fsm_master_action_process_foe( |
462 */ |
|
463 void ec_fsm_master_action_idle( |
466 ec_fsm_master_t *fsm /**< Master state machine. */ |
464 ec_fsm_master_t *fsm /**< Master state machine. */ |
467 ) |
465 ) |
468 { |
466 { |
469 ec_master_t *master = fsm->master; |
467 ec_master_t *master = fsm->master; |
470 ec_slave_t *slave; |
468 ec_slave_t *slave; |
471 ec_master_foe_request_t *request; |
469 |
472 |
470 // Check for pending internal SDO requests |
473 // search the first request to be processed |
|
474 while (1) { |
|
475 if (list_empty(&master->foe_requests)) |
|
476 break; |
|
477 |
|
478 // get first request |
|
479 request = list_entry(master->foe_requests.next, |
|
480 ec_master_foe_request_t, list); |
|
481 list_del_init(&request->list); // dequeue |
|
482 request->req.state = EC_INT_REQUEST_BUSY; |
|
483 slave = request->slave; |
|
484 |
|
485 if (master->debug_level) |
|
486 EC_DBG("Processing FoE request for slave %u.\n", |
|
487 slave->ring_position); |
|
488 |
|
489 fsm->foe_request = &request->req; |
|
490 fsm->slave = slave; |
|
491 fsm->state = ec_fsm_master_state_foe_request; |
|
492 fsm->idle = 0; |
|
493 ec_fsm_foe_transfer(&fsm->fsm_foe, slave, &request->req); |
|
494 ec_fsm_foe_exec(&fsm->fsm_foe); |
|
495 return 1; |
|
496 } |
|
497 |
|
498 return 0; |
|
499 } |
|
500 |
|
501 /*****************************************************************************/ |
|
502 |
|
503 /** Master action: IDLE. |
|
504 * |
|
505 * Does secondary work. |
|
506 */ |
|
507 void ec_fsm_master_action_idle( |
|
508 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
509 ) |
|
510 { |
|
511 ec_master_t *master = fsm->master; |
|
512 ec_slave_t *slave; |
|
513 |
|
514 // Check for pending SDO requests |
|
515 if (ec_fsm_master_action_process_sdo(fsm)) |
471 if (ec_fsm_master_action_process_sdo(fsm)) |
516 return; |
|
517 |
|
518 // Check for pending FoE requests |
|
519 if (ec_fsm_master_action_process_foe(fsm)) |
|
520 return; |
472 return; |
521 |
473 |
522 // check, if slaves have an SDO dictionary to read out. |
474 // check, if slaves have an SDO dictionary to read out. |
523 for (slave = master->slaves; |
475 for (slave = master->slaves; |
524 slave < master->slaves + master->slave_count; |
476 slave < master->slaves + master->slave_count; |
924 wake_up(&master->sii_queue); |
876 wake_up(&master->sii_queue); |
925 |
877 |
926 // check for another SII write request |
878 // check for another SII write request |
927 if (ec_fsm_master_action_process_sii(fsm)) |
879 if (ec_fsm_master_action_process_sii(fsm)) |
928 return; // processing another request |
880 return; // processing another request |
929 |
|
930 ec_fsm_master_restart(fsm); |
|
931 } |
|
932 |
|
933 /*****************************************************************************/ |
|
934 |
|
935 /** Master state: WRITE FOE. |
|
936 */ |
|
937 void ec_fsm_master_state_foe_request( |
|
938 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
939 ) |
|
940 { |
|
941 ec_master_t *master = fsm->master; |
|
942 ec_foe_request_t *request = fsm->foe_request; |
|
943 ec_slave_t *slave = fsm->slave; |
|
944 |
|
945 if (ec_fsm_foe_exec(&fsm->fsm_foe)) |
|
946 return; |
|
947 |
|
948 fsm->idle = 1; |
|
949 |
|
950 if (!ec_fsm_foe_success(&fsm->fsm_foe)) { |
|
951 EC_ERR("Failed to handle FoE request to slave %u.\n", |
|
952 slave->ring_position); |
|
953 request->state = EC_INT_REQUEST_FAILURE; |
|
954 wake_up(&master->foe_queue); |
|
955 ec_fsm_master_restart(fsm); |
|
956 return; |
|
957 } |
|
958 |
|
959 // finished transferring FoE |
|
960 if (master->debug_level) |
|
961 EC_DBG("Successfully transferred %u bytes of FoE data from/to" |
|
962 " slave %u.\n", request->data_size, slave->ring_position); |
|
963 |
|
964 request->state = EC_INT_REQUEST_SUCCESS; |
|
965 wake_up(&master->foe_queue); |
|
966 |
881 |
967 ec_fsm_master_restart(fsm); |
882 ec_fsm_master_restart(fsm); |
968 } |
883 } |
969 |
884 |
970 /*****************************************************************************/ |
885 /*****************************************************************************/ |