Fork of [[https://os.mbed.com/users/va009039/code/F401RE-USBHost/]]. Added support for Seeed Arch Max and STM32F407.

Dependents:   STM32F407VET6_USBHostMSD STM32F407VET6_USBHostMouse STM32F407VET6_USBHostKeyboard STM32F407VET6_USBHostMSD_1

Committer:
hudakz
Date:
Tue Feb 19 21:32:56 2019 +0000
Revision:
0:458bf947f46f
Fork of [[https://os.mbed.com/users/va009039/code/F401RE-USBHost/]]. Added support for Seeed Arch Max and STM32F407.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 0:458bf947f46f 1 #include "USBHostRSSI.h"
hudakz 0:458bf947f46f 2
hudakz 0:458bf947f46f 3 USBHostRSSI::USBHostRSSI()
hudakz 0:458bf947f46f 4 {
hudakz 0:458bf947f46f 5 host = USBHost::getHostInst();
hudakz 0:458bf947f46f 6 init();
hudakz 0:458bf947f46f 7 }
hudakz 0:458bf947f46f 8
hudakz 0:458bf947f46f 9 void USBHostRSSI::init()
hudakz 0:458bf947f46f 10 {
hudakz 0:458bf947f46f 11 dev = NULL;
hudakz 0:458bf947f46f 12 int_in = NULL;
hudakz 0:458bf947f46f 13 onUpdate = NULL;
hudakz 0:458bf947f46f 14 dev_connected = false;
hudakz 0:458bf947f46f 15 bluetooth_device_found = false;
hudakz 0:458bf947f46f 16 bluetooth_intf = -1;
hudakz 0:458bf947f46f 17 seq = 0;
hudakz 0:458bf947f46f 18
hudakz 0:458bf947f46f 19 }
hudakz 0:458bf947f46f 20
hudakz 0:458bf947f46f 21 bool USBHostRSSI::connected() {
hudakz 0:458bf947f46f 22 return dev_connected;
hudakz 0:458bf947f46f 23 }
hudakz 0:458bf947f46f 24
hudakz 0:458bf947f46f 25 bool USBHostRSSI::connect() {
hudakz 0:458bf947f46f 26
hudakz 0:458bf947f46f 27 if (dev_connected) {
hudakz 0:458bf947f46f 28 return true;
hudakz 0:458bf947f46f 29 }
hudakz 0:458bf947f46f 30
hudakz 0:458bf947f46f 31 for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) {
hudakz 0:458bf947f46f 32 if ((dev = host->getDevice(i)) != NULL) {
hudakz 0:458bf947f46f 33 if(host->enumerate(dev, this)) {
hudakz 0:458bf947f46f 34 break;
hudakz 0:458bf947f46f 35 }
hudakz 0:458bf947f46f 36 if (bluetooth_device_found) {
hudakz 0:458bf947f46f 37 int_in = dev->getEndpoint(bluetooth_intf, INTERRUPT_ENDPOINT, IN);
hudakz 0:458bf947f46f 38 USB_DBG("int_in=%p", int_in);
hudakz 0:458bf947f46f 39 if (!int_in) {
hudakz 0:458bf947f46f 40 break;
hudakz 0:458bf947f46f 41 }
hudakz 0:458bf947f46f 42 USB_INFO("New Bluetooth device: VID:%04x PID:%04x [dev: %p - intf: %d]", dev->getVid(), dev->getPid(), dev, bluetooth_intf);
hudakz 0:458bf947f46f 43 int_in->attach(this, &USBHostRSSI::rxHandler);
hudakz 0:458bf947f46f 44 int rc = host->interruptRead(dev, int_in, int_buf, sizeof(int_buf), false);
hudakz 0:458bf947f46f 45 USB_TEST_ASSERT(rc != USB_TYPE_ERROR);
hudakz 0:458bf947f46f 46 rc = cmdSend(HCI_OP_RESET);
hudakz 0:458bf947f46f 47 USB_TEST_ASSERT(rc == USB_TYPE_OK);
hudakz 0:458bf947f46f 48 dev_connected = true;
hudakz 0:458bf947f46f 49 return true;
hudakz 0:458bf947f46f 50 }
hudakz 0:458bf947f46f 51 }
hudakz 0:458bf947f46f 52 }
hudakz 0:458bf947f46f 53 init();
hudakz 0:458bf947f46f 54 return false;
hudakz 0:458bf947f46f 55 }
hudakz 0:458bf947f46f 56
hudakz 0:458bf947f46f 57 void USBHostRSSI::rxHandler() {
hudakz 0:458bf947f46f 58 event(int_buf, int_in->getLengthTransferred());
hudakz 0:458bf947f46f 59 if (dev) {
hudakz 0:458bf947f46f 60 host->interruptRead(dev, int_in, int_buf, sizeof(int_buf), false);
hudakz 0:458bf947f46f 61 }
hudakz 0:458bf947f46f 62 }
hudakz 0:458bf947f46f 63
hudakz 0:458bf947f46f 64 /*virtual*/ void USBHostRSSI::setVidPid(uint16_t vid, uint16_t pid)
hudakz 0:458bf947f46f 65 {
hudakz 0:458bf947f46f 66 USB_DBG("vid:%04x pid:%04x", vid, pid);
hudakz 0:458bf947f46f 67 // we don't check VID/PID for mouse driver
hudakz 0:458bf947f46f 68 }
hudakz 0:458bf947f46f 69
hudakz 0:458bf947f46f 70 /*virtual*/ bool USBHostRSSI::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
hudakz 0:458bf947f46f 71 {
hudakz 0:458bf947f46f 72 USB_DBG("intf: %d class: %02x %02x %02x", intf_nb, intf_class, intf_subclass, intf_protocol);
hudakz 0:458bf947f46f 73 if (bluetooth_intf == -1 && intf_class == 0xe0) {
hudakz 0:458bf947f46f 74 bluetooth_intf = intf_nb;
hudakz 0:458bf947f46f 75 return true;
hudakz 0:458bf947f46f 76 }
hudakz 0:458bf947f46f 77 return false;
hudakz 0:458bf947f46f 78 }
hudakz 0:458bf947f46f 79
hudakz 0:458bf947f46f 80 /*virtual*/ bool USBHostRSSI::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used
hudakz 0:458bf947f46f 81 {
hudakz 0:458bf947f46f 82 USB_DBG("intf_nb=%d type=%d dir=%d", intf_nb, type, dir);
hudakz 0:458bf947f46f 83
hudakz 0:458bf947f46f 84 if (intf_nb == bluetooth_intf) {
hudakz 0:458bf947f46f 85 if (type == INTERRUPT_ENDPOINT && dir == IN) {
hudakz 0:458bf947f46f 86 bluetooth_device_found = true;
hudakz 0:458bf947f46f 87 return true;
hudakz 0:458bf947f46f 88 }
hudakz 0:458bf947f46f 89 }
hudakz 0:458bf947f46f 90 return false;
hudakz 0:458bf947f46f 91 }
hudakz 0:458bf947f46f 92
hudakz 0:458bf947f46f 93 void USBHostRSSI::event(uint8_t* data, int len) {
hudakz 0:458bf947f46f 94 CTASSERT(sizeof(BD_ADDR) == 6);
hudakz 0:458bf947f46f 95 CTASSERT(sizeof(inquiry_with_rssi_info) == 14);
hudakz 0:458bf947f46f 96 inquiry_with_rssi_info* info;
hudakz 0:458bf947f46f 97 int max_period_length = 25;
hudakz 0:458bf947f46f 98 int min_period_length = 20;
hudakz 0:458bf947f46f 99 int inquiry_length = 15;
hudakz 0:458bf947f46f 100 USB_TYPE rc;
hudakz 0:458bf947f46f 101 if (len > 0) {
hudakz 0:458bf947f46f 102 USB_DBG_HEX(data, len);
hudakz 0:458bf947f46f 103 hci_event* event = reinterpret_cast<hci_event*>(data);
hudakz 0:458bf947f46f 104 switch(event->evt) {
hudakz 0:458bf947f46f 105 case HCI_EV_CMD_COMPLETE:
hudakz 0:458bf947f46f 106 switch(event->c.op) {
hudakz 0:458bf947f46f 107 case HCI_OP_RESET:
hudakz 0:458bf947f46f 108 wait_ms(500);
hudakz 0:458bf947f46f 109 rc = cmdSend(HCI_OP_WRITE_INQUIRY_MODE, "B", 0x01); // with RSSI
hudakz 0:458bf947f46f 110 USB_TEST_ASSERT(rc == USB_TYPE_OK);
hudakz 0:458bf947f46f 111 if (rc != USB_TYPE_OK) {
hudakz 0:458bf947f46f 112 }
hudakz 0:458bf947f46f 113 break;
hudakz 0:458bf947f46f 114 case HCI_OP_WRITE_INQUIRY_MODE:
hudakz 0:458bf947f46f 115 rc = cmdSend(HCI_OP_PERIODIC_INQUIRY, "HHBBBBB",
hudakz 0:458bf947f46f 116 max_period_length, min_period_length, 0x33, 0x8B, 0x9E, inquiry_length, 0);
hudakz 0:458bf947f46f 117 USB_TEST_ASSERT(rc == USB_TYPE_OK);
hudakz 0:458bf947f46f 118 break;
hudakz 0:458bf947f46f 119 default:
hudakz 0:458bf947f46f 120 break;
hudakz 0:458bf947f46f 121 }
hudakz 0:458bf947f46f 122 break;
hudakz 0:458bf947f46f 123 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
hudakz 0:458bf947f46f 124 //USB_DBG_HEX(buf, r);
hudakz 0:458bf947f46f 125 info = reinterpret_cast<inquiry_with_rssi_info*>(event->c.data);
hudakz 0:458bf947f46f 126 if (onUpdate) {
hudakz 0:458bf947f46f 127 (*onUpdate)(info);
hudakz 0:458bf947f46f 128 }
hudakz 0:458bf947f46f 129 break;
hudakz 0:458bf947f46f 130 default:
hudakz 0:458bf947f46f 131 break;
hudakz 0:458bf947f46f 132 }
hudakz 0:458bf947f46f 133 }
hudakz 0:458bf947f46f 134 }
hudakz 0:458bf947f46f 135
hudakz 0:458bf947f46f 136 USB_TYPE USBHostRSSI::cmdSend(uint16_t op)
hudakz 0:458bf947f46f 137 {
hudakz 0:458bf947f46f 138 return cmdSendSub(op, NULL, 0);
hudakz 0:458bf947f46f 139 }
hudakz 0:458bf947f46f 140
hudakz 0:458bf947f46f 141 USB_TYPE USBHostRSSI::cmdSend(uint16_t op, const char* fmt, ...)
hudakz 0:458bf947f46f 142 {
hudakz 0:458bf947f46f 143 va_list vl;
hudakz 0:458bf947f46f 144 va_start(vl, fmt);
hudakz 0:458bf947f46f 145 uint8_t buf[255];
hudakz 0:458bf947f46f 146 int pos = 0;
hudakz 0:458bf947f46f 147 char* name;
hudakz 0:458bf947f46f 148 int name_len;
hudakz 0:458bf947f46f 149 uint16_t h;
hudakz 0:458bf947f46f 150 BD_ADDR* bdaddr;
hudakz 0:458bf947f46f 151 for(int i = 0; fmt[i]; i++) {
hudakz 0:458bf947f46f 152 switch(fmt[i]) {
hudakz 0:458bf947f46f 153 case 's':
hudakz 0:458bf947f46f 154 name = va_arg(vl, char*);
hudakz 0:458bf947f46f 155 name_len = strlen(name)+1;
hudakz 0:458bf947f46f 156 memcpy(buf+pos, name, name_len);
hudakz 0:458bf947f46f 157 pos += name_len;
hudakz 0:458bf947f46f 158 break;
hudakz 0:458bf947f46f 159 case 'B':
hudakz 0:458bf947f46f 160 buf[pos++] = va_arg(vl, int);
hudakz 0:458bf947f46f 161 break;
hudakz 0:458bf947f46f 162 case 'H':
hudakz 0:458bf947f46f 163 h = va_arg(vl, int);
hudakz 0:458bf947f46f 164 buf[pos++] = h;
hudakz 0:458bf947f46f 165 buf[pos++] = h>>8;
hudakz 0:458bf947f46f 166 break;
hudakz 0:458bf947f46f 167 case 'A':
hudakz 0:458bf947f46f 168 bdaddr = va_arg(vl, BD_ADDR*);
hudakz 0:458bf947f46f 169 memcpy(buf+pos, bdaddr, 6);
hudakz 0:458bf947f46f 170 pos += 6;
hudakz 0:458bf947f46f 171 break;
hudakz 0:458bf947f46f 172 default:
hudakz 0:458bf947f46f 173 USB_DBG("op=%04X fmt=%s i=%d", op, fmt, i);
hudakz 0:458bf947f46f 174 break;
hudakz 0:458bf947f46f 175 }
hudakz 0:458bf947f46f 176 }
hudakz 0:458bf947f46f 177 return cmdSendSub(op, buf, pos);
hudakz 0:458bf947f46f 178 }
hudakz 0:458bf947f46f 179
hudakz 0:458bf947f46f 180 USB_TYPE USBHostRSSI::cmdSendSub(uint16_t op, const uint8_t* data, int size)
hudakz 0:458bf947f46f 181 {
hudakz 0:458bf947f46f 182 uint8_t* buf = new uint8_t[size+3];
hudakz 0:458bf947f46f 183 buf[0] = op;
hudakz 0:458bf947f46f 184 buf[1] = op>>8;
hudakz 0:458bf947f46f 185 buf[2] = size;
hudakz 0:458bf947f46f 186 if (data) {
hudakz 0:458bf947f46f 187 memcpy(buf+3, data, size);
hudakz 0:458bf947f46f 188 }
hudakz 0:458bf947f46f 189 USB_TYPE rc = host->controlWrite(dev, USB_REQUEST_TYPE_CLASS, 0, 0, 0, buf, size+3);
hudakz 0:458bf947f46f 190 USB_TEST_ASSERT(rc == USB_TYPE_OK);
hudakz 0:458bf947f46f 191 delete[] buf;
hudakz 0:458bf947f46f 192 return rc;
hudakz 0:458bf947f46f 193 }