Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 00029 #include "Utils.h" 00030 #include "USBHost.h" 00031 #include "hci.h" 00032 00033 #include "TextLCD.h" 00034 TextLCD lcd( p24, p26, p27, p28, p29, p30 ); // rs, e, d4-d7 00035 00036 void printf(const BD_ADDR* addr) 00037 { 00038 const u8* a = addr->addr; 00039 printf("%02X:%02X:%02X:%02X:%02X:%02X",a[5],a[4],a[3],a[2],a[1],a[0]); 00040 } 00041 00042 #define MAX_HCL_SIZE 260 00043 #define MAX_ACL_SIZE 400 00044 00045 class HCITransportUSB : public HCITransport 00046 { 00047 int _device; 00048 u8* _hciBuffer; 00049 u8* _aclBuffer; 00050 00051 public: 00052 void Open(int device, u8* hciBuffer, u8* aclBuffer) 00053 { 00054 _device = device; 00055 _hciBuffer = hciBuffer; 00056 _aclBuffer = aclBuffer; 00057 USBInterruptTransfer(_device,0x81,_hciBuffer,MAX_HCL_SIZE,HciCallback,this); 00058 USBBulkTransfer(_device,0x82,_aclBuffer,MAX_ACL_SIZE,AclCallback,this); 00059 } 00060 00061 static void HciCallback(int device, int endpoint, int status, u8* data, int len, void* userData) 00062 { 00063 HCI* t = ((HCITransportUSB*)userData)->_target; 00064 if (t) 00065 t->HCIRecv(data,len); 00066 USBInterruptTransfer(device,0x81,data,MAX_HCL_SIZE,HciCallback,userData); 00067 } 00068 00069 static void AclCallback(int device, int endpoint, int status, u8* data, int len, void* userData) 00070 { 00071 HCI* t = ((HCITransportUSB*)userData)->_target; 00072 if (t) 00073 t->ACLRecv(data,len); 00074 USBBulkTransfer(device,0x82,data,MAX_ACL_SIZE,AclCallback,userData); 00075 } 00076 00077 virtual void HCISend(const u8* data, int len) 00078 { 00079 USBControlTransfer(_device,REQUEST_TYPE_CLASS, 0, 0, 0,(u8*)data,len); 00080 } 00081 00082 virtual void ACLSend(const u8* data, int len) 00083 { 00084 USBBulkTransfer(_device,0x02,(u8*)data,len); 00085 } 00086 }; 00087 00088 00089 #define WII_REMOTE 0x042500 00090 00091 class HIDBluetooth 00092 { 00093 int _control; // Sockets for control (out) and interrupt (in) 00094 int _interrupt; 00095 int _devClass; 00096 BD_ADDR _addr; 00097 u8 _pad[2]; // Struct align 00098 00099 public: 00100 HIDBluetooth() : _control(0),_interrupt(0),_devClass(0) {}; 00101 00102 bool InUse() 00103 { 00104 return _control != 0; 00105 } 00106 00107 static void OnHidInterrupt(int socket, SocketState state, const u8* data, int len, void* userData) 00108 { 00109 HIDBluetooth* t = (HIDBluetooth*)userData; 00110 if (data) 00111 { 00112 if (t->_devClass == WII_REMOTE && data[1] == 0x30) 00113 { 00114 printf("================wii====================\n"); 00115 t->Led(); 00116 t->Hid(); // ask for accelerometer 00117 t->_devClass = 0; 00118 } 00119 00120 const u8* d = data; 00121 switch (d[1]) 00122 { 00123 case 0x02: 00124 { 00125 int x = (signed char)d[3]; 00126 int y = (signed char)d[4]; 00127 printf("Mouse %2X dx:%d dy:%d\n",d[2],x,y); 00128 } 00129 break; 00130 00131 case 0x37: // Accelerometer http://wiki.wiimoteproject.com/Reports 00132 { 00133 int pad = (d[2] & 0x9F) | ((d[3] & 0x9F) << 8); 00134 int x = (d[2] & 0x60) >> 5 | d[4] << 2; 00135 int y = (d[3] & 0x20) >> 4 | d[5] << 2; 00136 int z = (d[3] & 0x40) >> 5 | d[6] << 2; 00137 printf("WII %04X %d %d %d\n",pad,x,y,z); 00138 } 00139 break; 00140 00141 case 0x01: // Mini Keyboard 00142 { 00143 int keycode = (d[4]); 00144 int shiftcode = (d[2]); 00145 // printf("Keycode = %02x \n",keycode); 00146 // d[2] 0x01 ... Ctrl 00147 // d[2] 0x02 ... Shift(L) 00148 // d[2] 0x20 ... Shift(R) 00149 // d[2] 0x40 ... Alt 00150 // d[4] 0x28 ... Enter 00151 // d[4] 0x2a ... <- 00152 00153 if(keycode>=0x04 && keycode<=0x1d){ 00154 if(shiftcode==0x02 || shiftcode==0x20){ 00155 lcd.printf("%c", keycode-0x04+'A'); 00156 } else { 00157 lcd.printf("%c", keycode-0x04+'a'); 00158 } 00159 } else { 00160 if(shiftcode==0x02 || shiftcode==0x20){ 00161 switch(keycode){ 00162 case 0x1e: { lcd.printf("!"); break; } 00163 case 0x1f: { lcd.printf("@"); break; } 00164 case 0x20: { lcd.printf("#"); break; } 00165 case 0x21: { lcd.printf("$"); break; } 00166 case 0x22: { lcd.printf("%%"); break; } 00167 case 0x23: { lcd.printf("^"); break; } 00168 case 0x24: { lcd.printf("&"); break; } 00169 case 0x25: { lcd.printf("*"); break; } 00170 case 0x26: { lcd.printf("("); break; } 00171 case 0x27: { lcd.printf(")"); break; } 00172 case 0x28: { lcd.printf("\n"); break; } // Enter 00173 case 0x2a: { lcd.printf("%c",0x7f); break; } // Del 00174 case 0x2c: { lcd.printf(" "); break; } 00175 case 0x33: { lcd.printf(":"); break; } 00176 case 0x36: { lcd.printf("<"); break; } 00177 case 0x37: { lcd.printf(">"); break; } 00178 case 0x38: { lcd.printf("?"); break; } 00179 } 00180 } else { 00181 switch(keycode){ 00182 case 0x1e: { lcd.printf("1"); break; } 00183 case 0x1f: { lcd.printf("2"); break; } 00184 case 0x20: { lcd.printf("3"); break; } 00185 case 0x21: { lcd.printf("4"); break; } 00186 case 0x22: { lcd.printf("5"); break; } 00187 case 0x23: { lcd.printf("6"); break; } 00188 case 0x24: { lcd.printf("7"); break; } 00189 case 0x25: { lcd.printf("8"); break; } 00190 case 0x26: { lcd.printf("9"); break; } 00191 case 0x27: { lcd.printf("0"); break; } 00192 case 0x28: { lcd.printf("\n"); break; } // Enter 00193 case 0x2a: { lcd.printf("%c",0x7f); break; } // Del 00194 case 0x2c: { lcd.printf(" "); break; } 00195 case 0x33: { lcd.printf(";"); break; } 00196 case 0x36: { lcd.printf(","); break; } 00197 case 0x37: { lcd.printf("."); break; } 00198 case 0x38: { lcd.printf("/"); break; } 00199 } 00200 } 00201 } 00202 } 00203 break; 00204 case 0x03: // Connected? 00205 { 00206 lcd.printf("Connect!\n"); 00207 break; 00208 00209 } 00210 00211 00212 00213 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 00386 if (strcmp(cmd,"scan") == 0 || strcmp(cmd,"inquiry") == 0) 00387 Inquiry(); 00388 else if (strcmp(cmd,"ls") == 0) 00389 List(); 00390 else if (strcmp(cmd,"connect") == 0) 00391 Connect(); 00392 else if (strcmp(cmd,"disconnect") == 0) 00393 Disconnect(); 00394 else if (strcmp(cmd,"q")== 0) 00395 { 00396 Quit(); 00397 break; 00398 } else { 00399 printf("eh? %s\n",cmd); 00400 } 00401 } 00402 } 00403 }; 00404 00405 // Instance 00406 ShellApp gApp; 00407 00408 static int HciCallback(HCI* hci, HCI_CALLBACK_EVENT evt, const u8* data, int len) 00409 { 00410 switch (evt) 00411 { 00412 case CALLBACK_READY: 00413 printf("CALLBACK_READY\n"); 00414 gApp.Ready(); 00415 break; 00416 00417 case CALLBACK_INQUIRY_RESULT: 00418 printf("CALLBACK_INQUIRY_RESULT "); 00419 printf((BD_ADDR*)data); 00420 printf("\n"); 00421 break; 00422 00423 case CALLBACK_INQUIRY_DONE: 00424 printf("CALLBACK_INQUIRY_DONE\n"); 00425 gApp.ConnectDevices(); 00426 break; 00427 00428 case CALLBACK_REMOTE_NAME: 00429 { 00430 BD_ADDR* addr = (BD_ADDR*)data; 00431 const char* name = (const char*)(data + 6); 00432 printf(addr); 00433 printf(" % s\n",name); 00434 } 00435 break; 00436 00437 case CALLBACK_CONNECTION_COMPLETE: 00438 gApp.ConnectionComplete(hci,(connection_info*)data); 00439 break; 00440 }; 00441 return 0; 00442 } 00443 00444 // these should be placed in the DMA SRAM 00445 typedef struct 00446 { 00447 u8 _hciBuffer[MAX_HCL_SIZE]; 00448 u8 _aclBuffer[MAX_ACL_SIZE]; 00449 } SRAMPlacement; 00450 00451 HCITransportUSB _HCITransportUSB; 00452 HCI _HCI; 00453 00454 u8* USBGetBuffer(u32* len); 00455 int OnBluetoothInsert(int device) 00456 { 00457 printf("Bluetooth inserted of %d\n",device); 00458 u32 sramLen; 00459 u8* sram = USBGetBuffer(&sramLen); 00460 sram = (u8*)(((u32)sram + 1023) & ~1023); 00461 SRAMPlacement* s = (SRAMPlacement*)sram; 00462 _HCITransportUSB.Open(device,s->_hciBuffer,s->_aclBuffer); 00463 _HCI.Open(&_HCITransportUSB,HciCallback); 00464 RegisterSocketHandler(SOCKET_L2CAP,&_HCI); 00465 gHCI = &_HCI; 00466 gApp.Inquiry(); 00467 return 0; 00468 } 00469 00470 void TestShell() 00471 { 00472 USBInit(); 00473 printf("*** TestShell Started ***\n"); 00474 gApp.Run(); 00475 printf("*** TestShell Ended ***\n"); 00476 }
Generated on Tue Jul 12 2022 16:21:02 by
1.7.2