From 8eb5cbbe13f438fd93d66abcca8680f8fad23097 Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Mon, 27 Mar 2017 00:59:52 +0200 Subject: [PATCH] trezorhal: add stubs for vcp interface --- micropython/trezorhal/usb.c | 15 +++++++ micropython/trezorhal/usb.h | 4 +- micropython/trezorhal/usb_vcp-defs.h | 31 ++++++++++++++ micropython/trezorhal/usb_vcp-impl.h | 63 ++++++++++++++++++++++++++++ 4 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 micropython/trezorhal/usb_vcp-defs.h create mode 100644 micropython/trezorhal/usb_vcp-impl.h diff --git a/micropython/trezorhal/usb.c b/micropython/trezorhal/usb.c index 57934d18..d2eee8c6 100644 --- a/micropython/trezorhal/usb.c +++ b/micropython/trezorhal/usb.c @@ -159,6 +159,7 @@ static uint8_t usb_ep_clear_nak(USBD_HandleTypeDef *dev, uint8_t ep_num) { } #include "usb_hid-impl.h" +#include "usb_vcp-impl.h" static uint8_t usb_class_init(USBD_HandleTypeDef *dev, uint8_t cfg_idx) { for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) { @@ -166,6 +167,9 @@ static uint8_t usb_class_init(USBD_HandleTypeDef *dev, uint8_t cfg_idx) { case USB_IFACE_TYPE_HID: usb_hid_class_init(dev, &usb_ifaces[i].hid, cfg_idx); break; + case USB_IFACE_TYPE_VCP: + usb_vcp_class_init(dev, &usb_ifaces[i].vcp, cfg_idx); + break; default: break; } @@ -179,6 +183,9 @@ static uint8_t usb_class_deinit(USBD_HandleTypeDef *dev, uint8_t cfg_idx) { case USB_IFACE_TYPE_HID: usb_hid_class_deinit(dev, &usb_ifaces[i].hid, cfg_idx); break; + case USB_IFACE_TYPE_VCP: + usb_vcp_class_deinit(dev, &usb_ifaces[i].vcp, cfg_idx); + break; default: break; } @@ -197,6 +204,8 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re switch (usb_ifaces[req->wIndex].type) { case USB_IFACE_TYPE_HID: return usb_hid_class_setup(dev, &usb_ifaces[req->wIndex].hid, req); + case USB_IFACE_TYPE_VCP: + return usb_vcp_class_setup(dev, &usb_ifaces[req->wIndex].vcp, req); default: return USBD_FAIL; } @@ -212,6 +221,9 @@ static uint8_t usb_class_data_in(USBD_HandleTypeDef *dev, uint8_t ep_num) { case USB_IFACE_TYPE_HID: usb_hid_class_data_in(dev, &usb_ifaces[i].hid, ep_num); break; + case USB_IFACE_TYPE_VCP: + usb_vcp_class_data_in(dev, &usb_ifaces[i].vcp, ep_num); + break; default: break; } @@ -225,6 +237,9 @@ static uint8_t usb_class_data_out(USBD_HandleTypeDef *dev, uint8_t ep_num) { case USB_IFACE_TYPE_HID: usb_hid_class_data_out(dev, &usb_ifaces[i].hid, ep_num); break; + case USB_IFACE_TYPE_VCP: + usb_vcp_class_data_out(dev, &usb_ifaces[i].vcp, ep_num); + break; default: break; } diff --git a/micropython/trezorhal/usb.h b/micropython/trezorhal/usb.h index ede5e0b2..60118897 100644 --- a/micropython/trezorhal/usb.h +++ b/micropython/trezorhal/usb.h @@ -81,16 +81,18 @@ typedef struct { typedef enum { USB_IFACE_TYPE_DISABLED = 0, - // USB_IFACE_TYPE_CDC = 1, + USB_IFACE_TYPE_VCP = 1, // USB_IFACE_TYPE_MSC = 2, USB_IFACE_TYPE_HID = 3, } usb_iface_type_t; #include "usb_hid-defs.h" +#include "usb_vcp-defs.h" typedef struct { union { usb_hid_state_t hid; + usb_vcp_state_t vcp; }; usb_iface_type_t type; } usb_iface_t; diff --git a/micropython/trezorhal/usb_vcp-defs.h b/micropython/trezorhal/usb_vcp-defs.h new file mode 100644 index 00000000..3816332f --- /dev/null +++ b/micropython/trezorhal/usb_vcp-defs.h @@ -0,0 +1,31 @@ +typedef struct __attribute__((packed)) { +} usb_vcp_descriptor_t; + +typedef struct __attribute__((packed)) { + usb_interface_descriptor_t iface; + usb_vcp_descriptor_t vcp; + usb_endpoint_descriptor_t ep_in; + usb_endpoint_descriptor_t ep_out; + usb_endpoint_descriptor_t ep_cmd; +} usb_vcp_descriptor_block_t; + +typedef struct { + // Interface configuration + uint8_t iface_num; // Address of this VCP interface + uint8_t ep_in; // Address of IN endpoint (with the highest bit set) + uint8_t ep_out; // Address of OUT endpoint + uint8_t ep_cmd; // Address of CMD endpoint +} usb_vcp_info_t; + +typedef struct { + const usb_vcp_descriptor_block_t *desc_block; +} usb_vcp_state_t; + +int usb_vcp_add(const usb_vcp_info_t *vcp_info); +int usb_vcp_can_read(uint8_t iface_num); +int usb_vcp_can_write(uint8_t iface_num); +int usb_vcp_read(uint8_t iface_num, uint8_t *buf, uint32_t len); +int usb_vcp_write(uint8_t iface_num, const uint8_t *buf, uint32_t len); + +int usb_vcp_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len, uint32_t timeout); +int usb_vcp_write_blocking(uint8_t iface_num, const uint8_t *buf, uint32_t len, uint32_t timeout); diff --git a/micropython/trezorhal/usb_vcp-impl.h b/micropython/trezorhal/usb_vcp-impl.h new file mode 100644 index 00000000..2b195ecc --- /dev/null +++ b/micropython/trezorhal/usb_vcp-impl.h @@ -0,0 +1,63 @@ +/* usb_vcp_add adds and configures new USB VCP interface according to + * configuration options passed in `info`. */ +int usb_vcp_add(const usb_vcp_info_t *info) { + return 0; +} + +int usb_vcp_can_read(uint8_t iface_num) { + return 0; +} + +int usb_vcp_can_write(uint8_t iface_num) { + return 0; +} + +int usb_vcp_read(uint8_t iface_num, uint8_t *buf, uint32_t len) { + return 0; +} + +int usb_vcp_write(uint8_t iface_num, const uint8_t *buf, uint32_t len) { + return 0; +} + +int usb_vcp_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len, uint32_t timeout) { + uint32_t start = HAL_GetTick(); + while (!usb_vcp_can_read(iface_num)) { + if (HAL_GetTick() - start >= timeout) { + return 0; // Timeout + } + __WFI(); // Enter sleep mode, waiting for interrupt + } + return usb_vcp_read(iface_num, buf, len); +} + +int usb_vcp_write_blocking(uint8_t iface_num, const uint8_t *buf, uint32_t len, uint32_t timeout) { + uint32_t start = HAL_GetTick(); + while (!usb_vcp_can_write(iface_num)) { + if (HAL_GetTick() - start >= timeout) { + return 0; // Timeout + } + __WFI(); // Enter sleep mode, waiting for interrupt + } + return usb_vcp_write(iface_num, buf, len); +} + +static int usb_vcp_class_init(USBD_HandleTypeDef *dev, usb_vcp_state_t *state, uint8_t cfg_idx) { + return USBD_OK; +} + +static int usb_vcp_class_deinit(USBD_HandleTypeDef *dev, usb_vcp_state_t *state, uint8_t cfg_idx) { + return USBD_OK; +} + +static int usb_vcp_class_setup(USBD_HandleTypeDef *dev, usb_vcp_state_t *state, USBD_SetupReqTypedef *req) { + return USBD_OK; +} + +static uint8_t usb_vcp_class_data_in(USBD_HandleTypeDef *dev, usb_vcp_state_t *state, uint8_t ep_num) { + return USBD_OK; +} + +static uint8_t usb_vcp_class_data_out(USBD_HandleTypeDef *dev, usb_vcp_state_t *state, uint8_t ep_num) { + return USBD_OK; +}