Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
USBControl.cpp@1:0c3b6cc480b6, 2017-02-13 (annotated)
- Committer:
- Timmmm
- Date:
- Mon Feb 13 14:56:00 2017 +0000
- Revision:
- 1:0c3b6cc480b6
- Parent:
- 0:1a3aa2e25db9
Various changes?
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Timmmm | 0:1a3aa2e25db9 | 1 | #include "USBControl.h" |
Timmmm | 0:1a3aa2e25db9 | 2 | |
Timmmm | 0:1a3aa2e25db9 | 3 | #include <USBDescriptor.h> |
Timmmm | 0:1a3aa2e25db9 | 4 | |
Timmmm | 0:1a3aa2e25db9 | 5 | #define DEFAULT_CONFIGURATION (1) |
Timmmm | 0:1a3aa2e25db9 | 6 | |
Timmmm | 0:1a3aa2e25db9 | 7 | std::vector<uint8_t> MakeStringDescriptor(const char* s) |
Timmmm | 0:1a3aa2e25db9 | 8 | { |
Timmmm | 0:1a3aa2e25db9 | 9 | int len = strlen(s); |
Timmmm | 0:1a3aa2e25db9 | 10 | if (len > 126) // TODO: Double check this is the max length. |
Timmmm | 0:1a3aa2e25db9 | 11 | len = 126; |
Timmmm | 0:1a3aa2e25db9 | 12 | |
Timmmm | 0:1a3aa2e25db9 | 13 | std::vector<uint8_t> desc(len*2 + 2); |
Timmmm | 0:1a3aa2e25db9 | 14 | |
Timmmm | 0:1a3aa2e25db9 | 15 | desc[0] = desc.size(); |
Timmmm | 0:1a3aa2e25db9 | 16 | desc[1] = STRING_DESCRIPTOR; |
Timmmm | 0:1a3aa2e25db9 | 17 | for (int i = 0; i < len; ++i) |
Timmmm | 0:1a3aa2e25db9 | 18 | desc[2 + i*2] = s[i]; |
Timmmm | 0:1a3aa2e25db9 | 19 | |
Timmmm | 0:1a3aa2e25db9 | 20 | return desc; |
Timmmm | 0:1a3aa2e25db9 | 21 | } |
Timmmm | 0:1a3aa2e25db9 | 22 | |
Timmmm | 0:1a3aa2e25db9 | 23 | USBControl::USBControl(uint16_t vendor_id, uint16_t product_id, uint16_t product_release, const char* product_name, const char* manufacturer_name, const char* guid) : WinUSBDevice(vendor_id, product_id, product_release, guid) |
Timmmm | 0:1a3aa2e25db9 | 24 | { |
Timmmm | 0:1a3aa2e25db9 | 25 | mProductStringDescriptor = MakeStringDescriptor(product_name); |
Timmmm | 0:1a3aa2e25db9 | 26 | mManufacturerStringDescriptor = MakeStringDescriptor(manufacturer_name); |
Timmmm | 0:1a3aa2e25db9 | 27 | } |
Timmmm | 0:1a3aa2e25db9 | 28 | |
Timmmm | 0:1a3aa2e25db9 | 29 | bool USBControl::USBCallback_setConfiguration(uint8_t configuration) |
Timmmm | 0:1a3aa2e25db9 | 30 | { |
Timmmm | 0:1a3aa2e25db9 | 31 | // Called in ISR context. Return false if the configuration is not supported. |
Timmmm | 0:1a3aa2e25db9 | 32 | if (configuration != DEFAULT_CONFIGURATION) |
Timmmm | 0:1a3aa2e25db9 | 33 | return false; |
Timmmm | 0:1a3aa2e25db9 | 34 | |
Timmmm | 0:1a3aa2e25db9 | 35 | // Configure endpoints > 0 |
Timmmm | 0:1a3aa2e25db9 | 36 | addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT); |
Timmmm | 0:1a3aa2e25db9 | 37 | addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT); |
Timmmm | 0:1a3aa2e25db9 | 38 | |
Timmmm | 0:1a3aa2e25db9 | 39 | // Start receiving on the OUT endpoint |
Timmmm | 0:1a3aa2e25db9 | 40 | readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT); |
Timmmm | 0:1a3aa2e25db9 | 41 | |
Timmmm | 0:1a3aa2e25db9 | 42 | return true; |
Timmmm | 0:1a3aa2e25db9 | 43 | } |
Timmmm | 0:1a3aa2e25db9 | 44 | |
Timmmm | 0:1a3aa2e25db9 | 45 | bool USBControl::EPINT_OUT_callback() |
Timmmm | 0:1a3aa2e25db9 | 46 | { |
Timmmm | 0:1a3aa2e25db9 | 47 | // TODO: Presumably this is called in an interrupt context, therefore we really need a lock |
Timmmm | 0:1a3aa2e25db9 | 48 | // or a lock free ring buffer (better). |
Timmmm | 0:1a3aa2e25db9 | 49 | uint32_t bytesRead = 0; |
Timmmm | 0:1a3aa2e25db9 | 50 | uint8_t buf[MAX_PACKET_SIZE_EPINT]; |
Timmmm | 0:1a3aa2e25db9 | 51 | if (readEP(EPINT_OUT, buf, &bytesRead, MAX_PACKET_SIZE_EPINT)) |
Timmmm | 0:1a3aa2e25db9 | 52 | { |
Timmmm | 0:1a3aa2e25db9 | 53 | mReceivedPackets.push_back(std::string((char*)buf, bytesRead)); |
Timmmm | 0:1a3aa2e25db9 | 54 | } |
Timmmm | 0:1a3aa2e25db9 | 55 | |
Timmmm | 0:1a3aa2e25db9 | 56 | // Start reading again. |
Timmmm | 0:1a3aa2e25db9 | 57 | readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT); |
Timmmm | 0:1a3aa2e25db9 | 58 | // Return true to say that we have handled it. |
Timmmm | 0:1a3aa2e25db9 | 59 | return true; |
Timmmm | 0:1a3aa2e25db9 | 60 | } |
Timmmm | 0:1a3aa2e25db9 | 61 | |
Timmmm | 0:1a3aa2e25db9 | 62 | uint8_t* USBControl::stringIproductDesc() |
Timmmm | 0:1a3aa2e25db9 | 63 | { |
Timmmm | 0:1a3aa2e25db9 | 64 | return &mProductStringDescriptor.front(); |
Timmmm | 0:1a3aa2e25db9 | 65 | } |
Timmmm | 0:1a3aa2e25db9 | 66 | |
Timmmm | 0:1a3aa2e25db9 | 67 | uint8_t* USBControl::stringIinterfaceDesc() |
Timmmm | 0:1a3aa2e25db9 | 68 | { |
Timmmm | 0:1a3aa2e25db9 | 69 | static uint8_t stringIinterfaceDescriptor[] = { |
Timmmm | 0:1a3aa2e25db9 | 70 | 0x10, // bLength |
Timmmm | 0:1a3aa2e25db9 | 71 | STRING_DESCRIPTOR, // bDescriptorType 0x03 |
Timmmm | 0:1a3aa2e25db9 | 72 | 'C',0,'o',0,'n',0,'t',0,'r',0,'o',0,'l',0 // bString iInterface - Control |
Timmmm | 0:1a3aa2e25db9 | 73 | }; |
Timmmm | 0:1a3aa2e25db9 | 74 | return stringIinterfaceDescriptor; |
Timmmm | 0:1a3aa2e25db9 | 75 | } |
Timmmm | 0:1a3aa2e25db9 | 76 | |
Timmmm | 0:1a3aa2e25db9 | 77 | uint8_t* USBControl::stringImanufacturerDesc() |
Timmmm | 0:1a3aa2e25db9 | 78 | { |
Timmmm | 0:1a3aa2e25db9 | 79 | return &mManufacturerStringDescriptor.front(); |
Timmmm | 0:1a3aa2e25db9 | 80 | } |
Timmmm | 0:1a3aa2e25db9 | 81 | |
Timmmm | 0:1a3aa2e25db9 | 82 | #define SENSOR_CLASS (0xFF) // Vendor specific. |
Timmmm | 0:1a3aa2e25db9 | 83 | #define SENSOR_SUBCLASS (0x00) |
Timmmm | 0:1a3aa2e25db9 | 84 | #define SENSOR_PROTOCOL (0x00) |
Timmmm | 0:1a3aa2e25db9 | 85 | |
Timmmm | 0:1a3aa2e25db9 | 86 | #define NUM_ENDPOINTS 2 |
Timmmm | 0:1a3aa2e25db9 | 87 | |
Timmmm | 0:1a3aa2e25db9 | 88 | #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \ |
Timmmm | 0:1a3aa2e25db9 | 89 | + (1 * INTERFACE_DESCRIPTOR_LENGTH) \ |
Timmmm | 0:1a3aa2e25db9 | 90 | + (NUM_ENDPOINTS * ENDPOINT_DESCRIPTOR_LENGTH)) |
Timmmm | 0:1a3aa2e25db9 | 91 | |
Timmmm | 0:1a3aa2e25db9 | 92 | uint8_t* USBControl::configurationDesc() |
Timmmm | 0:1a3aa2e25db9 | 93 | { |
Timmmm | 0:1a3aa2e25db9 | 94 | static uint8_t configurationDescriptor[] = { |
Timmmm | 0:1a3aa2e25db9 | 95 | CONFIGURATION_DESCRIPTOR_LENGTH,// bLength |
Timmmm | 0:1a3aa2e25db9 | 96 | CONFIGURATION_DESCRIPTOR, // bDescriptorType |
Timmmm | 0:1a3aa2e25db9 | 97 | LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB) |
Timmmm | 0:1a3aa2e25db9 | 98 | MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB) |
Timmmm | 0:1a3aa2e25db9 | 99 | 0x01, // bNumInterfaces |
Timmmm | 0:1a3aa2e25db9 | 100 | DEFAULT_CONFIGURATION, // bConfigurationValue |
Timmmm | 0:1a3aa2e25db9 | 101 | 0x00, // iConfiguration |
Timmmm | 0:1a3aa2e25db9 | 102 | C_RESERVED, // bmAttributes (C_RESERVED must be set) |
Timmmm | 0:1a3aa2e25db9 | 103 | C_POWER(100), // bMaxPower in mA |
Timmmm | 0:1a3aa2e25db9 | 104 | |
Timmmm | 0:1a3aa2e25db9 | 105 | INTERFACE_DESCRIPTOR_LENGTH, // bLength |
Timmmm | 0:1a3aa2e25db9 | 106 | INTERFACE_DESCRIPTOR, // bDescriptorType |
Timmmm | 0:1a3aa2e25db9 | 107 | 0x00, // bInterfaceNumber |
Timmmm | 0:1a3aa2e25db9 | 108 | 0x00, // bAlternateSetting |
Timmmm | 0:1a3aa2e25db9 | 109 | NUM_ENDPOINTS, // bNumEndpoints |
Timmmm | 0:1a3aa2e25db9 | 110 | SENSOR_CLASS, // bInterfaceClass |
Timmmm | 0:1a3aa2e25db9 | 111 | SENSOR_SUBCLASS, // bInterfaceSubClass |
Timmmm | 0:1a3aa2e25db9 | 112 | SENSOR_PROTOCOL, // bInterfaceProtocol |
Timmmm | 0:1a3aa2e25db9 | 113 | 0x00, // iInterface |
Timmmm | 0:1a3aa2e25db9 | 114 | |
Timmmm | 0:1a3aa2e25db9 | 115 | // IN interrupt endpoint descriptor |
Timmmm | 0:1a3aa2e25db9 | 116 | ENDPOINT_DESCRIPTOR_LENGTH, // bLength |
Timmmm | 0:1a3aa2e25db9 | 117 | ENDPOINT_DESCRIPTOR, // bDescriptorType |
Timmmm | 0:1a3aa2e25db9 | 118 | PHY_TO_DESC(EPINT_IN), // bEndpointAddress |
Timmmm | 0:1a3aa2e25db9 | 119 | E_INTERRUPT, // bmAttributes |
Timmmm | 0:1a3aa2e25db9 | 120 | LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) |
Timmmm | 0:1a3aa2e25db9 | 121 | MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) |
Timmmm | 0:1a3aa2e25db9 | 122 | 1, // bInterval (milliseconds) |
Timmmm | 0:1a3aa2e25db9 | 123 | |
Timmmm | 0:1a3aa2e25db9 | 124 | // OUT interrupt endpoint descriptor |
Timmmm | 0:1a3aa2e25db9 | 125 | ENDPOINT_DESCRIPTOR_LENGTH, // bLength |
Timmmm | 0:1a3aa2e25db9 | 126 | ENDPOINT_DESCRIPTOR, // bDescriptorType |
Timmmm | 0:1a3aa2e25db9 | 127 | PHY_TO_DESC(EPINT_OUT), // bEndpointAddress |
Timmmm | 0:1a3aa2e25db9 | 128 | E_INTERRUPT, // bmAttributes |
Timmmm | 0:1a3aa2e25db9 | 129 | LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) |
Timmmm | 0:1a3aa2e25db9 | 130 | MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) |
Timmmm | 0:1a3aa2e25db9 | 131 | 1, // bInterval (milliseconds) |
Timmmm | 0:1a3aa2e25db9 | 132 | }; |
Timmmm | 0:1a3aa2e25db9 | 133 | return configurationDescriptor; |
Timmmm | 0:1a3aa2e25db9 | 134 | } |
Timmmm | 0:1a3aa2e25db9 | 135 | |
Timmmm | 0:1a3aa2e25db9 | 136 | bool USBControl::sendData(const std::string& data) |
Timmmm | 0:1a3aa2e25db9 | 137 | { |
Timmmm | 0:1a3aa2e25db9 | 138 | return write(EPINT_IN, (uint8_t*)data.c_str(), data.length(), MAX_PACKET_SIZE_EPINT); |
Timmmm | 0:1a3aa2e25db9 | 139 | } |
Timmmm | 0:1a3aa2e25db9 | 140 | |
Timmmm | 0:1a3aa2e25db9 | 141 | bool USBControl::sendData(const uint8_t* data, int len) |
Timmmm | 0:1a3aa2e25db9 | 142 | { |
Timmmm | 0:1a3aa2e25db9 | 143 | return write(EPINT_IN, const_cast<uint8_t*>(data), len, MAX_PACKET_SIZE_EPINT); |
Timmmm | 0:1a3aa2e25db9 | 144 | } |
Timmmm | 0:1a3aa2e25db9 | 145 | |
Timmmm | 0:1a3aa2e25db9 | 146 | bool USBControl::sendDataNB(const std::string& data) |
Timmmm | 0:1a3aa2e25db9 | 147 | { |
Timmmm | 0:1a3aa2e25db9 | 148 | return write(EPINT_IN, (uint8_t*)data.c_str(), data.length(), MAX_PACKET_SIZE_EPINT); |
Timmmm | 0:1a3aa2e25db9 | 149 | } |
Timmmm | 0:1a3aa2e25db9 | 150 | |
Timmmm | 0:1a3aa2e25db9 | 151 | bool USBControl::sendDataNB(const uint8_t* data, int len) |
Timmmm | 0:1a3aa2e25db9 | 152 | { |
Timmmm | 0:1a3aa2e25db9 | 153 | return write(EPINT_IN, const_cast<uint8_t*>(data), len, MAX_PACKET_SIZE_EPINT); |
Timmmm | 0:1a3aa2e25db9 | 154 | } |
Timmmm | 0:1a3aa2e25db9 | 155 | |
Timmmm | 0:1a3aa2e25db9 | 156 | std::string USBControl::receiveData() |
Timmmm | 0:1a3aa2e25db9 | 157 | { |
Timmmm | 0:1a3aa2e25db9 | 158 | while (mReceivedPackets.empty()) |
Timmmm | 0:1a3aa2e25db9 | 159 | ; |
Timmmm | 0:1a3aa2e25db9 | 160 | |
Timmmm | 0:1a3aa2e25db9 | 161 | std::string s = mReceivedPackets.front(); |
Timmmm | 0:1a3aa2e25db9 | 162 | mReceivedPackets.erase(mReceivedPackets.begin()); |
Timmmm | 0:1a3aa2e25db9 | 163 | return s; |
Timmmm | 0:1a3aa2e25db9 | 164 | } |
Timmmm | 0:1a3aa2e25db9 | 165 | |
Timmmm | 0:1a3aa2e25db9 | 166 | std::string USBControl::receiveDataNB() |
Timmmm | 0:1a3aa2e25db9 | 167 | { |
Timmmm | 0:1a3aa2e25db9 | 168 | if (mReceivedPackets.empty()) |
Timmmm | 0:1a3aa2e25db9 | 169 | return std::string(); |
Timmmm | 0:1a3aa2e25db9 | 170 | |
Timmmm | 0:1a3aa2e25db9 | 171 | std::string s = mReceivedPackets.front(); |
Timmmm | 0:1a3aa2e25db9 | 172 | mReceivedPackets.erase(mReceivedPackets.begin()); |
Timmmm | 0:1a3aa2e25db9 | 173 | return s; |
Timmmm | 0:1a3aa2e25db9 | 174 | } |
Timmmm | 0:1a3aa2e25db9 | 175 |