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