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