1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <time.h>
5 #include "asm.h"
6 #include "processor.h"
7 #include "system.h"
8 #include "ogcsys.h"
9 #include "video.h"
10 #include "irq.h"
11 #include "si.h"
12 #include "lwp_watchdog.h"
13
14 #define _SHIFTL(v, s, w) \
15 ((u32) (((u32)(v) & ((0x01 << (w)) - 1)) << (s)))
16 #define _SHIFTR(v, s, w) \
17 ((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1)))
18
19 #define SISR_ERRORMASK(chn) (0x0f000000>>((chn)<<3))
20 #define SIPOLL_ENABLE(chn) (0x80000000>>((chn)+24))
21
22 #define SICOMCSR_TCINT (1<<31)
23 #define SICOMCSR_TCINT_ENABLE (1<<30)
24 #define SICOMCSR_COMERR (1<<29)
25 #define SICOMCSR_RDSTINT (1<<28)
26 #define SICOMCSR_RDSTINT_ENABLE (1<<27)
27 #define SICOMCSR_TSTART (1<<0)
28
29 #define SISR_UNDERRUN 0x0001
30 #define SISR_OVERRUN 0x0002
31 #define SISR_COLLISION 0x0004
32 #define SISR_NORESPONSE 0x0008
33 #define SISR_WRST 0x0010
34 #define SISR_RDST 0x0020
35
36 typedef union _sicomcsr {
37 u32 val;
38 struct {
39 u32 tcint : 1;
40 u32 tcintmsk : 1;
41 u32 comerr : 1;
42 u32 rdstint : 1;
43 u32 rdstintmsk : 1;
44 u32 pad2 : 4;
45 u32 outlen : 7;
46 u32 pad1 : 1;
47 u32 inlen : 7;
48 u32 pad0 : 5;
49 u32 channel : 2;
50 u32 tstart : 1;
51 } csrmap;
52 } sicomcsr;
53
54 static struct _sipacket {
55 s32 chan;
56 void *out;
57 u32 out_bytes;
58 void *in;
59 u32 in_bytes;
60 SICallback callback;
61 u64 fire;
62 } sipacket[4];
63
64 static struct _sicntrl {
65 s32 chan;
66 u32 poll;
67 u32 in_bytes;
68 void *in;
69 SICallback callback;
70 } sicntrl = {
71 -1,
72 0,
73 0,
74 NULL,
75 NULL
76 };
77
78 static struct _xy {
79 u16 line;
80 u8 cnt;
81 } xy[2][12] = {
82 {
83 {0x00F6,0x02},{0x000F,0x12},{0x001E,0x09},{0x002C,0x06},
84 {0x0034,0x05},{0x0041,0x04},{0x0057,0x03},{0x0057,0x03},
85 {0x0057,0x03},{0x0083,0x02},{0x0083,0x02},{0x0083,0x02}
86 },
87
88 {
89 {0x0128,0x02},{0x000F,0x15},{0x001D,0x0B},{0x002D,0x07},
90 {0x0034,0x06},{0x003F,0x05},{0x004E,0x04},{0x0068,0x03},
91 {0x0068,0x03},{0x0068,0x03},{0x0068,0x03},{0x009C,0x02}
92 }
93 };
94
95 u32 __PADFixBits = 0;
96
97 static u32 sampling_rate = 0;
98 static u32 cmdtypeandstatus$47 = 0;
99 static u32 cmdtypeandstatus$223 = 0;
100 static u32 cmdfixdevice[4] = {0,0,0,0};
101 static u32 si_type[4] = {8,8,8,8};
102 static u32 inputBufferVCount[4] = {0,0,0,0};
103 static u32 inputBufferValid[4] = {0,0,0,0};
104 static u32 inputBuffer[4][2] = {{0,0},{0,0},{0,0},{0,0}};
105 static RDSTHandler rdstHandlers[4] = {NULL,NULL,NULL,NULL};
106 static u64 typeTime[4] = {0,0,0,0};
107 static u64 xferTime[4] = {0,0,0,0};
108 static SICallback typeCallback[4][4] = {{NULL,NULL,NULL,NULL},
109 {NULL,NULL,NULL,NULL},
110 {NULL,NULL,NULL,NULL},
111 {NULL,NULL,NULL,NULL}};
112 static syswd_t si_alarm[4];
113
114 #if defined(HW_DOL)
115 static vu32* const _siReg = (u32*)0xCC006400;
116 #elif defined(HW_RVL)
117 static vu32* const _siReg = (u32*)0xCD006400;
118 #else
119 #error HW model unknown.
120 #endif
121
122 static vu16* const _viReg = (u16*)0xCC002000;
123
124 static u32 __si_transfer(s32 chan,void *out,u32 out_len,void *in,u32 in_len,SICallback cb);
125
__si_getxy()126 static __inline__ struct _xy* __si_getxy()
127 {
128 switch(VIDEO_GetCurrentTvMode()) {
129 case VI_NTSC:
130 case VI_MPAL:
131 case VI_EURGB60:
132 return xy[0];
133 break;
134 case VI_PAL:
135 return xy[1];
136 break;
137 }
138 return NULL;
139 }
140
__si_cleartcinterrupt()141 static __inline__ void __si_cleartcinterrupt()
142 {
143 _siReg[13] = (_siReg[13]|SICOMCSR_TCINT)&SICOMCSR_TCINT;
144 }
145
__si_alarmhandler(syswd_t thealarm,void * cbarg)146 static void __si_alarmhandler(syswd_t thealarm,void *cbarg)
147 {
148 u32 chn = 0;
149
150 while(chn<4)
151 {
152 if(si_alarm[chn]==thealarm)
153 break;
154 chn++;
155 }
156 if(chn==4)
157 return;
158
159 if(sipacket[chn].chan!=-1) {
160 if(__si_transfer(sipacket[chn].chan,sipacket[chn].out,sipacket[chn].out_bytes,sipacket[chn].in,sipacket[chn].in_bytes,sipacket[chn].callback)) sipacket[chn].chan = -1;
161 }
162 }
163
__si_completetransfer()164 static u32 __si_completetransfer()
165 {
166 u32 val,cnt,i;
167 u32 *in;
168 u32 sisr = _siReg[14];
169
170 __si_cleartcinterrupt();
171
172 if(sicntrl.chan==-1) return sisr;
173
174 xferTime[sicntrl.chan] = gettime();
175
176 in = (u32*)sicntrl.in;
177 cnt = (sicntrl.in_bytes/4);
178 for(i=0;i<cnt;i++) in[i] = _siReg[32+i];
179 if(sicntrl.in_bytes&0x03) {
180 val = _siReg[32+cnt];
181 for(i=0;i<(sicntrl.in_bytes&0x03);i++) ((u8*)in)[(cnt*4)+i] = (val>>((3-i)*8))&0xff;
182 }
183 if(_siReg[13]&SICOMCSR_COMERR) {
184 sisr = (sisr>>((3-sicntrl.chan)*8))&0x0f;
185 if(sisr&SISR_NORESPONSE && !(si_type[sicntrl.chan]&SI_ERR_BUSY)) si_type[sicntrl.chan] = SI_ERROR_NO_RESPONSE;
186 if(!sisr) sisr = SISR_COLLISION;
187 } else {
188 typeTime[sicntrl.chan] = gettime();
189 sisr = 0;
190 }
191
192 sicntrl.chan = -1;
193 return sisr;
194 }
195
__si_transfer(s32 chan,void * out,u32 out_len,void * in,u32 in_len,SICallback cb)196 static u32 __si_transfer(s32 chan,void *out,u32 out_len,void *in,u32 in_len,SICallback cb)
197 {
198 u32 level,cnt,i;
199 sicomcsr csr;
200 _CPU_ISR_Disable(level);
201 if(sicntrl.chan!=-1) {
202 _CPU_ISR_Restore(level);
203 return 0;
204 }
205 _siReg[14] &= SISR_ERRORMASK(chan);
206
207 sicntrl.chan = chan;
208 sicntrl.callback = cb;
209 sicntrl.in_bytes = in_len;
210 sicntrl.in = in;
211 cnt = ((out_len+3)/4);
212 for(i=0;i<cnt;i++) _siReg[32+i] = ((u32*)out)[i];
213
214 csr.val = _siReg[13];
215 csr.csrmap.tcint = 1;
216 csr.csrmap.tcintmsk = 0;
217 if(cb) csr.csrmap.tcintmsk = 1;
218
219 if(out_len==128) out_len = 0;
220 csr.csrmap.outlen = out_len&0x7f;
221
222 if(in_len==128) in_len = 0;
223 csr.csrmap.inlen = in_len&0x7f;
224
225 csr.csrmap.channel = chan&0x03;
226 csr.csrmap.tstart = 1;
227 _siReg[13] = csr.val;
228 _CPU_ISR_Restore(level);
229
230 return 1;
231 }
232
__si_calltypandstatuscallback(s32 chan,u32 type)233 static void __si_calltypandstatuscallback(s32 chan,u32 type)
234 {
235 SICallback cb = NULL;
236 u32 typ = 0;
237 while(typ<4) {
238 cb = typeCallback[chan][typ];
239 if(cb) {
240 typeCallback[chan][typ] = NULL;
241 cb(chan,type);
242 }
243 typ++;
244 }
245 }
246
__si_gettypecallback(s32 chan,u32 type)247 static void __si_gettypecallback(s32 chan,u32 type)
248 {
249 u32 sipad_en,id;
250
251 si_type[chan] = (si_type[chan]&~SI_ERR_BUSY)|type;
252 typeTime[chan] = gettime();
253 sipad_en = __PADFixBits&SI_CHAN_BIT(chan);
254 __PADFixBits &= ~SI_CHAN_BIT(chan);
255
256 if(type&0x0f || ((si_type[chan]&SI_TYPE_MASK)-SI_TYPE_GC)
257 || !(si_type[chan]&SI_GC_WIRELESS) || si_type[chan]&SI_WIRELESS_IR) {
258 SYS_SetWirelessID(chan,0);
259 __si_calltypandstatuscallback(chan,si_type[chan]);
260 return;
261 }
262
263 id = _SHIFTL(SYS_GetWirelessID(chan),8,16);
264 if(sipad_en && id&SI_WIRELESS_FIX_ID) {
265 cmdfixdevice[chan] = 0x4e100000|(id&0x00CFFF00);
266 si_type[chan] = SI_ERR_BUSY;
267 SI_Transfer(chan,&cmdfixdevice[chan],3,&si_type[chan],3,__si_gettypecallback,0);
268 return;
269 }
270
271 if(si_type[chan]&SI_WIRELESS_FIX_ID) {
272 if((id&0x00CFFF00)==(si_type[chan]&0x00CFFF00)) goto exit;
273 if(!(id&SI_WIRELESS_FIX_ID)) {
274 id = SI_WIRELESS_FIX_ID|(si_type[chan]&0x00CFFF00);
275 SYS_SetWirelessID(chan,_SHIFTR(id,8,16));
276 }
277 cmdfixdevice[chan] = 0x4e000000|id;
278 si_type[chan] = SI_ERR_BUSY;
279 SI_Transfer(chan,&cmdfixdevice[chan],3,&si_type[chan],3,__si_gettypecallback,0);
280 return;
281 }
282
283 if(si_type[chan]&SI_WIRELESS_RECEIVED) {
284 id = SI_WIRELESS_FIX_ID|(si_type[chan]&0x00CFFF00);
285 SYS_SetWirelessID(chan,_SHIFTR(id,8,16));
286
287 cmdfixdevice[chan] = 0x4e000000|id;
288 si_type[chan] = SI_ERR_BUSY;
289 SI_Transfer(chan,&cmdfixdevice[chan],3,&si_type[chan],3,__si_gettypecallback,0);
290 return;
291 }
292 SYS_SetWirelessID(chan,0);
293
294 exit:
295 __si_calltypandstatuscallback(chan,si_type[chan]);
296 }
297
__si_transfernext(u32 chan)298 static void __si_transfernext(u32 chan)
299 {
300 u32 cnt;
301 u64 now;
302 s64 diff;
303 cnt = 0;
304 while(cnt<4) {
305 chan++;
306 chan %= 4;
307 if(sipacket[chan].chan!=-1) {
308 now = gettime();
309 diff = (now - sipacket[chan].fire);
310 if(diff>=0) {
311 if(!__si_transfer(sipacket[chan].chan,sipacket[chan].out,sipacket[chan].out_bytes,sipacket[chan].in,sipacket[chan].in_bytes,sipacket[chan].callback)) break;
312 SYS_CancelAlarm(si_alarm[chan]);
313 sipacket[chan].chan = -1;
314 }
315 }
316 cnt++;
317 }
318 }
319
__si_interrupthandler(u32 irq,void * ctx)320 static void __si_interrupthandler(u32 irq,void *ctx)
321 {
322 SICallback cb;
323 u32 chn,curr_line,line,ret;
324 sicomcsr csr;
325
326 csr.val = _siReg[13];
327 if(csr.csrmap.tcintmsk && csr.csrmap.tcint) {
328 chn = sicntrl.chan;
329 cb = sicntrl.callback;
330 sicntrl.callback = NULL;
331
332 ret = __si_completetransfer();
333 __si_transfernext(chn);
334
335 if(cb) cb(chn,ret);
336
337 _siReg[14] &= SISR_ERRORMASK(chn);
338
339 if(si_type[chn]==SI_ERR_BUSY && !SI_IsChanBusy(chn)) SI_Transfer(chn,&cmdtypeandstatus$47,1,&si_type[chn],3,__si_gettypecallback,65);
340 }
341
342 if(csr.csrmap.rdstintmsk && csr.csrmap.rdstint) {
343 curr_line = VIDEO_GetCurrentLine();
344 curr_line++;
345 line = _SHIFTR(sicntrl.poll,16,10);
346
347 chn = 0;
348 while(chn<4) {
349 if(SI_GetResponseRaw(chn)) inputBufferVCount[chn] = curr_line;
350 chn++;
351 }
352
353 chn = 0;
354 while(chn<4) {
355 if(sicntrl.poll&SIPOLL_ENABLE(chn)) {
356 if(!inputBufferVCount[chn] || ((line>>1)+inputBufferVCount[chn])<curr_line) return;
357 }
358 chn++;
359 }
360
361 chn = 0;
362 while(chn<4) inputBufferVCount[chn++] = 0;
363
364 chn = 0;
365 while(chn<4) {
366 if(rdstHandlers[chn]) rdstHandlers[chn](irq,ctx);
367 chn++;
368 }
369 }
370 }
371
SI_Sync()372 u32 SI_Sync()
373 {
374 u32 level,ret;
375
376 while(_siReg[13]&SICOMCSR_TSTART);
377
378 _CPU_ISR_Disable(level);
379 ret = __si_completetransfer();
380 __si_transfernext(4);
381 _CPU_ISR_Restore(level);
382
383 return ret;
384 }
385
SI_Busy()386 u32 SI_Busy()
387 {
388 return (sicntrl.chan==-1)?0:1;
389 }
390
SI_IsChanBusy(s32 chan)391 u32 SI_IsChanBusy(s32 chan)
392 {
393 u32 ret = 0;
394
395 if(sipacket[chan].chan!=-1 || sicntrl.chan==chan) ret = 1;
396
397 return ret;
398 }
399
SI_SetXY(u16 line,u8 cnt)400 void SI_SetXY(u16 line,u8 cnt)
401 {
402 u32 level;
403 _CPU_ISR_Disable(level);
404 sicntrl.poll = (sicntrl.poll&~0x3ffff00)|_SHIFTL(line,16,10)|_SHIFTL(cnt,8,8);
405 _siReg[12] = sicntrl.poll;
406 _CPU_ISR_Restore(level);
407 }
408
SI_EnablePolling(u32 poll)409 void SI_EnablePolling(u32 poll)
410 {
411 u32 level,mask;
412 _CPU_ISR_Disable(level);
413 poll >>= 24;
414 mask = (poll>>4)&0x0f;
415 sicntrl.poll &= ~mask;
416
417 poll &= (0x03fffff0|mask);
418
419 sicntrl.poll |= (poll&~0x03ffff00);
420 SI_TransferCommands();
421 _siReg[12] = sicntrl.poll;
422 _CPU_ISR_Restore(level);
423 }
424
SI_DisablePolling(u32 poll)425 void SI_DisablePolling(u32 poll)
426 {
427 u32 level,mask;
428 _CPU_ISR_Disable(level);
429 mask = (poll>>24)&0xf0;
430 sicntrl.poll &= ~mask;
431 _siReg[12] = sicntrl.poll;
432 _CPU_ISR_Restore(level);
433 }
434
SI_SetSamplingRate(u32 samplingrate)435 void SI_SetSamplingRate(u32 samplingrate)
436 {
437 u32 div,level;
438 struct _xy *xy = NULL;
439
440 if(samplingrate>11) samplingrate = 11;
441
442 _CPU_ISR_Disable(level);
443 sampling_rate = samplingrate;
444 xy = __si_getxy();
445
446 div = 1;
447 if(_viReg[54]&0x0001) div = 2;
448
449 SI_SetXY(div*xy[samplingrate].line,xy[samplingrate].cnt);
450 _CPU_ISR_Restore(level);
451 }
452
SI_RefreshSamplingRate()453 void SI_RefreshSamplingRate()
454 {
455 SI_SetSamplingRate(sampling_rate);
456 }
457
SI_GetStatus(s32 chan)458 u32 SI_GetStatus(s32 chan)
459 {
460 u32 level,sisr;
461
462 _CPU_ISR_Disable(level);
463 sisr = (_siReg[14]>>((3-chan)<<3));
464 if(sisr&SISR_NORESPONSE && !(si_type[chan]&SI_ERR_BUSY)) si_type[chan] = SI_ERROR_NO_RESPONSE;
465 _CPU_ISR_Restore(level);
466 return sisr;
467 }
468
SI_GetResponseRaw(s32 chan)469 u32 SI_GetResponseRaw(s32 chan)
470 {
471 u32 status,ret;
472 ret = 0;
473 status = SI_GetStatus(chan);
474 if(status&SISR_RDST) {
475 inputBuffer[chan][0] = _siReg[(chan*3)+1];
476 inputBuffer[chan][1] = _siReg[(chan*3)+2];
477 inputBufferValid[chan] = 1;
478 ret = 1;
479 }
480 return ret;
481 }
482
SI_GetResponse(s32 chan,void * buf)483 u32 SI_GetResponse(s32 chan,void *buf)
484 {
485 u32 level,valid;
486 _CPU_ISR_Disable(level);
487 SI_GetResponseRaw(chan);
488 valid = inputBufferValid[chan];
489 inputBufferValid[chan] = 0;
490 if(valid) {
491 ((u32*)buf)[0] = inputBuffer[chan][0];
492 ((u32*)buf)[1] = inputBuffer[chan][1];
493 }
494 _CPU_ISR_Restore(level);
495 return valid;
496 }
497
SI_SetCommand(s32 chan,u32 cmd)498 void SI_SetCommand(s32 chan,u32 cmd)
499 {
500 _siReg[chan*3] = cmd;
501 }
502
SI_GetCommand(s32 chan)503 u32 SI_GetCommand(s32 chan)
504 {
505 return (_siReg[chan*3]);
506 }
507
SI_Transfer(s32 chan,void * out,u32 out_len,void * in,u32 in_len,SICallback cb,u32 us_delay)508 u32 SI_Transfer(s32 chan,void *out,u32 out_len,void *in,u32 in_len,SICallback cb,u32 us_delay)
509 {
510 u32 ret = 0;
511 u32 level;
512 s64 diff;
513 u64 now,fire;
514 struct timespec tb;
515 _CPU_ISR_Disable(level);
516 if(sipacket[chan].chan==-1 && sicntrl.chan!=chan) {
517 ret = 1;
518 fire = now = gettime();
519 if(us_delay) fire = xferTime[chan]+microsecs_to_ticks(us_delay);
520 diff = (now - fire);
521 if(diff<0) {
522 tb.tv_sec = 0;
523 tb.tv_nsec = ticks_to_nanosecs((fire - now));
524 SYS_SetAlarm(si_alarm[chan],&tb,__si_alarmhandler,NULL);
525 } else if(__si_transfer(chan,out,out_len,in,in_len,cb)) {
526 _CPU_ISR_Restore(level);
527 return ret;
528 }
529 sipacket[chan].chan = chan;
530 sipacket[chan].out = out;
531 sipacket[chan].out_bytes = out_len;
532 sipacket[chan].in = in;
533 sipacket[chan].in_bytes = in_len;
534 sipacket[chan].callback = cb;
535 sipacket[chan].fire = fire;
536 }
537 _CPU_ISR_Restore(level);
538 return ret;
539 }
540
SI_GetType(s32 chan)541 u32 SI_GetType(s32 chan)
542 {
543 u32 level,type;
544 u64 now;
545 s64 diff;
546 _CPU_ISR_Disable(level);
547 now = gettime();
548 type = si_type[chan];
549 diff = (now - typeTime[chan]);
550 if(sicntrl.poll&(0x80>>chan)) {
551 if(type!=SI_ERROR_NO_RESPONSE) {
552 typeTime[chan] = gettime();
553 _CPU_ISR_Restore(level);
554 return type;
555 }
556 si_type[chan] = type = SI_ERR_BUSY;
557 } else if(diff==millisecs_to_ticks(50) && type!=SI_ERROR_NO_RESPONSE) {
558 _CPU_ISR_Restore(level);
559 return type;
560 } else if(diff==millisecs_to_ticks(75)) si_type[chan] = SI_ERR_BUSY;
561 else si_type[chan] = type = SI_ERR_BUSY;
562
563 typeTime[chan] = gettime();
564
565 SI_Transfer(chan,&cmdtypeandstatus$223,1,&si_type[chan],3,__si_gettypecallback,65);
566 _CPU_ISR_Restore(level);
567
568 return type;
569 }
570
SI_GetTypeAsync(s32 chan,SICallback cb)571 u32 SI_GetTypeAsync(s32 chan,SICallback cb)
572 {
573 u32 level;
574 u32 type,i;
575 _CPU_ISR_Disable(level);
576 type = SI_GetType(chan);
577 if(si_type[chan]&SI_ERR_BUSY) {
578 i=0;
579 for(i=0;i<4;i++) {
580 if(!typeCallback[chan][i] && typeCallback[chan][i]!=cb) {
581 typeCallback[chan][i] = cb;
582 break;
583 }
584 }
585 _CPU_ISR_Restore(level);
586 return type;
587 }
588
589 cb(chan,type);
590 _CPU_ISR_Restore(level);
591 return type;
592 }
593
SI_TransferCommands()594 void SI_TransferCommands()
595 {
596 _siReg[14] = 0x80000000;
597 }
598
SI_RegisterPollingHandler(RDSTHandler handler)599 u32 SI_RegisterPollingHandler(RDSTHandler handler)
600 {
601 u32 level,i;
602
603 _CPU_ISR_Disable(level);
604
605 i = 0;
606 for(i=0;i<4;i++) {
607 if(rdstHandlers[i]==handler) {
608 _CPU_ISR_Restore(level);
609 return 1;
610 }
611 }
612
613 for(i=0;i<4;i++) {
614 if(rdstHandlers[i]==NULL) {
615 rdstHandlers[i] = handler;
616 SI_EnablePollingInterrupt(TRUE);
617 _CPU_ISR_Restore(level);
618 return 1;
619 }
620 }
621
622 _CPU_ISR_Restore(level);
623 return 0;
624 }
625
SI_UnregisterPollingHandler(RDSTHandler handler)626 u32 SI_UnregisterPollingHandler(RDSTHandler handler)
627 {
628 u32 level,i;
629
630 _CPU_ISR_Disable(level);
631 for(i=0;i<4;i++) {
632 if(rdstHandlers[i]==handler) {
633 rdstHandlers[i] = NULL;
634 for(i=0;i<4;i++) {
635 if(rdstHandlers[i]!=NULL) break;
636 }
637 if(i>=4) SI_EnablePollingInterrupt(FALSE);
638
639 _CPU_ISR_Restore(level);
640 return 1;
641 }
642 }
643 _CPU_ISR_Restore(level);
644 return 0;
645 }
646
SI_EnablePollingInterrupt(s32 enable)647 u32 SI_EnablePollingInterrupt(s32 enable)
648 {
649 sicomcsr csr;
650 u32 level,ret,i;
651
652 _CPU_ISR_Disable(level);
653
654 ret = 0;
655 csr.val = _siReg[13];
656 if(csr.csrmap.rdstintmsk) ret = 1;
657
658 if(enable) {
659 csr.csrmap.rdstintmsk = 1;
660 for(i=0;i<4;i++) inputBufferVCount[i] = 0;
661 } else
662 csr.csrmap.rdstintmsk = 0;
663
664 csr.val &= 0x7ffffffe;
665 _siReg[13] = csr.val;
666
667 _CPU_ISR_Restore(level);
668 return ret;
669 }
670
__si_init()671 void __si_init()
672 {
673 u32 i;
674 for(i=0;i<4;i++) {
675 sipacket[i].chan = -1;
676 SYS_CreateAlarm(&si_alarm[i]);
677 }
678 sicntrl.poll = 0;
679
680 SI_SetSamplingRate(0);
681 while(_siReg[13]&0x0001);
682 _siReg[13] = 0x80000000;
683
684 _siReg[15] &= ~0x80000000; // permit exi clock to be set to 32MHz
685
686 IRQ_Request(IRQ_PI_SI,__si_interrupthandler,NULL);
687 __UnmaskIrq(IRQMASK(IRQ_PI_SI));
688
689 SI_GetType(0);
690 SI_GetType(1);
691 SI_GetType(2);
692 SI_GetType(3);
693 }
694