Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

sync with tinyusb core from samd with folowing PRs #349

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
163 changes: 136 additions & 27 deletions 163 cores/nRF5/Adafruit_TinyUSB_Core/Adafruit_USBD_Device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@
#define USB_PRODUCT "Unknown"
#endif

#ifndef USB_LANGUAGE
#define USB_LANGUAGE 0x0409 // default is English
#endif

#ifndef USB_CONFIG_POWER
#define USB_CONFIG_POWER 100
#endif

extern uint8_t load_serial_number(uint16_t* serial_str);

Adafruit_USBD_Device USBDevice;
Expand Down Expand Up @@ -76,23 +84,29 @@ Adafruit_USBD_Device::Adafruit_USBD_Device(void)
.bConfigurationValue = 1,
.iConfiguration = 0x00,
.bmAttributes = TU_BIT(7) | TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP,
.bMaxPower = TUSB_DESC_CONFIG_POWER_MA(100)
.bMaxPower = TUSB_DESC_CONFIG_POWER_MA(USB_CONFIG_POWER)
};

memcpy(_desc_cfg, &dev_cfg, sizeof(tusb_desc_configuration_t));
memcpy(_desc_cfg_buffer, &dev_cfg, sizeof(tusb_desc_configuration_t));
_desc_cfg = _desc_cfg_buffer;
_desc_cfg_maxlen = sizeof(_desc_cfg_buffer);
_desc_cfg_len = sizeof(tusb_desc_configuration_t);

_itf_count = 0;
_epin_count = _epout_count = 1;

_desc_cfglen = sizeof(tusb_desc_configuration_t);
_itf_count = 0;
_epin_count = _epout_count = 1;
_language_id = USB_LANGUAGE;
_manufacturer = USB_MANUFACTURER;
_product = USB_PRODUCT;
}

// Add interface descriptor
// - Interface number will be updated to match current count
// - Endpoint number is updated to be unique
bool Adafruit_USBD_Device::addInterface(Adafruit_USBD_Interface& itf)
{
uint8_t* desc = _desc_cfg+_desc_cfglen;
uint16_t const len = itf.getDescriptor(_itf_count, desc, sizeof(_desc_cfg)-_desc_cfglen);
uint8_t* desc = _desc_cfg+_desc_cfg_len;
uint16_t const len = itf.getDescriptor(_itf_count, desc, _desc_cfg_maxlen-_desc_cfg_len);
uint8_t* desc_end = desc+len;

if ( !len ) return false;
Expand All @@ -113,19 +127,29 @@ bool Adafruit_USBD_Device::addInterface(Adafruit_USBD_Interface& itf)
desc += desc[0]; // next
}

_desc_cfglen += len;
_desc_cfg_len += len;

// Update configuration descriptor
tusb_desc_configuration_t* config = (tusb_desc_configuration_t*)_desc_cfg;
config->wTotalLength = _desc_cfglen;
config->wTotalLength = _desc_cfg_len;
config->bNumInterfaces = _itf_count;

return true;
}

void Adafruit_USBD_Device::setDescriptorBuffer(uint8_t* buf, uint32_t buflen)
{
if (buflen < _desc_cfg_maxlen)
return;

memcpy(buf, _desc_cfg, _desc_cfg_len);
_desc_cfg = buf;
_desc_cfg_maxlen = buflen;
}

void Adafruit_USBD_Device::setID(uint16_t vid, uint16_t pid)
{
_desc_device.idVendor = vid;
_desc_device.idVendor = vid;
_desc_device.idProduct = pid;
}

Expand All @@ -134,6 +158,22 @@ void Adafruit_USBD_Device::setVersion(uint16_t bcd)
_desc_device.bcdUSB = bcd;
}


void Adafruit_USBD_Device::setLanguageDescriptor (uint16_t language_id)
{
_language_id = language_id;
}

void Adafruit_USBD_Device::setManufacturerDescriptor(const char *s)
{
_manufacturer = s;
}

void Adafruit_USBD_Device::setProductDescriptor(const char *s)
{
_product = s;
}

bool Adafruit_USBD_Device::begin(void)
{
return true;
Expand All @@ -157,6 +197,84 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
return USBDevice._desc_cfg;
}

static int utf8_to_unichar(const char *str8, int *unicharp)
{
int unichar;
int len;

if (str8[0] < 0x80)
len = 1;
else if ((str8[0] & 0xe0) == 0xc0)
len = 2;
else if ((str8[0] & 0xf0) == 0xe0)
len = 3;
else if ((str8[0] & 0xf8) == 0xf0)
len = 4;
else if ((str8[0] & 0xfc) == 0xf8)
len = 5;
else if ((str8[0] & 0xfe) == 0xfc)
len = 6;
else
return -1;

switch (len) {
case 1:
unichar = str8[0];
break;
case 2:
unichar = str8[0] & 0x1f;
break;
case 3:
unichar = str8[0] & 0x0f;
break;
case 4:
unichar = str8[0] & 0x07;
break;
case 5:
unichar = str8[0] & 0x03;
break;
case 6:
unichar = str8[0] & 0x01;
break;
}

for (int i = 1; i < len; i++) {
if ((str8[i] & 0xc0) != 0x80)
return -1;
unichar <<= 6;
unichar |= str8[i] & 0x3f;
}

*unicharp = unichar;
return len;
}

// Simple UCS-2/16-bit coversion, which handles the Basic Multilingual Plane
static int strcpy_uni16(const char *s, uint16_t *buf, int bufsize) {
int i = 0;
int buflen = 0;

while (i < bufsize) {
int unichar;
int utf8len = utf8_to_unichar(s + i, &unichar);

if (utf8len < 0) {
// Invalid utf8 sequence, skip it
i++;
continue;
}

i += utf8len;

// If the codepoint is larger than 16 bit, skip it
if (unichar <= 0xffff)
buf[buflen++] = unichar;
}

buf[buflen] = '\0';
return buflen;
}

// up to 32 unicode characters (header make it 33)
static uint16_t _desc_str[33];

Expand All @@ -169,25 +287,16 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index)
switch (index)
{
case 0:
// language = English
_desc_str[1] = 0x0409;
_desc_str[1] = USBDevice.getLanguageDescriptor();
chr_count = 1;
break;

case 1: // Manufacturer
case 2: // Product
{
char const * str = (index == 1) ? USB_MANUFACTURER : USB_PRODUCT;

// cap at max char
chr_count = strlen(str);
if ( chr_count > 32 ) chr_count = 32;
case 1:
chr_count = strcpy_uni16(USBDevice.getManufacturerDescriptor(), _desc_str + 1, 32);
break;

for(uint8_t i=0; i<chr_count; i++)
{
_desc_str[1+i] = str[i];
}
}
case 2:
chr_count = strcpy_uni16(USBDevice.getProductDescriptor(), _desc_str + 1, 32);
break;

case 3:
Expand All @@ -198,8 +307,8 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index)
default: return NULL;
}

// first byte is len, second byte is string type
_desc_str[0] = TUD_DESC_STR_HEADER(chr_count);
// first byte is length (including header), second byte is string type
_desc_str[0] = (TUSB_DESC_STRING << 8 ) | (2*chr_count + 2);

return _desc_str;
}
Expand Down
20 changes: 18 additions & 2 deletions 20 cores/nRF5/Adafruit_TinyUSB_Core/Adafruit_USBD_Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,37 @@ class Adafruit_USBD_Device
private:
tusb_desc_device_t _desc_device;

uint8_t _desc_cfg[256];
uint16_t _desc_cfglen;
uint8_t *_desc_cfg;
uint16_t _desc_cfg_maxlen;
uint16_t _desc_cfg_len;
uint8_t _desc_cfg_buffer[256];

uint8_t _itf_count;

uint8_t _epin_count;
uint8_t _epout_count;

uint16_t _language_id;
const char *_manufacturer;
const char *_product;

public:
Adafruit_USBD_Device(void);

bool addInterface(Adafruit_USBD_Interface& itf);
void setDescriptorBuffer(uint8_t* buf, uint32_t buflen);

void setID(uint16_t vid, uint16_t pid);
void setVersion(uint16_t bcd);

void setLanguageDescriptor(uint16_t language_id);
void setManufacturerDescriptor(const char *s);
void setProductDescriptor(const char *s);

uint16_t getLanguageDescriptor (void) { return _language_id; }
const char *getManufacturerDescriptor (void) { return _manufacturer; }
const char *getProductDescriptor (void) { return _product; }

bool begin(void);

bool mounted (void) { return tud_mounted(); }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -469,15 +469,6 @@ static inline uint8_t tu_desc_len(void const* desc)
return ((uint8_t const*) desc)[DESC_OFFSET_LEN];
}

// Length of the string descriptors in bytes with slen characters
#define TUD_DESC_STRLEN(_chr_count) (2*(_chr_count) + 2)

// Header of string descriptors with len + string type
#define TUD_DESC_STR_HEADER(_chr_count) ( (uint16_t) ( (TUSB_DESC_STRING << 8 ) | TUD_DESC_STRLEN(_chr_count)) )

// Convert comma-separated string to descriptor unicode format
#define TUD_DESC_STRCONV( ... ) (const uint16_t[]) { TUD_DESC_STR_HEADER(TU_ARGS_NUM(__VA_ARGS__)), __VA_ARGS__ }

#ifdef __cplusplus
}
#endif
Expand Down
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.