1 /*---------------------------------------------------------------------------*
2   Project:    vfdemo
3   File:       simple.c
4   Programers: yamamoto
5               komatu
6               gen
7               miyake
8               noma
9 
10   Copyright (C) 2006 Nintendo.  All rights reserved.
11 
12   These coded instructions, statements, and computer programs contain
13   proprietary information of Nintendo of America Inc. and/or Nintendo
14   Company Ltd., and are protected by Federal copyright law.  They may
15   not be disclosed to third parties or copied or duplicated in any form,
16   in whole or in part, without the prior written consent of Nintendo.
17  *---------------------------------------------------------------------------*/
18 #include <stdio.h>                      // size_t
19 
20 #include <revolution/os.h>              // OSHalt
21 #include <revolution/nand.h>            // NANDInit
22 #include <demo.h>                       // DEMO...
23 
24 #include <revolution/vf.h>
25 
26 #define USE_NAND
27 
28 static void _SampleInit();
29 static void _SampleMain();
30 static void _MakeWriteSampleData();
31 
32 #define DRIVE_NUM (3)
33 #define WORK_SIZE (DRIVE_NUM * VF_DRIVE_WORKSIZE)
34 static char l_vfWork[WORK_SIZE] ATTRIBUTE_ALIGN(32);
35 
36 /*---------------------------------------------------------------------------*
37   Name:         main
38 
39   Arguments:    none
40 
41   Description:  The application's main loop
42 
43   Returns:      none
44  *---------------------------------------------------------------------------*/
main(void)45 void main ( void )
46 {
47     GXColor Black  = {0, 0, 0, 0};
48     OSFontHeader* FontData = NULL;
49 
50     // demo Init
51     DEMOInit(NULL);
52     // font init
53     FontData = DEMOInitROMFont();	// Use IPL ROM font
54     if (FontData == 0) {
55         OSHalt("This program requires boot ROM ver 0.8 or later\n");
56     }
57     GXSetCopyClear(Black, 0x00ffffff);
58     GXCopyDisp(DEMOGetCurrentBuffer(), GX_TRUE);
59 
60     // make test data
61     _MakeWriteSampleData();
62     // sample init
63     _SampleInit();
64     // sample main
65     _SampleMain();
66 
67     while (1) {
68         GXRenderModeObj* rmp;
69 
70         DEMOBeforeRender();
71 
72         // none
73 
74         rmp = DEMOGetRenderModeObj();
75         DEMOInitCaption(DM_FT_XLU, (s16) rmp->fbWidth, (s16) rmp->efbHeight);
76         DEMOSetFontType(DM_FT_XLU);
77         DEMOSetROMFontSize(32, -1);
78 
79         (void)DEMORFPrintf(32, 64, 0, "VF");
80         DEMODoneRender();
81     }
82 }
83 
84 /*---------------------------------------------------------------------------*
85   Name:         _MakeWriteSampleData
86 
87   Arguments:    none
88 
89   Description:  Creates the write data for the demo
90 
91   Returns:      none
92  *---------------------------------------------------------------------------*/
93 #define TEST_DATA_SIZE (512)
94 static u8 l_writeData[TEST_DATA_SIZE] ATTRIBUTE_ALIGN(32);
_MakeWriteSampleData()95 static void _MakeWriteSampleData()
96 {
97     int 	i;
98     int		add = 0;
99     u8*		buf_p = l_writeData;
100     for ( i=0; i<TEST_DATA_SIZE; i++ ) {
101         const u8 set = (u8)((i + add) & 0xff);
102 
103         *buf_p = set;
104         buf_p++;
105 
106         if (set == 0xff) {
107             add++;
108         }
109     }
110 }
111 
112 /*---------------------------------------------------------------------------*
113   Name:         _SampleInit
114 
115   Arguments:    none
116 
117   Description:  The demo's initializer
118 
119   Returns:      none
120  *---------------------------------------------------------------------------*/
_SampleInit()121 static void _SampleInit()
122 {
123 #if defined(USE_NAND)
124     // NAND flash init
125     (void)NANDInit();
126 #endif //#if defined(USE_NAND)
127 }
128 
129 /*---------------------------------------------------------------------------*
130   Name:         WaitSec1
131 
132   Description:
133 
134   Arguments:
135 
136   Returns:
137  *---------------------------------------------------------------------------*/
_WaitSec1()138 static void _WaitSec1()
139 {
140     OSTime start = OSGetTime();
141     OSTime end = OSGetTime();
142     u32 printSec = 0;
143     u32 sec = (u32)OSTicksToSeconds(end - start);
144 
145     while(sec < 1) {
146         end = OSGetTime();
147         sec = (u32)OSTicksToSeconds(end - start);
148         if (sec != printSec) {
149             printSec = sec;
150         }
151     }
152 }
153 
154 /*---------------------------------------------------------------------------*
155   Name:         status
156 
157  *---------------------------------------------------------------------------*/
158 enum {
159     SD_DRIVE_STTS_NOMOUNTED=0,
160     SD_DRIVE_STTS_MOUNTED=(1<<0),
161     SD_DRIVE_STTS_REQ_EJECT_UNMOUNT=(1<<1)
162 };
163 static u8 l_SD_drive_stts = SD_DRIVE_STTS_NOMOUNTED;
164 
165 /*---------------------------------------------------------------------------*
166   Name:         _SDEventCallBack
167 
168   Arguments:    event
169 
170   Description:  SD event callback
171 
172   Returns:      none
173  *---------------------------------------------------------------------------*/
174 static int l_isEjected = 0;
_SDEventCallBack(VFEvent event)175 static void _SDEventCallBack(VFEvent event)
176 {
177     if (event == VF_EVENT_EJECTED) {
178         l_isEjected = 1;
179         l_SD_drive_stts |= SD_DRIVE_STTS_REQ_EJECT_UNMOUNT;
180     }
181     else {
182         l_isEjected = 0;
183     }
184 }
185 
186 /*---------------------------------------------------------------------------*
187   Name:         _NANDCheck
188 
189   Arguments:    i_filesize
190 
191   Description:  NAND check.
192 
193   Returns:      TRUE/FALSE
194  *---------------------------------------------------------------------------*/
195 // Reference NAND sample
check(const u32 fsBlock,const u32 inode)196 static BOOL check(const u32 fsBlock, const u32 inode)
197 {
198     u32 answer = 0xffffffff;
199     s32 ret = NANDCheck(fsBlock, inode, &answer);
200     if(ret==NAND_RESULT_OK)
201     {
202         if(answer==0)
203         {
204             return TRUE;
205         }
206         else
207         {
208             if(answer & NAND_CHECK_HOME_INSSPACE)
209             {
210                 OSReport("Your request will exceed limit of home directory (16MB).\n");
211             }
212             if(answer & NAND_CHECK_HOME_INSINODE)
213             {
214                 OSReport("Your request will exceed limit of home directory (32 i-nodes).\n");
215             }
216             if(answer & NAND_CHECK_SYS_INSSPACE)
217             {
218                 OSReport("Your request will invade space of system area.\n");
219             }
220             if(answer & NAND_CHECK_SYS_INSINODE)
221             {
222                 OSReport("Your request will invade i-nodes of system area.\n");
223             }
224             return FALSE;
225         }
226     }
227     else
228     {
229         OSReport("NANDCheck() failed.  Result code: %d\n", ret);
230         return FALSE;
231     }
232 }
_NANDCheck(u32 i_filesize)233 static BOOL _NANDCheck(u32 i_filesize)
234 {
235     return check(i_filesize/NAND_FSBLOCK_SIZE, 1);
236 }
237 
238 /*---------------------------------------------------------------------------*
239   Name:         _SampleMain
240 
241   Arguments:    none
242 
243   Description:  The demo's main section
244 
245   Returns:      none
246  *---------------------------------------------------------------------------*/
_SampleMain()247 static void _SampleMain()
248 {
249 #if defined(USE_NAND)
250     static char NandVffNameA[] = "testA.vff";
251 #endif //#if defined(USE_NAND)
252     VFErr 	Error = 0;
253     VFDevErr	devErr = 0;
254     VFFile	*fp = NULL;
255 
256     //------------------------------------------------------------------
257     // VF init
258     //------------------------------------------------------------------
259     // VFInit();
260     VFInitEx(l_vfWork, WORK_SIZE);
261 
262 #if defined(USE_NAND)
263     //------------------------------------------------------------------
264     // mount drive A for NAND
265     //------------------------------------------------------------------
266     // create system file
267     OSReport("[mount drive A for NAND - VFCreateSystemFileNANDFlash]\n");
268 
269 #if 0 //reset
270     (void)VFDeleteSystemFileNANDFlash(NandVffNameA);
271 #endif
272 
273     // mount system file
274     OSReport("[mount drive A for NAND - VFMountDriveNANDFlash]\n");
275     Error = VFMountDriveNANDFlash("A", NandVffNameA);
276     if (Error != VF_ERR_SUCCESS) {
277         OSReport("VFMountDriveNANDFlash Error %s Line %d\n",
278                  VFGetApiErrorString(Error), __LINE__);
279     }
280 
281     /**
282      *	VF_ERR_VFF_FILE_FORMAT ->
283      *  VFDeleteSystemFileNANDFlash
284      */
285     if (Error == VF_ERR_VFF_FILE_FORMAT) {
286         if (VFDeleteSystemFileNANDFlash(NandVffNameA) == NAND_RESULT_OK) {
287             Error = VF_ERR_NOT_EXIST_FILE;
288         }
289         else {
290             OSReport("VFDeleteSystemFileNANDFlash Error %s Line %d\n",
291                      VFGetApiErrorString(Error), __LINE__);
292             OSHalt("Can't delete system file.");
293         }
294     }
295 
296     /**
297      *	VF_ERR_NOT_EXIST_FILE ->
298      *  NANDCheck ->
299      *  VFCreateSystemFileNANDFlash ->
300      *	VFMountDriveNANDFlash ->
301      *	VFFormatDrive
302      */
303     if (Error == VF_ERR_NOT_EXIST_FILE) {
304         if (_NANDCheck(100*1024) == FALSE) {
305             OSHalt("NAND no space..");
306         }
307 
308         devErr = VFCreateSystemFileNANDFlash( NandVffNameA, (100*1024) );
309         if (devErr != NAND_RESULT_OK) {
310             OSReport("VFCreateSystemFileNANDFlash VFDevErr(NANDError) %d Line %d\n",
311                      devErr, __LINE__);
312             OSHalt("Can't create sytem file.");
313         }
314 
315         // mount system file
316         OSReport("[mount drive A for NAND - VFMountDriveNANDFlash]\n");
317         Error = VFMountDriveNANDFlash( "A", NandVffNameA );
318         if (Error != VF_ERR_SUCCESS) {
319             OSReport("VFMountDriveNANDFlash Error %s Line %d\n",
320                      VFGetApiErrorString(Error), __LINE__);
321             OSHalt( "Can't mount nand drive.");
322         }
323 
324         // format drive
325         Error = VFFormatDrive( "A" );
326         if (Error != VF_ERR_SUCCESS) {
327             OSReport("VFFormatDrive Error %s Line %d\n",
328                      VFGetApiErrorString(Error), __LINE__);
329             OSHalt( "Can't format nand drive");
330         }
331     }
332 
333     /**
334      *	Make Directory
335      */
336     OSReport("[mount drive A for NAND - VFCreateDir]\n");
337     Error = VFCreateDir("A:/Sample0");
338     if (Error != VF_ERR_SUCCESS) {
339         OSReport("VFCreateDir Error %s Line %d\n",
340                  VFGetApiErrorString(Error), __LINE__);
341     }
342     Error = VFCreateDir( "Sample0/Sample1");
343     if (Error != VF_ERR_SUCCESS) {
344         OSReport("VFCreateDir Error %s Line %d\n",
345                  VFGetApiErrorString(Error), __LINE__);
346     }
347 
348     /**
349      *	Change Directory
350      */
351     OSReport("[mount drive A for NAND - VFChangeDir]\n");
352     Error = VFChangeDir("/");
353     if (Error != VF_ERR_SUCCESS) {
354         OSReport("VFChangeDir Error %s Line %d\n",
355                  VFGetApiErrorString(Error), __LINE__);
356     }
357 
358     /**
359      *	Write File
360      */
361     // Open file
362     OSReport("[mount drive A for NAND - VFOpenFile]\n");
363     fp = VFOpenFile("A:/SAMPLEA.txt", "r+", 0);
364     if (fp == NULL){
365         OSReport("VFOpenFile Error %s Line %d\n",
366                  VFGetApiErrorString(VFGetLastError()), __LINE__);
367 
368         // create file
369         fp = VFCreateFile("SAMPLEA.txt", 0);
370         if (fp == NULL) {
371             OSReport( "VFCreateFile Error %s Line %d\n",
372                       VFGetApiErrorString(VFGetLastError()), __LINE__);
373         }
374     }
375     if (fp) {
376         // write file
377         OSReport("[mount drive A for NAND - VFWriteFile]\n");
378         Error = VFWriteFile(fp, l_writeData, TEST_DATA_SIZE);
379         if (Error != VF_ERR_SUCCESS) {
380             OSReport("VFWriteFile Error %s Line %d\n",
381                      VFGetApiErrorString(Error), __LINE__);
382         }
383         // sync file
384          OSReport("[mount drive A for NAND - VFFileSync]\n");
385          Error = VFFileSync(fp);
386          if (Error != VF_ERR_SUCCESS) {
387              OSReport("VFFileSync Error %s Line %d\n",
388                       VFGetApiErrorString(Error), __LINE__);
389              OSHalt("Can't sync file");
390          }
391         // Close file
392         OSReport("[mount drive A for NAND - VFCloseFile]\n");
393         Error = VFCloseFile(fp);
394         if (Error != VF_ERR_SUCCESS) {
395             OSReport("VFCloseFile Error %s Line %d\n",
396                      VFGetApiErrorString(Error), __LINE__);
397         }
398         // cut file (If file is closed, you success)
399         OSReport("[mount drive A for NAND - VFCutFileSize]\n");
400         Error = VFCutFileSize("A:/SAMPLEA.txt", 23);
401         if (Error != VF_ERR_SUCCESS) {
402             OSReport("VFCutFileSize Error %s Line %d\n",
403                      VFGetApiErrorString(Error), __LINE__);
404         }
405     }
406 
407     /**
408      * Delete Directory
409      */
410     // make directory
411     OSReport("[mount drive A for NAND - VFCreateDir]\n");
412     Error = VFCreateDir("A:/subDir0");
413     if (Error != VF_ERR_SUCCESS) {
414         OSReport("VFCreateDir Error %s Line %d\n",
415                  VFGetApiErrorString(Error), __LINE__);
416     }
417     Error = VFCreateDir("subDir0/subDir1");
418     if (Error != VF_ERR_SUCCESS) {
419         OSReport("VFCreateDir Error %s Line %d\n",
420                  VFGetApiErrorString(Error), __LINE__);
421     }
422     // delete directory
423     OSReport("[mount drive A for NAND - VFCreateDir]\n");
424     Error = VFDeleteDir("Sample0/Sample1");
425     if (Error != VF_ERR_SUCCESS) {
426         OSReport("VFDeleteDir Error %s Line %d\n",
427                  VFGetApiErrorString(Error), __LINE__);
428     }
429     // changed directory
430     Error = VFChangeDir("Sample0/Sample1");
431     if (Error != VF_ERR_SUCCESS) {
432         OSReport( "VFDeleteDir Error %s Line %d\n",
433                   VFGetApiErrorString(Error), __LINE__);
434         OSReport( "VFChangeDir failed. = test success!\n");
435     }
436 
437     /**
438      * Rename Directory
439      */
440     OSReport("[mount drive A for NAND - VFRenameDir]\n");
441     Error = VFRenameDir("A:/subDir0", "A:/subDirXXX");
442     if (Error != VF_ERR_SUCCESS) {
443         OSReport("VFRenameDir Error %s Line %d\n",
444                  VFGetApiErrorString(Error), __LINE__);
445     }
446 
447     OSReport( "mount drive A Success!\n" );
448 
449     //------------------------------------------------------------------
450     // reference drive A
451     //------------------------------------------------------------------
452     {
453         u8 	readBuf[TEST_DATA_SIZE];
454         VFFile* fp = NULL;
455         int 	i;
456         s32	fileSize;
457 
458         // Open file
459         OSReport("[reference drive A - VFOpenFile]\n");
460         fp = VFOpenFile("SAMPLEA.txt", "r", 0);
461         if (fp == NULL){
462             OSReport("VFOpenFile Error %s Line %d\n",
463                      VFGetApiErrorString(VFGetLastError()), __LINE__);
464         }
465 
466         // seek file
467         OSReport("[reference drive A - VFSeekFile]\n");
468         Error = VFSeekFile(fp, 5, VF_SEEK_SET);
469         if (Error != VF_ERR_SUCCESS) {
470             OSReport("VFSeekFile Error %s Line %d\n",
471                      VFGetApiErrorString(Error), __LINE__);
472         }
473 
474         // get file size
475         fileSize = VFGetFileSizeByFd(fp);
476 
477         if (fileSize != -1) {
478             u32	readSize = 0;
479 
480             // Read file
481             OSReport("[reference drive A - VFReadFile nowSeekOffset %d]\n",
482                      VFGetOffsetByFd(fp));
483             Error = VFReadFile(fp, readBuf, (u32)fileSize, &readSize);
484             if (Error != VF_ERR_SUCCESS) {
485                 OSReport("VFReadFile Error %s Line %d\n",
486                          VFGetApiErrorString(Error), __LINE__);
487             }
488             else {
489                 OSReport("# VFReadFile fileSize %d readSize %d\n",
490                          fileSize,
491                          readSize);
492             }
493 
494             // printf
495             OSReport("[ReadBuff]\n");
496             for (i=0; i<readSize; i++) {
497                 OSReport("%02x ", readBuf[i]);
498                 if ((i & 15) == 15) {
499                     OSReport("\n");
500                 }
501             }
502         }
503 
504         // close
505         OSReport("[reference drive A - VFCloseFile]\n");
506         Error = VFCloseFile( fp );
507         if (Error != VF_ERR_SUCCESS) {
508             OSReport("VFReadFile Error %s Line %d\n",
509                      VFGetApiErrorString(Error), __LINE__);
510         }
511 
512         OSReport("reference drive A Success!\n");
513     }
514 
515     //------------------------------------------------------------------
516     // print drive A Root Directory
517     //------------------------------------------------------------------
518     {
519         VFDta*	dta_p = (VFDta*)OSAlloc(sizeof(VFDta));
520         char*	name_p;
521         u8	attribute = 0;
522 
523         if (dta_p) {
524             OSReport("\n[print drive A Root Directory]\n");
525             // search first
526             Error = VFFileSearchFirst(dta_p, "A:/*", VF_ATTR_CAND);
527             if (Error == VF_ERR_SUCCESS) {
528                 name_p = (char*)VF_DTA_GET_LONG_FILE_NAME_P(*dta_p);
529                 attribute = VF_DTA_GET_FILE_ATTR(*dta_p);
530                 OSReport("<%s>", name_p);
531                 if (attribute & VF_ATTR_DIR) {
532                     OSReport(" is Directory.\n");
533                 }
534                 else {
535                     OSReport(" is File.\n");
536                 }
537 
538                 while (1) {
539                     // search next
540                     Error = VFFileSearchNext(dta_p);
541                     if (Error == VF_ERR_SUCCESS) {
542                         name_p = (char*)VF_DTA_GET_LONG_FILE_NAME_P(*dta_p);
543                         attribute = VF_DTA_GET_FILE_ATTR(*dta_p);
544                         OSReport("<%s>", name_p);
545                         if (attribute & VF_ATTR_DIR) {
546                             OSReport(" is Directory.\n");
547                         }
548                         else {
549                             OSReport(" is File.\n");
550                         }
551                     }
552                     else {
553                         break;
554                     }
555                 }
556             }
557             else {
558                 OSReport("VFFileSearchFirst Error %s Line %d\n",
559                          VFGetApiErrorString(Error), __LINE__);
560             }
561             OSReport("\n");
562             OSFree(dta_p);
563         }
564     }
565 
566     //------------------------------------------------------------------
567     // unmount drive A
568     //------------------------------------------------------------------
569     Error = VFUnmountDrive( "A" );
570     if (Error != VF_ERR_SUCCESS) {
571         OSReport("VFUnmountDrive Error %s Line %d\n",
572                  VFGetApiErrorString(Error), __LINE__);
573         OSHalt("Can't unmount nand drive.");
574     }
575     OSReport("unmount drive A Success!\n");
576 #endif //#if defined(USE_NAND)
577 
578     //------------------------------------------------------------------
579     // VF finalize
580     //------------------------------------------------------------------
581     VFFinalize();
582 }
583 
584