Radio Junk Box / Mbed 2 deprecated KAMUI_USBHOST_MIDI-CV_Example

Dependencies:   TextLCD mbed

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 /* 
00025 May 11 2012 Modified by RadioJunkBox
00026 */
00027 
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <stdio.h>
00031 #include <string.h>
00032 
00033 #include "Utils.h"
00034 #include "USBHost.h"
00035 #include "hci.h"
00036 
00037 void printf(const BD_ADDR* addr)
00038 {
00039     const u8* a = addr->addr;
00040     printf("%02X:%02X:%02X:%02X:%02X:%02X",a[5],a[4],a[3],a[2],a[1],a[0]);
00041 }
00042 
00043 #define MAX_HCL_SIZE 260
00044 #define MAX_ACL_SIZE 400
00045 
00046 class HCITransportUSB : public HCITransport
00047 {
00048     int _device;
00049     u8* _hciBuffer;
00050     u8* _aclBuffer;
00051 
00052     public:
00053     void Open(int device, u8* hciBuffer, u8* aclBuffer)
00054     {
00055         _device = device;
00056         _hciBuffer = hciBuffer;
00057         _aclBuffer = aclBuffer;
00058         USBInterruptTransfer(_device,0x81,_hciBuffer,MAX_HCL_SIZE,HciCallback,this);
00059         USBBulkTransfer(_device,0x82,_aclBuffer,MAX_ACL_SIZE,AclCallback,this);
00060     }
00061 
00062     static void HciCallback(int device, int endpoint, int status, u8* data, int len, void* userData)
00063     {
00064         HCI* t = ((HCITransportUSB*)userData)->_target;
00065         if (t)
00066             t->HCIRecv(data,len);
00067         USBInterruptTransfer(device,0x81,data,MAX_HCL_SIZE,HciCallback,userData);
00068     }
00069 
00070     static void AclCallback(int device, int endpoint, int status, u8* data, int len, void* userData)
00071     {
00072         HCI* t = ((HCITransportUSB*)userData)->_target;
00073         if (t)
00074             t->ACLRecv(data,len);
00075         USBBulkTransfer(device,0x82,data,MAX_ACL_SIZE,AclCallback,userData);
00076     }
00077 
00078     virtual void HCISend(const u8* data, int len)
00079     {
00080         USBControlTransfer(_device,REQUEST_TYPE_CLASS, 0, 0, 0,(u8*)data,len);
00081     }
00082 
00083     virtual void ACLSend(const u8* data, int len)
00084     {
00085         USBBulkTransfer(_device,0x02,(u8*)data,len);
00086     }
00087 };
00088 
00089 
00090 #define WII_REMOTE 0x042500
00091 
00092 class HIDBluetooth
00093 {
00094     int _control;   // Sockets for control (out) and interrupt (in)
00095     int _interrupt;
00096     int _devClass;
00097     BD_ADDR _addr;
00098     u8  _pad[2];    // Struct align
00099     
00100 public:
00101     HIDBluetooth() : _control(0),_interrupt(0),_devClass(0) {};
00102 
00103     bool InUse()
00104     {
00105         return _control != 0;
00106     }
00107 
00108     static void OnHidInterrupt(int socket, SocketState state, const u8* data, int len, void* userData)
00109     {
00110         HIDBluetooth* t = (HIDBluetooth*)userData;
00111         if (data)
00112         {
00113             if (t->_devClass == WII_REMOTE && data[1] == 0x30)
00114             {
00115                 printf("================wii====================\n");
00116                 t->Led();
00117                 t->Hid();   // ask for accelerometer
00118                 t->_devClass = 0;
00119             }
00120 
00121             const u8* d = data;
00122             switch (d[1])
00123             {
00124                 case 0x02:
00125                 {
00126                     int x = (signed char)d[3];
00127                     int y = (signed char)d[4];
00128                     printf("Mouse %2X dx:%d dy:%d\n",d[2],x,y);
00129                 }
00130                 break;
00131 
00132                 case 0x37: // Accelerometer http://wiki.wiimoteproject.com/Reports
00133                 {
00134                     int pad = (d[2] & 0x9F) | ((d[3] & 0x9F) << 8);
00135                     int x = (d[2] & 0x60) >> 5 | d[4] << 2;
00136                     int y = (d[3] & 0x20) >> 4 | d[5] << 2;
00137                     int z = (d[3] & 0x40) >> 5 | d[6] << 2;
00138                     printf("WII %04X %d %d %d\n",pad,x,y,z);
00139                 }
00140                 break;
00141                 default:
00142                     printHex(data,len);
00143             }
00144         }
00145     }
00146 
00147     static void OnHidControl(int socket, SocketState state, const u8* data, int len, void* userData)
00148     {
00149         printf("OnHidControl\n");
00150         if (data)
00151             printHex(data,len);
00152     }
00153 
00154     void Open(BD_ADDR* bdAddr, inquiry_info* info)
00155     {
00156         printf("L2CAPAddr size %d\n",sizeof(L2CAPAddr));
00157         _addr = *bdAddr;
00158         L2CAPAddr sockAddr;
00159         sockAddr.bdaddr = _addr;
00160         sockAddr.psm = L2CAP_PSM_HID_INTR;
00161                 printf("Socket_Open size %d\n",sizeof(L2CAPAddr));
00162         _interrupt = Socket_Open(SOCKET_L2CAP,&sockAddr.hdr,OnHidInterrupt,this);
00163         sockAddr.psm = L2CAP_PSM_HID_CNTL;
00164         _control = Socket_Open(SOCKET_L2CAP,&sockAddr.hdr,OnHidControl,this);
00165 
00166         printfBytes("OPEN DEVICE CLASS",info->dev_class,3);
00167         _devClass = (info->dev_class[0] << 16) | (info->dev_class[1] << 8) | info->dev_class[2];
00168     }
00169 
00170     void Close()
00171     {
00172         if (_control)
00173             Socket_Close(_control);
00174         if (_interrupt)
00175             Socket_Close(_interrupt);
00176        _control = _interrupt = 0;
00177     }
00178 
00179     void Led(int id = 0x10)
00180     {
00181         u8 led[3] = {0x52, 0x11, id};
00182         if (_control)
00183             Socket_Send(_control,led,3);
00184     }
00185 
00186     void Hid(int report = 0x37)
00187     {
00188         u8 hid[4] = { 0x52, 0x12, 0x00, report };
00189         if (_control != -1)
00190             Socket_Send(_control,hid,4);
00191     }
00192 };
00193 
00194 
00195 HCI* gHCI = 0;
00196 
00197 #define MAX_HID_DEVICES 8
00198 
00199 int GetConsoleChar();
00200 class ShellApp
00201 {
00202     char _line[64];
00203     HIDBluetooth    _hids[MAX_HID_DEVICES];
00204 
00205 public:
00206     void Ready()
00207     {
00208     printf("HIDBluetooth %d\n",sizeof(HIDBluetooth));
00209          memset(_hids,0,sizeof(_hids));
00210         Inquiry();
00211 
00212     }
00213 
00214     //  We have connected to a device
00215     void ConnectionComplete(HCI* hci, connection_info* info)
00216     {
00217     printf("ConnectionComplete ");
00218         BD_ADDR* a = &info->bdaddr;
00219         printf(a);
00220         BTDevice* bt = hci->Find(a);
00221         HIDBluetooth* hid = NewHIDBluetooth();
00222         printf("%08x %08x\n",bt,hid);
00223         if (hid)
00224             hid->Open(a,&bt->_info);
00225     }
00226 
00227     HIDBluetooth* NewHIDBluetooth()
00228     {
00229         for (int i = 0; i < MAX_HID_DEVICES; i++)
00230             if (!_hids[i].InUse())
00231                 return _hids+i;
00232         return 0;
00233     }
00234 
00235     void ConnectDevices()
00236     {
00237         BTDevice* devs[8];
00238         int count = gHCI->GetDevices(devs,8);
00239         for (int i = 0; i < count; i++)
00240         {
00241             printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3);
00242             if (devs[i]->_handle == 0)
00243             {
00244                 BD_ADDR* bd = &devs[i]->_info.bdaddr;
00245                 printf("Connecting to ");
00246                 printf(bd);
00247                 printf("\n");
00248                 gHCI->CreateConnection(bd);
00249             }
00250         }
00251     }
00252 
00253     const char* ReadLine()
00254     {
00255         int i;
00256         for (i = 0; i < 255; )
00257         {
00258             USBLoop();
00259             int c = GetConsoleChar();
00260             if (c == -1)
00261                 continue;
00262             if (c == '\n' || c == 13)
00263                 break;
00264             _line[i++] = c;
00265         }
00266         _line[i] = 0;
00267         return _line;
00268     }
00269 
00270     void Inquiry()
00271     {
00272         printf("Inquiry..\n");
00273         gHCI->Inquiry();
00274     }
00275 
00276     void List()
00277     {
00278         #if 0
00279         printf("%d devices\n",_deviceCount);
00280         for (int i = 0; i < _deviceCount; i++)
00281         {
00282             printf(&_devices[i].info.bdaddr);
00283             printf("\n");
00284         }
00285         #endif
00286     }
00287 
00288     void Connect()
00289     {
00290         ConnectDevices();
00291     }
00292 
00293     void Disconnect()
00294     {
00295         gHCI->DisconnectAll();
00296     }
00297 
00298     void CloseMouse()
00299     {
00300     }
00301 
00302     void Quit()
00303     {
00304         CloseMouse();
00305     }
00306 
00307     void Run()
00308     {
00309         for(;;)
00310         {
00311             const char* cmd = ReadLine();
00312             if (strcmp(cmd,"scan") == 0 || strcmp(cmd,"inquiry") == 0)
00313                 Inquiry();
00314             else if (strcmp(cmd,"ls") == 0)
00315                 List();
00316             else if (strcmp(cmd,"connect") == 0)
00317                 Connect();
00318             else if (strcmp(cmd,"disconnect") == 0)
00319                 Disconnect();
00320             else if (strcmp(cmd,"q")== 0)
00321             {
00322                 Quit();
00323                 break;
00324             } else {
00325                 printf("eh? %s\n",cmd);
00326             }
00327         }
00328     }
00329 };
00330 
00331 //  Instance
00332 ShellApp gApp;
00333 
00334 static int HciCallback(HCI* hci, HCI_CALLBACK_EVENT evt, const u8* data, int len)
00335 {
00336     switch (evt)
00337     {
00338         case CALLBACK_READY:
00339             printf("CALLBACK_READY\n");
00340             gApp.Ready();
00341             break;
00342 
00343         case CALLBACK_INQUIRY_RESULT:
00344             printf("CALLBACK_INQUIRY_RESULT ");
00345             printf((BD_ADDR*)data);
00346             printf("\n");
00347             break;
00348 
00349         case CALLBACK_INQUIRY_DONE:
00350             printf("CALLBACK_INQUIRY_DONE\n");
00351             gApp.ConnectDevices();
00352             break;
00353 
00354         case CALLBACK_REMOTE_NAME:
00355             {
00356                 BD_ADDR* addr = (BD_ADDR*)data;
00357                 const char* name = (const char*)(data + 6);
00358                 printf(addr);
00359                 printf(" % s\n",name);
00360             }
00361             break;
00362 
00363         case CALLBACK_CONNECTION_COMPLETE:
00364             gApp.ConnectionComplete(hci,(connection_info*)data);
00365             break;
00366     };
00367     return 0;
00368 }
00369 
00370 //  these should be placed in the DMA SRAM
00371 typedef struct
00372 {
00373     u8 _hciBuffer[MAX_HCL_SIZE];
00374     u8 _aclBuffer[MAX_ACL_SIZE];
00375 } SRAMPlacement;
00376 
00377 HCITransportUSB _HCITransportUSB;
00378 HCI _HCI;
00379 
00380 u8* USBGetBuffer(u32* len);
00381 int OnBluetoothInsert(int device)
00382 {
00383     printf("Bluetooth inserted of %d\n",device);
00384     u32 sramLen;
00385     u8* sram =  USBGetBuffer(&sramLen);
00386     sram = (u8*)(((u32)sram + 1023) & ~1023);
00387     SRAMPlacement* s = (SRAMPlacement*)sram;
00388     _HCITransportUSB.Open(device,s->_hciBuffer,s->_aclBuffer);
00389     _HCI.Open(&_HCITransportUSB,HciCallback);
00390     RegisterSocketHandler(SOCKET_L2CAP,&_HCI);
00391     gHCI = &_HCI;
00392     gApp.Inquiry();
00393     return 0;
00394 }
00395 
00396 void TestShell()
00397 {
00398 //    USBInit();  // Modified by RadioJunkBox
00399     gApp.Run();
00400 }