This is the project for the Old Model Robots for OU's Dr. Davis's Configurable Robots Research. This is being published so future robots can be set up easily.

Dependencies:   FatFileSystem MCP3008 Motor PinDetect QTR_8A SRF05 SSD1308_128x64_I2C mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BTRuntime.cpp Source File

BTRuntime.cpp

00001 /*
00002 Copyright (c) 2010 Peter Barrett
00003 
00004 Permission is hereby granted, free of charge, to any person obtaining a copy
00005 of this software and associated documentation files (the "Software"), to deal
00006 in the Software without restriction, including without limitation the rights
00007 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008 copies of the Software, and to permit persons to whom the Software is
00009 furnished to do so, subject to the following conditions:
00010 
00011 The above copyright notice and this permission notice shall be included in
00012 all copies or substantial portions of the Software.
00013 
00014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00020 THE SOFTWARE.
00021 */
00022 
00023 #include "mbed.h"
00024 #include "USBHost.h"
00025 #include "Utils.h"
00026 
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <stdio.h>
00030 #include <string.h>
00031 
00032 #include "Utils.h"
00033 #include "USBHost.h"
00034 #include "hci.h"
00035 
00036 extern void wii_data(char *data);
00037 
00038 extern void connected();
00039 
00040 extern void connect();
00041 
00042 extern void connecting();
00043 
00044 void printf(const BD_ADDR* addr)
00045 {
00046     const u8* a = addr->addr;
00047     printf("%02X:%02X:%02X:%02X:%02X:%02X",a[5],a[4],a[3],a[2],a[1],a[0]);
00048 }
00049 
00050 #define MAX_HCL_SIZE 260
00051 #define MAX_ACL_SIZE 400
00052 
00053 class HCITransportUSB : public HCITransport
00054 {
00055     int _device;
00056     u8* _hciBuffer;
00057     u8* _aclBuffer;
00058 
00059 public:
00060     void Open(int device, u8* hciBuffer, u8* aclBuffer) {
00061         _device = device;
00062         _hciBuffer = hciBuffer;
00063         _aclBuffer = aclBuffer;
00064         USBInterruptTransfer(_device,0x81,_hciBuffer,MAX_HCL_SIZE,HciCallback,this);
00065         USBBulkTransfer(_device,0x82,_aclBuffer,MAX_ACL_SIZE,AclCallback,this);
00066     }
00067 
00068     static void HciCallback(int device, int endpoint, int status, u8* data, int len, void* userData) {
00069         HCI* t = ((HCITransportUSB*)userData)->_target;
00070         if (t)
00071             t->HCIRecv(data,len);
00072         USBInterruptTransfer(device,0x81,data,MAX_HCL_SIZE,HciCallback,userData);
00073     }
00074 
00075     static void AclCallback(int device, int endpoint, int status, u8* data, int len, void* userData) {
00076         HCI* t = ((HCITransportUSB*)userData)->_target;
00077         if (t)
00078             t->ACLRecv(data,len);
00079         USBBulkTransfer(device,0x82,data,MAX_ACL_SIZE,AclCallback,userData);
00080     }
00081 
00082     virtual void HCISend(const u8* data, int len) {
00083         USBControlTransfer(_device,REQUEST_TYPE_CLASS, 0, 0, 0,(u8*)data,len);
00084     }
00085 
00086     virtual void ACLSend(const u8* data, int len) {
00087         USBBulkTransfer(_device,0x02,(u8*)data,len);
00088     }
00089 };
00090 
00091 
00092 #define WII_REMOTE 0x042500
00093 
00094 class HIDBluetooth
00095 {
00096     int _control;   // Sockets for control (out) and interrupt (in)
00097     int _interrupt;
00098     int _devClass;
00099     BD_ADDR _addr;
00100     u8  _pad[2];    // Struct align
00101 
00102 public:
00103     HIDBluetooth() : _control(0),_interrupt(0),_devClass(0) {};
00104 
00105     bool InUse() {
00106         return _control != 0;
00107     }
00108 
00109     static void OnHidInterrupt(int socket, SocketState state, const u8* data, int len, void* userData) {
00110         HIDBluetooth* t = (HIDBluetooth*)userData;
00111         if (data) {
00112             if (t->_devClass == WII_REMOTE && data[1] == 0x30) {
00113                 //printf("================wii====================\n");
00114                 t->Led();
00115                 t->Hid();   // ask for accelerometer
00116                 t->_devClass = 0;
00117             }
00118 
00119             const u8* d = data;
00120             switch (d[1]) {
00121 
00122                 case 0x02: {
00123                     int x = (signed char)d[3];
00124                     int y = (signed char)d[4];
00125                     printf("Mouse %2X dx:%d dy:%d\n",d[2],x,y);
00126                 }
00127                 break;
00128 
00129                 case 0x37: {
00130                     wii_data((char*)&d[2]);
00131                     /*
00132                                         char *dd = (char*)&d[2];
00133 
00134                                         Wiimote wii;
00135                                         wii.decode(dd);
00136                                         wii.dump();
00137 
00138                                         float dir = 0;
00139                                         if(wii.one) {
00140                                             dir = -1;
00141                                         }
00142                                         if(wii.two) {
00143                                             dir = 1;
00144                                            }
00145 
00146                                        if (dir != 0) {
00147                                              float f = wii.wheel / 200.0f;
00148 
00149                                             if(f < 0) {
00150                                                 m3pi.left_motor(dir * (0.6 + abs(f)));
00151                                                 m3pi.right_motor(dir * (0.6 - (abs(f) / 2)));
00152                                             } else {
00153                                                 m3pi.right_motor(dir * (0.6 + abs(f)));
00154                                                 m3pi.left_motor(dir * (0.6 - (abs(f) / 2)));
00155                                             }
00156                                         } else {
00157                                             m3pi.left_motor(0);
00158                                             m3pi.right_motor(0);
00159                                         }
00160 
00161                                         */
00162                 }
00163             }
00164         }
00165     }
00166 
00167     static void OnHidControl(int socket, SocketState state, const u8* data, int len, void* userData) {
00168         printf("OnHidControl\n");
00169         if (data) {
00170             printHex(data,len);
00171             connected();
00172         }
00173 
00174 
00175     }
00176 
00177     void Open(BD_ADDR* bdAddr, inquiry_info* info) {
00178         printf("L2CAPAddr size %d\n",sizeof(L2CAPAddr));
00179         _addr = *bdAddr;
00180         L2CAPAddr sockAddr;
00181         sockAddr.bdaddr = _addr;
00182         sockAddr.psm = L2CAP_PSM_HID_INTR;
00183         printf("Socket_Open size %d\n",sizeof(L2CAPAddr));
00184         _interrupt = Socket_Open(SOCKET_L2CAP,&sockAddr.hdr,OnHidInterrupt,this);
00185         sockAddr.psm = L2CAP_PSM_HID_CNTL;
00186         _control = Socket_Open(SOCKET_L2CAP,&sockAddr.hdr,OnHidControl,this);
00187 
00188         printfBytes("OPEN DEVICE CLASS",info->dev_class,3);
00189         _devClass = (info->dev_class[0] << 16) | (info->dev_class[1] << 8) | info->dev_class[2];
00190     }
00191 
00192     void Close() {
00193         if (_control)
00194             Socket_Close(_control);
00195         if (_interrupt)
00196             Socket_Close(_interrupt);
00197         _control = _interrupt = 0;
00198     }
00199 
00200     void Led(int id = 0x10) {
00201         u8 led[3] = {0x52, 0x11, id};
00202         if (_control)
00203             Socket_Send(_control,led,3);
00204     }
00205 
00206     void Hid(int report = 0x37) {
00207         u8 hid[4] = { 0x52, 0x12, 0x00, report };
00208         if (_control != -1)
00209             Socket_Send(_control,hid,4);
00210     }
00211 };
00212 
00213 
00214 HCI* gHCI = 0;
00215 
00216 #define MAX_HID_DEVICES 8
00217 
00218 class ShellApp
00219 {
00220     char _line[64];
00221     HIDBluetooth    _hids[MAX_HID_DEVICES];
00222 
00223 public:
00224     void Ready() {
00225         printf("HIDBluetooth %d\n",sizeof(HIDBluetooth));
00226         memset(_hids,0,sizeof(_hids));
00227         Inquiry();
00228 
00229     }
00230 
00231     //  We have connected to a device
00232     void ConnectionComplete(HCI* hci, connection_info* info) {
00233         printf("ConnectionComplete ");
00234         BD_ADDR* a = &info->bdaddr;
00235         //printf(a);
00236         BTDevice* bt = hci->Find(a);
00237         HIDBluetooth* hid = NewHIDBluetooth();
00238         printf("%08x %08x\n",bt,hid);
00239         if (hid)
00240             hid->Open(a,&bt->_info);
00241     }
00242 
00243     HIDBluetooth* NewHIDBluetooth() {
00244         for (int i = 0; i < MAX_HID_DEVICES; i++)
00245             if (!_hids[i].InUse())
00246                 return _hids+i;
00247         return 0;
00248     }
00249 
00250     void ConnectDevices() {
00251         BTDevice* devs[8];
00252         int count = gHCI->GetDevices(devs,8);
00253         for (int i = 0; i < count; i++) {
00254             printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3);
00255             if (devs[i]->_handle == 0) {
00256                 BD_ADDR* bd = &devs[i]->_info.bdaddr;
00257                 printf("Connecting to ");
00258                 //printf(bd);
00259                 printf("\n");
00260                 gHCI->CreateConnection(bd);
00261             }
00262         }
00263     }
00264     /*
00265         const char* ReadLine() {
00266             int i;
00267             for (i = 0; i < 255; ) {
00268                 USBLoop();
00269                 int c = GetConsoleChar();
00270                 if (c == -1)
00271                     continue;
00272                 if (c == '\n' || c == 13)
00273                     break;
00274                 _line[i++] = c;
00275             }
00276             _line[i] = 0;
00277             return _line;
00278         }
00279     */
00280     void Inquiry() {
00281         printf("Inquiry..\n");
00282         gHCI->Inquiry();
00283     }
00284 
00285     void List() {
00286 #if 0
00287         printf("%d devices\n",_deviceCount);
00288         for (int i = 0; i < _deviceCount; i++) {
00289             printf(&_devices[i].info.bdaddr);
00290             printf("\n");
00291         }
00292 #endif
00293     }
00294 
00295     void Connect() {
00296         ConnectDevices();
00297     }
00298 
00299     void Disconnect() {
00300         gHCI->DisconnectAll();
00301     }
00302 
00303     void CloseMouse() {
00304     }
00305 
00306     void Quit() {
00307         CloseMouse();
00308     }
00309 
00310 };
00311 
00312 //  Instance
00313 ShellApp gApp;
00314 
00315 static int HciCallback(HCI* hci, HCI_CALLBACK_EVENT evt, const u8* data, int len)
00316 {
00317     switch (evt) {
00318         case CALLBACK_READY:
00319             printf("CALLBACK_READY\n");
00320             connect();
00321             gApp.Ready();
00322             break;
00323 
00324         case CALLBACK_INQUIRY_RESULT:
00325             printf("CALLBACK_INQUIRY_RESULT ");
00326             //printf((BD_ADDR*)data);
00327             connecting();
00328             printf("\n");
00329             break;
00330 
00331         case CALLBACK_INQUIRY_DONE:
00332             printf("CALLBACK_INQUIRY_DONE\n");
00333             gApp.ConnectDevices();
00334             break;
00335 
00336         case CALLBACK_REMOTE_NAME: {
00337             BD_ADDR* addr = (BD_ADDR*)data;
00338             const char* name = (const char*)(data + 6);
00339             //printf(addr);
00340             printf(" % s\n",name);
00341         }
00342         break;
00343 
00344         case CALLBACK_CONNECTION_COMPLETE:
00345             gApp.ConnectionComplete(hci,(connection_info*)data);
00346             break;
00347     };
00348     return 0;
00349 }
00350 
00351 //  these should be placed in the DMA SRAM
00352 typedef struct {
00353     u8 _hciBuffer[MAX_HCL_SIZE];
00354     u8 _aclBuffer[MAX_ACL_SIZE];
00355 } SRAMPlacement;
00356 
00357 HCITransportUSB _HCITransportUSB;
00358 HCI _HCI;
00359 
00360 u8* USBGetBuffer(u32* len);
00361 int OnBluetoothInsert(int device)
00362 {
00363     printf("Bluetooth inserted of %d\n",device);
00364     u32 sramLen;
00365     u8* sram =  USBGetBuffer(&sramLen);
00366     sram = (u8*)(((u32)sram + 1023) & ~1023);
00367     SRAMPlacement* s = (SRAMPlacement*)sram;
00368     _HCITransportUSB.Open(device,s->_hciBuffer,s->_aclBuffer);
00369     _HCI.Open(&_HCITransportUSB,HciCallback);
00370     RegisterSocketHandler(SOCKET_L2CAP,&_HCI);
00371     gHCI = &_HCI;
00372     gApp.Inquiry();
00373     return 0;
00374 }
00375