51 void ec_fsm_master_state_scan_slave(ec_fsm_master_t *); |
52 void ec_fsm_master_state_scan_slave(ec_fsm_master_t *); |
52 void ec_fsm_master_state_write_sii(ec_fsm_master_t *); |
53 void ec_fsm_master_state_write_sii(ec_fsm_master_t *); |
53 void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *); |
54 void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *); |
54 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *); |
55 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *); |
55 void ec_fsm_master_state_phy_request(ec_fsm_master_t *); |
56 void ec_fsm_master_state_phy_request(ec_fsm_master_t *); |
|
57 void ec_fsm_master_state_foe_request(ec_fsm_master_t *); |
56 |
58 |
57 /*****************************************************************************/ |
59 /*****************************************************************************/ |
58 |
60 |
59 /** Constructor. |
61 /** Constructor. |
60 */ |
62 */ |
72 fsm->topology_change_pending = 0; |
74 fsm->topology_change_pending = 0; |
73 fsm->slave_states = EC_SLAVE_STATE_UNKNOWN; |
75 fsm->slave_states = EC_SLAVE_STATE_UNKNOWN; |
74 |
76 |
75 // init sub-state-machines |
77 // init sub-state-machines |
76 ec_fsm_coe_init(&fsm->fsm_coe, fsm->datagram); |
78 ec_fsm_coe_init(&fsm->fsm_coe, fsm->datagram); |
|
79 ec_fsm_foe_init(&fsm->fsm_foe, fsm->datagram); |
77 ec_fsm_pdo_init(&fsm->fsm_pdo, &fsm->fsm_coe); |
80 ec_fsm_pdo_init(&fsm->fsm_pdo, &fsm->fsm_coe); |
78 ec_fsm_change_init(&fsm->fsm_change, fsm->datagram); |
81 ec_fsm_change_init(&fsm->fsm_change, fsm->datagram); |
79 ec_fsm_slave_config_init(&fsm->fsm_slave_config, fsm->datagram, |
82 ec_fsm_slave_config_init(&fsm->fsm_slave_config, fsm->datagram, |
80 &fsm->fsm_change, &fsm->fsm_coe, &fsm->fsm_pdo); |
83 &fsm->fsm_change, &fsm->fsm_coe, &fsm->fsm_pdo); |
81 ec_fsm_slave_scan_init(&fsm->fsm_slave_scan, fsm->datagram, |
84 ec_fsm_slave_scan_init(&fsm->fsm_slave_scan, fsm->datagram, |
91 ec_fsm_master_t *fsm /**< Master state machine. */ |
94 ec_fsm_master_t *fsm /**< Master state machine. */ |
92 ) |
95 ) |
93 { |
96 { |
94 // clear sub-state machines |
97 // clear sub-state machines |
95 ec_fsm_coe_clear(&fsm->fsm_coe); |
98 ec_fsm_coe_clear(&fsm->fsm_coe); |
|
99 ec_fsm_foe_clear(&fsm->fsm_foe); |
96 ec_fsm_pdo_clear(&fsm->fsm_pdo); |
100 ec_fsm_pdo_clear(&fsm->fsm_pdo); |
97 ec_fsm_change_clear(&fsm->fsm_change); |
101 ec_fsm_change_clear(&fsm->fsm_change); |
98 ec_fsm_slave_config_clear(&fsm->fsm_slave_config); |
102 ec_fsm_slave_config_clear(&fsm->fsm_slave_config); |
99 ec_fsm_slave_scan_clear(&fsm->fsm_slave_scan); |
103 ec_fsm_slave_scan_clear(&fsm->fsm_slave_scan); |
100 ec_fsm_sii_clear(&fsm->fsm_sii); |
104 ec_fsm_sii_clear(&fsm->fsm_sii); |
209 if (!master->allow_scan) { |
213 if (!master->allow_scan) { |
210 up(&master->scan_sem); |
214 up(&master->scan_sem); |
211 } else { |
215 } else { |
212 master->scan_busy = 1; |
216 master->scan_busy = 1; |
213 up(&master->scan_sem); |
217 up(&master->scan_sem); |
214 |
218 |
215 // topology change when scan is allowed: |
219 // topology change when scan is allowed: |
216 // clear all slaves and scan the bus |
220 // clear all slaves and scan the bus |
217 fsm->topology_change_pending = 0; |
221 fsm->topology_change_pending = 0; |
218 fsm->idle = 0; |
222 fsm->idle = 0; |
219 fsm->scan_jiffies = jiffies; |
223 fsm->scan_jiffies = jiffies; |
279 } |
283 } |
280 |
284 |
281 /*****************************************************************************/ |
285 /*****************************************************************************/ |
282 |
286 |
283 /** Check for pending SII write requests and process one. |
287 /** Check for pending SII write requests and process one. |
284 * |
288 * |
285 * \return non-zero, if an SII write request is processed. |
289 * \return non-zero, if an SII write request is processed. |
286 */ |
290 */ |
287 int ec_fsm_master_action_process_sii( |
291 int ec_fsm_master_action_process_sii( |
288 ec_fsm_master_t *fsm /**< Master state machine. */ |
292 ec_fsm_master_t *fsm /**< Master state machine. */ |
289 ) |
293 ) |
373 } |
377 } |
374 |
378 |
375 /*****************************************************************************/ |
379 /*****************************************************************************/ |
376 |
380 |
377 /** Check for pending SDO requests and process one. |
381 /** Check for pending SDO requests and process one. |
378 * |
382 * |
379 * \return non-zero, if an SDO request is processed. |
383 * \return non-zero, if an SDO request is processed. |
380 */ |
384 */ |
381 int ec_fsm_master_action_process_sdo( |
385 int ec_fsm_master_action_process_sdo( |
382 ec_fsm_master_t *fsm /**< Master state machine. */ |
386 ec_fsm_master_t *fsm /**< Master state machine. */ |
383 ) |
387 ) |
455 fsm->sdo_request = &request->req; |
459 fsm->sdo_request = &request->req; |
456 fsm->slave = slave; |
460 fsm->slave = slave; |
457 fsm->state = ec_fsm_master_state_sdo_request; |
461 fsm->state = ec_fsm_master_state_sdo_request; |
458 ec_fsm_coe_transfer(&fsm->fsm_coe, slave, &request->req); |
462 ec_fsm_coe_transfer(&fsm->fsm_coe, slave, &request->req); |
459 ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately |
463 ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately |
|
464 return 1; |
|
465 } |
|
466 |
|
467 return 0; |
|
468 } |
|
469 |
|
470 /*****************************************************************************/ |
|
471 |
|
472 /** Check for pending FoE requests and process one. |
|
473 * |
|
474 * \return non-zero, if an FoE request is processed. |
|
475 */ |
|
476 int ec_fsm_master_action_process_foe( |
|
477 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
478 ) |
|
479 { |
|
480 ec_master_t *master = fsm->master; |
|
481 ec_slave_t *slave; |
|
482 ec_master_foe_request_t *request; |
|
483 |
|
484 // search the first request to be processed |
|
485 while (1) { |
|
486 if (list_empty(&master->foe_requests)) |
|
487 break; |
|
488 |
|
489 // get first request |
|
490 request = list_entry(master->foe_requests.next, |
|
491 ec_master_foe_request_t, list); |
|
492 list_del_init(&request->list); // dequeue |
|
493 request->req.state = EC_REQUEST_BUSY; |
|
494 slave = request->slave; |
|
495 |
|
496 EC_DBG("---- Master read command from queue ----\n"); |
|
497 // found pending FOE write operation. execute it! |
|
498 if (master->debug_level) |
|
499 EC_DBG("Writing FOE data to slave %u...\n", |
|
500 request->slave->ring_position); |
|
501 |
|
502 fsm->foe_request = &request->req; |
|
503 fsm->slave = slave; |
|
504 fsm->state = ec_fsm_master_state_foe_request; |
|
505 ec_fsm_foe_transfer(&fsm->fsm_foe, slave, &request->req); |
|
506 //(&fsm->fsm_foe, request->slave, request->offset, request->words); |
|
507 ec_fsm_foe_exec(&fsm->fsm_foe); |
460 return 1; |
508 return 1; |
461 } |
509 } |
462 |
510 |
463 return 0; |
511 return 0; |
464 } |
512 } |
719 void ec_fsm_master_state_scan_slave( |
767 void ec_fsm_master_state_scan_slave( |
720 ec_fsm_master_t *fsm /**< Master state machine. */ |
768 ec_fsm_master_t *fsm /**< Master state machine. */ |
721 ) |
769 ) |
722 { |
770 { |
723 ec_master_t *master = fsm->master; |
771 ec_master_t *master = fsm->master; |
|
772 #ifdef EC_EOE |
724 ec_slave_t *slave = fsm->slave; |
773 ec_slave_t *slave = fsm->slave; |
725 |
774 #endif |
726 if (ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan)) |
775 if (ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan)) |
727 return; |
776 return; |
728 |
777 |
729 #ifdef EC_EOE |
778 #ifdef EC_EOE |
730 if (slave->sii.mailbox_protocols & EC_MBOX_EOE) { |
779 if (slave->sii.mailbox_protocols & EC_MBOX_EOE) { |
838 if (request->offset <= 4 && request->offset + request->nwords > 4) { |
887 if (request->offset <= 4 && request->offset + request->nwords > 4) { |
839 // alias was written |
888 // alias was written |
840 slave->sii.alias = EC_READ_U16(request->words + 4); |
889 slave->sii.alias = EC_READ_U16(request->words + 4); |
841 } |
890 } |
842 // TODO: Evaluate other SII contents! |
891 // TODO: Evaluate other SII contents! |
843 |
892 |
844 request->state = EC_INT_REQUEST_SUCCESS; |
893 request->state = EC_INT_REQUEST_SUCCESS; |
845 wake_up(&master->sii_queue); |
894 wake_up(&master->sii_queue); |
846 |
895 |
847 // check for another SII write request |
896 // check for another SII write request |
848 if (ec_fsm_master_action_process_sii(fsm)) |
897 if (ec_fsm_master_action_process_sii(fsm)) |
849 return; // processing another request |
898 return; // processing another request |
|
899 |
|
900 ec_fsm_master_restart(fsm); |
|
901 } |
|
902 |
|
903 /*****************************************************************************/ |
|
904 |
|
905 /** Master state: WRITE FOE. |
|
906 */ |
|
907 void ec_fsm_master_state_foe_request( |
|
908 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
909 ) |
|
910 { |
|
911 ec_master_t *master = fsm->master; |
|
912 ec_foe_request_t *request = fsm->foe_request; |
|
913 ec_slave_t *slave = fsm->slave; |
|
914 |
|
915 if (ec_fsm_foe_exec(&fsm->fsm_foe)) return; |
|
916 |
|
917 if (!ec_fsm_foe_success(&fsm->fsm_foe)) { |
|
918 EC_ERR("Failed to handle FOE request to slave %u.\n", |
|
919 slave->ring_position); |
|
920 request->state = EC_INT_REQUEST_FAILURE; |
|
921 wake_up(&master->foe_queue); |
|
922 ec_fsm_master_restart(fsm); |
|
923 return; |
|
924 } |
|
925 |
|
926 // finished writing FOE |
|
927 if (master->debug_level) |
|
928 EC_DBG("Finished writing %u words of FOE data to slave %u.\n", |
|
929 request->data_size, slave->ring_position); |
|
930 |
|
931 request->state = EC_INT_REQUEST_SUCCESS; |
|
932 wake_up(&master->foe_queue); |
850 |
933 |
851 ec_fsm_master_restart(fsm); |
934 ec_fsm_master_restart(fsm); |
852 } |
935 } |
853 |
936 |
854 /*****************************************************************************/ |
937 /*****************************************************************************/ |
904 wake_up(&master->sdo_queue); |
987 wake_up(&master->sdo_queue); |
905 ec_fsm_master_restart(fsm); |
988 ec_fsm_master_restart(fsm); |
906 return; |
989 return; |
907 } |
990 } |
908 |
991 |
909 // SDO request finished |
992 // SDO request finished |
910 request->state = EC_INT_REQUEST_SUCCESS; |
993 request->state = EC_INT_REQUEST_SUCCESS; |
911 wake_up(&master->sdo_queue); |
994 wake_up(&master->sdo_queue); |
912 |
995 |
913 if (master->debug_level) |
996 if (master->debug_level) |
914 EC_DBG("Finished SDO request for slave %u.\n", |
997 EC_DBG("Finished SDO request for slave %u.\n", |