1 /****************************************************************************** |
|
2 * |
|
3 * msr_io.c |
|
4 * |
|
5 * Sample Modul für EtherCAT |
|
6 * |
|
7 * Autoren: Wilhelm Hagemeister, Florian Pose |
|
8 * |
|
9 * $Date$ |
|
10 * $Author$ |
|
11 * |
|
12 * (C) Copyright IgH 2005 |
|
13 * Ingenieurgemeinschaft IgH |
|
14 * Heinz-Bäcker Str. 34 |
|
15 * D-45356 Essen |
|
16 * Tel.: +49 201/61 99 31 |
|
17 * Fax.: +49 201/61 98 36 |
|
18 * E-mail: hm@igh-essen.com |
|
19 * |
|
20 * /bin/setserial /dev/ttyS0 uart none |
|
21 * /bin/setserial /dev/ttyS1 uart none |
|
22 * |
|
23 ******************************************************************************/ |
|
24 |
|
25 /*--Includes-----------------------------------------------------------------*/ |
|
26 |
|
27 #include <linux/module.h> |
|
28 #include <linux/tqueue.h> |
|
29 #include <linux/slab.h> |
|
30 #include <linux/delay.h> |
|
31 |
|
32 #include <msr_reg.h> |
|
33 #include <msr_messages.h> |
|
34 #include <msr_main.h> |
|
35 |
|
36 #include <rtai.h> |
|
37 #include <rtai_sched.h> |
|
38 |
|
39 #include "msr_io.h" |
|
40 |
|
41 //#include <msr_float.h> |
|
42 |
|
43 #include "../drivers/ec_master.h" |
|
44 #include "../drivers/ec_device.h" |
|
45 #include "../drivers/ec_types.h" |
|
46 #include "../rs232dbg/rs232dbg.h" |
|
47 |
|
48 /*--Defines------------------------------------------------------------------*/ |
|
49 |
|
50 #define TIMERTICS 1e6 // in ns; Thus have a task time of 1ms |
|
51 #define MSR_ABTASTFREQUENZ (1e9/TIMERTICS) |
|
52 |
|
53 //#define MSR_ABTASTFREQUENZ (1000) //1e9/TIMERTICS) |
|
54 #define TICK ((1000000 / MSR_ABTASTFREQUENZ) * 1000) |
|
55 #define TIMER_FREQ (APIC_TIMER ? FREQ_APIC : FREQ_8254) |
|
56 #define APIC_TIMER 0 |
|
57 |
|
58 //#define MSR_SLOW_DEBUG |
|
59 |
|
60 /*--Globale Variablen--------------------------------------------------------*/ |
|
61 |
|
62 RT_TASK process_image; |
|
63 |
|
64 const int Tick = TICK; |
|
65 |
|
66 unsigned int ecat_tx_delay = 0; //Zeit vom Ende der TimerInterruptRoutine bis |
|
67 //TX-Interrupt der Netzwerkkarte |
|
68 unsigned int ecat_rx_delay = 0; //RX-Interrupt der Netzwerkkarte |
|
69 |
|
70 unsigned int tx_intr = 0; |
|
71 unsigned int rx_intr = 0; |
|
72 unsigned int total_intr = 0; |
|
73 |
|
74 unsigned int thread_end = 0; |
|
75 |
|
76 #define USE_ETHERCAT |
|
77 |
|
78 #ifdef USE_ETHERCAT |
|
79 |
|
80 static EtherCAT_master_t *ecat_master = NULL; |
|
81 |
|
82 extern EtherCAT_device_t rtl_ecat_dev; |
|
83 |
|
84 //#define ECAT_SLAVES_COUNT 16 |
|
85 |
|
86 static EtherCAT_slave_t ecat_slaves[] = |
|
87 { |
|
88 //Block 1 |
|
89 /* ECAT_INIT_SLAVE(Beckhoff_EK1100), |
|
90 ECAT_INIT_SLAVE(Beckhoff_EL4102), |
|
91 ECAT_INIT_SLAVE(Beckhoff_EL3162), |
|
92 ECAT_INIT_SLAVE(Beckhoff_EL1014), |
|
93 ECAT_INIT_SLAVE(Beckhoff_EL2004), |
|
94 ECAT_INIT_SLAVE(Beckhoff_EL3102), |
|
95 ECAT_INIT_SLAVE(Beckhoff_EL4102), |
|
96 ECAT_INIT_SLAVE(Beckhoff_EL4102), |
|
97 ECAT_INIT_SLAVE(Beckhoff_EL4102), |
|
98 ECAT_INIT_SLAVE(Beckhoff_EL3162), |
|
99 ECAT_INIT_SLAVE(Beckhoff_EL3162), |
|
100 ECAT_INIT_SLAVE(Beckhoff_EL3162), |
|
101 ECAT_INIT_SLAVE(Beckhoff_EL3102), |
|
102 ECAT_INIT_SLAVE(Beckhoff_EL3102), |
|
103 ECAT_INIT_SLAVE(Beckhoff_EL2004), |
|
104 ECAT_INIT_SLAVE(Beckhoff_EL2004), |
|
105 ECAT_INIT_SLAVE(Beckhoff_EL2004), |
|
106 ECAT_INIT_SLAVE(Beckhoff_EL2004), */ |
|
107 //Block 2 |
|
108 ECAT_INIT_SLAVE(Beckhoff_EK1100), |
|
109 ECAT_INIT_SLAVE(Beckhoff_EL4102), |
|
110 ECAT_INIT_SLAVE(Beckhoff_EL1014), |
|
111 ECAT_INIT_SLAVE(Beckhoff_EL3162), |
|
112 ECAT_INIT_SLAVE(Beckhoff_EL2004), |
|
113 ECAT_INIT_SLAVE(Beckhoff_EL3102), |
|
114 //Block 3 |
|
115 ECAT_INIT_SLAVE(Beckhoff_EK1100), |
|
116 ECAT_INIT_SLAVE(Beckhoff_EL1014), |
|
117 ECAT_INIT_SLAVE(Beckhoff_EL1014), |
|
118 ECAT_INIT_SLAVE(Beckhoff_EL1014), |
|
119 ECAT_INIT_SLAVE(Beckhoff_EL1014), |
|
120 ECAT_INIT_SLAVE(Beckhoff_EL1014), |
|
121 ECAT_INIT_SLAVE(Beckhoff_EL2004), |
|
122 ECAT_INIT_SLAVE(Beckhoff_EL2004), |
|
123 ECAT_INIT_SLAVE(Beckhoff_EL2004), |
|
124 ECAT_INIT_SLAVE(Beckhoff_EL2004), |
|
125 ECAT_INIT_SLAVE(Beckhoff_EL1014), |
|
126 ECAT_INIT_SLAVE(Beckhoff_EL1014), |
|
127 ECAT_INIT_SLAVE(Beckhoff_EL1014) |
|
128 |
|
129 |
|
130 }; |
|
131 |
|
132 #define ECAT_SLAVES_COUNT (sizeof(ecat_slaves)/sizeof(EtherCAT_slave_t)) |
|
133 |
|
134 #endif |
|
135 |
|
136 double value; |
|
137 int dig1; |
|
138 |
|
139 |
|
140 static int next2004(int *wrap) |
|
141 { |
|
142 static int i=0; |
|
143 |
|
144 int j=0; |
|
145 |
|
146 *wrap = 0; |
|
147 for(j=0;j<ECAT_SLAVES_COUNT;j++) { |
|
148 i++; |
|
149 i %= ECAT_SLAVES_COUNT; |
|
150 if(i == 0) *wrap = 1; |
|
151 if(ecat_slaves[i].desc == Beckhoff_EL2004) { |
|
152 return i; |
|
153 } |
|
154 } |
|
155 return -1; |
|
156 } |
|
157 |
|
158 /* |
|
159 ******************************************************************************* |
|
160 * |
|
161 * Function: msr_controller |
|
162 * |
|
163 * Beschreibung: Zyklischer Prozess |
|
164 * |
|
165 * Parameter: |
|
166 * |
|
167 * Rückgabe: |
|
168 * |
|
169 * Status: exp |
|
170 * |
|
171 ******************************************************************************* |
|
172 */ |
|
173 |
|
174 void msr_controller(void) |
|
175 { |
|
176 static int ms = 0; |
|
177 static int cnt = 0; |
|
178 static unsigned long int k = 0; |
|
179 static int firstrun = 1; |
|
180 |
|
181 static int klemme = 12; |
|
182 static int kanal = 0; |
|
183 static int up_down = 0; |
|
184 int wrap = 0; |
|
185 |
|
186 ms++; |
|
187 ms %= 1000; |
|
188 |
|
189 #ifdef USE_ETHERCAT |
|
190 ecat_tx_delay = ((unsigned int) (100000 / HZ) * (ecat_master->dev->tx_time-k)) |
|
191 / (current_cpu_data.loops_per_jiffy / 10); |
|
192 ecat_rx_delay = ((unsigned int) (100000 / HZ) * (ecat_master->dev->rx_time-k)) |
|
193 / (current_cpu_data.loops_per_jiffy / 10); |
|
194 |
|
195 rx_intr = ecat_master->dev->rx_intr_cnt; |
|
196 tx_intr = ecat_master->dev->tx_intr_cnt; |
|
197 total_intr = ecat_master->dev->intr_cnt; |
|
198 // Prozessdaten lesen |
|
199 if(!firstrun) { |
|
200 EtherCAT_read_process_data(ecat_master); |
|
201 |
|
202 // Daten lesen und skalieren |
|
203 value = EtherCAT_read_value(&ecat_master->slaves[5], 0) / 3276.7; |
|
204 dig1 = EtherCAT_read_value(&ecat_master->slaves[3], 0); |
|
205 } |
|
206 // Daten schreiben |
|
207 |
|
208 EtherCAT_write_value(&ecat_master->slaves[4], 0, ms > 500 ? 1 : 0); |
|
209 EtherCAT_write_value(&ecat_master->slaves[4], 1, ms > 500 ? 0 : 1); |
|
210 EtherCAT_write_value(&ecat_master->slaves[4], 2, ms > 500 ? 0 : 1); |
|
211 EtherCAT_write_value(&ecat_master->slaves[4], 3, ms > 500 ? 1 : 0); |
|
212 |
|
213 |
|
214 if(cnt++ > 20) { |
|
215 cnt = 0; |
|
216 if(++kanal > 3) { |
|
217 kanal = 0; |
|
218 klemme = next2004(&wrap); |
|
219 if (wrap == 1) { |
|
220 if(up_down == 1) |
|
221 up_down = 0; |
|
222 else up_down = 1; |
|
223 } |
|
224 } |
|
225 } |
|
226 if (klemme >=0) |
|
227 EtherCAT_write_value(&ecat_master->slaves[klemme], kanal,up_down); |
|
228 |
|
229 // EtherCAT_write_value(&ecat_master->slaves[13], 1, ms > 500 ? 0 : 1); |
|
230 // EtherCAT_write_value(&ecat_master->slaves[14], 2, ms > 500 ? 0 : 1); |
|
231 // EtherCAT_write_value(&ecat_master->slaves[15], 3, ms > 500 ? 1 : 0); |
|
232 |
|
233 // Prozessdaten schreiben |
|
234 rdtscl(k); |
|
235 EtherCAT_write_process_data(ecat_master); |
|
236 firstrun = 0; |
|
237 #endif |
|
238 } |
|
239 |
|
240 /* |
|
241 ******************************************************************************* |
|
242 * |
|
243 * Function: msr_run_interrupt |
|
244 * |
|
245 * Beschreibung: Interrupt abarbeiten |
|
246 * |
|
247 * Parameter: |
|
248 * |
|
249 * Rückgabe: |
|
250 * |
|
251 * Status: exp |
|
252 * |
|
253 ******************************************************************************* |
|
254 */ |
|
255 |
|
256 void process_thread(int priv_data) |
|
257 { |
|
258 while (1) |
|
259 { |
|
260 |
|
261 #ifdef USE_ETHERCAT |
|
262 MSR_RTAITHREAD_CODE(msr_controller(); msr_write_kanal_list(); ); |
|
263 #else |
|
264 MSR_RTAITHREAD_CODE( msr_write_kanal_list(); ); |
|
265 #endif |
|
266 |
|
267 |
|
268 |
|
269 /* if(counter++ >=MSR_ABTASTFREQUENZ) { |
|
270 counter = 0; |
|
271 sprintf(buf,"rt:life"); |
|
272 msr_print_info(buf); |
|
273 } |
|
274 */ |
|
275 rt_task_wait_period(); |
|
276 } |
|
277 thread_end = 1; |
|
278 } |
|
279 |
|
280 /* |
|
281 ******************************************************************************* |
|
282 * |
|
283 * Function: msr_register_channels |
|
284 * |
|
285 * Beschreibung: Kanäle registrieren |
|
286 * |
|
287 * Parameter: |
|
288 * |
|
289 * Rückgabe: |
|
290 * |
|
291 * Status: exp |
|
292 * |
|
293 ******************************************************************************* |
|
294 */ |
|
295 |
|
296 int msr_globals_register(void) |
|
297 { |
|
298 msr_reg_kanal("/value", "V", &value, TDBL); |
|
299 msr_reg_kanal("/dig1", "", &dig1, TINT); |
|
300 msr_reg_kanal("/Taskinfo/Ecat/TX-Delay","us",&ecat_tx_delay,TUINT); |
|
301 msr_reg_kanal("/Taskinfo/Ecat/RX-Delay","us",&ecat_rx_delay,TUINT); |
|
302 msr_reg_kanal("/Taskinfo/Ecat/TX-Cnt","",&tx_intr,TUINT); |
|
303 msr_reg_kanal("/Taskinfo/Ecat/RX-Cnt","",&rx_intr,TUINT); |
|
304 msr_reg_kanal("/Taskinfo/Ecat/Total-Cnt","",&total_intr,TUINT); |
|
305 |
|
306 return 0; |
|
307 } |
|
308 |
|
309 /* |
|
310 ******************************************************************************* |
|
311 * |
|
312 * Function: msr_init |
|
313 * |
|
314 * Beschreibung: MSR initialisieren |
|
315 * |
|
316 * Parameter: |
|
317 * |
|
318 * Rückgabe: |
|
319 * |
|
320 * Status: exp |
|
321 * |
|
322 ******************************************************************************* |
|
323 */ |
|
324 |
|
325 int msr_init(void) |
|
326 { |
|
327 int rv = -1; |
|
328 RTIME tick_period, now; |
|
329 |
|
330 // rt_mount_rtai(); |
|
331 |
|
332 msr_print_info("Initialising rtlib."); |
|
333 |
|
334 // RT-lib initialisieren |
|
335 if (msr_rtlib_init(1, MSR_ABTASTFREQUENZ, 10, msr_globals_register) < 0) |
|
336 { |
|
337 msr_print_warn("msr_modul: can't initialize rtlib!"); |
|
338 goto out_umount; |
|
339 } |
|
340 |
|
341 #ifdef USE_ETHERCAT |
|
342 msr_print_info("Opening EtherCAT device."); |
|
343 |
|
344 mdelay(100); |
|
345 |
|
346 if (EtherCAT_device_open(&rtl_ecat_dev) < 0) |
|
347 { |
|
348 msr_print_warn("msr_modul: Could not initialize EtherCAT NIC."); |
|
349 goto out_rtlib; |
|
350 } |
|
351 |
|
352 if (!rtl_ecat_dev.dev) // Es gibt kein EtherCAT-Device |
|
353 { |
|
354 msr_print_warn("msr_modul: No EtherCAT device!"); |
|
355 goto out_close; |
|
356 } |
|
357 // goto out_close; |
|
358 |
|
359 // EtherCAT-Master und Slaves initialisieren |
|
360 |
|
361 msr_print_info("Initialising EtherCAT master"); |
|
362 |
|
363 if ((ecat_master = (EtherCAT_master_t *) kmalloc(sizeof(EtherCAT_master_t), GFP_KERNEL)) == 0) |
|
364 { |
|
365 msr_print_warn(KERN_ERR "msr_modul: Could not alloc memory for EtherCAT master!\n"); |
|
366 goto out_close; |
|
367 } |
|
368 |
|
369 if (EtherCAT_master_init(ecat_master, &rtl_ecat_dev) < 0) |
|
370 { |
|
371 msr_print_warn(KERN_ERR "EtherCAT could not init master!\n"); |
|
372 goto out_master; |
|
373 } |
|
374 |
|
375 msr_print_info("Checking EtherCAT slaves."); |
|
376 mdelay(10); //Nachricht abwarten |
|
377 |
|
378 if (EtherCAT_check_slaves(ecat_master, ecat_slaves, ECAT_SLAVES_COUNT) != 0) |
|
379 { |
|
380 msr_print_warn(KERN_ERR "EtherCAT: Could not init slaves!\n"); |
|
381 goto out_masterclear; |
|
382 } |
|
383 |
|
384 msr_print_info("Activating all EtherCAT slaves."); |
|
385 mdelay(10); //Nachricht abwarten |
|
386 |
|
387 if (EtherCAT_activate_all_slaves(ecat_master) != 0) |
|
388 { |
|
389 printk(KERN_ERR "EtherCAT: Could not activate slaves!\n"); |
|
390 goto out_masterclear; |
|
391 } |
|
392 |
|
393 // Zyklischen Aufruf starten |
|
394 |
|
395 #endif |
|
396 msr_print_info("Starting cyclic sample thread."); |
|
397 mdelay(10); //Nachricht abwarten |
|
398 |
|
399 EtherCAT_write_process_data(ecat_master); |
|
400 |
|
401 //mdelay(100); |
|
402 tick_period = start_rt_timer(nano2count(TIMERTICS)); |
|
403 now = rt_get_time(); |
|
404 |
|
405 if ((rv = rt_task_init(&process_image, process_thread, 0/*data*/, 64000/*stacksize*/, 0/*prio*/, 1/*use fpu*/, 0/*signal*/))) |
|
406 { |
|
407 msr_print_error("Could not initialise process_thread\n"); |
|
408 goto out_stoptimer; |
|
409 } |
|
410 |
|
411 msr_print_info("Initialised sample thread\n"); |
|
412 |
|
413 if ((rv = rt_task_make_periodic(&process_image, |
|
414 now + tick_period, |
|
415 tick_period))) |
|
416 { |
|
417 msr_print_error("Could not start process_thread\n"); |
|
418 goto out_stoptask; |
|
419 } |
|
420 |
|
421 msr_print_info("Started sample thread."); |
|
422 |
|
423 return 0; |
|
424 |
|
425 out_stoptask: |
|
426 msr_print_info("Deleting task...."); |
|
427 rt_task_delete(&process_image); |
|
428 |
|
429 out_stoptimer: |
|
430 msr_print_info("Stopping timer."); |
|
431 stop_rt_timer(); |
|
432 |
|
433 #ifdef USE_ETHERCAT |
|
434 out_masterclear: |
|
435 msr_print_info("Clearing EtherCAT master."); |
|
436 EtherCAT_master_clear(ecat_master); |
|
437 |
|
438 out_master: |
|
439 msr_print_info("Freeing EtherCAT master."); |
|
440 kfree(ecat_master); |
|
441 |
|
442 out_close: |
|
443 msr_print_info("Closing device."); |
|
444 |
|
445 EtherCAT_device_close(&rtl_ecat_dev); |
|
446 #endif |
|
447 |
|
448 out_rtlib: |
|
449 msr_print_info("msr_rtlib_cleanup()"); |
|
450 mdelay(10); |
|
451 msr_rtlib_cleanup(); |
|
452 |
|
453 out_umount: |
|
454 // rt_umount_rtai(); |
|
455 |
|
456 return rv; |
|
457 } |
|
458 |
|
459 /* |
|
460 ******************************************************************************* |
|
461 * |
|
462 * Function: msr_io_cleanup |
|
463 * |
|
464 * Beschreibung: Aufräumen |
|
465 * |
|
466 * Parameter: |
|
467 * |
|
468 * Rückgabe: |
|
469 * |
|
470 * Status: exp |
|
471 * |
|
472 ******************************************************************************* |
|
473 */ |
|
474 |
|
475 void msr_io_cleanup(void) |
|
476 { |
|
477 |
|
478 msr_print_info("Stopping timer."); |
|
479 |
|
480 stop_rt_timer(); |
|
481 |
|
482 msr_print_info("Deleting task...."); |
|
483 |
|
484 rt_task_delete(&process_image); |
|
485 /* |
|
486 for(i=0;i<1000;i++) { |
|
487 udelay(100); |
|
488 if(thread_end == 1) { |
|
489 msr_print_info("Task ended at count %d",i); |
|
490 break; |
|
491 } |
|
492 } |
|
493 */ |
|
494 //noch einmal lesen |
|
495 |
|
496 msr_print_info("Read Processdata"); |
|
497 EtherCAT_read_process_data(ecat_master); |
|
498 |
|
499 //EtherCAT_read_process_data(ecat_master); |
|
500 #ifdef USE_ETHERCAT |
|
501 if (ecat_master) |
|
502 { |
|
503 |
|
504 msr_print_info("Deactivating slaves."); |
|
505 |
|
506 |
|
507 EtherCAT_deactivate_all_slaves(ecat_master); |
|
508 |
|
509 |
|
510 msr_print_info("Clearing EtherCAT master."); |
|
511 |
|
512 EtherCAT_master_clear(ecat_master); |
|
513 |
|
514 msr_print_info("Freeing EtherCAT master."); |
|
515 |
|
516 |
|
517 kfree(ecat_master); |
|
518 ecat_master = NULL; |
|
519 } |
|
520 |
|
521 msr_print_info("Closing device."); |
|
522 |
|
523 EtherCAT_device_close(&rtl_ecat_dev); |
|
524 |
|
525 #endif |
|
526 msr_print_info("msr_rtlib_cleanup()"); |
|
527 |
|
528 msr_rtlib_cleanup(); |
|
529 //rt_umount_rtai(); |
|
530 } |
|
531 |
|
532 /*---Treiber-Einsprungspunkte etc.-------------------------------------------*/ |
|
533 |
|
534 MODULE_LICENSE("GPL"); |
|
535 |
|
536 module_init(msr_init); |
|
537 module_exit(msr_io_cleanup); |
|
538 |
|
539 /*---Ende--------------------------------------------------------------------*/ |
|