BLE demo for mbed Ported RunningElectronics's SBDBT firmware for BLE. It can communicate with iOS

Dependencies:   FatFileSystem mbed

Fork of BTstack by Norimasa Okamoto

Committer:
todotani
Date:
Wed Feb 20 14:18:38 2013 +0000
Revision:
6:cf06ba884429
Parent:
5:5fb56e13a1f9
Change tick timer to 1ms. Change attribute 0xFFF1 as read of DigitalIn p5

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 0:1ed23ab1345f 1 #include "usbbt.h"
todotani 5:5fb56e13a1f9 2 //#define __DEBUG
va009039 0:1ed23ab1345f 3 #include "mydbg.h"
va009039 0:1ed23ab1345f 4 #include "Utils.h"
va009039 0:1ed23ab1345f 5
va009039 0:1ed23ab1345f 6 usbbt::usbbt(int dongle)
va009039 0:1ed23ab1345f 7 : m_dongle(dongle),m_pEpIntIn(NULL),m_pEpBulkIn(NULL),m_pEpBulkOut(NULL),
va009039 0:1ed23ab1345f 8 m_int_seq(0),m_bulk_seq(0)
va009039 0:1ed23ab1345f 9 {
va009039 0:1ed23ab1345f 10
va009039 0:1ed23ab1345f 11 }
va009039 0:1ed23ab1345f 12
va009039 0:1ed23ab1345f 13 int usbbt::setup(int timeout)
va009039 0:1ed23ab1345f 14 {
va009039 0:1ed23ab1345f 15 for(int i = 0; i < 2; i++) {
va009039 0:1ed23ab1345f 16 m_pDev = m_pHost->getDeviceByClass(0xe0, m_dongle);
va009039 0:1ed23ab1345f 17 if (m_pDev || i > 0) {
va009039 0:1ed23ab1345f 18 break;
va009039 0:1ed23ab1345f 19 }
va009039 0:1ed23ab1345f 20 UsbErr rc = Usb_poll();
va009039 0:1ed23ab1345f 21 if (rc == USBERR_PROCESSING) {
va009039 0:1ed23ab1345f 22 VERBOSE("%p USBERR_PROCESSING\n", this);
va009039 0:1ed23ab1345f 23 return -1;
va009039 0:1ed23ab1345f 24 }
va009039 0:1ed23ab1345f 25 }
va009039 0:1ed23ab1345f 26 DBG("m_pDev=%p\n", m_pDev);
va009039 0:1ed23ab1345f 27 if (m_pDev == NULL) {
va009039 0:1ed23ab1345f 28 VERBOSE("%p Bluetooth dongle(%d) NOT FOUND\n", this, m_dongle);
va009039 0:1ed23ab1345f 29 return -1;
va009039 0:1ed23ab1345f 30 }
va009039 0:1ed23ab1345f 31 DBG_ASSERT(m_pDev);
va009039 0:1ed23ab1345f 32
va009039 0:1ed23ab1345f 33 ParseConfiguration();
va009039 0:1ed23ab1345f 34 return 0;
va009039 0:1ed23ab1345f 35 }
va009039 0:1ed23ab1345f 36
va009039 0:1ed23ab1345f 37 int usbbt::ParseConfiguration()
va009039 0:1ed23ab1345f 38 {
va009039 0:1ed23ab1345f 39 UsbErr rc;
va009039 0:1ed23ab1345f 40 uint8_t ConfigDesc[9];
va009039 0:1ed23ab1345f 41 int index = 0;
va009039 0:1ed23ab1345f 42 DBG_ASSERT(m_pDev);
va009039 0:1ed23ab1345f 43 rc = m_pDev->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, ConfigDesc, sizeof(ConfigDesc));
va009039 0:1ed23ab1345f 44 DBG_ASSERT(rc == USBERR_OK);
va009039 0:1ed23ab1345f 45 DBG_BYTES("ConfigDescriptor 9bytes", ConfigDesc, sizeof(ConfigDesc));
va009039 0:1ed23ab1345f 46 DBG_ASSERT(ConfigDesc[0] == 9);
va009039 0:1ed23ab1345f 47 DBG_ASSERT(ConfigDesc[1] == 0x02);
va009039 0:1ed23ab1345f 48 int wTotalLength = *((uint16_t*)&ConfigDesc[2]);
va009039 0:1ed23ab1345f 49 DBG("TotalLength: %d\n", wTotalLength);
va009039 0:1ed23ab1345f 50 int bConfigValue = ConfigDesc[5];
va009039 0:1ed23ab1345f 51 DBG_ASSERT(bConfigValue == 1);
va009039 0:1ed23ab1345f 52 DBG("ConfigValue: %d\n", bConfigValue);
va009039 0:1ed23ab1345f 53 VERBOSE("MaxPower: %d mA\n", ConfigDesc[8]*2);
va009039 0:1ed23ab1345f 54
va009039 0:1ed23ab1345f 55 uint8_t* buf = new uint8_t[wTotalLength];
va009039 0:1ed23ab1345f 56 DBG_ASSERT(buf);
va009039 0:1ed23ab1345f 57 rc = m_pDev->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, wTotalLength);
va009039 0:1ed23ab1345f 58 DBG_ASSERT(rc == USBERR_OK);
va009039 0:1ed23ab1345f 59 DBG_ASSERT(ConfigDesc[1] == 0x02);
va009039 0:1ed23ab1345f 60 for (int pos = 0; pos < wTotalLength; pos += buf[pos]) {
va009039 0:1ed23ab1345f 61 DBG_BYTES("CFG", buf+pos, buf[pos]);
va009039 0:1ed23ab1345f 62 int type = buf[pos+1];
va009039 0:1ed23ab1345f 63 if (USB_DESCRIPTOR_TYPE_INTERFACE == type) { // 0x04
va009039 0:1ed23ab1345f 64 DBG("InterfaceNumber: %d\n", buf[pos+2]);
va009039 0:1ed23ab1345f 65 DBG("AlternateSetting: %d\n", buf[pos+3]);
va009039 0:1ed23ab1345f 66 DBG("NumEndpoint: %d\n", buf[pos+4]);
va009039 0:1ed23ab1345f 67 VERBOSE("InterfaceClass: %02X\n", buf[pos+5]);
va009039 0:1ed23ab1345f 68 VERBOSE("InterfaceSubClass: %02X\n", buf[pos+6]);
va009039 0:1ed23ab1345f 69 VERBOSE("InterfaceProtocol: %02X\n", buf[pos+7]);
va009039 0:1ed23ab1345f 70 DBG_ASSERT(buf[pos+6] == 0x01);
va009039 0:1ed23ab1345f 71 DBG_ASSERT(buf[pos+7] == 0x01);
va009039 0:1ed23ab1345f 72 }
va009039 0:1ed23ab1345f 73 if (USB_DESCRIPTOR_TYPE_ENDPOINT == type) {
va009039 0:1ed23ab1345f 74 DBG_ASSERT(buf[pos] == 7);
va009039 0:1ed23ab1345f 75 uint8_t att = buf[pos+3];
va009039 0:1ed23ab1345f 76 uint8_t ep = buf[pos+2];
va009039 0:1ed23ab1345f 77 bool dir = ep & 0x80; // true=IN
va009039 0:1ed23ab1345f 78 uint16_t size = LE16(buf+pos+4);
va009039 0:1ed23ab1345f 79 DBG("EndpointAddress: %02X\n", ep);
va009039 0:1ed23ab1345f 80 DBG("Attribute: %02X\n", att);
va009039 0:1ed23ab1345f 81 DBG("MaxPacketSize: %d\n", size);
va009039 0:1ed23ab1345f 82 UsbEndpoint* pEp = new UsbEndpoint(m_pDev, ep, dir, att == 3 ? USB_INT : USB_BULK, size);
va009039 0:1ed23ab1345f 83 DBG_ASSERT(pEp);
va009039 0:1ed23ab1345f 84 if (att == 3) { // interrupt
va009039 0:1ed23ab1345f 85 if (m_pEpIntIn == NULL) {
va009039 0:1ed23ab1345f 86 m_pEpIntIn = pEp;
va009039 0:1ed23ab1345f 87 }
va009039 0:1ed23ab1345f 88 } else if (att == 2) { // bulk
va009039 0:1ed23ab1345f 89 if (dir) {
va009039 0:1ed23ab1345f 90 if (m_pEpBulkIn == NULL) {
va009039 0:1ed23ab1345f 91 m_pEpBulkIn = pEp;
va009039 0:1ed23ab1345f 92 }
va009039 0:1ed23ab1345f 93 } else {
va009039 0:1ed23ab1345f 94 if (m_pEpBulkOut == NULL) {
va009039 0:1ed23ab1345f 95 m_pEpBulkOut = pEp;
va009039 0:1ed23ab1345f 96 }
va009039 0:1ed23ab1345f 97 }
va009039 0:1ed23ab1345f 98 }
va009039 0:1ed23ab1345f 99 }
va009039 0:1ed23ab1345f 100 if (m_pEpIntIn && m_pEpBulkIn && m_pEpBulkOut) { // cut off
va009039 0:1ed23ab1345f 101 break;
va009039 0:1ed23ab1345f 102 }
va009039 0:1ed23ab1345f 103 }
va009039 0:1ed23ab1345f 104 delete[] buf;
va009039 0:1ed23ab1345f 105 DBG_ASSERT(m_pEpIntIn);
va009039 0:1ed23ab1345f 106 DBG_ASSERT(m_pEpBulkIn);
va009039 0:1ed23ab1345f 107 DBG_ASSERT(m_pEpBulkOut);
va009039 0:1ed23ab1345f 108 return 0;
va009039 0:1ed23ab1345f 109 }
va009039 0:1ed23ab1345f 110
va009039 0:1ed23ab1345f 111 int usbbt::send_packet(uint8_t packet_type, uint8_t* packet, int size)
va009039 0:1ed23ab1345f 112 {
va009039 0:1ed23ab1345f 113 //DBG("\npacket_type=%d\n", packet_type);
va009039 0:1ed23ab1345f 114 //DBG_HEX(packet, size);
va009039 0:1ed23ab1345f 115
va009039 0:1ed23ab1345f 116 int rc;
va009039 0:1ed23ab1345f 117 switch(packet_type){
va009039 0:1ed23ab1345f 118 case HCI_COMMAND_DATA_PACKET:
va009039 0:1ed23ab1345f 119 DBG_ASSERT(m_pDev);
va009039 0:1ed23ab1345f 120 DBG_BYTES("\nCMD", packet, size);
va009039 0:1ed23ab1345f 121 rc = m_pDev->controlSend(
va009039 0:1ed23ab1345f 122 USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_DEVICE,
va009039 0:1ed23ab1345f 123 0, 0, 0, packet, size);
va009039 0:1ed23ab1345f 124 DBG_ASSERT(rc == USBERR_OK);
va009039 0:1ed23ab1345f 125 return 0;
va009039 0:1ed23ab1345f 126 case HCI_ACL_DATA_PACKET:
va009039 0:1ed23ab1345f 127 DBG_ASSERT(m_pEpBulkOut);
va009039 0:1ed23ab1345f 128 DBG_BYTES("\nACL", packet, size);
va009039 0:1ed23ab1345f 129 rc = m_pEpBulkOut->transfer(packet, size);
va009039 0:1ed23ab1345f 130 DBG_ASSERT(rc == USBERR_PROCESSING);
va009039 0:1ed23ab1345f 131 while(m_pEpBulkOut->status() == USBERR_PROCESSING){
va009039 0:1ed23ab1345f 132 wait_us(1);
va009039 0:1ed23ab1345f 133 }
va009039 0:1ed23ab1345f 134 return 0;
va009039 0:1ed23ab1345f 135 default:
va009039 0:1ed23ab1345f 136 DBG_ASSERT(0);
va009039 0:1ed23ab1345f 137 return -1;
va009039 0:1ed23ab1345f 138 }
va009039 0:1ed23ab1345f 139 }
va009039 0:1ed23ab1345f 140
va009039 0:1ed23ab1345f 141
va009039 0:1ed23ab1345f 142 void usbbt::poll()
va009039 0:1ed23ab1345f 143 {
va009039 0:1ed23ab1345f 144 //DBG("m_int_seq=%d\n", m_int_seq);
va009039 0:1ed23ab1345f 145 int rc, len;
va009039 0:1ed23ab1345f 146 switch(m_int_seq) {
va009039 0:1ed23ab1345f 147 case 0:
va009039 0:1ed23ab1345f 148 m_int_seq++;
va009039 0:1ed23ab1345f 149 break;
va009039 0:1ed23ab1345f 150 case 1:
va009039 0:1ed23ab1345f 151 rc = m_pEpIntIn->transfer(m_int_buf, sizeof(m_int_buf));
va009039 0:1ed23ab1345f 152 DBG_ASSERT(rc == USBERR_PROCESSING);
va009039 0:1ed23ab1345f 153 m_int_seq++;
va009039 0:1ed23ab1345f 154 break;
va009039 0:1ed23ab1345f 155 case 2:
va009039 0:1ed23ab1345f 156 len = m_pEpIntIn->status();
va009039 0:1ed23ab1345f 157 if (len == USBERR_PROCESSING) {
va009039 0:1ed23ab1345f 158 break;
va009039 0:1ed23ab1345f 159 }
va009039 0:1ed23ab1345f 160 if (len >= 0) {
va009039 0:1ed23ab1345f 161 //DBG("len=%d\n", len);
va009039 0:1ed23ab1345f 162 //DBG_HEX(m_int_buf, len);
va009039 0:1ed23ab1345f 163 onPacket(HCI_EVENT_PACKET, m_int_buf, len);
va009039 0:1ed23ab1345f 164 m_int_seq = 0;
va009039 0:1ed23ab1345f 165 break;
va009039 0:1ed23ab1345f 166 }
va009039 0:1ed23ab1345f 167 DBG_ASSERT(0);
va009039 0:1ed23ab1345f 168 break;
va009039 0:1ed23ab1345f 169 }
va009039 0:1ed23ab1345f 170
va009039 0:1ed23ab1345f 171 switch(m_bulk_seq) {
va009039 0:1ed23ab1345f 172 case 0:
va009039 0:1ed23ab1345f 173 m_bulk_seq++;
va009039 0:1ed23ab1345f 174 break;
va009039 0:1ed23ab1345f 175 case 1:
va009039 0:1ed23ab1345f 176 rc = m_pEpBulkIn->transfer(m_bulk_buf, sizeof(m_bulk_buf));
va009039 0:1ed23ab1345f 177 DBG_ASSERT(rc == USBERR_PROCESSING);
va009039 0:1ed23ab1345f 178 m_bulk_seq++;
va009039 0:1ed23ab1345f 179 break;
va009039 0:1ed23ab1345f 180 case 2:
va009039 0:1ed23ab1345f 181 len = m_pEpBulkIn->status();
va009039 0:1ed23ab1345f 182 if (len == USBERR_PROCESSING) {
va009039 0:1ed23ab1345f 183 break;
va009039 0:1ed23ab1345f 184 }
va009039 0:1ed23ab1345f 185 if (len >= 0) {
va009039 0:1ed23ab1345f 186 //DBG("len=%d\n", len);
va009039 0:1ed23ab1345f 187 //DBG_HEX(m_bulk_buf, len);
va009039 0:1ed23ab1345f 188 onPacket(HCI_ACL_DATA_PACKET, m_bulk_buf, len);
va009039 0:1ed23ab1345f 189 m_bulk_seq = 0;
va009039 0:1ed23ab1345f 190 break;
va009039 0:1ed23ab1345f 191 }
va009039 0:1ed23ab1345f 192 DBG_ASSERT(0);
va009039 0:1ed23ab1345f 193 break;
va009039 0:1ed23ab1345f 194 }
va009039 0:1ed23ab1345f 195 }
va009039 0:1ed23ab1345f 196
va009039 0:1ed23ab1345f 197 void usbbt::onPacket(uint8_t packet_type, uint8_t* packet, uint16_t size)
va009039 0:1ed23ab1345f 198 {
va009039 0:1ed23ab1345f 199 DBG("\npacket_type=%d packet=%p size=%d\n", packet_type, packet, size);
va009039 0:1ed23ab1345f 200 DBG_HEX(packet, size);
va009039 0:1ed23ab1345f 201
va009039 0:1ed23ab1345f 202 if(m_pCbItem && m_pCbMeth)
va009039 0:1ed23ab1345f 203 (m_pCbItem->*m_pCbMeth)(packet_type, packet, size);
va009039 0:1ed23ab1345f 204 else if(m_pCb)
va009039 0:1ed23ab1345f 205 m_pCb(packet_type, packet, size);
va009039 0:1ed23ab1345f 206 }
va009039 0:1ed23ab1345f 207
va009039 0:1ed23ab1345f 208 void usbbt::setOnPacket( void (*pMethod)(uint8_t, uint8_t*, uint16_t) )
va009039 0:1ed23ab1345f 209 {
va009039 0:1ed23ab1345f 210 m_pCb = pMethod;
va009039 0:1ed23ab1345f 211 m_pCbItem = NULL;
va009039 0:1ed23ab1345f 212 m_pCbMeth = NULL;
va009039 0:1ed23ab1345f 213 }
va009039 0:1ed23ab1345f 214
va009039 0:1ed23ab1345f 215 void usbbt::clearOnPacket()
va009039 0:1ed23ab1345f 216 {
va009039 0:1ed23ab1345f 217 m_pCb = NULL;
va009039 0:1ed23ab1345f 218 m_pCbItem = NULL;
va009039 0:1ed23ab1345f 219 m_pCbMeth = NULL;
va009039 0:1ed23ab1345f 220 }