63 |
63 |
64 /*****************************************************************************/ |
64 /*****************************************************************************/ |
65 |
65 |
66 /** \cond */ |
66 /** \cond */ |
67 |
67 |
68 EC_SYSFS_READ_ATTR(slave_count); |
68 EC_SYSFS_READ_ATTR(info); |
69 EC_SYSFS_READ_ATTR(mode); |
|
70 EC_SYSFS_READ_WRITE_ATTR(eeprom_write_enable); |
69 EC_SYSFS_READ_WRITE_ATTR(eeprom_write_enable); |
71 EC_SYSFS_READ_WRITE_ATTR(debug_level); |
70 EC_SYSFS_READ_WRITE_ATTR(debug_level); |
72 |
71 |
73 static struct attribute *ec_def_attrs[] = { |
72 static struct attribute *ec_def_attrs[] = { |
74 &attr_slave_count, |
73 &attr_info, |
75 &attr_mode, |
|
76 &attr_eeprom_write_enable, |
74 &attr_eeprom_write_enable, |
77 &attr_debug_level, |
75 &attr_debug_level, |
78 NULL, |
76 NULL, |
79 }; |
77 }; |
80 |
78 |
120 master->eoe_timer.function = ec_master_eoe_run; |
118 master->eoe_timer.function = ec_master_eoe_run; |
121 master->eoe_timer.data = (unsigned long) master; |
119 master->eoe_timer.data = (unsigned long) master; |
122 master->internal_lock = SPIN_LOCK_UNLOCKED; |
120 master->internal_lock = SPIN_LOCK_UNLOCKED; |
123 master->eoe_running = 0; |
121 master->eoe_running = 0; |
124 master->eoe_checked = 0; |
122 master->eoe_checked = 0; |
|
123 master->idle_cycle_time = 0; |
|
124 master->eoe_cycle_time = 0; |
125 |
125 |
126 // create workqueue |
126 // create workqueue |
127 if (!(master->workqueue = create_singlethread_workqueue("EtherCAT"))) { |
127 if (!(master->workqueue = create_singlethread_workqueue("EtherCAT"))) { |
128 EC_ERR("Failed to create master workqueue.\n"); |
128 EC_ERR("Failed to create master workqueue.\n"); |
129 goto out_return; |
129 goto out_return; |
604 */ |
604 */ |
605 |
605 |
606 void ec_master_idle_run(void *data /**< master pointer */) |
606 void ec_master_idle_run(void *data /**< master pointer */) |
607 { |
607 { |
608 ec_master_t *master = (ec_master_t *) data; |
608 ec_master_t *master = (ec_master_t *) data; |
|
609 cycles_t start, end; |
609 |
610 |
610 // aquire master lock |
611 // aquire master lock |
611 spin_lock_bh(&master->internal_lock); |
612 spin_lock_bh(&master->internal_lock); |
612 |
613 |
|
614 start = get_cycles(); |
613 ecrt_master_receive(master); |
615 ecrt_master_receive(master); |
614 |
616 |
615 // execute master state machine |
617 // execute master state machine |
616 ec_fsm_execute(&master->fsm); |
618 ec_fsm_execute(&master->fsm); |
617 |
619 |
618 ecrt_master_send(master); |
620 ecrt_master_send(master); |
|
621 end = get_cycles(); |
619 |
622 |
620 // release master lock |
623 // release master lock |
621 spin_unlock_bh(&master->internal_lock); |
624 spin_unlock_bh(&master->internal_lock); |
|
625 |
|
626 master->idle_cycle_time = (u32) (end - start) * 1000 / cpu_khz; |
622 |
627 |
623 if (master->mode == EC_MASTER_MODE_IDLE) |
628 if (master->mode == EC_MASTER_MODE_IDLE) |
624 queue_delayed_work(master->workqueue, &master->idle_work, 1); |
629 queue_delayed_work(master->workqueue, &master->idle_work, 1); |
625 } |
630 } |
626 |
631 |
684 } |
689 } |
685 |
690 |
686 /*****************************************************************************/ |
691 /*****************************************************************************/ |
687 |
692 |
688 /** |
693 /** |
|
694 Formats master information for SysFS read access. |
|
695 \return number of bytes written |
|
696 */ |
|
697 |
|
698 ssize_t ec_master_info(ec_master_t *master, /**< EtherCAT master */ |
|
699 char *buffer /**< memory to store data */ |
|
700 ) |
|
701 { |
|
702 off_t off = 0; |
|
703 |
|
704 off += sprintf(buffer + off, "\nMode: "); |
|
705 switch (master->mode) { |
|
706 case EC_MASTER_MODE_ORPHANED: |
|
707 off += sprintf(buffer + off, "ORPHANED"); |
|
708 case EC_MASTER_MODE_IDLE: |
|
709 off += sprintf(buffer + off, "IDLE"); |
|
710 case EC_MASTER_MODE_OPERATION: |
|
711 off += sprintf(buffer + off, "OPERATION"); |
|
712 } |
|
713 |
|
714 off += sprintf(buffer + off, "\n\nNumber of slaves: %i\n", |
|
715 master->slave_count); |
|
716 |
|
717 off += sprintf(buffer + off, "\nTiming [us]:\n"); |
|
718 off += sprintf(buffer + off, " Idle cycle time: %u\n", |
|
719 master->idle_cycle_time); |
|
720 off += sprintf(buffer + off, " EoE cycle time: %u\n", |
|
721 master->eoe_cycle_time); |
|
722 |
|
723 off += sprintf(buffer + off, "\n"); |
|
724 |
|
725 return off; |
|
726 } |
|
727 |
|
728 /*****************************************************************************/ |
|
729 |
|
730 /** |
689 Formats attribute data for SysFS read access. |
731 Formats attribute data for SysFS read access. |
690 \return number of bytes to read |
732 \return number of bytes to read |
691 */ |
733 */ |
692 |
734 |
693 ssize_t ec_show_master_attribute(struct kobject *kobj, /**< kobject */ |
735 ssize_t ec_show_master_attribute(struct kobject *kobj, /**< kobject */ |
695 char *buffer /**< memory to store data */ |
737 char *buffer /**< memory to store data */ |
696 ) |
738 ) |
697 { |
739 { |
698 ec_master_t *master = container_of(kobj, ec_master_t, kobj); |
740 ec_master_t *master = container_of(kobj, ec_master_t, kobj); |
699 |
741 |
700 if (attr == &attr_slave_count) { |
742 if (attr == &attr_info) { |
701 return sprintf(buffer, "%i\n", master->slave_count); |
743 return ec_master_info(master, buffer); |
702 } |
|
703 else if (attr == &attr_mode) { |
|
704 switch (master->mode) { |
|
705 case EC_MASTER_MODE_ORPHANED: |
|
706 return sprintf(buffer, "ORPHANED\n"); |
|
707 case EC_MASTER_MODE_IDLE: |
|
708 return sprintf(buffer, "IDLE\n"); |
|
709 case EC_MASTER_MODE_OPERATION: |
|
710 return sprintf(buffer, "OPERATION\n"); |
|
711 } |
|
712 } |
744 } |
713 else if (attr == &attr_debug_level) { |
745 else if (attr == &attr_debug_level) { |
714 return sprintf(buffer, "%i\n", master->debug_level); |
746 return sprintf(buffer, "%i\n", master->debug_level); |
715 } |
747 } |
716 else if (attr == &attr_eeprom_write_enable) { |
748 else if (attr == &attr_eeprom_write_enable) { |
882 void ec_master_eoe_run(unsigned long data /**< master pointer */) |
914 void ec_master_eoe_run(unsigned long data /**< master pointer */) |
883 { |
915 { |
884 ec_master_t *master = (ec_master_t *) data; |
916 ec_master_t *master = (ec_master_t *) data; |
885 ec_eoe_t *eoe; |
917 ec_eoe_t *eoe; |
886 unsigned int active = 0; |
918 unsigned int active = 0; |
|
919 cycles_t start, end; |
887 |
920 |
888 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
921 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
889 if (ec_eoe_active(eoe)) active++; |
922 if (ec_eoe_active(eoe)) active++; |
890 } |
923 } |
891 if (!active) goto queue_timer; |
924 if (!active) goto queue_timer; |
901 } |
934 } |
902 else |
935 else |
903 goto queue_timer; |
936 goto queue_timer; |
904 |
937 |
905 // actual EoE stuff |
938 // actual EoE stuff |
|
939 start = get_cycles(); |
906 ecrt_master_receive(master); |
940 ecrt_master_receive(master); |
|
941 |
907 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
942 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
908 ec_eoe_run(eoe); |
943 ec_eoe_run(eoe); |
909 } |
944 } |
|
945 |
910 ecrt_master_send(master); |
946 ecrt_master_send(master); |
|
947 end = get_cycles(); |
911 |
948 |
912 // release lock... |
949 // release lock... |
913 if (master->mode == EC_MASTER_MODE_OPERATION) { |
950 if (master->mode == EC_MASTER_MODE_OPERATION) { |
914 master->release_cb(master->cb_data); |
951 master->release_cb(master->cb_data); |
915 } |
952 } |
916 else if (master->mode == EC_MASTER_MODE_IDLE) { |
953 else if (master->mode == EC_MASTER_MODE_IDLE) { |
917 spin_unlock(&master->internal_lock); |
954 spin_unlock(&master->internal_lock); |
918 } |
955 } |
|
956 |
|
957 master->eoe_cycle_time = (u32) (end - start) * 1000 / cpu_khz; |
919 |
958 |
920 queue_timer: |
959 queue_timer: |
921 master->eoe_timer.expires += HZ / EC_EOE_FREQUENCY; |
960 master->eoe_timer.expires += HZ / EC_EOE_FREQUENCY; |
922 add_timer(&master->eoe_timer); |
961 add_timer(&master->eoe_timer); |
923 } |
962 } |