1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - SPI - demos
3 File: main.c
4
5 Copyright 2003-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-12-22#$
14 $Rev: 9714 $
15 $Author: okubata_ryoma $
16 *---------------------------------------------------------------------------*/
17
18 /*---------------------------------------------------------------------------*
19 A sample that controls mic sampling status.
20
21 USAGE:
22 UP, DOWN : Control sampling span.
23 LEFT, RIGHT: Control sampling bit range. ( 8-bit, 12-bit, etc.)
24 SEL , STA : Control loop sampling enable or disable.
25
26 HOWTO:
27 1. Initialize memory allocate system to get 32byte aligned big buffer.
28 2. Initialize MIC library.
29 Start auto sampling of MIC by default status.
30 When you change status , first , stop auto sampling.
31 Then , edit status and start auto sampling again.
32 *---------------------------------------------------------------------------*/
33
34 #include <nitro.h>
35 #include <nitro/spi/common/pm_common.h>
36 #include <nitro/spi/ARM9/pm.h>
37
38
39 /*---------------------------------------------------------------------------*
40 Constant Definitions
41 *---------------------------------------------------------------------------*/
42 #define KEY_REPEAT_START 25 // Number of frames until key repeat starts
43 #define KEY_REPEAT_SPAN 10 // Number of frames between key repeats
44 #define TEST_BUFFER_SIZE ( 1024 * 1024 ) // 1M
45
46
47 /*---------------------------------------------------------------------------*
48 Structure Definitions
49 *---------------------------------------------------------------------------*/
50 // Key input data
51 typedef struct KeyInformation
52 {
53 u16 cnt; // Unprocessed input value
54 u16 trg; // Push trigger input
55 u16 up; // Release trigger input
56 u16 rep; // Press and hold repeat input
57
58 }
59 KeyInformation;
60
61 /*---------------------------------------------------------------------------*
62 Internal Function Definitions
63 *---------------------------------------------------------------------------*/
64 static void InitializeAllocateSystem(void);
65 static void Init3D(void);
66 static void Draw3D(void);
67 static void DrawLine(s16 sx, s16 sy, s16 ex, s16 ey);
68 static void VBlankIntr(void);
69 static void KeyRead(KeyInformation * pKey);
70 static void SetDrawData(void *address, MICSamplingType type);
71 static void PrintfVariableData(void);
72
73 /*---------------------------------------------------------------------------*
74 Internal Variable Definitions
75 *---------------------------------------------------------------------------*/
76 static KeyInformation gKey;
77 static MICAutoParam gMicAutoParam;
78 static u8 *gMicData;
79 static u8 gDrawData[192];
80
81
82 /*---------------------------------------------------------------------------*
83 Name: NitroMain
84
85 Description: Initialization and main loop.
86
87 Arguments: None.
88
89 Returns: None.
90 *---------------------------------------------------------------------------*/
NitroMain(void)91 void NitroMain(void)
92 {
93 // Various types of initialization
94 OS_Init();
95 FX_Init();
96 GX_Init();
97 GX_DispOff();
98 GXS_DispOff();
99
100 // Initializes display settings
101 GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
102 MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
103 (void)GX_DisableBankForLCDC();
104 MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE);
105 MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE);
106 MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE);
107 MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE);
108
109 // 3D-related initialization
110 Init3D();
111
112 // Interrupt settings
113 OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
114 (void)OS_EnableIrqMask(OS_IE_V_BLANK);
115 (void)OS_EnableIrq();
116 (void)OS_EnableInterrupts();
117 (void)GX_VBlankIntr(TRUE);
118
119 //****************************************************************
120 // Initialize MIC.
121 InitializeAllocateSystem();
122 // Because the memory allocated with OS_Alloc is 32-byte aligned, other memory is not destroyed even if the cache is manipulated
123 //
124 gMicData = (u8 *)OS_Alloc(TEST_BUFFER_SIZE);
125 MIC_Init();
126
127 #ifdef SDK_TS
128 // Initialize PMIC
129 PM_Init();
130 // AMP on
131 (void)PM_SetAmp(PM_AMP_ON);
132 #if defined(SDK_TS_VERSION) && ( SDK_TS_VERSION >= 100 )
133 // Adjust AMP gain
134 (void)PM_SetAmpGain(PM_AMPGAIN_80);
135 #endif
136 #if defined(SDK_TS_VERSION) && ( SDK_TS_VERSION == 100 )
137 // Turn off LCD backlight to deal with noise
138 (void)PM_SetBackLight(PM_LCD_ALL, PM_BACKLIGHT_OFF);
139 #endif
140 #endif
141
142 gMicAutoParam.type = MIC_SAMPLING_TYPE_8BIT;
143 gMicAutoParam.buffer = (void *)gMicData;
144 gMicAutoParam.size = TEST_BUFFER_SIZE;
145 gMicAutoParam.rate = MIC_SAMPLING_RATE_8K;
146 gMicAutoParam.loop_enable = TRUE;
147 gMicAutoParam.full_callback = NULL;
148 (void)MIC_StartAutoSampling(&gMicAutoParam);
149 //****************************************************************
150
151 // Initialize internal variables
152 {
153 s32 i;
154
155 for (i = 0; i < 192; i++)
156 {
157 gDrawData[i] = 0x80;
158 }
159 }
160
161 // LCD display start
162 GX_DispOn();
163 GXS_DispOn();
164
165 // Debug string output
166 OS_Printf("ARM9: MIC demo started.\n");
167 OS_Printf(" up/down -> change sampling span\n");
168 OS_Printf(" left/right -> change bit range\n");
169 OS_Printf(" select -> change loop setting\n");
170 OS_Printf("\n");
171 PrintfVariableData();
172
173 // Empty call for getting key input data (strategy for pressing A button in the IPL)
174 KeyRead(&gKey);
175
176 // Main loop
177 while (TRUE)
178 {
179 // Get key input data
180 KeyRead(&gKey);
181
182 // Change variable parameters
183 {
184 // Change sampling type (bit width)
185 if ((gKey.trg | gKey.rep) & (PAD_KEY_LEFT | PAD_KEY_RIGHT))
186 {
187 //****************************************************************
188 (void)MIC_StopAutoSampling();
189 gMicAutoParam.type = (MICSamplingType)((gMicAutoParam.type +
190 1) % MIC_SAMPLING_TYPE_MAX);
191 (void)MIC_StartAutoSampling(&gMicAutoParam);
192 //****************************************************************
193 PrintfVariableData();
194 }
195 // Change sampling rate
196 if ((gKey.trg | gKey.rep) & PAD_KEY_UP)
197 {
198 //****************************************************************
199 gMicAutoParam.rate = (u32)(gMicAutoParam.rate / 2);
200 if (gMicAutoParam.rate < MIC_SAMPLING_RATE_LIMIT)
201 {
202 gMicAutoParam.rate = MIC_SAMPLING_RATE_LIMIT;
203 }
204 (void)MIC_AdjustAutoSampling(gMicAutoParam.rate);
205 //****************************************************************
206 PrintfVariableData();
207 }
208 if ((gKey.trg | gKey.rep) & PAD_KEY_DOWN)
209 {
210 //****************************************************************
211 gMicAutoParam.rate = (u32)(gMicAutoParam.rate * 2);
212 if (gMicAutoParam.rate < MIC_SAMPLING_RATE_LIMIT)
213 {
214 gMicAutoParam.rate = MIC_SAMPLING_RATE_LIMIT;
215 }
216 (void)MIC_AdjustAutoSampling(gMicAutoParam.rate);
217 //****************************************************************
218 PrintfVariableData();
219 }
220 // Change loop availability when buffer is full
221 if ((gKey.trg | gKey.rep) & (PAD_BUTTON_SELECT | PAD_BUTTON_START))
222 {
223 //****************************************************************
224 (void)MIC_StopAutoSampling();
225 gMicAutoParam.loop_enable = (gMicAutoParam.loop_enable + 1) % 2;
226 (void)MIC_StartAutoSampling(&gMicAutoParam);
227 //****************************************************************
228 PrintfVariableData();
229 }
230 }
231
232 // Render waveform
233 SetDrawData(MIC_GetLastSamplingAddress(), gMicAutoParam.type);
234 Draw3D();
235
236 // Waiting for the V-Blank
237 OS_WaitVBlankIntr();
238 }
239 }
240
241 /*---------------------------------------------------------------------------*
242 Name: InitializeAllocateSystem
243
244 Description: Initializes the memory allocation system within the main memory arena.
245
246 Arguments: None.
247
248 Returns: None.
249 *---------------------------------------------------------------------------*/
InitializeAllocateSystem(void)250 static void InitializeAllocateSystem(void)
251 {
252 void *tempLo;
253 OSHeapHandle hh;
254
255 tempLo = OS_InitAlloc(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1);
256 OS_SetArenaLo(OS_ARENA_MAIN, tempLo);
257 hh = OS_CreateHeap(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi());
258 if (hh < 0)
259 {
260 OS_Panic("ARM9: Fail to create heap...\n");
261 }
262 hh = OS_SetCurrentHeap(OS_ARENA_MAIN, hh);
263 }
264
265 /*---------------------------------------------------------------------------*
266 Name: Init3D
267
268 Description: Initialization for 3D display.
269
270 Arguments: None.
271
272 Returns: None.
273 *---------------------------------------------------------------------------*/
Init3D(void)274 static void Init3D(void)
275 {
276 G3X_Init();
277 G3X_InitMtxStack();
278 GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_3D);
279 GX_SetVisiblePlane(GX_PLANEMASK_BG0);
280 G2_SetBG0Priority(0);
281 G3X_AlphaTest(FALSE, 0);
282 G3X_AntiAlias(TRUE);
283 G3X_EdgeMarking(FALSE);
284 G3X_SetFog(FALSE, (GXFogBlend)0, (GXFogSlope)0, 0);
285 G3X_SetClearColor(0, 0, 0x7fff, 63, FALSE);
286 G3_ViewPort(0, 0, 255, 191);
287 G3_MtxMode(GX_MTXMODE_POSITION_VECTOR);
288 }
289
290 /*---------------------------------------------------------------------------*
291 Name: Draw3D
292
293 Description: Displays waveforms in 3D.
294
295 Arguments: None.
296
297 Returns: None.
298 *---------------------------------------------------------------------------*/
Draw3D(void)299 static void Draw3D(void)
300 {
301 G3X_Reset();
302 G3_Identity();
303 G3_PolygonAttr(GX_LIGHTMASK_NONE, GX_POLYGONMODE_MODULATE, GX_CULL_NONE, 0, 31, 0);
304
305 {
306 s32 i;
307
308 if ((gMicAutoParam.type == MIC_SAMPLING_TYPE_SIGNED_8BIT) ||
309 (gMicAutoParam.type == MIC_SAMPLING_TYPE_SIGNED_12BIT) ||
310 (gMicAutoParam.type == MIC_SAMPLING_TYPE_SIGNED_12BIT_FILTER_OFF))
311 {
312 for (i = 0; i < 191; i++)
313 {
314 DrawLine((s16)((s8)gDrawData[i]),
315 (s16)i, (s16)((s8)gDrawData[i + 1]), (s16)(i + 1));
316 }
317 }
318 else
319 {
320 for (i = 0; i < 191; i++)
321 {
322 DrawLine((s16)(gDrawData[i]), (s16)i, (s16)(gDrawData[i + 1]), (s16)(i + 1));
323 }
324 }
325 }
326
327 G3_SwapBuffers(GX_SORTMODE_AUTO, GX_BUFFERMODE_W);
328 }
329
330 /*---------------------------------------------------------------------------*
331 Name: DrawLine
332
333 Description: Renders lines with triangular polygons.
334
335 Arguments: sx: X-coordinate of line's starting point
336 sy: Y-coordinate of line's starting point
337 ex: X-coordinate of line's ending point
338 ey: Y-coordinate of line's ending point
339
340 Returns: None.
341 *---------------------------------------------------------------------------*/
DrawLine(s16 sx,s16 sy,s16 ex,s16 ey)342 static void DrawLine(s16 sx, s16 sy, s16 ex, s16 ey)
343 {
344 fx16 fsx = (fx16)(((sx - 128) * 0x1000) / 128);
345 fx16 fsy = (fx16)(((96 - sy) * 0x1000) / 96);
346 fx16 fex = (fx16)(((ex - 128) * 0x1000) / 128);
347 fx16 fey = (fx16)(((96 - ey) * 0x1000) / 96);
348
349 G3_Begin(GX_BEGIN_TRIANGLES);
350 {
351 G3_Color(GX_RGB(31, 31, 31));
352 G3_Vtx(fsx, fsy, 0);
353 G3_Color(GX_RGB(31, 31, 31));
354 G3_Vtx(fex, fey, 0);
355 G3_Color(GX_RGB(31, 31, 31));
356 G3_Vtx(fsx, fsy, 1);
357 }
358 G3_End();
359 }
360
361 /*---------------------------------------------------------------------------*
362 Name: VBlankIntr
363
364 Description: V-Blank interrupt vector.
365
366 Arguments: None.
367
368 Returns: None.
369 *---------------------------------------------------------------------------*/
VBlankIntr(void)370 static void VBlankIntr(void)
371 {
372 // Sets the IRQ check flag
373 OS_SetIrqCheckFlag(OS_IE_V_BLANK);
374 }
375
376 /*---------------------------------------------------------------------------*
377 Name: KeyRead
378
379 Description: Edits key input data.
380 Detects press trigger, release trigger, and press-and-hold repeat.
381
382 Arguments: pKey: Structure that holds key input data to be edited
383
384 Returns: None.
385 *---------------------------------------------------------------------------*/
KeyRead(KeyInformation * pKey)386 static void KeyRead(KeyInformation * pKey)
387 {
388 static u16 repeat_count[12];
389 int i;
390 u16 r;
391
392 r = PAD_Read();
393 pKey->trg = 0x0000;
394 pKey->up = 0x0000;
395 pKey->rep = 0x0000;
396
397 for (i = 0; i < 12; i++)
398 {
399 if (r & (0x0001 << i))
400 {
401 if (!(pKey->cnt & (0x0001 << i)))
402 {
403 pKey->trg |= (0x0001 << i); // Press trigger
404 repeat_count[i] = 1;
405 }
406 else
407 {
408 if (repeat_count[i] > KEY_REPEAT_START)
409 {
410 pKey->rep |= (0x0001 << i); // Press-and-hold repeat
411 repeat_count[i] = KEY_REPEAT_START - KEY_REPEAT_SPAN;
412 }
413 else
414 {
415 repeat_count[i]++;
416 }
417 }
418 }
419 else
420 {
421 if (pKey->cnt & (0x0001 << i))
422 {
423 pKey->up |= (0x0001 << i); // Release trigger
424 }
425 }
426 }
427 pKey->cnt = r; // Unprocessed key input
428 }
429
430 /*---------------------------------------------------------------------------*
431 Name: SetDrawData
432
433 Description: Stores the current newest sampled data in the buffer that puts it on the display.
434
435
436 Arguments: address: Location in main memory where the most recent sampling data is stored by the components
437
438 type: Sampling type (bit width)
439
440 Returns: None.
441 *---------------------------------------------------------------------------*/
SetDrawData(void * address,MICSamplingType type)442 static void SetDrawData(void *address, MICSamplingType type)
443 {
444 s32 i;
445
446 // If sampling has never been performed, do nothing and stop.
447 // (Because it would delete memory cache(s) unrelated to the microphone)
448 if ((address < gMicData) || (address >= (gMicData + TEST_BUFFER_SIZE)))
449 {
450 return;
451 }
452
453 // In the case of 8-bit sampling
454 switch (type)
455 {
456 case MIC_SAMPLING_TYPE_8BIT:
457 case MIC_SAMPLING_TYPE_SIGNED_8BIT:
458 {
459 u8 *p;
460
461 p = (u8 *)((u32)address - 191);
462 if (p < gMicData)
463 {
464 p = (u8 *)((u32)p + TEST_BUFFER_SIZE);
465 }
466 DC_InvalidateRange((void *)((u32)p & 0xffffffe0), 32);
467 for (i = 0; i < 192; i++)
468 {
469 gDrawData[i] = *p;
470 p++;
471 if ((u32)p >= (u32)(gMicData + TEST_BUFFER_SIZE))
472 {
473 p -= TEST_BUFFER_SIZE;
474 }
475 if (((u32)p % 32) == 0)
476 {
477 DC_InvalidateRange(p, 32);
478 }
479 }
480 }
481 break;
482 case MIC_SAMPLING_TYPE_12BIT:
483 case MIC_SAMPLING_TYPE_SIGNED_12BIT:
484 case MIC_SAMPLING_TYPE_12BIT_FILTER_OFF:
485 case MIC_SAMPLING_TYPE_SIGNED_12BIT_FILTER_OFF:
486 {
487 u16 *p;
488
489 p = (u16 *)((u32)address - 382);
490 if ((u32)p < (u32)gMicData)
491 {
492 p = (u16 *)((u32)p + TEST_BUFFER_SIZE);
493 }
494 DC_InvalidateRange((void *)((u32)p & 0xffffffe0), 32);
495 for (i = 0; i < 192; i++)
496 {
497 gDrawData[i] = (u8)((*p >> 8) & 0x00ff);
498 p++;
499 if ((u32)p >= (u32)(gMicData + TEST_BUFFER_SIZE))
500 {
501 p = (u16 *)((u32)p - TEST_BUFFER_SIZE);
502 }
503 if (((u32)p % 32) == 0)
504 {
505 DC_InvalidateRange(p, 32);
506 }
507 }
508 }
509 break;
510 }
511 }
512
513 /*---------------------------------------------------------------------------*
514 Name: PrintfVariableData
515
516 Description: Print out the variable sampling settings.
517
518 Arguments: None.
519
520 Returns: None.
521 *---------------------------------------------------------------------------*/
PrintfVariableData(void)522 static void PrintfVariableData(void)
523 {
524 s32 range = 0;
525
526 OS_Printf(" sampling-span: %d , bit-range: ", gMicAutoParam.rate);
527 switch (gMicAutoParam.type)
528 {
529 case MIC_SAMPLING_TYPE_8BIT:
530 OS_Printf("8");
531 break;
532 case MIC_SAMPLING_TYPE_12BIT:
533 OS_Printf("12");
534 break;
535 case MIC_SAMPLING_TYPE_SIGNED_8BIT:
536 OS_Printf("signed 8");
537 break;
538 case MIC_SAMPLING_TYPE_SIGNED_12BIT:
539 OS_Printf("signed 12");
540 break;
541 case MIC_SAMPLING_TYPE_12BIT_FILTER_OFF:
542 OS_Printf("12(filter off)");
543 break;
544 case MIC_SAMPLING_TYPE_SIGNED_12BIT_FILTER_OFF:
545 OS_Printf("signed 12(filter off)");
546 break;
547 }
548 if (gMicAutoParam.loop_enable)
549 {
550 OS_Printf(" , loop: on\n");
551 }
552 else
553 {
554 OS_Printf(" , loop: off\n");
555 }
556 }
557
558
559 /*---------------------------------------------------------------------------*
560 End of file
561 *---------------------------------------------------------------------------*/
562