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;
}