1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - RTC - demos - swclock-1
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:: 2007-11-02#$
14 $Rev: 2048 $
15 $Author: tokunaga_eiji $
16 *---------------------------------------------------------------------------*/
17
18 #ifdef SDK_TWL
19 #include <twl.h>
20 #include <twl/rtc.h>
21 #else
22 #include <nitro.h>
23 #include <nitro/rtc.h>
24 #endif
25
26 #include "font.h"
27
28
29 /*---------------------------------------------------------------------------*
30 Constant Definitions
31 *---------------------------------------------------------------------------*/
32 #define KEY_REPEAT_START 25 // Number of frames until key repeat starts
33 #define KEY_REPEAT_SPAN 10 // Number of frames between key repeats
34
35
36 /*---------------------------------------------------------------------------*
37 Character string constant definitions
38 *---------------------------------------------------------------------------*/
39 // Day of the week
40 const char *StrWeek[7] = {
41 "Sunday",
42 "Monday",
43 "Tuesday",
44 "Wednesday",
45 "Thursday",
46 "Friday",
47 "Saturday"
48 };
49
50 /*---------------------------------------------------------------------------*
51 Structure Definitions
52 *---------------------------------------------------------------------------*/
53 // Key input data
54 typedef struct KeyInformation
55 {
56 u16 cnt; // Unprocessed input value
57 u16 trg; // Push trigger input
58 u16 up; // Release trigger input
59 u16 rep; // Press and hold repeat input
60
61 }
62 KeyInformation;
63
64 /*---------------------------------------------------------------------------*
65 Internal Function Definitions
66 *---------------------------------------------------------------------------*/
67 static void VBlankIntr(void);
68 static void AlarmIntrCallback(void);
69
70 static void KeyRead(KeyInformation * pKey);
71 static void ClearString(void);
72 static void PrintString(s16 x, s16 y, u8 palette, char *text, ...);
73 static void ColorString(s16 x, s16 y, s16 length, u8 palette);
74
75
76 /*---------------------------------------------------------------------------*
77 Internal Variable Definitions
78 *---------------------------------------------------------------------------*/
79 static u16 gScreen[32 * 32]; // Virtual screen
80 static KeyInformation gKey; // Key input
81
82 static RTCDate gRtcDate; // Date obtained from the RTC
83 static RTCTime gRtcTime; // Time obtained from the RTC
84 static RTCDate gSWClockDate; // Date obtained from the software clock
85 static RTCTimeEx gSWClockTimeEx; // Time obtained from the software clock
86
87 /*---------------------------------------------------------------------------*
88 Name: NitroMain
89
90 Description: Initialization and main loop.
91
92 Arguments: None.
93
94 Returns: None.
95 *---------------------------------------------------------------------------*/
NitroMain(void)96 void NitroMain(void)
97 {
98 // Various types of initialization
99 OS_Init();
100 FX_Init();
101 GX_Init();
102 GX_DispOff();
103 GXS_DispOff();
104
105 // Initializes display settings
106 GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
107 MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
108 (void)GX_DisableBankForLCDC();
109 MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE);
110 MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE);
111 MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE);
112 MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE);
113
114 // 2D display settings for text string display
115 GX_SetBankForBG(GX_VRAM_BG_128_A);
116 G2_SetBG0Control(GX_BG_SCRSIZE_TEXT_256x256, GX_BG_COLORMODE_16, GX_BG_SCRBASE_0xf800, // SCR base block 31
117 GX_BG_CHARBASE_0x00000, // CHR base block 0
118 GX_BG_EXTPLTT_01);
119 G2_SetBG0Priority(0);
120 G2_BG0Mosaic(FALSE);
121 GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS, GX_BGMODE_0, GX_BG0_AS_2D);
122 GX_SetVisiblePlane(GX_PLANEMASK_BG0);
123 GX_LoadBG0Char(d_CharData, 0, sizeof(d_CharData));
124 GX_LoadBGPltt(d_PaletteData, 0, sizeof(d_PaletteData));
125 MI_CpuFillFast((void *)gScreen, 0, sizeof(gScreen));
126 DC_FlushRange(gScreen, sizeof(gScreen));
127 /* I/O register is accessed using DMA operation, so cache wait is not needed */
128 // DC_WaitWriteBufferEmpty();
129 GX_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
130
131 // Interrupt settings
132 OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
133 (void)OS_EnableIrqMask(OS_IE_V_BLANK);
134 (void)GX_VBlankIntr(TRUE);
135 (void)OS_EnableIrq();
136 (void)OS_EnableInterrupts();
137
138
139 //****************************************************************
140 // RTC initialization
141 RTC_Init();
142 // Initialize tick
143 OS_InitTick();
144 // Initialize software clock
145 (void)RTC_InitSWClock();
146 //****************************************************************
147
148 // LCD display start
149 GX_DispOn();
150 GXS_DispOn();
151
152 // Debug string output
153 OS_Printf("ARM9: SWClock demo started.\n");
154
155 // Empty call for getting key input data (strategy for pressing A button in the IPL)
156 KeyRead(&gKey);
157
158 // Main loop
159 while (TRUE)
160 {
161 // Get key input data
162 KeyRead(&gKey);
163
164 // Clear the screen
165 ClearString();
166
167 //****************************************************************
168 // Read date and time from the RTC
169 (void)RTC_GetDateTime(&gRtcDate, &gRtcTime);
170 // Read date and time from the software clock
171 (void)RTC_GetDateTimeExFromSWClock(&gSWClockDate, &gSWClockTimeEx);
172 //****************************************************************
173
174 // Display date obtained from the RTC
175 PrintString(1, 3, 0xf, "RTCDate:");
176 PrintString(10, 3, 0xf, "%04d/%02d/%02d/%s",
177 gRtcDate.year + 2000, gRtcDate.month, gRtcDate.day, StrWeek[gRtcDate.week]);
178 // Display date obtained from the software clock
179 PrintString(1, 5, 0xf, "SWCDate:");
180 PrintString(10, 5, 0xf, "%04d/%02d/%02d/%s",
181 gSWClockDate.year + 2000, gSWClockDate.month, gSWClockDate.day, StrWeek[gSWClockDate.week]);
182
183 // Display time obtained from the RTC
184 PrintString(1, 8, 0xf, "RTCTime:");
185 PrintString(10, 8, 0xf, "%02d:%02d:%02d", gRtcTime.hour, gRtcTime.minute, gRtcTime.second);
186 // Display time obtained from the software clock
187 PrintString(1, 10, 0xf, "SWCTime:");
188 PrintString(10, 10, 0xf, "%02d:%02d:%02d:%03d", gSWClockTimeEx.hour, gSWClockTimeEx.minute,
189 gSWClockTimeEx.second, gSWClockTimeEx.millisecond);
190
191 // Display the total number of ticks that have occurred since midnight on January 1st, 2000 (this value was obtained from the software clock)
192 PrintString(1, 13, 0xf, "SWCTick:");
193 PrintString(10, 13, 0xf, "%llu", RTC_GetSWClockTick() );
194
195 // Display explanation of button operations
196 PrintString(1, 19, 0x3, "START > Synclonize SWC with RTC.");
197 PrintString(1, 20, 0x3, "A > Go to sleep.");
198 PrintString(1, 21, 0x3, "B > Wake up from sleep.");
199
200
201 // Button input operation
202 // START button
203 if ((gKey.trg) & PAD_BUTTON_START)
204 {
205 OS_TPrintf("Synchronizing SWC with RTC.\n");
206 (void)RTC_SyncSWClock();
207 }
208
209 // A button
210 if (gKey.trg & PAD_BUTTON_A)
211 {
212 OS_TPrintf("Going to sleep... Press B button to wake up.\n");
213 PM_GoSleepMode( PM_TRIGGER_KEY, PM_PAD_LOGIC_AND, PAD_BUTTON_B );
214 }
215
216 // Waiting for the V-Blank
217 OS_WaitVBlankIntr();
218 }
219 }
220
221 /*---------------------------------------------------------------------------*
222 Name: VBlankIntr
223
224 Description: V-Blank interrupt vector.
225
226 Arguments: None.
227
228 Returns: None.
229 *---------------------------------------------------------------------------*/
VBlankIntr(void)230 static void VBlankIntr(void)
231 {
232 // Reflect virtual screen in VRAM
233 DC_FlushRange(gScreen, sizeof(gScreen));
234 /* I/O register is accessed using DMA operation, so cache wait is not needed */
235 // DC_WaitWriteBufferEmpty();
236 GX_LoadBG0Scr(gScreen, 0, sizeof(gScreen));
237
238 // Sets the IRQ check flag
239 OS_SetIrqCheckFlag(OS_IE_V_BLANK);
240 }
241
242 /*---------------------------------------------------------------------------*
243 Name: KeyRead
244
245 Description: Edits key input data.
246 Detects press trigger, release trigger, and press-and-hold repeat.
247
248 Arguments: pKey: Structure that holds key input data to be edited
249
250 Returns: None.
251 *---------------------------------------------------------------------------*/
KeyRead(KeyInformation * pKey)252 static void KeyRead(KeyInformation * pKey)
253 {
254 static u16 repeat_count[12];
255 int i;
256 u16 r;
257
258 r = PAD_Read();
259 pKey->trg = 0x0000;
260 pKey->up = 0x0000;
261 pKey->rep = 0x0000;
262
263 for (i = 0; i < 12; i++)
264 {
265 if (r & (0x0001 << i))
266 {
267 if (!(pKey->cnt & (0x0001 << i)))
268 {
269 pKey->trg |= (0x0001 << i); // Press trigger
270 repeat_count[i] = 1;
271 }
272 else
273 {
274 if (repeat_count[i] > KEY_REPEAT_START)
275 {
276 pKey->rep |= (0x0001 << i); // Press-and-hold repeat
277 repeat_count[i] = KEY_REPEAT_START - KEY_REPEAT_SPAN;
278 }
279 else
280 {
281 repeat_count[i]++;
282 }
283 }
284 }
285 else
286 {
287 if (pKey->cnt & (0x0001 << i))
288 {
289 pKey->up |= (0x0001 << i); // Release trigger
290 }
291 }
292 }
293 pKey->cnt = r; // Unprocessed key input
294 }
295
296 /*---------------------------------------------------------------------------*
297 Name: ClearString
298
299 Description: Clears the virtual screen.
300
301 Arguments: None.
302
303 Returns: None.
304 *---------------------------------------------------------------------------*/
ClearString(void)305 static void ClearString(void)
306 {
307 MI_CpuClearFast((void *)gScreen, sizeof(gScreen));
308 }
309
310 /*---------------------------------------------------------------------------*
311 Name: PrintString
312
313 Description: Positions the text string on the virtual screen. The string can be up to 32 chars.
314
315 Arguments: x: X-coordinate where character string starts (x 8 dots)
316 y: Y-coordinate where character string starts (x 8 dots)
317 palette: Specify text color by palette number
318 text: Text string to position. NULL terminated.
319 ...: Virtual argument
320
321 Returns: None.
322 *---------------------------------------------------------------------------*/
PrintString(s16 x,s16 y,u8 palette,char * text,...)323 static void PrintString(s16 x, s16 y, u8 palette, char *text, ...)
324 {
325 va_list vlist;
326 char temp[32 + 2];
327 s32 i;
328
329 va_start(vlist, text);
330 (void)vsnprintf(temp, 33, text, vlist);
331 va_end(vlist);
332
333 *(u16 *)(&temp[32]) = 0x0000;
334 for (i = 0;; i++)
335 {
336 if (temp[i] == 0x00)
337 {
338 break;
339 }
340 gScreen[((y * 32) + x + i) % (32 * 32)] = (u16)((palette << 12) | temp[i]);
341 }
342 }
343
344 /*---------------------------------------------------------------------------*
345 Name: ColorString
346
347 Description: Changes the color of character strings printed on the virtual screen.
348
349 Arguments: x: X-coordinate (x 8 dots ) from which to start color change
350 y: Y-coordinate (x 8 dots ) from which to start color change
351 length: Number of characters to continue the color change for
352 palette: Specify text color by palette number
353
354 Returns: None.
355 *---------------------------------------------------------------------------*/
ColorString(s16 x,s16 y,s16 length,u8 palette)356 static void ColorString(s16 x, s16 y, s16 length, u8 palette)
357 {
358 s32 i;
359 u16 temp;
360 s32 index;
361
362 if (length < 0)
363 return;
364
365 for (i = 0; i < length; i++)
366 {
367 index = ((y * 32) + x + i) % (32 * 32);
368 temp = gScreen[index];
369 temp &= 0x0fff;
370 temp |= (palette << 12);
371 gScreen[index] = temp;
372 }
373 }
374
375 /*---------------------------------------------------------------------------*
376 End of file
377 *---------------------------------------------------------------------------*/
378