1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-26 09:28:13 +00:00

trezorhal: cleanup hid, usb

This commit is contained in:
Jan Pochyla 2017-04-10 18:28:35 +02:00
parent f12c630914
commit 137d27d69e
3 changed files with 38 additions and 23 deletions

View File

@ -60,11 +60,13 @@ int usb_init(const usb_dev_info_t *dev_info) {
usb_dev_desc.bNumConfigurations = 1; usb_dev_desc.bNumConfigurations = 1;
// String table // String table
if (0 != check_desc_str(dev_info->manufacturer_str)) return 1; if ((0 != check_desc_str(dev_info->manufacturer_str)) ||
if (0 != check_desc_str(dev_info->product_str)) return 1; (0 != check_desc_str(dev_info->product_str)) ||
if (0 != check_desc_str(dev_info->serial_number_str)) return 1; (0 != check_desc_str(dev_info->serial_number_str)) ||
if (0 != check_desc_str(dev_info->configuration_str)) return 1; (0 != check_desc_str(dev_info->configuration_str)) ||
if (0 != check_desc_str(dev_info->interface_str)) return 1; (0 != check_desc_str(dev_info->interface_str))) {
return 1; // Invalid descriptor string
}
usb_str_table.manufacturer_str = dev_info->manufacturer_str; usb_str_table.manufacturer_str = dev_info->manufacturer_str;
usb_str_table.product_str = dev_info->product_str; usb_str_table.product_str = dev_info->product_str;
usb_str_table.serial_str = dev_info->serial_number_str; usb_str_table.serial_str = dev_info->serial_number_str;
@ -265,6 +267,15 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
} }
static uint8_t usb_class_ep0_rx_ready(USBD_HandleTypeDef *dev) { static uint8_t usb_class_ep0_rx_ready(USBD_HandleTypeDef *dev) {
for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) {
switch (usb_ifaces[i].type) {
case USB_IFACE_TYPE_VCP:
usb_vcp_class_ep0_rx_ready(dev, &usb_ifaces[i].vcp);
break;
default:
break;
}
}
return USBD_OK; return USBD_OK;
} }

View File

@ -39,11 +39,11 @@ typedef struct {
uint8_t ep_out; // Address of OUT endpoint uint8_t ep_out; // Address of OUT endpoint
uint8_t subclass; // usb_iface_subclass_t uint8_t subclass; // usb_iface_subclass_t
uint8_t protocol; // usb_iface_protocol_t uint8_t protocol; // usb_iface_protocol_t
uint8_t max_packet_len; // rx_buffer should be big enough
uint8_t polling_interval; // In units of 1ms uint8_t polling_interval; // In units of 1ms
uint8_t report_desc_len; uint8_t max_packet_len; // Length of the biggest report and of rx_buffer
const uint8_t *report_desc; uint8_t report_desc_len; // Length of report_desc
uint8_t *rx_buffer; // Big enough for max_packet_len uint8_t *rx_buffer; // With length of max_packet_len bytes
const uint8_t *report_desc; // With length of report_desc_len bytes
} usb_hid_info_t; } usb_hid_info_t;
typedef struct { typedef struct {
@ -51,9 +51,8 @@ typedef struct {
uint8_t protocol; // For SET_PROTOCOL/GET_PROTOCOL setup reqs uint8_t protocol; // For SET_PROTOCOL/GET_PROTOCOL setup reqs
uint8_t idle_rate; // For SET_IDLE/GET_IDLE setup reqs uint8_t idle_rate; // For SET_IDLE/GET_IDLE setup reqs
uint8_t alt_setting; // For SET_INTERFACE/GET_INTERFACE setup reqs uint8_t alt_setting; // For SET_INTERFACE/GET_INTERFACE setup reqs
uint8_t rx_buffer_len; // Length of data read into rx_buffer uint8_t last_read_len; // Length of data read into rx_buffer
// Configuration (copied from usb_hid_info_t on init)
uint8_t ep_in; uint8_t ep_in;
uint8_t ep_out; uint8_t ep_out;
uint8_t max_packet_len; uint8_t max_packet_len;

View File

@ -5,6 +5,8 @@
* see LICENSE file for details * see LICENSE file for details
*/ */
#define USB_CLASS_HID 0x03
#define USB_DESC_TYPE_HID 0x21 #define USB_DESC_TYPE_HID 0x21
#define USB_DESC_TYPE_REPORT 0x22 #define USB_DESC_TYPE_REPORT 0x22
@ -50,8 +52,8 @@ int usb_hid_add(const usb_hid_info_t *info) {
d->iface.bDescriptorType = USB_DESC_TYPE_INTERFACE; d->iface.bDescriptorType = USB_DESC_TYPE_INTERFACE;
d->iface.bInterfaceNumber = info->iface_num; d->iface.bInterfaceNumber = info->iface_num;
d->iface.bAlternateSetting = 0x00; d->iface.bAlternateSetting = 0x00;
d->iface.bNumEndpoints = 0x02; d->iface.bNumEndpoints = 2;
d->iface.bInterfaceClass = 0x03; // HID Class 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 = 0x00; // Index of string descriptor describing the interface d->iface.iInterface = 0x00; // Index of string descriptor describing the interface
@ -61,7 +63,7 @@ int usb_hid_add(const usb_hid_info_t *info) {
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 = 0x1101; // HID Class Spec release number
d->hid.bCountryCode = 0x00; // Hardware target country d->hid.bCountryCode = 0x00; // Hardware target country
d->hid.bNumDescriptors = 0x01; // Number of HID class descriptors to follow d->hid.bNumDescriptors = 1; // Number of HID class descriptors
d->hid.bReportDescriptorType = USB_DESC_TYPE_REPORT; d->hid.bReportDescriptorType = USB_DESC_TYPE_REPORT;
d->hid.wReportDescriptorLength = info->report_desc_len; d->hid.wReportDescriptorLength = info->report_desc_len;
@ -86,11 +88,15 @@ int usb_hid_add(const usb_hid_info_t *info) {
// Interface state // Interface state
iface->type = USB_IFACE_TYPE_HID; iface->type = USB_IFACE_TYPE_HID;
iface->hid.in_idle = 1;
iface->hid.protocol = 0;
iface->hid.idle_rate = 0;
iface->hid.alt_setting = 0;
iface->hid.ep_in = info->ep_in; iface->hid.ep_in = info->ep_in;
iface->hid.ep_out = info->ep_out; iface->hid.ep_out = info->ep_out;
iface->hid.rx_buffer = info->rx_buffer;
iface->hid.max_packet_len = info->max_packet_len; iface->hid.max_packet_len = info->max_packet_len;
iface->hid.report_desc_len = info->report_desc_len; iface->hid.report_desc_len = info->report_desc_len;
iface->hid.rx_buffer = info->rx_buffer;
iface->hid.report_desc = info->report_desc; iface->hid.report_desc = info->report_desc;
iface->hid.desc_block = d; iface->hid.desc_block = d;
@ -105,7 +111,7 @@ int usb_hid_can_read(uint8_t iface_num) {
if (iface->type != USB_IFACE_TYPE_HID) { if (iface->type != USB_IFACE_TYPE_HID) {
return 0; // Invalid interface type return 0; // Invalid interface type
} }
if (iface->hid.rx_buffer_len == 0) { if (iface->hid.last_read_len == 0) {
return 0; // Nothing in the receiving buffer return 0; // Nothing in the receiving buffer
} }
if (usb_dev_handle.dev_state != USBD_STATE_CONFIGURED) { if (usb_dev_handle.dev_state != USBD_STATE_CONFIGURED) {
@ -142,11 +148,11 @@ int usb_hid_read(uint8_t iface_num, uint8_t *buf, uint32_t len) {
usb_hid_state_t *state = &iface->hid; usb_hid_state_t *state = &iface->hid;
// Copy maximum possible amount of data and truncate the buffer length // Copy maximum possible amount of data and truncate the buffer length
if (len < state->rx_buffer_len) { if (len < state->last_read_len) {
return 0; // Not enough data in the read buffer return 0; // Not enough data in the read buffer
} }
len = state->rx_buffer_len; len = state->last_read_len;
state->rx_buffer_len = 0; state->last_read_len = 0;
memcpy(buf, state->rx_buffer, len); memcpy(buf, state->rx_buffer, len);
// Clear NAK to indicate we are ready to read more data // Clear NAK to indicate we are ready to read more data
@ -302,14 +308,13 @@ static uint8_t usb_hid_class_data_in(USBD_HandleTypeDef *dev, usb_hid_state_t *s
static uint8_t usb_hid_class_data_out(USBD_HandleTypeDef *dev, usb_hid_state_t *state, uint8_t ep_num) { static uint8_t usb_hid_class_data_out(USBD_HandleTypeDef *dev, usb_hid_state_t *state, uint8_t ep_num) {
if (ep_num == state->ep_out) { if (ep_num == state->ep_out) {
// User should provide state->rx_buffer_len that is big state->last_read_len = USBD_LL_GetRxDataSize(dev, ep_num);
// enough for state->max_packet_len bytes.
state->rx_buffer_len = USBD_LL_GetRxDataSize(dev, ep_num);
// Prepare the OUT EP to receive next packet // Prepare the OUT EP to receive next packet
// User should provide state->rx_buffer that is big enough for state->max_packet_len bytes
USBD_LL_PrepareReceive(dev, ep_num, state->rx_buffer, state->max_packet_len); USBD_LL_PrepareReceive(dev, ep_num, state->rx_buffer, state->max_packet_len);
if (state->rx_buffer_len > 0) { if (state->last_read_len > 0) {
// Block the OUT EP until we process received data // Block the OUT EP until we process received data
usb_ep_set_nak(dev, ep_num); usb_ep_set_nak(dev, ep_num);
} }