56 /*****************************************************************************/ |
56 /*****************************************************************************/ |
57 |
57 |
58 void ec_master_freerun(void *); |
58 void ec_master_freerun(void *); |
59 void ec_master_eoe_run(unsigned long); |
59 void ec_master_eoe_run(unsigned long); |
60 ssize_t ec_show_master_attribute(struct kobject *, struct attribute *, char *); |
60 ssize_t ec_show_master_attribute(struct kobject *, struct attribute *, char *); |
|
61 ssize_t ec_store_master_attribute(struct kobject *, struct attribute *, |
|
62 const char *, size_t); |
61 |
63 |
62 /*****************************************************************************/ |
64 /*****************************************************************************/ |
63 |
65 |
64 /** \cond */ |
66 /** \cond */ |
65 |
67 |
66 EC_SYSFS_READ_ATTR(slave_count); |
68 EC_SYSFS_READ_ATTR(slave_count); |
67 EC_SYSFS_READ_ATTR(mode); |
69 EC_SYSFS_READ_ATTR(mode); |
|
70 EC_SYSFS_READ_WRITE_ATTR(eeprom_write_enable); |
68 |
71 |
69 static struct attribute *ec_def_attrs[] = { |
72 static struct attribute *ec_def_attrs[] = { |
70 &attr_slave_count, |
73 &attr_slave_count, |
71 &attr_mode, |
74 &attr_mode, |
|
75 &attr_eeprom_write_enable, |
72 NULL, |
76 NULL, |
73 }; |
77 }; |
74 |
78 |
75 static struct sysfs_ops ec_sysfs_ops = { |
79 static struct sysfs_ops ec_sysfs_ops = { |
76 .show = &ec_show_master_attribute, |
80 .show = &ec_show_master_attribute, |
77 .store = NULL |
81 .store = ec_store_master_attribute |
78 }; |
82 }; |
79 |
83 |
80 static struct kobj_type ktype_ec_master = { |
84 static struct kobj_type ktype_ec_master = { |
81 .release = ec_master_clear, |
85 .release = ec_master_clear, |
82 .sysfs_ops = &ec_sysfs_ops, |
86 .sysfs_ops = &ec_sysfs_ops, |
242 |
246 |
243 master->request_cb = NULL; |
247 master->request_cb = NULL; |
244 master->release_cb = NULL; |
248 master->release_cb = NULL; |
245 master->cb_data = NULL; |
249 master->cb_data = NULL; |
246 |
250 |
|
251 master->eeprom_write_enable = 0; |
|
252 |
247 ec_fsm_reset(&master->fsm); |
253 ec_fsm_reset(&master->fsm); |
248 } |
254 } |
249 |
255 |
250 /*****************************************************************************/ |
256 /*****************************************************************************/ |
251 |
257 |
490 ec_command_t *command /**< command */ |
496 ec_command_t *command /**< command */ |
491 ) |
497 ) |
492 { |
498 { |
493 unsigned int response_tries_left; |
499 unsigned int response_tries_left; |
494 |
500 |
495 response_tries_left = 10; |
501 response_tries_left = 10000; |
496 |
502 |
497 while (1) |
503 while (1) |
498 { |
504 { |
499 ec_master_queue_command(master, command); |
505 ec_master_queue_command(master, command); |
500 ecrt_master_sync_io(master); |
506 ecrt_master_sync_io(master); |
696 if (master->mode != EC_MASTER_MODE_FREERUN) return; |
702 if (master->mode != EC_MASTER_MODE_FREERUN) return; |
697 |
703 |
698 ec_master_eoe_stop(master); |
704 ec_master_eoe_stop(master); |
699 |
705 |
700 EC_INFO("Stopping Free-Run mode.\n"); |
706 EC_INFO("Stopping Free-Run mode.\n"); |
|
707 master->mode = EC_MASTER_MODE_IDLE; |
701 |
708 |
702 if (!cancel_delayed_work(&master->freerun_work)) { |
709 if (!cancel_delayed_work(&master->freerun_work)) { |
703 flush_workqueue(master->workqueue); |
710 flush_workqueue(master->workqueue); |
704 } |
711 } |
705 |
712 |
706 ec_master_clear_slaves(master); |
713 ec_master_clear_slaves(master); |
707 master->mode = EC_MASTER_MODE_IDLE; |
|
708 } |
714 } |
709 |
715 |
710 /*****************************************************************************/ |
716 /*****************************************************************************/ |
711 |
717 |
712 /** |
718 /** |
728 ecrt_master_async_send(master); |
734 ecrt_master_async_send(master); |
729 |
735 |
730 // release master lock |
736 // release master lock |
731 spin_unlock_bh(&master->internal_lock); |
737 spin_unlock_bh(&master->internal_lock); |
732 |
738 |
733 queue_delayed_work(master->workqueue, &master->freerun_work, 1); |
739 if (master->mode == EC_MASTER_MODE_FREERUN) |
|
740 queue_delayed_work(master->workqueue, &master->freerun_work, 1); |
734 } |
741 } |
735 |
742 |
736 /*****************************************************************************/ |
743 /*****************************************************************************/ |
737 |
744 |
738 /** |
745 /** |
739 Initializes a sync manager configuration page. |
746 Initializes a sync manager configuration page. |
740 The referenced memory (\a data) must be at least EC_SYNC_SIZE bytes. |
747 The referenced memory (\a data) must be at least EC_SYNC_SIZE bytes. |
741 */ |
748 */ |
742 |
749 |
743 void ec_sync_config(const ec_sync_t *sync, /**< sync manager */ |
750 void ec_sync_config(const ec_sync_t *sync, /**< sync manager */ |
|
751 const ec_slave_t *slave, /**< EtherCAT slave */ |
744 uint8_t *data /**> configuration memory */ |
752 uint8_t *data /**> configuration memory */ |
745 ) |
753 ) |
746 { |
754 { |
|
755 size_t sync_size; |
|
756 |
|
757 sync_size = ec_slave_calc_sync_size(slave, sync); |
|
758 |
747 EC_WRITE_U16(data, sync->physical_start_address); |
759 EC_WRITE_U16(data, sync->physical_start_address); |
748 EC_WRITE_U16(data + 2, sync->size); |
760 EC_WRITE_U16(data + 2, sync_size); |
749 EC_WRITE_U8 (data + 4, sync->control_byte); |
761 EC_WRITE_U8 (data + 4, sync->control_byte); |
750 EC_WRITE_U8 (data + 5, 0x00); // status byte (read only) |
762 EC_WRITE_U8 (data + 5, 0x00); // status byte (read only) |
751 EC_WRITE_U16(data + 6, 0x0001); // enable |
763 EC_WRITE_U16(data + 6, 0x0001); // enable |
752 } |
764 } |
753 |
765 |
775 Initializes an FMMU configuration page. |
787 Initializes an FMMU configuration page. |
776 The referenced memory (\a data) must be at least EC_FMMU_SIZE bytes. |
788 The referenced memory (\a data) must be at least EC_FMMU_SIZE bytes. |
777 */ |
789 */ |
778 |
790 |
779 void ec_fmmu_config(const ec_fmmu_t *fmmu, /**< FMMU */ |
791 void ec_fmmu_config(const ec_fmmu_t *fmmu, /**< FMMU */ |
|
792 const ec_slave_t *slave, /**< EtherCAT slave */ |
780 uint8_t *data /**> configuration memory */ |
793 uint8_t *data /**> configuration memory */ |
781 ) |
794 ) |
782 { |
795 { |
|
796 size_t sync_size; |
|
797 |
|
798 sync_size = ec_slave_calc_sync_size(slave, fmmu->sync); |
|
799 |
783 EC_WRITE_U32(data, fmmu->logical_start_address); |
800 EC_WRITE_U32(data, fmmu->logical_start_address); |
784 EC_WRITE_U16(data + 4, fmmu->sync->size); |
801 EC_WRITE_U16(data + 4, sync_size); // size of fmmu |
785 EC_WRITE_U8 (data + 6, 0x00); // logical start bit |
802 EC_WRITE_U8 (data + 6, 0x00); // logical start bit |
786 EC_WRITE_U8 (data + 7, 0x07); // logical end bit |
803 EC_WRITE_U8 (data + 7, 0x07); // logical end bit |
787 EC_WRITE_U16(data + 8, fmmu->sync->physical_start_address); |
804 EC_WRITE_U16(data + 8, fmmu->sync->physical_start_address); |
788 EC_WRITE_U8 (data + 10, 0x00); // physical start bit |
805 EC_WRITE_U8 (data + 10, 0x00); // physical start bit |
789 EC_WRITE_U8 (data + 11, (fmmu->sync->control_byte & 0x04) ? 0x02 : 0x01); |
806 EC_WRITE_U8 (data + 11, (fmmu->sync->control_byte & 0x04) ? 0x02 : 0x01); |
818 return sprintf(buffer, "RUNNING\n"); |
835 return sprintf(buffer, "RUNNING\n"); |
819 } |
836 } |
820 } |
837 } |
821 |
838 |
822 return 0; |
839 return 0; |
|
840 } |
|
841 |
|
842 /*****************************************************************************/ |
|
843 |
|
844 /** |
|
845 Formats attribute data for SysFS write access. |
|
846 \return number of bytes processed, or negative error code |
|
847 */ |
|
848 |
|
849 ssize_t ec_store_master_attribute(struct kobject *kobj, /**< slave's kobject */ |
|
850 struct attribute *attr, /**< attribute */ |
|
851 const char *buffer, /**< memory with data */ |
|
852 size_t size /**< size of data to store */ |
|
853 ) |
|
854 { |
|
855 ec_master_t *master = container_of(kobj, ec_master_t, kobj); |
|
856 |
|
857 if (attr == &attr_eeprom_write_enable) { |
|
858 if (!strcmp(buffer, "1\n")) { |
|
859 master->eeprom_write_enable = 1; |
|
860 EC_INFO("Slave EEPROM writing enabled.\n"); |
|
861 return size; |
|
862 } |
|
863 else if (!strcmp(buffer, "0\n")) { |
|
864 master->eeprom_write_enable = 0; |
|
865 EC_INFO("Slave EEPROM writing disabled.\n"); |
|
866 return size; |
|
867 } |
|
868 |
|
869 EC_ERR("Invalid value for eeprom_write_enable!\n"); |
|
870 |
|
871 if (master->eeprom_write_enable) { |
|
872 master->eeprom_write_enable = 0; |
|
873 EC_INFO("Slave EEPROM writing disabled.\n"); |
|
874 } |
|
875 } |
|
876 |
|
877 return -EINVAL; |
823 } |
878 } |
824 |
879 |
825 /*****************************************************************************/ |
880 /*****************************************************************************/ |
826 |
881 |
827 /** |
882 /** |
1086 for (j = 0; type->sync_managers[j] && j < EC_MAX_SYNC; j++) { |
1141 for (j = 0; type->sync_managers[j] && j < EC_MAX_SYNC; j++) { |
1087 sync = type->sync_managers[j]; |
1142 sync = type->sync_managers[j]; |
1088 if (ec_command_npwr(command, slave->station_address, |
1143 if (ec_command_npwr(command, slave->station_address, |
1089 0x0800 + j * EC_SYNC_SIZE, EC_SYNC_SIZE)) |
1144 0x0800 + j * EC_SYNC_SIZE, EC_SYNC_SIZE)) |
1090 return -1; |
1145 return -1; |
1091 ec_sync_config(sync, command->data); |
1146 ec_sync_config(sync, slave, command->data); |
1092 if (unlikely(ec_master_simple_io(master, command))) { |
1147 if (unlikely(ec_master_simple_io(master, command))) { |
1093 EC_ERR("Setting sync manager %i failed on slave %i!\n", |
1148 EC_ERR("Setting sync manager %i failed on slave %i!\n", |
1094 j, slave->ring_position); |
1149 j, slave->ring_position); |
1095 return -1; |
1150 return -1; |
1096 } |
1151 } |
1164 for (j = 0; j < slave->fmmu_count; j++) { |
1219 for (j = 0; j < slave->fmmu_count; j++) { |
1165 fmmu = &slave->fmmus[j]; |
1220 fmmu = &slave->fmmus[j]; |
1166 if (ec_command_npwr(command, slave->station_address, |
1221 if (ec_command_npwr(command, slave->station_address, |
1167 0x0600 + j * EC_FMMU_SIZE, EC_FMMU_SIZE)) |
1222 0x0600 + j * EC_FMMU_SIZE, EC_FMMU_SIZE)) |
1168 return -1; |
1223 return -1; |
1169 ec_fmmu_config(fmmu, command->data); |
1224 ec_fmmu_config(fmmu, slave, command->data); |
1170 if (unlikely(ec_master_simple_io(master, command))) { |
1225 if (unlikely(ec_master_simple_io(master, command))) { |
1171 EC_ERR("Setting FMMU %i failed on slave %i!\n", |
1226 EC_ERR("Setting FMMU %i failed on slave %i!\n", |
1172 j, slave->ring_position); |
1227 j, slave->ring_position); |
1173 return -1; |
1228 return -1; |
1174 } |
1229 } |