PS2SDK
PS2 Homebrew Libraries
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
22 extern padState_t padState[2][4];
23 extern u32 openSlots[2];
24 
25 extern int thpri_lo;
26 extern int thpri_hi;
27 
28 extern int padman_init;
29 
30 static 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 
92 static 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 
392 static void SetMainModeThread(void *arg)
393 {
394  u32 i, res;
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 
454 void SetActAlignThread(void *arg)
455 {
456  u32 i, res;
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 
516 static void SetButtonInfoThread(void *arg)
517 {
518  int i, res;
519  u32 val;
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 
596 static void SetVrefParamThread(void *arg)
597 {
598  int i, res;
599  u32 val;
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 
662 s32 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 }
thbase.h
padPortClose
int padPortClose(int port, int slot)
Definition: libpad.c:574
TH_SELF
#define TH_SELF
Definition: kernel.h:68
EA_MULTI
#define EA_MULTI
Definition: thevent.h:35
padState_t
Definition: freepad.h:158
thread
Definition: thcommon.h:143
event
Definition: thcommon.h:71
padInit
int padInit(int mode)
Definition: libpad.c:300
count
u32 count
start sector of fragmented bd/file
Definition: usbhdfsd-common.h:3
padPortOpen
int padPortOpen(int port, int slot, void *padArea)
Definition: libpad.c:462
tinfo
Definition: tty.c:47
stdio.h
_iop_thread
Definition: thbase.h:39
freepad.h
padCmds.h
padData.h
iop_event_t
Definition: thevent.h:37
thevent.h
sio2Cmds.h
_iop_thread_status
Definition: thbase.h:68