BlueUSB and Waveplayer merged

Dependencies:   SDFileSystem mbed-rtos mbed wave_player

Fork of z_test_BlueUSBv1 by Stuart Kent

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TestShell.cpp Source File

TestShell.cpp

00001 
00002 /*
00003 Copyright (c) 2010 Peter Barrett
00004 
00005 Permission is hereby granted, free of charge, to any person obtaining a copy
00006 of this software and associated documentation files (the "Software"), to deal
00007 in the Software without restriction, including without limitation the rights
00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00009 copies of the Software, and to permit persons to whom the Software is
00010 furnished to do so, subject to the following conditions:
00011 
00012 The above copyright notice and this permission notice shall be included in
00013 all copies or substantial portions of the Software.
00014 
00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00021 THE SOFTWARE.
00022 */
00023 
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <stdio.h>
00027 #include <string.h>
00028 #include <math.h>
00029 
00030 #include "Utils.h"
00031 #include "USBHost.h"
00032 #include "hci.h"
00033 #include "mbed.h"
00034 #include "rtos.h"
00035 
00036 DigitalOut  led1(LED1);
00037 DigitalOut  led2(LED2);
00038 DigitalOut  led3(LED3);
00039 DigitalOut  led4(LED4);
00040 
00041 
00042 #include "shared.h"
00043 /*
00044 typedef enum { //MAKE STATE VALUES
00045 Left,
00046 Right,
00047 Up,
00048 Down,
00049 Nothing
00050 } Wiistate;
00051 
00052 Wiistate wiistate = Nothing;
00053 
00054 float vol = 0; //VOLUME FLOAT
00055 
00056 Mutex key;
00057 */
00058 
00059 void printf(const BD_ADDR* addr)
00060 {
00061     const u8* a = addr->addr;
00062     printf("%02X:%02X:%02X:%02X:%02X:%02X",a[5],a[4],a[3],a[2],a[1],a[0]);
00063 }
00064 
00065 #define MAX_HCL_SIZE 260
00066 #define MAX_ACL_SIZE 400
00067 
00068 class HCITransportUSB : public HCITransport
00069 {
00070     int _device;
00071     u8* _hciBuffer;
00072     u8* _aclBuffer;
00073 
00074     public:
00075     void Open(int device, u8* hciBuffer, u8* aclBuffer)
00076     {
00077         _device = device;
00078         _hciBuffer = hciBuffer;
00079         _aclBuffer = aclBuffer;
00080         USBInterruptTransfer(_device,0x81,_hciBuffer,MAX_HCL_SIZE,HciCallback,this);
00081         USBBulkTransfer(_device,0x82,_aclBuffer,MAX_ACL_SIZE,AclCallback,this);
00082     }
00083 
00084     static void HciCallback(int device, int endpoint, int status, u8* data, int len, void* userData)
00085     {
00086         HCI* t = ((HCITransportUSB*)userData)->_target;
00087         if (t)
00088             t->HCIRecv(data,len);
00089         USBInterruptTransfer(device,0x81,data,MAX_HCL_SIZE,HciCallback,userData);
00090     }
00091 
00092     static void AclCallback(int device, int endpoint, int status, u8* data, int len, void* userData)
00093     {
00094         HCI* t = ((HCITransportUSB*)userData)->_target;
00095         if (t)
00096             t->ACLRecv(data,len);
00097         USBBulkTransfer(device,0x82,data,MAX_ACL_SIZE,AclCallback,userData);
00098     }
00099 
00100     virtual void HCISend(const u8* data, int len)
00101     {
00102         USBControlTransfer(_device,REQUEST_TYPE_CLASS, 0, 0, 0,(u8*)data,len);
00103     }
00104 
00105     virtual void ACLSend(const u8* data, int len)
00106     {
00107         USBBulkTransfer(_device,0x02,(u8*)data,len);
00108     }
00109 };
00110 
00111 
00112 #define WII_REMOTE 0x042500
00113 
00114 class HIDBluetooth
00115 {
00116     int _control;   // Sockets for control (out) and interrupt (in)
00117     int _interrupt;
00118     int _devClass;
00119     BD_ADDR _addr;
00120     u8  _pad[2];    // Struct align
00121     
00122 public:
00123     HIDBluetooth() : _control(0),_interrupt(0),_devClass(0) {};
00124 
00125     bool InUse()
00126     {
00127         return _control != 0;
00128     }
00129 
00130     static void OnHidInterrupt(int socket, SocketState state, const u8* data, int len, void* userData)
00131     {
00132         HIDBluetooth* t = (HIDBluetooth*)userData;
00133         if (data)
00134         {
00135             if (t->_devClass == WII_REMOTE && data[1] == 0x30)
00136             {
00137                 printf("================wii====================\n");
00138                 t->Led();
00139                 t->Hid();   // ask for accelerometer
00140                 t->_devClass = 0;
00141             }
00142 
00143             const u8* d = data;
00144             switch (d[1])
00145             {
00146                 case 0x02:
00147                 {
00148                     int x = (signed char)d[3];
00149                     int y = (signed char)d[4];
00150                     printf("Mouse %2X dx:%d dy:%d\n",d[2],x,y);
00151                 }
00152                 break;
00153 
00154                 case 0x37: // Accelerometer http://wiki.wiimoteproject.com/Reports
00155                 {
00156                     int pad = (d[2] & 0x9F) | ((d[3] & 0x9F) << 8);
00157                     int x = (d[2] & 0x60) >> 5 | d[4] << 2;
00158                     int y = (d[3] & 0x20) >> 4 | d[5] << 2;
00159                     int z = (d[3] & 0x40) >> 5 | d[6] << 2;
00160                     //printf("WII2 %04X %d %d %d\n",pad,x,y,z);
00161                     int resolution= 24;                             //SENSITIVITY OF STATES
00162                     
00163                     key.lock();                                     //LOCK GLOBAL VAR CHANGES
00164                     
00165                     if(pad==0x0800){                                //CHECK FOR BUTTON A
00166                     vol= (x-420)-(x-420)%21;
00167                     vol= vol/210;
00168                     if(vol<0) vol=0;
00169                     printf("Volume= %f\n",vol);
00170                     }
00171                     else if(pad==0x0400){                           //OTHERWISE CHECK B
00172                     
00173                         if(x<416+resolution){                       //LEFT
00174                             wiistate=Left;
00175                             led1=1;
00176                             led2=0;
00177                             led3=0;
00178                             led4=0;
00179                         }
00180                         else if(x>630-resolution){                  //RIGHT
00181                             wiistate=Right;
00182                             led1=0;
00183                             led2=1;
00184                             led3=0;
00185                             led4=0;                            
00186                         }
00187                         else if(y<420+resolution){                  //UP
00188                             wiistate=Up;
00189                             led1=0;
00190                             led2=0;
00191                             led3=1;
00192                             led4=0;                            
00193                         }
00194                         else if(z>630-resolution){                  //DOWN
00195                             wiistate=Down;
00196                             led1=0;
00197                             led2=0;
00198                             led3=0;
00199                             led4=1;                            
00200                         }
00201                         else{                                       //NOTHING
00202                             wiistate=Nothing;
00203                             led1=0;
00204                             led2=0;
00205                             led3=0;
00206                             led4=0;                            
00207                         }
00208                     }
00209                                         
00210                     key.unlock();                                   //UNLOCK GLOBAL VAR CHANGES                    
00211                     
00212                 }
00213                 break;
00214                 default:
00215                     printHex(data,len);
00216             }
00217         }
00218     }
00219 
00220     static void OnHidControl(int socket, SocketState state, const u8* data, int len, void* userData)
00221     {
00222         printf("OnHidControl\n");
00223         if (data)
00224             printHex(data,len);
00225     }
00226 
00227     void Open(BD_ADDR* bdAddr, inquiry_info* info)
00228     {
00229         printf("L2CAPAddr size %d\n",sizeof(L2CAPAddr));
00230         _addr = *bdAddr;
00231         L2CAPAddr sockAddr;
00232         sockAddr.bdaddr = _addr;
00233         sockAddr.psm = L2CAP_PSM_HID_INTR;
00234                 printf("Socket_Open size %d\n",sizeof(L2CAPAddr));
00235         _interrupt = Socket_Open(SOCKET_L2CAP,&sockAddr.hdr,OnHidInterrupt,this);
00236         sockAddr.psm = L2CAP_PSM_HID_CNTL;
00237         _control = Socket_Open(SOCKET_L2CAP,&sockAddr.hdr,OnHidControl,this);
00238 
00239         printfBytes("OPEN DEVICE CLASS",info->dev_class,3);
00240         _devClass = (info->dev_class[0] << 16) | (info->dev_class[1] << 8) | info->dev_class[2];
00241     }
00242 
00243     void Close()
00244     {
00245         if (_control)
00246             Socket_Close(_control);
00247         if (_interrupt)
00248             Socket_Close(_interrupt);
00249        _control = _interrupt = 0;
00250     }
00251 
00252     void Led(int id = 0x10)
00253     {
00254         u8 led[3] = {0x52, 0x11, id};
00255         if (_control)
00256             Socket_Send(_control,led,3);
00257     }
00258 
00259     void Hid(int report = 0x37)
00260     {
00261         u8 hid[4] = { 0x52, 0x12, 0x00, report };
00262         if (_control != -1)
00263             Socket_Send(_control,hid,4);
00264     }
00265 };
00266 
00267 
00268 HCI* gHCI = 0;
00269 
00270 #define MAX_HID_DEVICES 8
00271 
00272 int GetConsoleChar();
00273 class ShellApp
00274 {
00275     char _line[64];
00276     HIDBluetooth    _hids[MAX_HID_DEVICES];
00277 
00278 public:
00279     void Ready()
00280     {
00281     printf("HIDBluetooth %d\n",sizeof(HIDBluetooth));
00282          memset(_hids,0,sizeof(_hids));
00283         Inquiry();
00284 
00285     }
00286 
00287     //  We have connected to a device
00288     void ConnectionComplete(HCI* hci, connection_info* info)
00289     {
00290     printf("ConnectionComplete ");
00291         BD_ADDR* a = &info->bdaddr;
00292         printf(a);
00293         BTDevice* bt = hci->Find(a);
00294         HIDBluetooth* hid = NewHIDBluetooth();
00295         printf("%08x %08x\n",bt,hid);
00296         if (hid)
00297             hid->Open(a,&bt->_info);
00298     }
00299 
00300     HIDBluetooth* NewHIDBluetooth()
00301     {
00302         for (int i = 0; i < MAX_HID_DEVICES; i++)
00303             if (!_hids[i].InUse())
00304                 return _hids+i;
00305         return 0;
00306     }
00307 
00308     void ConnectDevices()
00309     {
00310         BTDevice* devs[8];
00311         int count = gHCI->GetDevices(devs,8);
00312         for (int i = 0; i < count; i++)
00313         {
00314             printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3);
00315             if (devs[i]->_handle == 0)
00316             {
00317                 BD_ADDR* bd = &devs[i]->_info.bdaddr;
00318                 printf("Connecting to ");
00319                 printf(bd);
00320                 printf("\n");
00321                 gHCI->CreateConnection(bd);
00322             }
00323         }
00324     }
00325 
00326     const char* ReadLine()
00327     {
00328         int i;
00329         for (i = 0; i < 255; )
00330         {
00331             USBLoop();
00332             int c = GetConsoleChar();
00333             if (c == -1)
00334                 continue;
00335             if (c == '\n' || c == 13)
00336                 break;
00337             _line[i++] = c;
00338         }
00339         _line[i] = 0;
00340         return _line;
00341     }
00342 
00343     void Inquiry()
00344     {
00345         printf("Inquiry..\n");
00346         gHCI->Inquiry();
00347     }
00348 
00349     void List()
00350     {
00351         #if 0
00352         printf("%d devices\n",_deviceCount);
00353         for (int i = 0; i < _deviceCount; i++)
00354         {
00355             printf(&_devices[i].info.bdaddr);
00356             printf("\n");
00357         }
00358         #endif
00359     }
00360 
00361     void Connect()
00362     {
00363         ConnectDevices();
00364     }
00365 
00366     void Disconnect()
00367     {
00368         gHCI->DisconnectAll();
00369     }
00370 
00371     void CloseMouse()
00372     {
00373     }
00374 
00375     void Quit()
00376     {
00377         CloseMouse();
00378     }
00379 
00380     void Run()
00381     {
00382         for(;;)
00383         {
00384             const char* cmd = ReadLine();
00385             if (strcmp(cmd,"scan") == 0 || strcmp(cmd,"inquiry") == 0)
00386                 Inquiry();
00387             else if (strcmp(cmd,"ls") == 0)
00388                 List();
00389             else if (strcmp(cmd,"connect") == 0)
00390                 Connect();
00391             else if (strcmp(cmd,"disconnect") == 0)
00392                 Disconnect();
00393             else if (strcmp(cmd,"q")== 0)
00394             {
00395                 Quit();
00396                 break;
00397             } else {
00398                 printf("eh? %s\n",cmd);
00399             }
00400         }
00401     }
00402 };
00403 
00404 //  Instance
00405 ShellApp gApp;
00406 
00407 static int HciCallback(HCI* hci, HCI_CALLBACK_EVENT evt, const u8* data, int len)
00408 {
00409     switch (evt)
00410     {
00411         case CALLBACK_READY:
00412             printf("CALLBACK_READY\n");
00413             gApp.Ready();
00414             break;
00415 
00416         case CALLBACK_INQUIRY_RESULT:
00417             printf("CALLBACK_INQUIRY_RESULT ");
00418             printf((BD_ADDR*)data);
00419             printf("\n");
00420             break;
00421 
00422         case CALLBACK_INQUIRY_DONE:
00423             printf("CALLBACK_INQUIRY_DONE\n");
00424             gApp.ConnectDevices();
00425             break;
00426 
00427         case CALLBACK_REMOTE_NAME:
00428             {
00429                 BD_ADDR* addr = (BD_ADDR*)data;
00430                 const char* name = (const char*)(data + 6);
00431                 printf(addr);
00432                 printf(" % s\n",name);
00433             }
00434             break;
00435 
00436         case CALLBACK_CONNECTION_COMPLETE:
00437             gApp.ConnectionComplete(hci,(connection_info*)data);
00438             break;
00439     };
00440     return 0;
00441 }
00442 
00443 //  these should be placed in the DMA SRAM
00444 typedef struct
00445 {
00446     u8 _hciBuffer[MAX_HCL_SIZE];
00447     u8 _aclBuffer[MAX_ACL_SIZE];
00448 } SRAMPlacement;
00449 
00450 HCITransportUSB _HCITransportUSB;
00451 HCI _HCI;
00452 
00453 u8* USBGetBuffer(u32* len);
00454 int OnBluetoothInsert(int device)
00455 {
00456     printf("Bluetooth inserted of %d\n",device);
00457     u32 sramLen;
00458     u8* sram =  USBGetBuffer(&sramLen);
00459     sram = (u8*)(((u32)sram + 1023) & ~1023);
00460     SRAMPlacement* s = (SRAMPlacement*)sram;
00461     _HCITransportUSB.Open(device,s->_hciBuffer,s->_aclBuffer);
00462     _HCI.Open(&_HCITransportUSB,HciCallback);
00463     RegisterSocketHandler(SOCKET_L2CAP,&_HCI);
00464     gHCI = &_HCI;
00465     gApp.Inquiry();
00466     return 0;
00467 }
00468 
00469 void TestShell()
00470 {
00471     USBInit();
00472     gApp.Run();
00473 }