1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - demos.TWL - os - os_jump
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 #include <twl.h>
19 #include <stdlib.h>
20 
21 #include "screen.h"
22 #include "DEMO.h"
23 
24 /*---------------------------------------------------------------------------*
25     Constant Definitions
26  *---------------------------------------------------------------------------*/
27 #define KEY_REPEAT_START    25  // Number of frames until key repeat starts
28 #define KEY_REPEAT_SPAN     10  // Number of frames between key repeats
29 
30 /*---------------------------------------------------------------------------*
31     Structure Definitions
32  *---------------------------------------------------------------------------*/
33 
34 // Key input data
35 typedef struct KeyInfo
36 {
37     u16 cnt;    // Unprocessed input value
38     u16 trg;    // Push trigger input
39     u16 up;     // Release trigger input
40     u16 rep;    // Press and hold repeat input
41 } KeyInfo;
42 
43 // Key input
44 static KeyInfo  gKey;
45 
46 /*---------------------------------------------------------------------------*
47    Prototype
48  *---------------------------------------------------------------------------*/
49 
50 static void VBlankIntr(void);
51 static void InitInterrupts(void);
52 static void InitHeap(void);
53 
54 static void ReadKey(KeyInfo* pKey);
55 
56 /*---------------------------------------------------------------------------*/
57 
TwlMain(void)58 void TwlMain(void)
59 {
60     OS_Init();
61     OS_InitTick();
62     OS_InitAlarm();
63 
64     // When in NITRO mode, stopped by Panic
65     DEMOCheckRunOnTWL();
66 
67     GX_Init();
68     GX_DispOff();
69     GXS_DispOff();
70 
71     InitHeap();
72     InitScreen();
73     InitInterrupts();
74 
75     GX_DispOn();
76     GXS_DispOn();
77 
78     ClearScreen();
79 
80     // Empty call for getting key input data (strategy for pressing A Button in the IPL)
81     ReadKey(&gKey);
82 
83     while(TRUE)
84     {
85         // Get key input data
86         ReadKey(&gKey);
87 
88         // Clear the main screen
89         ClearScreen();
90 
91         PutMainScreen(0, 0, 0xff, "OS_IsRebooted = %s", OS_IsRebooted()? "TRUE":"FALSE");
92 
93         PutSubScreen(0, 0, 0xff, "APPLICATION JUMP DEMO");
94         PutSubScreen(0, 1, 0xff, "  A: OS_JumpToSystemMenu");
95         PutSubScreen(0, 2, 0xff, "  B: OS_RebootSystem");
96         PutSubScreen(0, 3, 0xff, "  X: OS_JumpToEULAViewer");
97         PutSubScreen(0, 4, 0xff, "  Y: OS_JumpToInternetSetting");
98         PutSubScreen(0, 5, 0xff, "  R: OS_JumpToWirelessSetting");
99 
100         if (gKey.trg & PAD_BUTTON_A)
101         {
102             if (FALSE == OS_JumpToSystemMenu() )
103             {
104                 //Jump failure
105                 OS_Panic("OS_JumpToSystemMenu() is Failed");
106             }
107         }
108 
109         if (gKey.trg & PAD_BUTTON_B)
110         {
111             if (FALSE == OS_RebootSystem() )
112             {
113                 //Jump failure
114                 OS_Panic("OS_RebootSystem() is Failed");
115             }
116         }
117 
118         if (gKey.trg & PAD_BUTTON_X)
119         {
120             if (FALSE == OS_JumpToEULAViewer() )
121             {
122                 //Jump failure
123                 OS_Panic("OS_JumpToEULAViewer() is Failed");
124             }
125         }
126 
127         if (gKey.trg & PAD_BUTTON_Y)
128         {
129             if (FALSE == OS_JumpToInternetSetting() )
130             {
131                 //Jump failure
132                 OS_Panic("OS_JumpToInternetSetting() is Failed");
133             }
134         }
135         if (gKey.trg & PAD_BUTTON_R)
136         {
137             if (FALSE == OS_JumpToWirelessSetting() )
138             {
139                 //Jump failure
140                 OS_Panic("OS_JumpToWirelessSetting() is Failed");
141             }
142         }
143         // Wait for V-Blank (this supports threading)
144         OS_WaitVBlankIntr();
145     }
146 
147     OS_Terminate();
148 }
149 
150 /*---------------------------------------------------------------------------*
151   Name:         VBlankIntr
152 
153   Description:  V-Blank interrupt handler.
154 
155   Arguments:    None.
156 
157   Returns:      None.
158  *---------------------------------------------------------------------------*/
VBlankIntr(void)159 static void VBlankIntr(void)
160 {
161     // Updates text display
162     UpdateScreen();
163 
164     // Sets the IRQ check flag
165     OS_SetIrqCheckFlag(OS_IE_V_BLANK);
166 }
167 
168 /*---------------------------------------------------------------------------*
169   Name:         InitInterrupts
170 
171   Description:  Initializes the interrupt settings.
172                 Allows V-Blank interrupts and configures the interrupt handler.
173 
174   Arguments:    None.
175 
176   Returns:      None.
177  *---------------------------------------------------------------------------*/
InitInterrupts(void)178 static void InitInterrupts(void)
179 {
180     // V-Blank interrupt settings
181     OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
182     (void)OS_EnableIrqMask(OS_IE_V_BLANK);
183     (void)GX_VBlankIntr(TRUE);
184 
185     // Allow interrupts
186     (void)OS_EnableIrq();
187     (void)OS_EnableInterrupts();
188 }
189 
190 /*---------------------------------------------------------------------------*
191   Name:         InitHeap
192 
193   Description:  Initializes the memory allocation system within the main memory arena.
194 
195   Arguments:    None.
196 
197   Returns:      None.
198  *---------------------------------------------------------------------------*/
InitHeap(void)199 static void InitHeap(void)
200 {
201     void*           tempLo;
202     OSHeapHandle    hh;
203 
204     // Creates a heap in the main memory arena
205     tempLo = OS_InitAlloc(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1);
206     OS_SetArenaLo(OS_ARENA_MAIN, tempLo);
207     hh = OS_CreateHeap(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi());
208     if (hh < 0)
209     {
210         // Abnormal end when heap creation fails
211         OS_Panic("ARM9: Fail to create heap...\n");
212     }
213     (void)OS_SetCurrentHeap(OS_ARENA_MAIN, hh);
214 }
215 
216 /*---------------------------------------------------------------------------*
217   Name:         ReadKey
218 
219   Description:  Gets key input data and edits the input data structure.
220                 Detects push, release, and push and hold repeat triggers.
221 
222   Arguments:    pKey: Key input structure to be changed
223 
224   Returns:      None.
225  *---------------------------------------------------------------------------*/
ReadKey(KeyInfo * pKey)226 static void ReadKey(KeyInfo* pKey)
227 {
228     static u16  repeat_count[12];
229     int         i;
230     u16         r;
231 
232     r = PAD_Read();
233     pKey->trg = 0x0000;
234     pKey->up = 0x0000;
235     pKey->rep = 0x0000;
236 
237     for (i = 0; i < 12; i++)
238     {
239         if (r & (0x0001 << i))
240         {
241             if (!(pKey->cnt & (0x0001 << i)))
242             {
243                 pKey->trg |= (0x0001 << i);     // Press trigger
244                 repeat_count[i] = 1;
245             }
246             else
247             {
248                 if (repeat_count[i] > KEY_REPEAT_START)
249                 {
250                     pKey->rep |= (0x0001 << i); // Press-and-hold repeat
251                     repeat_count[i] = (u16) (KEY_REPEAT_START - KEY_REPEAT_SPAN);
252                 }
253                 else
254                 {
255                     repeat_count[i]++;
256                 }
257             }
258         }
259         else
260         {
261             if (pKey->cnt & (0x0001 << i))
262             {
263                 pKey->up |= (0x0001 << i);      // Release trigger
264             }
265         }
266     }
267 
268     pKey->cnt = r;  // Unprocessed key input
269 }
270 
271 /*---------------------------------------------------------------------------*
272   End of file
273  *---------------------------------------------------------------------------*/
274