mbed base bard check program for BlueTooth USB dongle module (3 switches, 6 leds, I2C LCD, A/D)
Fork of BTstack by
Diff: usbbt/usbbt.cpp
- Revision:
- 0:1ed23ab1345f
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/usbbt/usbbt.cpp Tue Jun 26 14:27:45 2012 +0000 @@ -0,0 +1,220 @@ +#include "usbbt.h" +#define __DEBUG +#include "mydbg.h" +#include "Utils.h" + +usbbt::usbbt(int dongle) + : m_dongle(dongle),m_pEpIntIn(NULL),m_pEpBulkIn(NULL),m_pEpBulkOut(NULL), + m_int_seq(0),m_bulk_seq(0) +{ + +} + +int usbbt::setup(int timeout) +{ + for(int i = 0; i < 2; i++) { + m_pDev = m_pHost->getDeviceByClass(0xe0, m_dongle); + if (m_pDev || i > 0) { + break; + } + UsbErr rc = Usb_poll(); + if (rc == USBERR_PROCESSING) { + VERBOSE("%p USBERR_PROCESSING\n", this); + return -1; + } + } + DBG("m_pDev=%p\n", m_pDev); + if (m_pDev == NULL) { + VERBOSE("%p Bluetooth dongle(%d) NOT FOUND\n", this, m_dongle); + return -1; + } + DBG_ASSERT(m_pDev); + + ParseConfiguration(); + return 0; +} + +int usbbt::ParseConfiguration() +{ + UsbErr rc; + uint8_t ConfigDesc[9]; + int index = 0; + DBG_ASSERT(m_pDev); + rc = m_pDev->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, ConfigDesc, sizeof(ConfigDesc)); + DBG_ASSERT(rc == USBERR_OK); + DBG_BYTES("ConfigDescriptor 9bytes", ConfigDesc, sizeof(ConfigDesc)); + DBG_ASSERT(ConfigDesc[0] == 9); + DBG_ASSERT(ConfigDesc[1] == 0x02); + int wTotalLength = *((uint16_t*)&ConfigDesc[2]); + DBG("TotalLength: %d\n", wTotalLength); + int bConfigValue = ConfigDesc[5]; + DBG_ASSERT(bConfigValue == 1); + DBG("ConfigValue: %d\n", bConfigValue); + VERBOSE("MaxPower: %d mA\n", ConfigDesc[8]*2); + + uint8_t* buf = new uint8_t[wTotalLength]; + DBG_ASSERT(buf); + rc = m_pDev->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, buf, wTotalLength); + DBG_ASSERT(rc == USBERR_OK); + DBG_ASSERT(ConfigDesc[1] == 0x02); + for (int pos = 0; pos < wTotalLength; pos += buf[pos]) { + DBG_BYTES("CFG", buf+pos, buf[pos]); + int type = buf[pos+1]; + if (USB_DESCRIPTOR_TYPE_INTERFACE == type) { // 0x04 + DBG("InterfaceNumber: %d\n", buf[pos+2]); + DBG("AlternateSetting: %d\n", buf[pos+3]); + DBG("NumEndpoint: %d\n", buf[pos+4]); + VERBOSE("InterfaceClass: %02X\n", buf[pos+5]); + VERBOSE("InterfaceSubClass: %02X\n", buf[pos+6]); + VERBOSE("InterfaceProtocol: %02X\n", buf[pos+7]); + DBG_ASSERT(buf[pos+6] == 0x01); + DBG_ASSERT(buf[pos+7] == 0x01); + } + if (USB_DESCRIPTOR_TYPE_ENDPOINT == type) { + DBG_ASSERT(buf[pos] == 7); + uint8_t att = buf[pos+3]; + uint8_t ep = buf[pos+2]; + bool dir = ep & 0x80; // true=IN + uint16_t size = LE16(buf+pos+4); + DBG("EndpointAddress: %02X\n", ep); + DBG("Attribute: %02X\n", att); + DBG("MaxPacketSize: %d\n", size); + UsbEndpoint* pEp = new UsbEndpoint(m_pDev, ep, dir, att == 3 ? USB_INT : USB_BULK, size); + DBG_ASSERT(pEp); + if (att == 3) { // interrupt + if (m_pEpIntIn == NULL) { + m_pEpIntIn = pEp; + } + } else if (att == 2) { // bulk + if (dir) { + if (m_pEpBulkIn == NULL) { + m_pEpBulkIn = pEp; + } + } else { + if (m_pEpBulkOut == NULL) { + m_pEpBulkOut = pEp; + } + } + } + } + if (m_pEpIntIn && m_pEpBulkIn && m_pEpBulkOut) { // cut off + break; + } + } + delete[] buf; + DBG_ASSERT(m_pEpIntIn); + DBG_ASSERT(m_pEpBulkIn); + DBG_ASSERT(m_pEpBulkOut); + return 0; +} + +int usbbt::send_packet(uint8_t packet_type, uint8_t* packet, int size) +{ + //DBG("\npacket_type=%d\n", packet_type); + //DBG_HEX(packet, size); + + int rc; + switch(packet_type){ + case HCI_COMMAND_DATA_PACKET: + DBG_ASSERT(m_pDev); + DBG_BYTES("\nCMD", packet, size); + rc = m_pDev->controlSend( + USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_DEVICE, + 0, 0, 0, packet, size); + DBG_ASSERT(rc == USBERR_OK); + return 0; + case HCI_ACL_DATA_PACKET: + DBG_ASSERT(m_pEpBulkOut); + DBG_BYTES("\nACL", packet, size); + rc = m_pEpBulkOut->transfer(packet, size); + DBG_ASSERT(rc == USBERR_PROCESSING); + while(m_pEpBulkOut->status() == USBERR_PROCESSING){ + wait_us(1); + } + return 0; + default: + DBG_ASSERT(0); + return -1; + } +} + + +void usbbt::poll() +{ + //DBG("m_int_seq=%d\n", m_int_seq); + int rc, len; + switch(m_int_seq) { + case 0: + m_int_seq++; + break; + case 1: + rc = m_pEpIntIn->transfer(m_int_buf, sizeof(m_int_buf)); + DBG_ASSERT(rc == USBERR_PROCESSING); + m_int_seq++; + break; + case 2: + len = m_pEpIntIn->status(); + if (len == USBERR_PROCESSING) { + break; + } + if (len >= 0) { + //DBG("len=%d\n", len); + //DBG_HEX(m_int_buf, len); + onPacket(HCI_EVENT_PACKET, m_int_buf, len); + m_int_seq = 0; + break; + } + DBG_ASSERT(0); + break; + } + + switch(m_bulk_seq) { + case 0: + m_bulk_seq++; + break; + case 1: + rc = m_pEpBulkIn->transfer(m_bulk_buf, sizeof(m_bulk_buf)); + DBG_ASSERT(rc == USBERR_PROCESSING); + m_bulk_seq++; + break; + case 2: + len = m_pEpBulkIn->status(); + if (len == USBERR_PROCESSING) { + break; + } + if (len >= 0) { + //DBG("len=%d\n", len); + //DBG_HEX(m_bulk_buf, len); + onPacket(HCI_ACL_DATA_PACKET, m_bulk_buf, len); + m_bulk_seq = 0; + break; + } + DBG_ASSERT(0); + break; + } +} + +void usbbt::onPacket(uint8_t packet_type, uint8_t* packet, uint16_t size) +{ + DBG("\npacket_type=%d packet=%p size=%d\n", packet_type, packet, size); + DBG_HEX(packet, size); + + if(m_pCbItem && m_pCbMeth) + (m_pCbItem->*m_pCbMeth)(packet_type, packet, size); + else if(m_pCb) + m_pCb(packet_type, packet, size); +} + +void usbbt::setOnPacket( void (*pMethod)(uint8_t, uint8_t*, uint16_t) ) +{ + m_pCb = pMethod; + m_pCbItem = NULL; + m_pCbMeth = NULL; +} + +void usbbt::clearOnPacket() +{ + m_pCb = NULL; + m_pCbItem = NULL; + m_pCbMeth = NULL; +}