1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - demos.TWL - SPI - pm-2
3   File:     main.c
4 
5   Copyright 2008-2009 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-11-13#$
14   $Rev: 0 $
15   $Author: yada $
16  *---------------------------------------------------------------------------*/
17 #include  <nitro.h>
18 #include  "font.h"
19 #include  "screen.h"
20 #include  "DEMO.h"
21 
22 #define EXIT_COUNT 0xA0
23 
24 //---- For RTC
25 static RTCTime myCurrentTime;
26 
27 //---- V-Count
28 static u32 myVCount;
29 
30 //---- Auto exit flag
31 static BOOL isAutoExit = FALSE;
32 
33 //---- Exit callback info
34 static PMExitCallbackInfo exitCallbackInfo;
35 
36 //---- Whether exit callback was called
37 static BOOL isExit = FALSE;
38 
39 //---- Exit delay counter
40 static int  exitCounter;
41 
42 static void myInit(void);
43 static void myVBlankIntr(void);
44 static void myExitCallback(void *arg);
45 
46 /*---------------------------------------------------------------------------*
47   Name:         NitroMain
48 
49   Description:  Main
50 
51   Arguments:    None.
52 
53   Returns:      None.
54  *---------------------------------------------------------------------------*/
NitroMain(void)55 void NitroMain(void)
56 {
57     u16     preButton;
58     u16     button;
59     u16     trigger;
60 
61     //---------------- Initialize
62     myInit();
63     RTC_Init();
64 
65     // When in NITRO mode, stopped by Panic
66     DEMOCheckRunOnTWL();
67 
68     PM_SetAutoExit( isAutoExit );
69 
70     OS_Printf("[ARM9] set exit callback\n");
71     PM_SetExitCallbackInfo( &exitCallbackInfo, myExitCallback, (void*)100 );
72     PM_AppendPreExitCallback( &exitCallbackInfo );
73 
74     preButton = PAD_Read();            // Dummy read for pressing 'A' on IPL
75 
76     //---------------- Main loop
77     while (TRUE)
78     {
79         button = PAD_Read();
80         trigger = (u16)((button ^ preButton) & button);
81         preButton = button;
82 
83         //---- V-Blank count
84         myVCount = OS_GetVBlankCount();
85 
86         //---- Counter
87         if ( isExit )
88         {
89             if ( -- exitCounter < 0 )
90             {
91                 PM_ReadyToExit();
92             }
93         }
94 
95         //---- Clear screen buffer
96         ClearScreen();
97 
98         //---- Display key description
99         PrintString(3, 4, 15, "A : toggle Auto Exit mode");
100         PrintString(3, 6, 15, "X : do hardware reset");
101 
102         //---- Display time
103         if (RTC_GetTime(&myCurrentTime) == 0 /*No error */ )
104         {
105             PrintString(5, 20, 8, "%02d:%02d:%02d", myCurrentTime.hour, myCurrentTime.minute, myCurrentTime.second);
106         }
107 
108         //---- Display AutoExit mode
109         {
110             BOOL a = PM_GetAutoExit();
111             PrintString(8, 16, 15, "AUTO EXIT : %s", a? "TRUE": "FALSE" );
112         }
113 
114         //---- Display v-counter
115         PrintString(18, 20, 4, "%08X", myVCount);
116 
117         //---- Display count
118         if ( isExit )
119         {
120             static int blinkCount = 0;
121             if ( (++ blinkCount) & 0x4 )
122             {
123                 PrintString(12, 12, 1, "NOW EXIT...");
124             }
125             PrintString(15, 10, 4, "%X", exitCounter / 0x10);
126         }
127 
128         //---- Push A to switch top backlight on/off
129         if (trigger & PAD_BUTTON_A)
130         {
131             isAutoExit = (isAutoExit == FALSE);
132             PM_SetAutoExit( isAutoExit );
133         }
134 
135         //---- Push X to do hardware reset
136         if (trigger & PAD_BUTTON_X)
137         {
138             (void)OS_RebootSystem();
139             // Do not call the PM_ForceToResetHardware function directly
140         }
141 
142         OS_WaitVBlankIntr();
143     }
144 }
145 
146 //----------------------------------------------------------------
147 //  myInit
148 //
myInit(void)149 void myInit(void)
150 {
151     //---- Init
152     OS_Init();
153     OS_InitTick();
154     OS_InitAlarm();
155     FX_Init();
156     GX_Init();
157     GX_DispOff();
158     GXS_DispOff();
159 
160     //---- Display init
161     GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
162     MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
163     (void)GX_DisableBankForLCDC();
164 
165     MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE);
166     MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE);
167     MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE);
168     MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE);
169 
170     //---- Setting 2D for top screen
171     GX_SetBankForBG(GX_VRAM_BG_128_A);
172 
173     G2_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256,
174                      GX_BG_COLORMODE_16,
175                      GX_BG_SCRBASE_0xf800, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01);
176     G2_SetBG0Priority(0);
177     G2_BG0Mosaic(FALSE);
178     GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_2D);
179     GX_SetVisiblePlane(GX_PLANEMASK_BG0);
180 
181     GX_LoadBG0Char(d_CharData, 0, sizeof(d_CharData));
182     GX_LoadBGPltt(d_PaletteData, 0, sizeof(d_PaletteData));
183 
184 
185 
186     //---- Setting 2D for bottom screen
187     GX_SetBankForSubBG(GX_VRAM_SUB_BG_128_C);
188 
189     G2S_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256,
190                       GX_BG_COLORMODE_16,
191                       GX_BG_SCRBASE_0xf800, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01);
192     G2S_SetBG0Priority(0);
193     G2S_BG0Mosaic(FALSE);
194     GXS_SetGraphicsMode(GX_BGMODE_0);
195     GXS_SetVisiblePlane(GX_PLANEMASK_BG0);
196 
197     GXS_LoadBG0Char(d_CharData, 0, sizeof(d_CharData));
198     GXS_LoadBGPltt(d_PaletteData, 0, sizeof(d_PaletteData));
199 
200 
201     //---- Screen
202     MI_CpuFillFast((void *)gScreen, 0, sizeof(gScreen));
203     DC_FlushRange(gScreen, sizeof(gScreen));
204     /* I/O register is accessed using DMA operation, so cache wait is not needed */
205     // DC_WaitWriteBufferEmpty();
206     GX_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
207     GXS_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
208 
209     //---- Init interrupt
210     OS_SetIrqFunction(OS_IE_V_BLANK, myVBlankIntr);
211     (void)OS_EnableIrqMask(OS_IE_V_BLANK);
212     (void)GX_VBlankIntr(TRUE);
213     (void)OS_EnableIrq();
214     (void)OS_EnableInterrupts();
215 
216     //---- FileSytem init
217     FS_Init(FS_DMA_NOT_USE);
218 
219     //---- Start displaying
220     GX_DispOn();
221     GXS_DispOn();
222 }
223 
224 //----------------------------------------------------------------
225 //  myVBlankIntr
226 //             V-Blank interrupt handler
227 //
myVBlankIntr(void)228 static void myVBlankIntr(void)
229 {
230     //---- Upload pseudo screen to VRAM
231     DC_FlushRange(gScreen, sizeof(gScreen));
232     /* I/O register is accessed using DMA operation, so cache wait is not needed */
233     // DC_WaitWriteBufferEmpty();
234     GX_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
235     GXS_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
236 
237     OS_SetIrqCheckFlag(OS_IE_V_BLANK);
238 }
239 
240 //================================================================
241 //----------------------------------------------------------------
242 //  myExitCallback
243 //
myExitCallback(void * arg)244 void myExitCallback(void *arg)
245 {
246 #ifdef SDK_FINALROM
247 #pragma unused( arg )
248 #endif
249     OS_Printf("exit callback. arg=%d factor=%d\n", arg, PM_GetExitFactor() );
250 
251     exitCounter = EXIT_COUNT;
252     isExit = TRUE;
253 }
254