1 /*---------------------------------------------------------------------------*
2 Project: Revolution PMIC simple demo
3 File: pmic_simple.c
4
5 Copyright (C)2008 Nintendo All Rights Reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Log: pmic_simple.c,v $
14 Revision 1.5.2.3 2009/12/14 00:21:52 aka
15 Fixed misspelling.
16
17 Revision 1.5.2.2 2009/11/19 07:30:49 aka
18 Copied from HEAD.
19
20 Revision 1.7 2009/11/19 07:28:06 aka
21 Removed WPADShutdown() & WPADDisconnect().
22
23 Revision 1.6 2009/10/15 07:15:34 aka
24 Revised error handling of PMICQuit().
25
26 Revision 1.5 2009/04/17 06:34:21 ozeki_kohei
27 Correct behavior for the case that device is detached while PMICQuit().
28
29 Revision 1.4 2009/03/11 07:24:21 aka
30 Added SOUT meter.
31
32 Revision 1.1.4.2 2009/03/11 07:21:41 aka
33 Added SOUT meter.
34
35 Revision 1.1.4.1 2008/08/28 01:36:31 aka
36 Copied from HEAD.
37
38 Revision 1.3 2008/08/06 01:39:14 carlmu
39 Added graphic demo.
40
41 Revision 1.2 2008/08/04 23:52:55 carlmu
42 Simplified the demo state machine.
43 Added ability to exit the demo completely.
44
45 Revision 1.1 2008/01/22 02:50:19 aka
46 initial check-in.
47
48 $NoKeywords: $
49 *---------------------------------------------------------------------------*/
50
51 #include <string.h>
52 #include <demo.h>
53 #include <revolution/mem.h>
54 #include <revolution/pmic.h>
55 #include <revolution/wpad.h>
56
57 #include "audio.h"
58
59 #define SCREEN_WIDTH 320
60 #define SCREEN_HEIGHT 240
61
62 BOOL PMICIsUp( void );
63
64 static MEMHeapHandle mem2Heap;
65 static u16 button;
66
67 static void* myAlloc ( u32 size );
68 static u8 myFree ( void* ptr );
69 static BOOL usePMIC ( void );
70 static void printInfo ( void );
71 static void printLM ( void );
72
73 /*---------------------------------------------------------------------------*
74 Name: main
75
76 Description: main func.
77
78 Arguments: none.
79
80 Returns: none.
81 *---------------------------------------------------------------------------*/
82
main(void)83 void main(void)
84 {
85 void* arenaMem2Lo;
86 void* arenaMem2Hi;
87 s32 status;
88 u32 type;
89 WPADStatus currWpad;
90 WPADStatus prevWpad;
91 BOOL running = TRUE;
92
93 // init DEMO lib.
94 DEMOInit(&GXNtsc480IntDf);
95 DEMOInitCaption(DM_FT_XLU, SCREEN_WIDTH, SCREEN_HEIGHT);
96 DEMOPadInit();
97
98 // init MEM lib.
99 arenaMem2Lo = OSGetMEM2ArenaLo();
100 arenaMem2Hi = OSGetMEM2ArenaHi();
101 mem2Heap = MEMCreateExpHeap(arenaMem2Lo, (u32)arenaMem2Hi - (u32) arenaMem2Lo);
102
103 // init Audio libs.
104 AUDIOInit(&mem2Heap, NULL); // NULL means use default processing function
105
106 // init WPAD.
107 WPADRegisterAllocator(myAlloc, myFree);
108 WPADInit();
109
110 OSReport ("\n\n");
111 OSReport ("************************************************\n");
112 OSReport ("pmic_simple: Simple demo for Party Mic device\n");
113 OSReport ("************************************************\n");
114 OSReport ("This demo requires the Party Mic and a Wii Remote.\n");
115 OSReport ("Push Button A to start recording, speak,\n");
116 OSReport ("then push button A again to hear results.\n");
117 OSReport ("See messages for other instructions.\n");
118 OSReport ("\n");
119
120 do
121 {
122 status = WPADGetStatus();
123
124 } while (WPAD_STATE_SETUP != status);
125
126 memset(&currWpad, 0, sizeof(WPADStatus));
127 memset(&prevWpad, 0, sizeof(WPADStatus));
128
129 // spin...
130 while (running)
131 {
132 // read Remote.
133 status = WPADProbe(WPAD_CHAN0, &type);
134
135 if (WPAD_ERR_NONE == status)
136 {
137 WPADRead(WPAD_CHAN0, &currWpad);
138 }
139
140 button = WPADButtonDown(prevWpad.button, currWpad.button);
141 prevWpad = currWpad;
142
143 // operate P-Mic.
144 running = usePMIC();
145
146 // print info & SOUT meter
147 DEMOBeforeRender();
148 printInfo();
149 printLM();
150 DEMODoneRender();
151 }
152
153 // Kill audio
154 AUDIOQuit();
155
156 OSHalt("Demo finished!\n");
157 }
158
159 /*---------------------------------------------------------------------------*
160 Name: myAlloc
161
162 Description: allocate memory.
163
164 Arguments: size bytes to allocate.
165
166 Returns: pointer.
167 *---------------------------------------------------------------------------*/
168
myAlloc(u32 size)169 static void* myAlloc(u32 size)
170 {
171 void *ptr;
172
173 ptr = MEMAllocFromExpHeap(mem2Heap, size);
174
175 return ptr;
176 }
177
178 /*---------------------------------------------------------------------------*
179 Name: myFree
180
181 Description: free memory.
182
183 Arguments: ptr pointer to free.
184
185 Returns: always 1.
186 *---------------------------------------------------------------------------*/
187
myFree(void * ptr)188 static u8 myFree(void* ptr)
189 {
190 MEMFreeToExpHeap(mem2Heap, ptr);
191
192 return 1;
193 }
194
195 /*---------------------------------------------------------------------------*
196 *---------------------------------------------------------------------------*
197 * very simple P-Mic operation... *
198 *---------------------------------------------------------------------------*
199 *---------------------------------------------------------------------------*/
200
201 enum
202 {
203 STATE_NOT_INITIALIZED=0,
204 STATE_NOT_READY,
205 STATE_PROBE,
206 STATE_OPEN,
207 STATE_WAIT_FOR_OPEN,
208 STATE_STOPPED,
209 STATE_START,
210 STATE_WAIT_FOR_START,
211 STATE_RUN,
212 STATE_DO_STOP,
213 STATE_WAIT_FOR_STOP,
214
215 STATE_CLOSE,
216 STATE_WAIT_FOR_CLOSE,
217 STATE_WAIT_REOPEN,
218 STATE_QUIT,
219 STATE_WAIT_RESTART,
220 STATE_DIE
221 };
222
223 static u32 state = STATE_NOT_INITIALIZED;
224
225 static volatile PMIC_ERR errCode;
226 static volatile BOOL gettingSout = FALSE;
227 static volatile u16 sout;
228
229 static void funcCb ( PMIC_ERR result, void* arg );
230 static void levelCb ( PMIC_ERR result, void* arg );
231
232 /*---------------------------------------------------------------------------*
233 Name: PMICIsUp
234
235 Description: Indicates if P-Mic library has been initialized
236
237 Arguments: none.
238
239 Returns: BOOL indicating whether P-Mic library has been initialized
240 *---------------------------------------------------------------------------*/
241
PMICIsUp(void)242 BOOL PMICIsUp(void)
243 {
244 if (state == STATE_NOT_INITIALIZED ||
245 state == STATE_QUIT ||
246 state == STATE_WAIT_RESTART)
247 {
248 return FALSE;
249 }
250
251 return TRUE;
252 }
253
254 /*---------------------------------------------------------------------------*
255 Name: usePMIC
256
257 Description: operate P-Mic.
258
259 Arguments: none.
260
261 Returns: BOOL indicating whether to continue running or not.
262 *---------------------------------------------------------------------------*/
263
usePMIC(void)264 static BOOL usePMIC(void)
265 {
266 static s32 count = 0;
267 static u8* work;
268
269 PMIC_ERR retval;
270
271 switch (state)
272 {
273
274 case STATE_NOT_INITIALIZED:
275
276 work = MEMAllocFromExpHeapEx(mem2Heap, PMIC_MEM2_WORK, 32);
277 retval = PMICInit(work);
278
279 if (retval == PMIC_ERR_OK)
280 {
281 OSReport("(%ld) ok to call PMICInit() -> %ld\n", count++, retval);
282 state = STATE_NOT_READY;
283 }
284 else
285 {
286 OSReport("(%ld) fail to call PMICInit() -> %ld\n", count++, retval);
287 state = STATE_DIE; // fatal
288 }
289 break;
290
291 case STATE_NOT_READY:
292
293 state = STATE_PROBE;
294 break;
295
296 case STATE_PROBE:
297
298 retval = PMICProbe();
299
300 if (retval == PMIC_ERR_OK)
301 {
302 OSReport("(%ld) P-Mic is inserted -> %ld\n", count++, retval);
303 state = STATE_OPEN;
304 }
305 else if (retval != PMIC_ERR_NO_DEVICE)
306 {
307 OSReport("(%ld) fail to call PMICProbe() -> %ld\n", count++, retval);
308 state = STATE_DIE;
309 }
310 else if (button & WPAD_BUTTON_B)
311 {
312 state = STATE_QUIT;
313 }
314 break;
315
316 case STATE_OPEN:
317
318 errCode = (PMIC_ERR)(PMIC_ERR_OK + 1);
319 retval = PMICOpenAsync(funcCb, NULL);
320
321 if (retval == PMIC_ERR_OK)
322 {
323 OSReport("(%ld) ok to call PMICOpenAsync() -> %ld\n", count++, retval);
324 state = STATE_WAIT_FOR_OPEN;
325 }
326 else
327 {
328 OSReport("(%ld) fail to call PMICOpenAsync() -> %ld\n", count++, retval);
329 state = STATE_NOT_READY; // probe again
330 }
331 break;
332
333 case STATE_WAIT_FOR_OPEN:
334
335 // errCode comes from the PMICOpenAsync callback
336 if (errCode > PMIC_ERR_OK) { // still waiting?
337 break;
338 }
339 else if (errCode == PMIC_ERR_OK)
340 {
341 OSReport("(%ld) ok to open P-Mic -> %ld.\n", count++, errCode);
342 state = STATE_STOPPED;
343 }
344 else
345 {
346 OSReport("(%ld) fail to open P-Mic -> %ld.\n", count++, errCode);
347 state = STATE_NOT_READY; // probe again
348 }
349 break;
350
351 case STATE_STOPPED:
352
353 retval = PMICProbe();
354
355 if (retval == PMIC_ERR_NO_DEVICE)
356 {
357 OSReport("(%ld) P-Mic is removed -> %ld\n", count++, retval);
358 state = STATE_NOT_READY;
359 }
360 else if (retval != PMIC_ERR_OK)
361 {
362 OSReport("(%ld) fail to call PMICProbe() -> %ld\n", count++, retval);
363 state = STATE_DIE;
364 }
365 else if (button & WPAD_BUTTON_A)
366 {
367 AUDIOStopPlay(); // stop playing p-mic data
368 state = STATE_START;
369 }
370 else if (button & WPAD_BUTTON_B)
371 {
372 state = STATE_CLOSE;
373 }
374 break;
375
376 case STATE_START:
377
378 errCode = (PMIC_ERR)(PMIC_ERR_OK + 1);
379 retval = PMICStartAsync(funcCb, NULL);
380
381 if (retval == PMIC_ERR_OK)
382 {
383 OSReport("(%ld) ok to call PMICStartAsync() -> %ld\n", count++, retval);
384 state = STATE_WAIT_FOR_START;
385 }
386 else
387 {
388 OSReport("(%ld) fail to call PMICStartAsync() -> %ld\n", count++, retval);
389 state = STATE_NOT_READY;
390 }
391 break;
392
393 case STATE_WAIT_FOR_START:
394
395 // errCode is returned by PMICStartAsync callback
396 if (errCode > PMIC_ERR_OK)
397 {
398 // still waiting?
399 break;
400 }
401 else if (errCode == PMIC_ERR_OK)
402 {
403 OSReport("(%ld) ok to start P-Mic -> %ld.\n", count++, errCode);
404 state = STATE_RUN;
405 sout = 0;
406 }
407 else
408 {
409 OSReport("(%ld) fail to start P-Mic -> %ld.\n", count++, errCode);
410 state = STATE_NOT_READY;
411 }
412 break;
413
414 case STATE_RUN:
415
416 retval = PMICProbe();
417
418 if (retval == PMIC_ERR_NO_DEVICE)
419 {
420 OSReport("(%ld) P-Mic is removed -> %ld\n", count++, retval);
421 state = STATE_NOT_READY;
422 sout = 0;
423 }
424 else if (retval != PMIC_ERR_OK)
425 {
426 OSReport("(%ld) fail to call PMICProbe() -> %ld\n", count++, retval);
427 state = STATE_DIE;
428 sout = 0;
429 }
430 else if (button & WPAD_BUTTON_A)
431 {
432 AUDIOStartPlay(); // start playing p-mic data
433 state = STATE_DO_STOP;
434 sout = 0;
435 }
436 else if (button & WPAD_BUTTON_B)
437 {
438 state = STATE_CLOSE;
439 sout = 0;
440 }
441 else if (!gettingSout)
442 {
443 // get current sout level
444 retval = PMICGetLevelAsync(PMIC_LEVEL_SOUT, (u16*)&sout, levelCb, NULL);
445
446 if (retval == PMIC_ERR_OK)
447 {
448 gettingSout = TRUE;
449 }
450 }
451 break;
452
453 case STATE_DO_STOP:
454
455 errCode = (PMIC_ERR)(PMIC_ERR_OK + 1);
456 retval = PMICStopAsync(funcCb, NULL);
457
458 if (retval == PMIC_ERR_OK)
459 {
460 OSReport("(%ld) ok to call PMICStopAsync() -> %ld\n", count++, retval);
461 state = STATE_WAIT_FOR_STOP;
462 }
463 else
464 {
465 OSReport("(%ld) fail to call PMICStopAsync() -> %ld\n", count++, retval);
466 state = STATE_NOT_READY;
467 }
468 break;
469
470 case STATE_WAIT_FOR_STOP:
471
472 // errCode comes from the PMICStopAsync callback
473 if (errCode > PMIC_ERR_OK) // still waiting?
474 {
475 break;
476 }
477 else if (errCode == PMIC_ERR_OK)
478 {
479 OSReport("(%ld) ok to stop P-Mic -> %ld.\n", count++, errCode);
480 state = STATE_STOPPED;
481 }
482 else
483 {
484 OSReport("(%ld) fail to stop P-Mic -> %ld.\n", count++, errCode);
485 state = STATE_NOT_READY;
486 }
487 break;
488
489 case STATE_CLOSE:
490
491 errCode = (PMIC_ERR)(PMIC_ERR_OK + 1);
492 retval = PMICCloseAsync(funcCb, NULL);
493
494 if (retval == PMIC_ERR_OK)
495 {
496 OSReport("(%ld) ok to call PMICCloseAsync() -> %ld\n", count++, retval);
497 state = STATE_WAIT_FOR_CLOSE;
498 }
499 else
500 {
501 OSReport("(%ld) fail to call PMICCloseAsync() -> %ld\n", count++, retval);
502 state = STATE_NOT_READY;
503 }
504 break;
505
506 case STATE_WAIT_FOR_CLOSE:
507
508 // errCode comes from the PMICCloseAsync callback
509 if (errCode > PMIC_ERR_OK) // still waiting?
510 {
511 break;
512 } else if (errCode == PMIC_ERR_OK)
513 {
514 OSReport("(%ld) ok to close P-Mic -> %ld.\n", count++, errCode);
515 state = STATE_WAIT_REOPEN;
516 }
517 else
518 {
519 OSReport("(%ld) fail to close P-Mic -> %ld.\n", count++, errCode);
520 state = STATE_NOT_READY; // or DIE?
521 }
522 break;
523
524 case STATE_WAIT_REOPEN:
525
526 if (button & WPAD_BUTTON_A)
527 {
528 state = STATE_OPEN;
529 }
530 else if (button & WPAD_BUTTON_B)
531 {
532 state = STATE_QUIT;
533 }
534 break;
535
536 case STATE_QUIT:
537
538 retval = PMICQuit();
539
540 if (retval == PMIC_ERR_OK)
541 {
542 MEMFreeToExpHeap(mem2Heap, work);
543
544 OSReport("(%ld) ok to call PMICQuit() -> %ld\n", count++, retval);
545 state = STATE_WAIT_RESTART;
546 }
547 else
548 {
549 OSReport("(%ld) fail to call PMICQuit() -> %ld\n", count++, retval);
550 state = STATE_DIE;
551 }
552 break;
553
554 case STATE_WAIT_RESTART:
555
556 if (button & WPAD_BUTTON_A)
557 {
558 state = STATE_NOT_INITIALIZED;
559 }
560 else if (button & WPAD_BUTTON_B)
561 {
562 state = STATE_DIE;
563 }
564 break;
565
566 case STATE_DIE:
567
568 return FALSE;
569 }
570
571 return TRUE;
572 }
573
574 /*---------------------------------------------------------------------------*
575 Name: funcCb
576
577 Description: callback for PMICOpen/Close/Start/StopAsync
578
579 Arguments: result error code.
580 arg (not used.)
581
582 Returns: none.
583 *---------------------------------------------------------------------------*/
584
funcCb(PMIC_ERR result,void * arg)585 static void funcCb(PMIC_ERR result, void* arg)
586 {
587 #pragma unused(arg)
588
589 errCode = result;
590 }
591
592 /*---------------------------------------------------------------------------*
593 Name: levelCb
594
595 Description: callback for PMICGetLevelAsync
596
597 Arguments: result (not used.)
598 arg (not used.)
599
600 Returns: none.
601 *---------------------------------------------------------------------------*/
602
levelCb(PMIC_ERR result,void * arg)603 static void levelCb(PMIC_ERR result, void* arg)
604 {
605 #pragma unused(result)
606 #pragma unused(arg)
607
608 gettingSout = FALSE;
609 }
610
611 /*---------------------------------------------------------------------------*
612 Name: printInfo
613
614 Description: print P-Mic information.
615
616 Arguments: none.
617
618 Returns: none.
619 *---------------------------------------------------------------------------*/
620
printInfo(void)621 static void printInfo(void)
622 {
623 DEMOPrintf(10, 10, 0, "************************************");
624 DEMOPrintf(10, 20, 0, " pmic_simple: Simple demo for P-Mic");
625 DEMOPrintf(10, 30, 0, "************************************");
626
627 switch (state)
628 {
629 case STATE_NOT_INITIALIZED:
630 case STATE_NOT_READY:
631
632 break;
633
634 case STATE_PROBE:
635
636 DEMOPrintf(60, 50, 0, "Insert P-Mic,");
637 DEMOPrintf(60, 60, 0, "or Push B to quit lib.");
638 break;
639
640 case STATE_OPEN:
641 case STATE_WAIT_FOR_OPEN:
642
643 DEMOPrintf(60, 50, 0, "Got P-Mic. Opening...");
644 break;
645
646 case STATE_STOPPED:
647
648 DEMOPrintf(60, 50, 0, "Push A to start P-Mic,");
649 DEMOPrintf(60, 60, 0, "or B to close P-Mic,");
650 DEMOPrintf(60, 70, 0, "or Remove P-Mic.");
651 break;
652
653 case STATE_START:
654 case STATE_WAIT_FOR_START:
655
656 DEMOPrintf(60, 50, 0, "Starting...");
657 break;
658
659 case STATE_RUN:
660
661 DEMOPrintf(60, 50, 0, "Push A to stop P-Mic,");
662 DEMOPrintf(60, 60, 0, "or B to close P-Mic,");
663 DEMOPrintf(60, 70, 0, "or Remove P-Mic.");
664 break;
665
666 case STATE_DO_STOP:
667 case STATE_WAIT_FOR_STOP:
668
669 DEMOPrintf(60, 50, 0, "Stopping...");
670 break;
671
672 case STATE_CLOSE:
673 case STATE_WAIT_FOR_CLOSE:
674
675 DEMOPrintf(60, 50, 0, "Closing...");
676 break;
677
678 case STATE_WAIT_REOPEN:
679
680 DEMOPrintf(60, 50, 0, "Push A to open P-Mic,");
681 DEMOPrintf(60, 60, 0, "or B to quit lib.");
682 break;
683
684 case STATE_QUIT:
685
686 break;
687
688 case STATE_WAIT_RESTART:
689
690 DEMOPrintf(60, 50, 0, "Push A to init P-Mic,");
691 DEMOPrintf(60, 60, 0, "or B to quit application.");
692 break;
693
694 case STATE_DIE:
695
696 DEMOPrintf(60, 50, 0, "done");
697 break;
698 }
699 }
700
701 /*---------------------------------------------------------------------------*
702 Name: printLM
703
704 Description: print Level Meter.
705
706 Arguments: none.
707
708 Returns: none.
709 *---------------------------------------------------------------------------*/
710
711 static u16 maxLevels[17] =
712 {
713 0x0053, // <= -39dBm0
714 0x0075, // <= -36dBm0
715 0x00A5, // <= -33dBm0
716 0x00EA, // <= -30dBm0
717 0x014A, // <= -27dBm0
718 0x01D3, // <= -24dBm0
719 0x0293, // <= -21dBm0
720 0x03A3, // <= -18dBm0
721 0x0524, // <= -15dBm0
722 0x0743, // <= -12dBm0
723 0x0A42, // <= - 9dBm0
724 0x0E7D, // <= - 6dBm0
725 0x1477, // <= - 3dBm0
726 0x1CE9, // <= + 0dBm0
727 0x28D7, // <= + 3dBm0
728 0x39B0, // <= + 6dBm0
729 0x517C // <= + 9dBm0
730 };
731
732 static char showLevels[17][39] =
733 {
734 "................ <-39dBm0",
735 ">............... -36dBm0",
736 ">>.............. -33dBm0",
737 ">>>............. -30dBm0",
738 ">>>>............ -27dBm0",
739 ">>>>>........... -24dBm0",
740 ">>>>>>.......... -21dBm0",
741 ">>>>>>>......... -18dBm0",
742 ">>>>>>>>........ -15dBm0",
743 ">>>>>>>>>....... -12dBm0",
744 ">>>>>>>>>>...... -9dBm0",
745 ">>>>>>>>>>>..... -6dBm0",
746 ">>>>>>>>>>>>.... -3dBm0",
747 ">>>>>>>>>>>>>... +0dBm0",
748 ">>>>>>>>>>>>>>.. +3dBm0",
749 ">>>>>>>>>>>>>>>. +6dBm0",
750 ">>>>>>>>>>>>>>>> >+6dBm0"
751 };
752
printLM(void)753 static void printLM(void)
754 {
755 s32 i;
756
757 for (i = 0; i < 16; i++)
758 {
759 if (sout <= maxLevels[i])
760 {
761 break;
762 }
763 }
764
765 DEMOPrintf(60, 110, 0, "Level Meter");
766 DEMOPrintf(60, 120, 0, "%s", showLevels[i]);
767 }
768