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