1 /*---------------------------------------------------------------------------*
2 Project: Sample demo program for NAND library
3 File: async.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: async.c,v $
15 Revision 1.4 06/05/2006 13:07:26 hiratsu
16 Removed NANDFinalize().
17
18 Revision 1.3 05/09/2006 09:09:51 hiratsu
19 Added new tutorial code.
20
21 Revision 1.2 05/04/2006 04:49:33 hiratsu
22 Redesigned. Implemented chain of callback.
23
24 Revision 1.1 05/03/2006 09:08:54 hiratsu
25 Initial check-in. This is a sample code to use async NAND APIs.
26
27 *---------------------------------------------------------------------------*/
28
29 #include <stdio.h>
30 #include <string.h>
31 #include <stdlib.h>
32 #include <revolution.h>
33 #include <revolution/nand.h>
34
35 #include "util.h"
36
37 #define PATH "/tmp/nanddemo.dat"
38 #define PERM (NAND_PERM_OWNER_READ | NAND_PERM_OWNER_WRITE) // Owner can read/write
39 #define ATTR 0x00 // No attributes.
40 #define DATA_SIZE 1024*1024
41
42 static NANDCommandBlock s_block;
43 static NANDFileInfo s_info;
44 static u8 s_data[DATA_SIZE] ATTRIBUTE_ALIGN(32);
45 static volatile BOOL s_finished_flag = FALSE;
46
47 struct UserDataType
48 {
49 BOOL finished_flag;
50 s32 resultCode;
51 };
52
53 static void callback(s32 result, NANDCommandBlock *block);
54
55 static void sample1(void);
56 static void create (void);
57 static void openCallback (s32 result, NANDCommandBlock *block);
58 static void writeCallback (s32 result, NANDCommandBlock *block);
59 static void closeCallback (s32 result, NANDCommandBlock *block);
60 static void deleteCallback(s32 result, NANDCommandBlock *block);
61 static void finishCallback(s32 result, NANDCommandBlock *block);
62
63 static void sample2(void);
64
65
main(void)66 int main(void)
67 {
68 if(NANDInit()!=NAND_RESULT_OK)
69 {
70 OSHalt("NANDInit() failed.");
71 }
72
73 sample1();
74
75 sample2();
76
77 OSHalt("Finished with success");
78 return EXIT_SUCCESS; // Never reach here.
79 }
80
81
callback(s32 result,NANDCommandBlock * block)82 static void callback(s32 result, NANDCommandBlock *block)
83 {
84 ((struct UserDataType*)NANDGetUserData(block))->finished_flag = TRUE;
85 ((struct UserDataType*)NANDGetUserData(block))->resultCode = result;
86 }
87
88
sample1(void)89 static void sample1(void)
90 {
91 memset(s_data, 'A', DATA_SIZE);
92 create();
93 while(!s_finished_flag)
94 ;
95 OSReport("sample1() finished.\n");
96 }
97
98
create(void)99 static void create(void)
100 {
101 s32 ret = NANDCreateAsync(PATH, PERM, ATTR, openCallback, &s_block);
102 if(ret != NAND_RESULT_OK)
103 {
104 printErrMsg(ret);
105 OSHalt("NANDCreateAsync() failed.\n");
106 }
107 }
108
109
openCallback(s32 result,NANDCommandBlock *)110 static void openCallback(s32 result, NANDCommandBlock*)
111 {
112 if(result==NAND_RESULT_OK)
113 {
114 s32 ret = NANDOpenAsync(PATH, &s_info, NAND_ACCESS_WRITE | NAND_ACCESS_READ, writeCallback, &s_block);
115 if(ret != NAND_RESULT_OK)
116 {
117 printErrMsg(ret);
118 OSHalt("NANDOpenAsync() failed.");
119 }
120 }
121 else
122 {
123 OSHalt("NANDCreateAsync() failed.");
124 }
125 }
126
127
writeCallback(s32 result,NANDCommandBlock *)128 static void writeCallback(s32 result, NANDCommandBlock*)
129 {
130 if(result==NAND_RESULT_OK)
131 { s32 ret =NANDWriteAsync(&s_info, s_data, DATA_SIZE, closeCallback, &s_block);
132 if(ret != NAND_RESULT_OK)
133 {
134 printErrMsg(ret);
135 OSHalt("NANDWriteAsync() failed.");
136 }
137 }
138 else
139 {
140 OSHalt("NANDOpenAsync() failed.");
141 }
142
143 }
144
closeCallback(s32 result,NANDCommandBlock *)145 static void closeCallback(s32 result, NANDCommandBlock*)
146 {
147 if(result==DATA_SIZE)
148 {
149 s32 ret = NANDCloseAsync(&s_info, deleteCallback, &s_block);
150 if(ret != NAND_RESULT_OK)
151 {
152 printErrMsg(ret);
153 OSHalt("NANDCloseAsync() failed.");
154 }
155 }
156 else
157 {
158 OSHalt("NANDWriteAsync() failed.");
159 }
160 }
161
162
deleteCallback(s32 result,NANDCommandBlock *)163 static void deleteCallback(s32 result, NANDCommandBlock*)
164 {
165 if(result==NAND_RESULT_OK)
166 {
167 s32 ret = NANDDeleteAsync(PATH, finishCallback, &s_block);
168 if(ret != NAND_RESULT_OK)
169 {
170 printErrMsg(ret);
171 OSHalt("NANDDeleteAsync() failed.");
172 }
173 }
174 else
175 {
176 OSHalt("NANDCloseAsync() failed.");
177 }
178 }
179
180
finishCallback(s32 result,NANDCommandBlock *)181 static void finishCallback(s32 result, NANDCommandBlock*)
182 {
183 if(result==NAND_RESULT_OK)
184 {
185 s_finished_flag = TRUE;
186 }
187 else
188 {
189 OSHalt("NANDDeleteAsync() failed.");
190 }
191 }
192
193
194 #define ASYNC_CALLS 8
195
sample2(void)196 static void sample2(void)
197 {
198 volatile struct UserDataType userData[ASYNC_CALLS];
199 NANDCommandBlock block[ASYNC_CALLS];
200 int i = 0;
201
202 // Start async calls.
203 for(i = 0; i<ASYNC_CALLS; ++i)
204 {
205 s32 result = NAND_RESULT_FATAL_ERROR;
206 char path[NAND_MAX_PATH];
207 userData[i].finished_flag = FALSE;
208 userData[i].resultCode = NAND_RESULT_FATAL_ERROR;
209 NANDSetUserData(&block[i], (void*)&userData[i]);
210 sprintf(path, "/tmp/async%d.tmp", i);
211 result = NANDCreateAsync(path, PERM, ATTR, callback, &block[i]);
212 if(result != NAND_RESULT_OK)
213 {
214 userData[i].finished_flag = TRUE;
215 userData[i].resultCode = result;
216 }
217 }
218
219 // Wait async calls to be finished.
220 while(1)
221 {
222 BOOL finished_all_flag = TRUE;
223 for(i=0; i<ASYNC_CALLS; ++i)
224 {
225 finished_all_flag = finished_all_flag & userData[i].finished_flag;
226 }
227 if(finished_all_flag)
228 {
229 break;
230 }
231 }
232
233 // Report results
234 for(i = 0; i<ASYNC_CALLS; ++i)
235 {
236 if(userData[i].resultCode == NAND_RESULT_OK)
237 {
238 OSReport("Async call [%d]...success\n", i);
239 }
240 else
241 {
242 OSReport("Async call [%d]...failed : result code (%d)\n", i, userData[i].resultCode);
243 OSHalt("sample2() failed.");
244 }
245 }
246
247 OSReport("sample2() finished.\n");
248 }
249