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