1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - demos - spi - tp-2
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:: 2009-06-08#$
14   $Rev: 10700 $
15   $Author: yosizaki $
16  *---------------------------------------------------------------------------*/
17 
18 #include    <nitro.h>
19 
20 #define     CHATTER_RANGE           20
21 #define     CHATTER_RETRY           5
22 
23 #define     SAMPLING_FREQUENCE      4  // Touch-Panel sampling frequency per frame
24 #define     SAMPLING_BUFSIZE        (SAMPLING_FREQUENCE + 1)    // Auto-sampling buffer size
25 #define     SAMPLING_START_VCOUNT   0  // Base V-Count value in auto-sampling
26 
27 /*---------------------------------------------------------------------------*
28     Prototype definitions
29  *---------------------------------------------------------------------------*/
30 static void VBlankIntr(void);
31 static void KeyInit(void);
32 static void KeyRead(void);
33 static inline void PutDot(u16 x, u16 y, u16 col);
34 static void DrawLine(u16 x1, u16 y1, u16 x2, u16 y2, u16 col);
35 static void HandDraw(TPData *buf, u32 size);
36 
37 
38 // Key States
39 static struct
40 {
41     u16     con;
42     u16     trg;
43 }
44 keys;
45 
46 
47 /*---------------------------------------------------------------------------*
48     Static variable definitions
49  *---------------------------------------------------------------------------*/
50 static TPData gTpBuf[SAMPLING_BUFSIZE];
51 
52 
53 /*---------------------------------------------------------------------------*
54   Name:         PutDot
55 
56   Description:  Draws a dot in VRAM for LCDC.
57 
58   Arguments:    x: Position X
59                 y: Position Y
60                 col: DotColor
61 
62   Returns:      None.
63  *---------------------------------------------------------------------------*/
PutDot(u16 x,u16 y,u16 col)64 static inline void PutDot(u16 x, u16 y, u16 col)
65 {
66     *(u16 *)(HW_LCDC_VRAM_C + y * 256 * 2 + x * 2) = col;
67 }
68 
69 
70 /*---------------------------------------------------------------------------*
71   Name:         DrawLine
72 
73   Description:  Draws a line VRAM for LCDC.
74 
75   Arguments:    x1: Beginning X coordinate
76                 y1: Beginning Y coordinate
77                 x2: Ending X coordinate
78                 y2: Ending Y coordinate
79                 col: Line color
80 
81   Returns:      None.
82  *---------------------------------------------------------------------------*/
DrawLine(u16 x1,u16 y1,u16 x2,u16 y2,u16 col)83 static void DrawLine(u16 x1, u16 y1, u16 x2, u16 y2, u16 col)
84 {
85     u16     width, height;
86     u16     i, min, max, base;
87     u16     px, py;
88 
89     width = (u16)((x1 >= x2) ? (x1 - x2) : (x2 - x1));  // width  = | x1 - x2 |
90     height = (u16)((y1 >= y2) ? (y1 - y2) : (y2 - y1)); // height = | y1 - y2 |
91 
92 
93     if (width > height)
94     {
95         /* If (X size > Y size) draw a Dot per Xdot */
96         if (x1 >= x2)
97         {
98             min = x2;
99             max = x1;
100             base = y2;
101         }
102         else
103         {
104             min = x1;
105             max = x2;
106             base = y1;
107         }
108 
109         for (i = min; i <= max; i++)
110         {
111             px = i;
112             py = (u16)(((px - min) * (y2 - y1)) / (x2 - x1) + base);
113             PutDot(px, py, col);
114         }
115 
116     }
117     else
118     {
119         /* If (X size <= Y size) draw a Dot per Ydot */
120         if (y1 >= y2)
121         {
122             min = y2;
123             max = y1;
124             base = x2;
125         }
126         else
127         {
128             min = y1;
129             max = y2;
130             base = x1;
131         }
132 
133         for (i = min; i <= max; i++)
134         {
135             py = i;
136             px = (u16)((py - min) * (x2 - x1) / (y2 - y1) + base);
137             PutDot(px, py, col);
138         }
139     }
140 }
141 
142 
143 /*---------------------------------------------------------------------------*
144   Name:         HandDraw
145 
146   Description:  Displays the coordinates of all contact points gotten through auto-sampling.
147 
148   Arguments:    buf: Pointer to auto-sampling buffer
149                 size: Frequency of auto sampling
150 
151   Returns:      None.
152  *---------------------------------------------------------------------------*/
HandDraw(TPData * buf,u32 size)153 static void HandDraw(TPData *buf, u32 size)
154 {
155     s32     i, idx;
156     s32     last_idx;
157     TPData  sample;
158     static TPData tpLast = { 0, 0, 0, 0 };
159 
160     // The data in buf[LatestIndex + 1] may be overwritten by the auto-sampling process
161     last_idx = TP_GetLatestIndexInAuto();
162 
163     for (i = 0; i < size; i++)
164     {
165         idx = last_idx - (s32)size + i + 1;
166         if (idx < 0)
167         {
168             idx += SAMPLING_BUFSIZE;
169         }
170 
171         if (!buf[idx].touch)
172         {
173             tpLast.touch = 0;
174             continue;
175         }
176         if (buf[idx].validity != 0)
177         {
178             continue;
179         }
180 
181         TP_GetCalibratedPoint(&sample, &buf[idx]);
182         OS_Printf("( %d, %d ) -> ( %d, %d )\n", buf[idx].x, buf[idx].y, sample.x, sample.y);
183         if (!tpLast.touch)
184         {
185             PutDot(sample.x, sample.y, 0);
186         }
187         else
188         {
189             DrawLine(tpLast.x, tpLast.y, sample.x, sample.y, 0);
190         }
191         tpLast = sample;
192     }
193 }
194 
195 
196 /*---------------------------------------------------------------------------*
197   Name:         DisplayInit
198 
199   Description:  Graphics initialization.
200 
201   Arguments:    None.
202 
203   Returns:      None.
204  *---------------------------------------------------------------------------*/
DisplayInit()205 static void DisplayInit()
206 {
207 
208     GX_Init();
209     FX_Init();
210 
211     GX_DispOff();
212     GXS_DispOff();
213 
214     GX_SetDispSelect(GX_DISP_SELECT_SUB_MAIN);
215 
216     OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
217     (void)OS_EnableIrqMask(OS_IE_V_BLANK);
218     (void)GX_VBlankIntr(TRUE);         // To generate V-Blank interrupt request
219     (void)OS_EnableIrq();
220 
221 
222     GX_SetBankForLCDC(GX_VRAM_LCDC_ALL);
223     MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE);
224 
225     MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE);   // Clear OAM
226     MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE);     // Clear the standard palette
227 
228     MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE);     // Clear OAM
229     MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE);       // Clear the standard palette
230     MI_DmaFill32(3, (void *)HW_LCDC_VRAM_C, 0x7FFF7FFF, 256 * 192 * sizeof(u16));
231 
232 
233     GX_SetBankForOBJ(GX_VRAM_OBJ_256_AB);       // Set VRAM-A, B for OBJ
234 
235     GX_SetGraphicsMode(GX_DISPMODE_GRAPHICS,    // 2D / 3D Mode
236                        GX_BGMODE_0,    // BGMODE 0
237                        GX_BG0_AS_2D);  // Set BG0 as 2D
238 
239     GX_SetVisiblePlane(GX_PLANEMASK_OBJ);       // Make OBJ visible
240     GX_SetOBJVRamModeBmp(GX_OBJVRAMMODE_BMP_1D_128K);   // 2D mapping OBJ
241 
242     OS_WaitVBlankIntr();               // Waiting for the end of the V-Blank interrupt
243     GX_DispOn();
244 
245 }
246 
247 
248 
249 
250 
251 /*---------------------------------------------------------------------------*
252   Name:         NitroMain
253 
254   Description:  Initialization and main loop.
255 
256   Arguments:    None.
257 
258   Returns:      None.
259  *---------------------------------------------------------------------------*/
NitroMain(void)260 void NitroMain(void)
261 {
262 
263     TPCalibrateParam calibrate;
264 
265     // Initialization
266     KeyInit();
267     OS_Init();
268     TP_Init();
269 
270     // Get CalibrateParameter from FlashMemory
271     if (!TP_GetUserInfo(&calibrate))
272     {
273         OS_Panic("FATAL ERROR: can't get UserInfo\n");
274     }
275     else
276     {
277         OS_Printf("Get Calibration Parameter from NVRAM\n");
278     }
279 
280     TP_SetCalibrateParam(&calibrate);
281 
282     DisplayInit();
283 
284     // Unnecessary called.
285     // Be able to use default parameter (retry,range).
286 #if 0
287     // Send parameter of revision noise
288     if (TP_RequestSetStability(3, 15) != 0)
289     {
290         OS_Panic("SetStability request err!\n");
291     }
292 #endif
293 
294     GX_SetGraphicsMode(GX_DISPMODE_VRAM_C,      // VRAM mode
295                        (GXBGMode)0,    // Dummy
296                        (GXBG0As)0);    // Dummy
297 
298     // Send auto-sampling start request
299     if (TP_RequestAutoSamplingStart(SAMPLING_START_VCOUNT, SAMPLING_FREQUENCE,
300                                     gTpBuf, SAMPLING_BUFSIZE))
301     {
302         OS_Panic("auto sampling start reqeuest err!\n");
303     }
304     OS_Printf("Start auto sampling\n");
305 
306     // Empty call for getting key input data (strategy for pressing A Button in the IPL)
307     KeyRead();
308 
309     while (TRUE)
310     {
311         KeyRead();
312 
313         // Draw
314 
315         // If START button pressed, clear screen
316         if (keys.trg & PAD_BUTTON_START)
317         {
318             MI_DmaFill32(3, (void *)HW_LCDC_VRAM_C, 0x7FFF7FFF, 256 * 192 * sizeof(u16));
319         }
320 
321         // Displays the results obtained through auto-sampling
322         HandDraw(gTpBuf, SAMPLING_FREQUENCE);
323 
324         // Wait for V-Blank interrupt
325         OS_WaitVBlankIntr();
326     }
327 }
328 
329 
330 /*---------------------------------------------------------------------------*
331   Name:         VBlankIntr
332 
333   Description:  V-Blank function.
334 
335   Arguments:    None.
336 
337   Returns:      None.
338  *---------------------------------------------------------------------------*/
VBlankIntr(void)339 static void VBlankIntr(void)
340 {
341 
342     // Set IRQ check flag
343     OS_SetIrqCheckFlag(OS_IE_V_BLANK);
344 }
345 
346 
347 /*---------------------------------------------------------------------------*
348   Name:         KeyRead
349 
350   Description:  Reads pad keys.
351 
352   Arguments:    None.
353 
354   Returns:      None.
355  *---------------------------------------------------------------------------*/
KeyRead(void)356 static void KeyRead(void)
357 {
358     u16     r = PAD_Read();
359 
360     keys.trg = (u16)(~keys.con & r);
361     keys.con = r;
362 }
363 
364 /*---------------------------------------------------------------------------*
365   Name:         KeyInit
366 
367   Description:  Initializes pad keys.
368 
369   Arguments:    None.
370 
371   Returns:      None.
372  *---------------------------------------------------------------------------*/
KeyInit(void)373 static void KeyInit(void)
374 {
375 
376     keys.trg = 0;
377     keys.con = 0;
378 
379 }
380 
381 
382 /*---------------------------------------------------------------------------*
383   End of file
384  *---------------------------------------------------------------------------*/
385