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