1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - WBT - demos - wbt-1
3 File: bt.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-09-18#$
14 $Rev: 8576 $
15 $Author: nishimoto_takashi $
16 *---------------------------------------------------------------------------*/
17
18 #ifdef SDK_TWL
19 #include <twl.h>
20 #else
21 #include <nitro.h>
22 #endif
23
24 #include <nitro/wbt.h>
25 #include "wh.h"
26 #include "bt.h"
27 #include "text.h"
28
29 #define NOT_USE_ALLOC
30
31 #ifndef SDK_NO_MESSAGE
32 #define __MY_LINE__ __LINE__
33 #else
34 #define __MY_LINE__ 0
35 #endif
36
37 /* Reception block control data for child device */
38 static int request_block_num;
39 static int block_info_num = 0;
40 static OSTick start_tick;
41 static int bt_loop_count = 0;
42 static int bt_running = 0;
43
44 /* Child device receive buffers */
45 static WBTBlockInfoTable block_info_table;
46 static WBTRecvBufTable recv_buf_table;
47 static WBTPacketBitmapTable recv_buf_packet_bmp_table;
48 static WBTAidBitmap tbmp = 1; /* Request partner (parent) */
49
50 /* User data send buffer for child device */
51 static u8 user_data[WBT_SIZE_USER_DATA];
52
53 #ifdef NOT_USE_ALLOC
54 WBTBlockInfo block_info[WBT_NUM_OF_AID][NUM_OF_BT_LIST];
55 u8 recv_buf[WBT_NUM_OF_AID][BT_DATA_SIZE];
56 u32
57 recv_pkt_bmp_buf[WBT_NUM_OF_AID][WBT_PACKET_BITMAP_SIZE(BT_DATA_SIZE, BT_PARENT_PACKET_SIZE)];
58 #endif
59
60 /* Block data for parent device */
61 static WBTBlockInfoList bt_list[NUM_OF_BT_LIST];
62 static u8 bt_data[NUM_OF_BT_LIST][BT_DATA_SIZE];
63
64 static u8 user_char_id[NUM_OF_BT_LIST][WBT_USER_ID_LEN] = {
65 "BT text information area 0",
66 "BT text information area 1",
67 "BT text information area 2",
68 #if 0
69 "BT text information area 3",
70 "BT text information area 4"
71 #endif
72 };
73
74
75 const char *command_str[] = {
76 "REQ_NONE",
77 "REQ_WAIT",
78 "REQ_SYNC",
79 "RES_SYNC",
80 "REQ_GET_BLOCK",
81 "RES_GET_BLOCK",
82 "REQ_GET_BLOCKINFO",
83 "RES_GET_BLOCKINFO",
84 "REQ_GET_BLOCK_DONE",
85 "RES_GET_BLOCK_DONE",
86 "REQ_USER_DATA",
87 "RES_USER_DATA",
88 "SYSTEM_CALLBACK",
89 "PREPARE_SEND_DATA",
90 "REQ_ERROR",
91 "RES_ERROR",
92 "CANCEL"
93 };
94
95
96
97
strlen(char * str)98 static int strlen(char *str)
99 {
100 int i = 0;
101 while (1)
102 {
103 if (*str != '\0')
104 {
105 str++;
106 i++;
107 }
108 else
109 {
110 break;
111 }
112 }
113 return i;
114 }
115
116
117 /* Block registration function for parent device */
bt_register_blocks(void)118 void bt_register_blocks(void)
119 {
120 int i;
121 char *end_string = "This is BlockTransfer test data contents end\n";
122 char *ptr;
123 int offset;
124
125 for (i = 0; i < NUM_OF_BT_LIST; i++)
126 {
127 offset = BT_DATA_SIZE - (strlen(end_string) + 1);
128 *(s32 *)(&(bt_data[i][0])) = offset;
129 (void)OS_SPrintf((char *)&(bt_data[i][4]),
130 "This is BlockTransfer test data contents start %d\n", i);
131
132 ptr = (char *)(&(bt_data[i][0]) + offset);
133 (void)OS_SPrintf((char *)ptr, "%s", end_string);
134
135 (void)WBT_RegisterBlock(&(bt_list[i]), (u32)(10000 + i) /* IDs of 1000 or less are not allowed */ ,
136 user_char_id[i], &(bt_data[i][0]), BT_DATA_SIZE, 0);
137 }
138 }
139
140
141 /* Block transmission end function for child device */
bt_stop(void)142 void bt_stop(void)
143 {
144 bt_running = 0;
145 (void)WBT_CancelCurrentCommand(0xffff);
146 }
147
148
149 /* Block transmission start function for child device */
bt_start(void)150 void bt_start(void)
151 {
152 OSIntrMode enabled;
153 static int init_flag = FALSE;
154 int i;
155
156 enabled = OS_DisableInterrupts();
157
158 if (bt_running)
159 {
160 (void)OS_RestoreInterrupts(enabled);
161 return;
162 }
163 bt_running = 1;
164
165 #ifdef NOT_USE_ALLOC
166
167 if (init_flag == FALSE)
168 {
169 init_flag = TRUE;
170 for (i = 0; i < WBT_NUM_OF_AID; i++)
171 {
172 block_info_table.block_info[i] = &(block_info[i][0]);
173 recv_buf_table.recv_buf[i] = &(recv_buf[i][0]);
174 recv_buf_packet_bmp_table.packet_bitmap[i] = &(recv_pkt_bmp_buf[i][0]);
175 }
176 }
177
178 #else
179
180 mfprintf(tc[2], "child bt start\n");
181
182 if (init_flag == FALSE)
183
184 {
185 init_flag = TRUE;
186 /* Initialize child device receive buffers */
187 for (i = 0; i < WBT_NUM_OF_AID; i++)
188 {
189 block_info_table.block_info[i] = NULL;
190 recv_buf_table.recv_buf[i] = NULL;
191 recv_buf_packet_bmp_table.packet_bitmap[i] = NULL;
192 }
193 }
194
195 for (i = 0; i < WBT_NUM_OF_AID; i++)
196 {
197 if (block_info_table.block_info[i] != NULL)
198 {
199 OS_Free(block_info_table.block_info[i]);
200 block_info_table.block_info[i] = NULL;
201 }
202 if (recv_buf_table.recv_buf[i] != NULL)
203 {
204 OS_Free(recv_buf_table.recv_buf[i]);
205 recv_buf_table.recv_buf[i] = NULL;
206 }
207 if (recv_buf_packet_bmp_table.packet_bitmap[i] != NULL)
208 {
209 OS_Free(recv_buf_packet_bmp_table.packet_bitmap[i]);
210 recv_buf_packet_bmp_table.packet_bitmap[i] = NULL;
211 }
212 }
213 #endif
214
215 (void)OS_RestoreInterrupts(enabled);
216
217 (void)WBT_RequestSync(tbmp, /* Partner that is requesting Sync (multiple only possible for parent) */
218 bt_callback /* Callback when ending */
219 );
220 }
221
222
223 /* Callback function for block transmission */
bt_callback(void * arg)224 void bt_callback(void *arg)
225 {
226
227 WBTCommand *uc = (WBTCommand *)arg;
228 int peer_aid = WBT_AidbitmapToAid(uc->peer_bmp); /* AID of communications partner station */
229 // mfprintf(tc[2],"aid = %d\n", peer_aid);
230
231 switch (uc->event)
232 {
233 case WBT_CMD_RES_SYNC:
234 /* WBT_RequestSync end */
235 request_block_num = 0;
236 block_info_num = uc->sync.num_of_list; /* Number of blocks held by partner */
237 mfprintf(tc[2], "blockinfo num = %d my_packet_size = %d peer_packet_size = %d\n", block_info_num, uc->sync.my_packet_size, /* Partner's send data size */
238 uc->sync.peer_packet_size /* Send data size here */
239 );
240 #ifndef NOT_USE_ALLOC
241 mfprintf(tc[2], "info buf alloc %d\n", peer_aid);
242 /* Block information table initialization */
243 block_info_table.block_info[peer_aid] = (WBTBlockInfo *)OS_Alloc(sizeof(WBTBlockInfo));
244 #endif
245
246 if (uc->target_bmp == 0) /* Has there been a response from all partner stations? */
247 {
248 (void)OS_SPrintf((char *)user_data, " %5d\n", bt_loop_count);
249
250 /* Send user data */
251 if (FALSE == WBT_PutUserData(tbmp, /* Partner that sends user data (multiple only possible for parent) */
252 user_data, /* User data buffer */
253 WBT_SIZE_USER_DATA, /* User data size of 12 or lower */
254 bt_callback /* Callback when ending */
255 ))
256 {
257 mfprintf(tc[2], "command invoke error %d\n", __MY_LINE__);
258 }
259 }
260 break;
261 case WBT_CMD_RES_USER_DATA:
262
263 if (uc->target_bmp == 0) /* Has there been a response from all partner stations? */
264 {
265 /* Block list request */
266 if (FALSE == WBT_GetBlockInfo(tbmp, /* Partner that makes block list request (multiple only possible for parent) */
267 request_block_num /* Block list number */ ,
268 &block_info_table, /* Block information table */
269 bt_callback /* Callback when ending */
270 ))
271 {
272 mfprintf(tc[2], "command invoke error %d\n", __MY_LINE__);
273 }
274 }
275 break;
276 case WBT_CMD_RES_GET_BLOCKINFO:
277
278 /* End WBT_GetBlockInfo */
279
280 mfprintf(tc[2], "blockinfo %d done\n", uc->get.block_id); /* Obtained block list ID */
281 mfprintf(tc[2], " info id = %d\n", block_info_table.block_info[peer_aid]->id); /* Block ID */
282 mfprintf(tc[2], " info block size = %d\n", block_info_table.block_info[peer_aid]->block_size); /* Block size */
283 mfprintf(tc[2], " info = %s\n", block_info_table.block_info[peer_aid]->user_id); /* Block user definition information */
284
285 #ifndef NOT_USE_ALLOC
286 /* Initialize receive buffer table */
287 recv_buf_table.recv_buf[peer_aid] =
288 (u8 *)OS_Alloc((u32)block_info_table.block_info[peer_aid]->block_size);
289 mfprintf(tc[2], "recv buf alloc %d\n", peer_aid);
290
291 /* Initialize buffer table for registration of packet reception number */
292 recv_buf_packet_bmp_table.packet_bitmap[peer_aid] =
293 (u32 *)
294 OS_Alloc((u32)
295 WBT_CalcPacketbitmapSize(block_info_table.block_info[peer_aid]->block_size));
296
297 mfprintf(tc[2], "recv pkt bmp size = %d\n",
298 WBT_CalcPacketbitmapSize(block_info_table.block_info[peer_aid]->block_size));
299 #endif
300
301 if (uc->target_bmp == 0) /* Has there been a response from all partner stations? */
302 {
303
304 /* Block reception request */
305 if (FALSE == WBT_GetBlock(tbmp, /* Partner that makes the block reception request (multiple only possible for parent) */
306 block_info_table.block_info[peer_aid]->id /* Block ID */ ,
307 &recv_buf_table, /* Receive buffer table */
308 (u32)block_info_table.block_info[peer_aid]->block_size, /* Block size */
309 &recv_buf_packet_bmp_table, /* Buffer table for registration of packet reception number */
310 bt_callback /* Callback when ending */
311 ))
312 {
313 mfprintf(tc[2], "command invoke error %d\n", __MY_LINE__);
314 }
315 else
316 {
317 start_tick = OS_GetTick(); /* Start time measurement */
318 }
319
320 }
321
322 break;
323 case WBT_CMD_RES_GET_BLOCK:
324 /* End WBT_GetBlock */
325
326 mfprintf(tc[2], "get block %d done\n", uc->get.block_id); /* Received block ID */
327 mfprintf(tc[2], " time %d msec\n", OS_TicksToMilliSeconds(OS_GetTick() - start_tick));
328
329 mfprintf(tc[2], " %s\n", &(recv_buf_table.recv_buf[peer_aid][4])); /* Received block contents */
330 {
331 u32 offset;
332 offset = *(u32 *)&(recv_buf_table.recv_buf[peer_aid][0]);
333 mfprintf(tc[2], " %s\n", (char *)(&(recv_buf_table.recv_buf[peer_aid][offset])));
334 }
335
336 #ifndef NOT_USE_ALLOC
337 /* Reception buffer table deallocation */
338 mfprintf(tc[2], "recv buf free %d\n", peer_aid);
339 OS_Free(recv_buf_table.recv_buf[peer_aid]);
340 recv_buf_table.recv_buf[peer_aid] = NULL;
341
342 /* Deallocation of buffer table for recording of the packet reception number */
343 OS_Free(recv_buf_packet_bmp_table.packet_bitmap[peer_aid]);
344 recv_buf_packet_bmp_table.packet_bitmap[peer_aid] = NULL;
345
346 OS_Free(block_info_table.block_info[peer_aid]);
347 block_info_table.block_info[peer_aid] = NULL;
348
349 {
350 mfprintf(tc[2], "info buf alloc %d\n", peer_aid);
351 /* Block information table initialization */
352 block_info_table.block_info[peer_aid] = (WBTBlockInfo *)OS_Alloc(sizeof(WBTBlockInfo));
353 }
354 #endif
355
356 if (uc->target_bmp == 0)
357 { /* Has there been a response from all requested partner stations? */
358
359 request_block_num++;
360
361 if (request_block_num < block_info_num)
362 {
363
364 /* Block list request */
365 if (FALSE == WBT_GetBlockInfo(tbmp, request_block_num, /* Block list number */
366 &block_info_table, /* Block information table */
367 bt_callback /* Callback when ending */
368 ))
369 {
370 mfprintf(tc[2], "command invoke error %d\n", __MY_LINE__);
371 }
372 }
373 else
374 {
375 request_block_num = 0;
376
377 bt_loop_count++;
378 if (bt_loop_count > 99999)
379 {
380 bt_loop_count = 0;
381 }
382
383 (void)OS_SPrintf((char *)user_data, " %05d\n", bt_loop_count);
384
385 /* Send user data */
386 if (FALSE == WBT_PutUserData(tbmp, /* Partner that sends user data (multiple only possible for parent) */
387 user_data, /* User data buffer */
388 WBT_SIZE_USER_DATA, /* User data size of 12 or lower */
389 bt_callback /* Callback when ending */
390 ))
391 {
392 mfprintf(tc[2], "command invoke error %d\n", __MY_LINE__);
393 }
394 }
395 }
396 break;
397 case WBT_CMD_REQ_NONE:
398 mfprintf(tc[2], "WBT user none\n");
399 break;
400 case WBT_CMD_REQ_USER_DATA:
401 mfprintf(tc[2], "get user data = %s\n", uc->user_data.data);
402 break;
403 case WBT_CMD_REQ_GET_BLOCK_DONE:
404 mfprintf(tc[2], "get peer getblockdone %d done from %d\n", uc->blockdone.block_id,
405 peer_aid);
406 break;
407 case WBT_CMD_REQ_SYNC:
408 mfprintf(tc[2], "get peer sync from %d\n", peer_aid);
409 break;
410 case WBT_CMD_RES_ERROR:
411 mfprintf(tc[2], "get req error %d from %d\n", peer_aid, uc->result);
412 break;
413 case WBT_CMD_REQ_ERROR:
414 mfprintf(tc[2], "get res error %d from %d\n", peer_aid, uc->result);
415 break;
416 case WBT_CMD_CANCEL:
417 mfprintf(tc[2], "get canncel [%s] command from %d\n", command_str[uc->command], peer_aid);
418 break;
419 default:
420 mfprintf(tc[2], "WBT callback unknown %d\n", uc->event);
421 break;
422 }
423 }
424