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