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
- Committer:
- Timmmm
- Date:
- 2016-11-04
- Revision:
- 0:1a3aa2e25db9
File content as of revision 0:1a3aa2e25db9:
#include "USBControl.h" #include <USBDescriptor.h> #define DEFAULT_CONFIGURATION (1) std::vector<uint8_t> MakeStringDescriptor(const char* s) { int len = strlen(s); if (len > 126) // TODO: Double check this is the max length. len = 126; std::vector<uint8_t> desc(len*2 + 2); desc[0] = desc.size(); desc[1] = STRING_DESCRIPTOR; for (int i = 0; i < len; ++i) desc[2 + i*2] = s[i]; return desc; } 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) { mProductStringDescriptor = MakeStringDescriptor(product_name); mManufacturerStringDescriptor = MakeStringDescriptor(manufacturer_name); } bool USBControl::USBCallback_setConfiguration(uint8_t configuration) { // Called in ISR context. Return false if the configuration is not supported. if (configuration != DEFAULT_CONFIGURATION) return false; // Configure endpoints > 0 addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT); addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT); // Start receiving on the OUT endpoint readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT); return true; } bool USBControl::EPINT_OUT_callback() { // TODO: Presumably this is called in an interrupt context, therefore we really need a lock // or a lock free ring buffer (better). uint32_t bytesRead = 0; uint8_t buf[MAX_PACKET_SIZE_EPINT]; if (readEP(EPINT_OUT, buf, &bytesRead, MAX_PACKET_SIZE_EPINT)) { mReceivedPackets.push_back(std::string((char*)buf, bytesRead)); } // Start reading again. readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT); // Return true to say that we have handled it. return true; } uint8_t* USBControl::stringIproductDesc() { return &mProductStringDescriptor.front(); } uint8_t* USBControl::stringIinterfaceDesc() { static uint8_t stringIinterfaceDescriptor[] = { 0x10, // bLength STRING_DESCRIPTOR, // bDescriptorType 0x03 'C',0,'o',0,'n',0,'t',0,'r',0,'o',0,'l',0 // bString iInterface - Control }; return stringIinterfaceDescriptor; } uint8_t* USBControl::stringImanufacturerDesc() { return &mManufacturerStringDescriptor.front(); } #define SENSOR_CLASS (0xFF) // Vendor specific. #define SENSOR_SUBCLASS (0x00) #define SENSOR_PROTOCOL (0x00) #define NUM_ENDPOINTS 2 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \ + (1 * INTERFACE_DESCRIPTOR_LENGTH) \ + (NUM_ENDPOINTS * ENDPOINT_DESCRIPTOR_LENGTH)) uint8_t* USBControl::configurationDesc() { static uint8_t configurationDescriptor[] = { CONFIGURATION_DESCRIPTOR_LENGTH,// bLength CONFIGURATION_DESCRIPTOR, // bDescriptorType LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB) MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB) 0x01, // bNumInterfaces DEFAULT_CONFIGURATION, // bConfigurationValue 0x00, // iConfiguration C_RESERVED, // bmAttributes (C_RESERVED must be set) C_POWER(100), // bMaxPower in mA INTERFACE_DESCRIPTOR_LENGTH, // bLength INTERFACE_DESCRIPTOR, // bDescriptorType 0x00, // bInterfaceNumber 0x00, // bAlternateSetting NUM_ENDPOINTS, // bNumEndpoints SENSOR_CLASS, // bInterfaceClass SENSOR_SUBCLASS, // bInterfaceSubClass SENSOR_PROTOCOL, // bInterfaceProtocol 0x00, // iInterface // IN interrupt endpoint descriptor ENDPOINT_DESCRIPTOR_LENGTH, // bLength ENDPOINT_DESCRIPTOR, // bDescriptorType PHY_TO_DESC(EPINT_IN), // bEndpointAddress E_INTERRUPT, // bmAttributes LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) 1, // bInterval (milliseconds) // OUT interrupt endpoint descriptor ENDPOINT_DESCRIPTOR_LENGTH, // bLength ENDPOINT_DESCRIPTOR, // bDescriptorType PHY_TO_DESC(EPINT_OUT), // bEndpointAddress E_INTERRUPT, // bmAttributes LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB) MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB) 1, // bInterval (milliseconds) }; return configurationDescriptor; } bool USBControl::sendData(const std::string& data) { return write(EPINT_IN, (uint8_t*)data.c_str(), data.length(), MAX_PACKET_SIZE_EPINT); } bool USBControl::sendData(const uint8_t* data, int len) { return write(EPINT_IN, const_cast<uint8_t*>(data), len, MAX_PACKET_SIZE_EPINT); } bool USBControl::sendDataNB(const std::string& data) { return write(EPINT_IN, (uint8_t*)data.c_str(), data.length(), MAX_PACKET_SIZE_EPINT); } bool USBControl::sendDataNB(const uint8_t* data, int len) { return write(EPINT_IN, const_cast<uint8_t*>(data), len, MAX_PACKET_SIZE_EPINT); } std::string USBControl::receiveData() { while (mReceivedPackets.empty()) ; std::string s = mReceivedPackets.front(); mReceivedPackets.erase(mReceivedPackets.begin()); return s; } std::string USBControl::receiveDataNB() { if (mReceivedPackets.empty()) return std::string(); std::string s = mReceivedPackets.front(); mReceivedPackets.erase(mReceivedPackets.begin()); return s; }