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