1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - demos - CTRDG - backup-1
3 File: main.c
4
5 Copyright 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:: $
14 $Rev: $
15 $Author: $
16 *---------------------------------------------------------------------------*/
17
18 #include <nitro.h>
19
20 /* Routine for screen rendering */
21 #include "draw.h"
22
23 /* ****************************************************************************/
24 static async_task_busy = FALSE; // TRUE when a separate task is running
25
26 // Insert data here because it is global, and send to command
27 CTRDGTaskInfo CTRDG_TaskData;
28
29 u32 TaskBusyCallback(CTRDGTaskInfo * p);
30 u32 ReadCallback(CTRDGTaskInfo * p);
31 //---------------------------------------------------------------------------
32 static void InitBackupAccess(void);
33 static void TestBackupAccess(void);
34 static void SelectDevice(void);
35
36 u16 sec_num = 1; // 0�`16
37 u8 dst_buf[4096];
38
39 // Key information
40 u16 Trg;
41 u16 Cont;
42 u16 keyData;
43
44 BOOL sram_flag = FALSE; // TRUE for SRAM
45 BOOL flash512k_flag = FALSE; // TRUE for FLASH512K
46 BOOL flash1m_flag = FALSE; // TRUE for FLASH1M
47 BOOL nocommond_flag = FALSE; // TRUE if the specified command is not on the device
48 BOOL async_flag = FALSE; // TRUE if in asynchronous mode
49 /* Sample demo function **********************************************************/
TaskBusyCallback(CTRDGTaskInfo * p)50 u32 TaskBusyCallback(CTRDGTaskInfo * p)
51 {
52 async_task_busy = FALSE;
53 if (p->result != 0)
54 OS_TPrintf("error\n");
55 return 1;
56 }
57
ReadCallback(CTRDGTaskInfo * p)58 u32 ReadCallback(CTRDGTaskInfo * p)
59 {
60 (void)p;
61 async_task_busy = FALSE;
62 OS_TPrintf("Read : sector%d = %s\n", sec_num, dst_buf);
63 ClearFrame(RGB555_BLACK);
64 return 1;
65 }
66
67 /*---------------------------------------------------------------------------*
68 Name: VBlankIntr
69
70 Description: V-Blank callback.
71
72 Arguments: None.
73
74 Returns: None.
75 *---------------------------------------------------------------------------*/
VBlankIntr(void)76 static void VBlankIntr(void)
77 {
78 OS_SetIrqCheckFlag(OS_IE_V_BLANK);
79 }
80
81 /*---------------------------------------------------------------------------*
82 Name: InitApp
83
84 Description: OS and other initializations of basic parts of the application.
85
86 Arguments: None.
87
88 Returns: None.
89 *---------------------------------------------------------------------------*/
InitApp(void)90 static void InitApp(void)
91 {
92 void *tmp;
93 OSHeapHandle hh;
94
95 /* OS initialization */
96 OS_Init();
97 OS_InitThread();
98 OS_InitTick();
99 /* Arena initialization */
100 tmp = OS_InitAlloc(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1);
101 OS_SetArenaLo(OS_ARENA_MAIN, tmp);
102 hh = OS_CreateHeap(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi());
103 if (hh < 0)
104 OS_Panic("ARM9: Fail to create heap...\n");
105 hh = OS_SetCurrentHeap(OS_ARENA_MAIN, hh);
106 /* Enable interrupts */
107 OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
108 (void)OS_EnableIrqMask(OS_IE_V_BLANK);
109 (void)OS_EnableIrq();
110 }
111
112 /*---------------------------------------------------------------------------*
113 Name: NitroMain
114
115 Description: Main entry point.
116
117 Arguments: None.
118
119 Returns: None.
120 *---------------------------------------------------------------------------*/
NitroMain(void)121 void NitroMain(void)
122 {
123 /* Sample application initialization */
124 InitApp();
125
126 InitBackupAccess();
127
128 OS_TPrintf("start test\n");
129
130 TestBackupAccess();
131
132 }
133
InitBackupAccess(void)134 void InitBackupAccess(void)
135 {
136 CTRDG_Init();
137 CTRDG_Enable(TRUE);
138 InitDraw();
139
140 /* Device identified and default settings */
141 SelectDevice();
142 }
143
TestBackupAccess(void)144 void TestBackupAccess(void)
145 {
146 u32 result = TRUE;
147 u32 offset = 0;
148 u8 src_buf[4096];
149 u8 src_buf2[4096];
150 u32 size = 4096;
151 u16 i;
152
153 MI_CpuClear8(dst_buf, size);
154 MI_CpuClear8(src_buf, size);
155 MI_CpuClear8(src_buf2, size);
156 MI_CpuCopy8("Write Sector", src_buf, 13);
157 MI_CpuCopy8("Write & Verify", src_buf2, 14);
158
159 if (sram_flag)
160 offset = CTRDG_AGB_SRAM_ADR;
161 ClearFrame(RGB555_BLACK);
162
163 while (1)
164 {
165 DrawBegin();
166 //---- Read pad data
167 keyData = PAD_Read();
168 keyData = PAD_Read();
169 Trg = (u16)(keyData & (keyData ^ Cont));
170 Cont = keyData;
171
172 /* String display */
173 DrawText(10, 40, "A : Write");
174 DrawText(10, 50, "B : Erase");
175 DrawText(10, 60, "X : Read");
176 DrawText(10, 70, "Y : Write & Verify");
177 DrawText(10, 80, "UP : Add SectorNo or offset");
178 DrawText(10, 90, "DOWN : Sub SectorNo or offset");
179 DrawText(10, 100, "START : change Async/Sync Mode");
180
181 if (!async_task_busy)
182 {
183 // Write with A
184 if (Trg == PAD_BUTTON_A)
185 {
186 if (async_flag)
187 {
188 async_task_busy = TRUE;
189 if (!sram_flag)
190 {
191 CTRDG_WriteAgbFlashSectorAsync(sec_num, src_buf, TaskBusyCallback);
192 }
193 else
194 {
195 CTRDG_WriteAgbSramAsync(offset, src_buf, size, TaskBusyCallback);
196 }
197 }
198 else
199 {
200 if (!sram_flag)
201 {
202 result = CTRDG_WriteAgbFlashSector(sec_num, src_buf);
203 if (result != 0)
204 OS_TPrintf("error : Write\n");
205 }
206 else
207 {
208 CTRDG_WriteAgbSram(offset, src_buf, size);
209 }
210 }
211 OS_TPrintf("Write sector%d\n", sec_num);
212 }
213 // Erase with B
214 else if (Trg == PAD_BUTTON_B)
215 {
216 if (async_flag)
217 {
218 async_task_busy = TRUE;
219 if (!sram_flag)
220 {
221 CTRDG_EraseAgbFlashSectorAsync(sec_num, TaskBusyCallback);
222 }
223 else
224 {
225 nocommond_flag = TRUE;
226 ClearFrame(RGB555_BLACK);
227 async_task_busy = FALSE;
228 }
229 }
230 else
231 {
232 if (!sram_flag)
233 {
234 result = CTRDG_EraseAgbFlashSector(sec_num);
235 }
236 else
237 {
238 nocommond_flag = TRUE;
239 ClearFrame(RGB555_BLACK);
240 result = 0;
241 }
242 if (result != 0)
243 OS_TPrintf("error : Erase\n");
244 }
245 OS_TPrintf("Erase : sector%d\n", sec_num);
246 }
247 // Read with X
248 else if (Trg == PAD_BUTTON_X)
249 {
250 nocommond_flag = FALSE;
251 if (async_flag)
252 {
253 async_task_busy = TRUE;
254 if (!sram_flag)
255 {
256 CTRDG_ReadAgbFlashAsync(sec_num, offset, dst_buf, size, ReadCallback);
257 }
258 else
259 {
260 CTRDG_ReadAgbSramAsync(offset, (void *)dst_buf, size, ReadCallback);
261 }
262 }
263 else
264 {
265 if (!sram_flag)
266 {
267 CTRDG_ReadAgbFlash(sec_num, offset, dst_buf, size);
268 }
269 else
270 {
271 CTRDG_ReadAgbSram(offset, (void *)dst_buf, size);
272 }
273 OS_TPrintf("Read : sector%d = %s\n", sec_num, dst_buf);
274 ClearFrame(RGB555_BLACK);
275 }
276 }
277 // WriteAndVerify with Y
278 else if (Trg == PAD_BUTTON_Y)
279 {
280 if (async_flag)
281 {
282 async_task_busy = TRUE;
283 if (!sram_flag)
284 {
285 CTRDG_WriteAndVerifyAgbFlashAsync(sec_num, src_buf2, size,
286 TaskBusyCallback);
287 }
288 else
289 {
290 CTRDG_WriteAndVerifyAgbSramAsync(offset, src_buf2, size, TaskBusyCallback);
291 }
292 }
293 else
294 {
295 if (!sram_flag)
296 {
297 result = CTRDG_WriteAndVerifyAgbFlash(sec_num, src_buf2, size);
298 }
299 else
300 {
301 result = CTRDG_WriteAndVerifyAgbSram(offset, src_buf2, size);
302 }
303 if (result != 0)
304 OS_TPrintf("error : WriteAndVerify\n");
305 }
306 OS_TPrintf("Write sector%d\n", sec_num);
307 }
308 // Use the above key to increase the accessed SectorNo and offset
309 else if (Trg == PAD_KEY_UP)
310 {
311 if (flash512k_flag)
312 {
313 if (sec_num < 15)
314 sec_num++;
315 }
316 else if (flash1m_flag)
317 {
318 if (sec_num < 31)
319 sec_num++;
320 }
321 else if (sram_flag)
322 {
323 if (offset <= 167800832)
324 offset += 4096;
325 }
326
327 ClearFrame(RGB555_BLACK);
328 }
329 // Use the lower key to decrease the accessed SectorNo and offset
330 else if (Trg == PAD_KEY_DOWN)
331 {
332 if (flash512k_flag || flash1m_flag)
333 {
334 if (sec_num > 0)
335 sec_num--;
336 }
337 else if (sram_flag)
338 {
339 if (offset >= 167776256)
340 offset -= 4096;
341 }
342 ClearFrame(RGB555_BLACK);
343 }
344 // Use the right key to increase the accessed Size
345 else if (Cont == PAD_KEY_RIGHT)
346 {
347 if (size <= 4088)
348 size += 8;
349 OS_TPrintf("Access Size = %d\n", size);
350 ClearFrame(RGB555_BLACK);
351 }
352 // Use the left key to decrease the accessed Size
353 else if (Cont == PAD_KEY_LEFT)
354 {
355 if (size >= 8)
356 size -= 8;
357 OS_TPrintf("Access Size = %d\n", size);
358 ClearFrame(RGB555_BLACK);
359 }
360 // Use START to switch between asynchronous and synchronous modes
361 else if (Trg == PAD_BUTTON_START)
362 {
363 async_flag = !async_flag;
364 ClearFrame(RGB555_BLACK);
365 }
366 // Use SELECT to Verify
367 else if (Trg == PAD_BUTTON_SELECT)
368 {
369 if (async_flag)
370 {
371 async_task_busy = TRUE;
372 if (!sram_flag)
373 {
374 CTRDG_VerifyAgbFlashAsync(sec_num, src_buf2, size, TaskBusyCallback);
375 }
376 else
377 {
378 offset = CTRDG_AGB_SRAM_ADR;
379 CTRDG_VerifyAgbSramAsync(offset, src_buf2, size, TaskBusyCallback);
380 }
381 }
382 else
383 {
384 if (!sram_flag)
385 {
386 result = CTRDG_VerifyAgbFlash(sec_num, src_buf2, size);
387 }
388 else
389 {
390 offset = CTRDG_AGB_SRAM_ADR;
391 result = CTRDG_VerifyAgbSram(offset, src_buf2, size);
392 }
393 if (result != 0)
394 OS_TPrintf("error : Verify\n");
395 }
396 OS_TPrintf("Verify sector%d\n", sec_num);
397 }
398 // Use L to set the thread priority to 0
399 else if (Trg == PAD_BUTTON_L)
400 {
401 u32 priority = 0;
402 CTRDG_SetTaskThreadPriority(priority);
403 OS_TPrintf("Task Thread Priority = %d\n", priority);
404 }
405 }
406 /* String display */
407 if (flash512k_flag || flash1m_flag)
408 {
409 DrawText(10, 140, "SectorNo : %d", sec_num);
410 }
411 else if (sram_flag)
412 {
413 DrawText(10, 140, "offset : %x", offset);
414 }
415 DrawText(10, 150, "Access Size : %d", size);
416 DrawText(10, 130, "result : ");
417 if (nocommond_flag)
418 DrawText(120, 130, "Erase is nothing");
419 if (!nocommond_flag)
420 {
421 for (i = 0; i < size; i++)
422 {
423 if (dst_buf[i] != 0xFF)
424 DrawText(120 + (i * 8), 130, "%c", dst_buf[i]);
425 }
426 }
427 if (async_flag)
428 DrawText(10, 170, "Async Mode");
429 if (!async_flag)
430 DrawText(10, 170, "Sync Mode");
431
432 DrawEnd();
433 OS_WaitVBlankIntr();
434 }
435 }
436
437 /*---------------------------------------------------------------------------*
438 Name: SelectDevice
439
440 Description: Device selection screen.
441
442 Arguments: None.
443
444 Returns: None.
445 *---------------------------------------------------------------------------*/
SelectDevice(void)446 static void SelectDevice(void)
447 {
448 /* *INDENT-OFF* */
449 static const struct
450 {
451 CTRDGBackupType type;
452 const char *comment;
453 }
454 types_table[] =
455 {
456 { CTRDG_BACKUP_TYPE_FLASH_512K, "FLASH 512 kb"},
457 { CTRDG_BACKUP_TYPE_FLASH_1M, "FLASH 1 Mb"},
458 { CTRDG_BACKUP_TYPE_SRAM, "SRAM 256 kb"},
459 };
460 /* *INDENT-ON* */
461 enum
462 { types_table_max = sizeof(types_table) / sizeof(*types_table) };
463
464 int cur = 0;
465 BOOL error = FALSE;
466 BOOL end = TRUE;
467 int i;
468
469 while (end != 0)
470 {
471
472 keyData = PAD_Read();
473 keyData = PAD_Read();
474 Trg = (u16)(keyData & (keyData ^ Cont));
475 Cont = keyData;
476
477 DrawBegin();
478 ClearFrame(RGB555_BLACK);
479
480 /* Move the cursor with the up and down buttons */
481 if (Trg & PAD_KEY_DOWN)
482 {
483 error = FALSE;
484 if (++cur >= types_table_max)
485 cur -= types_table_max;
486 }
487 if (Trg & PAD_KEY_UP)
488 {
489 error = FALSE;
490 if (--cur < 0)
491 cur += types_table_max;
492 }
493
494 /*
495 * Set the currently selected device with the A Button.
496 *
497 * Set this correctly because the library cannot determine whether the specified device has actually been loaded.
498 *
499 */
500 if (Trg & PAD_BUTTON_A)
501 {
502 end = CTRDG_IdentifyAgbBackup(types_table[cur].type);
503 if (end != 0)
504 {
505 error = TRUE;
506 }
507 else
508 {
509 if (types_table[cur].type == CTRDG_BACKUP_TYPE_SRAM)
510 sram_flag = TRUE;
511 if (types_table[cur].type == CTRDG_BACKUP_TYPE_FLASH_512K)
512 flash512k_flag = TRUE;
513 if (types_table[cur].type == CTRDG_BACKUP_TYPE_FLASH_1M)
514 flash1m_flag = TRUE;
515 }
516 }
517
518 /* String display */
519 SetTextColor(RGB555_GREEN);
520 DrawText(10, 40, "select device!");
521 for (i = 0; i < types_table_max; ++i)
522 {
523 DrawText(20, 60 + 10 * i, types_table[i].comment);
524 }
525 FillRect(10, 60, 10, i * 10, RGB555_BLACK);
526 DrawText(10, 60 + 10 * cur, ">");
527 if (error)
528 {
529 /* Error display */
530 SetTextColor(RGB555_RED);
531 DrawText(10, 120, "error!");
532 }
533 DrawEnd();
534 }
535 }
536