55 /*****************************************************************************/ |
55 /*****************************************************************************/ |
56 |
56 |
57 void ec_master_clear(struct kobject *); |
57 void ec_master_clear(struct kobject *); |
58 void ec_master_destroy_domains(ec_master_t *); |
58 void ec_master_destroy_domains(ec_master_t *); |
59 void ec_master_sync_io(ec_master_t *); |
59 void ec_master_sync_io(ec_master_t *); |
60 void ec_master_idle_run(void *); |
60 static int ec_master_thread(void *); |
61 void ec_master_eoe_run(unsigned long); |
61 void ec_master_eoe_run(unsigned long); |
62 void ec_master_check_sdo(unsigned long); |
62 void ec_master_check_sdo(unsigned long); |
63 int ec_master_measure_bus_time(ec_master_t *); |
63 int ec_master_measure_bus_time(ec_master_t *); |
64 ssize_t ec_show_master_attribute(struct kobject *, struct attribute *, char *); |
64 ssize_t ec_show_master_attribute(struct kobject *, struct attribute *, char *); |
65 ssize_t ec_store_master_attribute(struct kobject *, struct attribute *, |
65 ssize_t ec_store_master_attribute(struct kobject *, struct attribute *, |
182 goto out_clear_eoe; |
174 goto out_clear_eoe; |
183 } |
175 } |
184 list_add_tail(&eoe->list, &master->eoe_handlers); |
176 list_add_tail(&eoe->list, &master->eoe_handlers); |
185 } |
177 } |
186 |
178 |
|
179 // init state machine datagram |
|
180 ec_datagram_init(&master->fsm_datagram); |
|
181 if (ec_datagram_prealloc(&master->fsm_datagram, EC_MAX_DATA_SIZE)) { |
|
182 EC_ERR("Failed to allocate FSM datagram.\n"); |
|
183 goto out_clear_eoe; |
|
184 } |
|
185 |
187 // create state machine object |
186 // create state machine object |
188 if (ec_fsm_init(&master->fsm, master)) goto out_clear_eoe; |
187 ec_fsm_master_init(&master->fsm, master, &master->fsm_datagram); |
189 |
188 |
190 // init kobject and add it to the hierarchy |
189 // init kobject and add it to the hierarchy |
191 memset(&master->kobj, 0x00, sizeof(struct kobject)); |
190 memset(&master->kobj, 0x00, sizeof(struct kobject)); |
192 kobject_init(&master->kobj); |
191 kobject_init(&master->kobj); |
193 master->kobj.ktype = &ktype_ec_master; |
192 master->kobj.ktype = &ktype_ec_master; |
318 } |
316 } |
319 |
317 |
320 /*****************************************************************************/ |
318 /*****************************************************************************/ |
321 |
319 |
322 /** |
320 /** |
|
321 Internal locking callback. |
|
322 */ |
|
323 |
|
324 int ec_master_request_cb(void *master /**< callback data */) |
|
325 { |
|
326 spin_lock(&((ec_master_t *) master)->internal_lock); |
|
327 return 0; |
|
328 } |
|
329 |
|
330 /*****************************************************************************/ |
|
331 |
|
332 /** |
|
333 Internal unlocking callback. |
|
334 */ |
|
335 |
|
336 void ec_master_release_cb(void *master /**< callback data */) |
|
337 { |
|
338 spin_unlock(&((ec_master_t *) master)->internal_lock); |
|
339 } |
|
340 |
|
341 /*****************************************************************************/ |
|
342 |
|
343 /** |
|
344 * Starts the master thread. |
|
345 */ |
|
346 |
|
347 int ec_master_thread_start(ec_master_t *master /**< EtherCAT master */) |
|
348 { |
|
349 init_completion(&master->thread_exit); |
|
350 |
|
351 EC_INFO("Starting master thread.\n"); |
|
352 if (!(master->thread_id = |
|
353 kernel_thread(ec_master_thread, master, CLONE_KERNEL))) |
|
354 return -1; |
|
355 |
|
356 return 0; |
|
357 } |
|
358 |
|
359 /*****************************************************************************/ |
|
360 |
|
361 /** |
|
362 * Stops the master thread. |
|
363 */ |
|
364 |
|
365 void ec_master_thread_stop(ec_master_t *master /**< EtherCAT master */) |
|
366 { |
|
367 if (master->thread_id) { |
|
368 kill_proc(master->thread_id, SIGTERM, 1); |
|
369 wait_for_completion(&master->thread_exit); |
|
370 EC_INFO("Master thread exited.\n"); |
|
371 } |
|
372 } |
|
373 |
|
374 /*****************************************************************************/ |
|
375 |
|
376 /** |
|
377 * Transition function from ORPHANED to IDLE mode. |
323 */ |
378 */ |
324 |
379 |
325 int ec_master_enter_idle_mode(ec_master_t *master /**< EtherCAT master */) |
380 int ec_master_enter_idle_mode(ec_master_t *master /**< EtherCAT master */) |
326 { |
381 { |
|
382 master->request_cb = ec_master_request_cb; |
|
383 master->release_cb = ec_master_release_cb; |
|
384 master->cb_data = master; |
|
385 |
327 master->mode = EC_MASTER_MODE_IDLE; |
386 master->mode = EC_MASTER_MODE_IDLE; |
328 queue_delayed_work(master->workqueue, &master->idle_work, 1); |
387 if (ec_master_thread_start(master)) { |
|
388 master->mode = EC_MASTER_MODE_ORPHANED; |
|
389 return -1; |
|
390 } |
|
391 |
329 return 0; |
392 return 0; |
330 } |
393 } |
331 |
394 |
332 /*****************************************************************************/ |
395 /*****************************************************************************/ |
333 |
396 |
334 /** |
397 /** |
|
398 * Transition function from IDLE to ORPHANED mode. |
335 */ |
399 */ |
336 |
400 |
337 void ec_master_leave_idle_mode(ec_master_t *master /**< EtherCAT master */) |
401 void ec_master_leave_idle_mode(ec_master_t *master /**< EtherCAT master */) |
338 { |
402 { |
|
403 master->mode = EC_MASTER_MODE_ORPHANED; |
|
404 |
339 ec_master_eoe_stop(master); |
405 ec_master_eoe_stop(master); |
340 |
406 ec_master_thread_stop(master); |
341 master->mode = EC_MASTER_MODE_ORPHANED; |
|
342 while (!cancel_delayed_work(&master->idle_work)) { |
|
343 flush_workqueue(master->workqueue); |
|
344 } |
|
345 |
|
346 ec_master_flush_sdo_requests(master); |
407 ec_master_flush_sdo_requests(master); |
347 } |
408 } |
348 |
409 |
349 /*****************************************************************************/ |
410 /*****************************************************************************/ |
350 |
411 |
351 /** |
412 /** |
|
413 * Transition function from IDLE to OPERATION mode. |
352 */ |
414 */ |
353 |
415 |
354 int ec_master_enter_operation_mode(ec_master_t *master /**< EtherCAT master */) |
416 int ec_master_enter_operation_mode(ec_master_t *master /**< EtherCAT master */) |
355 { |
417 { |
356 ec_slave_t *slave; |
418 ec_slave_t *slave; |
357 ec_datagram_t *datagram = &master->fsm.datagram; |
419 |
|
420 ec_master_eoe_stop(master); // stop EoE timer |
|
421 master->eoe_checked = 1; // prevent from starting again by FSM |
|
422 ec_master_thread_stop(master); |
358 |
423 |
359 master->mode = EC_MASTER_MODE_OPERATION; |
424 master->mode = EC_MASTER_MODE_OPERATION; |
360 while (!cancel_delayed_work(&master->idle_work)) { |
|
361 flush_workqueue(master->workqueue); |
|
362 } |
|
363 |
425 |
364 // wait for FSM datagram |
426 // wait for FSM datagram |
365 if (datagram->state == EC_DATAGRAM_SENT) {; |
427 if (master->fsm_datagram.state == EC_DATAGRAM_SENT) { |
366 while (get_cycles() - datagram->cycles_sent |
428 while (get_cycles() - master->fsm_datagram.cycles_sent |
367 < (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000)) {} |
429 < (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000)) {} |
368 ecrt_master_receive(master); |
430 ecrt_master_receive(master); |
369 } |
431 } |
370 |
432 |
371 // finish running master FSM |
433 // finish running master FSM |
372 if (ec_fsm_running(&master->fsm)) { |
434 if (ec_fsm_master_running(&master->fsm)) { |
373 while (ec_fsm_exec(&master->fsm)) { |
435 while (ec_fsm_master_exec(&master->fsm)) { |
374 ec_master_sync_io(master); |
436 ec_master_sync_io(master); |
375 } |
437 } |
376 } |
438 } |
377 |
439 |
378 if (master->debug_level) { |
440 if (master->debug_level) { |
390 else { |
452 else { |
391 ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP); |
453 ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP); |
392 } |
454 } |
393 } |
455 } |
394 |
456 |
|
457 master->eoe_checked = 0; // allow starting EoE again |
|
458 |
395 return 0; |
459 return 0; |
396 |
460 |
397 out_idle: |
461 out_idle: |
398 master->mode = EC_MASTER_MODE_IDLE; |
462 master->mode = EC_MASTER_MODE_IDLE; |
399 queue_delayed_work(master->workqueue, &master->idle_work, 1); |
463 if (ec_master_thread_start(master)) { |
|
464 EC_WARN("Failed to start master thread again!\n"); |
|
465 } |
400 return -1; |
466 return -1; |
401 } |
467 } |
402 |
468 |
403 /*****************************************************************************/ |
469 /*****************************************************************************/ |
404 |
470 |
405 /** |
471 /** |
|
472 * Transition function from OPERATION to IDLE mode. |
406 */ |
473 */ |
407 |
474 |
408 void ec_master_leave_operation_mode(ec_master_t *master |
475 void ec_master_leave_operation_mode(ec_master_t *master |
409 /**< EtherCAT master */) |
476 /**< EtherCAT master */) |
410 { |
477 { |
411 ec_slave_t *slave; |
478 ec_slave_t *slave; |
412 ec_fsm_t *fsm = &master->fsm; |
479 ec_fsm_master_t *fsm = &master->fsm; |
413 ec_datagram_t *datagram = &master->fsm.datagram; |
480 ec_fsm_slave_t fsm_slave; |
|
481 |
|
482 ec_master_eoe_stop(master); // stop EoE timer |
|
483 master->eoe_checked = 1; // prevent from starting again by FSM |
414 |
484 |
415 // wait for FSM datagram |
485 // wait for FSM datagram |
416 if (datagram->state == EC_DATAGRAM_SENT) { |
486 if (master->fsm_datagram.state == EC_DATAGRAM_SENT) { |
417 while (get_cycles() - datagram->cycles_sent |
487 // active waiting |
418 < (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000)) {} |
488 while (get_cycles() - master->fsm_datagram.cycles_sent |
|
489 < (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000)); |
419 ecrt_master_receive(master); |
490 ecrt_master_receive(master); |
420 } |
491 } |
421 |
492 |
422 // finish running master FSM |
493 // finish running master FSM |
423 if (ec_fsm_running(fsm)) { |
494 if (ec_fsm_master_running(fsm)) { |
424 while (ec_fsm_exec(fsm)) { |
495 while (ec_fsm_master_exec(fsm)) { |
425 ec_master_sync_io(master); |
496 ec_master_sync_io(master); |
426 } |
497 } |
427 } |
498 } |
428 |
499 |
|
500 ec_fsm_slave_init(&fsm_slave, &master->fsm_datagram); |
|
501 |
429 // set states for all slaves |
502 // set states for all slaves |
430 list_for_each_entry(slave, &master->slaves, list) { |
503 list_for_each_entry(slave, &master->slaves, list) { |
431 ec_slave_reset(slave); |
504 ec_slave_reset(slave); |
432 ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP); |
505 ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP); |
433 |
506 |
434 fsm->slave = slave; |
507 // don't try to set PREOP for slaves that don't respond, |
435 fsm->slave_state = ec_fsm_slaveconf_state_start; |
508 // because of 3 second timeout. |
436 |
509 if (!slave->online) { |
437 do { |
510 if (master->debug_level) |
438 fsm->slave_state(fsm); |
511 EC_DBG("Skipping to configure offline slave %i.\n", |
|
512 slave->ring_position); |
|
513 continue; |
|
514 } |
|
515 |
|
516 ec_fsm_slave_start_conf(&fsm_slave, slave); |
|
517 while (ec_fsm_slave_exec(&fsm_slave)) { |
439 ec_master_sync_io(master); |
518 ec_master_sync_io(master); |
440 } |
519 } |
441 while (fsm->slave_state != ec_fsm_slave_state_end |
520 } |
442 && fsm->slave_state != ec_fsm_slave_state_error); |
521 |
443 } |
522 ec_fsm_slave_clear(&fsm_slave); |
444 |
523 |
445 ec_master_destroy_domains(master); |
524 ec_master_destroy_domains(master); |
446 |
525 |
447 master->request_cb = NULL; |
526 master->request_cb = ec_master_request_cb; |
448 master->release_cb = NULL; |
527 master->release_cb = ec_master_release_cb; |
449 master->cb_data = NULL; |
528 master->cb_data = master; |
|
529 |
|
530 master->eoe_checked = 0; // allow EoE again |
450 |
531 |
451 master->mode = EC_MASTER_MODE_IDLE; |
532 master->mode = EC_MASTER_MODE_IDLE; |
452 queue_delayed_work(master->workqueue, &master->idle_work, 1); |
533 if (ec_master_thread_start(master)) { |
|
534 EC_WARN("Failed to start master thread!\n"); |
|
535 } |
453 } |
536 } |
454 |
537 |
455 /*****************************************************************************/ |
538 /*****************************************************************************/ |
456 |
539 |
457 /** |
540 /** |
719 } |
801 } |
720 |
802 |
721 /*****************************************************************************/ |
803 /*****************************************************************************/ |
722 |
804 |
723 /** |
805 /** |
724 Idle mode function. |
806 Master kernel thread function. |
725 */ |
807 */ |
726 |
808 |
727 void ec_master_idle_run(void *data /**< master pointer */) |
809 static int ec_master_thread(void *data) |
728 { |
810 { |
729 ec_master_t *master = (ec_master_t *) data; |
811 ec_master_t *master = (ec_master_t *) data; |
730 cycles_t cycles_start, cycles_end; |
812 cycles_t cycles_start, cycles_end; |
731 |
813 |
732 // aquire master lock |
814 daemonize("EtherCAT"); |
733 spin_lock_bh(&master->internal_lock); |
815 allow_signal(SIGTERM); |
734 |
816 |
735 cycles_start = get_cycles(); |
817 while (!signal_pending(current) && master->mode == EC_MASTER_MODE_IDLE) { |
736 ecrt_master_receive(master); |
818 cycles_start = get_cycles(); |
737 |
819 |
738 // execute master state machine |
820 // receive |
739 ec_fsm_exec(&master->fsm); |
821 spin_lock_bh(&master->internal_lock); |
740 |
822 ecrt_master_receive(master); |
741 ecrt_master_send(master); |
823 spin_unlock_bh(&master->internal_lock); |
742 cycles_end = get_cycles(); |
824 |
743 |
825 // execute master state machine |
744 // release master lock |
826 ec_fsm_master_exec(&master->fsm); |
745 spin_unlock_bh(&master->internal_lock); |
827 |
746 |
828 // send |
747 master->idle_cycle_times[master->idle_cycle_time_pos] |
829 spin_lock_bh(&master->internal_lock); |
748 = (u32) (cycles_end - cycles_start) * 1000 / cpu_khz; |
830 ecrt_master_send(master); |
749 master->idle_cycle_time_pos++; |
831 spin_unlock_bh(&master->internal_lock); |
750 master->idle_cycle_time_pos %= HZ; |
832 |
751 |
833 cycles_end = get_cycles(); |
752 if (master->mode == EC_MASTER_MODE_IDLE) |
834 master->idle_cycle_times[master->idle_cycle_time_pos] |
753 queue_delayed_work(master->workqueue, &master->idle_work, 1); |
835 = (u32) (cycles_end - cycles_start) * 1000 / cpu_khz; |
754 } |
836 master->idle_cycle_time_pos++; |
755 |
837 master->idle_cycle_time_pos %= HZ; |
756 /*****************************************************************************/ |
838 |
757 |
839 set_current_state(TASK_INTERRUPTIBLE); |
758 /** |
840 schedule_timeout(1); |
759 Initializes a sync manager configuration page with EEPROM data. |
841 } |
760 The referenced memory (\a data) must be at least EC_SYNC_SIZE bytes. |
842 |
761 */ |
843 master->thread_id = 0; |
762 |
844 complete_and_exit(&master->thread_exit, 0); |
763 void ec_sync_config(const ec_sii_sync_t *sync, /**< sync manager */ |
|
764 const ec_slave_t *slave, /**< EtherCAT slave */ |
|
765 uint8_t *data /**> configuration memory */ |
|
766 ) |
|
767 { |
|
768 size_t sync_size; |
|
769 |
|
770 sync_size = ec_slave_calc_sync_size(slave, sync); |
|
771 |
|
772 if (slave->master->debug_level) { |
|
773 EC_DBG("Slave %3i, SM %i: Addr 0x%04X, Size %3i, Ctrl 0x%02X, En %i\n", |
|
774 slave->ring_position, sync->index, sync->physical_start_address, |
|
775 sync_size, sync->control_register, sync->enable); |
|
776 } |
|
777 |
|
778 EC_WRITE_U16(data, sync->physical_start_address); |
|
779 EC_WRITE_U16(data + 2, sync_size); |
|
780 EC_WRITE_U8 (data + 4, sync->control_register); |
|
781 EC_WRITE_U8 (data + 5, 0x00); // status byte (read only) |
|
782 EC_WRITE_U16(data + 6, sync->enable ? 0x0001 : 0x0000); // enable |
|
783 } |
|
784 |
|
785 /*****************************************************************************/ |
|
786 |
|
787 /** |
|
788 Initializes an FMMU configuration page. |
|
789 The referenced memory (\a data) must be at least EC_FMMU_SIZE bytes. |
|
790 */ |
|
791 |
|
792 void ec_fmmu_config(const ec_fmmu_t *fmmu, /**< FMMU */ |
|
793 const ec_slave_t *slave, /**< EtherCAT slave */ |
|
794 uint8_t *data /**> configuration memory */ |
|
795 ) |
|
796 { |
|
797 size_t sync_size; |
|
798 |
|
799 sync_size = ec_slave_calc_sync_size(slave, fmmu->sync); |
|
800 |
|
801 if (slave->master->debug_level) { |
|
802 EC_DBG("Slave %3i, FMMU %2i:" |
|
803 " LogAddr 0x%08X, Size %3i, PhysAddr 0x%04X, Dir %s\n", |
|
804 slave->ring_position, fmmu->index, fmmu->logical_start_address, |
|
805 sync_size, fmmu->sync->physical_start_address, |
|
806 ((fmmu->sync->control_register & 0x04) ? "out" : "in")); |
|
807 } |
|
808 |
|
809 EC_WRITE_U32(data, fmmu->logical_start_address); |
|
810 EC_WRITE_U16(data + 4, sync_size); // size of fmmu |
|
811 EC_WRITE_U8 (data + 6, 0x00); // logical start bit |
|
812 EC_WRITE_U8 (data + 7, 0x07); // logical end bit |
|
813 EC_WRITE_U16(data + 8, fmmu->sync->physical_start_address); |
|
814 EC_WRITE_U8 (data + 10, 0x00); // physical start bit |
|
815 EC_WRITE_U8 (data + 11, ((fmmu->sync->control_register & 0x04) |
|
816 ? 0x02 : 0x01)); |
|
817 EC_WRITE_U16(data + 12, 0x0001); // enable |
|
818 EC_WRITE_U16(data + 14, 0x0000); // reserved |
|
819 } |
845 } |
820 |
846 |
821 /*****************************************************************************/ |
847 /*****************************************************************************/ |
822 |
848 |
823 /** |
849 /** |
1090 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
1117 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
1091 if (ec_eoe_active(eoe)) active++; |
1118 if (ec_eoe_active(eoe)) active++; |
1092 } |
1119 } |
1093 if (!active) goto queue_timer; |
1120 if (!active) goto queue_timer; |
1094 |
1121 |
1095 // aquire master lock... |
1122 // receive datagrams |
1096 if (master->mode == EC_MASTER_MODE_OPERATION) { |
1123 if (master->request_cb(master->cb_data)) goto queue_timer; |
1097 // request_cb must return 0, if the lock has been aquired! |
|
1098 if (master->request_cb(master->cb_data)) |
|
1099 goto queue_timer; |
|
1100 } |
|
1101 else if (master->mode == EC_MASTER_MODE_IDLE) { |
|
1102 spin_lock(&master->internal_lock); |
|
1103 } |
|
1104 else |
|
1105 goto queue_timer; |
|
1106 |
|
1107 // actual EoE processing |
|
1108 cycles_start = get_cycles(); |
1124 cycles_start = get_cycles(); |
1109 ecrt_master_receive(master); |
1125 ecrt_master_receive(master); |
1110 |
1126 master->release_cb(master->cb_data); |
|
1127 |
|
1128 // actual EoE processing |
1111 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
1129 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
1112 ec_eoe_run(eoe); |
1130 ec_eoe_run(eoe); |
1113 } |
1131 } |
1114 |
1132 |
|
1133 // send datagrams |
|
1134 if (master->request_cb(master->cb_data)) goto queue_timer; |
1115 ecrt_master_send(master); |
1135 ecrt_master_send(master); |
1116 cycles_end = get_cycles(); |
1136 cycles_end = get_cycles(); |
1117 |
1137 master->release_cb(master->cb_data); |
1118 // release lock... |
|
1119 if (master->mode == EC_MASTER_MODE_OPERATION) { |
|
1120 master->release_cb(master->cb_data); |
|
1121 } |
|
1122 else if (master->mode == EC_MASTER_MODE_IDLE) { |
|
1123 spin_unlock(&master->internal_lock); |
|
1124 } |
|
1125 |
1138 |
1126 master->eoe_cycle_times[master->eoe_cycle_time_pos] |
1139 master->eoe_cycle_times[master->eoe_cycle_time_pos] |
1127 = (u32) (cycles_end - cycles_start) * 1000 / cpu_khz; |
1140 = (u32) (cycles_end - cycles_start) * 1000 / cpu_khz; |
1128 master->eoe_cycle_time_pos++; |
1141 master->eoe_cycle_time_pos++; |
1129 master->eoe_cycle_time_pos %= HZ; |
1142 master->eoe_cycle_time_pos %= HZ; |
1247 error: |
1260 error: |
1248 ec_datagram_clear(&datagram); |
1261 ec_datagram_clear(&datagram); |
1249 return -1; |
1262 return -1; |
1250 } |
1263 } |
1251 |
1264 |
|
1265 /*****************************************************************************/ |
|
1266 |
|
1267 /** |
|
1268 Prepares synchronous IO. |
|
1269 Queues all domain datagrams and sends them. Then waits a certain time, so |
|
1270 that ecrt_master_receive() can be called securely. |
|
1271 */ |
|
1272 |
|
1273 void ec_master_prepare(ec_master_t *master /**< EtherCAT master */) |
|
1274 { |
|
1275 ec_domain_t *domain; |
|
1276 cycles_t cycles_start, cycles_end, cycles_timeout; |
|
1277 |
|
1278 // queue datagrams of all domains |
|
1279 list_for_each_entry(domain, &master->domains, list) |
|
1280 ecrt_domain_queue(domain); |
|
1281 |
|
1282 ecrt_master_send(master); |
|
1283 |
|
1284 cycles_start = get_cycles(); |
|
1285 cycles_timeout = (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000); |
|
1286 |
|
1287 // active waiting |
|
1288 while (1) { |
|
1289 udelay(100); |
|
1290 cycles_end = get_cycles(); |
|
1291 if (cycles_end - cycles_start >= cycles_timeout) break; |
|
1292 } |
|
1293 } |
|
1294 |
1252 /****************************************************************************** |
1295 /****************************************************************************** |
1253 * Realtime interface |
1296 * Realtime interface |
1254 *****************************************************************************/ |
1297 *****************************************************************************/ |
1255 |
1298 |
1256 /** |
1299 /** |
1311 return -1; |
1354 return -1; |
1312 } |
1355 } |
1313 domain_offset += domain->data_size; |
1356 domain_offset += domain->data_size; |
1314 } |
1357 } |
1315 |
1358 |
|
1359 ec_fsm_slave_init(&fsm_slave, &master->fsm_datagram); |
|
1360 |
1316 // configure all slaves |
1361 // configure all slaves |
1317 list_for_each_entry(slave, &master->slaves, list) { |
1362 list_for_each_entry(slave, &master->slaves, list) { |
1318 fsm->slave = slave; |
1363 ec_fsm_slave_start_conf(&fsm_slave, slave); |
1319 fsm->slave_state = ec_fsm_slaveconf_state_start; |
1364 while (ec_fsm_slave_exec(&fsm_slave)) { |
1320 |
|
1321 do { |
|
1322 fsm->slave_state(fsm); |
|
1323 ec_master_sync_io(master); |
1365 ec_master_sync_io(master); |
1324 } |
1366 } |
1325 while (fsm->slave_state != ec_fsm_slave_state_end |
1367 |
1326 && fsm->slave_state != ec_fsm_slave_state_error); |
1368 if (!ec_fsm_slave_success(&fsm_slave)) { |
1327 |
1369 ec_fsm_slave_clear(&fsm_slave); |
1328 if (fsm->slave_state == ec_fsm_slave_state_error) { |
|
1329 EC_ERR("Failed to configure slave %i!\n", slave->ring_position); |
1370 EC_ERR("Failed to configure slave %i!\n", slave->ring_position); |
1330 return -1; |
1371 return -1; |
1331 } |
1372 } |
1332 } |
1373 } |
1333 |
1374 |
|
1375 ec_fsm_slave_clear(&fsm_slave); |
|
1376 ec_master_prepare(master); // prepare asynchronous IO |
|
1377 |
1334 return 0; |
1378 return 0; |
1335 } |
1379 } |
1336 |
1380 |
1337 /*****************************************************************************/ |
1381 /*****************************************************************************/ |
1338 |
1382 |
1339 /** |
1383 /** |
1340 Resets all slaves to INIT state. |
|
1341 This method is deprecated and will disappear in the next version |
|
1342 of the realtime interface. The functionality is moved to |
|
1343 ecrt_master_release(). |
|
1344 \ingroup RealtimeInterface |
|
1345 */ |
|
1346 |
|
1347 void ecrt_master_deactivate(ec_master_t *master /**< EtherCAT master */) |
|
1348 { |
|
1349 } |
|
1350 |
|
1351 /*****************************************************************************/ |
|
1352 |
|
1353 /** |
|
1354 Sends queued datagrams and waits for their reception. |
1384 Sends queued datagrams and waits for their reception. |
1355 */ |
1385 */ |
1356 |
1386 |
1357 void ec_master_sync_io(ec_master_t *master /**< EtherCAT master */) |
1387 void ec_master_sync_io(ec_master_t *master /**< EtherCAT master */) |
1358 { |
1388 { |
1359 ec_datagram_t *datagram; |
1389 ec_datagram_t *datagram; |
1360 unsigned int datagrams_waiting; |
1390 unsigned int datagrams_sent; |
1361 |
1391 |
1362 // send datagrams |
1392 // send all datagrams |
1363 ecrt_master_send(master); |
1393 ecrt_master_send(master); |
1364 |
1394 |
1365 while (1) { // active waiting |
1395 while (1) { // active waiting |
|
1396 schedule(); // schedule other processes while waiting. |
1366 ecrt_master_receive(master); // receive and dequeue datagrams |
1397 ecrt_master_receive(master); // receive and dequeue datagrams |
1367 |
1398 |
1368 // count number of datagrams still waiting for response |
1399 // count number of datagrams still waiting for response |
1369 datagrams_waiting = 0; |
1400 datagrams_sent = 0; |
1370 list_for_each_entry(datagram, &master->datagram_queue, queue) { |
1401 list_for_each_entry(datagram, &master->datagram_queue, queue) { |
1371 datagrams_waiting++; |
1402 // there may be another process that queued commands |
1372 } |
1403 // in the meantime. |
1373 |
1404 if (datagram->state == EC_DATAGRAM_QUEUED) continue; |
1374 // if there are no more datagrams waiting, abort loop. |
1405 datagrams_sent++; |
1375 if (!datagrams_waiting) break; |
1406 } |
|
1407 |
|
1408 // abort loop if there are no more datagrams marked as sent. |
|
1409 if (!datagrams_sent) break; |
1376 } |
1410 } |
1377 } |
1411 } |
1378 |
1412 |
1379 /*****************************************************************************/ |
1413 /*****************************************************************************/ |
1380 |
1414 |
1414 { |
1448 { |
1415 ec_datagram_t *datagram, *next; |
1449 ec_datagram_t *datagram, *next; |
1416 cycles_t cycles_timeout; |
1450 cycles_t cycles_timeout; |
1417 |
1451 |
1418 // receive datagrams |
1452 // receive datagrams |
1419 ec_device_call_isr(master->device); |
1453 ec_device_poll(master->device); |
1420 |
1454 |
1421 cycles_timeout = (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000); |
1455 cycles_timeout = (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000); |
1422 |
1456 |
1423 // dequeue all datagrams that timed out |
1457 // dequeue all datagrams that timed out |
1424 list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) { |
1458 list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) { |
1425 switch (datagram->state) { |
1459 if (datagram->state != EC_DATAGRAM_SENT) continue; |
1426 case EC_DATAGRAM_QUEUED: |
1460 |
1427 if (master->device->cycles_isr |
1461 if (master->device->cycles_poll - datagram->cycles_sent |
1428 - datagram->cycles_queued > cycles_timeout) { |
1462 > cycles_timeout) { |
1429 list_del_init(&datagram->queue); |
1463 list_del_init(&datagram->queue); |
1430 datagram->state = EC_DATAGRAM_TIMED_OUT; |
1464 datagram->state = EC_DATAGRAM_TIMED_OUT; |
1431 master->stats.timeouts++; |
1465 master->stats.timeouts++; |
1432 ec_master_output_stats(master); |
1466 ec_master_output_stats(master); |
1433 } |
1467 } |
1434 break; |
|
1435 case EC_DATAGRAM_SENT: |
|
1436 if (master->device->cycles_isr |
|
1437 - datagram->cycles_sent > cycles_timeout) { |
|
1438 list_del_init(&datagram->queue); |
|
1439 datagram->state = EC_DATAGRAM_TIMED_OUT; |
|
1440 master->stats.timeouts++; |
|
1441 ec_master_output_stats(master); |
|
1442 } |
|
1443 break; |
|
1444 default: |
|
1445 break; |
|
1446 } |
|
1447 } |
|
1448 } |
|
1449 |
|
1450 /*****************************************************************************/ |
|
1451 |
|
1452 /** |
|
1453 Prepares synchronous IO. |
|
1454 Queues all domain datagrams and sends them. Then waits a certain time, so |
|
1455 that ecrt_master_receive() can be called securely. |
|
1456 \ingroup RealtimeInterface |
|
1457 */ |
|
1458 |
|
1459 void ecrt_master_prepare(ec_master_t *master /**< EtherCAT master */) |
|
1460 { |
|
1461 ec_domain_t *domain; |
|
1462 cycles_t cycles_start, cycles_end, cycles_timeout; |
|
1463 |
|
1464 // queue datagrams of all domains |
|
1465 list_for_each_entry(domain, &master->domains, list) |
|
1466 ec_domain_queue_datagrams(domain); |
|
1467 |
|
1468 ecrt_master_send(master); |
|
1469 |
|
1470 cycles_start = get_cycles(); |
|
1471 cycles_timeout = (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000); |
|
1472 |
|
1473 // active waiting |
|
1474 while (1) { |
|
1475 udelay(100); |
|
1476 cycles_end = get_cycles(); |
|
1477 if (cycles_end - cycles_start >= cycles_timeout) break; |
|
1478 } |
1468 } |
1479 } |
1469 } |
1480 |
1470 |
1481 /*****************************************************************************/ |
1471 /*****************************************************************************/ |
1482 |
1472 |
1553 else { |
1546 else { |
1554 list_for_each_entry(slave, &master->slaves, list) { |
1547 list_for_each_entry(slave, &master->slaves, list) { |
1555 if (slave->ring_position == first) return slave; |
1548 if (slave->ring_position == first) return slave; |
1556 } |
1549 } |
1557 EC_ERR("Slave address \"%s\" - Absolute position invalid!\n", |
1550 EC_ERR("Slave address \"%s\" - Absolute position invalid!\n", |
1558 address); |
1551 original); |
1559 } |
1552 } |
1560 } |
1553 } |
1561 else if (remainder[0] == ':') { // field position |
1554 else if (remainder[0] == ':') { // field position |
1562 remainder++; |
1555 remainder++; |
1563 second = simple_strtoul(remainder, &remainder2, 0); |
1556 second = simple_strtoul(remainder, &remainder2, 0); |
1564 |
1557 |
1565 if (remainder2 == remainder) { |
1558 if (remainder2 == remainder) { |
1566 EC_ERR("Slave address \"%s\" - Second number empty!\n", address); |
1559 EC_ERR("Slave address \"%s\" - Second number empty!\n", original); |
1567 return NULL; |
1560 return NULL; |
1568 } |
1561 } |
1569 |
1562 |
1570 if (remainder2[0]) { |
1563 if (remainder2[0]) { |
1571 EC_ERR("Slave address \"%s\" - Invalid trailer!\n", address); |
1564 EC_ERR("Slave address \"%s\" - Invalid trailer!\n", original); |
1572 return NULL; |
1565 return NULL; |
1573 } |
1566 } |
1574 |
1567 |
1575 if (alias_requested) { |
1568 if (alias_requested) { |
1576 if (!ec_slave_is_coupler(alias_slave)) { |
1569 if (!ec_slave_is_coupler(alias_slave)) { |
1577 EC_ERR("Slave address \"%s\": Alias slave must be bus coupler" |
1570 EC_ERR("Slave address \"%s\": Alias slave must be bus coupler" |
1578 " in colon mode.\n", address); |
1571 " in colon mode.\n", original); |
1579 return NULL; |
1572 return NULL; |
1580 } |
1573 } |
1581 list_for_each_entry(slave, &master->slaves, list) { |
1574 list_for_each_entry(slave, &master->slaves, list) { |
1582 if (slave->coupler_index == alias_slave->coupler_index |
1575 if (slave->coupler_index == alias_slave->coupler_index |
1583 && slave->coupler_subindex == second) |
1576 && slave->coupler_subindex == second) |
1584 return slave; |
1577 return slave; |
1585 } |
1578 } |
1586 EC_ERR("Slave address \"%s\" - Bus coupler %i has no %lu. slave" |
1579 EC_ERR("Slave address \"%s\" - Bus coupler %i has no %lu. slave" |
1587 " following!\n", address, alias_slave->ring_position, |
1580 " following!\n", original, alias_slave->ring_position, |
1588 second); |
1581 second); |
1589 return NULL; |
1582 return NULL; |
1590 } |
1583 } |
1591 else { |
1584 else { |
1592 list_for_each_entry(slave, &master->slaves, list) { |
1585 list_for_each_entry(slave, &master->slaves, list) { |