うおーるぼっとをWiiリモコンでコントロールする新しいプログラムです。 以前のものより、Wiiリモコンが早く繋がる様になりました。 It is a program which controls A with the Wii remote. ※ A Bluetooth dongle and a Wii remote control are needed.

Dependencies:   USBHost mbed FATFileSystem mbed-rtos

Committer:
jksoft
Date:
Mon Jun 10 16:01:50 2013 +0000
Revision:
0:fccb789424fc
1.0

Who changed what in which revision?

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