Simon Ford / Mbed 2 deprecated WiiRacing

Dependencies:   mbed m3pi ID12RFIDIRQ

Committer:
simon
Date:
Mon Apr 11 23:03:22 2011 +0000
Revision:
0:e2ef12467862

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
simon 0:e2ef12467862 1 /*
simon 0:e2ef12467862 2 Copyright (c) 2010 Peter Barrett
simon 0:e2ef12467862 3
simon 0:e2ef12467862 4 Permission is hereby granted, free of charge, to any person obtaining a copy
simon 0:e2ef12467862 5 of this software and associated documentation files (the "Software"), to deal
simon 0:e2ef12467862 6 in the Software without restriction, including without limitation the rights
simon 0:e2ef12467862 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
simon 0:e2ef12467862 8 copies of the Software, and to permit persons to whom the Software is
simon 0:e2ef12467862 9 furnished to do so, subject to the following conditions:
simon 0:e2ef12467862 10
simon 0:e2ef12467862 11 The above copyright notice and this permission notice shall be included in
simon 0:e2ef12467862 12 all copies or substantial portions of the Software.
simon 0:e2ef12467862 13
simon 0:e2ef12467862 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
simon 0:e2ef12467862 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
simon 0:e2ef12467862 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
simon 0:e2ef12467862 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
simon 0:e2ef12467862 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
simon 0:e2ef12467862 19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
simon 0:e2ef12467862 20 THE SOFTWARE.
simon 0:e2ef12467862 21 */
simon 0:e2ef12467862 22
simon 0:e2ef12467862 23 #include "mbed.h"
simon 0:e2ef12467862 24 #include "USBHost.h"
simon 0:e2ef12467862 25 #include "Utils.h"
simon 0:e2ef12467862 26
simon 0:e2ef12467862 27 #include <stdio.h>
simon 0:e2ef12467862 28 #include <stdlib.h>
simon 0:e2ef12467862 29 #include <stdio.h>
simon 0:e2ef12467862 30 #include <string.h>
simon 0:e2ef12467862 31
simon 0:e2ef12467862 32 #include "Utils.h"
simon 0:e2ef12467862 33 #include "USBHost.h"
simon 0:e2ef12467862 34 #include "hci.h"
simon 0:e2ef12467862 35
simon 0:e2ef12467862 36 extern void wii_data(char *data);
simon 0:e2ef12467862 37
simon 0:e2ef12467862 38 void printf(const BD_ADDR* addr) {
simon 0:e2ef12467862 39 const u8* a = addr->addr;
simon 0:e2ef12467862 40 printf("%02X:%02X:%02X:%02X:%02X:%02X",a[5],a[4],a[3],a[2],a[1],a[0]);
simon 0:e2ef12467862 41 }
simon 0:e2ef12467862 42
simon 0:e2ef12467862 43 #define MAX_HCL_SIZE 260
simon 0:e2ef12467862 44 #define MAX_ACL_SIZE 400
simon 0:e2ef12467862 45
simon 0:e2ef12467862 46 class HCITransportUSB : public HCITransport {
simon 0:e2ef12467862 47 int _device;
simon 0:e2ef12467862 48 u8* _hciBuffer;
simon 0:e2ef12467862 49 u8* _aclBuffer;
simon 0:e2ef12467862 50
simon 0:e2ef12467862 51 public:
simon 0:e2ef12467862 52 void Open(int device, u8* hciBuffer, u8* aclBuffer) {
simon 0:e2ef12467862 53 _device = device;
simon 0:e2ef12467862 54 _hciBuffer = hciBuffer;
simon 0:e2ef12467862 55 _aclBuffer = aclBuffer;
simon 0:e2ef12467862 56 USBInterruptTransfer(_device,0x81,_hciBuffer,MAX_HCL_SIZE,HciCallback,this);
simon 0:e2ef12467862 57 USBBulkTransfer(_device,0x82,_aclBuffer,MAX_ACL_SIZE,AclCallback,this);
simon 0:e2ef12467862 58 }
simon 0:e2ef12467862 59
simon 0:e2ef12467862 60 static void HciCallback(int device, int endpoint, int status, u8* data, int len, void* userData) {
simon 0:e2ef12467862 61 HCI* t = ((HCITransportUSB*)userData)->_target;
simon 0:e2ef12467862 62 if (t)
simon 0:e2ef12467862 63 t->HCIRecv(data,len);
simon 0:e2ef12467862 64 USBInterruptTransfer(device,0x81,data,MAX_HCL_SIZE,HciCallback,userData);
simon 0:e2ef12467862 65 }
simon 0:e2ef12467862 66
simon 0:e2ef12467862 67 static void AclCallback(int device, int endpoint, int status, u8* data, int len, void* userData) {
simon 0:e2ef12467862 68 HCI* t = ((HCITransportUSB*)userData)->_target;
simon 0:e2ef12467862 69 if (t)
simon 0:e2ef12467862 70 t->ACLRecv(data,len);
simon 0:e2ef12467862 71 USBBulkTransfer(device,0x82,data,MAX_ACL_SIZE,AclCallback,userData);
simon 0:e2ef12467862 72 }
simon 0:e2ef12467862 73
simon 0:e2ef12467862 74 virtual void HCISend(const u8* data, int len) {
simon 0:e2ef12467862 75 USBControlTransfer(_device,REQUEST_TYPE_CLASS, 0, 0, 0,(u8*)data,len);
simon 0:e2ef12467862 76 }
simon 0:e2ef12467862 77
simon 0:e2ef12467862 78 virtual void ACLSend(const u8* data, int len) {
simon 0:e2ef12467862 79 USBBulkTransfer(_device,0x02,(u8*)data,len);
simon 0:e2ef12467862 80 }
simon 0:e2ef12467862 81 };
simon 0:e2ef12467862 82
simon 0:e2ef12467862 83
simon 0:e2ef12467862 84 #define WII_REMOTE 0x042500
simon 0:e2ef12467862 85
simon 0:e2ef12467862 86 class HIDBluetooth {
simon 0:e2ef12467862 87 int _control; // Sockets for control (out) and interrupt (in)
simon 0:e2ef12467862 88 int _interrupt;
simon 0:e2ef12467862 89 int _devClass;
simon 0:e2ef12467862 90 BD_ADDR _addr;
simon 0:e2ef12467862 91 u8 _pad[2]; // Struct align
simon 0:e2ef12467862 92
simon 0:e2ef12467862 93 public:
simon 0:e2ef12467862 94 HIDBluetooth() : _control(0),_interrupt(0),_devClass(0) {};
simon 0:e2ef12467862 95
simon 0:e2ef12467862 96 bool InUse() {
simon 0:e2ef12467862 97 return _control != 0;
simon 0:e2ef12467862 98 }
simon 0:e2ef12467862 99
simon 0:e2ef12467862 100 static void OnHidInterrupt(int socket, SocketState state, const u8* data, int len, void* userData) {
simon 0:e2ef12467862 101 HIDBluetooth* t = (HIDBluetooth*)userData;
simon 0:e2ef12467862 102 if (data) {
simon 0:e2ef12467862 103 if (t->_devClass == WII_REMOTE && data[1] == 0x30) {
simon 0:e2ef12467862 104 //printf("================wii====================\n");
simon 0:e2ef12467862 105 t->Led();
simon 0:e2ef12467862 106 t->Hid(); // ask for accelerometer
simon 0:e2ef12467862 107 t->_devClass = 0;
simon 0:e2ef12467862 108 }
simon 0:e2ef12467862 109
simon 0:e2ef12467862 110 const u8* d = data;
simon 0:e2ef12467862 111 switch (d[1]) {
simon 0:e2ef12467862 112
simon 0:e2ef12467862 113 case 0x02: {
simon 0:e2ef12467862 114 int x = (signed char)d[3];
simon 0:e2ef12467862 115 int y = (signed char)d[4];
simon 0:e2ef12467862 116 printf("Mouse %2X dx:%d dy:%d\n",d[2],x,y);
simon 0:e2ef12467862 117 }
simon 0:e2ef12467862 118 break;
simon 0:e2ef12467862 119
simon 0:e2ef12467862 120 case 0x37: {
simon 0:e2ef12467862 121 wii_data((char*)&d[2]);
simon 0:e2ef12467862 122 /*
simon 0:e2ef12467862 123 char *dd = (char*)&d[2];
simon 0:e2ef12467862 124
simon 0:e2ef12467862 125 Wiimote wii;
simon 0:e2ef12467862 126 wii.decode(dd);
simon 0:e2ef12467862 127 wii.dump();
simon 0:e2ef12467862 128
simon 0:e2ef12467862 129 float dir = 0;
simon 0:e2ef12467862 130 if(wii.one) {
simon 0:e2ef12467862 131 dir = -1;
simon 0:e2ef12467862 132 }
simon 0:e2ef12467862 133 if(wii.two) {
simon 0:e2ef12467862 134 dir = 1;
simon 0:e2ef12467862 135 }
simon 0:e2ef12467862 136
simon 0:e2ef12467862 137 if (dir != 0) {
simon 0:e2ef12467862 138 float f = wii.wheel / 200.0f;
simon 0:e2ef12467862 139
simon 0:e2ef12467862 140 if(f < 0) {
simon 0:e2ef12467862 141 m3pi.left_motor(dir * (0.6 + abs(f)));
simon 0:e2ef12467862 142 m3pi.right_motor(dir * (0.6 - (abs(f) / 2)));
simon 0:e2ef12467862 143 } else {
simon 0:e2ef12467862 144 m3pi.right_motor(dir * (0.6 + abs(f)));
simon 0:e2ef12467862 145 m3pi.left_motor(dir * (0.6 - (abs(f) / 2)));
simon 0:e2ef12467862 146 }
simon 0:e2ef12467862 147 } else {
simon 0:e2ef12467862 148 m3pi.left_motor(0);
simon 0:e2ef12467862 149 m3pi.right_motor(0);
simon 0:e2ef12467862 150 }
simon 0:e2ef12467862 151
simon 0:e2ef12467862 152 */
simon 0:e2ef12467862 153 }
simon 0:e2ef12467862 154 }
simon 0:e2ef12467862 155 }
simon 0:e2ef12467862 156 }
simon 0:e2ef12467862 157
simon 0:e2ef12467862 158 static void OnHidControl(int socket, SocketState state, const u8* data, int len, void* userData) {
simon 0:e2ef12467862 159 printf("OnHidControl\n");
simon 0:e2ef12467862 160 if (data)
simon 0:e2ef12467862 161 printHex(data,len);
simon 0:e2ef12467862 162 }
simon 0:e2ef12467862 163
simon 0:e2ef12467862 164 void Open(BD_ADDR* bdAddr, inquiry_info* info) {
simon 0:e2ef12467862 165 printf("L2CAPAddr size %d\n",sizeof(L2CAPAddr));
simon 0:e2ef12467862 166 _addr = *bdAddr;
simon 0:e2ef12467862 167 L2CAPAddr sockAddr;
simon 0:e2ef12467862 168 sockAddr.bdaddr = _addr;
simon 0:e2ef12467862 169 sockAddr.psm = L2CAP_PSM_HID_INTR;
simon 0:e2ef12467862 170 printf("Socket_Open size %d\n",sizeof(L2CAPAddr));
simon 0:e2ef12467862 171 _interrupt = Socket_Open(SOCKET_L2CAP,&sockAddr.hdr,OnHidInterrupt,this);
simon 0:e2ef12467862 172 sockAddr.psm = L2CAP_PSM_HID_CNTL;
simon 0:e2ef12467862 173 _control = Socket_Open(SOCKET_L2CAP,&sockAddr.hdr,OnHidControl,this);
simon 0:e2ef12467862 174
simon 0:e2ef12467862 175 printfBytes("OPEN DEVICE CLASS",info->dev_class,3);
simon 0:e2ef12467862 176 _devClass = (info->dev_class[0] << 16) | (info->dev_class[1] << 8) | info->dev_class[2];
simon 0:e2ef12467862 177 }
simon 0:e2ef12467862 178
simon 0:e2ef12467862 179 void Close() {
simon 0:e2ef12467862 180 if (_control)
simon 0:e2ef12467862 181 Socket_Close(_control);
simon 0:e2ef12467862 182 if (_interrupt)
simon 0:e2ef12467862 183 Socket_Close(_interrupt);
simon 0:e2ef12467862 184 _control = _interrupt = 0;
simon 0:e2ef12467862 185 }
simon 0:e2ef12467862 186
simon 0:e2ef12467862 187 void Led(int id = 0x10) {
simon 0:e2ef12467862 188 u8 led[3] = {0x52, 0x11, id};
simon 0:e2ef12467862 189 if (_control)
simon 0:e2ef12467862 190 Socket_Send(_control,led,3);
simon 0:e2ef12467862 191 }
simon 0:e2ef12467862 192
simon 0:e2ef12467862 193 void Hid(int report = 0x37) {
simon 0:e2ef12467862 194 u8 hid[4] = { 0x52, 0x12, 0x00, report };
simon 0:e2ef12467862 195 if (_control != -1)
simon 0:e2ef12467862 196 Socket_Send(_control,hid,4);
simon 0:e2ef12467862 197 }
simon 0:e2ef12467862 198 };
simon 0:e2ef12467862 199
simon 0:e2ef12467862 200
simon 0:e2ef12467862 201 HCI* gHCI = 0;
simon 0:e2ef12467862 202
simon 0:e2ef12467862 203 #define MAX_HID_DEVICES 8
simon 0:e2ef12467862 204
simon 0:e2ef12467862 205 class ShellApp {
simon 0:e2ef12467862 206 char _line[64];
simon 0:e2ef12467862 207 HIDBluetooth _hids[MAX_HID_DEVICES];
simon 0:e2ef12467862 208
simon 0:e2ef12467862 209 public:
simon 0:e2ef12467862 210 void Ready() {
simon 0:e2ef12467862 211 printf("HIDBluetooth %d\n",sizeof(HIDBluetooth));
simon 0:e2ef12467862 212 memset(_hids,0,sizeof(_hids));
simon 0:e2ef12467862 213 Inquiry();
simon 0:e2ef12467862 214
simon 0:e2ef12467862 215 }
simon 0:e2ef12467862 216
simon 0:e2ef12467862 217 // We have connected to a device
simon 0:e2ef12467862 218 void ConnectionComplete(HCI* hci, connection_info* info) {
simon 0:e2ef12467862 219 printf("ConnectionComplete ");
simon 0:e2ef12467862 220 BD_ADDR* a = &info->bdaddr;
simon 0:e2ef12467862 221 //printf(a);
simon 0:e2ef12467862 222 BTDevice* bt = hci->Find(a);
simon 0:e2ef12467862 223 HIDBluetooth* hid = NewHIDBluetooth();
simon 0:e2ef12467862 224 printf("%08x %08x\n",bt,hid);
simon 0:e2ef12467862 225 if (hid)
simon 0:e2ef12467862 226 hid->Open(a,&bt->_info);
simon 0:e2ef12467862 227 }
simon 0:e2ef12467862 228
simon 0:e2ef12467862 229 HIDBluetooth* NewHIDBluetooth() {
simon 0:e2ef12467862 230 for (int i = 0; i < MAX_HID_DEVICES; i++)
simon 0:e2ef12467862 231 if (!_hids[i].InUse())
simon 0:e2ef12467862 232 return _hids+i;
simon 0:e2ef12467862 233 return 0;
simon 0:e2ef12467862 234 }
simon 0:e2ef12467862 235
simon 0:e2ef12467862 236 void ConnectDevices() {
simon 0:e2ef12467862 237 BTDevice* devs[8];
simon 0:e2ef12467862 238 int count = gHCI->GetDevices(devs,8);
simon 0:e2ef12467862 239 for (int i = 0; i < count; i++) {
simon 0:e2ef12467862 240 printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3);
simon 0:e2ef12467862 241 if (devs[i]->_handle == 0) {
simon 0:e2ef12467862 242 BD_ADDR* bd = &devs[i]->_info.bdaddr;
simon 0:e2ef12467862 243 printf("Connecting to ");
simon 0:e2ef12467862 244 //printf(bd);
simon 0:e2ef12467862 245 printf("\n");
simon 0:e2ef12467862 246 gHCI->CreateConnection(bd);
simon 0:e2ef12467862 247 }
simon 0:e2ef12467862 248 }
simon 0:e2ef12467862 249 }
simon 0:e2ef12467862 250 /*
simon 0:e2ef12467862 251 const char* ReadLine() {
simon 0:e2ef12467862 252 int i;
simon 0:e2ef12467862 253 for (i = 0; i < 255; ) {
simon 0:e2ef12467862 254 USBLoop();
simon 0:e2ef12467862 255 int c = GetConsoleChar();
simon 0:e2ef12467862 256 if (c == -1)
simon 0:e2ef12467862 257 continue;
simon 0:e2ef12467862 258 if (c == '\n' || c == 13)
simon 0:e2ef12467862 259 break;
simon 0:e2ef12467862 260 _line[i++] = c;
simon 0:e2ef12467862 261 }
simon 0:e2ef12467862 262 _line[i] = 0;
simon 0:e2ef12467862 263 return _line;
simon 0:e2ef12467862 264 }
simon 0:e2ef12467862 265 */
simon 0:e2ef12467862 266 void Inquiry() {
simon 0:e2ef12467862 267 printf("Inquiry..\n");
simon 0:e2ef12467862 268 gHCI->Inquiry();
simon 0:e2ef12467862 269 }
simon 0:e2ef12467862 270
simon 0:e2ef12467862 271 void List() {
simon 0:e2ef12467862 272 #if 0
simon 0:e2ef12467862 273 printf("%d devices\n",_deviceCount);
simon 0:e2ef12467862 274 for (int i = 0; i < _deviceCount; i++) {
simon 0:e2ef12467862 275 printf(&_devices[i].info.bdaddr);
simon 0:e2ef12467862 276 printf("\n");
simon 0:e2ef12467862 277 }
simon 0:e2ef12467862 278 #endif
simon 0:e2ef12467862 279 }
simon 0:e2ef12467862 280
simon 0:e2ef12467862 281 void Connect() {
simon 0:e2ef12467862 282 ConnectDevices();
simon 0:e2ef12467862 283 }
simon 0:e2ef12467862 284
simon 0:e2ef12467862 285 void Disconnect() {
simon 0:e2ef12467862 286 gHCI->DisconnectAll();
simon 0:e2ef12467862 287 }
simon 0:e2ef12467862 288
simon 0:e2ef12467862 289 void CloseMouse() {
simon 0:e2ef12467862 290 }
simon 0:e2ef12467862 291
simon 0:e2ef12467862 292 void Quit() {
simon 0:e2ef12467862 293 CloseMouse();
simon 0:e2ef12467862 294 }
simon 0:e2ef12467862 295
simon 0:e2ef12467862 296 };
simon 0:e2ef12467862 297
simon 0:e2ef12467862 298 // Instance
simon 0:e2ef12467862 299 ShellApp gApp;
simon 0:e2ef12467862 300
simon 0:e2ef12467862 301 static int HciCallback(HCI* hci, HCI_CALLBACK_EVENT evt, const u8* data, int len) {
simon 0:e2ef12467862 302 switch (evt) {
simon 0:e2ef12467862 303 case CALLBACK_READY:
simon 0:e2ef12467862 304 printf("CALLBACK_READY\n");
simon 0:e2ef12467862 305 gApp.Ready();
simon 0:e2ef12467862 306 break;
simon 0:e2ef12467862 307
simon 0:e2ef12467862 308 case CALLBACK_INQUIRY_RESULT:
simon 0:e2ef12467862 309 printf("CALLBACK_INQUIRY_RESULT ");
simon 0:e2ef12467862 310 //printf((BD_ADDR*)data);
simon 0:e2ef12467862 311 printf("\n");
simon 0:e2ef12467862 312 break;
simon 0:e2ef12467862 313
simon 0:e2ef12467862 314 case CALLBACK_INQUIRY_DONE:
simon 0:e2ef12467862 315 printf("CALLBACK_INQUIRY_DONE\n");
simon 0:e2ef12467862 316 gApp.ConnectDevices();
simon 0:e2ef12467862 317 break;
simon 0:e2ef12467862 318
simon 0:e2ef12467862 319 case CALLBACK_REMOTE_NAME: {
simon 0:e2ef12467862 320 BD_ADDR* addr = (BD_ADDR*)data;
simon 0:e2ef12467862 321 const char* name = (const char*)(data + 6);
simon 0:e2ef12467862 322 //printf(addr);
simon 0:e2ef12467862 323 printf(" % s\n",name);
simon 0:e2ef12467862 324 }
simon 0:e2ef12467862 325 break;
simon 0:e2ef12467862 326
simon 0:e2ef12467862 327 case CALLBACK_CONNECTION_COMPLETE:
simon 0:e2ef12467862 328 gApp.ConnectionComplete(hci,(connection_info*)data);
simon 0:e2ef12467862 329 break;
simon 0:e2ef12467862 330 };
simon 0:e2ef12467862 331 return 0;
simon 0:e2ef12467862 332 }
simon 0:e2ef12467862 333
simon 0:e2ef12467862 334 // these should be placed in the DMA SRAM
simon 0:e2ef12467862 335 typedef struct {
simon 0:e2ef12467862 336 u8 _hciBuffer[MAX_HCL_SIZE];
simon 0:e2ef12467862 337 u8 _aclBuffer[MAX_ACL_SIZE];
simon 0:e2ef12467862 338 } SRAMPlacement;
simon 0:e2ef12467862 339
simon 0:e2ef12467862 340 HCITransportUSB _HCITransportUSB;
simon 0:e2ef12467862 341 HCI _HCI;
simon 0:e2ef12467862 342
simon 0:e2ef12467862 343 u8* USBGetBuffer(u32* len);
simon 0:e2ef12467862 344 int OnBluetoothInsert(int device) {
simon 0:e2ef12467862 345 printf("Bluetooth inserted of %d\n",device);
simon 0:e2ef12467862 346 u32 sramLen;
simon 0:e2ef12467862 347 u8* sram = USBGetBuffer(&sramLen);
simon 0:e2ef12467862 348 sram = (u8*)(((u32)sram + 1023) & ~1023);
simon 0:e2ef12467862 349 SRAMPlacement* s = (SRAMPlacement*)sram;
simon 0:e2ef12467862 350 _HCITransportUSB.Open(device,s->_hciBuffer,s->_aclBuffer);
simon 0:e2ef12467862 351 _HCI.Open(&_HCITransportUSB,HciCallback);
simon 0:e2ef12467862 352 RegisterSocketHandler(SOCKET_L2CAP,&_HCI);
simon 0:e2ef12467862 353 gHCI = &_HCI;
simon 0:e2ef12467862 354 gApp.Inquiry();
simon 0:e2ef12467862 355 return 0;
simon 0:e2ef12467862 356 }
simon 0:e2ef12467862 357