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