1 /****************************************************************************** |
|
2 * |
|
3 * ec_mini.c |
|
4 * |
|
5 * Minimalmodul für EtherCAT |
|
6 * |
|
7 * $Id$ |
|
8 * |
|
9 *****************************************************************************/ |
|
10 |
|
11 #include <linux/module.h> |
|
12 #include <linux/delay.h> |
|
13 #include <linux/timer.h> |
|
14 |
|
15 #include "../drivers/ec_master.h" |
|
16 #include "../drivers/ec_device.h" |
|
17 #include "../drivers/ec_types.h" |
|
18 #include "../drivers/ec_module.h" |
|
19 |
|
20 /*****************************************************************************/ |
|
21 |
|
22 // Auskommentieren, wenn keine zyklischen Daten erwuenscht |
|
23 #define ECAT_CYCLIC_DATA |
|
24 |
|
25 /*****************************************************************************/ |
|
26 |
|
27 static EtherCAT_master_t *ecat_master = NULL; |
|
28 |
|
29 static EtherCAT_slave_t ecat_slaves[] = |
|
30 { |
|
31 #if 0 |
|
32 // Block 1 |
|
33 ECAT_INIT_SLAVE(Beckhoff_EK1100, 1), |
|
34 ECAT_INIT_SLAVE(Beckhoff_EL4102, 1), |
|
35 ECAT_INIT_SLAVE(Beckhoff_EL3162, 1), |
|
36 ECAT_INIT_SLAVE(Beckhoff_EL1014, 1), |
|
37 |
|
38 ECAT_INIT_SLAVE(Beckhoff_EL4102, 1), |
|
39 ECAT_INIT_SLAVE(Beckhoff_EL4102, 1), |
|
40 ECAT_INIT_SLAVE(Beckhoff_EL4102, 1), |
|
41 |
|
42 ECAT_INIT_SLAVE(Beckhoff_EL3162, 1), |
|
43 ECAT_INIT_SLAVE(Beckhoff_EL3162, 1), |
|
44 ECAT_INIT_SLAVE(Beckhoff_EL3162, 1), |
|
45 ECAT_INIT_SLAVE(Beckhoff_EL3102, 1), |
|
46 ECAT_INIT_SLAVE(Beckhoff_EL3102, 1), |
|
47 ECAT_INIT_SLAVE(Beckhoff_EL3102, 1), |
|
48 |
|
49 #endif |
|
50 |
|
51 #if 1 |
|
52 // Block 2 |
|
53 ECAT_INIT_SLAVE(Beckhoff_EK1100, 1), |
|
54 ECAT_INIT_SLAVE(Beckhoff_EL4102, 1), |
|
55 ECAT_INIT_SLAVE(Beckhoff_EL1014, 1), |
|
56 ECAT_INIT_SLAVE(Beckhoff_EL3162, 1), |
|
57 ECAT_INIT_SLAVE(Beckhoff_EL2004, 1), |
|
58 ECAT_INIT_SLAVE(Beckhoff_EL3102, 1), |
|
59 ECAT_INIT_SLAVE(Beckhoff_EL2004, 1), |
|
60 ECAT_INIT_SLAVE(Beckhoff_EL2004, 1), |
|
61 ECAT_INIT_SLAVE(Beckhoff_EL2004, 1), |
|
62 ECAT_INIT_SLAVE(Beckhoff_EL2004, 1), |
|
63 ECAT_INIT_SLAVE(Beckhoff_EL2004, 1), |
|
64 |
|
65 // Block 3 |
|
66 ECAT_INIT_SLAVE(Beckhoff_EK1100, 1), |
|
67 ECAT_INIT_SLAVE(Beckhoff_EL1014, 1), |
|
68 ECAT_INIT_SLAVE(Beckhoff_EL1014, 1), |
|
69 ECAT_INIT_SLAVE(Beckhoff_EL1014, 1), |
|
70 ECAT_INIT_SLAVE(Beckhoff_EL1014, 1), |
|
71 ECAT_INIT_SLAVE(Beckhoff_EL1014, 1), |
|
72 ECAT_INIT_SLAVE(Beckhoff_EL2004, 1), |
|
73 ECAT_INIT_SLAVE(Beckhoff_EL2004, 1), |
|
74 ECAT_INIT_SLAVE(Beckhoff_EL2004, 1), |
|
75 ECAT_INIT_SLAVE(Beckhoff_EL2004, 1), |
|
76 ECAT_INIT_SLAVE(Beckhoff_EL1014, 1), |
|
77 ECAT_INIT_SLAVE(Beckhoff_EL1014, 1), |
|
78 ECAT_INIT_SLAVE(Beckhoff_EL1014, 1) |
|
79 #endif |
|
80 }; |
|
81 |
|
82 #define ECAT_SLAVES_COUNT (sizeof(ecat_slaves) / sizeof(EtherCAT_slave_t)) |
|
83 |
|
84 #ifdef ECAT_CYCLIC_DATA |
|
85 |
|
86 int value; |
|
87 int dig1; |
|
88 |
|
89 struct timer_list timer; |
|
90 unsigned long last_start_jiffies; |
|
91 |
|
92 #endif // ECAT_CYCLIC_DATA |
|
93 |
|
94 /****************************************************************************** |
|
95 * |
|
96 * Function: next2004 |
|
97 * |
|
98 *****************************************************************************/ |
|
99 |
|
100 #ifdef ECAT_CYCLIC_DATA |
|
101 |
|
102 static int next2004(int *wrap) |
|
103 { |
|
104 static int i = 0; |
|
105 unsigned int j = 0; |
|
106 |
|
107 *wrap = 0; |
|
108 |
|
109 for (j = 0; j < ECAT_SLAVES_COUNT; j++) |
|
110 { |
|
111 i++; |
|
112 |
|
113 i %= ECAT_SLAVES_COUNT; |
|
114 |
|
115 if (i == 0) *wrap = 1; |
|
116 |
|
117 if (ecat_slaves[i].desc == Beckhoff_EL2004) |
|
118 { |
|
119 return i; |
|
120 } |
|
121 } |
|
122 |
|
123 return -1; |
|
124 } |
|
125 #endif |
|
126 |
|
127 /****************************************************************************** |
|
128 * |
|
129 * Function: run |
|
130 * |
|
131 * Beschreibung: Zyklischer Prozess |
|
132 * |
|
133 *****************************************************************************/ |
|
134 |
|
135 #ifdef ECAT_CYCLIC_DATA |
|
136 |
|
137 static void run(unsigned long data) |
|
138 { |
|
139 static int ms = 0; |
|
140 static int cnt = 0; |
|
141 static unsigned long int k = 0; |
|
142 static int firstrun = 1; |
|
143 |
|
144 static int klemme = 0; |
|
145 static int kanal = 0; |
|
146 static int up_down = 0; |
|
147 int wrap = 0; |
|
148 |
|
149 ms++; |
|
150 ms %= 1000; |
|
151 |
|
152 if (firstrun) klemme = next2004(&wrap); |
|
153 |
|
154 if (cnt++ > 20) |
|
155 { |
|
156 cnt = 0; |
|
157 |
|
158 if (++kanal > 3) |
|
159 { |
|
160 kanal = 0; |
|
161 klemme = next2004(&wrap); |
|
162 |
|
163 if (wrap == 1) |
|
164 { |
|
165 if (up_down == 1) up_down = 0; |
|
166 else up_down = 1; |
|
167 } |
|
168 } |
|
169 } |
|
170 |
|
171 if (klemme >= 0) |
|
172 EtherCAT_write_value(&ecat_slaves[klemme], kanal, up_down); |
|
173 |
|
174 // Prozessdaten lesen und schreiben |
|
175 rdtscl(k); |
|
176 EtherCAT_process_data_cycle(ecat_master, 1, 100); |
|
177 firstrun = 0; |
|
178 |
|
179 timer.expires += HZ / 1000; |
|
180 add_timer(&timer); |
|
181 } |
|
182 |
|
183 #endif // ECAT_CYCLIC_DATA |
|
184 |
|
185 /****************************************************************************** |
|
186 * |
|
187 * Function: init |
|
188 * |
|
189 *****************************************************************************/ |
|
190 |
|
191 int __init init_module() |
|
192 { |
|
193 unsigned int i; |
|
194 |
|
195 printk(KERN_INFO "=== Starting Minimal EtherCAT environment... ===\n"); |
|
196 |
|
197 if ((ecat_master = EtherCAT_request(0)) == NULL) { |
|
198 printk(KERN_ERR "EtherCAT master 0 not available!\n"); |
|
199 goto out_return; |
|
200 } |
|
201 |
|
202 printk("Checking EtherCAT slaves.\n"); |
|
203 |
|
204 if (EtherCAT_check_slaves(ecat_master, ecat_slaves, |
|
205 ECAT_SLAVES_COUNT) != 0) { |
|
206 printk(KERN_ERR "EtherCAT: Could not init slaves!\n"); |
|
207 goto out_release_master; |
|
208 } |
|
209 |
|
210 printk("Activating all EtherCAT slaves.\n"); |
|
211 |
|
212 for (i = 0; i < ECAT_SLAVES_COUNT; i++) { |
|
213 if (EtherCAT_activate_slave(ecat_master, &ecat_slaves[i]) != 0) { |
|
214 printk(KERN_ERR "EtherCAT: Could not activate slave %i!\n", i); |
|
215 goto out_release_master; |
|
216 } |
|
217 } |
|
218 |
|
219 #ifdef ECAT_CYCLIC_DATA |
|
220 printk("Starting cyclic sample thread.\n"); |
|
221 |
|
222 init_timer(&timer); |
|
223 |
|
224 timer.function = run; |
|
225 timer.data = 0; |
|
226 timer.expires = jiffies+10; // Das erste Mal sofort feuern |
|
227 last_start_jiffies = timer.expires; |
|
228 add_timer(&timer); |
|
229 |
|
230 printk("Initialised sample thread.\n"); |
|
231 #endif |
|
232 |
|
233 printk(KERN_INFO "=== Minimal EtherCAT environment started. ===\n"); |
|
234 |
|
235 return 0; |
|
236 |
|
237 out_release_master: |
|
238 EtherCAT_release(ecat_master); |
|
239 |
|
240 out_return: |
|
241 return -1; |
|
242 } |
|
243 |
|
244 /****************************************************************************** |
|
245 * |
|
246 * Function: cleanup |
|
247 * |
|
248 *****************************************************************************/ |
|
249 |
|
250 void __exit cleanup_module() |
|
251 { |
|
252 unsigned int i; |
|
253 |
|
254 printk(KERN_INFO "=== Stopping Minimal EtherCAT environment... ===\n"); |
|
255 |
|
256 if (ecat_master) |
|
257 { |
|
258 #ifdef ECAT_CYCLIC_DATA |
|
259 del_timer_sync(&timer); |
|
260 #endif // ECAT_CYCLIC_DATA |
|
261 |
|
262 printk(KERN_INFO "Deactivating slaves.\n"); |
|
263 |
|
264 for (i = 0; i < ECAT_SLAVES_COUNT; i++) { |
|
265 EtherCAT_deactivate_slave(ecat_master, &ecat_slaves[i]); |
|
266 } |
|
267 |
|
268 EtherCAT_release(ecat_master); |
|
269 } |
|
270 |
|
271 printk(KERN_INFO "=== Minimal EtherCAT environment stopped. ===\n"); |
|
272 } |
|
273 |
|
274 /*****************************************************************************/ |
|
275 |
|
276 MODULE_LICENSE("GPL"); |
|
277 MODULE_AUTHOR ("Florian Pose <fp@igh-essen.com>"); |
|
278 MODULE_DESCRIPTION ("Minimal EtherCAT environment"); |
|
279 |
|
280 module_init(init_module); |
|
281 module_exit(cleanup_module); |
|
282 |
|
283 /*****************************************************************************/ |
|
284 |
|
285 /* Emacs-Konfiguration |
|
286 ;;; Local Variables: *** |
|
287 ;;; c-basic-offset:4 *** |
|
288 ;;; End: *** |
|
289 */ |
|