changeset 1989 | 6aa393418fb3 |
parent 1927 | 365a90e93161 |
child 1995 | 7d748d9cf9e8 |
1988:ea38efeeb7b3 | 1989:6aa393418fb3 |
---|---|
41 #include "ethernet.h" |
41 #include "ethernet.h" |
42 #endif |
42 #endif |
43 |
43 |
44 #include "fsm_master.h" |
44 #include "fsm_master.h" |
45 #include "fsm_foe.h" |
45 #include "fsm_foe.h" |
46 |
|
47 /*****************************************************************************/ |
|
48 |
|
49 /** Time difference [ns] to tolerate without setting a new system time offset. |
|
50 */ |
|
51 #define EC_SYSTEM_TIME_TOLERANCE_NS 100000000 |
|
46 |
52 |
47 /*****************************************************************************/ |
53 /*****************************************************************************/ |
48 |
54 |
49 void ec_fsm_master_state_start(ec_fsm_master_t *); |
55 void ec_fsm_master_state_start(ec_fsm_master_t *); |
50 void ec_fsm_master_state_broadcast(ec_fsm_master_t *); |
56 void ec_fsm_master_state_broadcast(ec_fsm_master_t *); |
52 void ec_fsm_master_state_acknowledge(ec_fsm_master_t *); |
58 void ec_fsm_master_state_acknowledge(ec_fsm_master_t *); |
53 void ec_fsm_master_state_configure_slave(ec_fsm_master_t *); |
59 void ec_fsm_master_state_configure_slave(ec_fsm_master_t *); |
54 void ec_fsm_master_state_clear_addresses(ec_fsm_master_t *); |
60 void ec_fsm_master_state_clear_addresses(ec_fsm_master_t *); |
55 void ec_fsm_master_state_dc_measure_delays(ec_fsm_master_t *); |
61 void ec_fsm_master_state_dc_measure_delays(ec_fsm_master_t *); |
56 void ec_fsm_master_state_scan_slave(ec_fsm_master_t *); |
62 void ec_fsm_master_state_scan_slave(ec_fsm_master_t *); |
63 void ec_fsm_master_state_dc_read_offset(ec_fsm_master_t *); |
|
64 void ec_fsm_master_state_dc_write_offset(ec_fsm_master_t *); |
|
57 void ec_fsm_master_state_write_sii(ec_fsm_master_t *); |
65 void ec_fsm_master_state_write_sii(ec_fsm_master_t *); |
58 void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *); |
66 void ec_fsm_master_state_sdo_dictionary(ec_fsm_master_t *); |
59 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *); |
67 void ec_fsm_master_state_sdo_request(ec_fsm_master_t *); |
60 void ec_fsm_master_state_reg_request(ec_fsm_master_t *); |
68 void ec_fsm_master_state_reg_request(ec_fsm_master_t *); |
61 |
69 |
70 void ec_fsm_master_enter_write_system_times(ec_fsm_master_t *); |
|
62 |
71 |
63 /*****************************************************************************/ |
72 /*****************************************************************************/ |
64 |
73 |
65 /** Constructor. |
74 /** Constructor. |
66 */ |
75 */ |
192 |
201 |
193 // bus topology change? |
202 // bus topology change? |
194 if (datagram->working_counter != fsm->slaves_responding) { |
203 if (datagram->working_counter != fsm->slaves_responding) { |
195 fsm->topology_change_pending = 1; |
204 fsm->topology_change_pending = 1; |
196 fsm->slaves_responding = datagram->working_counter; |
205 fsm->slaves_responding = datagram->working_counter; |
197 EC_INFO("%u slave(s) responding.\n", fsm->slaves_responding); |
206 EC_MASTER_INFO(master, "%u slave(s) responding.\n", |
207 fsm->slaves_responding); |
|
198 } |
208 } |
199 |
209 |
200 if (fsm->link_state && !master->main_device.link_state) { // link went down |
210 if (fsm->link_state && !master->main_device.link_state) { // link went down |
201 if (master->debug_level) { |
211 EC_MASTER_DBG(master, 1, "Master state machine detected " |
202 EC_DBG("Master state machine detected " |
212 "link down. Clearing slave list.\n"); |
203 "link down. Clearing slave list.\n"); |
|
204 } |
|
205 |
213 |
206 #ifdef EC_EOE |
214 #ifdef EC_EOE |
207 ec_master_eoe_stop(master); |
215 ec_master_eoe_stop(master); |
208 ec_master_clear_eoe_handlers(master); |
216 ec_master_clear_eoe_handlers(master); |
209 #endif |
217 #endif |
221 uint8_t states = EC_READ_U8(datagram->data); |
229 uint8_t states = EC_READ_U8(datagram->data); |
222 if (states != fsm->slave_states) { // slave states changed? |
230 if (states != fsm->slave_states) { // slave states changed? |
223 char state_str[EC_STATE_STRING_SIZE]; |
231 char state_str[EC_STATE_STRING_SIZE]; |
224 fsm->slave_states = states; |
232 fsm->slave_states = states; |
225 ec_state_string(fsm->slave_states, state_str, 1); |
233 ec_state_string(fsm->slave_states, state_str, 1); |
226 EC_INFO("Slave states: %s.\n", state_str); |
234 EC_MASTER_INFO(master, "Slave states: %s.\n", state_str); |
227 } |
235 } |
228 } else { |
236 } else { |
229 fsm->slave_states = 0x00; |
237 fsm->slave_states = 0x00; |
230 } |
238 } |
231 |
239 |
259 return; |
267 return; |
260 } |
268 } |
261 |
269 |
262 size = sizeof(ec_slave_t) * master->slave_count; |
270 size = sizeof(ec_slave_t) * master->slave_count; |
263 if (!(master->slaves = (ec_slave_t *) kmalloc(size, GFP_KERNEL))) { |
271 if (!(master->slaves = (ec_slave_t *) kmalloc(size, GFP_KERNEL))) { |
264 EC_ERR("Failed to allocate %u bytes of slave memory!\n", |
272 EC_MASTER_ERR(master, "Failed to allocate %u bytes" |
265 size); |
273 " of slave memory!\n", size); |
266 master->slave_count = 0; // TODO avoid retrying scan! |
274 master->slave_count = 0; // TODO avoid retrying scan! |
267 master->scan_busy = 0; |
275 master->scan_busy = 0; |
268 wake_up_interruptible(&master->scan_queue); |
276 wake_up_interruptible(&master->scan_queue); |
269 ec_fsm_master_restart(fsm); |
277 ec_fsm_master_restart(fsm); |
270 return; |
278 return; |
289 return; |
297 return; |
290 } |
298 } |
291 } |
299 } |
292 |
300 |
293 if (master->slave_count) { |
301 if (master->slave_count) { |
294 // fetch state from first slave |
302 |
295 fsm->slave = master->slaves; |
303 // application applied configurations |
296 ec_datagram_fprd(fsm->datagram, fsm->slave->station_address, |
304 if (master->config_changed) { |
297 0x0130, 2); |
305 master->config_changed = 0; |
298 ec_datagram_zero(datagram); |
306 |
299 fsm->retries = EC_FSM_RETRIES; |
307 EC_MASTER_DBG(master, 1, "Configuration changed.\n"); |
300 fsm->state = ec_fsm_master_state_read_state; |
308 |
309 fsm->slave = master->slaves; // begin with first slave |
|
310 ec_fsm_master_enter_write_system_times(fsm); |
|
311 |
|
312 } else { |
|
313 // fetch state from first slave |
|
314 fsm->slave = master->slaves; |
|
315 ec_datagram_fprd(fsm->datagram, fsm->slave->station_address, |
|
316 0x0130, 2); |
|
317 ec_datagram_zero(datagram); |
|
318 fsm->retries = EC_FSM_RETRIES; |
|
319 fsm->state = ec_fsm_master_state_read_state; |
|
320 } |
|
301 } else { |
321 } else { |
302 ec_fsm_master_restart(fsm); |
322 ec_fsm_master_restart(fsm); |
303 } |
323 } |
304 } |
324 } |
305 |
325 |
326 ec_sii_write_request_t, list); |
346 ec_sii_write_request_t, list); |
327 list_del_init(&request->list); // dequeue |
347 list_del_init(&request->list); // dequeue |
328 request->state = EC_INT_REQUEST_BUSY; |
348 request->state = EC_INT_REQUEST_BUSY; |
329 |
349 |
330 // found pending SII write operation. execute it! |
350 // found pending SII write operation. execute it! |
331 if (master->debug_level) |
351 EC_SLAVE_DBG(request->slave, 1, "Writing SII data...\n"); |
332 EC_DBG("Writing SII data to slave %u...\n", |
|
333 request->slave->ring_position); |
|
334 fsm->sii_request = request; |
352 fsm->sii_request = request; |
335 fsm->sii_index = 0; |
353 fsm->sii_index = 0; |
336 ec_fsm_sii_write(&fsm->fsm_sii, request->slave, request->offset, |
354 ec_fsm_sii_write(&fsm->fsm_sii, request->slave, request->offset, |
337 request->words, EC_FSM_SII_USE_CONFIGURED_ADDRESS); |
355 request->words, EC_FSM_SII_USE_CONFIGURED_ADDRESS); |
338 fsm->state = ec_fsm_master_state_write_sii; |
356 fsm->state = ec_fsm_master_state_write_sii; |
364 ec_reg_request_t, list); |
382 ec_reg_request_t, list); |
365 list_del_init(&request->list); // dequeue |
383 list_del_init(&request->list); // dequeue |
366 request->state = EC_INT_REQUEST_BUSY; |
384 request->state = EC_INT_REQUEST_BUSY; |
367 |
385 |
368 // found pending request; process it! |
386 // found pending request; process it! |
369 if (master->debug_level) |
387 EC_SLAVE_DBG(request->slave, 1, "Processing register request, " |
370 EC_DBG("Processing register request for slave %u, " |
388 "offset 0x%04x, length %zu...\n", |
371 "offset 0x%04x, length %zu...\n", |
389 request->offset, request->length); |
372 request->slave->ring_position, |
|
373 request->offset, request->length); |
|
374 |
390 |
375 if (request->length > fsm->datagram->mem_size) { |
391 if (request->length > fsm->datagram->mem_size) { |
376 EC_ERR("Request length (%zu) exceeds maximum " |
392 EC_MASTER_ERR(master, "Request length (%zu) exceeds maximum " |
377 "datagram size (%zu)!\n", request->length, |
393 "datagram size (%zu)!\n", request->length, |
378 fsm->datagram->mem_size); |
394 fsm->datagram->mem_size); |
379 request->state = EC_INT_REQUEST_FAILURE; |
395 request->state = EC_INT_REQUEST_FAILURE; |
380 wake_up(&master->reg_queue); |
396 wake_up(&master->reg_queue); |
381 continue; |
397 continue; |
423 list_for_each_entry(req, &slave->config->sdo_requests, list) { |
439 list_for_each_entry(req, &slave->config->sdo_requests, list) { |
424 if (req->state == EC_INT_REQUEST_QUEUED) { |
440 if (req->state == EC_INT_REQUEST_QUEUED) { |
425 |
441 |
426 if (ec_sdo_request_timed_out(req)) { |
442 if (ec_sdo_request_timed_out(req)) { |
427 req->state = EC_INT_REQUEST_FAILURE; |
443 req->state = EC_INT_REQUEST_FAILURE; |
428 if (master->debug_level) |
444 EC_SLAVE_DBG(slave, 1, "Internal SDO request" |
429 EC_DBG("Internal SDO request for slave %u" |
445 " timed out.\n"); |
430 " timed out...\n", slave->ring_position); |
|
431 continue; |
446 continue; |
432 } |
447 } |
433 |
448 |
434 if (slave->current_state == EC_SLAVE_STATE_INIT) { |
449 if (slave->current_state == EC_SLAVE_STATE_INIT) { |
435 req->state = EC_INT_REQUEST_FAILURE; |
450 req->state = EC_INT_REQUEST_FAILURE; |
436 continue; |
451 continue; |
437 } |
452 } |
438 |
453 |
439 req->state = EC_INT_REQUEST_BUSY; |
454 req->state = EC_INT_REQUEST_BUSY; |
440 if (master->debug_level) |
455 EC_SLAVE_DBG(slave, 1, "Processing internal" |
441 EC_DBG("Processing internal SDO request for slave %u...\n", |
456 " SDO request...\n"); |
442 slave->ring_position); |
|
443 |
|
444 fsm->idle = 0; |
457 fsm->idle = 0; |
445 fsm->sdo_request = req; |
458 fsm->sdo_request = req; |
446 fsm->slave = slave; |
459 fsm->slave = slave; |
447 fsm->state = ec_fsm_master_state_sdo_request; |
460 fsm->state = ec_fsm_master_state_sdo_request; |
448 ec_fsm_coe_transfer(&fsm->fsm_coe, slave, req); |
461 ec_fsm_coe_transfer(&fsm->fsm_coe, slave, req); |
490 || slave->current_state == EC_SLAVE_STATE_INIT |
503 || slave->current_state == EC_SLAVE_STATE_INIT |
491 || slave->current_state == EC_SLAVE_STATE_UNKNOWN |
504 || slave->current_state == EC_SLAVE_STATE_UNKNOWN |
492 || jiffies - slave->jiffies_preop < EC_WAIT_SDO_DICT * HZ |
505 || jiffies - slave->jiffies_preop < EC_WAIT_SDO_DICT * HZ |
493 ) continue; |
506 ) continue; |
494 |
507 |
495 if (master->debug_level) { |
508 EC_SLAVE_DBG(slave, 1, "Fetching SDO dictionary.\n"); |
496 EC_DBG("Fetching SDO dictionary from slave %u.\n", |
|
497 slave->ring_position); |
|
498 } |
|
499 |
509 |
500 slave->sdo_dictionary_fetched = 1; |
510 slave->sdo_dictionary_fetched = 1; |
501 |
511 |
502 // start fetching SDO dictionary |
512 // start fetching SDO dictionary |
503 fsm->idle = 0; |
513 fsm->idle = 0; |
572 if (master->debug_level) { |
582 if (master->debug_level) { |
573 char old_state[EC_STATE_STRING_SIZE], |
583 char old_state[EC_STATE_STRING_SIZE], |
574 new_state[EC_STATE_STRING_SIZE]; |
584 new_state[EC_STATE_STRING_SIZE]; |
575 ec_state_string(slave->current_state, old_state, 0); |
585 ec_state_string(slave->current_state, old_state, 0); |
576 ec_state_string(slave->requested_state, new_state, 0); |
586 ec_state_string(slave->requested_state, new_state, 0); |
577 EC_DBG("Changing state of slave %u from %s to %s%s.\n", |
587 EC_SLAVE_DBG(slave, 1, "Changing state from %s to %s%s.\n", |
578 slave->ring_position, old_state, new_state, |
588 old_state, new_state, |
579 slave->force_config ? " (forced)" : ""); |
589 slave->force_config ? " (forced)" : ""); |
580 } |
590 } |
581 |
591 |
582 fsm->idle = 0; |
592 fsm->idle = 0; |
583 fsm->state = ec_fsm_master_state_configure_slave; |
593 fsm->state = ec_fsm_master_state_configure_slave; |
606 |
616 |
607 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
617 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
608 return; |
618 return; |
609 |
619 |
610 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
620 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
611 EC_ERR("Failed to receive AL state datagram for slave %u: ", |
621 EC_SLAVE_ERR(slave, "Failed to receive AL state datagram: "); |
612 slave->ring_position); |
|
613 ec_datagram_print_state(datagram); |
622 ec_datagram_print_state(datagram); |
614 ec_fsm_master_restart(fsm); |
623 ec_fsm_master_restart(fsm); |
615 return; |
624 return; |
616 } |
625 } |
617 |
626 |
618 // did the slave not respond to its station address? |
627 // did the slave not respond to its station address? |
619 if (datagram->working_counter != 1) { |
628 if (datagram->working_counter != 1) { |
620 if (!slave->error_flag) { |
629 if (!slave->error_flag) { |
621 slave->error_flag = 1; |
630 slave->error_flag = 1; |
622 if (fsm->master->debug_level) |
631 EC_SLAVE_DBG(slave, 1, "Slave did not respond to state query.\n"); |
623 EC_DBG("Slave %u did not respond to state query.\n", |
|
624 fsm->slave->ring_position); |
|
625 } |
632 } |
626 fsm->topology_change_pending = 1; |
633 fsm->topology_change_pending = 1; |
627 ec_fsm_master_restart(fsm); |
634 ec_fsm_master_restart(fsm); |
628 return; |
635 return; |
629 } |
636 } |
663 if (ec_fsm_change_exec(&fsm->fsm_change)) |
670 if (ec_fsm_change_exec(&fsm->fsm_change)) |
664 return; |
671 return; |
665 |
672 |
666 if (!ec_fsm_change_success(&fsm->fsm_change)) { |
673 if (!ec_fsm_change_success(&fsm->fsm_change)) { |
667 fsm->slave->error_flag = 1; |
674 fsm->slave->error_flag = 1; |
668 EC_ERR("Failed to acknowledge state change on slave %u.\n", |
675 EC_SLAVE_ERR(slave, "Failed to acknowledge state change.\n"); |
669 slave->ring_position); |
|
670 } |
676 } |
671 |
677 |
672 ec_fsm_master_action_configure(fsm); |
678 ec_fsm_master_action_configure(fsm); |
673 } |
679 } |
674 |
680 |
685 |
691 |
686 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
692 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
687 return; |
693 return; |
688 |
694 |
689 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
695 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
690 EC_ERR("Failed to receive address clearing datagram (state %u).\n", |
696 EC_MASTER_ERR(master, "Failed to receive address" |
691 datagram->state); |
697 " clearing datagram: "); |
698 ec_datagram_print_state(datagram); |
|
692 master->scan_busy = 0; |
699 master->scan_busy = 0; |
693 wake_up_interruptible(&master->scan_queue); |
700 wake_up_interruptible(&master->scan_queue); |
694 ec_fsm_master_restart(fsm); |
701 ec_fsm_master_restart(fsm); |
695 return; |
702 return; |
696 } |
703 } |
697 |
704 |
698 if (datagram->working_counter != master->slave_count) { |
705 if (datagram->working_counter != master->slave_count) { |
699 EC_WARN("Failed to clear all station addresses: Cleared %u of %u", |
706 EC_MASTER_WARN(master, "Failed to clear all station addresses:" |
707 " Cleared %u of %u", |
|
700 datagram->working_counter, master->slave_count); |
708 datagram->working_counter, master->slave_count); |
701 } |
709 } |
702 |
710 |
703 if (master->debug_level) |
711 EC_MASTER_DBG(master, 1, "Sending broadcast-write" |
704 EC_DBG("Sending broadcast-write to measure transmission delays.\n"); |
712 " to measure transmission delays.\n"); |
705 |
713 |
706 ec_datagram_bwr(datagram, 0x0900, 1); |
714 ec_datagram_bwr(datagram, 0x0900, 1); |
707 ec_datagram_zero(datagram); |
715 ec_datagram_zero(datagram); |
708 fsm->retries = EC_FSM_RETRIES; |
716 fsm->retries = EC_FSM_RETRIES; |
709 fsm->state = ec_fsm_master_state_dc_measure_delays; |
717 fsm->state = ec_fsm_master_state_dc_measure_delays; |
722 |
730 |
723 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
731 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
724 return; |
732 return; |
725 |
733 |
726 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
734 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
727 EC_ERR("Failed to receive delay measuring datagram (state %u).\n", |
735 EC_MASTER_ERR(master, "Failed to receive delay measuring datagram: "); |
728 datagram->state); |
736 ec_datagram_print_state(datagram); |
729 master->scan_busy = 0; |
737 master->scan_busy = 0; |
730 wake_up_interruptible(&master->scan_queue); |
738 wake_up_interruptible(&master->scan_queue); |
731 ec_fsm_master_restart(fsm); |
739 ec_fsm_master_restart(fsm); |
732 return; |
740 return; |
733 } |
741 } |
734 |
742 |
735 if (master->debug_level) |
743 EC_MASTER_DBG(master, 1, "%u slaves responded to delay measuring.\n", |
736 EC_DBG("%u slaves responded to delay measuring.\n", |
744 datagram->working_counter); |
737 datagram->working_counter); |
745 |
738 |
746 EC_MASTER_INFO(master, "Scanning bus.\n"); |
739 EC_INFO("Scanning bus.\n"); |
|
740 |
747 |
741 // begin scanning of slaves |
748 // begin scanning of slaves |
742 fsm->slave = master->slaves; |
749 fsm->slave = master->slaves; |
743 fsm->state = ec_fsm_master_state_scan_slave; |
750 fsm->state = ec_fsm_master_state_scan_slave; |
744 ec_fsm_slave_scan_start(&fsm->fsm_slave_scan, fsm->slave); |
751 ec_fsm_slave_scan_start(&fsm->fsm_slave_scan, fsm->slave); |
765 #ifdef EC_EOE |
772 #ifdef EC_EOE |
766 if (slave->sii.mailbox_protocols & EC_MBOX_EOE) { |
773 if (slave->sii.mailbox_protocols & EC_MBOX_EOE) { |
767 // create EoE handler for this slave |
774 // create EoE handler for this slave |
768 ec_eoe_t *eoe; |
775 ec_eoe_t *eoe; |
769 if (!(eoe = kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) { |
776 if (!(eoe = kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) { |
770 EC_ERR("Failed to allocate EoE handler memory for slave %u!\n", |
777 EC_SLAVE_ERR(slave, "Failed to allocate EoE handler memory!\n"); |
771 slave->ring_position); |
|
772 } else if (ec_eoe_init(eoe, slave)) { |
778 } else if (ec_eoe_init(eoe, slave)) { |
773 EC_ERR("Failed to init EoE handler for slave %u!\n", |
779 EC_SLAVE_ERR(slave, "Failed to init EoE handler!\n"); |
774 slave->ring_position); |
|
775 kfree(eoe); |
780 kfree(eoe); |
776 } else { |
781 } else { |
777 list_add_tail(&eoe->list, &master->eoe_handlers); |
782 list_add_tail(&eoe->list, &master->eoe_handlers); |
778 } |
783 } |
779 } |
784 } |
785 ec_fsm_slave_scan_start(&fsm->fsm_slave_scan, fsm->slave); |
790 ec_fsm_slave_scan_start(&fsm->fsm_slave_scan, fsm->slave); |
786 ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan); // execute immediately |
791 ec_fsm_slave_scan_exec(&fsm->fsm_slave_scan); // execute immediately |
787 return; |
792 return; |
788 } |
793 } |
789 |
794 |
790 EC_INFO("Bus scanning completed in %u ms.\n", |
795 EC_MASTER_INFO(master, "Bus scanning completed in %u ms.\n", |
791 (u32) (jiffies - fsm->scan_jiffies) * 1000 / HZ); |
796 (u32) (jiffies - fsm->scan_jiffies) * 1000 / HZ); |
792 |
797 |
793 master->scan_busy = 0; |
798 master->scan_busy = 0; |
794 wake_up_interruptible(&master->scan_queue); |
799 wake_up_interruptible(&master->scan_queue); |
795 |
800 |
801 #ifdef EC_EOE |
806 #ifdef EC_EOE |
802 // check if EoE processing has to be started |
807 // check if EoE processing has to be started |
803 ec_master_eoe_start(master); |
808 ec_master_eoe_start(master); |
804 #endif |
809 #endif |
805 |
810 |
806 ec_fsm_master_restart(fsm); |
811 if (master->slave_count) { |
812 fsm->slave = master->slaves; // begin with first slave |
|
813 ec_fsm_master_enter_write_system_times(fsm); |
|
814 } else { |
|
815 ec_fsm_master_restart(fsm); |
|
816 } |
|
807 } |
817 } |
808 |
818 |
809 /*****************************************************************************/ |
819 /*****************************************************************************/ |
810 |
820 |
811 /** Master state: CONFIGURE SLAVE. |
821 /** Master state: CONFIGURE SLAVE. |
835 ec_fsm_master_action_next_slave_state(fsm); |
845 ec_fsm_master_action_next_slave_state(fsm); |
836 } |
846 } |
837 |
847 |
838 /*****************************************************************************/ |
848 /*****************************************************************************/ |
839 |
849 |
850 /** Start writing DC system times. |
|
851 */ |
|
852 void ec_fsm_master_enter_write_system_times( |
|
853 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
854 ) |
|
855 { |
|
856 ec_master_t *master = fsm->master; |
|
857 |
|
858 EC_MASTER_DBG(master, 1, "Writing system time offsets...\n"); |
|
859 |
|
860 if (master->has_app_time) { |
|
861 while (fsm->slave < master->slaves + master->slave_count) { |
|
862 if (!fsm->slave->base_dc_supported |
|
863 || !fsm->slave->has_dc_system_time) { |
|
864 fsm->slave++; |
|
865 continue; |
|
866 } |
|
867 |
|
868 // read DC system time (0x0910, 64 bit) |
|
869 // gap (64 bit) |
|
870 // and time offset (0x0920, 64 bit) |
|
871 ec_datagram_fprd(fsm->datagram, fsm->slave->station_address, |
|
872 0x0910, 24); |
|
873 fsm->retries = EC_FSM_RETRIES; |
|
874 fsm->state = ec_fsm_master_state_dc_read_offset; |
|
875 return; |
|
876 } |
|
877 } else { |
|
878 EC_MASTER_DBG(master, 1, "No app_time received up to now.\n"); |
|
879 } |
|
880 |
|
881 ec_master_request_op(master); |
|
882 ec_fsm_master_restart(fsm); |
|
883 } |
|
884 |
|
885 /*****************************************************************************/ |
|
886 |
|
887 /** Configure 32 bit time offset. |
|
888 */ |
|
889 u64 ec_fsm_master_dc_offset32( |
|
890 ec_fsm_master_t *fsm, /**< Master state machine. */ |
|
891 u64 system_time, /**< System time register. */ |
|
892 u64 old_offset, /**< Time offset register. */ |
|
893 u64 correction /**< Correction. */ |
|
894 ) |
|
895 { |
|
896 ec_slave_t *slave = fsm->slave; |
|
897 u32 correction32, system_time32, old_offset32, new_offset; |
|
898 s32 time_diff; |
|
899 |
|
900 system_time32 = (u32) system_time; |
|
901 // correct read system time by elapsed time between read operation |
|
902 // and app_time set time |
|
903 correction32 = (u32)correction; |
|
904 system_time32 -= correction32; |
|
905 old_offset32 = (u32) old_offset; |
|
906 |
|
907 time_diff = (u32) slave->master->app_time - system_time32; |
|
908 |
|
909 EC_SLAVE_DBG(slave, 1, "DC system time offset calculation:" |
|
910 " system_time=%u (corrected with %u)," |
|
911 " app_time=%u, diff=%i\n", |
|
912 system_time32, correction32, |
|
913 (u32) slave->master->app_time, time_diff); |
|
914 |
|
915 if (EC_ABS(time_diff) > EC_SYSTEM_TIME_TOLERANCE_NS) { |
|
916 new_offset = time_diff + old_offset32; |
|
917 EC_SLAVE_DBG(slave, 1, "Setting time offset to %u (was %u)\n", |
|
918 new_offset, old_offset32); |
|
919 return (u64) new_offset; |
|
920 } else { |
|
921 EC_SLAVE_DBG(slave, 1, "Not touching time offset.\n"); |
|
922 return old_offset; |
|
923 } |
|
924 } |
|
925 |
|
926 /*****************************************************************************/ |
|
927 |
|
928 /** Configure 64 bit time offset. |
|
929 */ |
|
930 u64 ec_fsm_master_dc_offset64( |
|
931 ec_fsm_master_t *fsm, /**< Master state machine. */ |
|
932 u64 system_time, /**< System time register. */ |
|
933 u64 old_offset, /**< Time offset register. */ |
|
934 u64 correction /**< Correction. */ |
|
935 ) |
|
936 { |
|
937 ec_slave_t *slave = fsm->slave; |
|
938 u64 new_offset; |
|
939 s64 time_diff; |
|
940 |
|
941 // correct read system time by elapsed time between read operation |
|
942 // and app_time set time |
|
943 system_time -= correction; |
|
944 time_diff = fsm->slave->master->app_time - system_time; |
|
945 |
|
946 EC_SLAVE_DBG(slave, 1, "DC system time offset calculation:" |
|
947 " system_time=%llu (corrected with %llu)," |
|
948 " app_time=%llu, diff=%lli\n", |
|
949 system_time, correction, |
|
950 slave->master->app_time, time_diff); |
|
951 |
|
952 if (EC_ABS(time_diff) > EC_SYSTEM_TIME_TOLERANCE_NS) { |
|
953 new_offset = time_diff + old_offset; |
|
954 EC_SLAVE_DBG(slave, 1, "Setting time offset to %llu (was %llu)\n", |
|
955 new_offset, old_offset); |
|
956 } else { |
|
957 new_offset = old_offset; |
|
958 EC_SLAVE_DBG(slave, 1, "Not touching time offset.\n"); |
|
959 } |
|
960 |
|
961 return new_offset; |
|
962 } |
|
963 |
|
964 /*****************************************************************************/ |
|
965 |
|
966 /** Master state: DC READ OFFSET. |
|
967 */ |
|
968 void ec_fsm_master_state_dc_read_offset( |
|
969 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
970 ) |
|
971 { |
|
972 ec_datagram_t *datagram = fsm->datagram; |
|
973 ec_slave_t *slave = fsm->slave; |
|
974 u64 system_time, old_offset, new_offset, correction; |
|
975 |
|
976 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
|
977 return; |
|
978 |
|
979 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
|
980 EC_SLAVE_ERR(slave, "Failed to receive DC times datagram: "); |
|
981 ec_datagram_print_state(datagram); |
|
982 fsm->slave++; |
|
983 ec_fsm_master_enter_write_system_times(fsm); |
|
984 return; |
|
985 } |
|
986 |
|
987 if (datagram->working_counter != 1) { |
|
988 EC_SLAVE_WARN(slave, "Failed to get DC times: "); |
|
989 ec_datagram_print_wc_error(datagram); |
|
990 fsm->slave++; |
|
991 ec_fsm_master_enter_write_system_times(fsm); |
|
992 return; |
|
993 } |
|
994 |
|
995 system_time = EC_READ_U64(datagram->data); // 0x0910 |
|
996 old_offset = EC_READ_U64(datagram->data + 16); // 0x0920 |
|
997 /* correct read system time by elapsed time since read operation |
|
998 and the app_time set time */ |
|
999 #ifdef EC_HAVE_CYCLES |
|
1000 correction = |
|
1001 (datagram->cycles_sent - slave->master->dc_cycles_app_time) |
|
1002 * 1000000LL; |
|
1003 do_div(correction,cpu_khz); |
|
1004 #else |
|
1005 correction = |
|
1006 (u64) ((datagram->jiffies_sent-slave->master->dc_jiffies_app_time) * 1000 / HZ) |
|
1007 * 1000000; |
|
1008 #endif |
|
1009 |
|
1010 if (slave->base_dc_range == EC_DC_32) { |
|
1011 new_offset = ec_fsm_master_dc_offset32(fsm, |
|
1012 system_time, old_offset, correction); |
|
1013 } else { |
|
1014 new_offset = ec_fsm_master_dc_offset64(fsm, |
|
1015 system_time, old_offset, correction); |
|
1016 } |
|
1017 |
|
1018 // set DC system time offset and transmission delay |
|
1019 ec_datagram_fpwr(datagram, slave->station_address, 0x0920, 12); |
|
1020 EC_WRITE_U64(datagram->data, new_offset); |
|
1021 EC_WRITE_U32(datagram->data + 8, slave->transmission_delay); |
|
1022 fsm->retries = EC_FSM_RETRIES; |
|
1023 fsm->state = ec_fsm_master_state_dc_write_offset; |
|
1024 } |
|
1025 |
|
1026 /*****************************************************************************/ |
|
1027 |
|
1028 /** Master state: DC WRITE OFFSET. |
|
1029 */ |
|
1030 void ec_fsm_master_state_dc_write_offset( |
|
1031 ec_fsm_master_t *fsm /**< Master state machine. */ |
|
1032 ) |
|
1033 { |
|
1034 ec_datagram_t *datagram = fsm->datagram; |
|
1035 ec_slave_t *slave = fsm->slave; |
|
1036 |
|
1037 if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) |
|
1038 return; |
|
1039 |
|
1040 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
|
1041 EC_SLAVE_ERR(slave, |
|
1042 "Failed to receive DC system time offset datagram: "); |
|
1043 ec_datagram_print_state(datagram); |
|
1044 fsm->slave++; |
|
1045 ec_fsm_master_enter_write_system_times(fsm); |
|
1046 return; |
|
1047 } |
|
1048 |
|
1049 if (datagram->working_counter != 1) { |
|
1050 EC_SLAVE_ERR(slave, "Failed to set DC system time offset: "); |
|
1051 ec_datagram_print_wc_error(datagram); |
|
1052 fsm->slave++; |
|
1053 ec_fsm_master_enter_write_system_times(fsm); |
|
1054 return; |
|
1055 } |
|
1056 |
|
1057 fsm->slave++; |
|
1058 ec_fsm_master_enter_write_system_times(fsm); |
|
1059 } |
|
1060 |
|
1061 /*****************************************************************************/ |
|
1062 |
|
840 /** Master state: WRITE SII. |
1063 /** Master state: WRITE SII. |
841 */ |
1064 */ |
842 void ec_fsm_master_state_write_sii( |
1065 void ec_fsm_master_state_write_sii( |
843 ec_fsm_master_t *fsm /**< Master state machine. */ |
1066 ec_fsm_master_t *fsm /**< Master state machine. */ |
844 ) |
1067 ) |
848 ec_slave_t *slave = request->slave; |
1071 ec_slave_t *slave = request->slave; |
849 |
1072 |
850 if (ec_fsm_sii_exec(&fsm->fsm_sii)) return; |
1073 if (ec_fsm_sii_exec(&fsm->fsm_sii)) return; |
851 |
1074 |
852 if (!ec_fsm_sii_success(&fsm->fsm_sii)) { |
1075 if (!ec_fsm_sii_success(&fsm->fsm_sii)) { |
853 EC_ERR("Failed to write SII data to slave %u.\n", |
1076 EC_SLAVE_ERR(slave, "Failed to write SII data.\n"); |
854 slave->ring_position); |
|
855 request->state = EC_INT_REQUEST_FAILURE; |
1077 request->state = EC_INT_REQUEST_FAILURE; |
856 wake_up(&master->sii_queue); |
1078 wake_up(&master->sii_queue); |
857 ec_fsm_master_restart(fsm); |
1079 ec_fsm_master_restart(fsm); |
858 return; |
1080 return; |
859 } |
1081 } |
867 ec_fsm_sii_exec(&fsm->fsm_sii); // execute immediately |
1089 ec_fsm_sii_exec(&fsm->fsm_sii); // execute immediately |
868 return; |
1090 return; |
869 } |
1091 } |
870 |
1092 |
871 // finished writing SII |
1093 // finished writing SII |
872 if (master->debug_level) |
1094 EC_SLAVE_DBG(slave, 1, "Finished writing %zu words of SII data.\n", |
873 EC_DBG("Finished writing %zu words of SII data to slave %u.\n", |
1095 request->nwords); |
874 request->nwords, slave->ring_position); |
|
875 |
1096 |
876 if (request->offset <= 4 && request->offset + request->nwords > 4) { |
1097 if (request->offset <= 4 && request->offset + request->nwords > 4) { |
877 // alias was written |
1098 // alias was written |
878 slave->sii.alias = EC_READ_U16(request->words + 4); |
1099 slave->sii.alias = EC_READ_U16(request->words + 4); |
879 // TODO: read alias from register 0x0012 |
1100 // TODO: read alias from register 0x0012 |
912 // SDO dictionary fetching finished |
1133 // SDO dictionary fetching finished |
913 |
1134 |
914 if (master->debug_level) { |
1135 if (master->debug_level) { |
915 unsigned int sdo_count, entry_count; |
1136 unsigned int sdo_count, entry_count; |
916 ec_slave_sdo_dict_info(slave, &sdo_count, &entry_count); |
1137 ec_slave_sdo_dict_info(slave, &sdo_count, &entry_count); |
917 EC_DBG("Fetched %u SDOs and %u entries from slave %u.\n", |
1138 EC_SLAVE_DBG(slave, 1, "Fetched %u SDOs and %u entries.\n", |
918 sdo_count, entry_count, slave->ring_position); |
1139 sdo_count, entry_count); |
919 } |
1140 } |
920 |
1141 |
921 // attach pdo names from dictionary |
1142 // attach pdo names from dictionary |
922 ec_slave_attach_pdo_names(slave); |
1143 ec_slave_attach_pdo_names(slave); |
923 |
1144 |
930 */ |
1151 */ |
931 void ec_fsm_master_state_sdo_request( |
1152 void ec_fsm_master_state_sdo_request( |
932 ec_fsm_master_t *fsm /**< Master state machine. */ |
1153 ec_fsm_master_t *fsm /**< Master state machine. */ |
933 ) |
1154 ) |
934 { |
1155 { |
935 ec_master_t *master = fsm->master; |
|
936 ec_sdo_request_t *request = fsm->sdo_request; |
1156 ec_sdo_request_t *request = fsm->sdo_request; |
937 |
1157 |
938 if (ec_fsm_coe_exec(&fsm->fsm_coe)) return; |
1158 if (ec_fsm_coe_exec(&fsm->fsm_coe)) return; |
939 |
1159 |
940 if (!ec_fsm_coe_success(&fsm->fsm_coe)) { |
1160 if (!ec_fsm_coe_success(&fsm->fsm_coe)) { |
941 EC_DBG("Failed to process internal SDO request for slave %u.\n", |
1161 EC_SLAVE_DBG(fsm->slave, 1, |
942 fsm->slave->ring_position); |
1162 "Failed to process internal SDO request.\n"); |
943 request->state = EC_INT_REQUEST_FAILURE; |
1163 request->state = EC_INT_REQUEST_FAILURE; |
944 wake_up(&fsm->slave->sdo_queue); |
1164 wake_up(&fsm->slave->sdo_queue); |
945 ec_fsm_master_restart(fsm); |
1165 ec_fsm_master_restart(fsm); |
946 return; |
1166 return; |
947 } |
1167 } |
948 |
1168 |
949 // SDO request finished |
1169 // SDO request finished |
950 request->state = EC_INT_REQUEST_SUCCESS; |
1170 request->state = EC_INT_REQUEST_SUCCESS; |
951 wake_up(&fsm->slave->sdo_queue); |
1171 wake_up(&fsm->slave->sdo_queue); |
952 |
1172 |
953 if (master->debug_level) |
1173 EC_SLAVE_DBG(fsm->slave, 1, "Finished internal SDO request.\n"); |
954 EC_DBG("Finished internal SDO request for slave %u.\n", |
|
955 fsm->slave->ring_position); |
|
956 |
1174 |
957 // check for another SDO request |
1175 // check for another SDO request |
958 if (ec_fsm_master_action_process_sdo(fsm)) |
1176 if (ec_fsm_master_action_process_sdo(fsm)) |
959 return; // processing another request |
1177 return; // processing another request |
960 |
1178 |
972 ec_master_t *master = fsm->master; |
1190 ec_master_t *master = fsm->master; |
973 ec_datagram_t *datagram = fsm->datagram; |
1191 ec_datagram_t *datagram = fsm->datagram; |
974 ec_reg_request_t *request = fsm->reg_request; |
1192 ec_reg_request_t *request = fsm->reg_request; |
975 |
1193 |
976 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
1194 if (datagram->state != EC_DATAGRAM_RECEIVED) { |
977 EC_ERR("Failed to receive register request datagram (state %u).\n", |
1195 EC_MASTER_ERR(master, "Failed to receive register" |
978 datagram->state); |
1196 " request datagram: "); |
1197 ec_datagram_print_state(datagram); |
|
979 request->state = EC_INT_REQUEST_FAILURE; |
1198 request->state = EC_INT_REQUEST_FAILURE; |
980 wake_up(&master->reg_queue); |
1199 wake_up(&master->reg_queue); |
981 ec_fsm_master_restart(fsm); |
1200 ec_fsm_master_restart(fsm); |
982 return; |
1201 return; |
983 } |
1202 } |
986 if (request->dir == EC_DIR_INPUT) { // read request |
1205 if (request->dir == EC_DIR_INPUT) { // read request |
987 if (request->data) |
1206 if (request->data) |
988 kfree(request->data); |
1207 kfree(request->data); |
989 request->data = kmalloc(request->length, GFP_KERNEL); |
1208 request->data = kmalloc(request->length, GFP_KERNEL); |
990 if (!request->data) { |
1209 if (!request->data) { |
991 EC_ERR("Failed to allocate %zu bytes of memory for" |
1210 EC_MASTER_ERR(master, "Failed to allocate %zu bytes" |
992 " register data.\n", request->length); |
1211 " of memory for register data.\n", request->length); |
993 request->state = EC_INT_REQUEST_FAILURE; |
1212 request->state = EC_INT_REQUEST_FAILURE; |
994 wake_up(&master->reg_queue); |
1213 wake_up(&master->reg_queue); |
995 ec_fsm_master_restart(fsm); |
1214 ec_fsm_master_restart(fsm); |
996 return; |
1215 return; |
997 } |
1216 } |
998 memcpy(request->data, datagram->data, request->length); |
1217 memcpy(request->data, datagram->data, request->length); |
999 } |
1218 } |
1000 |
1219 |
1001 request->state = EC_INT_REQUEST_SUCCESS; |
1220 request->state = EC_INT_REQUEST_SUCCESS; |
1002 if (master->debug_level) { |
1221 EC_SLAVE_DBG(request->slave, 1, "Register request successful.\n"); |
1003 EC_DBG("Register request successful.\n"); |
|
1004 } |
|
1005 } else { |
1222 } else { |
1006 request->state = EC_INT_REQUEST_FAILURE; |
1223 request->state = EC_INT_REQUEST_FAILURE; |
1007 EC_ERR("Register request failed.\n"); |
1224 EC_MASTER_ERR(master, "Register request failed.\n"); |
1008 } |
1225 } |
1009 |
1226 |
1010 wake_up(&master->reg_queue); |
1227 wake_up(&master->reg_queue); |
1011 |
1228 |
1012 // check for another register request |
1229 // check for another register request |