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(&current, &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