1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-22 23:48:12 +00:00

trezorhal: add configuration, interface strings to usb descriptors, minor typos

This commit is contained in:
Pavol Rusnak 2018-01-20 21:48:53 +01:00
parent 08376a4a54
commit 30ff61b588
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
9 changed files with 147 additions and 122 deletions

View File

@ -134,6 +134,8 @@ static void usb_init_all(void) {
.manufacturer = (const uint8_t *)"SatoshiLabs", .manufacturer = (const uint8_t *)"SatoshiLabs",
.product = (const uint8_t *)"TREZOR Bootloader", .product = (const uint8_t *)"TREZOR Bootloader",
.serial_number = (const uint8_t *)"", .serial_number = (const uint8_t *)"",
.configuration = (const uint8_t *)"",
.interface = (const uint8_t *)"TREZOR Interface",
}; };
static uint8_t hid_rx_buffer[USB_PACKET_SIZE]; static uint8_t hid_rx_buffer[USB_PACKET_SIZE];
static const uint8_t hid_report_desc[] = { static const uint8_t hid_report_desc[] = {

View File

@ -327,9 +327,11 @@ static const char *get_0str(mp_obj_t o, size_t min_len, size_t max_len) {
/// vendor_id: int, /// vendor_id: int,
/// product_id: int, /// product_id: int,
/// release_num: int, /// release_num: int,
/// manufacturer: str, /// manufacturer: str='',
/// product: str, /// product: str='',
/// serial_number: str) -> None: /// serial_number: str='',
/// configuration: str='',
/// interface: str='') -> None:
/// ''' /// '''
/// ''' /// '''
STATIC mp_obj_t mod_trezorio_USB_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { STATIC mp_obj_t mod_trezorio_USB_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
@ -338,9 +340,11 @@ STATIC mp_obj_t mod_trezorio_USB_make_new(const mp_obj_type_t *type, size_t n_ar
{ MP_QSTR_vendor_id, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_vendor_id, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_product_id, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_product_id, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_release_num, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_release_num, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
{ MP_QSTR_manufacturer, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_manufacturer, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
{ MP_QSTR_product, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_product, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
{ MP_QSTR_serial_number, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_serial_number, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
{ MP_QSTR_configuration, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
{ MP_QSTR_interface, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_empty_bytes} },
}; };
mp_arg_val_t vals[MP_ARRAY_SIZE(allowed_args)]; mp_arg_val_t vals[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals); mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals);
@ -351,9 +355,12 @@ STATIC mp_obj_t mod_trezorio_USB_make_new(const mp_obj_type_t *type, size_t n_ar
const char *manufacturer = get_0str(vals[3].u_obj, 0, 32); const char *manufacturer = get_0str(vals[3].u_obj, 0, 32);
const char *product = get_0str(vals[4].u_obj, 0, 32); const char *product = get_0str(vals[4].u_obj, 0, 32);
const char *serial_number = get_0str(vals[5].u_obj, 0, 32); const char *serial_number = get_0str(vals[5].u_obj, 0, 32);
const char *configuration = get_0str(vals[6].u_obj, 0, 32);
const char *interface = get_0str(vals[7].u_obj, 0, 32);
CHECK_PARAM_RANGE(vendor_id, 0, 65535) CHECK_PARAM_RANGE(vendor_id, 0, 65535)
CHECK_PARAM_RANGE(product_id, 0, 65535) CHECK_PARAM_RANGE(product_id, 0, 65535)
CHECK_PARAM_RANGE(release_num, 0, 65535)
if (manufacturer == NULL) { if (manufacturer == NULL) {
mp_raise_ValueError("manufacturer is invalid"); mp_raise_ValueError("manufacturer is invalid");
} }
@ -363,6 +370,12 @@ STATIC mp_obj_t mod_trezorio_USB_make_new(const mp_obj_type_t *type, size_t n_ar
if (serial_number == NULL) { if (serial_number == NULL) {
mp_raise_ValueError("serial_number is invalid"); mp_raise_ValueError("serial_number is invalid");
} }
if (configuration == NULL) {
mp_raise_ValueError("configuration is invalid");
}
if (interface == NULL) {
mp_raise_ValueError("interface is invalid");
}
mp_obj_USB_t *o = m_new_obj(mp_obj_USB_t); mp_obj_USB_t *o = m_new_obj(mp_obj_USB_t);
o->base.type = type; o->base.type = type;
@ -375,6 +388,8 @@ STATIC mp_obj_t mod_trezorio_USB_make_new(const mp_obj_type_t *type, size_t n_ar
o->info.manufacturer = (const uint8_t *)(manufacturer); o->info.manufacturer = (const uint8_t *)(manufacturer);
o->info.product = (const uint8_t *)(product); o->info.product = (const uint8_t *)(product);
o->info.serial_number = (const uint8_t *)(serial_number); o->info.serial_number = (const uint8_t *)(serial_number);
o->info.configuration = (const uint8_t *)(configuration);
o->info.interface = (const uint8_t *)(interface);
mp_obj_list_init(&o->ifaces, 0); mp_obj_list_init(&o->ifaces, 0);
return MP_OBJ_FROM_PTR(o); return MP_OBJ_FROM_PTR(o);

View File

@ -91,7 +91,9 @@ static void usb_init_all(void)
.release_num = 0x0002, .release_num = 0x0002,
.manufacturer = (const uint8_t *)"SatoshiLabs", .manufacturer = (const uint8_t *)"SatoshiLabs",
.product = (const uint8_t *)"TREZOR", .product = (const uint8_t *)"TREZOR",
.serial_number = (const uint8_t *)"", .serial_number = (const uint8_t *)"000000000000",
.configuration = (const uint8_t *)"",
.interface = (const uint8_t *)"TREZOR Interface",
}; };
static uint8_t tx_packet[VCP_PACKET_LEN]; static uint8_t tx_packet[VCP_PACKET_LEN];

View File

@ -53,8 +53,8 @@ void usb_init(const usb_dev_info_t *dev_info) {
// Device descriptor // Device descriptor
usb_dev_desc.bLength = sizeof(usb_device_descriptor_t); usb_dev_desc.bLength = sizeof(usb_device_descriptor_t);
usb_dev_desc.bDescriptorType = USB_DESC_TYPE_DEVICE; usb_dev_desc.bDescriptorType = USB_DESC_TYPE_DEVICE;
usb_dev_desc.bcdUSB = 0x0200; usb_dev_desc.bcdUSB = 0x0200; // USB 2.0
usb_dev_desc.bDeviceClass = 0xef; // Composite Device Class usb_dev_desc.bDeviceClass = 0xEF; // Composite Device Class
usb_dev_desc.bDeviceSubClass = 0x02; // Common Class usb_dev_desc.bDeviceSubClass = 0x02; // Common Class
usb_dev_desc.bDeviceProtocol = 0x01; // Interface Association Descriptor usb_dev_desc.bDeviceProtocol = 0x01; // Interface Association Descriptor
usb_dev_desc.bMaxPacketSize0 = USB_MAX_EP0_SIZE; usb_dev_desc.bMaxPacketSize0 = USB_MAX_EP0_SIZE;
@ -74,6 +74,8 @@ void usb_init(const usb_dev_info_t *dev_info) {
usb_str_table.manufacturer = dev_info->manufacturer; usb_str_table.manufacturer = dev_info->manufacturer;
usb_str_table.product = dev_info->product; usb_str_table.product = dev_info->product;
usb_str_table.serial_number = dev_info->serial_number; usb_str_table.serial_number = dev_info->serial_number;
usb_str_table.configuration = dev_info->configuration;
usb_str_table.interface = dev_info->interface;
// Configuration descriptor // Configuration descriptor
usb_config_desc->bLength = sizeof(usb_config_descriptor_t); usb_config_desc->bLength = sizeof(usb_config_descriptor_t);
@ -81,9 +83,9 @@ void usb_init(const usb_dev_info_t *dev_info) {
usb_config_desc->wTotalLength = sizeof(usb_config_descriptor_t); usb_config_desc->wTotalLength = sizeof(usb_config_descriptor_t);
usb_config_desc->bNumInterfaces = 0; usb_config_desc->bNumInterfaces = 0;
usb_config_desc->bConfigurationValue = 0x01; usb_config_desc->bConfigurationValue = 0x01;
usb_config_desc->iConfiguration = 0; usb_config_desc->iConfiguration = USBD_IDX_CONFIG_STR;
usb_config_desc->bmAttributes = 0x80; // 0x80 = bus powered; 0xc0 = self powered usb_config_desc->bmAttributes = 0x80; // 0x80 = bus powered; 0xC0 = self powered
usb_config_desc->bMaxPower = 0xfa; // Maximum Power Consumption in 2mA units usb_config_desc->bMaxPower = 0xFA; // Maximum Power Consumption in 2mA units
// Pointer to interface descriptor data // Pointer to interface descriptor data
usb_next_iface_desc = (usb_interface_descriptor_t *)(usb_config_buf + usb_config_desc->wTotalLength); usb_next_iface_desc = (usb_interface_descriptor_t *)(usb_config_buf + usb_config_desc->wTotalLength);
@ -174,27 +176,27 @@ static uint8_t *usb_get_langid_str_descriptor(USBD_SpeedTypeDef speed, uint16_t
} }
static uint8_t *usb_get_manufacturer_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) { static uint8_t *usb_get_manufacturer_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
USBD_GetString(UNCONST(usb_str_table.manufacturer), usb_str_buf, length); USBD_GetString(usb_str_table.manufacturer, usb_str_buf, length);
return usb_str_buf; return usb_str_buf;
} }
static uint8_t *usb_get_product_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) { static uint8_t *usb_get_product_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
USBD_GetString(UNCONST(usb_str_table.product), usb_str_buf, length); USBD_GetString(usb_str_table.product, usb_str_buf, length);
return usb_str_buf; return usb_str_buf;
} }
static uint8_t *usb_get_serial_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) { static uint8_t *usb_get_serial_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
USBD_GetString(UNCONST(usb_str_table.serial_number), usb_str_buf, length); USBD_GetString(usb_str_table.serial_number, usb_str_buf, length);
return usb_str_buf; return usb_str_buf;
} }
static uint8_t *usb_get_config_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) { static uint8_t *usb_get_configuration_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
USBD_GetString(UNCONST(""), usb_str_buf, length); USBD_GetString(usb_str_table.configuration, usb_str_buf, length);
return usb_str_buf; return usb_str_buf;
} }
static uint8_t *usb_get_interface_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) { static uint8_t *usb_get_interface_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
USBD_GetString(UNCONST(""), usb_str_buf, length); USBD_GetString(usb_str_table.interface, usb_str_buf, length);
return usb_str_buf; return usb_str_buf;
} }
@ -204,7 +206,7 @@ static const USBD_DescriptorsTypeDef usb_descriptors = {
.GetManufacturerStrDescriptor = usb_get_manufacturer_str_descriptor, .GetManufacturerStrDescriptor = usb_get_manufacturer_str_descriptor,
.GetProductStrDescriptor = usb_get_product_str_descriptor, .GetProductStrDescriptor = usb_get_product_str_descriptor,
.GetSerialStrDescriptor = usb_get_serial_str_descriptor, .GetSerialStrDescriptor = usb_get_serial_str_descriptor,
.GetConfigurationStrDescriptor = usb_get_config_str_descriptor, .GetConfigurationStrDescriptor = usb_get_configuration_str_descriptor,
.GetInterfaceStrDescriptor = usb_get_interface_str_descriptor, .GetInterfaceStrDescriptor = usb_get_interface_str_descriptor,
}; };
@ -231,14 +233,14 @@ static uint8_t usb_class_init(USBD_HandleTypeDef *dev, uint8_t cfg_idx) {
static uint8_t usb_class_deinit(USBD_HandleTypeDef *dev, uint8_t cfg_idx) { static uint8_t usb_class_deinit(USBD_HandleTypeDef *dev, uint8_t cfg_idx) {
for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) { for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) {
switch (usb_ifaces[i].type) { switch (usb_ifaces[i].type) {
case USB_IFACE_TYPE_HID: case USB_IFACE_TYPE_HID:
usb_hid_class_deinit(dev, &usb_ifaces[i].hid, cfg_idx); usb_hid_class_deinit(dev, &usb_ifaces[i].hid, cfg_idx);
break; break;
case USB_IFACE_TYPE_VCP: case USB_IFACE_TYPE_VCP:
usb_vcp_class_deinit(dev, &usb_ifaces[i].vcp, cfg_idx); usb_vcp_class_deinit(dev, &usb_ifaces[i].vcp, cfg_idx);
break; break;
default: default:
break; break;
} }
} }
return USBD_OK; return USBD_OK;
@ -253,26 +255,26 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
return USBD_FAIL; return USBD_FAIL;
} }
switch (usb_ifaces[req->wIndex].type) { switch (usb_ifaces[req->wIndex].type) {
case USB_IFACE_TYPE_HID: case USB_IFACE_TYPE_HID:
return usb_hid_class_setup(dev, &usb_ifaces[req->wIndex].hid, req); return usb_hid_class_setup(dev, &usb_ifaces[req->wIndex].hid, req);
case USB_IFACE_TYPE_VCP: case USB_IFACE_TYPE_VCP:
return usb_vcp_class_setup(dev, &usb_ifaces[req->wIndex].vcp, req); return usb_vcp_class_setup(dev, &usb_ifaces[req->wIndex].vcp, req);
default: default:
return USBD_FAIL; return USBD_FAIL;
} }
} }
static uint8_t usb_class_data_in(USBD_HandleTypeDef *dev, uint8_t ep_num) { static uint8_t usb_class_data_in(USBD_HandleTypeDef *dev, uint8_t ep_num) {
for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) { for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) {
switch (usb_ifaces[i].type) { switch (usb_ifaces[i].type) {
case USB_IFACE_TYPE_HID: case USB_IFACE_TYPE_HID:
usb_hid_class_data_in(dev, &usb_ifaces[i].hid, ep_num); usb_hid_class_data_in(dev, &usb_ifaces[i].hid, ep_num);
break; break;
case USB_IFACE_TYPE_VCP: case USB_IFACE_TYPE_VCP:
usb_vcp_class_data_in(dev, &usb_ifaces[i].vcp, ep_num); usb_vcp_class_data_in(dev, &usb_ifaces[i].vcp, ep_num);
break; break;
default: default:
break; break;
} }
} }
return USBD_OK; return USBD_OK;
@ -281,14 +283,14 @@ static uint8_t usb_class_data_in(USBD_HandleTypeDef *dev, uint8_t ep_num) {
static uint8_t usb_class_data_out(USBD_HandleTypeDef *dev, uint8_t ep_num) { static uint8_t usb_class_data_out(USBD_HandleTypeDef *dev, uint8_t ep_num) {
for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) { for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) {
switch (usb_ifaces[i].type) { switch (usb_ifaces[i].type) {
case USB_IFACE_TYPE_HID: case USB_IFACE_TYPE_HID:
usb_hid_class_data_out(dev, &usb_ifaces[i].hid, ep_num); usb_hid_class_data_out(dev, &usb_ifaces[i].hid, ep_num);
break; break;
case USB_IFACE_TYPE_VCP: case USB_IFACE_TYPE_VCP:
usb_vcp_class_data_out(dev, &usb_ifaces[i].vcp, ep_num); usb_vcp_class_data_out(dev, &usb_ifaces[i].vcp, ep_num);
break; break;
default: default:
break; break;
} }
} }
return USBD_OK; return USBD_OK;
@ -297,11 +299,11 @@ static uint8_t usb_class_data_out(USBD_HandleTypeDef *dev, uint8_t ep_num) {
static uint8_t usb_class_sof(USBD_HandleTypeDef *dev) { static uint8_t usb_class_sof(USBD_HandleTypeDef *dev) {
for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) { for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) {
switch (usb_ifaces[i].type) { switch (usb_ifaces[i].type) {
case USB_IFACE_TYPE_VCP: case USB_IFACE_TYPE_VCP:
usb_vcp_class_sof(dev, &usb_ifaces[i].vcp); usb_vcp_class_sof(dev, &usb_ifaces[i].vcp);
break; break;
default: default:
break; break;
} }
} }
return USBD_OK; return USBD_OK;

View File

@ -89,6 +89,8 @@ typedef struct {
const uint8_t *manufacturer; const uint8_t *manufacturer;
const uint8_t *product; const uint8_t *product;
const uint8_t *serial_number; const uint8_t *serial_number;
const uint8_t *configuration;
const uint8_t *interface;
} usb_dev_string_table_t; } usb_dev_string_table_t;
typedef struct { typedef struct {
@ -98,6 +100,8 @@ typedef struct {
const uint8_t *manufacturer; const uint8_t *manufacturer;
const uint8_t *product; const uint8_t *product;
const uint8_t *serial_number; const uint8_t *serial_number;
const uint8_t *configuration;
const uint8_t *interface;
} usb_dev_info_t; } usb_dev_info_t;
typedef enum { typedef enum {

View File

@ -56,12 +56,12 @@ secbool usb_hid_add(const usb_hid_info_t *info) {
d->iface.bInterfaceClass = USB_CLASS_HID; d->iface.bInterfaceClass = USB_CLASS_HID;
d->iface.bInterfaceSubClass = info->subclass; d->iface.bInterfaceSubClass = info->subclass;
d->iface.bInterfaceProtocol = info->protocol; d->iface.bInterfaceProtocol = info->protocol;
d->iface.iInterface = 0; d->iface.iInterface = USBD_IDX_INTERFACE_STR;
// HID descriptor // HID descriptor
d->hid.bLength = sizeof(usb_hid_descriptor_t); d->hid.bLength = sizeof(usb_hid_descriptor_t);
d->hid.bDescriptorType = USB_DESC_TYPE_HID; d->hid.bDescriptorType = USB_DESC_TYPE_HID;
d->hid.bcdHID = 0x1101; // HID Class Spec release number d->hid.bcdHID = 0x0111; // HID Class Spec release number (1.11)
d->hid.bCountryCode = 0; // Hardware target country d->hid.bCountryCode = 0; // Hardware target country
d->hid.bNumDescriptors = 1; // Number of HID class descriptors d->hid.bNumDescriptors = 1; // Number of HID class descriptors
d->hid.bReportDescriptorType = USB_DESC_TYPE_REPORT; d->hid.bReportDescriptorType = USB_DESC_TYPE_REPORT;
@ -244,58 +244,58 @@ static void usb_hid_class_deinit(USBD_HandleTypeDef *dev, usb_hid_state_t *state
static int usb_hid_class_setup(USBD_HandleTypeDef *dev, usb_hid_state_t *state, USBD_SetupReqTypedef *req) { static int usb_hid_class_setup(USBD_HandleTypeDef *dev, usb_hid_state_t *state, USBD_SetupReqTypedef *req) {
switch (req->bmRequest & USB_REQ_TYPE_MASK) { switch (req->bmRequest & USB_REQ_TYPE_MASK) {
// Class request // Class request
case USB_REQ_TYPE_CLASS: case USB_REQ_TYPE_CLASS:
switch (req->bRequest) { switch (req->bRequest) {
case USB_HID_REQ_SET_PROTOCOL: case USB_HID_REQ_SET_PROTOCOL:
state->protocol = req->wValue; state->protocol = req->wValue;
break;
case USB_HID_REQ_GET_PROTOCOL:
USBD_CtlSendData(dev, &state->protocol, sizeof(state->protocol));
break;
case USB_HID_REQ_SET_IDLE:
state->idle_rate = req->wValue >> 8;
break;
case USB_HID_REQ_GET_IDLE:
USBD_CtlSendData(dev, &state->idle_rate, sizeof(state->idle_rate));
break;
default:
USBD_CtlError(dev, req);
return USBD_FAIL;
}
break;
// Interface & Endpoint request
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest) {
case USB_REQ_SET_INTERFACE:
state->alt_setting = req->wValue;
break;
case USB_REQ_GET_INTERFACE:
USBD_CtlSendData(dev, &state->alt_setting, sizeof(state->alt_setting));
break;
case USB_REQ_GET_DESCRIPTOR:
switch (req->wValue >> 8) {
case USB_DESC_TYPE_HID:
USBD_CtlSendData(dev, (uint8_t *)&state->desc_block->hid, MIN(req->wLength, sizeof(state->desc_block->hid)));
break; break;
case USB_DESC_TYPE_REPORT: case USB_HID_REQ_GET_PROTOCOL:
USBD_CtlSendData(dev, UNCONST(state->report_desc), MIN(req->wLength, state->report_desc_len)); USBD_CtlSendData(dev, &state->protocol, sizeof(state->protocol));
break; break;
case USB_HID_REQ_SET_IDLE:
state->idle_rate = req->wValue >> 8;
break;
case USB_HID_REQ_GET_IDLE:
USBD_CtlSendData(dev, &state->idle_rate, sizeof(state->idle_rate));
break;
default:
USBD_CtlError(dev, req);
return USBD_FAIL;
}
break;
// Interface & Endpoint request
case USB_REQ_TYPE_STANDARD:
switch (req->bRequest) {
case USB_REQ_SET_INTERFACE:
state->alt_setting = req->wValue;
break;
case USB_REQ_GET_INTERFACE:
USBD_CtlSendData(dev, &state->alt_setting, sizeof(state->alt_setting));
break;
case USB_REQ_GET_DESCRIPTOR:
switch (req->wValue >> 8) {
case USB_DESC_TYPE_HID:
USBD_CtlSendData(dev, (uint8_t *)&state->desc_block->hid, MIN(req->wLength, sizeof(state->desc_block->hid)));
break;
case USB_DESC_TYPE_REPORT:
USBD_CtlSendData(dev, UNCONST(state->report_desc), MIN(req->wLength, state->report_desc_len));
break;
}
break;
} }
break; break;
}
break;
} }
return USBD_OK; return USBD_OK;

View File

@ -18,7 +18,7 @@
#define USB_CDC_PROTOCOL_AT 0x01 #define USB_CDC_PROTOCOL_AT 0x01
// Descriptor Types (bDescriptorType) // Descriptor Types (bDescriptorType)
#define USB_DESC_TYPE_ASSOCIATION 0x0b #define USB_DESC_TYPE_ASSOCIATION 0x0B
#define USB_DESC_TYPE_CS_INTERACE 0x24 #define USB_DESC_TYPE_CS_INTERACE 0x24
// Descriptor SubTypes (bDescriptorSubtype) // Descriptor SubTypes (bDescriptorSubtype)
@ -106,7 +106,7 @@ secbool usb_vcp_add(const usb_vcp_info_t *info) {
d->iface_cdc.bInterfaceClass = USB_CLASS_CDC; d->iface_cdc.bInterfaceClass = USB_CLASS_CDC;
d->iface_cdc.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM; d->iface_cdc.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM;
d->iface_cdc.bInterfaceProtocol = USB_CDC_PROTOCOL_AT; d->iface_cdc.bInterfaceProtocol = USB_CDC_PROTOCOL_AT;
d->iface_cdc.iInterface = 0; d->iface_cdc.iInterface = USBD_IDX_INTERFACE_STR;
// Header Functional Descriptor // Header Functional Descriptor
d->fheader.bFunctionLength = sizeof(usb_vcp_header_descriptor_t); d->fheader.bFunctionLength = sizeof(usb_vcp_header_descriptor_t);
@ -155,7 +155,7 @@ secbool usb_vcp_add(const usb_vcp_info_t *info) {
d->iface_data.bInterfaceClass = USB_CLASS_DATA; d->iface_data.bInterfaceClass = USB_CLASS_DATA;
d->iface_data.bInterfaceSubClass = 0; d->iface_data.bInterfaceSubClass = 0;
d->iface_data.bInterfaceProtocol = 0; d->iface_data.bInterfaceProtocol = 0;
d->iface_data.iInterface = 0; d->iface_data.iInterface = USBD_IDX_INTERFACE_STR;
// OUT endpoint (receiving) // OUT endpoint (receiving)
d->ep_out.bLength = sizeof(usb_endpoint_descriptor_t); d->ep_out.bLength = sizeof(usb_endpoint_descriptor_t);
@ -357,21 +357,21 @@ static int usb_vcp_class_setup(USBD_HandleTypeDef *dev, usb_vcp_state_t *state,
} }
switch (req->bmRequest & USB_REQ_DIR_MASK) { switch (req->bmRequest & USB_REQ_DIR_MASK) {
case USB_D2H: case USB_D2H:
switch (req->bRequest) { switch (req->bRequest) {
case USB_CDC_GET_LINE_CODING: case USB_CDC_GET_LINE_CODING:
USBD_CtlSendData(dev, (uint8_t *)(&line_coding), MIN(req->wLength, sizeof(line_coding))); USBD_CtlSendData(dev, (uint8_t *)(&line_coding), MIN(req->wLength, sizeof(line_coding)));
break;
default:
USBD_CtlSendData(dev, cmd_buffer, MIN(req->wLength, sizeof(cmd_buffer)));
break;
}
break; break;
default: case USB_H2D:
USBD_CtlSendData(dev, cmd_buffer, MIN(req->wLength, sizeof(cmd_buffer))); if (req->wLength > 0) {
USBD_CtlPrepareRx(dev, cmd_buffer, MIN(req->wLength, sizeof(cmd_buffer)));
}
break; break;
}
break;
case USB_H2D:
if (req->wLength > 0) {
USBD_CtlPrepareRx(dev, cmd_buffer, MIN(req->wLength, sizeof(cmd_buffer)));
}
break;
} }
return USBD_OK; return USBD_OK;

View File

@ -97,7 +97,7 @@ static void USBD_SetFeature(USBD_HandleTypeDef *pdev ,
static void USBD_ClrFeature(USBD_HandleTypeDef *pdev , static void USBD_ClrFeature(USBD_HandleTypeDef *pdev ,
USBD_SetupReqTypedef *req); USBD_SetupReqTypedef *req);
static uint8_t USBD_GetLen(uint8_t *buf); static uint8_t USBD_GetLen(const uint8_t *buf);
/** /**
* @} * @}
@ -729,7 +729,7 @@ void USBD_CtlError( USBD_HandleTypeDef *pdev ,
* @param len : descriptor length * @param len : descriptor length
* @retval None * @retval None
*/ */
void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len) void USBD_GetString(const uint8_t *desc, uint8_t *unicode, uint16_t *len)
{ {
uint8_t idx = 0; uint8_t idx = 0;
@ -753,7 +753,7 @@ void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len)
* @param buf : pointer to the ascii string buffer * @param buf : pointer to the ascii string buffer
* @retval string length * @retval string length
*/ */
static uint8_t USBD_GetLen(uint8_t *buf) static uint8_t USBD_GetLen(const uint8_t *buf)
{ {
uint8_t len = 0; uint8_t len = 0;

View File

@ -90,7 +90,7 @@ void USBD_CtlError (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
void USBD_ParseSetupRequest (USBD_SetupReqTypedef *req, uint8_t *pdata); void USBD_ParseSetupRequest (USBD_SetupReqTypedef *req, uint8_t *pdata);
void USBD_GetString (uint8_t *desc, uint8_t *unicode, uint16_t *len); void USBD_GetString (const uint8_t *desc, uint8_t *unicode, uint16_t *len);
/** /**
* @} * @}
*/ */