mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 15:38:11 +00:00
trezorhal: cleanup hid, usb
This commit is contained in:
parent
f12c630914
commit
137d27d69e
@ -60,11 +60,13 @@ int usb_init(const usb_dev_info_t *dev_info) {
|
||||
usb_dev_desc.bNumConfigurations = 1;
|
||||
|
||||
// String table
|
||||
if (0 != check_desc_str(dev_info->manufacturer_str)) return 1;
|
||||
if (0 != check_desc_str(dev_info->product_str)) return 1;
|
||||
if (0 != check_desc_str(dev_info->serial_number_str)) return 1;
|
||||
if (0 != check_desc_str(dev_info->configuration_str)) return 1;
|
||||
if (0 != check_desc_str(dev_info->interface_str)) return 1;
|
||||
if ((0 != check_desc_str(dev_info->manufacturer_str)) ||
|
||||
(0 != check_desc_str(dev_info->product_str)) ||
|
||||
(0 != check_desc_str(dev_info->serial_number_str)) ||
|
||||
(0 != check_desc_str(dev_info->configuration_str)) ||
|
||||
(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.product_str = dev_info->product_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) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -39,11 +39,11 @@ typedef struct {
|
||||
uint8_t ep_out; // Address of OUT endpoint
|
||||
uint8_t subclass; // usb_iface_subclass_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 report_desc_len;
|
||||
const uint8_t *report_desc;
|
||||
uint8_t *rx_buffer; // Big enough for max_packet_len
|
||||
uint8_t max_packet_len; // Length of the biggest report and of rx_buffer
|
||||
uint8_t report_desc_len; // Length of report_desc
|
||||
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;
|
||||
|
||||
typedef struct {
|
||||
@ -51,9 +51,8 @@ typedef struct {
|
||||
uint8_t protocol; // For SET_PROTOCOL/GET_PROTOCOL 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 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_out;
|
||||
uint8_t max_packet_len;
|
||||
|
@ -5,6 +5,8 @@
|
||||
* see LICENSE file for details
|
||||
*/
|
||||
|
||||
#define USB_CLASS_HID 0x03
|
||||
|
||||
#define USB_DESC_TYPE_HID 0x21
|
||||
#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.bInterfaceNumber = info->iface_num;
|
||||
d->iface.bAlternateSetting = 0x00;
|
||||
d->iface.bNumEndpoints = 0x02;
|
||||
d->iface.bInterfaceClass = 0x03; // HID Class
|
||||
d->iface.bNumEndpoints = 2;
|
||||
d->iface.bInterfaceClass = USB_CLASS_HID;
|
||||
d->iface.bInterfaceSubClass = info->subclass;
|
||||
d->iface.bInterfaceProtocol = info->protocol;
|
||||
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.bcdHID = 0x1101; // HID Class Spec release number
|
||||
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.wReportDescriptorLength = info->report_desc_len;
|
||||
|
||||
@ -86,11 +88,15 @@ int usb_hid_add(const usb_hid_info_t *info) {
|
||||
|
||||
// Interface state
|
||||
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_out = info->ep_out;
|
||||
iface->hid.rx_buffer = info->rx_buffer;
|
||||
iface->hid.max_packet_len = info->max_packet_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.desc_block = d;
|
||||
|
||||
@ -105,7 +111,7 @@ int usb_hid_can_read(uint8_t iface_num) {
|
||||
if (iface->type != USB_IFACE_TYPE_HID) {
|
||||
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
|
||||
}
|
||||
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;
|
||||
|
||||
// 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
|
||||
}
|
||||
len = state->rx_buffer_len;
|
||||
state->rx_buffer_len = 0;
|
||||
len = state->last_read_len;
|
||||
state->last_read_len = 0;
|
||||
memcpy(buf, state->rx_buffer, len);
|
||||
|
||||
// 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) {
|
||||
if (ep_num == state->ep_out) {
|
||||
// User should provide state->rx_buffer_len that is big
|
||||
// enough for state->max_packet_len bytes.
|
||||
state->rx_buffer_len = USBD_LL_GetRxDataSize(dev, ep_num);
|
||||
state->last_read_len = USBD_LL_GetRxDataSize(dev, ep_num);
|
||||
|
||||
// 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);
|
||||
|
||||
if (state->rx_buffer_len > 0) {
|
||||
if (state->last_read_len > 0) {
|
||||
// Block the OUT EP until we process received data
|
||||
usb_ep_set_nak(dev, ep_num);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user