watch using the RSSI of Bluetooth

Dependencies:   BaseUsbHost ConfigFile EthernetInterface HTTPClient-long mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers UsbBt2.cpp Source File

UsbBt2.cpp

00001 // UsbBt2.cpp 2012/12/18
00002 #include "mbed.h"
00003 #include "rtos.h"
00004 #include "BaseUsbHost.h"
00005 #define DEBUG
00006 #include "BaseUsbHostDebug.h"
00007 #define TEST
00008 #include "BaseUsbHostTest.h"
00009 #include "UsbBt2.h"
00010 
00011 static int LE16(const uint8_t* d)
00012 {
00013     return d[0] | (d[1] << 8);
00014 }
00015 
00016 bthci::bthci(ControlEp* ctlEp):m_pEpIntIn(NULL),m_pEpBulkIn(NULL),m_pEpBulkOut(NULL)
00017 {
00018     if (ctlEp == NULL) { // root hub
00019         DBG_OHCI(LPC_USB->HcRhPortStatus1);
00020         TEST_ASSERT_FALSE(LPC_USB->HcRhPortStatus1 & 0x200);
00021         ctlEp = new ControlEp();
00022         TEST_ASSERT_TRUE(ctlEp);
00023     }
00024     m_ctlEp = ctlEp;
00025     bool r = check(ctlEp);
00026     TEST_ASSERT(r);
00027     ParseConfiguration(ctlEp);
00028     int rc = ctlEp->SetConfiguration(1);
00029     TEST_ASSERT_EQUAL(rc, USB_OK);
00030 }
00031 
00032 bool bthci::check(ControlEp* ctlEp)
00033 {
00034     if (ctlEp == NULL) {
00035         return false;
00036     }
00037     uint8_t buf[18];
00038     int r = ctlEp->GetDescriptor(1, 0, buf, 8);
00039     if (r != USB_OK) {
00040         return false;
00041     }
00042     DBG_HEX(buf, 8);
00043     r = ctlEp->GetDescriptor(1, 0, buf, 18);
00044     if (r != USB_OK) {
00045         return false;
00046     }
00047     DBG_HEX(buf, 18);
00048     uint16_t vid = *reinterpret_cast<uint16_t*>(buf+8);
00049     uint16_t pid = *reinterpret_cast<uint16_t*>(buf+10);
00050     DBG("VID PID: %04X %04X\n", vid, pid);
00051     if (buf[4] == 0xe0 && buf[5] == 0x01 && buf[6] == 0x01) {
00052         return true;
00053     }
00054     return false;
00055 }
00056 
00057 int bthci::cmdSend(uint16_t op)
00058 {
00059    return cmdSend(op, NULL, 0);
00060 }
00061 
00062 int bthci::cmdSend(uint16_t op, const uint8_t* data, int size)
00063 {
00064     uint8_t* buf = new uint8_t[size+3];
00065     TEST_ASSERT(buf);
00066     if (buf == NULL) {
00067         return USB_ERROR;
00068     }
00069     buf[0] = op;
00070     buf[1] = op>>8;
00071     buf[2] = size;
00072     if (data) {
00073         memcpy(buf+3, data, size);
00074     }
00075     int rc = m_ctlEp->controlSend(USB_REQUEST_TYPE_CLASS, 0, 0, 0, buf, size+3);
00076     TEST_ASSERT(rc == USB_OK);
00077     delete[] buf;
00078     return rc;
00079 }
00080 
00081 int bthci::cmdSend(uint16_t op, const char* fmt, ...) 
00082 {   
00083     va_list vl;
00084     va_start(vl, fmt);
00085     uint8_t* buf = new uint8_t[255];
00086     TEST_ASSERT(buf);
00087     if (buf == NULL) {
00088         return USB_ERROR;
00089     }
00090     buf[0] = op;
00091     buf[1] = op>>8;
00092     int pos = 3;
00093     char* name;
00094     int name_len;
00095     uint16_t h;
00096     BD_ADDR* bdaddr;
00097     for(int i = 0; fmt[i]; i++) {
00098         switch(fmt[i]) {
00099             case 's':
00100                 name = va_arg(vl, char*);
00101                 name_len = strlen(name)+1;
00102                 memcpy(buf+pos, name, name_len);
00103                 pos += name_len;
00104                 break;
00105             case 'B':
00106                 buf[pos++] = va_arg(vl, int);
00107                 break;
00108             case 'H':
00109                 h = va_arg(vl, int);
00110                 buf[pos++] = h;
00111                 buf[pos++] = h>>8;
00112                 break;
00113             case 'A':
00114                 bdaddr = va_arg(vl, BD_ADDR*);
00115                 memcpy(buf+pos, bdaddr, 6);
00116                 pos += 6;
00117                 break;
00118             default:
00119                 DBG("op=%04X fmt=%s i=%d", op, fmt, i);
00120                 TEST_ASSERT(0);
00121                 //break;
00122         }
00123     }
00124     buf[2] = pos-3;
00125     int rc = m_ctlEp->controlSend(USB_REQUEST_TYPE_CLASS, 0, 0, 0, buf, pos);
00126     TEST_ASSERT(rc == USB_OK);
00127     delete[] buf;
00128     return rc;
00129 }
00130 
00131 int bthci::eventReceive(uint8_t* buf, int size, int millisec)
00132 {
00133     //DBG("%p buf=%p size=%d millisec=%d\n", this, buf, size, millisec);
00134     TEST_ASSERT(m_pEpIntIn);
00135     return m_pEpIntIn->interruptReceive(buf, size, millisec);
00136 }
00137 
00138 int bthci::AclSend(uint8_t* buf, int size, int millisec)
00139 {
00140     TEST_ASSERT(m_pEpBulkOut);
00141     return m_pEpBulkOut->bulkSend(buf, size, millisec);
00142 }
00143 
00144 int bthci::AclReceive(uint8_t* buf, int size, int millisec)
00145 {
00146     TEST_ASSERT(m_pEpBulkIn);
00147     return m_pEpBulkIn->bulkReceive(buf, size, millisec);
00148 }
00149 
00150 int bthci::ParseConfiguration(ControlEp* ctlEp)
00151 {
00152     int rc;
00153     uint8_t ConfigDesc[9];
00154     int index = 0;
00155     rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, ConfigDesc, sizeof(ConfigDesc));
00156     TEST_ASSERT(rc == USB_OK);
00157     DBG_BYTES("ConfigDescriptor 9bytes", ConfigDesc, sizeof(ConfigDesc));
00158     TEST_ASSERT(ConfigDesc[0] == 9);
00159     TEST_ASSERT(ConfigDesc[1] == 0x02);
00160     int wTotalLength = *((uint16_t*)&ConfigDesc[2]);
00161     DBG("TotalLength: %d\n", wTotalLength);
00162     int bConfigValue = ConfigDesc[5];
00163     TEST_ASSERT(bConfigValue == 1);
00164     DBG("ConfigValue: %d\n", bConfigValue);
00165     VERBOSE("MaxPower: %d mA\n", ConfigDesc[8]*2);   
00166 
00167     uint8_t* buf = new uint8_t[wTotalLength];
00168     TEST_ASSERT(buf);
00169     rc = ctlEp->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, wTotalLength);
00170     TEST_ASSERT(rc == USB_OK);
00171     TEST_ASSERT(ConfigDesc[1] == 0x02);
00172     for (int pos = 0; pos < wTotalLength; pos += buf[pos]) {
00173         DBG_BYTES("CFG", buf+pos, buf[pos]);
00174         int type = buf[pos+1];
00175         if (USB_DESCRIPTOR_TYPE_INTERFACE == type) { // 0x04
00176             DBG("InterfaceNumber: %d\n", buf[pos+2]);
00177             DBG("AlternateSetting: %d\n", buf[pos+3]);
00178             DBG("NumEndpoint: %d\n", buf[pos+4]);
00179             VERBOSE("InterfaceClass: %02X\n", buf[pos+5]);
00180             VERBOSE("InterfaceSubClass: %02X\n", buf[pos+6]);
00181             VERBOSE("InterfaceProtocol: %02X\n", buf[pos+7]);
00182             TEST_ASSERT(buf[pos+6] == 0x01);
00183             TEST_ASSERT(buf[pos+7] == 0x01);
00184         } 
00185         if (USB_DESCRIPTOR_TYPE_ENDPOINT == type) {
00186             TEST_ASSERT(buf[pos] == 7);
00187             uint8_t att = buf[pos+3];
00188             uint8_t ep = buf[pos+2];
00189             uint16_t size = LE16(buf+pos+4);
00190             DBG("EndpointAddress: %02X\n", ep);
00191             DBG("Attribute: %02X\n", att);
00192             DBG("MaxPacketSize: %d\n", size);
00193             int addr = ctlEp->GetAddr(); 
00194             if (att == 3) { // interrupt
00195                 if (m_pEpIntIn == NULL) {
00196                     m_pEpIntIn = new InterruptEp(addr, ep, size);
00197                 }
00198             } else if (att == 2) { // bulk
00199                 if (ep & 0x80) { // IN
00200                   if (m_pEpBulkIn == NULL) {
00201                       m_pEpBulkIn = new BulkEp(addr, ep, size);
00202                   }
00203               } else { // OUT
00204                   if (m_pEpBulkOut == NULL) {
00205                       m_pEpBulkOut = new BulkEp(addr, ep, size);
00206                   }
00207               } 
00208           }
00209       }
00210       if (m_pEpIntIn && m_pEpBulkIn && m_pEpBulkOut) { // cut off
00211           break;
00212       }
00213   }
00214   delete[] buf;
00215   TEST_ASSERT(m_pEpIntIn);
00216   TEST_ASSERT(m_pEpBulkIn);
00217   TEST_ASSERT(m_pEpBulkOut);
00218   return 0;   
00219 }