329 follows_word = NULL; |
326 follows_word = NULL; |
330 more_datagrams_waiting = 0; |
327 more_datagrams_waiting = 0; |
331 |
328 |
332 // fill current frame with datagrams |
329 // fill current frame with datagrams |
333 list_for_each_entry(datagram, &master->datagram_queue, queue) { |
330 list_for_each_entry(datagram, &master->datagram_queue, queue) { |
334 if (datagram->state != EC_CMD_QUEUED) continue; |
331 if (datagram->state != EC_DATAGRAM_QUEUED) continue; |
335 |
332 |
336 // does the current datagram fit in the frame? |
333 // does the current datagram fit in the frame? |
337 datagram_size = EC_DATAGRAM_HEADER_SIZE + datagram->data_size |
334 datagram_size = EC_DATAGRAM_HEADER_SIZE + datagram->data_size |
338 + EC_DATAGRAM_FOOTER_SIZE; |
335 + EC_DATAGRAM_FOOTER_SIZE; |
339 if (cur_data - frame_data + datagram_size > ETH_DATA_LEN) { |
336 if (cur_data - frame_data + datagram_size > ETH_DATA_LEN) { |
340 more_datagrams_waiting = 1; |
337 more_datagrams_waiting = 1; |
341 break; |
338 break; |
342 } |
339 } |
343 |
340 |
344 datagram->state = EC_CMD_SENT; |
341 datagram->state = EC_DATAGRAM_SENT; |
345 datagram->t_sent = t_start; |
342 datagram->t_sent = t_start; |
346 datagram->index = master->datagram_index++; |
343 datagram->index = master->datagram_index++; |
347 |
344 |
348 if (unlikely(master->debug_level > 1)) |
345 if (unlikely(master->debug_level > 1)) |
349 EC_DBG("adding datagram 0x%02X\n", datagram->index); |
346 EC_DBG("adding datagram 0x%02X\n", datagram->index); |
480 // set the datagram's working counter |
477 // set the datagram's working counter |
481 datagram->working_counter = EC_READ_U16(cur_data); |
478 datagram->working_counter = EC_READ_U16(cur_data); |
482 cur_data += EC_DATAGRAM_FOOTER_SIZE; |
479 cur_data += EC_DATAGRAM_FOOTER_SIZE; |
483 |
480 |
484 // dequeue the received datagram |
481 // dequeue the received datagram |
485 datagram->state = EC_CMD_RECEIVED; |
482 datagram->state = EC_DATAGRAM_RECEIVED; |
486 list_del_init(&datagram->queue); |
483 list_del_init(&datagram->queue); |
487 } |
|
488 } |
|
489 |
|
490 /*****************************************************************************/ |
|
491 |
|
492 /** |
|
493 Sends a single datagram and waits for its reception. |
|
494 If the slave doesn't respond, the datagram is sent again. |
|
495 \return 0 in case of success, else < 0 |
|
496 */ |
|
497 |
|
498 int ec_master_simple_io(ec_master_t *master, /**< EtherCAT master */ |
|
499 ec_datagram_t *datagram /**< datagram */ |
|
500 ) |
|
501 { |
|
502 unsigned int response_tries_left; |
|
503 |
|
504 response_tries_left = 10000; |
|
505 |
|
506 while (1) |
|
507 { |
|
508 ec_master_queue_datagram(master, datagram); |
|
509 ecrt_master_sync_io(master); |
|
510 |
|
511 if (datagram->state == EC_CMD_RECEIVED) { |
|
512 if (likely(datagram->working_counter)) |
|
513 return 0; |
|
514 } |
|
515 else if (datagram->state == EC_CMD_TIMEOUT) { |
|
516 EC_ERR("Simple-IO TIMEOUT!\n"); |
|
517 return -1; |
|
518 } |
|
519 else if (datagram->state == EC_CMD_ERROR) { |
|
520 EC_ERR("Simple-IO datagram error!\n"); |
|
521 return -1; |
|
522 } |
|
523 |
|
524 // no direct response, wait a little bit... |
|
525 udelay(100); |
|
526 |
|
527 if (unlikely(--response_tries_left)) { |
|
528 EC_ERR("No response in simple-IO!\n"); |
|
529 return -1; |
|
530 } |
|
531 } |
484 } |
532 } |
485 } |
533 |
486 |
534 /*****************************************************************************/ |
487 /*****************************************************************************/ |
535 |
488 |
539 \return 0 in case of success, else < 0 |
492 \return 0 in case of success, else < 0 |
540 */ |
493 */ |
541 |
494 |
542 int ec_master_bus_scan(ec_master_t *master /**< EtherCAT master */) |
495 int ec_master_bus_scan(ec_master_t *master /**< EtherCAT master */) |
543 { |
496 { |
544 ec_slave_t *slave; |
497 ec_fsm_t *fsm = &master->fsm; |
545 ec_slave_ident_t *ident; |
498 |
546 ec_datagram_t *datagram; |
499 ec_fsm_startup(fsm); // init startup state machine |
547 unsigned int i; |
500 |
548 uint16_t coupler_index, coupler_subindex; |
501 do { |
549 uint16_t reverse_coupler_index, current_coupler_index; |
502 ec_fsm_execute(fsm); |
550 |
503 ec_master_sync_io(master); |
551 if (!list_empty(&master->slaves)) { |
504 } |
552 EC_ERR("Slave scan already done!\n"); |
505 while (ec_fsm_startup_running(fsm)); |
|
506 |
|
507 if (!ec_fsm_startup_success(fsm)) { |
|
508 ec_master_clear_slaves(master); |
553 return -1; |
509 return -1; |
554 } |
510 } |
555 |
511 |
556 datagram = &master->simple_datagram; |
|
557 |
|
558 // determine number of slaves on bus |
|
559 if (ec_datagram_brd(datagram, 0x0000, 4)) return -1; |
|
560 if (unlikely(ec_master_simple_io(master, datagram))) return -1; |
|
561 master->slave_count = datagram->working_counter; |
|
562 EC_INFO("Found %i slaves on bus.\n", master->slave_count); |
|
563 |
|
564 if (!master->slave_count) return 0; |
|
565 |
|
566 // init slaves |
|
567 for (i = 0; i < master->slave_count; i++) { |
|
568 if (!(slave = |
|
569 (ec_slave_t *) kmalloc(sizeof(ec_slave_t), GFP_KERNEL))) { |
|
570 EC_ERR("Failed to allocate slave %i!\n", i); |
|
571 goto out_free; |
|
572 } |
|
573 |
|
574 if (ec_slave_init(slave, master, i, i + 1)) goto out_free; |
|
575 |
|
576 if (kobject_add(&slave->kobj)) { |
|
577 EC_ERR("Failed to add kobject.\n"); |
|
578 kobject_put(&slave->kobj); // free |
|
579 goto out_free; |
|
580 } |
|
581 |
|
582 list_add_tail(&slave->list, &master->slaves); |
|
583 } |
|
584 |
|
585 coupler_index = 0; |
|
586 reverse_coupler_index = 0xFFFF; |
|
587 current_coupler_index = 0x3FFF; |
|
588 coupler_subindex = 0; |
|
589 |
|
590 // for every slave on the bus |
|
591 list_for_each_entry(slave, &master->slaves, list) { |
|
592 |
|
593 // write station address |
|
594 if (ec_datagram_apwr(datagram, slave->ring_position, 0x0010, |
|
595 sizeof(uint16_t))) goto out_free; |
|
596 EC_WRITE_U16(datagram->data, slave->station_address); |
|
597 if (unlikely(ec_master_simple_io(master, datagram))) { |
|
598 EC_ERR("Writing station address failed on slave %i!\n", |
|
599 slave->ring_position); |
|
600 goto out_free; |
|
601 } |
|
602 |
|
603 // fetch all slave information |
|
604 if (ec_slave_fetch(slave)) goto out_free; |
|
605 |
|
606 // search for identification in "database" |
|
607 ident = slave_idents; |
|
608 while (ident->type) { |
|
609 if (unlikely(ident->vendor_id == slave->sii_vendor_id |
|
610 && ident->product_code == slave->sii_product_code)) { |
|
611 slave->type = ident->type; |
|
612 break; |
|
613 } |
|
614 ident++; |
|
615 } |
|
616 |
|
617 if (!slave->type) { |
|
618 EC_WARN("Unknown slave device (vendor 0x%08X, code 0x%08X) at" |
|
619 " position %i.\n", slave->sii_vendor_id, |
|
620 slave->sii_product_code, slave->ring_position); |
|
621 } |
|
622 else if (slave->type->special == EC_TYPE_BUS_COUPLER) { |
|
623 if (slave->sii_alias) |
|
624 current_coupler_index = reverse_coupler_index--; |
|
625 else |
|
626 current_coupler_index = coupler_index++; |
|
627 coupler_subindex = 0; |
|
628 } |
|
629 |
|
630 slave->coupler_index = current_coupler_index; |
|
631 slave->coupler_subindex = coupler_subindex; |
|
632 coupler_subindex++; |
|
633 } |
|
634 |
|
635 return 0; |
512 return 0; |
636 |
|
637 out_free: |
|
638 ec_master_clear_slaves(master); |
|
639 return -1; |
|
640 } |
513 } |
641 |
514 |
642 /*****************************************************************************/ |
515 /*****************************************************************************/ |
643 |
516 |
644 /** |
517 /** |
746 } |
619 } |
747 |
620 |
748 /*****************************************************************************/ |
621 /*****************************************************************************/ |
749 |
622 |
750 /** |
623 /** |
751 Initializes a sync manager configuration page. |
624 Initializes a sync manager configuration page with EEPROM data. |
752 The referenced memory (\a data) must be at least EC_SYNC_SIZE bytes. |
625 The referenced memory (\a data) must be at least EC_SYNC_SIZE bytes. |
753 */ |
626 */ |
754 |
627 |
755 void ec_sync_config(const ec_sync_t *sync, /**< sync manager */ |
628 void ec_sync_config(const ec_sii_sync_t *sync, /**< sync manager */ |
756 const ec_slave_t *slave, /**< EtherCAT slave */ |
629 const ec_slave_t *slave, /**< EtherCAT slave */ |
757 uint8_t *data /**> configuration memory */ |
630 uint8_t *data /**> configuration memory */ |
758 ) |
631 ) |
759 { |
632 { |
760 size_t sync_size; |
633 size_t sync_size; |
761 |
634 |
762 sync_size = ec_slave_calc_sync_size(slave, sync); |
635 sync_size = ec_slave_calc_sync_size(slave, sync); |
763 |
|
764 EC_WRITE_U16(data, sync->physical_start_address); |
|
765 EC_WRITE_U16(data + 2, sync_size); |
|
766 EC_WRITE_U8 (data + 4, sync->control_byte); |
|
767 EC_WRITE_U8 (data + 5, 0x00); // status byte (read only) |
|
768 EC_WRITE_U16(data + 6, 0x0001); // enable |
|
769 } |
|
770 |
|
771 /*****************************************************************************/ |
|
772 |
|
773 /** |
|
774 Initializes a sync manager configuration page with EEPROM data. |
|
775 The referenced memory (\a data) must be at least EC_SYNC_SIZE bytes. |
|
776 */ |
|
777 |
|
778 void ec_eeprom_sync_config(const ec_eeprom_sync_t *sync, /**< sync manager */ |
|
779 const ec_slave_t *slave, /**< EtherCAT slave */ |
|
780 uint8_t *data /**> configuration memory */ |
|
781 ) |
|
782 { |
|
783 size_t sync_size; |
|
784 |
|
785 sync_size = ec_slave_calc_eeprom_sync_size(slave, sync); |
|
786 |
636 |
787 if (slave->master->debug_level) { |
637 if (slave->master->debug_level) { |
788 EC_INFO("Slave %i, sync manager %i:\n", slave->ring_position, |
638 EC_INFO("Slave %i, sync manager %i:\n", slave->ring_position, |
789 sync->index); |
639 sync->index); |
790 EC_INFO(" Address: 0x%04X\n", sync->physical_start_address); |
640 EC_INFO(" Address: 0x%04X\n", sync->physical_start_address); |
819 EC_WRITE_U16(data + 4, sync_size); // size of fmmu |
669 EC_WRITE_U16(data + 4, sync_size); // size of fmmu |
820 EC_WRITE_U8 (data + 6, 0x00); // logical start bit |
670 EC_WRITE_U8 (data + 6, 0x00); // logical start bit |
821 EC_WRITE_U8 (data + 7, 0x07); // logical end bit |
671 EC_WRITE_U8 (data + 7, 0x07); // logical end bit |
822 EC_WRITE_U16(data + 8, fmmu->sync->physical_start_address); |
672 EC_WRITE_U16(data + 8, fmmu->sync->physical_start_address); |
823 EC_WRITE_U8 (data + 10, 0x00); // physical start bit |
673 EC_WRITE_U8 (data + 10, 0x00); // physical start bit |
824 EC_WRITE_U8 (data + 11, (fmmu->sync->control_byte & 0x04) ? 0x02 : 0x01); |
674 EC_WRITE_U8 (data + 11, ((fmmu->sync->control_register & 0x04) |
|
675 ? 0x02 : 0x01)); |
825 EC_WRITE_U16(data + 12, 0x0001); // enable |
676 EC_WRITE_U16(data + 12, 0x0001); // enable |
826 EC_WRITE_U16(data + 14, 0x0000); // reserved |
677 EC_WRITE_U16(data + 14, 0x0000); // reserved |
827 } |
678 } |
828 |
679 |
829 /*****************************************************************************/ |
680 /*****************************************************************************/ |
920 } |
771 } |
921 |
772 |
922 /*****************************************************************************/ |
773 /*****************************************************************************/ |
923 |
774 |
924 /** |
775 /** |
925 Starts Ethernet-over-EtherCAT processing for all EoE-capable slaves. |
776 Starts/Stops Ethernet-over-EtherCAT processing on demand. |
926 */ |
777 */ |
927 |
778 |
928 void ec_master_eoe_start(ec_master_t *master /**< EtherCAT master */) |
779 void ec_master_eoe_start(ec_master_t *master /**< EtherCAT master */) |
929 { |
780 { |
930 ec_eoe_t *eoe; |
781 ec_eoe_t *eoe; |
931 ec_slave_t *slave; |
782 ec_slave_t *slave; |
932 unsigned int coupled, found; |
783 unsigned int coupled, found; |
933 |
784 |
934 if (master->eoe_running) return; |
785 if (master->eoe_running) return; |
935 |
786 |
|
787 // if the locking callbacks are not set in operation mode, |
|
788 // the EoE timer my not be started. |
|
789 if (master->mode == EC_MASTER_MODE_OPERATION |
|
790 && (!master->request_cb || !master->release_cb)) return; |
|
791 |
936 // decouple all EoE handlers |
792 // decouple all EoE handlers |
937 list_for_each_entry(eoe, &master->eoe_handlers, list) |
793 list_for_each_entry(eoe, &master->eoe_handlers, list) |
938 eoe->slave = NULL; |
794 eoe->slave = NULL; |
|
795 |
|
796 // couple a free EoE handler to every EoE-capable slave |
939 coupled = 0; |
797 coupled = 0; |
940 |
|
941 // couple a free EoE handler to every EoE-capable slave |
|
942 list_for_each_entry(slave, &master->slaves, list) { |
798 list_for_each_entry(slave, &master->slaves, list) { |
943 if (!(slave->sii_mailbox_protocols & EC_MBOX_EOE)) continue; |
799 if (!(slave->sii_mailbox_protocols & EC_MBOX_EOE)) continue; |
944 |
800 |
945 found = 0; |
801 found = 0; |
946 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
802 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
1036 } |
888 } |
1037 else |
889 else |
1038 goto queue_timer; |
890 goto queue_timer; |
1039 |
891 |
1040 // actual EoE stuff |
892 // actual EoE stuff |
1041 ecrt_master_async_receive(master); |
893 ecrt_master_receive(master); |
1042 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
894 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
1043 ec_eoe_run(eoe); |
895 ec_eoe_run(eoe); |
1044 } |
896 } |
1045 ecrt_master_async_send(master); |
897 ecrt_master_send(master); |
1046 |
898 |
1047 // release lock... |
899 // release lock... |
1048 if (master->mode == EC_MASTER_MODE_RUNNING) { |
900 if (master->mode == EC_MASTER_MODE_OPERATION) { |
1049 master->release_cb(master->cb_data); |
901 master->release_cb(master->cb_data); |
1050 } |
902 } |
1051 else if (master->mode == EC_MASTER_MODE_IDLE) { |
903 else if (master->mode == EC_MASTER_MODE_IDLE) { |
1052 spin_unlock(&master->internal_lock); |
904 spin_unlock(&master->internal_lock); |
1053 } |
905 } |
1054 |
906 |
1055 queue_timer: |
907 queue_timer: |
1056 master->eoe_timer.expires += HZ / EC_EOE_FREQUENCY; |
908 master->eoe_timer.expires += HZ / EC_EOE_FREQUENCY; |
1057 add_timer(&master->eoe_timer); |
909 add_timer(&master->eoe_timer); |
|
910 } |
|
911 |
|
912 /*****************************************************************************/ |
|
913 |
|
914 /** |
|
915 Calculates Advanced Position Adresses. |
|
916 */ |
|
917 |
|
918 void ec_master_calc_addressing(ec_master_t *master /**< EtherCAT master */) |
|
919 { |
|
920 uint16_t coupler_index, coupler_subindex; |
|
921 uint16_t reverse_coupler_index, current_coupler_index; |
|
922 ec_slave_t *slave; |
|
923 |
|
924 coupler_index = 0; |
|
925 reverse_coupler_index = 0xFFFF; |
|
926 current_coupler_index = 0x0000; |
|
927 coupler_subindex = 0; |
|
928 |
|
929 list_for_each_entry(slave, &master->slaves, list) { |
|
930 if (ec_slave_is_coupler(slave)) { |
|
931 if (slave->sii_alias) |
|
932 current_coupler_index = reverse_coupler_index--; |
|
933 else |
|
934 current_coupler_index = coupler_index++; |
|
935 coupler_subindex = 0; |
|
936 } |
|
937 |
|
938 slave->coupler_index = current_coupler_index; |
|
939 slave->coupler_subindex = coupler_subindex; |
|
940 coupler_subindex++; |
|
941 } |
1058 } |
942 } |
1059 |
943 |
1060 /****************************************************************************** |
944 /****************************************************************************** |
1061 * Realtime interface |
945 * Realtime interface |
1062 *****************************************************************************/ |
946 *****************************************************************************/ |
1135 return -1; |
1012 return -1; |
1136 } |
1013 } |
1137 domain_offset += domain->data_size; |
1014 domain_offset += domain->data_size; |
1138 } |
1015 } |
1139 |
1016 |
1140 // configure and activate slaves |
1017 // determine initial states. |
1141 list_for_each_entry(slave, &master->slaves, list) { |
1018 list_for_each_entry(slave, &master->slaves, list) { |
1142 |
1019 if (ec_slave_is_coupler(slave) || slave->registered) { |
1143 // change state to INIT |
1020 slave->requested_state = EC_SLAVE_STATE_OP; |
1144 if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_INIT))) |
1021 } |
1145 return -1; |
1022 else { |
1146 |
1023 slave->requested_state = EC_SLAVE_STATE_PREOP; |
1147 // check for slave registration |
1024 } |
1148 type = slave->type; |
1025 } |
1149 if (!type) |
1026 |
1150 EC_WARN("Slave %i has unknown type!\n", slave->ring_position); |
1027 ec_fsm_configuration(fsm); // init configuration state machine |
1151 |
1028 |
1152 // check and reset CRC fault counters |
1029 do { |
1153 ec_slave_check_crc(slave); |
1030 ec_fsm_execute(fsm); |
1154 |
1031 ec_master_sync_io(master); |
1155 // reset FMMUs |
1032 } |
1156 if (slave->base_fmmu_count) { |
1033 while (ec_fsm_configuration_running(fsm)); |
1157 if (ec_datagram_npwr(datagram, slave->station_address, 0x0600, |
1034 |
1158 EC_FMMU_SIZE * slave->base_fmmu_count)) |
1035 if (!ec_fsm_configuration_success(fsm)) { |
1159 return -1; |
1036 return -1; |
1160 memset(datagram->data, 0x00, |
1037 } |
1161 EC_FMMU_SIZE * slave->base_fmmu_count); |
1038 |
1162 if (unlikely(ec_master_simple_io(master, datagram))) { |
1039 ec_fsm_reset(&master->fsm); // prepare for operation state machine |
1163 EC_ERR("Resetting FMMUs failed on slave %i!\n", |
|
1164 slave->ring_position); |
|
1165 return -1; |
|
1166 } |
|
1167 } |
|
1168 |
|
1169 // reset sync managers |
|
1170 if (slave->base_sync_count) { |
|
1171 if (ec_datagram_npwr(datagram, slave->station_address, 0x0800, |
|
1172 EC_SYNC_SIZE * slave->base_sync_count)) |
|
1173 return -1; |
|
1174 memset(datagram->data, 0x00, |
|
1175 EC_SYNC_SIZE * slave->base_sync_count); |
|
1176 if (unlikely(ec_master_simple_io(master, datagram))) { |
|
1177 EC_ERR("Resetting sync managers failed on slave %i!\n", |
|
1178 slave->ring_position); |
|
1179 return -1; |
|
1180 } |
|
1181 } |
|
1182 |
|
1183 // configure sync managers |
|
1184 |
|
1185 // does the slave provide sync manager information? |
|
1186 if (!list_empty(&slave->eeprom_syncs)) { |
|
1187 list_for_each_entry(eeprom_sync, &slave->eeprom_syncs, list) { |
|
1188 if (ec_datagram_npwr(datagram, slave->station_address, |
|
1189 0x800 + eeprom_sync->index * |
|
1190 EC_SYNC_SIZE, |
|
1191 EC_SYNC_SIZE)) return -1; |
|
1192 ec_eeprom_sync_config(eeprom_sync, slave, datagram->data); |
|
1193 if (unlikely(ec_master_simple_io(master, datagram))) { |
|
1194 EC_ERR("Setting sync manager %i failed on slave %i!\n", |
|
1195 eeprom_sync->index, slave->ring_position); |
|
1196 return -1; |
|
1197 } |
|
1198 } |
|
1199 } |
|
1200 |
|
1201 else if (type) { // known slave type, take type's SM information |
|
1202 for (j = 0; type->sync_managers[j] && j < EC_MAX_SYNC; j++) { |
|
1203 sync = type->sync_managers[j]; |
|
1204 if (ec_datagram_npwr(datagram, slave->station_address, |
|
1205 0x0800 + j * EC_SYNC_SIZE, EC_SYNC_SIZE)) |
|
1206 return -1; |
|
1207 ec_sync_config(sync, slave, datagram->data); |
|
1208 if (unlikely(ec_master_simple_io(master, datagram))) { |
|
1209 EC_ERR("Setting sync manager %i failed on slave %i!\n", |
|
1210 j, slave->ring_position); |
|
1211 return -1; |
|
1212 } |
|
1213 } |
|
1214 } |
|
1215 |
|
1216 // no sync manager information; guess mailbox settings |
|
1217 else if (slave->sii_mailbox_protocols) { |
|
1218 mbox_sync.physical_start_address = |
|
1219 slave->sii_rx_mailbox_offset; |
|
1220 mbox_sync.length = slave->sii_rx_mailbox_size; |
|
1221 mbox_sync.control_register = 0x26; |
|
1222 mbox_sync.enable = 1; |
|
1223 if (ec_datagram_npwr(datagram, slave->station_address, |
|
1224 0x800,EC_SYNC_SIZE)) return -1; |
|
1225 ec_eeprom_sync_config(&mbox_sync, slave, datagram->data); |
|
1226 if (unlikely(ec_master_simple_io(master, datagram))) { |
|
1227 EC_ERR("Setting sync manager 0 failed on slave %i!\n", |
|
1228 slave->ring_position); |
|
1229 return -1; |
|
1230 } |
|
1231 |
|
1232 mbox_sync.physical_start_address = |
|
1233 slave->sii_tx_mailbox_offset; |
|
1234 mbox_sync.length = slave->sii_tx_mailbox_size; |
|
1235 mbox_sync.control_register = 0x22; |
|
1236 mbox_sync.enable = 1; |
|
1237 if (ec_datagram_npwr(datagram, slave->station_address, |
|
1238 0x808, EC_SYNC_SIZE)) return -1; |
|
1239 ec_eeprom_sync_config(&mbox_sync, slave, datagram->data); |
|
1240 if (unlikely(ec_master_simple_io(master, datagram))) { |
|
1241 EC_ERR("Setting sync manager 1 failed on slave %i!\n", |
|
1242 slave->ring_position); |
|
1243 return -1; |
|
1244 } |
|
1245 } |
|
1246 |
|
1247 // change state to PREOP |
|
1248 if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_PREOP))) |
|
1249 return -1; |
|
1250 |
|
1251 // stop activation here for slaves without type |
|
1252 if (!type) continue; |
|
1253 |
|
1254 // slaves that are not registered are only brought into PREOP |
|
1255 // state -> nice blinking and mailbox communication possible |
|
1256 if (!slave->registered && !slave->type->special) { |
|
1257 EC_WARN("Slave %i was not registered!\n", slave->ring_position); |
|
1258 continue; |
|
1259 } |
|
1260 |
|
1261 // configure FMMUs |
|
1262 for (j = 0; j < slave->fmmu_count; j++) { |
|
1263 fmmu = &slave->fmmus[j]; |
|
1264 if (ec_datagram_npwr(datagram, slave->station_address, |
|
1265 0x0600 + j * EC_FMMU_SIZE, EC_FMMU_SIZE)) |
|
1266 return -1; |
|
1267 ec_fmmu_config(fmmu, slave, datagram->data); |
|
1268 if (unlikely(ec_master_simple_io(master, datagram))) { |
|
1269 EC_ERR("Setting FMMU %i failed on slave %i!\n", |
|
1270 j, slave->ring_position); |
|
1271 return -1; |
|
1272 } |
|
1273 } |
|
1274 |
|
1275 // change state to SAVEOP |
|
1276 if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_SAVEOP))) |
|
1277 return -1; |
|
1278 |
|
1279 // change state to OP |
|
1280 if (unlikely(ec_slave_state_change(slave, EC_SLAVE_STATE_OP))) |
|
1281 return -1; |
|
1282 } |
|
1283 |
1040 |
1284 return 0; |
1041 return 0; |
1285 } |
1042 } |
1286 |
1043 |
1287 /*****************************************************************************/ |
1044 /*****************************************************************************/ |
1291 \ingroup RealtimeInterface |
1048 \ingroup RealtimeInterface |
1292 */ |
1049 */ |
1293 |
1050 |
1294 void ecrt_master_deactivate(ec_master_t *master /**< EtherCAT master */) |
1051 void ecrt_master_deactivate(ec_master_t *master /**< EtherCAT master */) |
1295 { |
1052 { |
|
1053 ec_fsm_t *fsm = &master->fsm; |
1296 ec_slave_t *slave; |
1054 ec_slave_t *slave; |
1297 |
1055 |
1298 list_for_each_entry(slave, &master->slaves, list) { |
1056 list_for_each_entry(slave, &master->slaves, list) { |
1299 ec_slave_check_crc(slave); |
1057 slave->requested_state = EC_SLAVE_STATE_INIT; |
1300 ec_slave_state_change(slave, EC_SLAVE_STATE_INIT); |
1058 } |
1301 } |
1059 |
1302 } |
1060 ec_fsm_configuration(fsm); // init configuration state machine |
1303 |
1061 |
1304 |
1062 do { |
1305 /*****************************************************************************/ |
1063 ec_fsm_execute(fsm); |
1306 |
1064 ec_master_sync_io(master); |
1307 /** |
1065 } |
1308 Fetches the SDO dictionaries of all slaves. |
1066 while (ec_fsm_configuration_running(fsm)); |
1309 Slaves that do not support the CoE protocol are left out. |
|
1310 \return 0 in case of success, else < 0 |
|
1311 \ingroup RealtimeInterface |
|
1312 */ |
|
1313 |
|
1314 int ecrt_master_fetch_sdo_lists(ec_master_t *master /**< EtherCAT master */) |
|
1315 { |
|
1316 ec_slave_t *slave; |
|
1317 |
|
1318 list_for_each_entry(slave, &master->slaves, list) { |
|
1319 if (slave->sii_mailbox_protocols & EC_MBOX_COE) { |
|
1320 if (unlikely(ec_slave_fetch_sdo_list(slave))) { |
|
1321 EC_ERR("Failed to fetch SDO list on slave %i!\n", |
|
1322 slave->ring_position); |
|
1323 return -1; |
|
1324 } |
|
1325 } |
|
1326 } |
|
1327 |
|
1328 return 0; |
|
1329 } |
1067 } |
1330 |
1068 |
1331 /*****************************************************************************/ |
1069 /*****************************************************************************/ |
1332 |
1070 |
1333 /** |
1071 /** |
1334 Sends queued datagrams and waits for their reception. |
1072 Sends queued datagrams and waits for their reception. |
1335 \ingroup RealtimeInterface |
1073 */ |
1336 */ |
1074 |
1337 |
1075 void ec_master_sync_io(ec_master_t *master /**< EtherCAT master */) |
1338 void ecrt_master_sync_io(ec_master_t *master /**< EtherCAT master */) |
|
1339 { |
1076 { |
1340 ec_datagram_t *datagram, *n; |
1077 ec_datagram_t *datagram, *n; |
1341 unsigned int datagrams_sent; |
1078 unsigned int datagrams_sent; |
1342 cycles_t t_start, t_end, t_timeout; |
1079 cycles_t t_start, t_end, t_timeout; |
1343 |
1080 |
1344 // send datagrams |
1081 // send datagrams |
1345 ecrt_master_async_send(master); |
1082 ecrt_master_send(master); |
1346 |
1083 |
1347 t_start = get_cycles(); // measure io time |
1084 t_start = get_cycles(); // measure io time |
1348 t_timeout = (cycles_t) master->timeout * (cpu_khz / 1000); |
1085 t_timeout = (cycles_t) EC_IO_TIMEOUT * (cpu_khz / 1000); |
1349 |
1086 |
1350 while (1) { // active waiting |
1087 while (1) { // active waiting |
1351 ec_device_call_isr(master->device); |
1088 ec_device_call_isr(master->device); |
1352 |
1089 |
1353 t_end = get_cycles(); // take current time |
1090 t_end = get_cycles(); // take current time |
1354 if (t_end - t_start >= t_timeout) break; // timeout! |
1091 if (t_end - t_start >= t_timeout) break; // timeout! |
1355 |
1092 |
1356 datagrams_sent = 0; |
1093 datagrams_sent = 0; |
1357 list_for_each_entry_safe(datagram, n, &master->datagram_queue, queue) { |
1094 list_for_each_entry_safe(datagram, n, &master->datagram_queue, queue) { |
1358 if (datagram->state == EC_CMD_RECEIVED) |
1095 if (datagram->state == EC_DATAGRAM_RECEIVED) |
1359 list_del_init(&datagram->queue); |
1096 list_del_init(&datagram->queue); |
1360 else if (datagram->state == EC_CMD_SENT) |
1097 else if (datagram->state == EC_DATAGRAM_SENT) |
1361 datagrams_sent++; |
1098 datagrams_sent++; |
1362 } |
1099 } |
1363 |
1100 |
1364 if (!datagrams_sent) break; |
1101 if (!datagrams_sent) break; |
1365 } |
1102 } |
1366 |
1103 |
1367 // timeout; dequeue all datagrams |
1104 // timeout; dequeue all datagrams |
1368 list_for_each_entry_safe(datagram, n, &master->datagram_queue, queue) { |
1105 list_for_each_entry_safe(datagram, n, &master->datagram_queue, queue) { |
1369 switch (datagram->state) { |
1106 switch (datagram->state) { |
1370 case EC_CMD_SENT: |
1107 case EC_DATAGRAM_SENT: |
1371 case EC_CMD_QUEUED: |
1108 case EC_DATAGRAM_QUEUED: |
1372 datagram->state = EC_CMD_TIMEOUT; |
1109 datagram->state = EC_DATAGRAM_TIMED_OUT; |
1373 master->stats.timeouts++; |
1110 master->stats.timeouts++; |
1374 ec_master_output_stats(master); |
1111 ec_master_output_stats(master); |
1375 break; |
1112 break; |
1376 case EC_CMD_RECEIVED: |
1113 case EC_DATAGRAM_RECEIVED: |
1377 master->stats.delayed++; |
1114 master->stats.delayed++; |
1378 ec_master_output_stats(master); |
1115 ec_master_output_stats(master); |
1379 break; |
1116 break; |
1380 default: |
1117 default: |
1381 break; |
1118 break; |
1416 /** |
1153 /** |
1417 Asynchronous receiving of datagrams. |
1154 Asynchronous receiving of datagrams. |
1418 \ingroup RealtimeInterface |
1155 \ingroup RealtimeInterface |
1419 */ |
1156 */ |
1420 |
1157 |
1421 void ecrt_master_async_receive(ec_master_t *master /**< EtherCAT master */) |
1158 void ecrt_master_receive(ec_master_t *master /**< EtherCAT master */) |
1422 { |
1159 { |
1423 ec_datagram_t *datagram, *next; |
1160 ec_datagram_t *datagram, *next; |
1424 cycles_t t_received, t_timeout; |
1161 cycles_t t_received, t_timeout; |
1425 |
1162 |
1426 ec_device_call_isr(master->device); |
1163 ec_device_call_isr(master->device); |
1427 |
1164 |
1428 t_received = get_cycles(); |
1165 t_received = get_cycles(); |
1429 t_timeout = (cycles_t) master->timeout * (cpu_khz / 1000); |
1166 t_timeout = (cycles_t) EC_IO_TIMEOUT * (cpu_khz / 1000); |
1430 |
1167 |
1431 // dequeue all received datagrams |
1168 // dequeue all received datagrams |
1432 list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) |
1169 list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) |
1433 if (datagram->state == EC_CMD_RECEIVED) |
1170 if (datagram->state == EC_DATAGRAM_RECEIVED) |
1434 list_del_init(&datagram->queue); |
1171 list_del_init(&datagram->queue); |
1435 |
1172 |
1436 // dequeue all datagrams that timed out |
1173 // dequeue all datagrams that timed out |
1437 list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) { |
1174 list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) { |
1438 switch (datagram->state) { |
1175 switch (datagram->state) { |
1439 case EC_CMD_SENT: |
1176 case EC_DATAGRAM_SENT: |
1440 case EC_CMD_QUEUED: |
1177 case EC_DATAGRAM_QUEUED: |
1441 if (t_received - datagram->t_sent > t_timeout) { |
1178 if (t_received - datagram->t_sent > t_timeout) { |
1442 list_del_init(&datagram->queue); |
1179 list_del_init(&datagram->queue); |
1443 datagram->state = EC_CMD_TIMEOUT; |
1180 datagram->state = EC_DATAGRAM_TIMED_OUT; |
1444 master->stats.timeouts++; |
1181 master->stats.timeouts++; |
1445 ec_master_output_stats(master); |
1182 ec_master_output_stats(master); |
1446 } |
1183 } |
1447 break; |
1184 break; |
1448 default: |
1185 default: |
1454 /*****************************************************************************/ |
1191 /*****************************************************************************/ |
1455 |
1192 |
1456 /** |
1193 /** |
1457 Prepares synchronous IO. |
1194 Prepares synchronous IO. |
1458 Queues all domain datagrams and sends them. Then waits a certain time, so |
1195 Queues all domain datagrams and sends them. Then waits a certain time, so |
1459 that ecrt_master_sasync_receive() can be called securely. |
1196 that ecrt_master_receive() can be called securely. |
1460 \ingroup RealtimeInterface |
1197 \ingroup RealtimeInterface |
1461 */ |
1198 */ |
1462 |
1199 |
1463 void ecrt_master_prepare_async_io(ec_master_t *master /**< EtherCAT master */) |
1200 void ecrt_master_prepare(ec_master_t *master /**< EtherCAT master */) |
1464 { |
1201 { |
1465 ec_domain_t *domain; |
1202 ec_domain_t *domain; |
1466 cycles_t t_start, t_end, t_timeout; |
1203 cycles_t t_start, t_end, t_timeout; |
1467 |
1204 |
1468 // queue datagrams of all domains |
1205 // queue datagrams of all domains |
1469 list_for_each_entry(domain, &master->domains, list) |
1206 list_for_each_entry(domain, &master->domains, list) |
1470 ecrt_domain_queue(domain); |
1207 ec_domain_queue(domain); |
1471 |
1208 |
1472 ecrt_master_async_send(master); |
1209 ecrt_master_send(master); |
1473 |
1210 |
1474 t_start = get_cycles(); // take sending time |
1211 t_start = get_cycles(); // take sending time |
1475 t_timeout = (cycles_t) master->timeout * (cpu_khz / 1000); |
1212 t_timeout = (cycles_t) EC_IO_TIMEOUT * (cpu_khz / 1000); |
1476 |
1213 |
1477 // active waiting |
1214 // active waiting |
1478 while (1) { |
1215 while (1) { |
1479 t_end = get_cycles(); |
1216 t_end = get_cycles(); |
1480 if (t_end - t_start >= t_timeout) break; |
1217 if (t_end - t_start >= t_timeout) break; |
1626 master->cb_data = cb_data; |
1362 master->cb_data = cb_data; |
1627 } |
1363 } |
1628 |
1364 |
1629 /*****************************************************************************/ |
1365 /*****************************************************************************/ |
1630 |
1366 |
1631 /** |
|
1632 Starts Ethernet-over-EtherCAT processing for all EoE-capable slaves. |
|
1633 \ingroup RealtimeInterface |
|
1634 */ |
|
1635 |
|
1636 int ecrt_master_start_eoe(ec_master_t *master /**< EtherCAT master */) |
|
1637 { |
|
1638 if (!master->request_cb || !master->release_cb) { |
|
1639 EC_ERR("EoE requires master callbacks to be set!\n"); |
|
1640 return -1; |
|
1641 } |
|
1642 |
|
1643 ec_master_eoe_start(master); |
|
1644 return 0; |
|
1645 } |
|
1646 |
|
1647 /*****************************************************************************/ |
|
1648 |
|
1649 /** |
|
1650 Sets the debug level of the master. |
|
1651 The following levels are valid: |
|
1652 - 1: only output positions marks and basic data |
|
1653 - 2: additional frame data output |
|
1654 \ingroup RealtimeInterface |
|
1655 */ |
|
1656 |
|
1657 void ecrt_master_debug(ec_master_t *master, /**< EtherCAT master */ |
|
1658 int level /**< debug level */ |
|
1659 ) |
|
1660 { |
|
1661 if (level != master->debug_level) { |
|
1662 master->debug_level = level; |
|
1663 EC_INFO("Master debug level set to %i.\n", level); |
|
1664 } |
|
1665 } |
|
1666 |
|
1667 /*****************************************************************************/ |
|
1668 |
|
1669 /** |
|
1670 Outputs all master information. |
|
1671 Verbosity: |
|
1672 - 0: Only slave types and positions |
|
1673 - 1: with EEPROM contents |
|
1674 - >1: with SDO dictionaries |
|
1675 \ingroup RealtimeInterface |
|
1676 */ |
|
1677 |
|
1678 void ecrt_master_print(const ec_master_t *master, /**< EtherCAT master */ |
|
1679 unsigned int verbosity /**< verbosity level */ |
|
1680 ) |
|
1681 { |
|
1682 ec_slave_t *slave; |
|
1683 ec_eoe_t *eoe; |
|
1684 |
|
1685 EC_INFO("*** Begin master information ***\n"); |
|
1686 if (master->slave_count) { |
|
1687 EC_INFO("Slave list:\n"); |
|
1688 list_for_each_entry(slave, &master->slaves, list) |
|
1689 ec_slave_print(slave, verbosity); |
|
1690 } |
|
1691 if (!list_empty(&master->eoe_handlers)) { |
|
1692 EC_INFO("Ethernet-over-EtherCAT (EoE) objects:\n"); |
|
1693 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
|
1694 ec_eoe_print(eoe); |
|
1695 } |
|
1696 } |
|
1697 EC_INFO("*** End master information ***\n"); |
|
1698 } |
|
1699 |
|
1700 /*****************************************************************************/ |
|
1701 |
|
1702 /** \cond */ |
1367 /** \cond */ |
1703 |
1368 |
1704 EXPORT_SYMBOL(ecrt_master_create_domain); |
1369 EXPORT_SYMBOL(ecrt_master_create_domain); |
1705 EXPORT_SYMBOL(ecrt_master_activate); |
1370 EXPORT_SYMBOL(ecrt_master_activate); |
1706 EXPORT_SYMBOL(ecrt_master_deactivate); |
1371 EXPORT_SYMBOL(ecrt_master_deactivate); |
1707 EXPORT_SYMBOL(ecrt_master_fetch_sdo_lists); |
1372 EXPORT_SYMBOL(ecrt_master_prepare); |
1708 EXPORT_SYMBOL(ecrt_master_prepare_async_io); |
1373 EXPORT_SYMBOL(ecrt_master_send); |
1709 EXPORT_SYMBOL(ecrt_master_sync_io); |
1374 EXPORT_SYMBOL(ecrt_master_receive); |
1710 EXPORT_SYMBOL(ecrt_master_async_send); |
|
1711 EXPORT_SYMBOL(ecrt_master_async_receive); |
|
1712 EXPORT_SYMBOL(ecrt_master_run); |
1375 EXPORT_SYMBOL(ecrt_master_run); |
1713 EXPORT_SYMBOL(ecrt_master_callbacks); |
1376 EXPORT_SYMBOL(ecrt_master_callbacks); |
1714 EXPORT_SYMBOL(ecrt_master_start_eoe); |
|
1715 EXPORT_SYMBOL(ecrt_master_debug); |
|
1716 EXPORT_SYMBOL(ecrt_master_print); |
|
1717 EXPORT_SYMBOL(ecrt_master_get_slave); |
1377 EXPORT_SYMBOL(ecrt_master_get_slave); |
1718 |
1378 |
1719 /** \endcond */ |
1379 /** \endcond */ |
1720 |
1380 |
1721 /*****************************************************************************/ |
1381 /*****************************************************************************/ |