1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - WM - demos - wireless-all
3 File: test.c
4
5 Copyright 2006-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:: 2008-10-02#$
14 $Rev: 8827 $
15 $Author: yosizaki $
16 *---------------------------------------------------------------------------*/
17
18 #ifdef SDK_TWL
19 #include <twl.h>
20 #else
21 #include <nitro.h>
22 #endif
23
24 #include "common.h"
25
26
27 /*****************************************************************************/
28 /* Variables */
29
30 /* Variable for parent WFS testing */
31 static BOOL is_parent_sync = FALSE;
32 static int parent_packet_size = WH_PARENT_MAX_SIZE;
33
34 /* Variable for child WFS testing */
35 static u8 tmp_buf[1024 * 128];
36 static int file_index = -1;
37 static OSTick read_tick;
38 static int read_byte;
39 static int read_time;
40 static BOOL file_sync_mode;
41 static FSFile file[1];
42
43 static const char *file_path[] = {
44 "test/16kB.bin",
45 "test/64kB.bin",
46 };
47 static const int file_max = sizeof(file_path) / sizeof(*file_path);
48
49
50 /*****************************************************************************/
51 /* Functions */
52
53 /*---------------------------------------------------------------------------*
54 Name: BeginFileTest
55
56 Description: Begins file read testing.
57
58 Arguments: None.
59
60 Returns: TRUE when asynchronous read begins normally.
61 *---------------------------------------------------------------------------*/
BeginFileTest(void)62 static BOOL BeginFileTest(void)
63 {
64 BOOL retval = FALSE;
65 if (FS_OpenFileEx(file, file_path[file_index], FS_FILEMODE_R))
66 {
67 read_tick = OS_GetTick();
68 read_byte = (int)FS_GetFileLength(file);
69 read_time = 0;
70 if (read_byte > (int)sizeof(tmp_buf))
71 {
72 read_byte = (int)sizeof(tmp_buf);
73 }
74 OS_TPrintf("reading... %d BYTE\n", read_byte);
75 if (FS_ReadFileAsync(file, tmp_buf, sizeof(tmp_buf)))
76 {
77 retval = TRUE;
78 }
79 }
80 return retval;
81 }
82
83 /*---------------------------------------------------------------------------*
84 Name: EndFileTest
85
86 Description: Completes the file read testing.
87
88 Arguments: None.
89
90 Returns: None.
91 *---------------------------------------------------------------------------*/
EndFileTest(void)92 static void EndFileTest(void)
93 {
94 if (FS_IsSucceeded(file))
95 {
96 u64 milli = OS_TicksToMilliSeconds(OS_GetTick() - read_tick);
97 if (!milli)
98 {
99 milli = 1;
100 }
101 read_time = (int)(((u64)read_byte * 8 * 1000) / milli);
102 }
103 else
104 {
105 read_time = -1;
106 }
107 (void)FS_CloseFile(file);
108 }
109
110 /*---------------------------------------------------------------------------*
111 Name: UpdateFrame
112
113 Description: Frame update process.
114
115 Arguments: None.
116
117 Returns: None.
118 *---------------------------------------------------------------------------*/
UpdateFrame(void)119 static void UpdateFrame(void)
120 {
121 /* Parent operations */
122 if (!MB_IsMultiBootChild())
123 {
124 /* Switch the transmission packet size */
125 int new_packet_size = parent_packet_size;
126 if (IS_PAD_TRIGGER(PAD_KEY_UP))
127 {
128 new_packet_size += 2;
129 if (new_packet_size > WH_PARENT_MAX_SIZE)
130 new_packet_size = 16;
131 }
132 if (IS_PAD_TRIGGER(PAD_KEY_DOWN))
133 {
134 new_packet_size -= 2;
135 if (new_packet_size < 16)
136 new_packet_size = WH_PARENT_MAX_SIZE;
137 }
138 if (parent_packet_size != new_packet_size)
139 {
140 parent_packet_size = new_packet_size;
141 WFS_SetPacketSize(parent_packet_size);
142 }
143 /*
144 * Press the A Button to switch to synchronous mode.
145 *
146 * This will cause access to be blocked for the first child if even one of the children specified to be synchronous does not receive the request.
147 *
148 * This setting can make communications more efficient if it is clear that the same combination of files will be requested in the same order.
149 *
150 *
151 * This setting will be reset automatically and a warning message will be sent to debug output when a group of children has conflicting access requests.
152 *
153 */
154 if (IS_PAD_TRIGGER(PAD_BUTTON_A))
155 {
156 is_parent_sync = !is_parent_sync;
157 WFS_EnableSync(is_parent_sync ? WFS_GetCurrentBitmap() : 0);
158 }
159 }
160 /* Child operations */
161 else
162 {
163 /* Select the file that should be read */
164 if (IS_PAD_TRIGGER(PAD_KEY_UP))
165 {
166 if (--file_index < 0)
167 {
168 file_index = file_max - 1;
169 }
170 }
171 if (IS_PAD_TRIGGER(PAD_KEY_DOWN))
172 {
173 if (++file_index > file_max - 1)
174 {
175 file_index = 0;
176 }
177 }
178 /* Switch between synchronous and asynchronous modes for testing */
179 if (IS_PAD_TRIGGER(PAD_KEY_LEFT) || IS_PAD_TRIGGER(PAD_KEY_RIGHT))
180 {
181 file_sync_mode = !file_sync_mode;
182 }
183 /* Confirm completion during asynchronous read testing */
184 if (FS_IsFile(file))
185 {
186 /* Measure if completed */
187 if (!FS_IsBusy(file))
188 {
189 EndFileTest();
190 }
191 }
192 /* If possible, use A button for file read testing */
193 else if (IS_PAD_TRIGGER(PAD_BUTTON_A))
194 {
195 if (!BeginFileTest())
196 {
197 /* When the wireless connection is disconnected, etc. */
198 EndFileTest();
199 }
200 /*
201 * Wait for completion here if this is a synchronous test.
202 * Synchronous operations are not stopped as long as the WFS_End function is not called, so polling is carried out as follows to detect disconnection.
203 *
204 * Except for the fact that it occupies CPU time by polling without transferring threads, this process is essentially equivalent to the FS_ReadFile function.
205 *
206 */
207 else if (file_sync_mode)
208 {
209 while (FS_IsBusy(file))
210 {
211 if (WH_GetSystemState() != WH_SYSSTATE_DATASHARING)
212 {
213 WFS_End();
214 }
215 #if defined(SDK_ENABLE_ARM7_PRINT)
216 // PrintServer for ARM7 (for debugging purposes)
217 OS_PrintServer();
218 #endif
219 }
220 EndFileTest();
221 }
222 }
223 }
224 /* End communications with the START button */
225 if (IS_PAD_TRIGGER(PAD_BUTTON_START))
226 {
227 (void)WH_Finalize();
228 }
229 }
230
231
232 /*---------------------------------------------------------------------------*
233 Name: DrawFrame
234
235 Description: Frame render process.
236
237 Arguments: None.
238
239 Returns: None.
240 *---------------------------------------------------------------------------*/
DrawFrame(void)241 static void DrawFrame(void)
242 {
243 int i;
244
245 /* Display data sharing reception status */
246 PrintString(8, 1, 0x2, "data-sharing mode");
247 PrintString(4, 5, 0x4, "Receive:");
248 for (i = 0; i < WH_PLAYER_MAX; ++i)
249 {
250 GShareData *input = GetCurrentInput(i);
251 if (input)
252 {
253 PrintString(4, (s16)(6 + i), 0x4,
254 "Player%02d: %04x-%04x", i, input->key, input->count & 0xFFFF);
255 }
256 else
257 {
258 PrintString(4, (s16)(6 + i), 0x7, "No child");
259 }
260 }
261
262 PrintString(0, 11, PLTT_BLUE, "--------------------------------");
263
264 /* Display WFS test */
265 if (!MB_IsMultiBootChild())
266 {
267 /* Parent */
268 PrintString(3, 13, PLTT_GREEN, "<UP & DOWN key>");
269 PrintString(3, 14, PLTT_WHITE, "parent packet ... %d BYTE", parent_packet_size);
270
271 PrintString(3, 15, PLTT_GREEN, "<toggle A button>");
272 PrintString(3, 16, PLTT_WHITE, "sync mode ... %s",
273 is_parent_sync ? "ENABLE" : "DISABLE");
274
275 PrintString(3, 17, PLTT_GREEN, "bitmap status");
276 PrintString(9, 18, PLTT_BLUE, "+ idle");
277 PrintString(9, 19, PLTT_BLUE, "* busy");
278 PrintString(9, 20, PLTT_BLUE, "! sync-blocking");
279 PrintString(9, 21, PLTT_BLUE, "- not connected");
280
281 PrintString(3, 19, PLTT_BLUE, "0123");
282 {
283 const int cur_bitmap = WFS_GetCurrentBitmap();
284 const int busy_bitmap = WFS_GetBusyBitmap();
285 const int sync_bitmap = WFS_GetSyncBitmap();
286 for (i = 0; i < WH_PLAYER_MAX; ++i)
287 {
288 char c;
289 const int bit = (1 << i);
290 if ((bit & busy_bitmap) != 0)
291 c = '*';
292 else if ((bit & cur_bitmap) != 0)
293 c = '+';
294 else
295 c = '-';
296 PrintString(3 + i, 20, PLTT_WHITE, "%c", c);
297 if ((bit & sync_bitmap) != 0)
298 PrintString(3 + i, 21, PLTT_WHITE, "!");
299 }
300 }
301 }
302 else
303 {
304 /* Child */
305 if (WFS_GetStatus() == WFS_STATE_READY)
306 {
307 /* Display operations overview and current setting items */
308 PrintString(3, 13, PLTT_GREEN, "<LEFT & RIGHT key>");
309 if (!file_sync_mode)
310 {
311 PrintString(3, 14, PLTT_WHITE, " sync ");
312 PrintString(10, 14, PLTT_YELLOW, "[async]");
313 }
314 else
315 {
316 PrintString(3, 14, PLTT_YELLOW, "[sync]");
317 PrintString(10, 14, PLTT_WHITE, " async ");
318 }
319 PrintString(3, 15, PLTT_GREEN, "<UP & DOWN key>");
320 PrintString(3, 16 + file_index, PLTT_YELLOW, ">");
321 for (i = 0; i < file_max; ++i)
322 {
323 PrintString(5, 16 + i, (i == file_index) ? PLTT_YELLOW : PLTT_WHITE, file_path[i]);
324 }
325 PrintString(3, 16 + file_max, PLTT_GREEN, "<press A button>");
326 /* Display when read test fails */
327 if (read_time == -1)
328 {
329 PrintString(3, 20, PLTT_WHITE, "read error!");
330 }
331 /* Display when read test succeeds */
332 else if (read_time != 0)
333 {
334 PrintString(3, 20, PLTT_WHITE, "read done %d BYTE", read_byte);
335 PrintString(3, 21, PLTT_WHITE, "%d [bps]", read_time);
336 }
337 /* Display during read test */
338 else
339 {
340 int current, total;
341 if (WFS_GetCurrentDownloadProgress(¤t, &total))
342 {
343 PrintString(3, 20, PLTT_WHITE, "reading %d BYTE", read_byte);
344 PrintString(3, 21, PLTT_WHITE, "%8d / %d", current, total);
345 }
346 }
347 }
348 }
349 }
350
351 /*---------------------------------------------------------------------------*
352 Name: ExecuteDataSharing
353
354 Description: Main process for data sharing.
355 WFS process in background.
356
357 Arguments: None.
358
359 Returns: None.
360 *---------------------------------------------------------------------------*/
ExecuteDataSharing(void)361 void ExecuteDataSharing(void)
362 {
363 /* Work variable initialization */
364 file_index = 0;
365 FS_InitFile(file);
366
367 /* Stand by until data sharing preparations are complete and then launch WFS */
368 WaitWHState(WH_SYSSTATE_DATASHARING);
369 WFS_Start();
370
371 /* Frame processing as long as communication continues */
372 while (WH_GetSystemState() == WH_SYSSTATE_DATASHARING)
373 {
374 if (WaitNextFrame())
375 {
376 /* Update the process if data sharing is successful */
377 UpdateFrame();
378 }
379 DrawFrame();
380 }
381
382 /* Because MP communications are finished, terminate WFS */
383 WFS_End();
384 WaitWHState(WH_SYSSTATE_IDLE);
385
386 }
387