Based on myBlueUSB reference ver. http://mbed.org/users/networker/programs/myBlueUSB/lsm1ui
Dependencies: mbed myUSBHost AvailableMemory rfcomm myBlueUSB sdp
Revision 0:8d8481ed6d49, committed 2011-07-05
- Comitter:
- kenbumono
- Date:
- Tue Jul 05 08:25:59 2011 +0000
- Commit message:
Changed in this revision
diff -r 000000000000 -r 8d8481ed6d49 AutoEvents.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AutoEvents.cpp Tue Jul 05 08:25:59 2011 +0000 @@ -0,0 +1,161 @@ + +/* +Copyright (c) 2010 Peter Barrett + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "mbed.h" +#include "USBHost.h" +#include "Utils.h" + +#define AUTOEVT(_class,_subclass,_protocol) (((_class) << 16) | ((_subclass) << 8) | _protocol) +#define AUTO_KEYBOARD AUTOEVT(CLASS_HID,1,1) +#define AUTO_MOUSE AUTOEVT(CLASS_HID,1,2) + +u8 auto_mouse[4]; // buttons,dx,dy,scroll +u8 auto_keyboard[8]; // modifiers,reserved,keycode1..keycode6 +u8 auto_joystick[4]; // x,y,buttons,throttle + +void AutoEventCallback(int device, int endpoint, int status, u8* data, int len, void* userData) +{ + int evt = (int)userData; + switch (evt) + { + case AUTO_KEYBOARD: + printf("AUTO_KEYBOARD "); + break; + case AUTO_MOUSE: + printf("AUTO_MOUSE "); + break; + default: + printf("HUH "); + } + printfBytes("data",data,len); + USBInterruptTransfer(device,endpoint,data,len,AutoEventCallback,userData); +} + +// Establish transfers for interrupt events +void AddAutoEvent(int device, InterfaceDescriptor* id, EndpointDescriptor* ed) +{ + if ((ed->bmAttributes & 3) != ENDPOINT_INTERRUPT || !(ed->bEndpointAddress & 0x80)) + return; + + // Make automatic interrupt enpoints for known devices + u32 evt = AUTOEVT(id->bInterfaceClass,id->bInterfaceSubClass,id->bInterfaceProtocol); + u8* dst = 0; + int len; + switch (evt) + { + case AUTO_MOUSE: + dst = auto_mouse; + len = sizeof(auto_mouse); + break; + case AUTO_KEYBOARD: + dst = auto_keyboard; + len = sizeof(auto_keyboard); + break; + default: + printf("Interrupt endpoint %02X %08X\n",ed->bEndpointAddress,evt); + break; + } + if (dst) + { + printf("Auto Event for %02X %08X\n",ed->bEndpointAddress,evt); + USBInterruptTransfer(device,ed->bEndpointAddress,dst,len,AutoEventCallback,(void*)evt); + } +} + +void PrintString(int device, int i) +{ + u8 buffer[256]; + int le = GetDescriptor(device,DESCRIPTOR_TYPE_STRING,i,buffer,255); + if (le < 0) + return; + char* dst = (char*)buffer; + for (int j = 2; j < le; j += 2) + *dst++ = buffer[j]; + *dst = 0; + printf("%d:%s\n",i,(const char*)buffer); + } + +// Walk descriptors and create endpoints for a given device +int StartAutoEvent(int device, int configuration, int interfaceNumber) +{ + u8 buffer[255]; + int err = GetDescriptor(device,DESCRIPTOR_TYPE_CONFIGURATION,0,buffer,255); + if (err < 0) + return err; + + int len = buffer[2] | (buffer[3] << 8); + u8* d = buffer; + u8* end = d + len; + while (d < end) + { + if (d[1] == DESCRIPTOR_TYPE_INTERFACE) + { + InterfaceDescriptor* id = (InterfaceDescriptor*)d; + if (id->bInterfaceNumber == interfaceNumber) + { + d += d[0]; + while (d < end && d[1] != DESCRIPTOR_TYPE_INTERFACE) + { + if (d[1] == DESCRIPTOR_TYPE_ENDPOINT) + AddAutoEvent(device,id,(EndpointDescriptor*)d); + d += d[0]; + } + } + } + d += d[0]; + } + return 0; +} + +// Implemented in main.cpp +int OnDiskInsert(int device); + +// Implemented in TestShell.cpp +int OnBluetoothInsert(int device); + +void OnLoadDevice(int device, DeviceDescriptor* deviceDesc, InterfaceDescriptor* interfaceDesc) +{ + printf("LoadDevice %d %02X:%02X:%02X\n",device,interfaceDesc->bInterfaceClass,interfaceDesc->bInterfaceSubClass,interfaceDesc->bInterfaceProtocol); + char s[128]; + for (int i = 1; i < 3; i++) + { + if (GetString(device,i,s,sizeof(s)) < 0) + break; + printf("%d: %s\n",i,s); + } + + switch (interfaceDesc->bInterfaceClass) + { + case CLASS_MASS_STORAGE: + if (interfaceDesc->bInterfaceSubClass == 0x06 && interfaceDesc->bInterfaceProtocol == 0x50) + OnDiskInsert(device); // it's SCSI! + break; + case CLASS_WIRELESS_CONTROLLER: + if (interfaceDesc->bInterfaceSubClass == 0x01 && interfaceDesc->bInterfaceProtocol == 0x01) + OnBluetoothInsert(device); // it's bluetooth! + break; + default: + StartAutoEvent(device,1,0); + break; + } +} \ No newline at end of file
diff -r 000000000000 -r 8d8481ed6d49 AvailableMemory.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/AvailableMemory.lib Tue Jul 05 08:25:59 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/networker/code/AvailableMemory/#2b2aa11cebd7
diff -r 000000000000 -r 8d8481ed6d49 FATFileSystem.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FATFileSystem.lib Tue Jul 05 08:25:59 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_unsupported/code/fatfilesystem/ \ No newline at end of file
diff -r 000000000000 -r 8d8481ed6d49 TestShell.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TestShell.cpp Tue Jul 05 08:25:59 2011 +0000 @@ -0,0 +1,347 @@ + +/* +Copyright (c) 2010 Peter Barrett + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +#include "mbed.h" +#include <vector> +#include "Utils.h" +#include "USBHost.h" +#include "hci.h" +#include "HCITransportUSB.h" +#include "RFCOMM.h" +#include "ftclasslibusbdevbt.h" +#include "sdp_data.h" +#include "sdp.h" +#include "btserial.h" +#include "neighbourhood.h" + +#include "motordriver.h" + +/************************************************ +TODO: +mtu and credits are completely unhandled - in progress +multiple rfcomm sessions should be possible - done +SDP would be nice - beta +multiple rfcomm channels are untested +decoupling of rfcomm and application - much better +packets are not reassembled - some are (HCI and ft application level) +disconnect and timeouts +************************************************/ +#define DEBUG 1 +int state = 0; + +//int bulk = 0; +void printf(const BD_ADDR* addr) { + const u8* a = addr->addr; + printf("%02X:%02X:%02X:%02X:%02X:%02X",a[5],a[4],a[3],a[2],a[1],a[0]); +} + +const char FtDevClass[3] = {0x00, 0x1F, 0x82 }; +const char SerDevClass[3] = {4, 1, 0x00}; +// Instance +extern RFCOMMManager rfcomm_manager; + +class application : public HCI { + BTDevice* devs[8]; + int count, i, pending; +public: + // We have connected to a device + void ConnectionComplete(connection_info* info) { + printf("ConnectionComplete "); + BD_ADDR* a = &info->bdaddr; + printf(a); + printf("\n"); + RemoteNameRequest(a); + for (i++; i < count; i++) {//find the next device to open + printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3); + if (devs[i]->_handle == 0 && memcmp(devs[i]->_info.dev_class, FtDevClass, 3)==0) {//or some other way to connect to RFCOMM devices + BD_ADDR* bd = &devs[i]->_info.bdaddr; + printf("Connecting to "); + printf(bd); + printf("\n"); + pending++; + CreateConnection(bd); //some low level connect, just let it happen for now (sets pin, mtu etc.) + printf("connection cmd was sent\n"); + return; + } + } + //state = 1; //start the real application + } + + void ConnectDevices() { + count = GetDevices(devs,8);//get pointers to all bluetooth devices + pending = 0; + for (i = 0; i < count; i++) { + printfBytes("DEVICE CLASS",devs[i]->_info.dev_class,3); + if (devs[i]->_handle == 0 /*&& memcmp(devs[i]->_info.dev_class, FtDevClass, 3)==0*/) {//or some other way to connect to RFCOMM devices + BD_ADDR* bd = &devs[i]->_info.bdaddr; + printf("Connecting to "); + printf(bd); + printf("\n"); + pending++; + CreateConnection(bd); //some low level connect, just let it happen for now (sets pin, mtu etc.) + printf("connection cmd was sent\n"); + return; + } + } + if (pending == 0) state = 1;//for the case when there are no ft devices + } + virtual void Callback(HCI_CALLBACK_EVENT c, const u8* data, int len); + int csr_write_bd_addr(BD_ADDR *bdaddr, bool transient=true); + int csr_reset_device(bool transient=true); +} App; //application instance + +extern "C" void mbed_reset(); + + +void application::Callback(HCI_CALLBACK_EVENT evt, const u8* data, int len) {//these events are forwarded (in)directly from HCIRecv + unsigned char pin[] = "1234"; + unsigned char newaddr[] = {0x2c, 0x07, 0x54, 0x7b, 0x13, 0x00};//possible ft TX address (ROBO TX-277) +// unsigned char newaddr[] = {0x57, 0x0a, 0x3d, 0x83, 0x15, 0x00};//original address of the cheap round BT dongle + printf("\x1b[%dm", 33); + switch (evt) { + case CALLBACK_READY: + printf("CALLBACK_READY\n"); + printf("my address = "); + printf((BD_ADDR*)data); + if (memcmp(newaddr, data, 6) != 0) { //csr_write_bd_addr((BD_ADDR*)newaddr, false); + } + Inquiry();//start the second phase of the discovery + break; + + case CALLBACK_INQUIRY_RESULT: //optionally build the list of FT devices here + printf("CALLBACK_INQUIRY_RESULT "); + printf((BD_ADDR*)data); + printf("\n");//data points to inquiry_info struct +// RemoteNameRequest((BD_ADDR*)data); + break; + + case CALLBACK_INQUIRY_DONE: + printf("CALLBACK_INQUIRY_DONE\n"); + neighbors = new neighbourhood(&App); + neighbors->read(); + ConnectDevices(); + break; + + case CALLBACK_REMOTE_NAME: { + BD_ADDR* addr = (BD_ADDR*)data; + const char* name = (const char*)(data + 6); + printf(addr); + printf(" = % s\n",name); + pending--; + if (pending == 0) state = 1; + } + break; + + case CALLBACK_CONNECTION_COMPLETE: { + connection_info *ci = (connection_info*)data; + if (ci->status>0) { + printf("Connection failed, status=0x%02X\n", ci->status); + break; + } + ConnectionComplete(ci); + printf("Going to open sdp socket\n"); + L2CAPAddr addr; + memcpy(&addr.bdaddr, &ci->bdaddr, 6); + //int s = SDP.Open(&addr.hdr); + } + break; + case CALLBACK_PIN_REQ: + printf("Enter PIN for "); + printf((BD_ADDR*)data); + printf(" : submitting %s\n", pin); + //USBLoop(); wait(1.0); USBLoop(); + //for(int k=0; k<2000000;k++) USBLoop(); + PinCodeReply(data, pin); + break; + case CALLBACK_VENDOR: + printfBytes("Vendor Reply:", data, len); + //mbed_reset(); + if (data[0] == 0xc2) + csr_reset_device(false); + break; + default: + printf("Unhandled HCI Callback %d\n", evt); + }; + printf("\x1b[%dm", 0); +} + +#define CSR_WRITE 0xFC00 + +int application::csr_write_bd_addr(BD_ADDR *bdaddr, bool transient) { + unsigned char cmd[] = { 0xc2, + 0x02, 0x00, 0x0c, 0x00, 0x11, 0x47, 0x03, 0x70, + 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + if (transient) + cmd[15] = 0x08; + + cmd[17] = bdaddr->addr[2]; + cmd[18] = 0x00; + cmd[19] = bdaddr->addr[0]; + cmd[20] = bdaddr->addr[1]; + cmd[21] = bdaddr->addr[3]; + cmd[22] = 0x00; + cmd[23] = bdaddr->addr[4]; + cmd[24] = bdaddr->addr[5]; + + return SendCmd(CSR_WRITE, cmd, sizeof(cmd)); +} + +int application::csr_reset_device(bool transient) { + unsigned char cmd[] = { 0xc2, 0x02, 0x00, 0x09, 0x00, + 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + if (transient) + cmd[7] = 0x02; + + return SendCmd(CSR_WRITE, cmd, sizeof(cmd)); +} + + +// these should be placed in the DMA SRAM +typedef struct { + u8 _hciBuffer[MAX_HCL_SIZE]; + u8 _aclBuffer[MAX_ACL_SIZE]; +} SRAMPlacement; + +HCITransportUSB _HCITransportUSB; //use USB as the transport to the radio + +int OnBluetoothInsert(int device) {//install the HCI and start discovery, user callbacks are made to HciCalback + printf("Bluetooth inserted of %d\n",device); + u32 sramLen; + u8* sram = USBGetBuffer(&sramLen); + sram = (u8*)(((u32)sram + 1023) & ~1023); + SRAMPlacement* s = (SRAMPlacement*)sram; + _HCITransportUSB.Open(device,s->_hciBuffer,s->_aclBuffer);//setup buffers for USB host, incoming data goes first to HCIRecv and ACLRecv + RegisterSocketHandler(SOCKET_L2CAP,&App); //register the application::hci as handler for L2CAP events + RegisterSocketHandler(SOCKET_RFCOM, &rfcomm_manager);//set the RFCOMMManager as the RFCOM socket handler + if (RegisterSocketHandler(SOCKET_SDP, &SDP)) + printf("Could not register SDP socket type\n"); + App.Open(&_HCITransportUSB);//the callback is virtual + App.Inquiry();//start discovery of BT devices phase 0 + return 0; +} + +DigitalOut led(LED1), loop(LED2); + +int comm = 0; +btserial *incoming, *outgoing; + +Motor motorRight(p21, p5, p6, 1); // pwm, fwd, rev, can break +Motor motorLeft(p22, p7, p8, 1); // pwm, fwd, rev, can break + +void motorSpeed(Motor& motor, int stick) +{ + float speed; + if(100 <= stick && stick <= 155) { + motor.stop(0); + } else if(0 <= stick && stick <= 99) { + speed = (100 - stick) * 0.01; + motor.speed(speed); + printf("Motor:%f", speed); + } else { + speed = (155 - stick) * 0.01; + motor.speed(speed); + printf("Motor:%f", speed); + } +} + +void echo(int socket, SocketState state, const u8* data, int len, void* userData) { + const u8 connack[] = { 0xbe, 0xef, 8, 'C','O','N','N','_','A','C','K', 0x11}; + printf("Echo: socket %d, state %d, len=%d\n", socket, state, len); + if (state==SocketState_Open) { + if (len == 0) { + printf("Sending CONN_ACK\n"); + Socket_Send(socket, connack, sizeof(connack)); + } else { + //Socket_Send(socket, data, len); + printfBytes("echo:", data, len); + + if(len >= 4) { + char temp[5] = {0}; + memcpy(temp, data, 4); + int num = strtol(temp, NULL, 16); + + int LeftStickY = num / 256; + int RightStickY = num - (LeftStickY * 256); + + motorSpeed(motorLeft, LeftStickY); + motorSpeed(motorRight, RightStickY); + } + } + } +} + +void TestShell() { + int n=0; + USBInit(); + for (;;) { + switch (state) { + case 0: //inquiry and low-level connection + break; + case 1: {//initialisation + printf("Ready to open ports\n"); + InitFtBtDeviceList(); + int n = GetNrOfFtBtDevices(); + printf("%d ft BT devices have been found\n", n); + if (n > 0) { + ftbtdev *d = GetFtUsbDeviceHandle(0); + if (d==0) printf("could not get device handle\n"); + //int sock = OpenFtBtDevice(d); + } + state = 2; + comm = Socket_Listen(SOCKET_RFCOM, 1, echo, 0); + //incoming = new btserial(1); + } + break; + case 2://main loop + /* if (incoming->readable()>0){ + int c= incoming->getc(); + putc(c, stderr); + incoming->putc(c); + } + else if (incoming->readable()<0){ + state = 3; + printf("end of session"); + delete incoming; + }*/ + break; + default: + break; + } + loop=1; + USBLoop(); + loop=0; + n++; + if (n>=500000) { + n=0; + led = !led; + } + } + //printf("Dropped out of main loop!\n"); +} + +//********************************************************************************************************************************
diff -r 000000000000 -r 8d8481ed6d49 btserial.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/btserial.cpp Tue Jul 05 08:25:59 2011 +0000 @@ -0,0 +1,1 @@ +#include "btserial.h" btserial::btserial(char ba[6], char ch) { L2CAPAddr a; memcpy(&a.bdaddr, ba, 6); a.psm = ch; sendptr = 0; recptrin = 0; recptrout = bufsize - 1; free = bufsize; sock = Socket_Open(SOCKET_RFCOM, &a.hdr, cb, this); } btserial::btserial(char ch) { sendptr = 0; recptrin = 0; recptrout = bufsize - 1; free = bufsize; sock = Socket_Listen(SOCKET_RFCOM, ch, cb, this); } void btserial::cb(int socket, SocketState state, const unsigned char *data, int len, void* userData) { btserial *self = (btserial*)userData; if (state == SocketState_Open) if (len > 0) self->stash(data, len); else { port_settings ps;//defaults are ok ps.baud = 3; //9600 baud ps.bits = 3;//8 bits ps.stop = 0;//1 bit ps.par = 0; //no parity ps.mask = MASK_BITRATE|MASK_DATABITS|MASK_STOPBITS|MASK_PARITYBITS; //set_remote_port_parameters(sock, &ps); self->open = true; } else if (state == SocketState_Closed) self->open = false; } void btserial::stash(const unsigned char *data, int len) { int i = 0; while (i < len && free>0) { recbuf[recptrin++] = data[i++]; if (recptrin == bufsize) recptrin = 0; free--; } } int btserial::getc() { if (free == bufsize || !open) return -1; free++; recptrout++; if (recptrout == bufsize) recptrout = 0; return recbuf[recptrout]; } int btserial::putc(int c) { if (sendptr==bufsize || !open) return -1; sendbuf[sendptr++] = c; if (sendptr==bufsize || c=='\n' || c=='\r') { Socket_Send(sock, sendbuf, sendptr); sendptr = 0; } return c; } void btserial::baud(int br) { int rates[] = {2400,4800,7200,9600,19200,38400,57600,115200,230400}; if (!open) return; for (int i = 0; i < sizeof(rates)/sizeof(int);i++) if (rates[i] == br) { port_settings ps; ps.baud = i; ps.mask = MASK_BITRATE; set_remote_port_parameters(sock, &ps); return; } printf("Illegal baudrate requested %d\n", br); } void btserial::format(int bits, Serial::Parity par, int stop) { if (!open) return; port_settings ps; ps.bits = bits-5; ps.stop = stop-1; switch (par) { case Serial::None: ps.par = 0; ps.par_t = 0; break; case Serial::Odd: ps.par = 1; ps.par_t = 0; break; case Serial::Even: ps.par = 1; ps.par_t = 1; break; case Serial::Forced0: ps.par = 1; ps.par_t = 3; break; case Serial::Forced1: ps.par = 1; ps.par_t = 2; break; } ps.mask = MASK_DATABITS|MASK_STOPBITS|MASK_PARITYBITS|MASK_PARITYTYPE; set_remote_port_parameters(sock, &ps); } \ No newline at end of file
diff -r 000000000000 -r 8d8481ed6d49 btserial.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/btserial.h Tue Jul 05 08:25:59 2011 +0000 @@ -0,0 +1,31 @@ +#ifndef BTSERIAL_H +#define BTSERIAL_H +#include "mbed.h" +#include "RFCOMM.h" + +class btserial { + static const int bufsize = 127; + int sock; + unsigned char sendbuf[bufsize], recbuf[bufsize]; + int sendptr, recptrin, recptrout, free; + static void cb(int socket, SocketState state, const unsigned char *data, int len, void* userData); + void stash(const unsigned char *data, int len); + bool open; +public: + btserial(char ba[6], char ch);//outgoing + btserial(char ch);//incoming + void baud(int); + void format(int, Serial::Parity, int); + int putc(int); + int getc(); + int readable() { + if (!open) return -1; + return bufsize-free; + } + int writeable() { + if (!open) return -1; + return bufsize - sendptr; + } +}; + +#endif \ No newline at end of file
diff -r 000000000000 -r 8d8481ed6d49 ftclasslibusbdevbt.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ftclasslibusbdevbt.cpp Tue Jul 05 08:25:59 2011 +0000 @@ -0,0 +1,134 @@ +#include "mbed.h" +#include <vector> +#include "Utils.h" +#include "hci.h" +#include "ftclasslibusbdevbt.h" + +//extern HCI* gHCI; +class application; +extern application App; + +void printf(const BD_ADDR* addr); + +void ftdev::receive(int socket, SocketState state, const u8* data, int len) { + printf("ftdev::receive was called: socket %d, state=%d, length=%d\n", socket, state, len); +// unsigned char req[] = "\xdget_ser_num\xd"; + unsigned char req[] = {0xbe, 0xef, 6, 0xfc, 0,0,0,0,0, 0xaf}; + if (len==0) { + switch (state) { + case SocketState_Opening: + break; + case SocketState_Open: + printf("sending request \n%s\n", req); + Socket_Send(sock, req, sizeof(req)); + break; + case SocketState_Closing: + case SocketState_Closed: + return; + } + } else { + //printHex(data, len); + parse(data, len); + if (state==SocketState_Open) + ;//Socket_Close(sock);//replace with ft primitive + } +} + +unsigned short ftdev::chksum() { + unsigned short sum = (X1_len & 0xFF) + (X1_len >> 8); + for (int i = 0; i < X1_len; i++) + sum += X1_pkt[i]; + return -sum; +} + +void ftdev::parse (const unsigned char *buf, unsigned len) { + unsigned i = 0; + while (i < len) { + char c = buf[i++]; + switch (parseState) { + case 0: //ascii state + if (c==2) + parseState = 1; + else + putc(c, stdout); + break; + case 1: + if (c==0x55) + parseState = 2; + else { + parseState = 0; + printf("expected 0x55 in X1 header, found %02X\n", c); + } + break; + case 2: + X1_len = c<<8; + parseState= 3; + break; + case 3: + X1_len += c; + parseState= 4; + X1_pkt = new unsigned char[X1_len]; + X1_pos = 0; + break; + case 4: + if (X1_pos < X1_len) X1_pkt[X1_pos++] = c; + else parseState = 5; + break; + case 5: + X1_crc = c<<8; + parseState= 6; + break; + case 6: + X1_crc += c; + parseState= 7; + break; + case 7: + if (c == 3 && X1_crc == chksum()) { + //handlePkt(); + printHex(X1_pkt, X1_len); + }else + printf("framing or checksum error, end char = %02X\n", c); + + parseState = 0; + break; + } + } +} + +vector<ftbtdev*> ft_devs; +ftdev _ftdev; //single instance, just for test + +int GetNrOfFtBtDevices() { + return ft_devs.size(); +} + +unsigned InitFtBtDeviceList() {//assume inquiry has been done + static char FtDevClass[3] = {0x00, 0x1F, 0x82 }; + BTDevice* devs[8]; + int count = ((HCI*)&App)->GetDevices(devs,8); + int n = 0; + for (int i = 0; i < count; i++) { + if (memcmp(devs[i]->_info.dev_class, FtDevClass, 3)==0) { + ft_devs.push_back(new ftbtdev(&devs[i]->_info)); + printf("%d: %s\n", n++, devs[i]->_name); + } +// printf("device %d (handle=%d) ", i, devs[i]->_handle); +// printfBytes("devclass: ", devs[i]->_info.dev_class, 3); + } + return n; +} + +ftbtdev* GetFtUsbDeviceHandle(unsigned Num) { + if (Num < ft_devs.size()) { + return ft_devs[Num]; + } + return 0; +} + +unsigned OpenFtBtDevice(ftbtdev* d) { + BD_ADDR* bd = d->BtAddr(); + printf("Connecting to "); + printf(bd); + printf("\n"); + return _ftdev.Open(bd, 1); //TODO: everything can go wrong here +}
diff -r 000000000000 -r 8d8481ed6d49 ftclasslibusbdevbt.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ftclasslibusbdevbt.h Tue Jul 05 08:25:59 2011 +0000 @@ -0,0 +1,47 @@ +#ifndef FTCLASSLIBUSBDEVBT_H +#define FTCLASSLIBUSBDEVBT_H + + +class ftbtdev {//small object for ft BT enumeration + inquiry_info info; +public: + ftbtdev(inquiry_info* ii) { + info = *ii; + } + BD_ADDR* BtAddr() { + return &info.bdaddr; + } +}; + +class ftdev {//this should in the future encapsulate the real TXC + int sock; + int parseState; + unsigned short X1_crc, X1_len, X1_pos; + unsigned char *X1_pkt; + unsigned short chksum(); + void parse(const unsigned char *, unsigned); +public: + ftdev(): sock(0) { parseState = 0;} + int Open(BD_ADDR *bt_addr, int chan=1, SocketCallback cb=&ftdev::recv) { + L2CAPAddr s; + s.bdaddr = *bt_addr; + s.psm = chan;//abuse the psm for the channelID + sock = Socket_Open(SOCKET_RFCOM, &s.hdr, cb, this);//Open the serial connection via RFCOMM + if (sock<=0) + printf("Opening of RFCOMM socket for ftdevice failed (%d)\n", sock); + return sock; + } + static void recv(int socket, SocketState state, const u8* data, int len, void* userData) { + if (userData) ((ftdev*)userData)->receive(socket, state, data, len); + } + void receive(int socket, SocketState state, const u8* data, int len);// {printf("ftdev::receive was called: socket %d, state=%d, length=%d\n", socket, state, len);} +}; + +extern ftdev _ftdev; + +unsigned InitFtBtDeviceList(); +int GetNrOfFtBtDevices(); +ftbtdev* GetFtUsbDeviceHandle(unsigned Num); +unsigned OpenFtBtDevice(ftbtdev* d); + +#endif
diff -r 000000000000 -r 8d8481ed6d49 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Jul 05 08:25:59 2011 +0000 @@ -0,0 +1,121 @@ +/* +Copyright (c) 2010 Peter Barrett + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +#include "mbed.h" +#include "USBHost.h" +#include "Utils.h" +#include "FATFileSystem.h" + +int MassStorage_ReadCapacity(int device, u32* blockCount, u32* blockSize); +int MassStorage_Read(int device, u32 blockAddr, u32 blockCount, u8* dst, u32 blockSize); +int MassStorage_Write(int device, u32 blockAddr, u32 blockCount, u8* dst, u32 blockSize); + +class USBFileSystem : public FATFileSystem +{ + int _device; + u32 _blockSize; + u32 _blockCount; + +public: + USBFileSystem() : FATFileSystem("usb"),_device(0),_blockSize(0),_blockCount(0) + { + } + + void SetDevice(int device) + { + _device = device; + } + + virtual int disk_initialize() + { + return MassStorage_ReadCapacity(_device,&_blockCount,&_blockSize); + } + + virtual int disk_write(const char *buffer, int block_number) + { + return MassStorage_Write(_device,block_number,1,(u8*)buffer,_blockSize); + } + + virtual int disk_read(char *buffer, int block_number) + { + return MassStorage_Read(_device,block_number,1,(u8*)buffer,_blockSize); + } + + virtual int disk_sectors() + { + return _blockCount; + } +}; + +void DumpFS(int depth, int count) +{ + DIR *d = opendir("/usb"); + if (!d) + { + printf("USB file system borked\n"); + return; + } + + printf("\nDumping root dir\n"); + struct dirent *p; + for(;;) + { + p = readdir(d); + if (!p) + break; + int len = sizeof( dirent); + printf("%s %d\n", p->d_name, len); + } + closedir(d); +} + +int OnDiskInsert(int device) +{ + USBFileSystem fs; + fs.SetDevice(device); + DumpFS(0,0); + return 0; +} + +/* + Simple test shell to exercise mouse,keyboard,mass storage and hubs. + Add 2 15k pulldown resistors between D+/D- and ground, attach a usb socket and have at it. +*/ + +Serial pc(USBTX, USBRX); +int GetConsoleChar() +{ + if (!pc.readable()) + return -1; + char c = pc.getc(); + pc.putc(c); // echo + return c; +} + +void TestShell(); + +int main() +{ + pc.baud(460800); + printf("BlueUSB\nNow get a bunch of usb or bluetooth things and plug them in\n"); + TestShell(); +}
diff -r 000000000000 -r 8d8481ed6d49 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Jul 05 08:25:59 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/63bcd7ba4912
diff -r 000000000000 -r 8d8481ed6d49 motordriver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/motordriver.cpp Tue Jul 05 08:25:59 2011 +0000 @@ -0,0 +1,142 @@ +/*motor driver libary modified from the following libary, +* +* mbed simple H-bridge motor controller +* Copyright (c) 2007-2010, sford +* +* by Christopher Hasler. +* +* from sford's libary, +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ + +#include "motordriver.h" + +#include "mbed.h" + +Motor::Motor(PinName pwm, PinName fwd, PinName rev, bool brakeable): + _pwm(pwm), _fwd(fwd), _rev(rev), _brakeable(brakeable), _sign(0) { + + // Set initial condition of PWM + _pwm.period(0.001); + _pwm = 0; + + // Initial condition of output enables + _fwd = 0; + _rev = 0; +} + +float Motor::speed(float speed) { + float temp = 0; + if (_sign == 0) { + _fwd = (speed > 0.0); + _rev = (speed < 0.0); + temp = abs(speed); + _pwm = temp; + } else if (_sign == 1) { + if (speed < 0) { + _fwd = (speed > 0.0); + _rev = (speed < 0.0); + _pwm = 0; + temp = 0; + } else { + _fwd = (speed > 0.0); + _rev = (speed < 0.0); + temp = abs(speed); + _pwm = temp; + } + } else if (_sign == -1) { + if (speed > 0) { + _fwd = (speed > 0.0); + _rev = (speed < 0.0); + _pwm = 0; + temp = 0; + } else { + _fwd = (speed > 0.0); + _rev = (speed < 0.0); + temp = abs(speed); + _pwm = temp; + } + } + if (speed > 0) + _sign = 1; + else if (speed < 0) { + _sign = -1; + } else if (speed == 0) { + _sign = 0; + } + return temp; +} +// (additions) +void Motor::coast(void) { + _fwd = 0; + _rev = 0; + _pwm = 0; + _sign = 0; +} + +float Motor::stop(float duty) { + if (_brakeable == 1) { + _fwd = 1; + _rev = 1; + _pwm = duty; + _sign = 0; + return duty; + } else + Motor::coast(); + return -1; // error, can't brake +} + +float Motor::state(void) const { + int fwd = _fwd.read(); + int rev = _rev.read(); + float pwm = _pwm.read(); + + if ((fwd == rev) && (pwm > 0)) { + return -2;//braking + } else if (pwm == 0) { + return 2;//coasting + } else if ((fwd == 0) && (rev == 1)) { + return -pwm;//reversing + } else if ((fwd == 1) && (rev == 0)) { + return pwm;//fowards + } else + return -3;//error +} + +//test code, this demonstrates working motor drivers. + +//Motor A(p22, p6, p5, 1); // pwm, fwd, rev, can break +/* +Motor A(p22, p7, p8, 1); // pwm, fwd, rev, can break +Motor B(p21, p5, p6, 1); // pwm, fwd, rev, can break +int main() { + for (float s=-1.0; s < 1.0 ; s += 0.01) { + //A.speed(s); + A.speed(s); + B.speed(s); + wait(0.02); + } + A.stop(0); + B.stop(0); + wait(1); + A.coast(); + B.coast(); +} +*/ \ No newline at end of file
diff -r 000000000000 -r 8d8481ed6d49 motordriver.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/motordriver.h Tue Jul 05 08:25:59 2011 +0000 @@ -0,0 +1,91 @@ +/*motor driver libary modified from the following libary, +* +* mbed simple H-bridge motor controller +* Copyright (c) 2007-2010, sford +* +* by Christopher Hasler. +* +* from sford's libary, +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ + +#ifndef MBED_MOTOR_H +#define MBED_MOTOR_H + +#include "mbed.h" + +/** Interface to control a standard DC motor +* with an H-bridge using a PwmOut and 2 DigitalOuts +*/ +class Motor { + public: + +/** Create a motor control interface +* +* @param pwm A PwmOut pin, driving the H-bridge enable line to control the speed +* @param fwd A DigitalOut, set high when the motor should go forward +* @param rev A DigitalOut, set high when the motor should go backwards +* @param set if the motor driver is able to do braking 0 false 1 true. +*/ + Motor(PinName pwm, PinName fwd, PinName rev, bool brakeable = false); + +/** Set the speed of the motor +* +* @param speed The speed of the motor as a normalised value between -1.0 and 1.0. +* @return the applied speed to the motor after checking to ensure motor doesn't switch from forward to reverse without stopping. +*/ + float speed(float speed); + +/** Set the the motor to coast +* +* @param void +* @return motor coasts until another instruction is recived. +*/ + + void coast(void); + +/** Set the motor to dynamicaly brake +* +* @param float 0 - 1.0 provides some control over how hard the motor brakes. +* @return duty applied to motor driver. -1 is error, motor driver can't brake. +*/ + + float stop(float duty); +/** return the current state of the motor +* +* @param void +* @return state of motor, -1 to 1 is speed, -2 is braking, 2 is coasting. -3 is error. +*/ + float state(void) const; + + protected: + mutable PwmOut _pwm; + mutable DigitalOut _fwd; + mutable DigitalOut _rev; + bool _brakeable; // cna the motor driver break + int _sign; //prevents throwing the motor from full foward to full reverse and stuff melting. + +}; + + + + + +#endif
diff -r 000000000000 -r 8d8481ed6d49 myBlueUSB.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/myBlueUSB.lib Tue Jul 05 08:25:59 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/networker/code/myBlueUSB/#57f7679dd651
diff -r 000000000000 -r 8d8481ed6d49 myUSBHost.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/myUSBHost.lib Tue Jul 05 08:25:59 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/networker/code/myUSBHost/#74fd0a8f9d02
diff -r 000000000000 -r 8d8481ed6d49 neighbourhood.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/neighbourhood.cpp Tue Jul 05 08:25:59 2011 +0000 @@ -0,0 +1,69 @@ +#include "Utils.h" +#include "neighbourhood.h" + +neighbourhood *neighbors = 0; + +int neighbourhood::get(BD_ADDR *a, unsigned char *key) { + for (list<item>::iterator i = keys.begin(); i != keys.end(); i++) + if (memcmp(a, &(*i).a, sizeof(BD_ADDR)) == 0) { + memcpy(key, (*i).lk, lksize); +#ifdef STRICT_MRU + if (i != keys.begin()) { + keys.push_front(*i); + keys.erase(i); + dirty = true; + } +#endif + return 1; + } + return 0; +} + +int neighbourhood::add(BD_ADDR *a, const unsigned char *key, bool init) { + for (list<item>::iterator i = keys.begin(); i != keys.end(); i++) + if (memcmp(a, &(*i).a, sizeof(BD_ADDR)) == 0) { + memcpy((*i).lk, key, lksize); //assume key has changed, update key + (*i).used = true; + return 1; + } + //new key + printf("Neighbourhood: "); printf(a); printf("\n"); + if (keys.size() < cap) { + keys.push_back(item(a, key, !init));//append as long as there is space + } else { + keys.push_front(item(a, key, true));//otherwise prepend + dirty = true; + } + return 0; +} + +void neighbourhood::write() { + int n = 0; + static const int maxkey = 11; + unsigned char param[maxkey*(lksize+sizeof(BD_ADDR))+1]; + int k = keys.size()-cap; + list<item>::iterator i = keys.begin(); + while (i != keys.end()) { + if (k>0) { + if (!(*i).used) { + delete_link_key(&(*i).a);//try to make some room + keys.erase(i); + k--; + } else + i++; + } else + break; + } + //hci->delete_link_keys(); + unsigned char *p = ¶m[1]; + for (list<item>::iterator i = keys.begin(); i != keys.end() && n<maxkey; i++, n++) { + memcpy(p, &(*i).a, sizeof(BD_ADDR)); + p += sizeof(BD_ADDR); + memcpy(p, (*i).lk, lksize); + p += lksize; + } + param[0] = n; + if (n > 0) + write_link_keys(param); +} +
diff -r 000000000000 -r 8d8481ed6d49 neighbourhood.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/neighbourhood.h Tue Jul 05 08:25:59 2011 +0000 @@ -0,0 +1,77 @@ +#ifndef NEIGHBOURHOOD_H +#define NEIGHBOURHOOD_H + +#include <list> +#include "hci.h" + +//#define STRICT_MRU + +/****************************************************************************************** +call 'read' as part of the startup +on HCI_READ-STORED-LINK-KEY -COMPLETED event, call 'set_cap' +on RETURN_LINK_KEYS_EVENT call 'add' for each key with init=true +on LINK_KEY_NOTIFICATION_EVENT call 'add' with init=false (default) +on LINK_KEY_REQUEST_EVENT call 'get' and send the proper reply +call 'write' as part of shutdown + +a simpler approach could be to check for a link if it exists (single read) and try to add it. +when it fails just delete all. +********************************************************************************************/ + +#define HCI_DELETE_STORED_LINK_KEY 0x0C12 +#define HCI_WRITE_STORED_LINK_KEY 0x0C11 +#define HCI_READ_STORED_LINK_KEY 0x0C0D + +void printf(const BD_ADDR* addr); + +class neighbourhood { + static const int lksize = 16; + struct item { + BD_ADDR a; + unsigned char lk[lksize]; + bool used; + item (BD_ADDR *ad, const unsigned char *k, bool d) { + memcpy(&a, ad, sizeof(BD_ADDR)); + memcpy(lk, k, lksize); + used=d; + } + }; + int cap, initsize, used; + list<item> keys; + bool dirty; + HCI *hci; + void delete_link_key(BD_ADDR *a) { + unsigned char param[sizeof(BD_ADDR)+1]; + memcpy(param, a, sizeof(BD_ADDR)); + param[sizeof(BD_ADDR)] = 0; + hci->SendCmd(HCI_DELETE_STORED_LINK_KEY, param, sizeof(param)); + } + void write_link_keys(unsigned char param[]) { + hci->SendCmd(HCI_WRITE_STORED_LINK_KEY, param, param[0]*(sizeof(BD_ADDR)+lksize)+1); + } +public: + neighbourhood(HCI *h): hci(h) { + dirty = false; + used = 0; + cap=0; + initsize=0; + } + void read() { + unsigned char param[sizeof(BD_ADDR)+1]; + memset(param, 0, sizeof(BD_ADDR)); + param[sizeof(BD_ADDR)] = 1; + hci->SendCmd(HCI_READ_STORED_LINK_KEY, param, sizeof(param)); + } + void write(); + void set_cap(int c, int s) { + cap = c; + initsize = s; + printf("Neighbourhood: capacity=%d, used=%d\n", c, s); + } + int get(BD_ADDR *a, unsigned char *key); + int add(BD_ADDR *a, const unsigned char *key, bool init=false); +}; + +extern neighbourhood *neighbors; + +#endif \ No newline at end of file
diff -r 000000000000 -r 8d8481ed6d49 rfcomm.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rfcomm.lib Tue Jul 05 08:25:59 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/networker/code/rfcomm/#1c90839a1e70
diff -r 000000000000 -r 8d8481ed6d49 sdp.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sdp.lib Tue Jul 05 08:25:59 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/networker/code/sdp/#d5c3e499603d