6 * |
6 * |
7 * This file is part of the IgH EtherCAT Master. |
7 * This file is part of the IgH EtherCAT Master. |
8 * |
8 * |
9 * The IgH EtherCAT Master is free software; you can redistribute it |
9 * The IgH EtherCAT Master is free software; you can redistribute it |
10 * and/or modify it under the terms of the GNU General Public License |
10 * and/or modify it under the terms of the GNU General Public License |
11 * as published by the Free Software Foundation; version 2 of the License. |
11 * as published by the Free Software Foundation; either version 2 of the |
|
12 * License, or (at your option) any later version. |
12 * |
13 * |
13 * The IgH EtherCAT Master is distributed in the hope that it will be |
14 * The IgH EtherCAT Master is distributed in the hope that it will be |
14 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 * GNU General Public License for more details. |
17 * GNU General Public License for more details. |
17 * |
18 * |
18 * You should have received a copy of the GNU General Public License |
19 * You should have received a copy of the GNU General Public License |
19 * along with the IgH EtherCAT Master; if not, write to the Free Software |
20 * along with the IgH EtherCAT Master; if not, write to the Free Software |
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
21 * |
22 * |
|
23 * The right to use EtherCAT Technology is granted and comes free of |
|
24 * charge under condition of compatibility of product made by |
|
25 * Licensee. People intending to distribute/sell products based on the |
|
26 * code, have to sign an agreement to guarantee that products using |
|
27 * software based on IgH EtherCAT master stay compatible with the actual |
|
28 * EtherCAT specification (which are released themselves as an open |
|
29 * standard) as the (only) precondition to have the right to use EtherCAT |
|
30 * Technology, IP and trade marks. |
|
31 * |
22 *****************************************************************************/ |
32 *****************************************************************************/ |
23 |
33 |
24 /** |
34 /** |
25 \file |
35 \file |
26 EtherCAT master methods. |
36 EtherCAT master methods. |
81 Master constructor. |
91 Master constructor. |
82 \return 0 in case of success, else < 0 |
92 \return 0 in case of success, else < 0 |
83 */ |
93 */ |
84 |
94 |
85 int ec_master_init(ec_master_t *master, /**< EtherCAT master */ |
95 int ec_master_init(ec_master_t *master, /**< EtherCAT master */ |
86 unsigned int index /**< master index */ |
96 unsigned int index, /**< master index */ |
|
97 unsigned int eoe_devices /**< number of EoE devices */ |
87 ) |
98 ) |
88 { |
99 { |
|
100 ec_eoe_t *eoe, *next_eoe; |
|
101 unsigned int i; |
|
102 |
89 EC_INFO("Initializing master %i.\n", index); |
103 EC_INFO("Initializing master %i.\n", index); |
90 |
104 |
91 master->index = index; |
105 master->index = index; |
92 master->device = NULL; |
106 master->device = NULL; |
93 master->reserved = 0; |
107 master->reserved = 0; |
94 |
|
95 INIT_LIST_HEAD(&master->slaves); |
108 INIT_LIST_HEAD(&master->slaves); |
96 INIT_LIST_HEAD(&master->command_queue); |
109 INIT_LIST_HEAD(&master->command_queue); |
97 INIT_LIST_HEAD(&master->domains); |
110 INIT_LIST_HEAD(&master->domains); |
98 INIT_LIST_HEAD(&master->eoe_slaves); |
111 INIT_LIST_HEAD(&master->eoe_handlers); |
|
112 ec_command_init(&master->simple_command); |
|
113 INIT_WORK(&master->freerun_work, ec_master_freerun, (void *) master); |
|
114 init_timer(&master->eoe_timer); |
|
115 master->eoe_timer.function = ec_master_eoe_run; |
|
116 master->eoe_timer.data = (unsigned long) master; |
|
117 master->internal_lock = SPIN_LOCK_UNLOCKED; |
|
118 master->eoe_running = 0; |
|
119 |
|
120 // create workqueue |
|
121 if (!(master->workqueue = create_singlethread_workqueue("EtherCAT"))) { |
|
122 EC_ERR("Failed to create master workqueue.\n"); |
|
123 goto out_return; |
|
124 } |
|
125 |
|
126 // create EoE handlers |
|
127 for (i = 0; i < eoe_devices; i++) { |
|
128 if (!(eoe = (ec_eoe_t *) kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) { |
|
129 EC_ERR("Failed to allocate EoE-Object.\n"); |
|
130 goto out_clear_eoe; |
|
131 } |
|
132 if (ec_eoe_init(eoe)) { |
|
133 kfree(eoe); |
|
134 goto out_clear_eoe; |
|
135 } |
|
136 list_add_tail(&eoe->list, &master->eoe_handlers); |
|
137 } |
|
138 |
|
139 // create state machine object |
|
140 if (ec_fsm_init(&master->fsm, master)) goto out_clear_eoe; |
99 |
141 |
100 // init kobject and add it to the hierarchy |
142 // init kobject and add it to the hierarchy |
101 memset(&master->kobj, 0x00, sizeof(struct kobject)); |
143 memset(&master->kobj, 0x00, sizeof(struct kobject)); |
102 kobject_init(&master->kobj); |
144 kobject_init(&master->kobj); |
103 master->kobj.ktype = &ktype_ec_master; |
145 master->kobj.ktype = &ktype_ec_master; |
128 */ |
172 */ |
129 |
173 |
130 void ec_master_clear(struct kobject *kobj /**< kobject of the master */) |
174 void ec_master_clear(struct kobject *kobj /**< kobject of the master */) |
131 { |
175 { |
132 ec_master_t *master = container_of(kobj, ec_master_t, kobj); |
176 ec_master_t *master = container_of(kobj, ec_master_t, kobj); |
|
177 ec_eoe_t *eoe, *next_eoe; |
133 |
178 |
134 EC_INFO("Clearing master %i...\n", master->index); |
179 EC_INFO("Clearing master %i...\n", master->index); |
135 |
180 |
136 del_timer_sync(&master->freerun_timer); |
|
137 |
|
138 ec_master_reset(master); |
181 ec_master_reset(master); |
|
182 ec_fsm_clear(&master->fsm); |
|
183 ec_command_clear(&master->simple_command); |
|
184 destroy_workqueue(master->workqueue); |
|
185 |
|
186 // clear EoE objects |
|
187 list_for_each_entry_safe(eoe, next_eoe, &master->eoe_handlers, list) { |
|
188 list_del(&eoe->list); |
|
189 ec_eoe_clear(eoe); |
|
190 kfree(eoe); |
|
191 } |
139 |
192 |
140 if (master->device) { |
193 if (master->device) { |
141 ec_device_clear(master->device); |
194 ec_device_clear(master->device); |
142 kfree(master->device); |
195 kfree(master->device); |
143 } |
196 } |
144 |
197 |
145 ec_command_clear(&master->simple_command); |
|
146 ec_command_clear(&master->watch_command); |
|
147 |
|
148 EC_INFO("Master %i cleared.\n", master->index); |
198 EC_INFO("Master %i cleared.\n", master->index); |
149 } |
199 } |
150 |
200 |
151 /*****************************************************************************/ |
201 /*****************************************************************************/ |
152 |
202 |
156 called, to free the slave list, domains etc. |
206 called, to free the slave list, domains etc. |
157 */ |
207 */ |
158 |
208 |
159 void ec_master_reset(ec_master_t *master /**< EtherCAT master */) |
209 void ec_master_reset(ec_master_t *master /**< EtherCAT master */) |
160 { |
210 { |
161 ec_slave_t *slave, *next_s; |
|
162 ec_command_t *command, *next_c; |
211 ec_command_t *command, *next_c; |
163 ec_domain_t *domain, *next_d; |
212 ec_domain_t *domain, *next_d; |
164 ec_eoe_t *eoe, *next_eoe; |
213 |
165 |
214 ec_master_eoe_stop(master); |
166 ec_master_freerun_stop(master); |
215 ec_master_freerun_stop(master); |
167 |
216 ec_master_clear_slaves(master); |
168 // remove all slaves |
|
169 list_for_each_entry_safe(slave, next_s, &master->slaves, list) { |
|
170 list_del(&slave->list); |
|
171 kobject_del(&slave->kobj); |
|
172 kobject_put(&slave->kobj); |
|
173 } |
|
174 master->slave_count = 0; |
|
175 |
217 |
176 // empty command queue |
218 // empty command queue |
177 list_for_each_entry_safe(command, next_c, &master->command_queue, queue) { |
219 list_for_each_entry_safe(command, next_c, &master->command_queue, queue) { |
178 list_del_init(&command->queue); |
220 list_del_init(&command->queue); |
179 command->state = EC_CMD_ERROR; |
221 command->state = EC_CMD_ERROR; |
184 list_del(&domain->list); |
226 list_del(&domain->list); |
185 kobject_del(&domain->kobj); |
227 kobject_del(&domain->kobj); |
186 kobject_put(&domain->kobj); |
228 kobject_put(&domain->kobj); |
187 } |
229 } |
188 |
230 |
189 // clear EoE objects |
|
190 list_for_each_entry_safe(eoe, next_eoe, &master->eoe_slaves, list) { |
|
191 list_del(&eoe->list); |
|
192 ec_eoe_clear(eoe); |
|
193 kfree(eoe); |
|
194 } |
|
195 |
|
196 master->command_index = 0; |
231 master->command_index = 0; |
197 master->debug_level = 0; |
232 master->debug_level = 0; |
198 master->timeout = 500; // 500us |
233 master->timeout = 500; // 500us |
199 |
|
200 master->slaves_responding = 0; |
|
201 master->slave_states = EC_SLAVE_STATE_UNKNOWN; |
|
202 |
234 |
203 master->stats.timeouts = 0; |
235 master->stats.timeouts = 0; |
204 master->stats.delayed = 0; |
236 master->stats.delayed = 0; |
205 master->stats.corrupted = 0; |
237 master->stats.corrupted = 0; |
206 master->stats.unmatched = 0; |
238 master->stats.unmatched = 0; |
207 master->stats.eoe_errors = 0; |
|
208 master->stats.t_last = 0; |
239 master->stats.t_last = 0; |
209 |
240 |
210 master->mode = EC_MASTER_MODE_IDLE; |
241 master->mode = EC_MASTER_MODE_IDLE; |
|
242 |
|
243 master->request_cb = NULL; |
|
244 master->release_cb = NULL; |
|
245 master->cb_data = NULL; |
|
246 |
|
247 ec_fsm_reset(&master->fsm); |
|
248 } |
|
249 |
|
250 /*****************************************************************************/ |
|
251 |
|
252 /** |
|
253 Clears all slaves. |
|
254 */ |
|
255 |
|
256 void ec_master_clear_slaves(ec_master_t *master) |
|
257 { |
|
258 ec_slave_t *slave, *next_slave; |
|
259 |
|
260 list_for_each_entry_safe(slave, next_slave, &master->slaves, list) { |
|
261 list_del(&slave->list); |
|
262 kobject_del(&slave->kobj); |
|
263 kobject_put(&slave->kobj); |
|
264 } |
|
265 master->slave_count = 0; |
211 } |
266 } |
212 |
267 |
213 /*****************************************************************************/ |
268 /*****************************************************************************/ |
214 |
269 |
215 /** |
270 /** |
247 { |
302 { |
248 ec_command_t *command; |
303 ec_command_t *command; |
249 size_t command_size; |
304 size_t command_size; |
250 uint8_t *frame_data, *cur_data; |
305 uint8_t *frame_data, *cur_data; |
251 void *follows_word; |
306 void *follows_word; |
252 cycles_t start = 0, end; |
307 cycles_t t_start, t_end; |
253 unsigned int frame_count, more_commands_waiting; |
308 unsigned int frame_count, more_commands_waiting; |
254 |
309 |
255 frame_count = 0; |
310 frame_count = 0; |
256 |
311 t_start = get_cycles(); |
257 if (unlikely(master->debug_level > 0)) { |
312 |
|
313 if (unlikely(master->debug_level > 0)) |
258 EC_DBG("ec_master_send_commands\n"); |
314 EC_DBG("ec_master_send_commands\n"); |
259 start = get_cycles(); |
|
260 } |
|
261 |
315 |
262 do { |
316 do { |
263 // fetch pointer to transmit socket buffer |
317 // fetch pointer to transmit socket buffer |
264 frame_data = ec_device_tx_data(master->device); |
318 frame_data = ec_device_tx_data(master->device); |
265 cur_data = frame_data + EC_FRAME_HEADER_SIZE; |
319 cur_data = frame_data + EC_FRAME_HEADER_SIZE; |
271 if (command->state != EC_CMD_QUEUED) continue; |
325 if (command->state != EC_CMD_QUEUED) continue; |
272 |
326 |
273 // does the current command fit in the frame? |
327 // does the current command fit in the frame? |
274 command_size = EC_COMMAND_HEADER_SIZE + command->data_size |
328 command_size = EC_COMMAND_HEADER_SIZE + command->data_size |
275 + EC_COMMAND_FOOTER_SIZE; |
329 + EC_COMMAND_FOOTER_SIZE; |
276 if (cur_data - frame_data + command_size > EC_MAX_FRAME_SIZE) { |
330 if (cur_data - frame_data + command_size > ETH_DATA_LEN) { |
277 more_commands_waiting = 1; |
331 more_commands_waiting = 1; |
278 break; |
332 break; |
279 } |
333 } |
280 |
334 |
281 command->state = EC_CMD_SENT; |
335 command->state = EC_CMD_SENT; |
|
336 command->t_sent = t_start; |
282 command->index = master->command_index++; |
337 command->index = master->command_index++; |
283 |
338 |
284 if (unlikely(master->debug_level > 0)) |
339 if (unlikely(master->debug_level > 0)) |
285 EC_DBG("adding command 0x%02X\n", command->index); |
340 EC_DBG("adding command 0x%02X\n", command->index); |
286 |
341 |
475 \return 0 in case of success, else < 0 |
530 \return 0 in case of success, else < 0 |
476 */ |
531 */ |
477 |
532 |
478 int ec_master_bus_scan(ec_master_t *master /**< EtherCAT master */) |
533 int ec_master_bus_scan(ec_master_t *master /**< EtherCAT master */) |
479 { |
534 { |
480 ec_slave_t *slave, *next; |
535 ec_slave_t *slave; |
481 ec_slave_ident_t *ident; |
536 ec_slave_ident_t *ident; |
|
537 ec_command_t *command; |
482 unsigned int i; |
538 unsigned int i; |
483 ec_command_t *command; |
|
484 ec_eoe_t *eoe; |
|
485 uint16_t coupler_index, coupler_subindex; |
539 uint16_t coupler_index, coupler_subindex; |
486 uint16_t reverse_coupler_index, current_coupler_index; |
540 uint16_t reverse_coupler_index, current_coupler_index; |
487 |
541 |
488 if (!list_empty(&master->slaves)) { |
542 if (!list_empty(&master->slaves)) { |
489 EC_ERR("Slave scan already done!\n"); |
543 EC_ERR("Slave scan already done!\n"); |
667 |
693 |
668 void ec_master_freerun_stop(ec_master_t *master /**< EtherCAT master */) |
694 void ec_master_freerun_stop(ec_master_t *master /**< EtherCAT master */) |
669 { |
695 { |
670 if (master->mode != EC_MASTER_MODE_FREERUN) return; |
696 if (master->mode != EC_MASTER_MODE_FREERUN) return; |
671 |
697 |
|
698 ec_master_eoe_stop(master); |
|
699 |
672 EC_INFO("Stopping Free-Run mode.\n"); |
700 EC_INFO("Stopping Free-Run mode.\n"); |
673 |
701 |
674 del_timer_sync(&master->freerun_timer); |
702 if (!cancel_delayed_work(&master->freerun_work)) { |
|
703 flush_workqueue(master->workqueue); |
|
704 } |
|
705 |
|
706 ec_master_clear_slaves(master); |
675 master->mode = EC_MASTER_MODE_IDLE; |
707 master->mode = EC_MASTER_MODE_IDLE; |
676 } |
708 } |
677 |
709 |
678 /*****************************************************************************/ |
710 /*****************************************************************************/ |
679 |
711 |
680 /** |
712 /** |
681 Free-Run mode function. |
713 Free-Run mode function. |
682 */ |
714 */ |
683 |
715 |
684 void ec_master_freerun(unsigned long data /**< private timer data = master */) |
716 void ec_master_freerun(void *data /**< master pointer */) |
685 { |
717 { |
686 ec_master_t *master = (ec_master_t *) data; |
718 ec_master_t *master = (ec_master_t *) data; |
687 |
719 |
|
720 // aquire master lock |
|
721 spin_lock_bh(&master->internal_lock); |
|
722 |
688 ecrt_master_async_receive(master); |
723 ecrt_master_async_receive(master); |
689 |
724 |
690 // watchdog command |
725 // execute master state machine |
691 ec_master_process_watch_command(master); |
726 ec_fsm_execute(&master->fsm); |
692 ec_master_queue_command(master, &master->watch_command); |
|
693 |
|
694 master->slave_count = master->watch_command.working_counter; |
|
695 |
727 |
696 ecrt_master_async_send(master); |
728 ecrt_master_async_send(master); |
697 |
729 |
698 master->freerun_timer.expires += HZ; |
730 // release master lock |
699 add_timer(&master->freerun_timer); |
731 spin_unlock_bh(&master->internal_lock); |
|
732 |
|
733 queue_delayed_work(master->workqueue, &master->freerun_work, 1); |
700 } |
734 } |
701 |
735 |
702 /*****************************************************************************/ |
736 /*****************************************************************************/ |
703 |
737 |
704 /** |
738 /** |
789 } |
823 } |
790 |
824 |
791 /*****************************************************************************/ |
825 /*****************************************************************************/ |
792 |
826 |
793 /** |
827 /** |
794 Processes the watchdog command. |
828 Starts Ethernet-over-EtherCAT processing for all EoE-capable slaves. |
795 */ |
829 */ |
796 |
830 |
797 void ec_master_process_watch_command(ec_master_t *master |
831 void ec_master_eoe_start(ec_master_t *master /**< EtherCAT master */) |
798 /**< EtherCAT master */ |
832 { |
799 ) |
833 ec_eoe_t *eoe; |
800 { |
834 ec_slave_t *slave; |
801 unsigned int first; |
835 unsigned int coupled, found; |
802 |
836 |
803 if (unlikely(master->watch_command.state == EC_CMD_INIT)) return; |
837 if (master->eoe_running) return; |
804 |
838 |
805 first = 1; |
839 // decouple all EoE handlers |
806 |
840 list_for_each_entry(eoe, &master->eoe_handlers, list) |
807 if (master->watch_command.working_counter != master->slaves_responding || |
841 eoe->slave = NULL; |
808 master->watch_command.data[0] != master->slave_states) |
842 coupled = 0; |
809 { |
843 |
810 master->slaves_responding = master->watch_command.working_counter; |
844 // couple a free EoE handler to every EoE-capable slave |
811 master->slave_states = master->watch_command.data[0]; |
845 list_for_each_entry(slave, &master->slaves, list) { |
812 |
846 if (!(slave->sii_mailbox_protocols & EC_MBOX_EOE)) continue; |
813 EC_INFO("%i slave%s responding (", master->slaves_responding, |
847 |
814 master->slaves_responding == 1 ? "" : "s"); |
848 found = 0; |
815 |
849 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
816 if (master->slave_states & EC_SLAVE_STATE_INIT) { |
850 if (eoe->slave) continue; |
817 printk("INIT"); |
851 eoe->slave = slave; |
818 first = 0; |
852 found = 1; |
819 } |
853 coupled++; |
820 if (master->slave_states & EC_SLAVE_STATE_PREOP) { |
854 EC_INFO("Coupling device %s to slave %i.\n", |
821 if (!first) printk(", "); |
855 eoe->dev->name, slave->ring_position); |
822 printk("PREOP"); |
856 if (eoe->opened) { |
823 first = 0; |
857 slave->requested_state = EC_SLAVE_STATE_OP; |
824 } |
858 } |
825 if (master->slave_states & EC_SLAVE_STATE_SAVEOP) { |
859 else { |
826 if (!first) printk(", "); |
860 slave->requested_state = EC_SLAVE_STATE_INIT; |
827 printk("SAVEOP"); |
861 } |
828 first = 0; |
862 slave->state_error = 0; |
829 } |
863 break; |
830 if (master->slave_states & EC_SLAVE_STATE_OP) { |
864 } |
831 if (!first) printk(", "); |
865 |
832 printk("OP"); |
866 if (!found) { |
833 } |
867 EC_WARN("No EoE handler for slave %i!\n", slave->ring_position); |
834 printk(")\n"); |
868 slave->requested_state = EC_SLAVE_STATE_INIT; |
835 } |
869 slave->state_error = 0; |
836 } |
870 } |
837 |
871 } |
838 /*****************************************************************************/ |
872 |
839 |
873 if (!coupled) { |
|
874 EC_INFO("No EoE handlers coupled.\n"); |
|
875 return; |
|
876 } |
|
877 |
|
878 EC_INFO("Starting EoE processing.\n"); |
|
879 master->eoe_running = 1; |
|
880 |
|
881 // start EoE processing |
|
882 master->eoe_timer.expires = jiffies + 10; |
|
883 add_timer(&master->eoe_timer); |
|
884 return; |
|
885 } |
|
886 |
|
887 /*****************************************************************************/ |
|
888 |
|
889 /** |
|
890 Stops the Ethernet-over-EtherCAT processing. |
|
891 */ |
|
892 |
|
893 void ec_master_eoe_stop(ec_master_t *master /**< EtherCAT master */) |
|
894 { |
|
895 ec_eoe_t *eoe; |
|
896 |
|
897 if (!master->eoe_running) return; |
|
898 |
|
899 EC_INFO("Stopping EoE processing.\n"); |
|
900 |
|
901 del_timer_sync(&master->eoe_timer); |
|
902 |
|
903 // decouple all EoE handlers |
|
904 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
|
905 if (eoe->slave) { |
|
906 eoe->slave->requested_state = EC_SLAVE_STATE_INIT; |
|
907 eoe->slave->state_error = 0; |
|
908 eoe->slave = NULL; |
|
909 } |
|
910 } |
|
911 |
|
912 master->eoe_running = 0; |
|
913 } |
|
914 |
|
915 /*****************************************************************************/ |
840 /** |
916 /** |
841 Does the Ethernet-over-EtherCAT processing. |
917 Does the Ethernet-over-EtherCAT processing. |
842 */ |
918 */ |
843 |
919 |
844 void ec_master_run_eoe(ec_master_t *master /**< EtherCAT master */) |
920 void ec_master_eoe_run(unsigned long data /**< master pointer */) |
845 { |
921 { |
|
922 ec_master_t *master = (ec_master_t *) data; |
846 ec_eoe_t *eoe; |
923 ec_eoe_t *eoe; |
847 |
924 unsigned int active = 0; |
848 list_for_each_entry(eoe, &master->eoe_slaves, list) { |
925 |
|
926 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
|
927 if (ec_eoe_active(eoe)) active++; |
|
928 } |
|
929 if (!active) goto queue_timer; |
|
930 |
|
931 // aquire master lock... |
|
932 if (master->mode == EC_MASTER_MODE_RUNNING) { |
|
933 // request_cb must return 0, if the lock has been aquired! |
|
934 if (master->request_cb(master->cb_data)) |
|
935 goto queue_timer; |
|
936 } |
|
937 else if (master->mode == EC_MASTER_MODE_FREERUN) { |
|
938 spin_lock(&master->internal_lock); |
|
939 } |
|
940 else |
|
941 goto queue_timer; |
|
942 |
|
943 // actual EoE stuff |
|
944 ecrt_master_async_receive(master); |
|
945 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
849 ec_eoe_run(eoe); |
946 ec_eoe_run(eoe); |
850 } |
947 } |
|
948 ecrt_master_async_send(master); |
|
949 |
|
950 // release lock... |
|
951 if (master->mode == EC_MASTER_MODE_RUNNING) { |
|
952 master->release_cb(master->cb_data); |
|
953 } |
|
954 else if (master->mode == EC_MASTER_MODE_FREERUN) { |
|
955 spin_unlock(&master->internal_lock); |
|
956 } |
|
957 |
|
958 queue_timer: |
|
959 master->eoe_timer.expires += HZ / EC_EOE_FREQUENCY; |
|
960 add_timer(&master->eoe_timer); |
851 } |
961 } |
852 |
962 |
853 /****************************************************************************** |
963 /****************************************************************************** |
854 * Realtime interface |
964 * Realtime interface |
855 *****************************************************************************/ |
965 *****************************************************************************/ |
917 uint32_t domain_offset; |
1027 uint32_t domain_offset; |
918 ec_domain_t *domain; |
1028 ec_domain_t *domain; |
919 ec_eeprom_sync_t *eeprom_sync, mbox_sync; |
1029 ec_eeprom_sync_t *eeprom_sync, mbox_sync; |
920 |
1030 |
921 command = &master->simple_command; |
1031 command = &master->simple_command; |
922 |
|
923 if (master->watch_command.state == EC_CMD_INIT) { |
|
924 if (ec_command_brd(&master->watch_command, 0x130, 2)) { |
|
925 EC_ERR("Failed to allocate watchdog command!\n"); |
|
926 return -1; |
|
927 } |
|
928 } |
|
929 |
1032 |
930 // allocate all domains |
1033 // allocate all domains |
931 domain_offset = 0; |
1034 domain_offset = 0; |
932 list_for_each_entry(domain, &master->domains, list) { |
1035 list_for_each_entry(domain, &master->domains, list) { |
933 if (ec_domain_alloc(domain, domain_offset)) { |
1036 if (ec_domain_alloc(domain, domain_offset)) { |
1221 */ |
1321 */ |
1222 |
1322 |
1223 void ecrt_master_async_receive(ec_master_t *master /**< EtherCAT master */) |
1323 void ecrt_master_async_receive(ec_master_t *master /**< EtherCAT master */) |
1224 { |
1324 { |
1225 ec_command_t *command, *next; |
1325 ec_command_t *command, *next; |
|
1326 cycles_t t_received, t_timeout; |
1226 |
1327 |
1227 ec_device_call_isr(master->device); |
1328 ec_device_call_isr(master->device); |
|
1329 |
|
1330 t_received = get_cycles(); |
|
1331 t_timeout = (cycles_t) master->timeout * (cpu_khz / 1000); |
1228 |
1332 |
1229 // dequeue all received commands |
1333 // dequeue all received commands |
1230 list_for_each_entry_safe(command, next, &master->command_queue, queue) |
1334 list_for_each_entry_safe(command, next, &master->command_queue, queue) |
1231 if (command->state == EC_CMD_RECEIVED) list_del_init(&command->queue); |
1335 if (command->state == EC_CMD_RECEIVED) list_del_init(&command->queue); |
1232 |
1336 |
1233 // dequeue all remaining commands |
1337 // dequeue all commands that timed out |
1234 list_for_each_entry_safe(command, next, &master->command_queue, queue) { |
1338 list_for_each_entry_safe(command, next, &master->command_queue, queue) { |
1235 switch (command->state) { |
1339 switch (command->state) { |
1236 case EC_CMD_SENT: |
1340 case EC_CMD_SENT: |
1237 case EC_CMD_QUEUED: |
1341 case EC_CMD_QUEUED: |
1238 command->state = EC_CMD_TIMEOUT; |
1342 if (t_received - command->t_sent > t_timeout) { |
1239 master->stats.timeouts++; |
1343 list_del_init(&command->queue); |
1240 ec_master_output_stats(master); |
1344 command->state = EC_CMD_TIMEOUT; |
|
1345 master->stats.timeouts++; |
|
1346 ec_master_output_stats(master); |
|
1347 } |
1241 break; |
1348 break; |
1242 default: |
1349 default: |
1243 break; |
1350 break; |
1244 } |
1351 } |
1245 list_del_init(&command->queue); |
|
1246 } |
1352 } |
1247 } |
1353 } |
1248 |
1354 |
1249 /*****************************************************************************/ |
1355 /*****************************************************************************/ |
1250 |
1356 |
1405 } |
1507 } |
1406 |
1508 |
1407 /*****************************************************************************/ |
1509 /*****************************************************************************/ |
1408 |
1510 |
1409 /** |
1511 /** |
|
1512 Sets the locking callbacks. |
|
1513 The request_cb function must return zero, to allow another instance |
|
1514 (the EoE process for example) to access the master. Non-zero means, |
|
1515 that access is forbidden at this time. |
|
1516 \ingroup RealtimeInterface |
|
1517 */ |
|
1518 |
|
1519 void ecrt_master_callbacks(ec_master_t *master, /**< EtherCAT master */ |
|
1520 int (*request_cb)(void *), /**< request lock CB */ |
|
1521 void (*release_cb)(void *), /**< release lock CB */ |
|
1522 void *cb_data /**< data parameter */ |
|
1523 ) |
|
1524 { |
|
1525 master->request_cb = request_cb; |
|
1526 master->release_cb = release_cb; |
|
1527 master->cb_data = cb_data; |
|
1528 } |
|
1529 |
|
1530 /*****************************************************************************/ |
|
1531 |
|
1532 /** |
|
1533 Starts Ethernet-over-EtherCAT processing for all EoE-capable slaves. |
|
1534 \ingroup RealtimeInterface |
|
1535 */ |
|
1536 |
|
1537 int ecrt_master_start_eoe(ec_master_t *master /**< EtherCAT master */) |
|
1538 { |
|
1539 if (!master->request_cb || !master->release_cb) { |
|
1540 EC_ERR("EoE requires master callbacks to be set!\n"); |
|
1541 return -1; |
|
1542 } |
|
1543 |
|
1544 ec_master_eoe_start(master); |
|
1545 return 0; |
|
1546 } |
|
1547 |
|
1548 /*****************************************************************************/ |
|
1549 |
|
1550 /** |
1410 Sets the debug level of the master. |
1551 Sets the debug level of the master. |
1411 The following levels are valid: |
1552 The following levels are valid: |
1412 - 1: only output positions marks and basic data |
1553 - 1: only output positions marks and basic data |
1413 - 2: additional frame data output |
1554 - 2: additional frame data output |
1414 \ingroup RealtimeInterface |
1555 \ingroup RealtimeInterface |
1446 if (master->slave_count) { |
1587 if (master->slave_count) { |
1447 EC_INFO("Slave list:\n"); |
1588 EC_INFO("Slave list:\n"); |
1448 list_for_each_entry(slave, &master->slaves, list) |
1589 list_for_each_entry(slave, &master->slaves, list) |
1449 ec_slave_print(slave, verbosity); |
1590 ec_slave_print(slave, verbosity); |
1450 } |
1591 } |
1451 if (!list_empty(&master->eoe_slaves)) { |
1592 if (!list_empty(&master->eoe_handlers)) { |
1452 EC_INFO("Ethernet-over-EtherCAT (EoE) objects:\n"); |
1593 EC_INFO("Ethernet-over-EtherCAT (EoE) objects:\n"); |
1453 list_for_each_entry(eoe, &master->eoe_slaves, list) { |
1594 list_for_each_entry(eoe, &master->eoe_handlers, list) { |
1454 ec_eoe_print(eoe); |
1595 ec_eoe_print(eoe); |
1455 } |
1596 } |
1456 } |
1597 } |
1457 EC_INFO("*** End master information ***\n"); |
1598 EC_INFO("*** End master information ***\n"); |
1458 } |
1599 } |