mbed base bard check program for BlueTooth USB dongle module (3 switches, 6 leds, I2C LCD, A/D)
Fork of BTstack by
USBHostBTstack/USBHostBTstack.cpp@3:7b7d1273e2d5, 2016-10-17 (annotated)
- Committer:
- tamaki
- Date:
- Mon Oct 17 00:25:18 2016 +0000
- Revision:
- 3:7b7d1273e2d5
- Parent:
- 2:871b41f4789e
mbed base bard check program
; for BlueTooth USB dongle module
; (3 switches, 6 leds, I2C LCD, A/D)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 2:871b41f4789e | 1 | // USBHostBTstack.cpp |
va009039 | 1:b657594559be | 2 | #include "USBHostBTstack.h" |
va009039 | 1:b657594559be | 3 | #include "dbg.h" |
va009039 | 1:b657594559be | 4 | |
va009039 | 2:871b41f4789e | 5 | //#define BTSTACK_DEBUG |
va009039 | 1:b657594559be | 6 | |
va009039 | 1:b657594559be | 7 | #ifdef BTSTACK_DEBUG |
va009039 | 1:b657594559be | 8 | #define BT_DBG(x, ...) std::printf("[%s:%d]"x"\r\n", __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); |
va009039 | 2:871b41f4789e | 9 | #define BT_DBG_BYTES(STR,BUF,LEN) _debug_bytes(__PRETTY_FUNCTION__,__LINE__,STR,BUF,LEN) |
va009039 | 1:b657594559be | 10 | #else |
va009039 | 1:b657594559be | 11 | #define BT_DBG(...) while(0); |
va009039 | 2:871b41f4789e | 12 | #define BT_DBG_BYTES(S,BUF,LEN) while(0); |
va009039 | 1:b657594559be | 13 | #endif |
va009039 | 1:b657594559be | 14 | |
va009039 | 1:b657594559be | 15 | #define HCI_COMMAND_DATA_PACKET 0x01 |
va009039 | 1:b657594559be | 16 | #define HCI_ACL_DATA_PACKET 0x02 |
va009039 | 1:b657594559be | 17 | #define HCI_SCO_DATA_PACKET 0x03 |
va009039 | 1:b657594559be | 18 | #define HCI_EVENT_PACKET 0x04 |
va009039 | 1:b657594559be | 19 | |
va009039 | 1:b657594559be | 20 | USBHostBTstack::USBHostBTstack() |
va009039 | 1:b657594559be | 21 | { |
va009039 | 1:b657594559be | 22 | host = USBHost::getHostInst(); |
va009039 | 1:b657594559be | 23 | init(); |
va009039 | 1:b657594559be | 24 | m_pCb = NULL; |
va009039 | 1:b657594559be | 25 | } |
va009039 | 1:b657594559be | 26 | |
va009039 | 1:b657594559be | 27 | void USBHostBTstack::init() |
va009039 | 1:b657594559be | 28 | { |
va009039 | 1:b657594559be | 29 | BT_DBG(""); |
va009039 | 1:b657594559be | 30 | dev = NULL; |
va009039 | 1:b657594559be | 31 | int_in = NULL; |
va009039 | 1:b657594559be | 32 | bulk_in = NULL; |
va009039 | 1:b657594559be | 33 | bulk_out = NULL; |
va009039 | 1:b657594559be | 34 | btstack_intf = -1; |
va009039 | 1:b657594559be | 35 | btstack_device_found = false; |
va009039 | 1:b657594559be | 36 | dev_connected = false; |
va009039 | 1:b657594559be | 37 | ep_int_in = false; |
va009039 | 1:b657594559be | 38 | ep_bulk_in = false; |
va009039 | 1:b657594559be | 39 | ep_bulk_out = false; |
va009039 | 1:b657594559be | 40 | } |
va009039 | 1:b657594559be | 41 | |
va009039 | 1:b657594559be | 42 | bool USBHostBTstack::connected() |
va009039 | 1:b657594559be | 43 | { |
va009039 | 1:b657594559be | 44 | return dev_connected; |
va009039 | 1:b657594559be | 45 | } |
va009039 | 1:b657594559be | 46 | |
va009039 | 1:b657594559be | 47 | bool USBHostBTstack::connect() |
va009039 | 1:b657594559be | 48 | { |
va009039 | 1:b657594559be | 49 | if (dev_connected) { |
va009039 | 1:b657594559be | 50 | return true; |
va009039 | 1:b657594559be | 51 | } |
va009039 | 1:b657594559be | 52 | |
va009039 | 1:b657594559be | 53 | for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { |
va009039 | 1:b657594559be | 54 | if ((dev = host->getDevice(i)) != NULL) { |
va009039 | 1:b657594559be | 55 | |
va009039 | 1:b657594559be | 56 | BT_DBG("Trying to connect BTstack device\r\n"); |
va009039 | 1:b657594559be | 57 | |
va009039 | 1:b657594559be | 58 | if(host->enumerate(dev, this)) { |
va009039 | 1:b657594559be | 59 | break; |
va009039 | 1:b657594559be | 60 | } |
va009039 | 1:b657594559be | 61 | if (btstack_device_found) { |
va009039 | 1:b657594559be | 62 | int_in = dev->getEndpoint(btstack_intf, INTERRUPT_ENDPOINT, IN); |
va009039 | 1:b657594559be | 63 | bulk_in = dev->getEndpoint(btstack_intf, BULK_ENDPOINT, IN); |
va009039 | 1:b657594559be | 64 | bulk_out = dev->getEndpoint(btstack_intf, BULK_ENDPOINT, OUT); |
va009039 | 1:b657594559be | 65 | if (!int_in || !bulk_in || !bulk_out) { |
va009039 | 1:b657594559be | 66 | continue; |
va009039 | 1:b657594559be | 67 | } |
va009039 | 1:b657594559be | 68 | USB_INFO("New BTstack device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, btstack_intf); |
va009039 | 1:b657594559be | 69 | dev->setName("BTstack", btstack_intf); |
va009039 | 1:b657594559be | 70 | host->registerDriver(dev, btstack_intf, this, &USBHostBTstack::init); |
va009039 | 1:b657594559be | 71 | |
va009039 | 1:b657594559be | 72 | int_in->attach(this, &USBHostBTstack::int_rxHandler); |
va009039 | 1:b657594559be | 73 | host->interruptRead(dev, int_in, int_report, int_in->getSize(), false); |
va009039 | 1:b657594559be | 74 | |
va009039 | 1:b657594559be | 75 | bulk_in->attach(this, &USBHostBTstack::bulk_rxHandler); |
va009039 | 1:b657594559be | 76 | host->bulkRead(dev, bulk_in, bulk_report, bulk_in->getSize(), false); |
va009039 | 1:b657594559be | 77 | |
va009039 | 1:b657594559be | 78 | dev_connected = true; |
va009039 | 1:b657594559be | 79 | return true; |
va009039 | 1:b657594559be | 80 | } |
va009039 | 1:b657594559be | 81 | } |
va009039 | 1:b657594559be | 82 | } |
va009039 | 1:b657594559be | 83 | init(); |
va009039 | 1:b657594559be | 84 | return false; |
va009039 | 1:b657594559be | 85 | } |
va009039 | 1:b657594559be | 86 | |
va009039 | 2:871b41f4789e | 87 | void USBHostBTstack::int_rxHandler() |
va009039 | 2:871b41f4789e | 88 | { |
va009039 | 1:b657594559be | 89 | int len = int_in->getLengthTransferred(); |
va009039 | 2:871b41f4789e | 90 | BT_DBG_BYTES("HCI_EVT:", int_report, len); |
va009039 | 2:871b41f4789e | 91 | Packet* pkt = mail_box.alloc(); |
va009039 | 2:871b41f4789e | 92 | TEST_ASSERT(pkt); |
va009039 | 2:871b41f4789e | 93 | pkt->type = HCI_EVENT_PACKET; |
va009039 | 2:871b41f4789e | 94 | pkt->buf = int_report; |
va009039 | 2:871b41f4789e | 95 | pkt->len = len; |
va009039 | 2:871b41f4789e | 96 | mail_box.put(pkt); |
va009039 | 1:b657594559be | 97 | } |
va009039 | 1:b657594559be | 98 | |
va009039 | 2:871b41f4789e | 99 | void USBHostBTstack::bulk_rxHandler() |
va009039 | 2:871b41f4789e | 100 | { |
va009039 | 1:b657594559be | 101 | int len = bulk_in->getLengthTransferred(); |
va009039 | 2:871b41f4789e | 102 | BT_DBG_BYTES("ACL_RCV:", bulk_report, len); |
va009039 | 2:871b41f4789e | 103 | Packet* pkt = mail_box.alloc(); |
va009039 | 2:871b41f4789e | 104 | TEST_ASSERT(pkt); |
va009039 | 2:871b41f4789e | 105 | pkt->type = HCI_ACL_DATA_PACKET; |
va009039 | 2:871b41f4789e | 106 | pkt->buf = bulk_report; |
va009039 | 2:871b41f4789e | 107 | pkt->len = len; |
va009039 | 2:871b41f4789e | 108 | mail_box.put(pkt); |
va009039 | 1:b657594559be | 109 | } |
va009039 | 1:b657594559be | 110 | |
va009039 | 1:b657594559be | 111 | /*virtual*/ void USBHostBTstack::setVidPid(uint16_t vid, uint16_t pid) |
va009039 | 1:b657594559be | 112 | { |
va009039 | 1:b657594559be | 113 | BT_DBG("vid:%04x,pid:%04x", vid, pid); |
va009039 | 1:b657594559be | 114 | } |
va009039 | 1:b657594559be | 115 | |
va009039 | 1:b657594559be | 116 | /*virtual*/ bool USBHostBTstack::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed |
va009039 | 1:b657594559be | 117 | { |
va009039 | 1:b657594559be | 118 | BT_DBG("intf_nb=%d,intf_class=%02X,intf_subclass=%d,intf_protocol=%d", intf_nb, intf_class, intf_subclass, intf_protocol); |
va009039 | 1:b657594559be | 119 | if ((btstack_intf == -1) && intf_class == 0xe0) { |
va009039 | 1:b657594559be | 120 | btstack_intf = intf_nb; |
va009039 | 1:b657594559be | 121 | return true; |
va009039 | 1:b657594559be | 122 | } |
va009039 | 1:b657594559be | 123 | return false; |
va009039 | 1:b657594559be | 124 | } |
va009039 | 1:b657594559be | 125 | |
va009039 | 1:b657594559be | 126 | /*virtual*/ bool USBHostBTstack::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used |
va009039 | 1:b657594559be | 127 | { |
va009039 | 1:b657594559be | 128 | BT_DBG("intf_nb:%d,type:%d,dir:%d",intf_nb, type, dir); |
va009039 | 1:b657594559be | 129 | if (intf_nb == btstack_intf) { |
va009039 | 1:b657594559be | 130 | if (ep_int_in == false && type == INTERRUPT_ENDPOINT && dir == IN) { |
va009039 | 1:b657594559be | 131 | ep_int_in = true; |
va009039 | 1:b657594559be | 132 | } else if (ep_bulk_in == false && type == BULK_ENDPOINT && dir == IN) { |
va009039 | 1:b657594559be | 133 | ep_bulk_in = true; |
va009039 | 1:b657594559be | 134 | } else if (ep_bulk_out == false && type == BULK_ENDPOINT && dir == OUT) { |
va009039 | 1:b657594559be | 135 | ep_bulk_out = true; |
va009039 | 1:b657594559be | 136 | } else { |
va009039 | 1:b657594559be | 137 | return false; |
va009039 | 1:b657594559be | 138 | } |
va009039 | 1:b657594559be | 139 | if (ep_int_in && ep_bulk_in && ep_bulk_out) { |
va009039 | 1:b657594559be | 140 | btstack_device_found = true; |
va009039 | 1:b657594559be | 141 | } |
va009039 | 1:b657594559be | 142 | return true; |
va009039 | 1:b657594559be | 143 | } |
va009039 | 1:b657594559be | 144 | return false; |
va009039 | 1:b657594559be | 145 | } |
va009039 | 1:b657594559be | 146 | |
va009039 | 1:b657594559be | 147 | int USBHostBTstack::open() |
va009039 | 1:b657594559be | 148 | { |
va009039 | 1:b657594559be | 149 | BT_DBG("%p", this); |
va009039 | 1:b657594559be | 150 | while(!connected()) { |
va009039 | 1:b657594559be | 151 | if (connect()) { |
va009039 | 1:b657594559be | 152 | break; |
va009039 | 1:b657594559be | 153 | } |
va009039 | 1:b657594559be | 154 | Thread::wait(500); |
va009039 | 1:b657594559be | 155 | } |
va009039 | 1:b657594559be | 156 | return 0; |
va009039 | 1:b657594559be | 157 | } |
va009039 | 1:b657594559be | 158 | |
va009039 | 1:b657594559be | 159 | int USBHostBTstack::send_packet(uint8_t packet_type, uint8_t* packet, int size) |
va009039 | 1:b657594559be | 160 | { |
va009039 | 1:b657594559be | 161 | USB_TYPE res; |
va009039 | 1:b657594559be | 162 | switch(packet_type){ |
va009039 | 1:b657594559be | 163 | case HCI_COMMAND_DATA_PACKET: |
va009039 | 2:871b41f4789e | 164 | BT_DBG_BYTES("HCI_CMD:", packet, size); |
va009039 | 1:b657594559be | 165 | res = host->controlWrite(dev, |
va009039 | 1:b657594559be | 166 | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_DEVICE, |
va009039 | 1:b657594559be | 167 | 0, 0, 0, packet, size); |
va009039 | 1:b657594559be | 168 | TEST_ASSERT(res == USB_TYPE_OK); |
va009039 | 1:b657594559be | 169 | break; |
va009039 | 1:b657594559be | 170 | case HCI_ACL_DATA_PACKET: |
va009039 | 2:871b41f4789e | 171 | BT_DBG_BYTES("ACL_SND:", packet, size); |
va009039 | 1:b657594559be | 172 | res = host->bulkWrite(dev, bulk_out, packet, size); |
va009039 | 1:b657594559be | 173 | TEST_ASSERT(res == USB_TYPE_OK); |
va009039 | 1:b657594559be | 174 | break; |
va009039 | 1:b657594559be | 175 | default: |
va009039 | 1:b657594559be | 176 | TEST_ASSERT(0); |
va009039 | 1:b657594559be | 177 | } |
va009039 | 1:b657594559be | 178 | return 0; |
va009039 | 1:b657594559be | 179 | } |
va009039 | 1:b657594559be | 180 | |
va009039 | 1:b657594559be | 181 | void USBHostBTstack::register_packet_handler(void (*pMethod)(uint8_t, uint8_t*, uint16_t) ) |
va009039 | 1:b657594559be | 182 | { |
va009039 | 1:b657594559be | 183 | BT_DBG("pMethod: %p", pMethod); |
va009039 | 1:b657594559be | 184 | m_pCb = pMethod; |
va009039 | 1:b657594559be | 185 | } |
va009039 | 1:b657594559be | 186 | |
va009039 | 2:871b41f4789e | 187 | void USBHostBTstack::poll() |
va009039 | 2:871b41f4789e | 188 | { |
va009039 | 2:871b41f4789e | 189 | osEvent evt = mail_box.get(0); // non-blocking |
va009039 | 2:871b41f4789e | 190 | if (evt.status == osEventMail) { |
va009039 | 2:871b41f4789e | 191 | Packet* pkt = reinterpret_cast<Packet*>(evt.value.p); |
va009039 | 2:871b41f4789e | 192 | TEST_ASSERT(pkt); |
va009039 | 2:871b41f4789e | 193 | //BT_DBG("type: %d, buf: %p, len: %d", pkt->type, pkt->buf, pkt->len); |
va009039 | 2:871b41f4789e | 194 | if (m_pCb) { |
va009039 | 2:871b41f4789e | 195 | m_pCb(pkt->type, pkt->buf, pkt->len); |
va009039 | 2:871b41f4789e | 196 | } |
va009039 | 2:871b41f4789e | 197 | if (dev) { |
va009039 | 2:871b41f4789e | 198 | if (pkt->type == HCI_EVENT_PACKET) { |
va009039 | 2:871b41f4789e | 199 | host->interruptRead(dev, int_in, int_report, int_in->getSize(), false); |
va009039 | 2:871b41f4789e | 200 | } else { // HCI_ACL_DATA_PACKET |
va009039 | 2:871b41f4789e | 201 | host->bulkRead(dev, bulk_in, bulk_report, bulk_in->getSize(), false); |
va009039 | 2:871b41f4789e | 202 | } |
va009039 | 2:871b41f4789e | 203 | } |
va009039 | 2:871b41f4789e | 204 | mail_box.free(pkt); |
va009039 | 2:871b41f4789e | 205 | } |
va009039 | 2:871b41f4789e | 206 | } |
va009039 | 2:871b41f4789e | 207 | |
va009039 | 2:871b41f4789e | 208 | void _debug_bytes(const char* pretty, int line, const char* s, uint8_t* buf, int len) |
va009039 | 2:871b41f4789e | 209 | { |
va009039 | 2:871b41f4789e | 210 | printf("[%s:%d]\n%s", pretty, line, s); |
va009039 | 2:871b41f4789e | 211 | for(int i = 0; i < len; i++) { |
va009039 | 2:871b41f4789e | 212 | printf(" %02x", buf[i]); |
va009039 | 2:871b41f4789e | 213 | } |
va009039 | 2:871b41f4789e | 214 | printf("\n"); |
va009039 | 2:871b41f4789e | 215 | } |