BTstack for EA LPC4088 QSB example program
Dependencies: LPC4088-USBHost mbed
Fork of KL46Z-BTstack_example by
The usage is the same as KL46Z-BTstack_example.
使い方はKL46Z-BTstack_exampleと同じです。
KL46Z-USBHostBTstack/USBHostBTstack.cpp@5:56897116e6b0, 2014-02-05 (annotated)
- Committer:
- va009039
- Date:
- Wed Feb 05 14:56:10 2014 +0000
- Revision:
- 5:56897116e6b0
- Parent:
- 4:cf1b23f4dcd4
update KL46Z-USBHost library.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 3:54f9b5e0d12d | 1 | // USBHostBTstack.cpp |
va009039 | 3:54f9b5e0d12d | 2 | #include "USBHostBTstack.h" |
va009039 | 3:54f9b5e0d12d | 3 | |
va009039 | 3:54f9b5e0d12d | 4 | //#define BTSTACK_DEBUG |
va009039 | 3:54f9b5e0d12d | 5 | |
va009039 | 3:54f9b5e0d12d | 6 | #ifdef BTSTACK_DEBUG |
va009039 | 3:54f9b5e0d12d | 7 | #define BT_DBG(x, ...) std::printf("[%s:%d]"x"\r\n", __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); |
va009039 | 3:54f9b5e0d12d | 8 | #define BT_DBG_BYTES(STR,BUF,LEN) _debug_bytes(__PRETTY_FUNCTION__,__LINE__,STR,BUF,LEN) |
va009039 | 3:54f9b5e0d12d | 9 | #else |
va009039 | 3:54f9b5e0d12d | 10 | #define BT_DBG(...) while(0); |
va009039 | 3:54f9b5e0d12d | 11 | #define BT_DBG_BYTES(S,BUF,LEN) while(0); |
va009039 | 3:54f9b5e0d12d | 12 | #endif |
va009039 | 4:cf1b23f4dcd4 | 13 | #define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\r\n");}while(0); |
va009039 | 3:54f9b5e0d12d | 14 | |
va009039 | 3:54f9b5e0d12d | 15 | #define HCI_COMMAND_DATA_PACKET 0x01 |
va009039 | 3:54f9b5e0d12d | 16 | #define HCI_ACL_DATA_PACKET 0x02 |
va009039 | 3:54f9b5e0d12d | 17 | #define HCI_SCO_DATA_PACKET 0x03 |
va009039 | 3:54f9b5e0d12d | 18 | #define HCI_EVENT_PACKET 0x04 |
va009039 | 3:54f9b5e0d12d | 19 | |
va009039 | 3:54f9b5e0d12d | 20 | USBHostBTstack::USBHostBTstack() |
va009039 | 3:54f9b5e0d12d | 21 | { |
va009039 | 3:54f9b5e0d12d | 22 | host = USBHost::getHostInst(); |
va009039 | 4:cf1b23f4dcd4 | 23 | init(); |
va009039 | 3:54f9b5e0d12d | 24 | m_pCb = NULL; |
va009039 | 3:54f9b5e0d12d | 25 | } |
va009039 | 3:54f9b5e0d12d | 26 | |
va009039 | 4:cf1b23f4dcd4 | 27 | void USBHostBTstack::init() |
va009039 | 4:cf1b23f4dcd4 | 28 | { |
va009039 | 4:cf1b23f4dcd4 | 29 | BT_DBG(""); |
va009039 | 4:cf1b23f4dcd4 | 30 | dev = NULL; |
va009039 | 4:cf1b23f4dcd4 | 31 | int_in = NULL; |
va009039 | 4:cf1b23f4dcd4 | 32 | bulk_in = NULL; |
va009039 | 4:cf1b23f4dcd4 | 33 | bulk_out = NULL; |
va009039 | 4:cf1b23f4dcd4 | 34 | btstack_intf = -1; |
va009039 | 4:cf1b23f4dcd4 | 35 | btstack_device_found = false; |
va009039 | 4:cf1b23f4dcd4 | 36 | dev_connected = false; |
va009039 | 4:cf1b23f4dcd4 | 37 | ep_int_in = false; |
va009039 | 4:cf1b23f4dcd4 | 38 | ep_bulk_in = false; |
va009039 | 4:cf1b23f4dcd4 | 39 | ep_bulk_out = false; |
va009039 | 4:cf1b23f4dcd4 | 40 | } |
va009039 | 4:cf1b23f4dcd4 | 41 | |
va009039 | 3:54f9b5e0d12d | 42 | bool USBHostBTstack::connected() |
va009039 | 3:54f9b5e0d12d | 43 | { |
va009039 | 4:cf1b23f4dcd4 | 44 | return dev_connected; |
va009039 | 3:54f9b5e0d12d | 45 | } |
va009039 | 3:54f9b5e0d12d | 46 | |
va009039 | 3:54f9b5e0d12d | 47 | bool USBHostBTstack::connect() |
va009039 | 3:54f9b5e0d12d | 48 | { |
va009039 | 4:cf1b23f4dcd4 | 49 | if (dev_connected) { |
va009039 | 4:cf1b23f4dcd4 | 50 | return true; |
va009039 | 4:cf1b23f4dcd4 | 51 | } |
va009039 | 4:cf1b23f4dcd4 | 52 | |
va009039 | 4:cf1b23f4dcd4 | 53 | for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { |
va009039 | 4:cf1b23f4dcd4 | 54 | if ((dev = host->getDevice(i)) != NULL) { |
va009039 | 4:cf1b23f4dcd4 | 55 | |
va009039 | 4:cf1b23f4dcd4 | 56 | BT_DBG("Trying to connect BTstack device\r\n"); |
va009039 | 4:cf1b23f4dcd4 | 57 | |
va009039 | 4:cf1b23f4dcd4 | 58 | if(host->enumerate(dev, this)) { |
va009039 | 4:cf1b23f4dcd4 | 59 | break; |
va009039 | 4:cf1b23f4dcd4 | 60 | } |
va009039 | 4:cf1b23f4dcd4 | 61 | if (btstack_device_found) { |
va009039 | 4:cf1b23f4dcd4 | 62 | int_in = dev->getEndpoint(btstack_intf, INTERRUPT_ENDPOINT, IN); |
va009039 | 4:cf1b23f4dcd4 | 63 | bulk_in = dev->getEndpoint(btstack_intf, BULK_ENDPOINT, IN); |
va009039 | 4:cf1b23f4dcd4 | 64 | bulk_out = dev->getEndpoint(btstack_intf, BULK_ENDPOINT, OUT); |
va009039 | 4:cf1b23f4dcd4 | 65 | if (!int_in || !bulk_in || !bulk_out) { |
va009039 | 4:cf1b23f4dcd4 | 66 | continue; |
va009039 | 4:cf1b23f4dcd4 | 67 | } |
va009039 | 4:cf1b23f4dcd4 | 68 | USB_INFO("New BTstack device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, btstack_intf); |
va009039 | 4:cf1b23f4dcd4 | 69 | //dev->setName("BTstack", btstack_intf); |
va009039 | 4:cf1b23f4dcd4 | 70 | //host->registerDriver(dev, btstack_intf, this, &USBHostBTstack::init); |
va009039 | 4:cf1b23f4dcd4 | 71 | |
va009039 | 4:cf1b23f4dcd4 | 72 | //int_in->attach(this, &USBHostBTstack::int_rxHandler); |
va009039 | 4:cf1b23f4dcd4 | 73 | //host->interruptRead(dev, int_in, int_report, int_in->getSize(), false); |
va009039 | 4:cf1b23f4dcd4 | 74 | |
va009039 | 4:cf1b23f4dcd4 | 75 | //bulk_in->attach(this, &USBHostBTstack::bulk_rxHandler); |
va009039 | 4:cf1b23f4dcd4 | 76 | //host->bulkRead(dev, bulk_in, bulk_report, bulk_in->getSize(), false); |
va009039 | 4:cf1b23f4dcd4 | 77 | |
va009039 | 4:cf1b23f4dcd4 | 78 | dev_connected = true; |
va009039 | 4:cf1b23f4dcd4 | 79 | return true; |
va009039 | 4:cf1b23f4dcd4 | 80 | } |
va009039 | 4:cf1b23f4dcd4 | 81 | } |
va009039 | 4:cf1b23f4dcd4 | 82 | } |
va009039 | 4:cf1b23f4dcd4 | 83 | init(); |
va009039 | 4:cf1b23f4dcd4 | 84 | return false; |
va009039 | 3:54f9b5e0d12d | 85 | } |
va009039 | 3:54f9b5e0d12d | 86 | |
va009039 | 4:cf1b23f4dcd4 | 87 | /*virtual*/ void USBHostBTstack::setVidPid(uint16_t vid, uint16_t pid) |
va009039 | 4:cf1b23f4dcd4 | 88 | { |
va009039 | 4:cf1b23f4dcd4 | 89 | BT_DBG("vid:%04x,pid:%04x", vid, pid); |
va009039 | 4:cf1b23f4dcd4 | 90 | } |
va009039 | 4:cf1b23f4dcd4 | 91 | |
va009039 | 4:cf1b23f4dcd4 | 92 | /*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 | 4:cf1b23f4dcd4 | 93 | { |
va009039 | 4:cf1b23f4dcd4 | 94 | BT_DBG("intf_nb=%d,intf_class=%02X,intf_subclass=%d,intf_protocol=%d", intf_nb, intf_class, intf_subclass, intf_protocol); |
va009039 | 4:cf1b23f4dcd4 | 95 | if ((btstack_intf == -1) && intf_class == 0xe0) { |
va009039 | 4:cf1b23f4dcd4 | 96 | btstack_intf = intf_nb; |
va009039 | 4:cf1b23f4dcd4 | 97 | return true; |
va009039 | 4:cf1b23f4dcd4 | 98 | } |
va009039 | 4:cf1b23f4dcd4 | 99 | return false; |
va009039 | 4:cf1b23f4dcd4 | 100 | } |
va009039 | 4:cf1b23f4dcd4 | 101 | |
va009039 | 4:cf1b23f4dcd4 | 102 | /*virtual*/ bool USBHostBTstack::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used |
va009039 | 4:cf1b23f4dcd4 | 103 | { |
va009039 | 4:cf1b23f4dcd4 | 104 | BT_DBG("intf_nb:%d,type:%d,dir:%d",intf_nb, type, dir); |
va009039 | 4:cf1b23f4dcd4 | 105 | if (intf_nb == btstack_intf) { |
va009039 | 4:cf1b23f4dcd4 | 106 | if (ep_int_in == false && type == INTERRUPT_ENDPOINT && dir == IN) { |
va009039 | 4:cf1b23f4dcd4 | 107 | ep_int_in = true; |
va009039 | 4:cf1b23f4dcd4 | 108 | } else if (ep_bulk_in == false && type == BULK_ENDPOINT && dir == IN) { |
va009039 | 4:cf1b23f4dcd4 | 109 | ep_bulk_in = true; |
va009039 | 4:cf1b23f4dcd4 | 110 | } else if (ep_bulk_out == false && type == BULK_ENDPOINT && dir == OUT) { |
va009039 | 4:cf1b23f4dcd4 | 111 | ep_bulk_out = true; |
va009039 | 4:cf1b23f4dcd4 | 112 | } else { |
va009039 | 4:cf1b23f4dcd4 | 113 | return false; |
va009039 | 4:cf1b23f4dcd4 | 114 | } |
va009039 | 4:cf1b23f4dcd4 | 115 | if (ep_int_in && ep_bulk_in && ep_bulk_out) { |
va009039 | 4:cf1b23f4dcd4 | 116 | btstack_device_found = true; |
va009039 | 4:cf1b23f4dcd4 | 117 | } |
va009039 | 4:cf1b23f4dcd4 | 118 | return true; |
va009039 | 4:cf1b23f4dcd4 | 119 | } |
va009039 | 4:cf1b23f4dcd4 | 120 | return false; |
va009039 | 4:cf1b23f4dcd4 | 121 | } |
va009039 | 4:cf1b23f4dcd4 | 122 | |
va009039 | 3:54f9b5e0d12d | 123 | int USBHostBTstack::open() |
va009039 | 3:54f9b5e0d12d | 124 | { |
va009039 | 4:cf1b23f4dcd4 | 125 | BT_DBG("%p", this); |
va009039 | 4:cf1b23f4dcd4 | 126 | if (!connect()) { |
va009039 | 4:cf1b23f4dcd4 | 127 | error("Bluetooth not found.\n"); |
va009039 | 4:cf1b23f4dcd4 | 128 | } |
va009039 | 3:54f9b5e0d12d | 129 | return 0; |
va009039 | 3:54f9b5e0d12d | 130 | } |
va009039 | 3:54f9b5e0d12d | 131 | |
va009039 | 3:54f9b5e0d12d | 132 | int USBHostBTstack::send_packet(uint8_t packet_type, uint8_t* packet, int size) |
va009039 | 3:54f9b5e0d12d | 133 | { |
va009039 | 3:54f9b5e0d12d | 134 | USB_TYPE res; |
va009039 | 3:54f9b5e0d12d | 135 | switch(packet_type){ |
va009039 | 3:54f9b5e0d12d | 136 | case HCI_COMMAND_DATA_PACKET: |
va009039 | 3:54f9b5e0d12d | 137 | BT_DBG_BYTES("HCI_CMD:", packet, size); |
va009039 | 3:54f9b5e0d12d | 138 | res = host->controlWrite(dev, |
va009039 | 3:54f9b5e0d12d | 139 | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_CLASS | USB_RECIPIENT_DEVICE, |
va009039 | 3:54f9b5e0d12d | 140 | 0, 0, 0, packet, size); |
va009039 | 3:54f9b5e0d12d | 141 | TEST_ASSERT(res == USB_TYPE_OK); |
va009039 | 3:54f9b5e0d12d | 142 | break; |
va009039 | 3:54f9b5e0d12d | 143 | case HCI_ACL_DATA_PACKET: |
va009039 | 3:54f9b5e0d12d | 144 | BT_DBG_BYTES("ACL_SND:", packet, size); |
va009039 | 3:54f9b5e0d12d | 145 | res = host->bulkWrite(dev, bulk_out, packet, size); |
va009039 | 3:54f9b5e0d12d | 146 | TEST_ASSERT(res == USB_TYPE_OK); |
va009039 | 3:54f9b5e0d12d | 147 | break; |
va009039 | 3:54f9b5e0d12d | 148 | default: |
va009039 | 3:54f9b5e0d12d | 149 | TEST_ASSERT(0); |
va009039 | 3:54f9b5e0d12d | 150 | } |
va009039 | 3:54f9b5e0d12d | 151 | return 0; |
va009039 | 3:54f9b5e0d12d | 152 | } |
va009039 | 3:54f9b5e0d12d | 153 | |
va009039 | 3:54f9b5e0d12d | 154 | void USBHostBTstack::register_packet_handler(void (*pMethod)(uint8_t, uint8_t*, uint16_t) ) |
va009039 | 3:54f9b5e0d12d | 155 | { |
va009039 | 3:54f9b5e0d12d | 156 | BT_DBG("pMethod: %p", pMethod); |
va009039 | 3:54f9b5e0d12d | 157 | m_pCb = pMethod; |
va009039 | 3:54f9b5e0d12d | 158 | } |
va009039 | 3:54f9b5e0d12d | 159 | |
va009039 | 3:54f9b5e0d12d | 160 | void USBHostBTstack::poll() |
va009039 | 3:54f9b5e0d12d | 161 | { |
va009039 | 5:56897116e6b0 | 162 | int result = host->interruptReadNB(int_in, int_report, sizeof(int_report)); |
va009039 | 5:56897116e6b0 | 163 | if (result >= 0) { |
va009039 | 4:cf1b23f4dcd4 | 164 | int len = int_in->getLengthTransferred(); |
va009039 | 4:cf1b23f4dcd4 | 165 | BT_DBG_BYTES("HCI_EVT:", int_report, len); |
va009039 | 3:54f9b5e0d12d | 166 | if (m_pCb) { |
va009039 | 4:cf1b23f4dcd4 | 167 | m_pCb(HCI_EVENT_PACKET, int_report, len); |
va009039 | 3:54f9b5e0d12d | 168 | } |
va009039 | 3:54f9b5e0d12d | 169 | } |
va009039 | 5:56897116e6b0 | 170 | result = host->bulkReadNB(bulk_in, bulk_report, sizeof(bulk_report)); |
va009039 | 3:54f9b5e0d12d | 171 | if (result >= 0) { |
va009039 | 4:cf1b23f4dcd4 | 172 | int len = bulk_in->getLengthTransferred(); |
va009039 | 4:cf1b23f4dcd4 | 173 | BT_DBG_BYTES("HCI_ACL_RECV:", bulk_report, len); |
va009039 | 3:54f9b5e0d12d | 174 | if (m_pCb) { |
va009039 | 4:cf1b23f4dcd4 | 175 | m_pCb(HCI_ACL_DATA_PACKET, bulk_report, len); |
va009039 | 3:54f9b5e0d12d | 176 | } |
va009039 | 3:54f9b5e0d12d | 177 | } |
va009039 | 3:54f9b5e0d12d | 178 | } |
va009039 | 3:54f9b5e0d12d | 179 | |
va009039 | 3:54f9b5e0d12d | 180 | void _debug_bytes(const char* pretty, int line, const char* s, uint8_t* buf, int len) |
va009039 | 3:54f9b5e0d12d | 181 | { |
va009039 | 3:54f9b5e0d12d | 182 | printf("[%s:%d]\n%s", pretty, line, s); |
va009039 | 3:54f9b5e0d12d | 183 | for(int i = 0; i < len; i++) { |
va009039 | 3:54f9b5e0d12d | 184 | printf(" %02x", buf[i]); |
va009039 | 3:54f9b5e0d12d | 185 | } |
va009039 | 3:54f9b5e0d12d | 186 | printf("\n"); |
va009039 | 3:54f9b5e0d12d | 187 | } |