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