|
1 /************************************************************************************************** |
|
2 * |
|
3 * msr_io.c |
|
4 * |
|
5 * Verwaltung der IO-Karten |
|
6 * |
|
7 * |
|
8 * Autor: Wilhelm Hagemeister |
|
9 * |
|
10 * (C) Copyright IgH 2002 |
|
11 * Ingenieurgemeinschaft IgH |
|
12 * Heinz-Bäcker Str. 34 |
|
13 * D-45356 Essen |
|
14 * Tel.: +49 201/61 99 31 |
|
15 * Fax.: +49 201/61 98 36 |
|
16 * E-mail: sp@igh-essen.com |
|
17 * |
|
18 * |
|
19 * $RCSfile: msr_io.c,v $ |
|
20 * $Revision: 1.9 $ |
|
21 * $Author: ha $ |
|
22 * $Date: 2005/06/24 20:06:56 $ |
|
23 * $State: Exp $ |
|
24 * |
|
25 * |
|
26 * $Log: msr_io.c,v $ |
|
27 * Revision 1.9 2005/06/24 20:06:56 ha |
|
28 * *** empty log message *** |
|
29 * |
|
30 * Revision 1.8 2005/06/24 17:39:05 ha |
|
31 * *** empty log message *** |
|
32 * |
|
33 * |
|
34 * |
|
35 * |
|
36 * |
|
37 * |
|
38 **************************************************************************************************/ |
|
39 |
|
40 |
|
41 /*--includes-------------------------------------------------------------------------------------*/ |
|
42 |
|
43 #ifndef __KERNEL__ |
|
44 # define __KERNEL__ |
|
45 #endif |
|
46 #ifndef MODULE |
|
47 # define MODULE |
|
48 #endif |
|
49 |
|
50 #include <linux/delay.h> /* mdelay() */ |
|
51 #include <linux/spinlock.h> |
|
52 #include <linux/param.h> /* HZ */ |
|
53 #include <linux/sched.h> /* jiffies */ |
|
54 #include <linux/fs.h> /* everything... */ |
|
55 #include <rtai_fifos.h> |
|
56 |
|
57 #include "msr_io.h" |
|
58 |
|
59 #include <msr_messages.h> |
|
60 |
|
61 |
|
62 #include "aim_globals.h" |
|
63 |
|
64 spinlock_t data_lock = SPIN_LOCK_UNLOCKED; |
|
65 |
|
66 #include "cif-rtai-io.h" |
|
67 |
|
68 /*--defines--------------------------------------------------------------------------------------*/ |
|
69 |
|
70 |
|
71 /*--external functions---------------------------------------------------------------------------*/ |
|
72 |
|
73 |
|
74 /*--external data--------------------------------------------------------------------------------*/ |
|
75 |
|
76 |
|
77 /*--public data----------------------------------------------------------------------------------*/ |
|
78 |
|
79 #define PB_CARDS 4 |
|
80 struct { |
|
81 unsigned int fd; |
|
82 unsigned int timestamp; |
|
83 unsigned int fault; |
|
84 unsigned int active; |
|
85 void *in_buf; |
|
86 void *out_buf; |
|
87 size_t in_buf_len; |
|
88 size_t out_buf_len; |
|
89 |
|
90 unsigned int reset_timeout; |
|
91 } card[PB_CARDS]; |
|
92 |
|
93 |
|
94 /* |
|
95 *************************************************************************************************** |
|
96 * |
|
97 * Function: msr_io_init |
|
98 * |
|
99 * Beschreibung: Initialisieren der I/O-Karten |
|
100 * |
|
101 * Parameter: |
|
102 * |
|
103 * Rückgabe: |
|
104 * |
|
105 * Status: exp |
|
106 * |
|
107 *************************************************************************************************** |
|
108 */ |
|
109 void x_PB_io(unsigned long card_no) { |
|
110 int rv = 0; |
|
111 unsigned int flags; |
|
112 |
|
113 spin_lock_irqsave(&data_lock, flags); |
|
114 |
|
115 switch (card_no) { |
|
116 case 0: |
|
117 rv = cif_exchange_io(card[0].fd,card[0].in_buf,card[0].out_buf); |
|
118 if (!rv) |
|
119 card[0].timestamp = jiffies; |
|
120 break; |
|
121 case 1: |
|
122 rv = cif_exchange_io(card[1].fd,card[1].in_buf,card[1].out_buf); |
|
123 // rv = cif_read_io(card[1].fd,card[1].in_buf); |
|
124 // IMO.to_dSPACE.P101.HX_Stat = 51; |
|
125 // IMO.from_dSPACE.P101.HX_Control |= IMO.to_dSPACE.P101.HX_Stat<<4; |
|
126 // rv += cif_write_io(card[1].fd,card[1].out_buf); |
|
127 if (!rv) |
|
128 card[1].timestamp = jiffies; |
|
129 break; |
|
130 /* |
|
131 case 2: |
|
132 rv = cif_exchange_io(card[2].fd,&cif_in.P201,&cif_out.P201); |
|
133 break; |
|
134 */ |
|
135 case 3: |
|
136 rv = cif_exchange_io(card[3].fd,card[3].in_buf,card[3].out_buf); |
|
137 if (!rv) |
|
138 card[3].timestamp = jiffies; |
|
139 break; |
|
140 } |
|
141 |
|
142 if (rv) { |
|
143 msr_print_error("Error during exchange_io %i %i", |
|
144 card_no, rv ); |
|
145 } |
|
146 |
|
147 spin_unlock_irqrestore(&data_lock, flags); |
|
148 |
|
149 } |
|
150 |
|
151 int msr_io_init() |
|
152 { |
|
153 int rv; |
|
154 |
|
155 memset(card, 0, sizeof(card)); |
|
156 |
|
157 #define FIFO_BUF 10000 |
|
158 |
|
159 if ((rv = rtf_create(0, FIFO_BUF)) < 0) { |
|
160 msr_print_error("Could not open FIFO %i", rv); |
|
161 return -1; |
|
162 } |
|
163 |
|
164 #ifndef _SIMULATION |
|
165 /* |
|
166 card[0].in_buf_len = sizeof(IMO.from_dSPACE); |
|
167 card[0].out_buf_len = sizeof(IMO.to_dSPACE); |
|
168 card[0].in_buf = &IMO.from_dSPACE; |
|
169 card[0].out_buf = &IMO.to_dSPACE; |
|
170 card[0].active = 1; |
|
171 if (!(card[0].fd = cif_open_card(0, card[0].in_buf_len, |
|
172 card[0].out_buf_len, x_PB_io, 0))) { |
|
173 msr_print_error("Cannot open CIF card PB01"); |
|
174 return -1; |
|
175 } |
|
176 |
|
177 |
|
178 card[1].in_buf_len = sizeof(IMO.to_dSPACE.P101); |
|
179 card[1].out_buf_len = sizeof(IMO.from_dSPACE.P101); |
|
180 card[1].in_buf = &IMO.to_dSPACE.P101; |
|
181 card[1].out_buf = &IMO.from_dSPACE.P101; |
|
182 card[1].active = 1; |
|
183 if (!(card[1].fd = cif_open_card(1, card[1].in_buf_len, |
|
184 card[1].out_buf_len, x_PB_io, 1))) { |
|
185 msr_print_error("Cannot open CIF card P101"); |
|
186 return -1; |
|
187 } |
|
188 |
|
189 card[2].in_buf_len = sizeof(IMO.to_dSPACE.P201); |
|
190 card[2].out_buf_len = sizeof(IMO.from_dSPACE.P201); |
|
191 card[2].in_buf = &IMO.to_dSPACE.P201; |
|
192 card[2].out_buf = &IMO.from_dSPACE.P201; |
|
193 if (!(card[2].fd = cif_open_card(2, card[2].in_buf_len, |
|
194 card[2].out_buf_len, x_PB_io, 2))) { |
|
195 msr_print_error("Cannot open CIF card P201"); |
|
196 return -1; |
|
197 } |
|
198 |
|
199 */ |
|
200 card[3].in_buf_len = sizeof(dSPACE.in); |
|
201 card[3].out_buf_len = sizeof(dSPACE.out); |
|
202 card[3].in_buf = &dSPACE.in; |
|
203 card[3].out_buf = &dSPACE.out; |
|
204 card[3].active = 1; |
|
205 if (!(card[3].fd = cif_open_card(0, card[3].in_buf_len, |
|
206 card[3].out_buf_len, x_PB_io,3))) { |
|
207 msr_print_error("Cannot open CIF card P301"); |
|
208 return -1; |
|
209 } |
|
210 |
|
211 //msr_reg_chk_failure(&int_cif_io_fail,TINT,T_CHK_HIGH,0,T_CRIT,"CIF Card was not ready to exchange data"); |
|
212 |
|
213 |
|
214 #endif |
|
215 |
|
216 return 0; |
|
217 } |
|
218 |
|
219 /* |
|
220 *************************************************************************************************** |
|
221 * |
|
222 * Function: msr_io_register |
|
223 * |
|
224 * Beschreibung: Rohdaten als Kanaele registrieren |
|
225 * |
|
226 * Parameter: |
|
227 * |
|
228 * Rückgabe: |
|
229 * |
|
230 * Status: exp |
|
231 * |
|
232 *************************************************************************************************** |
|
233 */ |
|
234 |
|
235 int msr_io_register() |
|
236 { |
|
237 |
|
238 #ifndef _SIMULATION |
|
239 |
|
240 #endif |
|
241 |
|
242 return 0; |
|
243 } |
|
244 |
|
245 |
|
246 /* |
|
247 *************************************************************************************************** |
|
248 * |
|
249 * Function: msr_io_write |
|
250 * |
|
251 * Beschreibung: Schreiben der Werte |
|
252 * |
|
253 * Parameter: |
|
254 * |
|
255 * Rückgabe: |
|
256 * |
|
257 * Status: exp |
|
258 * |
|
259 *************************************************************************************************** |
|
260 */ |
|
261 int msr_io_write() |
|
262 { |
|
263 static int return_value = 0; |
|
264 int rv; |
|
265 int i = 0; |
|
266 unsigned int flags; |
|
267 unsigned int com_check_timestamp = 0; |
|
268 static int COM_Up = 1; |
|
269 |
|
270 if (jiffies - com_check_timestamp > HZ/20) { |
|
271 |
|
272 if ( rtf_put_if(0,&IMO,sizeof(IMO)) != sizeof(IMO)) { |
|
273 //msr_print_error("Could not output data"); |
|
274 } |
|
275 |
|
276 com_check_timestamp = jiffies; |
|
277 |
|
278 spin_lock_irqsave(&data_lock, flags); |
|
279 for ( i=0; i < PB_CARDS; i++) { |
|
280 // Ignore inactive and cards that already have a fault |
|
281 if (!card[i].active || card[i].fault) |
|
282 continue; |
|
283 |
|
284 // For active cards, check timestamp value. Mark card |
|
285 // as faulty if there was no data exchange in the last |
|
286 // 50ms |
|
287 if (jiffies - card[i].timestamp > HZ/20) { |
|
288 COM_Up = 0; |
|
289 card[i].fault = 1; |
|
290 card[i].reset_timeout = jiffies; |
|
291 msr_print_error("Card %i timed out", i); |
|
292 } |
|
293 |
|
294 } |
|
295 |
|
296 spin_unlock_irqrestore(&data_lock, flags); |
|
297 |
|
298 for ( i = 0; i < PB_CARDS; i++ ) { |
|
299 if (!card[i].active || (card[i].active && !card[i].fault)) |
|
300 continue; |
|
301 |
|
302 switch (card[i].fault) { |
|
303 case 1: |
|
304 rv = cif_write_io(card[i].fd,card[i].out_buf); |
|
305 |
|
306 if (!rv) { |
|
307 msr_print_error("Card %i online", i); |
|
308 card[i].fault = 0; |
|
309 card[i].timestamp = jiffies; |
|
310 break; |
|
311 } |
|
312 |
|
313 msr_print_error("rv of cif_write_io(%i) = %i", |
|
314 i, rv); |
|
315 |
|
316 card[i].fault = 2; |
|
317 cif_set_host_state(card[i].fd,0); |
|
318 card[i].reset_timeout = jiffies; |
|
319 |
|
320 case 2: |
|
321 if (cif_card_ready(card[i].fd)) { |
|
322 cif_set_host_state(card[i].fd,1); |
|
323 card[i].fault = 0; |
|
324 break; |
|
325 } |
|
326 if (jiffies < card[i].reset_timeout) |
|
327 break; |
|
328 |
|
329 rv = cif_reset_card(card[i].fd,10,1); |
|
330 msr_print_error("rv of cif_reset_card(%i) = %i", |
|
331 i, rv); |
|
332 |
|
333 // Reset again in 10 seconds |
|
334 card[i].reset_timeout += 10*HZ; |
|
335 } |
|
336 } |
|
337 } |
|
338 |
|
339 if (COM_Up) |
|
340 IMO.to_dSPACE.Status = IMO.from_dSPACE.WatchDog; |
|
341 |
|
342 // if (return_value) |
|
343 // int_cif_io_fail = 1; |
|
344 |
|
345 return return_value; |
|
346 } |
|
347 |
|
348 /* |
|
349 *************************************************************************************************** |
|
350 * |
|
351 * Function: msr_io_read |
|
352 * |
|
353 * Beschreibung: Lesen der Werte |
|
354 * |
|
355 * Parameter: |
|
356 * |
|
357 * Rückgabe: |
|
358 * |
|
359 * Status: exp |
|
360 * |
|
361 *************************************************************************************************** |
|
362 */ |
|
363 int msr_io_read() |
|
364 { |
|
365 int return_value = 0; |
|
366 |
|
367 #ifndef _SIMULATION |
|
368 |
|
369 int_cif_io_fail = 0; |
|
370 /* |
|
371 return_value = cif_exchange_io(fd_PB01, |
|
372 &cif_out,&cif_in, |
|
373 sizeof(cif_out),sizeof(cif_in) |
|
374 ); |
|
375 */ |
|
376 /* if (return_value) */ |
|
377 /* int_cif_io_fail = 1; */ |
|
378 // printk("%i\n", return_value); |
|
379 |
|
380 #endif |
|
381 return return_value; |
|
382 } |
|
383 |
|
384 |
|
385 /* |
|
386 *************************************************************************************************** |
|
387 * |
|
388 * Function: msr_io_cleanup |
|
389 * |
|
390 * Beschreibung: Aufräumen |
|
391 * |
|
392 * Parameter: |
|
393 * |
|
394 * Rückgabe: |
|
395 * |
|
396 * Status: exp |
|
397 * |
|
398 *************************************************************************************************** |
|
399 */ |
|
400 void msr_io_cleanup() |
|
401 { |
|
402 /* |
|
403 cif_set_host_state(card[0].fd,0); |
|
404 cif_close_card(card[0].fd); |
|
405 |
|
406 cif_set_host_state(card[1].fd,0); |
|
407 cif_close_card(card[1].fd); |
|
408 |
|
409 cif_set_host_state(card[2].fd,0); |
|
410 cif_close_card(card[2].fd); |
|
411 |
|
412 |
|
413 */ |
|
414 cif_set_host_state(card[3].fd,0); |
|
415 cif_close_card(card[3].fd); |
|
416 |
|
417 rtf_destroy(0); |
|
418 } |
|
419 |
|
420 |