57 void ec_fsm_master_state_clear_addresses(ec_fsm_master_t *); |
57 void ec_fsm_master_state_clear_addresses(ec_fsm_master_t *); |
58 void ec_fsm_master_state_scan_slave(ec_fsm_master_t *); |
58 void ec_fsm_master_state_scan_slave(ec_fsm_master_t *); |
59 void ec_fsm_master_state_write_sii(ec_fsm_master_t *); |
59 void ec_fsm_master_state_write_sii(ec_fsm_master_t *); |
60 void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *); |
60 void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *); |
61 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *); |
61 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *); |
62 void ec_fsm_master_state_end(ec_fsm_master_t *); |
|
63 void ec_fsm_master_state_error(ec_fsm_master_t *); |
|
64 |
62 |
65 /*****************************************************************************/ |
63 /*****************************************************************************/ |
66 |
64 |
67 /** Constructor. |
65 /** Constructor. |
68 */ |
66 */ |
111 |
109 |
112 /** Executes the current state of the state machine. |
110 /** Executes the current state of the state machine. |
113 * |
111 * |
114 * If the state machine's datagram is not sent or received yet, the execution |
112 * If the state machine's datagram is not sent or received yet, the execution |
115 * of the state machine is delayed to the next cycle. |
113 * of the state machine is delayed to the next cycle. |
116 * |
114 */ |
117 * \return false, if state machine has terminated |
115 void ec_fsm_master_exec( |
118 */ |
|
119 int ec_fsm_master_exec( |
|
120 ec_fsm_master_t *fsm /**< Master state machine. */ |
116 ec_fsm_master_t *fsm /**< Master state machine. */ |
121 ) |
117 ) |
122 { |
118 { |
123 if (fsm->datagram->state == EC_DATAGRAM_SENT |
119 if (fsm->datagram->state == EC_DATAGRAM_SENT |
124 || fsm->datagram->state == EC_DATAGRAM_QUEUED) { |
120 || fsm->datagram->state == EC_DATAGRAM_QUEUED) { |
125 // datagram was not sent or received yet. |
121 // datagram was not sent or received yet. |
126 return ec_fsm_master_running(fsm); |
122 return; |
127 } |
123 } |
128 |
124 |
129 fsm->state(fsm); |
125 fsm->state(fsm); |
130 return ec_fsm_master_running(fsm); |
|
131 } |
|
132 |
|
133 /*****************************************************************************/ |
|
134 |
|
135 /** |
|
136 * \return false, if state machine has terminated |
|
137 */ |
|
138 int ec_fsm_master_running( |
|
139 const ec_fsm_master_t *fsm /**< Master state machine. */ |
|
140 ) |
|
141 { |
|
142 return fsm->state != ec_fsm_master_state_end |
|
143 && fsm->state != ec_fsm_master_state_error; |
|
144 } |
126 } |
145 |
127 |
146 /*****************************************************************************/ |
128 /*****************************************************************************/ |
147 |
129 |
148 /** |
130 /** |
151 int ec_fsm_master_idle( |
133 int ec_fsm_master_idle( |
152 const ec_fsm_master_t *fsm /**< Master state machine. */ |
134 const ec_fsm_master_t *fsm /**< Master state machine. */ |
153 ) |
135 ) |
154 { |
136 { |
155 return fsm->idle; |
137 return fsm->idle; |
|
138 } |
|
139 |
|
140 /*****************************************************************************/ |
|
141 |
|
142 /** Restarts the master state machine. |
|
143 */ |
|
144 void ec_fsm_master_restart( |
|
145 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
146 ) |
|
147 { |
|
148 fsm->state = ec_fsm_master_state_start; |
|
149 fsm->state(fsm); // execute immediately |
156 } |
150 } |
157 |
151 |
158 /****************************************************************************** |
152 /****************************************************************************** |
159 * Master state machine |
153 * Master state machine |
160 *****************************************************************************/ |
154 *****************************************************************************/ |
196 fsm->slaves_responding = datagram->working_counter; |
190 fsm->slaves_responding = datagram->working_counter; |
197 EC_INFO("%u slave(s) responding.\n", fsm->slaves_responding); |
191 EC_INFO("%u slave(s) responding.\n", fsm->slaves_responding); |
198 } |
192 } |
199 |
193 |
200 if (datagram->state != EC_DATAGRAM_RECEIVED) { // link is down |
194 if (datagram->state != EC_DATAGRAM_RECEIVED) { // link is down |
201 fsm->state = ec_fsm_master_state_error; |
195 ec_fsm_master_restart(fsm); |
202 return; |
196 return; |
203 } |
197 } |
204 |
198 |
205 if (fsm->slaves_responding) { |
199 if (fsm->slaves_responding) { |
206 uint8_t states = EC_READ_U8(datagram->data); |
200 uint8_t states = EC_READ_U8(datagram->data); |
238 |
232 |
239 if (!master->slave_count) { |
233 if (!master->slave_count) { |
240 // no slaves present -> finish state machine. |
234 // no slaves present -> finish state machine. |
241 master->scan_busy = 0; |
235 master->scan_busy = 0; |
242 wake_up_interruptible(&master->scan_queue); |
236 wake_up_interruptible(&master->scan_queue); |
243 fsm->state = ec_fsm_master_state_end; |
237 ec_fsm_master_restart(fsm); |
244 return; |
238 return; |
245 } |
239 } |
246 |
240 |
247 size = sizeof(ec_slave_t) * master->slave_count; |
241 size = sizeof(ec_slave_t) * master->slave_count; |
248 if (!(master->slaves = (ec_slave_t *) kmalloc(size, GFP_KERNEL))) { |
242 if (!(master->slaves = (ec_slave_t *) kmalloc(size, GFP_KERNEL))) { |
249 EC_ERR("Failed to allocate %u bytes of slave memory!\n", |
243 EC_ERR("Failed to allocate %u bytes of slave memory!\n", |
250 size); |
244 size); |
251 master->slave_count = 0; // FIXME avoid scanning! |
245 master->slave_count = 0; // FIXME avoid scanning! |
252 master->scan_busy = 0; |
246 master->scan_busy = 0; |
253 wake_up_interruptible(&master->scan_queue); |
247 wake_up_interruptible(&master->scan_queue); |
254 fsm->state = ec_fsm_master_state_error; |
248 ec_fsm_master_restart(fsm); |
255 return; |
249 return; |
256 } |
250 } |
257 |
251 |
258 // init slaves |
252 // init slaves |
259 for (i = 0; i < master->slave_count; i++) { |
253 for (i = 0; i < master->slave_count; i++) { |
281 ec_datagram_fprd(fsm->datagram, fsm->slave->station_address, |
275 ec_datagram_fprd(fsm->datagram, fsm->slave->station_address, |
282 0x0130, 2); |
276 0x0130, 2); |
283 fsm->retries = EC_FSM_RETRIES; |
277 fsm->retries = EC_FSM_RETRIES; |
284 fsm->state = ec_fsm_master_state_read_state; |
278 fsm->state = ec_fsm_master_state_read_state; |
285 } else { |
279 } else { |
286 fsm->state = ec_fsm_master_state_end; |
280 ec_fsm_master_restart(fsm); |
287 } |
281 } |
288 } |
282 } |
289 |
283 |
290 /*****************************************************************************/ |
284 /*****************************************************************************/ |
291 |
285 |
469 |
463 |
470 // check for pending SII write operations. |
464 // check for pending SII write operations. |
471 if (ec_fsm_master_action_process_sii(fsm)) |
465 if (ec_fsm_master_action_process_sii(fsm)) |
472 return; // SII write request found |
466 return; // SII write request found |
473 |
467 |
474 fsm->state = ec_fsm_master_state_end; |
468 ec_fsm_master_restart(fsm); |
475 } |
469 } |
476 |
470 |
477 /*****************************************************************************/ |
471 /*****************************************************************************/ |
478 |
472 |
479 /** Master action: Get state of next slave. |
473 /** Master action: Get state of next slave. |
566 |
560 |
567 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
561 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
568 EC_ERR("Failed to receive AL state datagram for slave %u" |
562 EC_ERR("Failed to receive AL state datagram for slave %u" |
569 " (datagram state %u)\n", |
563 " (datagram state %u)\n", |
570 slave->ring_position, datagram->state); |
564 slave->ring_position, datagram->state); |
571 fsm->state = ec_fsm_master_state_error; |
565 ec_fsm_master_restart(fsm); |
572 return; |
566 return; |
573 } |
567 } |
574 |
568 |
575 // did the slave not respond to its station address? |
569 // did the slave not respond to its station address? |
576 if (datagram->working_counter != 1) { |
570 if (datagram->working_counter != 1) { |
579 if (fsm->master->debug_level) |
573 if (fsm->master->debug_level) |
580 EC_DBG("Slave %u did not respond to state query.\n", |
574 EC_DBG("Slave %u did not respond to state query.\n", |
581 fsm->slave->ring_position); |
575 fsm->slave->ring_position); |
582 } |
576 } |
583 fsm->topology_change_pending = 1; |
577 fsm->topology_change_pending = 1; |
584 fsm->state = ec_fsm_master_state_error; |
578 ec_fsm_master_restart(fsm); |
585 return; |
579 return; |
586 } |
580 } |
587 |
581 |
588 // A single slave responded |
582 // A single slave responded |
589 ec_slave_set_state(slave, EC_READ_U8(datagram->data)); |
583 ec_slave_set_state(slave, EC_READ_U8(datagram->data)); |
646 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
640 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
647 EC_ERR("Failed to receive address clearing datagram (state %u).\n", |
641 EC_ERR("Failed to receive address clearing datagram (state %u).\n", |
648 datagram->state); |
642 datagram->state); |
649 master->scan_busy = 0; |
643 master->scan_busy = 0; |
650 wake_up_interruptible(&master->scan_queue); |
644 wake_up_interruptible(&master->scan_queue); |
651 fsm->state = ec_fsm_master_state_error; |
645 ec_fsm_master_restart(fsm); |
652 return; |
646 return; |
653 } |
647 } |
654 |
648 |
655 if (datagram->working_counter != master->slave_count) { |
649 if (datagram->working_counter != master->slave_count) { |
656 EC_WARN("Failed to clear all station addresses: Cleared %u of %u", |
650 EC_WARN("Failed to clear all station addresses: Cleared %u of %u", |
719 #ifdef EC_EOE |
713 #ifdef EC_EOE |
720 // check if EoE processing has to be started |
714 // check if EoE processing has to be started |
721 ec_master_eoe_start(master); |
715 ec_master_eoe_start(master); |
722 #endif |
716 #endif |
723 |
717 |
724 fsm->state = ec_fsm_master_state_end; |
718 ec_fsm_master_restart(fsm); |
725 } |
719 } |
726 |
720 |
727 /*****************************************************************************/ |
721 /*****************************************************************************/ |
728 |
722 |
729 /** Master state: CONFIGURE SLAVE. |
723 /** Master state: CONFIGURE SLAVE. |
768 if (!ec_fsm_sii_success(&fsm->fsm_sii)) { |
762 if (!ec_fsm_sii_success(&fsm->fsm_sii)) { |
769 EC_ERR("Failed to write SII data to slave %u.\n", |
763 EC_ERR("Failed to write SII data to slave %u.\n", |
770 slave->ring_position); |
764 slave->ring_position); |
771 request->state = EC_REQUEST_FAILURE; |
765 request->state = EC_REQUEST_FAILURE; |
772 wake_up(&master->sii_queue); |
766 wake_up(&master->sii_queue); |
773 fsm->state = ec_fsm_master_state_error; |
767 ec_fsm_master_restart(fsm); |
774 return; |
768 return; |
775 } |
769 } |
776 |
770 |
777 fsm->sii_index++; |
771 fsm->sii_index++; |
778 if (fsm->sii_index < request->nwords) { |
772 if (fsm->sii_index < request->nwords) { |
795 |
789 |
796 // check for another SII write request |
790 // check for another SII write request |
797 if (ec_fsm_master_action_process_sii(fsm)) |
791 if (ec_fsm_master_action_process_sii(fsm)) |
798 return; // processing another request |
792 return; // processing another request |
799 |
793 |
800 fsm->state = ec_fsm_master_state_end; |
794 ec_fsm_master_restart(fsm); |
801 } |
795 } |
802 |
796 |
803 /*****************************************************************************/ |
797 /*****************************************************************************/ |
804 |
798 |
805 /** Master state: SDO DICTIONARY. |
799 /** Master state: SDO DICTIONARY. |
812 ec_master_t *master = fsm->master; |
806 ec_master_t *master = fsm->master; |
813 |
807 |
814 if (ec_fsm_coe_exec(&fsm->fsm_coe)) return; |
808 if (ec_fsm_coe_exec(&fsm->fsm_coe)) return; |
815 |
809 |
816 if (!ec_fsm_coe_success(&fsm->fsm_coe)) { |
810 if (!ec_fsm_coe_success(&fsm->fsm_coe)) { |
817 fsm->state = ec_fsm_master_state_error; |
811 ec_fsm_master_restart(fsm); |
818 return; |
812 return; |
819 } |
813 } |
820 |
814 |
821 // Sdo dictionary fetching finished |
815 // Sdo dictionary fetching finished |
822 |
816 |
825 ec_slave_sdo_dict_info(slave, &sdo_count, &entry_count); |
819 ec_slave_sdo_dict_info(slave, &sdo_count, &entry_count); |
826 EC_DBG("Fetched %u Sdos and %u entries from slave %u.\n", |
820 EC_DBG("Fetched %u Sdos and %u entries from slave %u.\n", |
827 sdo_count, entry_count, slave->ring_position); |
821 sdo_count, entry_count, slave->ring_position); |
828 } |
822 } |
829 |
823 |
830 fsm->state = ec_fsm_master_state_end; |
824 ec_fsm_master_restart(fsm); |
831 } |
825 } |
832 |
826 |
833 /*****************************************************************************/ |
827 /*****************************************************************************/ |
834 |
828 |
835 /** Master state: SDO REQUEST. |
829 /** Master state: SDO REQUEST. |
846 if (!ec_fsm_coe_success(&fsm->fsm_coe)) { |
840 if (!ec_fsm_coe_success(&fsm->fsm_coe)) { |
847 EC_DBG("Failed to process Sdo request for slave %u.\n", |
841 EC_DBG("Failed to process Sdo request for slave %u.\n", |
848 fsm->slave->ring_position); |
842 fsm->slave->ring_position); |
849 request->state = EC_REQUEST_FAILURE; |
843 request->state = EC_REQUEST_FAILURE; |
850 wake_up(&master->sdo_queue); |
844 wake_up(&master->sdo_queue); |
851 fsm->state = ec_fsm_master_state_error; |
845 ec_fsm_master_restart(fsm); |
852 return; |
846 return; |
853 } |
847 } |
854 |
848 |
855 // Sdo request finished |
849 // Sdo request finished |
856 request->state = EC_REQUEST_SUCCESS; |
850 request->state = EC_REQUEST_SUCCESS; |
862 |
856 |
863 // check for another Sdo request |
857 // check for another Sdo request |
864 if (ec_fsm_master_action_process_sdo(fsm)) |
858 if (ec_fsm_master_action_process_sdo(fsm)) |
865 return; // processing another request |
859 return; // processing another request |
866 |
860 |
867 fsm->state = ec_fsm_master_state_end; |
861 ec_fsm_master_restart(fsm); |
868 } |
862 } |
869 |
863 |
870 /*****************************************************************************/ |
864 /*****************************************************************************/ |
871 |
|
872 /** State: ERROR. |
|
873 */ |
|
874 void ec_fsm_master_state_error( |
|
875 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
876 ) |
|
877 { |
|
878 fsm->state = ec_fsm_master_state_start; |
|
879 } |
|
880 |
|
881 /*****************************************************************************/ |
|
882 |
|
883 /** State: END. |
|
884 */ |
|
885 void ec_fsm_master_state_end( |
|
886 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
887 ) |
|
888 { |
|
889 fsm->state = ec_fsm_master_state_start; |
|
890 } |
|
891 |
|
892 /*****************************************************************************/ |
|