1 /*---------------------------------------------------------------------------*
2 Project: WPAD health demo program
3 File: wbc_simple.c
4
5 Copyright (C) 2007 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 $Log: $
14 *---------------------------------------------------------------------------*/
15
16 #include <stdlib.h>
17 #include <string.h>
18 #include <stddef.h>
19 #include <stdarg.h>
20 #include <stdio.h>
21 #include <ctype.h>
22
23 #include <revolution.h>
24 #include <revolution/wpad.h>
25 #include <revolution/wpadBalance.h>
26 #include <revolution/sc.h>
27 #include <revolution/wbc.h>
28
29 #define DEMO_USE_MEMLIB=1 // This turns on the DEMO library's MEM heaps.
30 #include <demo.h>
31
32
33 /*---------------------------------------------------------------------------*
34 * Local Definitions
35 *---------------------------------------------------------------------------*/
36 static u8 workarea[WPAD_BLCINT_WORK_LEN] ATTRIBUTE_ALIGN(32);
37 static WPADBLStatus status;
38 static double zero[WPAD_PRESS_UNITS];
39
40 /*---------------------------------------------------------------------------*
41 * Function prototypes
42 *---------------------------------------------------------------------------*/
43 // MEM2 memory allocation routines. The application must provide these to
44 // WPAD, so it can setup the data transfer buffer. This buffer must reside
45 // in MEM2.
46 static void *myAlloc ( u32 size );
47 static u8 myFree ( void *ptr );
48
49
50 // callbacks for CONNECT and EXTENSION events
51 static void connectCallback ( s32 chan, s32 reason );
52 static void extensionCallback ( s32 chan, s32 result );
53
54 /*===========================================================================*
55 * F U N C T I O N D E F I N I T I O N S
56 *===========================================================================*/
WaitMilliTime(s32 msec)57 static void WaitMilliTime(s32 msec)
58 {
59 OSTime t=OSGetTime();
60 while(OSTicksToMilliseconds(OSGetTime()-t) < msec)
61 ;
62 }
63
64
ZeroSetStart2(s32 chan,s32 result)65 static void ZeroSetStart2( s32 chan, s32 result )
66 {
67 #pragma unused(chan, result)
68
69 // Wait about 200[ms] so that Board's press value rarely becomes unstable
70 // after updating Balance Wii Board's temperature.
71 WaitMilliTime(200);
72
73 // Set Zero point.
74 zero[0] = status.press[0]; //Normally, set the average for 2 seconds.
75 zero[1] = status.press[1]; //Normally, set the average for 2 seconds.
76 zero[2] = status.press[2]; //Normally, set the average for 2 seconds.
77 zero[3] = status.press[3]; //Normally, set the average for 2 seconds.
78 WBCSetZEROPoint( zero,(u32)(sizeof(zero) / sizeof(zero[0])));
79 }
80
81
ZeroSetStart(s32 chan,s32 result)82 static void ZeroSetStart( s32 chan, s32 result )
83 {
84 #pragma unused(chan, result)
85
86 // Check Board's temperature.
87 WPADRead(WPAD_CHAN3, &status);
88
89
90 if((status.temp == 127) || (status.temp == -128))
91 {
92 // Update Board's temperature again if you can not get correct Board's temperature.
93 WPADControlBLC(WPAD_CHAN3, WPAD_BLCMD_UPDATE_TEMP, ZeroSetStart2);
94 }
95 else
96 {
97 // Wait about 200[ms] so that Board's press value rarely becomes unstable
98 // after updating Balance Wii Board's temperature.
99 WaitMilliTime(200);
100
101 // Set Zero point.
102 zero[0] = status.press[0]; //Normally, set the average for 2 seconds.
103 zero[1] = status.press[1]; //Normally, set the average for 2 seconds.
104 zero[2] = status.press[2]; //Normally, set the average for 2 seconds.
105 zero[3] = status.press[3]; //Normally, set the average for 2 seconds.
106 WBCSetZEROPoint( zero,(u32)(sizeof(zero) / sizeof(zero[0])));
107 }
108 }
109
110
111 /*---------------------------------------------------------------------------*
112 * Name : main()
113 * Description :
114 * Arguments : None.
115 * Returns : None.
116 *---------------------------------------------------------------------------*/
main(void)117 int main( void )
118 {
119 double weight[WPAD_PRESS_UNITS];
120 u32 type;
121
122 DEMOInit( NULL );
123 DEMOPadInit();
124
125 // If Japan, need to call WPADRegisterBLCWorkarea to set a work buffer.
126 // If not Japan, WPADRegisterBLCWorkarea does nothing.
127 WPADRegisterBLCWorkarea( workarea );
128
129 WPADRegisterAllocator(myAlloc, myFree);
130 WPADInit();
131 WPADSetConnectCallback(WPAD_CHAN3, connectCallback);
132
133 while (WPAD_STATE_SETUP != WPADGetStatus())
134 {
135 ;
136 }
137
138 // You can release the work buffer so initialize of WPAD library has finished.
139 // This sample program is nothing to do so it uses static buffer.
140
141
142 while(1)
143 {
144 DEMOPadRead();
145
146 if (DEMOPadGetButtonDown(0) & PAD_BUTTON_A)
147 {
148 // Update Board's temperature the eve of zero point correction.
149 WPADControlBLC(WPAD_CHAN3, WPAD_BLCMD_UPDATE_TEMP, ZeroSetStart);
150 }
151
152 if (WPADProbe(WPAD_CHAN3, &type) == WPAD_ERR_NO_CONTROLLER)
153 {
154 if (WPADIsRegisteredBLC())
155 {
156 OSReport("Balance Wii board is not connected.\n");
157 }
158 else
159 {
160 OSReport("Balance Wii board is not registered. Please regist Balance Wii board with SYNC button.\n");
161 }
162 }
163 else
164 {
165 if (type == WPAD_DEV_BALANCE_CHECKER)
166 {
167 WPADRead(WPAD_CHAN3, &status);
168
169 if(WBCGetCalibrationStatus() == TRUE)
170 {
171 double total;
172
173 WBCRead(&status, weight, (u32)(sizeof(weight) / sizeof(weight[0])));
174 total = (double)(weight[0]+weight[1]+weight[2]+weight[3]);
175
176 // Show the total weight. Normally, "total" value is the average for 2 seconds.
177 OSReport("%3.1f[kg]\n", WBCGetTGCWeight(total, &status));
178 }
179 else
180 {
181 OSReport("Calibration data read error. Please reconnect Balance Wii board.\n");
182 }
183 }
184 else
185 {
186 OSReport("No Balance Wii board is attached.\n");
187 }
188 }
189 }
190 } // end main()
191
192
193 /*---------------------------------------------------------------------------*
194 * Name : connectCallback()
195 *
196 * Description : This callback is invoked when a controller is connected or
197 * disconnected.
198 *
199 * Arguments : The channel (chan) for which the event has occurred.
200 * The channel status (reason):
201 * WPAD_ERR_NONE means a controller has been connected.
202 * WPAD_ERR_NO_CONTROLLER means a controller disconnected.
203 *
204 * Returns : None.
205 *---------------------------------------------------------------------------*/
connectCallback(s32 chan,s32 reason)206 static void connectCallback(s32 chan, s32 reason)
207 {
208 u32 type;
209
210 if (reason == WPAD_ERR_NONE)
211 {
212 // Disconnect 4P if 4P is not Balance Wii board.
213 // Because 4P is reserved for Balance Wii board.
214 WPADProbe(chan, &type);
215 if (chan == WPAD_CHAN0 && type != WPAD_DEV_BALANCE_CHECKER)
216 {
217 OSReport("Channel%d is reserved for Balance Wii board.\n", chan);
218 WPADDisconnect(chan);
219 }
220 else
221 {
222 // Read the calibration value for calculating a weight.
223 if(WPAD_ERR_NONE != WBCSetupCalibration())
224 {
225 OSHalt("Balance Wii board FATAL ERROR!!\n");
226 }
227 OSReport("Channel%d is connected.\n", chan);
228 WPADSetExtensionCallback(chan, extensionCallback);
229 }
230 }
231 else
232 {
233 OSReport("Channel%d is disconnected.\n", chan);
234 }
235 } // end connectCallback()
236
237 /*---------------------------------------------------------------------------*
238 * Name : extensionCallback()
239 *
240 * Description : This callback is invoked when an Extension has been attached.
241 *
242 * Arguments : The channel (chan) for which the extension event occurred.
243 * The device type (result):
244 *
245 * WPAD_DEV_UNKNOWN means that something has been attached, but
246 * it's being initialized, and we won't know what it is until
247 * initialization is complete.
248 *
249 * WPAD_DEV_CORE means that an extension has been removed and
250 * we're back to just the core device.
251 *
252 * WPAD_DEV_FREESTYLE means that the "NUNCHAK" extension has
253 * been attached and initialized.
254 *
255 * WPAD_DEV_CLASSIC means that the "CLASSIC" extension has been
256 * attached and initialized.
257 *
258 * Returns : None.
259 *---------------------------------------------------------------------------*/
extensionCallback(s32 chan,s32 result)260 static void extensionCallback(s32 chan, s32 result)
261 {
262 switch(result)
263 {
264 case WPAD_DEV_UNKNOWN:
265 OSReport("Initializing extension on channel%d...\n", chan);
266 break;
267
268 case WPAD_DEV_CORE:
269 WPADControlDpd(chan, WPAD_DPD_EXP, NULL);
270 WPADSetDataFormat(chan, WPAD_FMT_CORE_ACC_DPD);
271
272 OSReport("Extension removed on channel%d.\n", chan);
273 break;
274
275 case WPAD_DEV_NOT_SUPPORTED:
276 case WPAD_DEV_FUTURE:
277 WPADControlDpd(chan, WPAD_DPD_EXP, NULL);
278 WPADSetDataFormat(chan, WPAD_FMT_CORE_ACC_DPD);
279
280 OSReport("Extension is not useful on channel%d.\n", chan);
281 break;
282
283 case WPAD_DEV_FREESTYLE:
284 WPADControlDpd(chan, WPAD_DPD_STD, NULL);
285 WPADSetDataFormat(chan, WPAD_FMT_FREESTYLE_ACC_DPD);
286
287 OSReport("Freestyle initialized on channel%d.\n", chan);
288 break;
289
290 case WPAD_DEV_CLASSIC:
291 WPADControlDpd(chan, WPAD_DPD_STD, NULL);
292 WPADSetDataFormat(chan, WPAD_FMT_CLASSIC_ACC_DPD);
293
294 OSReport("Classicstyle initialized on channel%d.\n", chan);
295 break;
296
297 case WPAD_DEV_BALANCE_CHECKER:
298 WPADControlDpd(chan, WPAD_DPD_OFF, NULL);
299 WPADSetDataFormat(chan, WPAD_FMT_BALANCE_CHECKER);
300 WPADControlBLC(chan, WPAD_BLCMD_ON, NULL);
301
302 OSReport("Balance Wii board initialized on channel%d.\n", chan);
303 break;
304
305 default:
306 // Here is WPAD_DEV_NOT_FOUND.
307 // If the controller is disconnected while the extension is initializing
308 // it reaches here. There is nothing to do.
309 break;
310
311 } // end
312 } // end extensionCallback()
313
314 /*---------------------------------------------------------------------------*
315 * Name : myAlloc()
316 * Description : Callback needed by WPAD to allocate mem from MEM2 heap
317 * Arguments : size of block, in bytes.
318 * Returns : pointer to allocated block.
319 *---------------------------------------------------------------------------*/
myAlloc(u32 size)320 static void *myAlloc(u32 size)
321 {
322 void *ptr;
323
324 ptr = MEMAllocFromAllocator(&DemoAllocator2, size);
325 ASSERTMSG(ptr, "Memory allocation failed\n");
326
327 return(ptr);
328
329 } // myAlloc()
330
331 /*---------------------------------------------------------------------------*
332 * Name : myFree()
333 * Description : Callback needed by WPAD to free mem from MEM2 heap
334 * Arguments : None.
335 * Returns : Always 1.
336 *---------------------------------------------------------------------------*/
myFree(void * ptr)337 static u8 myFree(void *ptr)
338 {
339
340 MEMFreeToAllocator(&DemoAllocator2, ptr);
341
342 // we should ensure that memory is free'd properly, but oh well
343 return(1);
344
345 } // myFree()
346