1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - demos.TWL - spi - spiMonkey3
3   File:     main.c
4 
5   Copyright 2007-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   $Date:: 2009-09-24#$
14   $Rev: 11063 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 
18 /*---------------------------------------------------------------------------*
19     A sample which controls microphone input, touch panel input, and sound
20     output in parallel.
21     Since TWL has a hardware to control SPI inputs, Software is not imposed
22     limitation to use SPI devices in parallel.
23 
24     USAGE:
25         UP, DOWN: Switch microphone sampling span.
26         LEFT, RIGHT: Switch microphone sampling bit range.
27         SEL , STA    : Switch microphone sampling loop enable or disable.
28 
29     HOWTO:
30         1. Initialize MIC library and SNDEX library.
31         2. Start automatic sampling of microphone by default configuration.
32         3. Initialize TP library with getting calibration parameters.
33         4. Start automatic sampling of touch panel by fixed configuration.
34         5. Initialize SND library.
35         6. Start emitting sound.
36         7. When you switch parameters for automatic sampling of microphone,
37            first, stop automatic sampling. Then, if necessary, stop emitting sound
38            and switch I2S frequency. After that, edit parameters and start
39            automatic sampling of microphone again.
40  *---------------------------------------------------------------------------*/
41 
42 #include    <twl.h>
43 #include    "snd_data.h"
44 #include    "DEMO.h"
45 
46 /*---------------------------------------------------------------------------*
47     Constant definitions
48  *---------------------------------------------------------------------------*/
49 #define     BUFFER_SIZE_MIC         (256 * 1024)   // 256 KB
50 #define     RETRY_MAX_COUNT         8
51 #define     START_VCOUNT_TP         0
52 #define     FREQUENCE_TP            4
53 #define     BUFFER_SIZE_TP          (FREQUENCE_TP + 1)
54 
55 /* Microphone sampling type string */
56 static const char* bitRangeString[MIC_SAMPLING_TYPE_MAX] =
57 {
58     "unsigned 8",
59     "unsigned 12",
60     "signed 8",
61     "signed 12",
62     "unsigned 12 (filter off)",
63     "signed 12 (filter off)"
64 };
65 
66 /* Font data */
67 static const u32    fontChar[8 * 4];
68 static const u32    fontPltt[8 * 4];
69 
70 /*---------------------------------------------------------------------------*
71     Internal Function Definitions
72  *---------------------------------------------------------------------------*/
73 static void     StartMicSampling(const MICAutoParam* param);
74 static void     StopMicSampling(void);
75 static void     AdjustMicSampling(u32 rate);
76 static SNDEXFrequency   GetI2SFrequency(void);
77 static void     SetI2SFrequency(SNDEXFrequency freq);
78 static void     SwitchI2SFrequency(void);
79 
80 static void     StepUpSamplingRate(void);
81 static void     StepDownSamplingRate(void);
82 
83 static void     VBlankIntr(void);
84 
85 static void     InitDrawMicData(void);
86 static void     SetDrawMicData(void *address, MICSamplingType type);
87 static void     DrawMicData(void);
88 static void     DrawLine(s16 sx, s16 sy, s16 ex, s16 ey, GXRgb color);
89 static void     PrintMicSamplingParam(void);
90 
91 static void     InitDrawTpData(void);
92 static void     SetDrawTpData(void);
93 static void     DrawTpData(void);
94 
95 /*---------------------------------------------------------------------------*
96     Internal Variable Definitions
97  *---------------------------------------------------------------------------*/
98 static u16          fontScr[32 * 32] ATTRIBUTE_ALIGN(HW_CACHE_LINE_SIZE);
99 
100 static MICAutoParam gMicAutoParam;
101 static u8           gMicData[BUFFER_SIZE_MIC] ATTRIBUTE_ALIGN(HW_CACHE_LINE_SIZE);
102 static u8           gDrawMicData[192];
103 
104 static TPData       gTpData[BUFFER_SIZE_TP];
105 static TPData       gDrawTpData[FREQUENCE_TP];
106 
107 static volatile BOOL    g_sample_busy   =   FALSE;
108 static u32              g_snd_async_tag;
109 
110 /*---------------------------------------------------------------------------*
111   Name:         TwlMain
112 
113   Description:  Initialization and main loop.
114 
115   Arguments:    None.
116 
117   Returns:      None.
118  *---------------------------------------------------------------------------*/
TwlMain(void)119 void TwlMain(void)
120 {
121     /* Various types of initialization */
122     OS_Init();
123     FX_Init();
124     GX_Init();
125     GX_DispOff();
126     GXS_DispOff();
127 
128     // When in NITRO mode, stopped by Panic
129     DEMOCheckRunOnTWL();
130 
131     /* Initializes display settings */
132     GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
133     MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
134     (void)GX_DisableBankForLCDC();
135 
136     /* Display-related initialization */
137     InitDrawMicData();
138     InitDrawTpData();
139 
140     /* Interrupt settings */
141     OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
142     (void)OS_EnableIrqMask(OS_IE_V_BLANK);
143     (void)OS_EnableIrq();
144     (void)OS_EnableInterrupts();
145     (void)GX_VBlankIntr(TRUE);
146 
147     /* Initialize microphone-related libraries */
148     {
149         (void)PM_SetAmp(PM_AMP_ON);
150         SNDEX_Init();
151         MIC_Init();
152 
153         gMicAutoParam.type = MIC_SAMPLING_TYPE_8BIT;
154         gMicAutoParam.buffer = (void *)gMicData;
155         gMicAutoParam.size = BUFFER_SIZE_MIC;
156         if ((OS_IsRunOnTwl() == TRUE) && (GetI2SFrequency() == SNDEX_FREQUENCY_47610))
157         {
158             gMicAutoParam.rate = MIC_SAMPLING_RATE_23810;
159         }
160         else
161         {
162             gMicAutoParam.rate = MIC_SAMPLING_RATE_16360;
163         }
164         gMicAutoParam.loop_enable = TRUE;
165         gMicAutoParam.full_callback = NULL;
166         StartMicSampling((const MICAutoParam*)&gMicAutoParam);
167     }
168 
169     /* Touch screen initialization */
170     {
171         TPCalibrateParam    calibrate;
172 
173         TP_Init();
174         if (TRUE == TP_GetUserInfo(&calibrate))
175         {
176             TP_SetCalibrateParam(&calibrate);
177             if (0 != TP_RequestAutoSamplingStart(START_VCOUNT_TP, FREQUENCE_TP, gTpData, BUFFER_SIZE_TP))
178             {
179                 OS_Panic("Could not start auto sampling of touch panel.\n");
180             }
181         }
182         else
183         {
184             OS_Panic("Could not get userInfo about touch panel calibration.\n");
185         }
186     }
187 
188     /* Initialize sound */
189     SND_Init();
190     SND_AssignWaveArc((SNDBankData*)sound_bank_data, 0, (SNDWaveArc*)sound_wave_data);
191     SND_StartSeq(0, sound_seq_data, 0, (SNDBankData*)sound_bank_data);
192 
193     /* Initialize internal variables */
194     MI_CpuFill8(gDrawMicData, 0x80, 192);
195 
196     /* LCD display start */
197     GX_DispOn();
198     GXS_DispOn();
199 
200     /* Debug string output */
201     OS_Printf("spiMonkey3 demo started.\n");
202     OS_Printf("   up/down    -> switch microphone sampling rate\n");
203     OS_Printf("   left/right -> switch microphone sampling bit range\n");
204     OS_Printf("   select     -> switch microphone sampling loop state\n");
205     OS_Printf("\n");
206     PrintMicSamplingParam();
207 
208     /* Empty call for getting key input data (strategy for pressing A Button in the IPL) */
209     (void)PAD_Read();
210 
211     {
212         u16     keyOld  =   0;
213         u16     keyTrg;
214         u16     keyNow;
215 
216         /* Main loop */
217         while (TRUE)
218         {
219             /* Get key input data */
220             keyNow  =   PAD_Read();
221             keyTrg  =   (u16)((keyOld ^ keyNow) & keyNow);
222             keyOld  =   keyNow;
223 
224             if (g_sample_busy == FALSE)
225             {
226                 /* Change sampling type (bit width) */
227                 if (keyTrg & PAD_KEY_LEFT)
228                 {
229                     StopMicSampling();
230                     gMicAutoParam.type
231                         =   (MICSamplingType)((gMicAutoParam.type + MIC_SAMPLING_TYPE_MAX - 1) % MIC_SAMPLING_TYPE_MAX);
232                     StartMicSampling((const MICAutoParam*)&gMicAutoParam);
233                     PrintMicSamplingParam();
234                 }
235                 if (keyTrg & PAD_KEY_RIGHT)
236                 {
237                     StopMicSampling();
238                     gMicAutoParam.type
239                             =   (MICSamplingType)((gMicAutoParam.type + 1) % MIC_SAMPLING_TYPE_MAX);
240                     StartMicSampling((const MICAutoParam*)&gMicAutoParam);
241                     PrintMicSamplingParam();
242                 }
243 
244                 /* Change sampling rate */
245                 if (keyTrg & PAD_KEY_UP)
246                 {
247                     StepUpSamplingRate();
248                     PrintMicSamplingParam();
249                     if (OS_IsRunOnTwl() == TRUE)
250                     {
251                         g_sample_busy   =   TRUE;
252                         SND_PauseSeq(0, TRUE);
253                         g_snd_async_tag =   SND_GetCurrentCommandTag();
254                     }
255                 }
256                 if (keyTrg & PAD_KEY_DOWN)
257                 {
258                     StepDownSamplingRate();
259                     PrintMicSamplingParam();
260                     if (OS_IsRunOnTwl() == TRUE)
261                     {
262                         g_sample_busy   =   TRUE;
263                         SND_PauseSeq(0, TRUE);
264                         g_snd_async_tag =   SND_GetCurrentCommandTag();
265                     }
266                 }
267 
268                 /* Change loop availability when buffer is full */
269                 if (keyTrg & (PAD_BUTTON_SELECT | PAD_BUTTON_START))
270                 {
271                     StopMicSampling();
272                     gMicAutoParam.loop_enable = (gMicAutoParam.loop_enable + 1) % 2;
273                     StartMicSampling((const MICAutoParam*)&gMicAutoParam);
274                     PrintMicSamplingParam();
275                 }
276             }
277             else
278             {
279                 if (OS_IsRunOnTwl() == TRUE)
280                 {
281                     if (SND_IsFinishedCommandTag(g_snd_async_tag) == TRUE)
282                     {
283                         StopMicSampling();
284                         SwitchI2SFrequency();
285                         StartMicSampling((const MICAutoParam*)&gMicAutoParam);
286                         SND_PauseSeq(0, FALSE);
287                         g_sample_busy   =   FALSE;
288                     }
289                 }
290                 else
291                 {
292                     g_sample_busy   =   FALSE;
293                 }
294             }
295 
296             /* Edit sampling results in display buffer */
297             SetDrawMicData(MIC_GetLastSamplingAddress(), gMicAutoParam.type);
298             SetDrawTpData();
299 
300             /* Render microphone sampling waveform */
301             DrawMicData();
302 
303             /* Main sound processing */
304             while (SND_RecvCommandReply(SND_COMMAND_NOBLOCK) != NULL)
305             {
306             }
307             (void)SND_FlushCommand(SND_COMMAND_NOBLOCK);
308 
309             /* Waiting for the V-Blank */
310             OS_WaitVBlankIntr();
311         }
312     }
313 }
314 
315 /*---------------------------------------------------------------------------*
316   Name:         StartMicSampling
317 
318   Description:  Calls the MIC_StartLimitedSampling function and performs error processing.
319 
320   Arguments:    param: Parameters passed to the microphone functions
321 
322   Returns:      None.
323  *---------------------------------------------------------------------------*/
324 static void
StartMicSampling(const MICAutoParam * param)325 StartMicSampling(const MICAutoParam* param)
326 {
327     MICResult   result;
328     s32         retry   =   0;
329 
330     while (TRUE)
331     {
332         result  =   MIC_StartLimitedSampling(param);
333         switch (result)
334         {
335         case MIC_RESULT_SUCCESS:            // Success
336             return;
337         case MIC_RESULT_BUSY:               // Another thread is using the microphone
338         case MIC_RESULT_SEND_ERROR:         // PXI queue is full
339             if (++ retry <= RETRY_MAX_COUNT)
340             {
341                 OS_Sleep(1);
342                 continue;
343             }
344             OS_TWarning("Retry count overflow.\n");
345             return;
346         case MIC_RESULT_ILLEGAL_STATUS:     // Not in an autosampling stopped state
347             OS_TWarning("Already started sampling.\n");
348             return;
349         case MIC_RESULT_ILLEGAL_PARAMETER:  // The specified parameter is not supported
350             OS_TWarning("Illegal parameter to start automatic sampling.\n");
351             return;
352         default:                            // Other fatal error
353             OS_Panic("Fatal error (%d).\n", result);
354             /* Never return */
355         }
356     }
357 }
358 
359 /*---------------------------------------------------------------------------*
360   Name:         StopMicSampling
361 
362   Description:  Calls the MIC_StopLimitedSampling function and performs error processing.
363 
364   Arguments:    None.
365 
366   Returns:      None.
367  *---------------------------------------------------------------------------*/
368 static void
StopMicSampling(void)369 StopMicSampling(void)
370 {
371     MICResult   result;
372     s32         retry   =   0;
373 
374     while (TRUE)
375     {
376         result  =   MIC_StopLimitedSampling();
377         switch (result)
378         {
379         case MIC_RESULT_SUCCESS:            // Success
380         case MIC_RESULT_ILLEGAL_STATUS:     // Not in an autosampling state
381             return;
382         case MIC_RESULT_BUSY:               // Microphone in use by other thread
383         case MIC_RESULT_SEND_ERROR:         // PXI queue is full
384             if (++ retry <= RETRY_MAX_COUNT)
385             {
386                 OS_Sleep(1);
387                 continue;
388             }
389             OS_TWarning("Retry count overflow.\n");
390             return;
391         default:                            // Other fatal error
392             OS_Panic("Fatal error (%d).\n", result);
393             /* Never return */
394         }
395     }
396 }
397 
398 /*---------------------------------------------------------------------------*
399   Name:         AdjustMicSampling
400 
401   Description:  Calls the MIC_AdjustLimitedSampling function and performs error processing.
402 
403   Arguments:    rate: Specifies the sampling period.
404 
405   Returns:      None.
406  *---------------------------------------------------------------------------*/
407 static void
AdjustMicSampling(u32 rate)408 AdjustMicSampling(u32 rate)
409 {
410     MICResult   result;
411     s32         retry   =   0;
412 
413     while (TRUE)
414     {
415         result  =   MIC_AdjustLimitedSampling(rate);
416         switch (result)
417         {
418         case MIC_RESULT_SUCCESS:            // Success
419         case MIC_RESULT_ILLEGAL_STATUS:     // Not in an autosampling state
420             return;
421         case MIC_RESULT_BUSY:               // Microphone in use by other thread
422         case MIC_RESULT_SEND_ERROR:         // PXI queue is full
423             if (++ retry <= RETRY_MAX_COUNT)
424             {
425                 OS_Sleep(1);
426                 continue;
427             }
428             OS_TWarning("Retry count overflow.\n");
429             return;
430         case MIC_RESULT_ILLEGAL_PARAMETER:  // The specified parameter is not supported
431             OS_TWarning("Illegal parameter to adjust automatic sampling rate.\n");
432             return;
433         default:                            // Other fatal error
434             OS_Panic("Fatal error (%d).\n", result);
435             /* Never return */
436         }
437     }
438 }
439 
440 #include <twl/ltdmain_begin.h>
441 /*---------------------------------------------------------------------------*
442   Name:         GetI2SFrequency
443 
444   Description:  Gets the I2S operating frequency.
445 
446   Arguments:    None.
447 
448   Returns:      SNDEXFrequency: Returns the I2S operating frequency.
449  *---------------------------------------------------------------------------*/
450 static SNDEXFrequency
GetI2SFrequency(void)451 GetI2SFrequency(void)
452 {
453     SNDEXResult     result;
454     SNDEXFrequency  freq;
455     s32             retry   =   0;
456 
457     while (TRUE)
458     {
459         result  =   SNDEX_GetI2SFrequency(&freq);
460         switch (result)
461         {
462         case SNDEX_RESULT_SUCCESS:          // Success
463             return freq;
464         case SNDEX_RESULT_EXCLUSIVE:        // Exclusion error
465         case SNDEX_RESULT_PXI_SEND_ERROR:   // PXI queue is full
466             if (++ retry <= RETRY_MAX_COUNT)
467             {
468                 OS_Sleep(1);
469                 continue;
470             }
471             OS_TWarning("Retry count overflow.\n");
472             break;
473         case SNDEX_RESULT_BEFORE_INIT:      // Pre-initialization
474         case SNDEX_RESULT_ILLEGAL_STATE:    // Abnormal state
475             OS_TWarning("Illegal state to get I2S frequency.\n");
476             break;
477         case SNDEX_RESULT_FATAL_ERROR:      // Fatal error
478         default:
479             OS_Panic("Fatal error (%d).\n", result);
480             /* Never return */
481         }
482     }
483     return SNDEX_FREQUENCY_32730;
484 }
485 
486 /*---------------------------------------------------------------------------*
487   Name:         SetI2SFrequency
488 
489   Description:  Changes the I2S operating frequency.
490 
491   Arguments:    freq: I2S operating frequency.
492 
493   Returns:      None.
494  *---------------------------------------------------------------------------*/
495 static void
SetI2SFrequency(SNDEXFrequency freq)496 SetI2SFrequency(SNDEXFrequency freq)
497 {
498     SNDEXResult     result;
499     s32             retry   =   0;
500 
501     while (TRUE)
502     {
503         result  =   SNDEX_SetI2SFrequency(freq);
504         switch (result)
505         {
506         case SNDEX_RESULT_SUCCESS:          // Success
507             return;
508         case SNDEX_RESULT_EXCLUSIVE:        // Exclusion error
509         case SNDEX_RESULT_PXI_SEND_ERROR:   // PXI queue is full
510             if (++ retry <= RETRY_MAX_COUNT)
511             {
512                 OS_Sleep(1);
513                 continue;
514             }
515             OS_TWarning("Retry count overflow.\n");
516             return;
517         case SNDEX_RESULT_BEFORE_INIT:      // Pre-initialization
518         case SNDEX_RESULT_ILLEGAL_STATE:    // Abnormal state
519             OS_TWarning("Illegal state to set I2S frequency.\n");
520             return;
521         case SNDEX_RESULT_INVALID_PARAM:    // Abnormal argument
522             OS_TWarning("Could not set I2S frequency into %d.\n", freq);
523             return;
524         case SNDEX_RESULT_FATAL_ERROR:      // Fatal error
525         default:
526             OS_Panic("Fatal error (%d)\n", result);
527             /* Never return */
528         }
529     }
530 }
531 
532 /*---------------------------------------------------------------------------*
533   Name:         SwitchI2SFrequency
534 
535   Description:  Changes the I2S operating frequency in conjunction with the microphone sampling frequency.
536 
537   Arguments:    None.
538 
539   Returns:      None.
540  *---------------------------------------------------------------------------*/
541 static void
SwitchI2SFrequency(void)542 SwitchI2SFrequency(void)
543 {
544     SNDEXFrequency  freq;
545 
546     freq    =   GetI2SFrequency();
547     switch (gMicAutoParam.rate)
548     {
549     case MIC_SAMPLING_RATE_8180:
550     case MIC_SAMPLING_RATE_10910:
551     case MIC_SAMPLING_RATE_16360:
552     case MIC_SAMPLING_RATE_32730:
553         if (freq != SNDEX_FREQUENCY_32730)
554         {
555             SetI2SFrequency(SNDEX_FREQUENCY_32730);
556         }
557         break;
558     case MIC_SAMPLING_RATE_11900:
559     case MIC_SAMPLING_RATE_15870:
560     case MIC_SAMPLING_RATE_23810:
561     case MIC_SAMPLING_RATE_47610:
562         if (freq != SNDEX_FREQUENCY_47610)
563         {
564             SetI2SFrequency(SNDEX_FREQUENCY_47610);
565         }
566         break;
567     }
568 }
569 
570 #include <twl/ltdmain_end.h>
571 
572 /*---------------------------------------------------------------------------*
573   Name:         StepUpSamplingRate
574 
575   Description:  Increases the microphone sampling frequency by one level.
576 
577   Arguments:    None.
578 
579   Returns:      None.
580  *---------------------------------------------------------------------------*/
581 static void
StepUpSamplingRate(void)582 StepUpSamplingRate(void)
583 {
584     if (OS_IsRunOnTwl() == TRUE)
585     {
586         switch (gMicAutoParam.rate)
587         {
588         case MIC_SAMPLING_RATE_8180:    // 32.73k / 4
589             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_10910;
590             break;
591         case MIC_SAMPLING_RATE_10910:   // 32.73k / 3
592             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_11900;
593             break;
594         case MIC_SAMPLING_RATE_11900:   // 47.61k / 4
595             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_15870;
596             break;
597         case MIC_SAMPLING_RATE_15870:   // 47.61k / 3
598             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_16360;
599             break;
600         case MIC_SAMPLING_RATE_16360:   // 32.73k / 2
601             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_23810;
602             break;
603         case MIC_SAMPLING_RATE_23810:   // 47.61k / 2
604             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_32730;
605             break;
606         case MIC_SAMPLING_RATE_32730:   // 32.73k / 1
607             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_47610;
608             break;
609         case MIC_SAMPLING_RATE_47610:   // 47.61k / 1
610         default:
611             /* Do nothing */
612             return;
613         }
614     }
615     else
616     {
617         switch (gMicAutoParam.rate)
618         {
619         case MIC_SAMPLING_RATE_8180:    // 32.73k / 4
620             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_10910;
621             break;
622         case MIC_SAMPLING_RATE_10910:   // 32.73k / 3
623             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_11900;
624             break;
625         case MIC_SAMPLING_RATE_11900:   // 47.61k / 4
626             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_15870;
627             break;
628         case MIC_SAMPLING_RATE_15870:   // 47.61k / 3
629             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_16360;
630             break;
631         case MIC_SAMPLING_RATE_16360:   // 32.73k / 2
632             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_23810;
633             break;
634         case MIC_SAMPLING_RATE_23810:   // 47.61k / 2
635         default:
636             /* Do nothing */
637             return;
638         }
639         AdjustMicSampling(gMicAutoParam.rate);
640     }
641 }
642 
643 /*---------------------------------------------------------------------------*
644   Name:         StepUpSamplingRate
645 
646   Description:  Decreases the microphone sampling frequency by one level.
647 
648   Arguments:    None.
649 
650   Returns:      None.
651  *---------------------------------------------------------------------------*/
652 static void
StepDownSamplingRate(void)653 StepDownSamplingRate(void)
654 {
655     if (OS_IsRunOnTwl() == TRUE)
656     {
657         switch (gMicAutoParam.rate)
658         {
659         case MIC_SAMPLING_RATE_47610:   // 47.61k / 1
660             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_32730;
661             break;
662         case MIC_SAMPLING_RATE_32730:   // 32.73k / 1
663             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_23810;
664             break;
665         case MIC_SAMPLING_RATE_23810:   // 47.61k / 2
666             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_16360;
667             break;
668         case MIC_SAMPLING_RATE_16360:   // 32.73k / 2
669             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_15870;
670             break;
671         case MIC_SAMPLING_RATE_15870:   // 47.61k / 3
672             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_11900;
673             break;
674         case MIC_SAMPLING_RATE_11900:   // 47.61k / 4
675             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_10910;
676             break;
677         case MIC_SAMPLING_RATE_10910:   // 32.73k / 3
678             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_8180;
679             break;
680         case MIC_SAMPLING_RATE_8180:    // 32.73k / 4
681         default:
682             /* Do nothing */
683             return;
684         }
685     }
686     else
687     {
688         switch (gMicAutoParam.rate)
689         {
690         case MIC_SAMPLING_RATE_23810:   // 47.61k / 2
691             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_16360;
692             break;
693         case MIC_SAMPLING_RATE_16360:   // 32.73k / 2
694             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_15870;
695             break;
696         case MIC_SAMPLING_RATE_15870:   // 47.61k / 3
697             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_11900;
698             break;
699         case MIC_SAMPLING_RATE_11900:   // 47.61k / 4
700             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_10910;
701             break;
702         case MIC_SAMPLING_RATE_10910:   // 32.73k / 3
703             gMicAutoParam.rate  =   MIC_SAMPLING_RATE_8180;
704             break;
705         case MIC_SAMPLING_RATE_8180:    // 32.73k / 4
706         default:
707             /* Do nothing */
708             return;
709         }
710         AdjustMicSampling(gMicAutoParam.rate);
711     }
712 }
713 
714 /*---------------------------------------------------------------------------*
715   Name:         VBlankIntr
716 
717   Description:  V-Blank interrupt vector.
718 
719   Arguments:    None.
720 
721   Returns:      None.
722  *---------------------------------------------------------------------------*/
VBlankIntr(void)723 static void VBlankIntr(void)
724 {
725     /* Sets the IRQ check flag */
726     OS_SetIrqCheckFlag(OS_IE_V_BLANK);
727 
728     /* Display the position of touch screen contact */
729     DrawTpData();
730 }
731 
732 /*---------------------------------------------------------------------------*
733   Name:         InitDrawMicData
734 
735   Description:  Performs initialization for 3D display of microphone sampling waveform.
736 
737   Arguments:    None.
738 
739   Returns:      None.
740  *---------------------------------------------------------------------------*/
InitDrawMicData(void)741 static void InitDrawMicData(void)
742 {
743     /* Main display 3D display settings */
744     G3X_Init();
745     G3X_InitMtxStack();
746     G3X_AlphaTest(FALSE, 0);
747     G3X_AntiAlias(TRUE);
748     G3X_EdgeMarking(FALSE);
749     G3X_SetFog(FALSE, (GXFogBlend)0, (GXFogSlope)0, 0);
750     G3X_SetClearColor(GX_RGB(0, 0, 0), 0, 0x7fff, 63, FALSE);
751     G3_ViewPort(0, 0, 255, 191);
752     G3_MtxMode(GX_MTXMODE_POSITION_VECTOR);
753 
754     MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE);
755     GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_3D);
756     GX_SetVisiblePlane(GX_PLANEMASK_BG0);
757     G2_SetBG0Priority(0);
758 }
759 
760 /*---------------------------------------------------------------------------*
761   Name:         SetDrawMicData
762 
763   Description:  Edits the most recent microphone sampled data in the display buffer.
764 
765   Arguments:    address: Location in main memory where the most recent sampling data was stored by the component
766 
767                 type:     Sampling type (bit width).
768 
769   Returns:      None.
770  *---------------------------------------------------------------------------*/
SetDrawMicData(void * address,MICSamplingType type)771 static void SetDrawMicData(void *address, MICSamplingType type)
772 {
773     s32     i;
774 
775     /* If sampling has never been performed, do nothing and stop.
776        (Because it would delete memory cache(s) unrelated to the microphone) */
777     if ((address < gMicData) || (address >= (gMicData + BUFFER_SIZE_MIC)))
778     {
779         return;
780     }
781 
782     switch (type)
783     {
784     case MIC_SAMPLING_TYPE_8BIT:
785     case MIC_SAMPLING_TYPE_SIGNED_8BIT:
786         /* In the case of 8-bit sampling */
787         {
788             u8     *p;
789 
790             p = (u8 *)((u32)address - 191);
791             if (p < gMicData)
792             {
793                 p = (u8 *)((u32)p + BUFFER_SIZE_MIC);
794             }
795             DC_InvalidateRange((void *)((u32)p & ~(HW_CACHE_LINE_SIZE - 1)), HW_CACHE_LINE_SIZE);
796             for (i = 0; i < 192; i++)
797             {
798                 gDrawMicData[i] = *p;
799                 p++;
800                 if ((u32)p >= (u32)(gMicData + BUFFER_SIZE_MIC))
801                 {
802                     p -= BUFFER_SIZE_MIC;
803                 }
804                 if (((u32)p % HW_CACHE_LINE_SIZE) == 0)
805                 {
806                     DC_InvalidateRange(p, HW_CACHE_LINE_SIZE);
807                 }
808             }
809         }
810         break;
811     case MIC_SAMPLING_TYPE_12BIT:
812     case MIC_SAMPLING_TYPE_SIGNED_12BIT:
813     case MIC_SAMPLING_TYPE_12BIT_FILTER_OFF:
814     case MIC_SAMPLING_TYPE_SIGNED_12BIT_FILTER_OFF:
815         /* For 12-bit sampling */
816         {
817             u16    *p;
818 
819             p = (u16 *)((u32)address - 382);
820             if ((u32)p < (u32)gMicData)
821             {
822                 p = (u16 *)((u32)p + BUFFER_SIZE_MIC);
823             }
824             DC_InvalidateRange((void *)((u32)p & ~(HW_CACHE_LINE_SIZE - 1)), HW_CACHE_LINE_SIZE);
825             for (i = 0; i < 192; i++)
826             {
827                 gDrawMicData[i] = (u8)((*p >> 8) & 0x00ff);
828                 p++;
829                 if ((u32)p >= (u32)(gMicData + BUFFER_SIZE_MIC))
830                 {
831                     p = (u16 *)((u32)p - BUFFER_SIZE_MIC);
832                 }
833                 if (((u32)p % HW_CACHE_LINE_SIZE) == 0)
834                 {
835                     DC_InvalidateRange(p, HW_CACHE_LINE_SIZE);
836                 }
837             }
838         }
839         break;
840     }
841 }
842 
843 /*---------------------------------------------------------------------------*
844   Name:         DrawMicData
845 
846   Description:  Performs 3D display of microphone sampling waveform.
847 
848   Arguments:    None.
849 
850   Returns:      None.
851  *---------------------------------------------------------------------------*/
DrawMicData(void)852 static void DrawMicData(void)
853 {
854     s32     i;
855 
856     G3X_Reset();
857     G3_Identity();
858     G3_PolygonAttr(GX_LIGHTMASK_NONE, GX_POLYGONMODE_MODULATE, GX_CULL_NONE, 0, 31, 0);
859 
860     if ((gMicAutoParam.type == MIC_SAMPLING_TYPE_SIGNED_8BIT) ||
861         (gMicAutoParam.type == MIC_SAMPLING_TYPE_SIGNED_12BIT) ||
862         (gMicAutoParam.type == MIC_SAMPLING_TYPE_SIGNED_12BIT_FILTER_OFF))
863     {
864         for (i = 0; i < 191; i++)
865         {
866             DrawLine((s16)((s8)gDrawMicData[i]), (s16)i, (s16)((s8)gDrawMicData[i + 1]), (s16)(i + 1), GX_RGB(31, 31, 31));
867         }
868     }
869     else
870     {
871         for (i = 0; i < 191; i++)
872         {
873             DrawLine((s16)(gDrawMicData[i]), (s16)i, (s16)(gDrawMicData[i + 1]), (s16)(i + 1), GX_RGB(31, 31, 31));
874         }
875     }
876     G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W);
877 }
878 
879 /*---------------------------------------------------------------------------*
880   Name:         DrawLine
881 
882   Description:  Renders a line with a triangular polygon.
883 
884   Arguments:    sx:   X-coordinate of starting point of line to render
885                 sy:   Y-coordinate of starting point of line to render
886                 ex:   X-coordinate of endpoint of line to render
887                 ey:   Y-coordinate of endpoint of line to render
888                 color:   Color of line to render
889 
890   Returns:      None.
891  *---------------------------------------------------------------------------*/
DrawLine(s16 sx,s16 sy,s16 ex,s16 ey,GXRgb color)892 static void DrawLine(s16 sx, s16 sy, s16 ex, s16 ey, GXRgb color)
893 {
894     fx16    fsx = (fx16)(((sx - 128) * 0x1000) / 128);
895     fx16    fsy = (fx16)(((96 - sy) * 0x1000) / 96);
896     fx16    fex = (fx16)(((ex - 128) * 0x1000) / 128);
897     fx16    fey = (fx16)(((96 - ey) * 0x1000) / 96);
898 
899     G3_Begin(GX_BEGIN_TRIANGLES);
900     {
901         G3_Color(color);
902         G3_Vtx(fsx, fsy, 0);
903         G3_Color(color);
904         G3_Vtx(fex, fey, 0);
905         G3_Color(color);
906         G3_Vtx(fsx, fsy, 1);
907     }
908     G3_End();
909 }
910 
911 /*---------------------------------------------------------------------------*
912   Name:         PrintMicSamplingParam
913 
914   Description:  Print-outputs the microphone's sampling settings.
915 
916   Arguments:    None.
917 
918   Returns:      None.
919  *---------------------------------------------------------------------------*/
PrintMicSamplingParam(void)920 static void PrintMicSamplingParam(void)
921 {
922     s32     range = 0;
923 
924     OS_Printf(" sampling-rate: ");
925     switch (gMicAutoParam.rate)
926     {
927     case MIC_SAMPLING_RATE_32730:   OS_Printf("32.73kHz");  break;
928     case MIC_SAMPLING_RATE_16360:   OS_Printf("16.36kHz");  break;
929     case MIC_SAMPLING_RATE_10910:   OS_Printf("10.91kHz");  break;
930     case MIC_SAMPLING_RATE_8180:    OS_Printf(" 8.18kHz");  break;
931     case MIC_SAMPLING_RATE_47610:   OS_Printf("47.61kHz");  break;
932     case MIC_SAMPLING_RATE_23810:   OS_Printf("23.81kHz");  break;
933     case MIC_SAMPLING_RATE_15870:   OS_Printf("15.87kHz");  break;
934     case MIC_SAMPLING_RATE_11900:   OS_Printf("11.90kHz");  break;
935     }
936 
937     OS_Printf(" , loop: %s", (gMicAutoParam.loop_enable ? " on" : "off"));
938 
939     OS_Printf(" , bit-range: %s\n",
940             bitRangeString[gMicAutoParam.type % MIC_SAMPLING_TYPE_MAX]);
941 }
942 
943 /*---------------------------------------------------------------------------*
944   Name:         Prepare2DScreen
945 
946   Description:  Initializes the 2D screen to display touch screen contact positions.
947 
948 
949   Arguments:    scr: Specifies the start address of screen data to be edited.
950                 pltt: Specifies the palette number used for the line indicating the contact position.
951 
952   Returns:      None.
953  *---------------------------------------------------------------------------*/
954 static void
Prepare2DScreen(u16 * scr,u16 pltt)955 Prepare2DScreen(u16* scr, u16 pltt)
956 {
957     s32     i;
958     s32     j;
959 
960     scr[0]  =   (u16)(0x0003 | ((pltt & 0x000f) << 12));
961     for (j = 1; j < 32; j ++)
962     {
963         scr[j]  =   (u16)(0x0001 | ((pltt & 0x000f) << 12));
964     }
965     for (i = 1; i < 32; i ++)
966     {
967         scr[i * 32] =   (u16)(0x0002 | ((pltt & 0x000f) << 12));
968         for (j = 1; j < 32; j ++)
969         {
970             scr[(i * 32) + j]   =   (u16)((pltt & 0x000f) << 12);
971         }
972     }
973     DC_StoreRange(scr, (32 * 32 * sizeof(u16)));
974 }
975 
976 /*---------------------------------------------------------------------------*
977   Name:         InitDrawTpData
978 
979   Description:  Performs initialization for 2D display of touch screen contact positions.
980 
981   Arguments:    None.
982 
983   Returns:      None.
984  *---------------------------------------------------------------------------*/
985 static void
InitDrawTpData(void)986 InitDrawTpData(void)
987 {
988     /* Sub-display 2D display settings */
989     GX_SetBankForSubBG(GX_VRAM_SUB_BG_32_H);
990     GXS_SetGraphicsMode(GX_BGMODE_0);
991 
992     G2S_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256, GX_BG_COLORMODE_16,
993             GX_BG_SCRBASE_0x6000, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01);
994     G2S_SetBG1Control(GX_BG_SCRSIZE_TEXT_256x256, GX_BG_COLORMODE_16,
995             GX_BG_SCRBASE_0x6800, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01);
996     G2S_SetBG2ControlText(GX_BG_SCRSIZE_TEXT_256x256, GX_BG_COLORMODE_16,
997             GX_BG_SCRBASE_0x7000, GX_BG_CHARBASE_0x00000);
998     G2S_SetBG3ControlText(GX_BG_SCRSIZE_TEXT_256x256, GX_BG_COLORMODE_16,
999             GX_BG_SCRBASE_0x7800, GX_BG_CHARBASE_0x00000);
1000     Prepare2DScreen(fontScr, 0);
1001     GXS_LoadBG0Scr(fontScr, 0, sizeof(fontScr));
1002     Prepare2DScreen(fontScr, 1);
1003     GXS_LoadBG1Scr(fontScr, 0, sizeof(fontScr));
1004     Prepare2DScreen(fontScr, 2);
1005     GXS_LoadBG2Scr(fontScr, 0, sizeof(fontScr));
1006     Prepare2DScreen(fontScr, 3);
1007     GXS_LoadBG3Scr(fontScr, 0, sizeof(fontScr));
1008     G2S_SetBG0Priority(0);
1009     G2S_SetBG1Priority(1);
1010     G2S_SetBG2Priority(2);
1011     G2S_SetBG3Priority(3);
1012 
1013     GXS_LoadBGPltt(fontPltt, 0, sizeof(fontPltt));
1014     GXS_LoadBG0Char(fontChar, 0, sizeof(fontChar));
1015     GXS_SetVisiblePlane(GX_PLANEMASK_BG0 | GX_PLANEMASK_BG1 | GX_PLANEMASK_BG2 | GX_PLANEMASK_BG3);
1016 }
1017 
1018 /*---------------------------------------------------------------------------*
1019   Name:         SetDrawTpData
1020 
1021   Description:  Edits the buffer for converting the most recent touch screen sampled data to display screen coordinates and displaying it.
1022 
1023 
1024   Arguments:    None.
1025 
1026   Returns:      None.
1027  *---------------------------------------------------------------------------*/
1028 static void
SetDrawTpData(void)1029 SetDrawTpData(void)
1030 {
1031     s32     i;
1032     s32     index;
1033     s32     lastIndex;
1034 
1035     lastIndex   =   TP_GetLatestIndexInAuto();
1036     for (i = 0; i < FREQUENCE_TP; i ++)
1037     {
1038         index   =   (lastIndex + BUFFER_SIZE_TP - i) % BUFFER_SIZE_TP;
1039         if ((gTpData[index].touch == TP_TOUCH_ON) && (gTpData[index].validity == TP_VALIDITY_VALID))
1040         {
1041             gDrawTpData[i].touch    =   TP_TOUCH_ON;
1042             TP_GetCalibratedPoint(&gDrawTpData[i], &gTpData[index]);
1043         }
1044         else
1045         {
1046             gDrawTpData[i].touch    =   TP_TOUCH_OFF;
1047         }
1048     }
1049 }
1050 
1051 /*---------------------------------------------------------------------------*
1052   Name:         DrawTpData
1053 
1054   Description:  Performs 2D display of the touch screen contact position.
1055 
1056   Arguments:    None.
1057 
1058   Returns:      None.
1059  *---------------------------------------------------------------------------*/
1060 static void
DrawTpData(void)1061 DrawTpData(void)
1062 {
1063     int     plane   =   GX_PLANEMASK_NONE;
1064 
1065     if (gDrawTpData[0].touch == TP_TOUCH_ON)
1066     {
1067         G2S_SetBG0Offset((256 - gDrawTpData[0].x), (256 - gDrawTpData[0].y));
1068         plane   |=  GX_PLANEMASK_BG0;
1069     }
1070     if (gDrawTpData[1].touch == TP_TOUCH_ON)
1071     {
1072         G2S_SetBG1Offset((256 - gDrawTpData[1].x), (256 - gDrawTpData[1].y));
1073         plane   |=  GX_PLANEMASK_BG1;
1074     }
1075     if (gDrawTpData[2].touch == TP_TOUCH_ON)
1076     {
1077         G2S_SetBG2Offset((256 - gDrawTpData[2].x), (256 - gDrawTpData[2].y));
1078         plane   |=  GX_PLANEMASK_BG2;
1079     }
1080     if (gDrawTpData[3].touch == TP_TOUCH_ON)
1081     {
1082         G2S_SetBG3Offset((256 - gDrawTpData[3].x), (256 - gDrawTpData[3].y));
1083         plane   |=  GX_PLANEMASK_BG3;
1084     }
1085     GXS_SetVisiblePlane(plane);
1086 }
1087 
1088 /*---------------------------------------------------------------------------*
1089     Font data
1090  *---------------------------------------------------------------------------*/
1091 static const u32    fontChar[8 * 4] =
1092 {
1093     0x00000000, 0x00000000, 0x00000000, 0x00000000,
1094     0x00000000, 0x00000000, 0x00000000, 0x00000000,
1095     0x11111111, 0x00000000, 0x00000000, 0x00000000,
1096     0x00000000, 0x00000000, 0x00000000, 0x00000000,
1097     0x00000001, 0x00000001, 0x00000001, 0x00000001,
1098     0x00000001, 0x00000001, 0x00000001, 0x00000001,
1099     0x11111111, 0x00000001, 0x00000001, 0x00000001,
1100     0x00000001, 0x00000001, 0x00000001, 0x00000001
1101 };
1102 
1103 static const u32    fontPltt[8 * 4] =
1104 {
1105     0x7fff0000, 0x00000000, 0x00000000, 0x00000000,
1106     0x00000000, 0x00000000, 0x00000000, 0x00000000,
1107     0x5ef70000, 0x00000000, 0x00000000, 0x00000000,
1108     0x00000000, 0x00000000, 0x00000000, 0x00000000,
1109     0x3def0000, 0x00000000, 0x00000000, 0x00000000,
1110     0x00000000, 0x00000000, 0x00000000, 0x00000000,
1111     0x1ce70000, 0x00000000, 0x00000000, 0x00000000,
1112     0x00000000, 0x00000000, 0x00000000, 0x00000000
1113 };
1114 
1115