PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
padPortOpen.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007 Lukasz Bruun <mail@lukasz.dk>
3 *
4 * See the file LICENSE included with this distribution for licensing terms.
5 */
6
12#include "types.h"
13#include "freepad.h"
14#include "stdio.h"
15#include "thevent.h"
16#include "thbase.h"
17#include "sio2Cmds.h"
18#include "padCmds.h"
19#include "padData.h"
20
21// Global variables
22extern padState_t padState[2][4];
23extern u32 openSlots[2];
24
25extern int thpri_lo;
26extern int thpri_hi;
27
28extern int padman_init;
29
30static void UpdatePadThread(void *arg)
31{
32 iop_thread_info_t tstatus;
33 padState_t *pstate;
34 u32 res = 0;
35
36 (void)arg;
37
38 ReferThreadStatus(TH_SELF, &tstatus);
39 pstate = (padState_t*)tstatus.option;
40
41 while(1)
42 {
43 WaitClearEvent(pstate->eventflag, EF_UPDATE_PAD, WEF_AND|WEF_CLEAR, NULL);
44
45 // Check if able to read button data from pad
46 if( ReadData(pstate) == 1)
47 {
48 res = 0;
49
50 if( (pstate->outbuffer[2] != 0x5a) || ( pstate->outbuffer[1] != pstate->modeCurId) || (pstate->outbuffer[1] == 0xf3) )
51 {
52 pstate->buttonDataReady = 0;
53 pstate->state = PAD_STATE_EXECCMD ;
54 pstate->currentTask = TASK_QUERY_PAD;
55 StartThread(pstate->querypadTid, NULL);
56 }
57 else
58 {
59 u32 i;
60
61 for(i=0; i < 32; i++)
62 pstate->buttonStatus[i] = pstate->outbuffer[i];
63
64 pstate->buttonDataReady = 1;
65
66 if(pstate->modeConfig == MODE_CONFIG_QUERY_PAD)
67 pstate->state = PAD_STATE_FINDCTP1;
68 else
69 pstate->state = PAD_STATE_STABLE ;
70
71 if( (pstate->reqState == PAD_RSTAT_BUSY) && (pstate->runTask == TASK_NONE))
72 pstate->reqState = PAD_RSTAT_COMPLETE;
73 }
74 }
75 else
76 {
77 pstate->buttonDataReady = 0;
78 pstate->state = PAD_STATE_ERROR;
79 pstate->findPadRetries++;
80
81 res += pdGetError( pstate->port, pstate->slot );
82
83 if(res >= 10)
84 {
85 pstate->currentTask = TASK_QUERY_PAD;
86 StartThread(pstate->querypadTid, NULL);
87 }
88 }
89 }
90}
91
92static void QueryPadThread(void *arg)
93{
95 padState_t *pstate;
96 u32 i;
97 u8 count;
98 u32 res;
99 u32 modeCurId = 0xFF;
100
101 (void)arg;
102
103 ReferThreadStatus(TH_SELF, &tinfo);
104
105 pstate = (padState_t*)tinfo.option;
106
107 pstate->modeConfig = 0;
108 pstate->modeCurId = 0;
109 pstate->model = 0;
110 pstate->numModes = 0;
111 pstate->numActuators = 0;
112 pstate->numActComb = 0;
113
114 for(i=0; i < 4; i++)
115 {
116 pstate->buttonInfo[i] = 0;
117 pstate->buttonMask[i] = 0;
118 }
119
120 pstate->buttonDataReady = 0;
121 pstate->ee_actDirectSize = 0;
122 pstate->findPadRetries = 0;
123 pstate->modeCurId = 0;
124
125
126 D_PRINTF("QueryPadThread: Checking for pad (%i,%i)\n", pstate->port, pstate->slot);
127
128 do
129 {
130 WaitClearEvent( pstate->eventflag, EF_QUERY_PAD, WEF_AND|WEF_CLEAR, NULL);
131
132 res = PadIsSupported(pstate);
133
134 if(res == 1)
135 {
136 if(pstate->modeCurId != 0xFF)
137 {
138 modeCurId = pstate->modeCurId;
139 pstate->modeCurId = 0;
140 pstate->state = PAD_STATE_EXECCMD;
141 }
142 else
143 {
144 pstate->state = PAD_STATE_DISCONN;
145 pstate->disconnected = 1;
146 }
147 }
148 else
149 {
150 pstate->state = PAD_STATE_DISCONN;
151 pstate->disconnected = 1;
152 }
153 }
154 while( (res != 1) || (pstate->modeCurId == 0xFF) );
155
156
157 if(pstate->disconnected != 0)
158 {
159 for(i=0; i < 6; i++)
160 pstate->ee_actAlignData.data[i] = 0xFF;
161 }
162
163 D_PRINTF("Found pad (%i,%i) - modeCurId: 0x%x\n", (int)pstate->port, (int)pstate->slot, (int)modeCurId);
164
165 res = 0;
166
167 for(i=0; (i < 10) && (res != 1); i++)
168 {
169 WaitClearEvent( pstate->eventflag, EF_QUERY_PAD, WEF_AND|WEF_CLEAR, NULL);
170
171 res = EnterConfigMode(modeCurId, pstate);
172
173 if(res == 1) pstate->modeConfig = MODE_CONFIG_READY;
174 }
175
176 if( res != 1 )
177 {
178 D_PRINTF("EnterConfigMode (%i, %i): Failed\n", (int)pstate->port, (int)pstate->slot);
179
180 pstate->modeConfig = MODE_CONFIG_QUERY_PAD;
181 pstate->modeCurId = modeCurId;
182 pstate->currentTask = TASK_UPDATE_PAD;
183
184 ExitThread();
185 }
186
187 D_PRINTF("EnterConfigMode (%i, %i): Success\n", (int)pstate->port, (int)pstate->slot);
188
189 for(i=0,res=0; res != 1; i++)
190 {
191 WaitClearEvent( pstate->eventflag, EF_QUERY_PAD, WEF_AND|WEF_CLEAR, NULL);
192 res = QueryModel(pstate);
193
194 if((res != 1) && (i >= 10))
195 {
196 D_PRINTF("QueryModel (%i, %i): Failed\n",(int)pstate->port, (int)pstate->slot);
197
198 pstate->modeCurId = 0;
199 pstate->currentTask = TASK_UPDATE_PAD;
200 ExitThread();
201 }
202 }
203
204 D_PRINTF("QueryModel (%i, %i): Success\n", (int)pstate->port, (int)pstate->slot);
205
206 if( (pstate->disconnected == 1) && (pstate->modeCurOffs != 0))
207 {
208 pstate->mode = 0;
209 pstate->lock = 0;
210
211 for(i=0,res=0; res != 1; i++)
212 {
213 WaitClearEvent( pstate->eventflag, EF_QUERY_PAD, WEF_AND|WEF_CLEAR, NULL);
214
215 res = SetMainMode(pstate);
216
217 if(res == 1)
218 {
219 D_PRINTF("SetMainMode (%i,%i): Success\n", (int)pstate->port, (int)pstate->slot);
220 D_PRINTF("QueryPadThread: Done (%i,%i)\n", (int)pstate->port, (int)pstate->slot);
221
222 pstate->modeCurId = 0;
223 pstate->currentTask = TASK_UPDATE_PAD;
224 pstate->disconnected = 0;
225 ExitThread();
226 }
227 else
228 {
229 if(i >= 10)
230 {
231 D_PRINTF("SetMainMode (%i, %i): Failed\n", (int)pstate->port, (int)pstate->slot);
232
233 pstate->reqState = PAD_RSTAT_FAILED;
234 pstate->currentTask = TASK_UPDATE_PAD;
235 ExitThread();
236 }
237 }
238 }
239 }
240
241 for(count=0; count < pstate->numActuators; count++)
242 {
243 for(i=0,res=0; res != 1; i++)
244 {
245 WaitClearEvent( pstate->eventflag, EF_QUERY_PAD, WEF_AND|WEF_CLEAR, NULL);
246
247 res = QueryAct(count, pstate);
248
249 if((res != 1) && (i >= 10))
250 {
251 D_PRINTF("QueryAct (%i,%i): Failed\n", (int)pstate->port, (int)pstate->slot);
252
253 pstate->modeCurId = 0;
254 pstate->currentTask = TASK_UPDATE_PAD;
255 ExitThread();
256 }
257 }
258 }
259
260 D_PRINTF("QueryAct (%i,%i): Success\n", (int)pstate->port, (int)pstate->slot);
261
262 for(count=0; count < pstate->numActComb; count++)
263 {
264 for(i=0,res=0; res != 1; i++)
265 {
266 WaitClearEvent( pstate->eventflag, EF_QUERY_PAD, WEF_AND|WEF_CLEAR, NULL);
267
268 res = QueryComb(count, pstate);
269
270 if((res != 1) && (i >= 10))
271 {
272 D_PRINTF("QueryComb (%i,%i): Failed\n", (int)pstate->port, (int)pstate->slot);
273
274 pstate->modeCurId = 0;
275 pstate->currentTask = TASK_UPDATE_PAD;
276 ExitThread();
277 }
278 }
279 }
280
281 D_PRINTF("QueryComb (%i,%i): Success\n", (int)pstate->port, (int)pstate->slot);
282
283 for(count=0; count < pstate->numModes; count++)
284 {
285 for(i=0,res=0; res != 1; i++)
286 {
287 WaitClearEvent( pstate->eventflag, EF_QUERY_PAD, WEF_AND|WEF_CLEAR, NULL);
288
289 res = QueryMode(count, pstate);
290
291 if((res != 1) && (i >= 10))
292 {
293 D_PRINTF("QueryMode (%i,%i): Failed\n", (int)pstate->port, (int)pstate->slot);
294
295 pstate->modeCurId = 0;
296 pstate->currentTask = TASK_UPDATE_PAD;
297 ExitThread();
298 }
299 }
300 }
301
302 D_PRINTF("QueryMode (%i,%i): Success\n", (int)pstate->port, (int)pstate->slot);
303
304 for(i=0,res=0; res != 1; i++)
305 {
306 WaitClearEvent( pstate->eventflag, EF_QUERY_PAD, WEF_AND|WEF_CLEAR, NULL);
307
308 res = SetActAlign(pstate);
309
310 if((res != 1) && (i >= 10))
311 {
312 D_PRINTF("SetActAlign (%i,%i): Failed\n", (int)pstate->port, (int)pstate->slot);
313
314 pstate->reqState = PAD_RSTAT_FAILED;
315 pstate->currentTask = TASK_UPDATE_PAD;
316 ExitThread();
317 }
318 }
319
320 D_PRINTF("SetActAlign (%i,%i): Success\n", (int)pstate->port, (int)pstate->slot);
321
322 if(((pstate->modeConfig & 0xFF) == 0x02) &&
323 ((pstate->model & 0x02) == 0x02))
324 {
325 for(i=0,res=0; res != 1; i++)
326 {
327 WaitClearEvent( pstate->eventflag, EF_QUERY_PAD, WEF_AND|WEF_CLEAR, NULL);
328
329 res = QueryButtonMask(pstate);
330
331 if((res != 1) && (i >= 10))
332 {
333 D_PRINTF("QueryButtonMask (%i,%i): Failed\n", (int)pstate->port, (int)pstate->slot);
334
335 pstate->modeCurId = 0;
336 pstate->currentTask = TASK_UPDATE_PAD;
337 ExitThread();
338 }
339 }
340
341 D_PRINTF("QueryButtonMask (%i,%i): Success\n", (int)pstate->port, (int)pstate->slot);
342 }
343
344 for(i=0,res=0; res != 1; i++)
345 {
346 WaitClearEvent( pstate->eventflag, EF_QUERY_PAD, WEF_AND|WEF_CLEAR, NULL);
347
348 res = ExitConfigMode(pstate);
349
350 if((res != 1) && (i >= 10))
351 {
352 D_PRINTF("ExitConfigMode (%i,%i): Failed\n", (int)pstate->port, (int)pstate->slot);
353
354 pstate->modeCurId = 0;
355 pstate->currentTask = TASK_UPDATE_PAD;
356 ExitThread();
357 }
358 }
359
360 D_PRINTF("ExitConfigMode (%i,%i): Success\n", (int)pstate->port, (int)pstate->slot);
361
362 for(i=0,res=0; res != 1; i++)
363 {
364 WaitClearEvent( pstate->eventflag, EF_QUERY_PAD, WEF_AND|WEF_CLEAR, NULL);
365
366 res = PadIsSupported(pstate);
367
368 if((res != 1) && (i >= 10))
369 {
370 D_PRINTF("PadIsSupported (%i,%i): Failed\n", (int)pstate->port, (int)pstate->slot);
371
372 pstate->modeCurId = 0;
373 pstate->currentTask = TASK_UPDATE_PAD;
374 ExitThread();
375 }
376 }
377
378 D_PRINTF("PadIsSupported (%i,%i): Success\n", (int)pstate->port, (int)pstate->slot);
379
380 D_PRINTF("QueryPadThread: Done (%i,%i)\n", (int)pstate->port, (int)pstate->slot);
381
382 modeCurId = pstate->modeCurId;
383 pstate->state = PAD_STATE_EXECCMD;
384 pstate->modeCurId = 0;
385 pstate->currentTask = TASK_UPDATE_PAD;
386 pstate->disconnected = 0;
387 pstate->modeCurId = modeCurId; //Weird, but this was how it was done.
388
389 ExitThread();
390}
391
392static void SetMainModeThread(void *arg)
393{
394 u32 i, res;
395 iop_thread_info_t tinfo;
396 padState_t *pstate;
397
398 (void)arg;
399
400 ReferThreadStatus(TH_SELF, &tinfo);
401
402 pstate = (padState_t*)tinfo.option;
403
404 pstate->buttonDataReady = 0;
405 pstate->state = PAD_STATE_EXECCMD;
406
407 for(i=0,res=0; res != 1; i++)
408 {
409 WaitClearEvent( pstate->eventflag, EF_SET_MAIN_MODE, WEF_AND|WEF_CLEAR, NULL);
410
411 res = EnterConfigMode(pstate->modeCurId, pstate);
412
413 if((res != 1) && (i >= 10))
414 {
415 pstate->reqState = PAD_RSTAT_FAILED;
416 pstate->currentTask = TASK_UPDATE_PAD;
417 ExitThread();
418 }
419 }
420
421 for(i=0,res=0; res != 1; i++)
422 {
423 WaitClearEvent( pstate->eventflag, EF_SET_MAIN_MODE, WEF_AND|WEF_CLEAR, NULL);
424
425 res = SetMainMode( pstate);
426
427 if((res != 1) && (i >= 10))
428 {
429 pstate->reqState = PAD_RSTAT_FAILED;
430 pstate->currentTask = TASK_UPDATE_PAD;
431 ExitThread();
432 }
433 }
434
435 for(i=0,res=0; res != 1; i++)
436 {
437 WaitClearEvent( pstate->eventflag, EF_SET_MAIN_MODE, WEF_AND|WEF_CLEAR, NULL);
438
439 res = ExitConfigMode(pstate);
440
441 if((res != 1) && (i >= 10))
442 {
443 pstate->reqState = PAD_RSTAT_FAILED;
444 pstate->currentTask = TASK_UPDATE_PAD;
445 ExitThread();
446 }
447 }
448
449 pstate->currentTask = TASK_UPDATE_PAD;
450 ExitThread();
451
452}
453
454void SetActAlignThread(void *arg)
455{
456 u32 i, res;
457 iop_thread_info_t tinfo;
458 padState_t *pstate;
459
460 (void)arg;
461
462 ReferThreadStatus(TH_SELF, &tinfo);
463
464 pstate = (padState_t*)tinfo.option;
465
466 pstate->buttonDataReady = 0;
467 pstate->state = PAD_STATE_EXECCMD;
468
469 for(i=0,res=0; res != 1; i++)
470 {
471 WaitClearEvent( pstate->eventflag, EF_SET_ACT_ALIGN, WEF_AND|WEF_CLEAR, NULL);
472
473 res = EnterConfigMode(pstate->modeCurId, pstate);
474
475 if((res != 1) && (i >= 10))
476 {
477 pstate->reqState = PAD_RSTAT_FAILED;
478 pstate->currentTask = TASK_UPDATE_PAD;
479 ExitThread();
480 }
481 }
482
483 for(i=0,res=0; res != 1; i++)
484 {
485 WaitClearEvent( pstate->eventflag, EF_SET_ACT_ALIGN, WEF_AND|WEF_CLEAR, NULL);
486
487 res = SetActAlign(pstate);
488
489 if((res != 1) && (i >= 10))
490 {
491 pstate->reqState = PAD_RSTAT_FAILED;
492 pstate->currentTask = TASK_UPDATE_PAD;
493 ExitThread();
494 }
495 }
496
497 for(i=0,res=0; res != 1; i++)
498 {
499 WaitClearEvent( pstate->eventflag, EF_SET_ACT_ALIGN, WEF_AND|WEF_CLEAR, NULL);
500
501 res = ExitConfigMode(pstate);
502
503 if((res != 1) && (i >= 10))
504 {
505 pstate->reqState = PAD_RSTAT_FAILED;
506 pstate->currentTask = TASK_UPDATE_PAD;
507 ExitThread();
508 }
509 }
510
511 pstate->currentTask = TASK_UPDATE_PAD;
512
513 ExitThread();
514}
515
516static void SetButtonInfoThread(void *arg)
517{
518 int i, res;
519 u32 val;
520 iop_thread_info_t tinfo;
521 padState_t *pstate;
522
523 (void)arg;
524
525 ReferThreadStatus(TH_SELF, &tinfo);
526
527 pstate = (padState_t*)tinfo.option;
528
529 pstate->buttonDataReady = 0;
530 pstate->state = PAD_STATE_EXECCMD;
531
532 for(i=0,res=0; res != 1; i++)
533 {
534 WaitClearEvent( pstate->eventflag, EF_SET_SET_BUTTON_INFO, WEF_AND|WEF_CLEAR, NULL);
535
536 res = EnterConfigMode(pstate->modeCurId, pstate);
537
538 if((res != 1) && (i >= 10))
539 {
540 pstate->reqState = PAD_RSTAT_FAILED;
541 pstate->currentTask = TASK_UPDATE_PAD;
542 ExitThread();
543 }
544 }
545
546 for(i=0,res=0; res != 1; i++)
547 {
548 WaitClearEvent( pstate->eventflag, EF_SET_SET_BUTTON_INFO, WEF_AND|WEF_CLEAR, NULL);
549
550 res = SetButtonInfo(pstate);
551
552 if((res != 1) && (i >= 10))
553 {
554 pstate->reqState = PAD_RSTAT_FAILED;
555 pstate->currentTask = TASK_UPDATE_PAD;
556 ExitThread();
557 }
558 }
559
560 for(val = 0; val < 12; val++)
561 {
562 for(i=0,res=0; res != 1; i++)
563 {
564 WaitClearEvent( pstate->eventflag, EF_SET_SET_BUTTON_INFO, WEF_AND|WEF_CLEAR, NULL);
565
566 res = VrefParam(val, pstate);
567
568 if((res != 1) && (i >= 10))
569 {
570 pstate->reqState = PAD_RSTAT_FAILED;
571 pstate->currentTask = TASK_UPDATE_PAD;
572 ExitThread();
573 }
574 }
575 }
576
577 for(i=0,res=0; res != 1; i++)
578 {
579 WaitClearEvent( pstate->eventflag, EF_SET_SET_BUTTON_INFO, WEF_AND|WEF_CLEAR, NULL);
580
581 res = ExitConfigMode(pstate);
582
583 if((res != 1) && (i >= 10))
584 {
585 pstate->reqState = PAD_RSTAT_FAILED;
586 pstate->currentTask = TASK_UPDATE_PAD;
587 ExitThread();
588 }
589 }
590
591 pstate->val_c6 = 1;
592 pstate->currentTask = TASK_UPDATE_PAD;
593 ExitThread();
594}
595
596static void SetVrefParamThread(void *arg)
597{
598 int i, res;
599 u32 val;
600 iop_thread_info_t tinfo;
601 padState_t *pstate;
602
603 (void)arg;
604
605 ReferThreadStatus(TH_SELF, &tinfo);
606
607 pstate = (padState_t*)tinfo.option;
608
609 pstate->buttonDataReady = 0;
610 pstate->state = PAD_STATE_EXECCMD;
611
612 for(i=0,res=0; res != 1; i++)
613 {
614 WaitClearEvent( pstate->eventflag, EF_SET_VREF_PARAM, WEF_AND|WEF_CLEAR, NULL);
615
616 res = EnterConfigMode(pstate->modeCurId, pstate);
617
618 if((res != 1) && (i >= 10))
619 {
620 pstate->reqState = PAD_RSTAT_FAILED;
621 pstate->currentTask = TASK_UPDATE_PAD;
622 ExitThread();
623 }
624 }
625
626 for(val = 0; val < 12; val++)
627 {
628 for(i=0,res=0; res != 1; i++)
629 {
630 WaitClearEvent( pstate->eventflag, EF_SET_VREF_PARAM, WEF_AND|WEF_CLEAR, NULL);
631
632 res = VrefParam(val, pstate);
633
634 if((res != 1) && (i >= 10))
635 {
636 pstate->reqState = PAD_RSTAT_FAILED;
637 pstate->currentTask = TASK_UPDATE_PAD;
638 ExitThread();
639 }
640 }
641 }
642
643 for(i=0,res=0; res != 1; i++)
644 {
645 WaitClearEvent( pstate->eventflag, EF_SET_VREF_PARAM, WEF_AND|WEF_CLEAR, NULL);
646
647 res = ExitConfigMode( pstate);
648
649 if((res != 1) && (i >= 10))
650 {
651 pstate->reqState = PAD_RSTAT_FAILED;
652 pstate->currentTask = TASK_UPDATE_PAD;
653 ExitThread();
654 }
655 }
656
657 pstate->currentTask = TASK_UPDATE_PAD;
658
659 ExitThread();
660}
661
662s32 padPortOpen(s32 port, s32 slot, s32 pad_area_ee_addr, u32 *buf)
663{
666
667 (void)buf;
668
669 if(port >= 2)
670 {
671 M_PRINTF("Invalid port number: %d\n", (int)port);
672 return 0;
673 }
674
675#ifdef BUILDING_XPADMAN
676 if(slot >= 4)
677#else
678 if(slot >= 1)
679#endif
680 {
681 M_PRINTF("Invalid slot number: %d\n", (int)port);
682 return 0;
683 }
684
685 if (padman_init == 0)
686 {
687 padInit(NULL);
688 }
689
690 if( (openSlots[port] >> slot) & 0x1)
691 {
692 M_PRINTF("The slot will be refreshed: (%d, %d)\n", (int)port, (int)slot);
693 padPortClose(port, slot, 1);
694 }
695
696 padState[port][slot].port = port;
697 padState[port][slot].slot = slot;
698
699 openSlots[port] |= 1 << slot;
700
701 padState[port][slot].state = PAD_STATE_EXECCMD;
702 padState[port][slot].modeCurId = 0;
703 padState[port][slot].reqState = PAD_RSTAT_COMPLETE;
704 padState[port][slot].frame = 0;
705 padState[port][slot].padarea_ee_addr = pad_area_ee_addr;
706 padState[port][slot].buttonDataReady = 0;
707 padState[port][slot].ee_actDirectSize = 0;
708 padState[port][slot].val_c6 = 0;
709 padState[port][slot].currentTask = TASK_NONE;
710 padState[port][slot].runTask = TASK_NONE;
711 padState[port][slot].val_184 = 0;
712
713 padState[port][slot].disconnected = 1;
714 padState[port][slot].stat70bit = 0;
715
716 event.attr = EA_MULTI;
717 event.bits = 0;
718
719 if((padState[port][slot].eventflag = CreateEventFlag(&event)) == 0)
720 {
721 M_PRINTF("Port open failed (CreateEventFlag).\n");
722 return 0;
723 }
724
725
726 // Create UpdatePadThread
727 thread.attr = TH_C;
728 thread.option = (u32)&padState[port][slot];
729 thread.thread = &UpdatePadThread;
730 thread.stacksize = 0x600;
731 thread.priority = thpri_lo;
732
733 padState[port][slot].updatepadTid = CreateThread(&thread);
734
735 if(padState[port][slot].updatepadTid == 0)
736 {
737 M_PRINTF("Port open failed (CreateThread UpdatePadThread).\n");
738 return 0;
739 }
740
741 // Create QueryPadThread
742 thread.attr = TH_C;
743 thread.option = (u32)&padState[port][slot];
744 thread.thread = &QueryPadThread;
745 thread.stacksize = 0x600;
746 thread.priority = thpri_lo;
747
748 padState[port][slot].querypadTid = CreateThread(&thread);
749
750 if(padState[port][slot].querypadTid == 0)
751 {
752 M_PRINTF("Port open failed (CreateThread QueryPadThread).\n");
753 return 0;
754 }
755
756 // Create SetMainModeThread
757 thread.attr = TH_C;
758 thread.option = (u32)&padState[port][slot];
759 thread.thread = &SetMainModeThread;
760 thread.stacksize = 0x400;
761 thread.priority = thpri_lo;
762
763 padState[port][slot].setmainmodeTid = CreateThread(&thread);
764
765 if(padState[port][slot].setmainmodeTid == 0)
766 {
767 M_PRINTF("Port open failed (CreateThread SetMainModeThread)\n.");
768 return 0;
769 }
770
771 // Create SetActAlignThread
772 thread.attr = TH_C;
773 thread.option = (u32)&padState[port][slot];
774 thread.thread = &SetActAlignThread;
775 thread.stacksize = 0x400;
776 thread.priority = thpri_lo;
777
778 padState[port][slot].setactalignTid = CreateThread(&thread);
779
780 if(padState[port][slot].setactalignTid == 0)
781 {
782 M_PRINTF("Port open failed (CreateThread SetActAlignThread).\n");
783 return 0;
784 }
785
786 // Create SetButtonInfoThread
787 thread.attr = TH_C;
788 thread.option = (u32)&padState[port][slot];
789 thread.thread = &SetButtonInfoThread;
790 thread.stacksize = 0x400;
791 thread.priority = thpri_lo;
792
793 padState[port][slot].setbuttoninfoTid = CreateThread(&thread);
794
795 if(padState[port][slot].setbuttoninfoTid == 0)
796 {
797 M_PRINTF("Port open failed (CreateThread SetButtonInfoThread).\n");
798 return 0;
799 }
800
801 // Create SetVrefParamThread
802 thread.attr = TH_C;
803 thread.option = (u32)&padState[port][slot];
804 thread.thread = &SetVrefParamThread;
805 thread.stacksize = 0x400;
806 thread.priority = thpri_lo;
807
808 padState[port][slot].setvrefparamTid = CreateThread(&thread);
809
810 if(padState[port][slot].setvrefparamTid == 0)
811 {
812 M_PRINTF("Port open failed (CreateThread SetVrefParamThread).\n");
813 return 0;
814 }
815
816 if(padState[port][slot].currentTask < TASK_QUERY_PAD)
817 {
818 StartThread(padState[port][slot].updatepadTid, NULL);
819 padState[port][slot].currentTask = TASK_UPDATE_PAD;
820 }
821 else
822 {
823 M_PRINTF("Port open failed, busy.\n");
824 return 0;
825 }
826
827 return 1;
828}
#define TH_SELF
Definition kernel.h:67
int padPortOpen(int port, int slot, void *padArea)
Definition libpad.c:394
int padInit(int mode)
Definition libpad.c:297
int padPortClose(int port, int slot)
Definition libpad.c:451
#define EA_MULTI
Definition thevent.h:35
u32 count
start sector of fragmented bd/file