1 /*---------------------------------------------------------------------------*
2   Project:      Sample demo program for NAND library
3   File:         safe.c
4   Programmer:   HIRATSU Daisuke
5 
6   Copyright (C) 2006 Nintendo.  All rights reserved.
7 
8   These coded instructions, statements, and computer programs contain
9   proprietary information of Nintendo of America Inc. and/or Nintendo
10   Company Ltd., and are protected by Federal copyright law.  They may
11   not be disclosed to third parties or copied or duplicated in any form,
12   in whole or in part, without the prior written consent of Nintendo.
13 
14   $Log: safe.c,v $
15   Revision 1.4  2007/05/07 12:50:37  hiratsu
16   Modified copy buffer size.
17 
18   Revision 1.3  2007/04/23 09:32:13  hiratsu
19   Replaced NANDSafe series API with NANDSimpleSafe series API.
20 
21   Revision 1.2  2006/08/12 12:00:54  hiratsu
22   Refactoring.
23 
24   Revision 1.1  2006/07/24 07:24:03  hiratsu
25   This demo tells differences between normal Open/Close and SafeOpen/SafeClose.
26 
27  *---------------------------------------------------------------------------*/
28 
29 #include <revolution.h>
30 #include <revolution/nand.h>
31 
32 #include <string.h>
33 
34 #include "util.h"
35 
36 
37 #define PERM (NAND_PERM_OWNER_READ | NAND_PERM_OWNER_WRITE)    // Owner can read/write
38 #define ATTR 0x00                                              // No attributes.
39 #define COPYBUF_SIZE  NAND_FSBLOCK_SIZE
40 #define FILE_SIZE (1*1024*1024)
41 #define SAFE_FILENAME    "safe.dat"
42 #define UNSAFE_FILENAME  "unsafe.dat"
43 
44 
45 static void checkFileData(const char *filename);
46 static void initFile(const char *filename);
47 
48 
checkFileData(const char * filename)49 static void checkFileData(const char *filename)
50 {
51     static u8 s_buf[FILE_SIZE] ATTRIBUTE_ALIGN(32);
52     int i = 0;
53     NANDFileInfo info;
54     s32 rc = NANDOpen(filename, &info, NAND_ACCESS_READ);
55     if(rc!=NAND_RESULT_OK)
56     {
57         printErrMsg(rc);
58     }
59 
60     rc = NANDRead(&info, s_buf, FILE_SIZE);
61     if(rc!=FILE_SIZE)
62     {
63         printErrMsg(rc);
64     }
65 
66     rc = NANDClose(&info);
67     if(rc!=NAND_RESULT_OK)
68     {
69         printErrMsg(rc);
70     }
71 
72     OSReport("Checking anterior half and last half of %s ...  ", filename);
73     if(memcmp(s_buf, s_buf+FILE_SIZE/2, FILE_SIZE/2)==0)
74     {
75         OSReport("Equivalent.\n");
76     }
77     else
78     {
79         OSReport("Different!\n");
80     }
81 }
82 
83 
initFile(const char * filename)84 static void initFile(const char *filename)
85 {
86     s32 rc = NANDCreate(filename, PERM, ATTR);
87     if(rc==NAND_RESULT_OK)
88     {
89         OSReport("Created %s.\n", filename);
90     }
91 
92     if(rc==NAND_RESULT_OK || rc==NAND_RESULT_EXISTS)
93     {
94         static u8 s_buf[FILE_SIZE] ATTRIBUTE_ALIGN(32);
95         NANDFileInfo info;
96         rc = NANDOpen(filename, &info, NAND_ACCESS_WRITE);
97         if(rc!=NAND_RESULT_OK)
98         {
99             printErrMsg(rc);
100         }
101 
102         memset(s_buf, 'A', FILE_SIZE);
103         rc = NANDWrite(&info, s_buf, FILE_SIZE);
104         if(rc!=FILE_SIZE)
105         {
106             printErrMsg(rc);
107         }
108 
109         rc = NANDClose(&info);
110         if(rc!=NAND_RESULT_OK)
111         {
112             printErrMsg(rc);
113         }
114 
115         OSReport("Now %s is filled with 'A'.\n", filename);
116     }
117     else
118     {
119         printErrMsg(rc);
120         OSHalt("Unexpected error.");
121     }
122 }
123 
124 
main(void)125 int main(void)
126 {
127     PADStatus pad[PAD_MAX_CONTROLLERS];
128     NANDFileInfo safeInfo, unsafeInfo;
129     static u8 aryB[FILE_SIZE/2] ATTRIBUTE_ALIGN(32);
130     static u8 copyBuf[COPYBUF_SIZE] ATTRIBUTE_ALIGN(32);
131     s32 rc = NAND_RESULT_FATAL_ERROR;
132     u8 type = 0x00;
133 
134     NANDInit();
135     PADInit();
136     VIInit();
137 
138     memset(aryB, 'B', FILE_SIZE/2);
139 
140     rc = NANDGetType(SAFE_FILENAME, &type);
141     if(rc==NAND_RESULT_OK && type==NAND_TYPE_FILE)
142     {
143         checkFileData(SAFE_FILENAME);
144     }
145 
146     rc = NANDGetType(SAFE_FILENAME, &type);
147     if(rc==NAND_RESULT_OK && type==NAND_TYPE_FILE)
148     {
149         checkFileData(UNSAFE_FILENAME);
150     }
151 
152     initFile(SAFE_FILENAME);
153     initFile(UNSAFE_FILENAME);
154 
155     rc = NANDSimpleSafeOpen(SAFE_FILENAME, &safeInfo, NAND_ACCESS_RW, copyBuf, COPYBUF_SIZE);
156     if(rc != NAND_RESULT_OK)
157     {
158         printErrMsg(rc);
159         OSHalt("Unexpected error.");
160     }
161 
162     rc = NANDOpen(UNSAFE_FILENAME, &unsafeInfo, NAND_ACCESS_RW);
163     if(rc != NAND_RESULT_OK)
164     {
165         printErrMsg(rc);
166         OSHalt("Unexpected error.");
167     }
168 
169     // First write
170     rc = NANDWrite(&safeInfo, aryB, FILE_SIZE/2);
171     if(rc != FILE_SIZE/2)
172     {
173         printErrMsg(rc);
174         OSHalt("Unexpected error.");
175     }
176 
177     // First write
178     rc = NANDWrite(&unsafeInfo, aryB, FILE_SIZE/2);
179     if(rc != FILE_SIZE/2)
180     {
181         printErrMsg(rc);
182         OSHalt("Unexpected error.");
183     }
184 
185     OSReport("Wrote 'B' to both anterior half area.\n");
186 
187     // This operation causes FAT commit.
188     rc = NANDCreate("/tmp/file.tmp", PERM, ATTR);
189     if(rc!=NAND_RESULT_OK)
190     {
191         printErrMsg(rc);
192         OSHalt("create tmp file failed.");
193     }
194 
195     OSReport("Press A button to continue writing data.\n");
196     OSReport("Press START button to quit writing data.\n");
197     OSReport("After that, please execute this demo program again.\n");
198     while(1)
199     {
200         PADRead(pad);
201         if(pad[0].button & PAD_BUTTON_A)
202         {
203             break;
204         }
205         if(pad[0].button & PAD_BUTTON_START)
206         {
207             OSHalt("Program is terminated before closing files.");
208         }
209 
210         VIWaitForRetrace();
211     }
212 
213     // Second write
214     rc = NANDWrite(&safeInfo, aryB, FILE_SIZE/2);
215     if(rc != FILE_SIZE/2)
216     {
217         printErrMsg(rc);
218         OSHalt("Unexpected error.");
219     }
220 
221     // Second write
222     rc = NANDWrite(&unsafeInfo, aryB, FILE_SIZE/2);
223     if(rc != FILE_SIZE/2)
224     {
225         printErrMsg(rc);
226         OSHalt("Unexpected error.");
227     }
228 
229     OSReport("Wrote 'B' to both last half area.\n");
230 
231     rc = NANDSimpleSafeClose(&safeInfo);
232     if(rc != NAND_RESULT_OK)
233     {
234         printErrMsg(rc);
235         OSHalt("Unexpected error.");
236     }
237 
238     rc = NANDClose(&unsafeInfo);
239     if(rc != NAND_RESULT_OK)
240     {
241         printErrMsg(rc);
242         OSHalt("Unexpected error.");
243     }
244 
245     OSHalt("Program completed normally.");
246     return 0;
247 }
248 
249