Merge pull request #2 from ndreys/staging
Fix for USB string descriptors/USB iSerialNumber helper functions
This commit is contained in:
commit
1768df7eda
@ -244,6 +244,8 @@ int main(void)
|
|||||||
AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON;
|
AFIO_MAPR |= AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON;
|
||||||
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15);
|
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, 0, GPIO15);
|
||||||
|
|
||||||
|
rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_OTGFSEN);
|
||||||
|
|
||||||
usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings);
|
usbd_init(&stm32f107_usb_driver, &dev, &config, usb_strings);
|
||||||
usbd_set_control_buffer_size(sizeof(usbd_control_buffer));
|
usbd_set_control_buffer_size(sizeof(usbd_control_buffer));
|
||||||
usbd_register_control_callback(
|
usbd_register_control_callback(
|
||||||
|
@ -51,6 +51,15 @@ u16 desig_get_flash_size(void);
|
|||||||
*/
|
*/
|
||||||
void desig_get_unique_id(u32 result[]);
|
void desig_get_unique_id(u32 result[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the full 96 bit unique identifier and return it as a
|
||||||
|
* zero-terminated string
|
||||||
|
* @param string memory region to write the result to
|
||||||
|
8 @param string_len the size of string in bytes
|
||||||
|
*/
|
||||||
|
void desig_get_unique_id_as_string(char *string,
|
||||||
|
unsigned int string_len);
|
||||||
|
|
||||||
END_DECLS
|
END_DECLS
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -24,6 +24,13 @@
|
|||||||
|
|
||||||
BEGIN_DECLS
|
BEGIN_DECLS
|
||||||
|
|
||||||
|
|
||||||
|
enum usbd_request_return_codes {
|
||||||
|
USBD_REQ_NOTSUPP = 0,
|
||||||
|
USBD_REQ_HANDLED = 1,
|
||||||
|
USBD_REQ_NEXT_CALLBACK = 2,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct _usbd_driver usbd_driver;
|
typedef struct _usbd_driver usbd_driver;
|
||||||
extern const usbd_driver stm32f103_usb_driver;
|
extern const usbd_driver stm32f103_usb_driver;
|
||||||
extern const usbd_driver stm32f107_usb_driver;
|
extern const usbd_driver stm32f107_usb_driver;
|
||||||
@ -38,7 +45,7 @@ extern u8 usbd_control_buffer[];
|
|||||||
extern int usbd_init(const usbd_driver *driver,
|
extern int usbd_init(const usbd_driver *driver,
|
||||||
const struct usb_device_descriptor *dev,
|
const struct usb_device_descriptor *dev,
|
||||||
const struct usb_config_descriptor *conf,
|
const struct usb_config_descriptor *conf,
|
||||||
const char **strings);
|
const char **strings, int num_strings);
|
||||||
extern void usbd_set_control_buffer_size(u16 size);
|
extern void usbd_set_control_buffer_size(u16 size);
|
||||||
|
|
||||||
extern void usbd_register_reset_callback(void (*callback)(void));
|
extern void usbd_register_reset_callback(void (*callback)(void));
|
||||||
|
@ -220,4 +220,7 @@ struct usb_iface_assoc_descriptor {
|
|||||||
#define USB_DT_INTERFACE_ASSOCIATION_SIZE \
|
#define USB_DT_INTERFACE_ASSOCIATION_SIZE \
|
||||||
sizeof(struct usb_iface_assoc_descriptor)
|
sizeof(struct usb_iface_assoc_descriptor)
|
||||||
|
|
||||||
|
enum usb_language_id {
|
||||||
|
USB_LANGID_ENGLISH_US = 0x409,
|
||||||
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -35,3 +35,25 @@ void desig_get_unique_id(u32 result[])
|
|||||||
result[1] = bits63_32;
|
result[1] = bits63_32;
|
||||||
result[2] = bits31_16 << 16 | bits15_0;
|
result[2] = bits31_16 << 16 | bits15_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void desig_get_unique_id_as_string(char *string,
|
||||||
|
unsigned int string_len)
|
||||||
|
{
|
||||||
|
int i, len;
|
||||||
|
u8 device_id[12];
|
||||||
|
static const char chars[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
desig_get_unique_id((u32 *)device_id);
|
||||||
|
|
||||||
|
/* Each byte produces two characters */
|
||||||
|
len = (2 * sizeof(device_id) < string_len) ?
|
||||||
|
2 * sizeof(device_id) : string_len - 1;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i += 2) {
|
||||||
|
string[i] = chars[(device_id[i / 2] >> 0) & 0x0F];
|
||||||
|
string[i + 1] = chars[(device_id[i / 2] >> 4) & 0x0F];
|
||||||
|
}
|
||||||
|
|
||||||
|
string[len] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -45,12 +45,14 @@ u8 usbd_control_buffer[128] __attribute__((weak));
|
|||||||
*/
|
*/
|
||||||
int usbd_init(const usbd_driver *driver,
|
int usbd_init(const usbd_driver *driver,
|
||||||
const struct usb_device_descriptor *dev,
|
const struct usb_device_descriptor *dev,
|
||||||
const struct usb_config_descriptor *conf, const char **strings)
|
const struct usb_config_descriptor *conf,
|
||||||
|
const char **strings, int num_strings)
|
||||||
{
|
{
|
||||||
_usbd_device.driver = driver;
|
_usbd_device.driver = driver;
|
||||||
_usbd_device.desc = dev;
|
_usbd_device.desc = dev;
|
||||||
_usbd_device.config = conf;
|
_usbd_device.config = conf;
|
||||||
_usbd_device.strings = strings;
|
_usbd_device.strings = strings;
|
||||||
|
_usbd_device.num_strings = num_strings;
|
||||||
_usbd_device.ctrl_buf = usbd_control_buffer;
|
_usbd_device.ctrl_buf = usbd_control_buffer;
|
||||||
_usbd_device.ctrl_buf_len = sizeof(usbd_control_buffer);
|
_usbd_device.ctrl_buf_len = sizeof(usbd_control_buffer);
|
||||||
|
|
||||||
|
@ -102,7 +102,8 @@ static int usb_control_request_dispatch(struct usb_setup_data *req)
|
|||||||
result = cb[i].cb(req, &control_state.ctrl_buf,
|
result = cb[i].cb(req, &control_state.ctrl_buf,
|
||||||
&control_state.ctrl_len,
|
&control_state.ctrl_len,
|
||||||
&control_state.complete);
|
&control_state.complete);
|
||||||
if (result)
|
if (result == USBD_REQ_HANDLED ||
|
||||||
|
result == USBD_REQ_NOTSUPP)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ extern struct _usbd_device {
|
|||||||
const struct usb_device_descriptor *desc;
|
const struct usb_device_descriptor *desc;
|
||||||
const struct usb_config_descriptor *config;
|
const struct usb_config_descriptor *config;
|
||||||
const char **strings;
|
const char **strings;
|
||||||
|
int num_strings;
|
||||||
|
|
||||||
u8 *ctrl_buf; /**< Internal buffer used for control transfers */
|
u8 *ctrl_buf; /**< Internal buffer used for control transfers */
|
||||||
u16 ctrl_buf_len;
|
u16 ctrl_buf_len;
|
||||||
|
@ -87,50 +87,74 @@ static u16 build_config_descriptor(u8 index, u8 *buf, u16 len)
|
|||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int usb_descriptor_type(u16 wValue)
|
||||||
|
{
|
||||||
|
return wValue >> 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int usb_descriptor_index(u16 wValue)
|
||||||
|
{
|
||||||
|
return wValue & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
static int usb_standard_get_descriptor(struct usb_setup_data *req,
|
static int usb_standard_get_descriptor(struct usb_setup_data *req,
|
||||||
u8 **buf, u16 *len)
|
u8 **buf, u16 *len)
|
||||||
{
|
{
|
||||||
int i;
|
int i, array_idx, descr_idx;
|
||||||
struct usb_string_descriptor *sd;
|
struct usb_string_descriptor *sd;
|
||||||
|
|
||||||
switch (req->wValue >> 8) {
|
descr_idx = usb_descriptor_index(req->wValue);
|
||||||
|
|
||||||
|
switch (usb_descriptor_type(req->wValue)) {
|
||||||
case USB_DT_DEVICE:
|
case USB_DT_DEVICE:
|
||||||
*buf = (u8 *) _usbd_device.desc;
|
*buf = (u8 *) _usbd_device.desc;
|
||||||
*len = MIN(*len, _usbd_device.desc->bLength);
|
*len = MIN(*len, _usbd_device.desc->bLength);
|
||||||
return 1;
|
return USBD_REQ_HANDLED;
|
||||||
case USB_DT_CONFIGURATION:
|
case USB_DT_CONFIGURATION:
|
||||||
*buf = _usbd_device.ctrl_buf;
|
*buf = _usbd_device.ctrl_buf;
|
||||||
*len = build_config_descriptor(req->wValue & 0xff, *buf, *len);
|
*len = build_config_descriptor(descr_idx, *buf, *len);
|
||||||
return 1;
|
return USBD_REQ_HANDLED;
|
||||||
case USB_DT_STRING:
|
case USB_DT_STRING:
|
||||||
sd = (struct usb_string_descriptor *)_usbd_device.ctrl_buf;
|
sd = (struct usb_string_descriptor *)_usbd_device.ctrl_buf;
|
||||||
|
|
||||||
if (!_usbd_device.strings)
|
if (descr_idx == 0) {
|
||||||
return 0; /* Device doesn't support strings. */
|
/* Send sane Language ID descriptor... */
|
||||||
|
sd->wData[0] = USB_LANGID_ENGLISH_US;
|
||||||
|
sd->bLength = sizeof(sd->bLength) + sizeof(sd->bDescriptorType)
|
||||||
|
+ sizeof(sd->wData[0]);
|
||||||
|
|
||||||
/* Check that string index is in range. */
|
*len = MIN(*len, sd->bLength);
|
||||||
for (i = 0; i <= (req->wValue & 0xff); i++)
|
} else {
|
||||||
if (_usbd_device.strings[i] == NULL)
|
array_idx = descr_idx - 1;
|
||||||
return 0;
|
|
||||||
|
if (!_usbd_device.strings)
|
||||||
|
return USBD_REQ_NOTSUPP; /* Device doesn't support strings. */
|
||||||
|
/* Check that string index is in range. */
|
||||||
|
if (array_idx >= _usbd_device.num_strings)
|
||||||
|
return USBD_REQ_NOTSUPP;
|
||||||
|
|
||||||
|
/* Strings with Language ID differnet from
|
||||||
|
* USB_LANGID_ENGLISH_US are not supported */
|
||||||
|
if (req->wIndex != USB_LANGID_ENGLISH_US)
|
||||||
|
return USBD_REQ_NOTSUPP;
|
||||||
|
|
||||||
|
/* Ths string is returned as UTF16, hence the multiplication */
|
||||||
|
sd->bLength = strlen(_usbd_device.strings[array_idx]) * 2 +
|
||||||
|
sizeof(sd->bLength) + sizeof(sd->bDescriptorType);
|
||||||
|
|
||||||
|
*len = MIN(*len, sd->bLength);
|
||||||
|
|
||||||
|
for (i = 0; i < (*len / 2) - 1; i++)
|
||||||
|
sd->wData[i] =
|
||||||
|
_usbd_device.strings[array_idx][i];
|
||||||
|
}
|
||||||
|
|
||||||
sd->bLength = strlen(_usbd_device.strings[req->wValue & 0xff])
|
|
||||||
* 2 + 2;
|
|
||||||
sd->bDescriptorType = USB_DT_STRING;
|
sd->bDescriptorType = USB_DT_STRING;
|
||||||
|
|
||||||
*buf = (u8 *)sd;
|
*buf = (u8 *)sd;
|
||||||
*len = MIN(*len, sd->bLength);
|
|
||||||
|
|
||||||
for (i = 0; i < (*len / 2) - 1; i++)
|
return USBD_REQ_HANDLED;
|
||||||
sd->wData[i] =
|
|
||||||
_usbd_device.strings[req->wValue & 0xff][i];
|
|
||||||
|
|
||||||
/* Send sane Language ID descriptor... */
|
|
||||||
if ((req->wValue & 0xff) == 0)
|
|
||||||
sd->wData[0] = 0x409;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return USBD_REQ_NOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int usb_standard_set_address(struct usb_setup_data *req, u8 **buf,
|
static int usb_standard_set_address(struct usb_setup_data *req, u8 **buf,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user