Tim H / Mbed OS UsbKnob

Dependencies:   USBDevice

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?

UserRevisionLine numberNew 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