77 ec_fsm_master_t *fsm, /**< Master state machine. */ |
78 ec_fsm_master_t *fsm, /**< Master state machine. */ |
78 ec_master_t *master, /**< EtherCAT master. */ |
79 ec_master_t *master, /**< EtherCAT master. */ |
79 ec_datagram_t *datagram /**< Datagram object to use. */ |
80 ec_datagram_t *datagram /**< Datagram object to use. */ |
80 ) |
81 ) |
81 { |
82 { |
|
83 ec_device_index_t dev_idx; |
|
84 |
82 fsm->master = master; |
85 fsm->master = master; |
83 fsm->datagram = datagram; |
86 fsm->datagram = datagram; |
84 fsm->state = ec_fsm_master_state_start; |
87 fsm->state = ec_fsm_master_state_start; |
85 fsm->idle = 0; |
88 fsm->idle = 0; |
86 fsm->link_state = 0; |
89 fsm->dev_idx = EC_DEVICE_MAIN; |
87 fsm->slaves_responding = 0; |
90 for (dev_idx = EC_DEVICE_MAIN; dev_idx < EC_NUM_DEVICES; dev_idx++) { |
|
91 fsm->link_state[dev_idx] = 0; |
|
92 fsm->slaves_responding[dev_idx] = 0; |
|
93 fsm->slave_states[dev_idx] = EC_SLAVE_STATE_UNKNOWN; |
|
94 } |
88 fsm->rescan_required = 0; |
95 fsm->rescan_required = 0; |
89 fsm->slave_states = EC_SLAVE_STATE_UNKNOWN; |
|
90 |
96 |
91 // init sub-state-machines |
97 // init sub-state-machines |
92 ec_fsm_coe_init(&fsm->fsm_coe, fsm->datagram); |
98 ec_fsm_coe_init(&fsm->fsm_coe, fsm->datagram); |
93 ec_fsm_pdo_init(&fsm->fsm_pdo, &fsm->fsm_coe); |
99 ec_fsm_pdo_init(&fsm->fsm_pdo, &fsm->fsm_coe); |
94 ec_fsm_change_init(&fsm->fsm_change, fsm->datagram); |
100 ec_fsm_change_init(&fsm->fsm_change, fsm->datagram); |
194 ec_datagram_t *datagram = fsm->datagram; |
202 ec_datagram_t *datagram = fsm->datagram; |
195 unsigned int i, size; |
203 unsigned int i, size; |
196 ec_slave_t *slave; |
204 ec_slave_t *slave; |
197 ec_master_t *master = fsm->master; |
205 ec_master_t *master = fsm->master; |
198 |
206 |
199 if (datagram->state == EC_DATAGRAM_TIMED_OUT) |
|
200 return; // always retry |
|
201 |
|
202 // bus topology change? |
207 // bus topology change? |
203 if (datagram->working_counter != fsm->slaves_responding) { |
208 if (datagram->working_counter != fsm->slaves_responding[fsm->dev_idx]) { |
204 fsm->rescan_required = 1; |
209 fsm->rescan_required = 1; |
205 fsm->slaves_responding = datagram->working_counter; |
210 fsm->slaves_responding[fsm->dev_idx] = datagram->working_counter; |
206 EC_MASTER_INFO(master, "%u slave(s) responding.\n", |
211 EC_MASTER_INFO(master, "%u slave(s) responding on %s device.\n", |
207 fsm->slaves_responding); |
212 fsm->slaves_responding[fsm->dev_idx], |
208 } |
213 ec_device_names[fsm->dev_idx]); |
209 |
214 } |
210 if (fsm->link_state && !master->main_device.link_state) { |
215 |
211 // link went down |
216 if (fsm->link_state[fsm->dev_idx] && |
|
217 !master->devices[fsm->dev_idx].link_state) { |
|
218 ec_device_index_t dev_idx; |
|
219 |
212 EC_MASTER_DBG(master, 1, "Master state machine detected " |
220 EC_MASTER_DBG(master, 1, "Master state machine detected " |
213 "link down. Clearing slave list.\n"); |
221 "link down on %s device. Clearing slave list.\n", |
|
222 ec_device_names[fsm->dev_idx]); |
214 |
223 |
215 #ifdef EC_EOE |
224 #ifdef EC_EOE |
216 ec_master_eoe_stop(master); |
225 ec_master_eoe_stop(master); |
217 ec_master_clear_eoe_handlers(master); |
226 ec_master_clear_eoe_handlers(master); |
218 #endif |
227 #endif |
219 ec_master_clear_slaves(master); |
228 ec_master_clear_slaves(master); |
220 fsm->slave_states = 0x00; |
229 |
221 fsm->slaves_responding = 0; /* reset to trigger rescan on next link |
230 for (dev_idx = EC_DEVICE_MAIN; dev_idx < EC_NUM_DEVICES; dev_idx++) { |
222 up. */ |
231 fsm->slave_states[dev_idx] = 0x00; |
223 } |
232 fsm->slaves_responding[dev_idx] = 0; /* Reset to trigger rescan on |
224 fsm->link_state = master->main_device.link_state; |
233 next link up. */ |
225 |
234 } |
226 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
235 } |
227 ec_fsm_master_restart(fsm); |
236 fsm->link_state[fsm->dev_idx] = master->devices[fsm->dev_idx].link_state; |
228 return; |
237 |
229 } |
238 if (datagram->state == EC_DATAGRAM_RECEIVED && |
230 |
239 fsm->slaves_responding[fsm->dev_idx]) { |
231 if (fsm->slaves_responding) { |
|
232 uint8_t states = EC_READ_U8(datagram->data); |
240 uint8_t states = EC_READ_U8(datagram->data); |
233 if (states != fsm->slave_states) { // slave states changed? |
241 if (states != fsm->slave_states[fsm->dev_idx]) { |
|
242 // slave states changed |
234 char state_str[EC_STATE_STRING_SIZE]; |
243 char state_str[EC_STATE_STRING_SIZE]; |
235 fsm->slave_states = states; |
244 fsm->slave_states[fsm->dev_idx] = states; |
236 ec_state_string(fsm->slave_states, state_str, 1); |
245 ec_state_string(states, state_str, 1); |
237 EC_MASTER_INFO(master, "Slave states: %s.\n", state_str); |
246 EC_MASTER_INFO(master, "Slave states on %s device: %s.\n", |
|
247 ec_device_names[fsm->dev_idx], state_str); |
238 } |
248 } |
239 } else { |
249 } else { |
240 fsm->slave_states = 0x00; |
250 fsm->slave_states[fsm->dev_idx] = 0x00; |
|
251 } |
|
252 |
|
253 fsm->dev_idx++; |
|
254 if (fsm->dev_idx < EC_NUM_DEVICES) { |
|
255 // check number of responding slaves on next device |
|
256 fsm->state = ec_fsm_master_state_start; |
|
257 fsm->state(fsm); // execute immediately |
|
258 return; |
241 } |
259 } |
242 |
260 |
243 if (fsm->rescan_required) { |
261 if (fsm->rescan_required) { |
244 down(&master->scan_sem); |
262 down(&master->scan_sem); |
245 if (!master->allow_scan) { |
263 if (!master->allow_scan) { |
246 up(&master->scan_sem); |
264 up(&master->scan_sem); |
247 } else { |
265 } else { |
|
266 unsigned int count = 0, next_dev_slave, ring_position; |
|
267 ec_device_index_t dev_idx; |
|
268 |
248 master->scan_busy = 1; |
269 master->scan_busy = 1; |
249 up(&master->scan_sem); |
270 up(&master->scan_sem); |
250 |
271 |
251 // clear all slaves and scan the bus |
272 // clear all slaves and scan the bus |
252 fsm->rescan_required = 0; |
273 fsm->rescan_required = 0; |
257 ec_master_eoe_stop(master); |
278 ec_master_eoe_stop(master); |
258 ec_master_clear_eoe_handlers(master); |
279 ec_master_clear_eoe_handlers(master); |
259 #endif |
280 #endif |
260 ec_master_clear_slaves(master); |
281 ec_master_clear_slaves(master); |
261 |
282 |
262 master->slave_count = fsm->slaves_responding; |
283 for (dev_idx = EC_DEVICE_MAIN; dev_idx < EC_NUM_DEVICES; |
263 |
284 dev_idx++) { |
264 if (!master->slave_count) { |
285 count += fsm->slaves_responding[dev_idx]; |
|
286 } |
|
287 |
|
288 if (!count) { |
265 // no slaves present -> finish state machine. |
289 // no slaves present -> finish state machine. |
266 master->scan_busy = 0; |
290 master->scan_busy = 0; |
267 wake_up_interruptible(&master->scan_queue); |
291 wake_up_interruptible(&master->scan_queue); |
268 ec_fsm_master_restart(fsm); |
292 ec_fsm_master_restart(fsm); |
269 return; |
293 return; |
270 } |
294 } |
271 |
295 |
272 size = sizeof(ec_slave_t) * master->slave_count; |
296 size = sizeof(ec_slave_t) * count; |
273 if (!(master->slaves = |
297 if (!(master->slaves = |
274 (ec_slave_t *) kmalloc(size, GFP_KERNEL))) { |
298 (ec_slave_t *) kmalloc(size, GFP_KERNEL))) { |
275 EC_MASTER_ERR(master, "Failed to allocate %u bytes" |
299 EC_MASTER_ERR(master, "Failed to allocate %u bytes" |
276 " of slave memory!\n", size); |
300 " of slave memory!\n", size); |
277 master->slave_count = 0; // TODO avoid retrying scan! |
|
278 master->scan_busy = 0; |
301 master->scan_busy = 0; |
279 wake_up_interruptible(&master->scan_queue); |
302 wake_up_interruptible(&master->scan_queue); |
280 ec_fsm_master_restart(fsm); |
303 ec_fsm_master_restart(fsm); |
281 return; |
304 return; |
282 } |
305 } |
283 |
306 |
284 // init slaves |
307 // init slaves |
285 for (i = 0; i < master->slave_count; i++) { |
308 dev_idx = EC_DEVICE_MAIN; |
|
309 next_dev_slave = fsm->slaves_responding[dev_idx]; |
|
310 ring_position = 0; |
|
311 for (i = 0; i < count; i++, ring_position++) { |
286 slave = master->slaves + i; |
312 slave = master->slaves + i; |
287 ec_slave_init(slave, master, i, i + 1); |
313 while (i >= next_dev_slave) { |
|
314 dev_idx++; |
|
315 next_dev_slave += fsm->slaves_responding[dev_idx]; |
|
316 ring_position = 0; |
|
317 } |
|
318 |
|
319 ec_slave_init(slave, master, dev_idx, ring_position, i + 1); |
288 |
320 |
289 // do not force reconfiguration in operation phase to avoid |
321 // do not force reconfiguration in operation phase to avoid |
290 // unnecesssary process data interruptions |
322 // unnecesssary process data interruptions |
291 if (master->phase != EC_OPERATION) |
323 if (master->phase != EC_OPERATION) { |
292 slave->force_config = 1; |
324 slave->force_config = 1; |
|
325 } |
293 } |
326 } |
294 |
327 master->slave_count = count; |
295 // broadcast clear all station addresses |
328 |
296 ec_datagram_bwr(datagram, 0x0010, 2); |
329 /* start with first device with slaves responding; at least one |
297 EC_WRITE_U16(datagram->data, 0x0000); |
330 * has responding slaves, otherwise count would be zero. */ |
298 fsm->retries = EC_FSM_RETRIES; |
331 fsm->dev_idx = EC_DEVICE_MAIN; |
299 fsm->state = ec_fsm_master_state_clear_addresses; |
332 while (!fsm->slaves_responding[fsm->dev_idx]) { |
|
333 fsm->dev_idx++; |
|
334 } |
|
335 |
|
336 ec_fsm_master_enter_clear_addresses(fsm); |
300 return; |
337 return; |
301 } |
338 } |
302 } |
339 } |
303 |
340 |
304 if (master->slave_count) { |
341 if (master->slave_count) { |
691 ec_fsm_master_action_configure(fsm); |
735 ec_fsm_master_action_configure(fsm); |
692 } |
736 } |
693 |
737 |
694 /*****************************************************************************/ |
738 /*****************************************************************************/ |
695 |
739 |
|
740 /** Start clearing slave addresses. |
|
741 */ |
|
742 void ec_fsm_master_enter_clear_addresses( |
|
743 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
744 ) |
|
745 { |
|
746 // broadcast clear all station addresses |
|
747 ec_datagram_bwr(fsm->datagram, 0x0010, 2); |
|
748 EC_WRITE_U16(fsm->datagram->data, 0x0000); |
|
749 fsm->datagram->device_index = fsm->dev_idx; |
|
750 fsm->retries = EC_FSM_RETRIES; |
|
751 fsm->state = ec_fsm_master_state_clear_addresses; |
|
752 } |
|
753 |
|
754 /*****************************************************************************/ |
|
755 |
696 /** Master state: CLEAR ADDRESSES. |
756 /** Master state: CLEAR ADDRESSES. |
697 */ |
757 */ |
698 void ec_fsm_master_state_clear_addresses( |
758 void ec_fsm_master_state_clear_addresses( |
699 ec_fsm_master_t *fsm /**< Master state machine. */ |
759 ec_fsm_master_t *fsm /**< Master state machine. */ |
700 ) |
760 ) |
701 { |
761 { |
702 ec_master_t *master = fsm->master; |
762 ec_master_t *master = fsm->master; |
703 ec_datagram_t *datagram = fsm->datagram; |
763 ec_datagram_t *datagram = fsm->datagram; |
704 |
764 |
705 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
765 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) { |
706 return; |
766 return; |
|
767 } |
707 |
768 |
708 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
769 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
709 EC_MASTER_ERR(master, "Failed to receive address" |
770 EC_MASTER_ERR(master, "Failed to receive address" |
710 " clearing datagram: "); |
771 " clearing datagram on %s link: ", |
|
772 ec_device_names[fsm->dev_idx]); |
711 ec_datagram_print_state(datagram); |
773 ec_datagram_print_state(datagram); |
712 master->scan_busy = 0; |
774 master->scan_busy = 0; |
713 wake_up_interruptible(&master->scan_queue); |
775 wake_up_interruptible(&master->scan_queue); |
714 ec_fsm_master_restart(fsm); |
776 ec_fsm_master_restart(fsm); |
715 return; |
777 return; |
716 } |
778 } |
717 |
779 |
718 if (datagram->working_counter != master->slave_count) { |
780 if (datagram->working_counter != fsm->slaves_responding[fsm->dev_idx]) { |
719 EC_MASTER_WARN(master, "Failed to clear all station addresses:" |
781 EC_MASTER_WARN(master, "Failed to clear station addresses on %s link:" |
720 " Cleared %u of %u", |
782 " Cleared %u of %u", |
721 datagram->working_counter, master->slave_count); |
783 ec_device_names[fsm->dev_idx], datagram->working_counter, |
|
784 fsm->slaves_responding[fsm->dev_idx]); |
722 } |
785 } |
723 |
786 |
724 EC_MASTER_DBG(master, 1, "Sending broadcast-write" |
787 EC_MASTER_DBG(master, 1, "Sending broadcast-write" |
725 " to measure transmission delays.\n"); |
788 " to measure transmission delays on %s link.\n", |
|
789 ec_device_names[fsm->dev_idx]); |
726 |
790 |
727 ec_datagram_bwr(datagram, 0x0900, 1); |
791 ec_datagram_bwr(datagram, 0x0900, 1); |
728 ec_datagram_zero(datagram); |
792 ec_datagram_zero(datagram); |
|
793 fsm->datagram->device_index = fsm->dev_idx; |
729 fsm->retries = EC_FSM_RETRIES; |
794 fsm->retries = EC_FSM_RETRIES; |
730 fsm->state = ec_fsm_master_state_dc_measure_delays; |
795 fsm->state = ec_fsm_master_state_dc_measure_delays; |
731 } |
796 } |
732 |
797 |
733 /*****************************************************************************/ |
798 /*****************************************************************************/ |
743 |
808 |
744 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
809 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
745 return; |
810 return; |
746 |
811 |
747 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
812 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
748 EC_MASTER_ERR(master, "Failed to receive delay measuring datagram: "); |
813 EC_MASTER_ERR(master, "Failed to receive delay measuring datagram" |
|
814 " on %s link: ", ec_device_names[fsm->dev_idx]); |
749 ec_datagram_print_state(datagram); |
815 ec_datagram_print_state(datagram); |
750 master->scan_busy = 0; |
816 master->scan_busy = 0; |
751 wake_up_interruptible(&master->scan_queue); |
817 wake_up_interruptible(&master->scan_queue); |
752 ec_fsm_master_restart(fsm); |
818 ec_fsm_master_restart(fsm); |
753 return; |
819 return; |
754 } |
820 } |
755 |
821 |
756 EC_MASTER_DBG(master, 1, "%u slaves responded to delay measuring.\n", |
822 EC_MASTER_DBG(master, 1, "%u slaves responded to delay measuring" |
757 datagram->working_counter); |
823 " on %s link.\n", |
|
824 datagram->working_counter, ec_device_names[fsm->dev_idx]); |
|
825 |
|
826 do { |
|
827 fsm->dev_idx++; |
|
828 } while (fsm->dev_idx < EC_NUM_DEVICES && |
|
829 !fsm->slaves_responding[fsm->dev_idx]); |
|
830 if (fsm->dev_idx < EC_NUM_DEVICES) { |
|
831 ec_fsm_master_enter_clear_addresses(fsm); |
|
832 return; |
|
833 } |
758 |
834 |
759 EC_MASTER_INFO(master, "Scanning bus.\n"); |
835 EC_MASTER_INFO(master, "Scanning bus.\n"); |
760 |
836 |
761 // begin scanning of slaves |
837 // begin scanning of slaves |
762 fsm->slave = master->slaves; |
838 fsm->slave = master->slaves; |
|
839 EC_MASTER_DBG(master, 1, "Scanning slave %u on %s link.\n", |
|
840 fsm->slave->ring_position, |
|
841 ec_device_names[fsm->slave->device_index]); |
763 fsm->state = ec_fsm_master_state_scan_slave; |
842 fsm->state = ec_fsm_master_state_scan_slave; |
764 ec_fsm_slave_scan_start(&fsm->fsm_slave_scan, fsm->slave); |
843 ec_fsm_slave_scan_start(&fsm->fsm_slave_scan, fsm->slave); |
765 ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan); // execute immediately |
844 ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan); // execute immediately |
|
845 fsm->datagram->device_index = fsm->slave->device_index; |
766 } |
846 } |
767 |
847 |
768 /*****************************************************************************/ |
848 /*****************************************************************************/ |
769 |
849 |
770 /** Master state: SCAN SLAVE. |
850 /** Master state: SCAN SLAVE. |
798 #endif |
880 #endif |
799 |
881 |
800 // another slave to fetch? |
882 // another slave to fetch? |
801 fsm->slave++; |
883 fsm->slave++; |
802 if (fsm->slave < master->slaves + master->slave_count) { |
884 if (fsm->slave < master->slaves + master->slave_count) { |
|
885 EC_MASTER_DBG(master, 1, "Scanning slave %u on %s link.\n", |
|
886 fsm->slave->ring_position, |
|
887 ec_device_names[fsm->slave->device_index]); |
803 ec_fsm_slave_scan_start(&fsm->fsm_slave_scan, fsm->slave); |
888 ec_fsm_slave_scan_start(&fsm->fsm_slave_scan, fsm->slave); |
804 ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan); // execute immediately |
889 ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan); // execute immediately |
|
890 fsm->datagram->device_index = fsm->slave->device_index; |
805 return; |
891 return; |
806 } |
892 } |
807 |
893 |
808 EC_MASTER_INFO(master, "Bus scanning completed in %lu ms.\n", |
894 EC_MASTER_INFO(master, "Bus scanning completed in %lu ms.\n", |
809 (jiffies - fsm->scan_jiffies) * 1000 / HZ); |
895 (jiffies - fsm->scan_jiffies) * 1000 / HZ); |
1029 |
1117 |
1030 // set DC system time offset and transmission delay |
1118 // set DC system time offset and transmission delay |
1031 ec_datagram_fpwr(datagram, slave->station_address, 0x0920, 12); |
1119 ec_datagram_fpwr(datagram, slave->station_address, 0x0920, 12); |
1032 EC_WRITE_U64(datagram->data, new_offset); |
1120 EC_WRITE_U64(datagram->data, new_offset); |
1033 EC_WRITE_U32(datagram->data + 8, slave->transmission_delay); |
1121 EC_WRITE_U32(datagram->data + 8, slave->transmission_delay); |
|
1122 fsm->datagram->device_index = slave->device_index; |
1034 fsm->retries = EC_FSM_RETRIES; |
1123 fsm->retries = EC_FSM_RETRIES; |
1035 fsm->state = ec_fsm_master_state_dc_write_offset; |
1124 fsm->state = ec_fsm_master_state_dc_write_offset; |
1036 } |
1125 } |
1037 |
1126 |
1038 /*****************************************************************************/ |
1127 /*****************************************************************************/ |