diff --git a/Makefile.firmware b/Makefile.firmware
index da74b16223..af4af9e079 100644
--- a/Makefile.firmware
+++ b/Makefile.firmware
@@ -262,11 +262,6 @@ OBJ_MP += $(addprefix $(BUILD_MP)/,\
stmhal/pendsv.o \
stmhal/startup_stm32.o \
stmhal/systick.o \
- \
- stmhal/usbd_cdc_interface.o \
- stmhal/usbd_conf.o \
- stmhal/usbd_desc.o \
- stmhal/usbd_hid_interface.o \
)
# OBJ vendor/micropython
@@ -300,10 +295,6 @@ OBJ_HAL += $(addprefix $(BUILD_MP)/,\
stmhal/hal/f4/src/stm32f4xx_ll_sdmmc.o \
stmhal/hal/f4/src/stm32f4xx_ll_usb.o \
\
- stmhal/usbdev/class/src/usbd_cdc_msc_hid.o \
- stmhal/usbdev/class/src/usbd_msc_bot.o \
- stmhal/usbdev/class/src/usbd_msc_data.o \
- stmhal/usbdev/class/src/usbd_msc_scsi.o \
stmhal/usbdev/core/src/usbd_core.o \
stmhal/usbdev/core/src/usbd_ctlreq.o \
stmhal/usbdev/core/src/usbd_ioreq.o \
@@ -321,6 +312,7 @@ OBJ_FW += $(addprefix $(BUILD_FW)/, \
trezorhal/sdcard.o \
trezorhal/touch.o \
trezorhal/usb.o \
+ trezorhal/usbd_conf.o \
trezorhal/stm32_it.o \
trezorhal/stm32_system.o \
trezorhal/hal/stm32f4xx_hal_sram.o \
diff --git a/micropython/extmod/modtrezormsg/modtrezormsg-stmhal.h b/micropython/extmod/modtrezormsg/modtrezormsg-stmhal.h
index c86c9f2f48..a3bc853cd3 100644
--- a/micropython/extmod/modtrezormsg/modtrezormsg-stmhal.h
+++ b/micropython/extmod/modtrezormsg/modtrezormsg-stmhal.h
@@ -5,9 +5,8 @@
* see LICENSE file for details
*/
-extern struct _USBD_HandleTypeDef hUSBDDevice;
-extern uint8_t USBD_HID_SendReport(struct _USBD_HandleTypeDef *pdev, uint8_t *report, uint16_t len);
-extern int USBD_HID_Rx(uint8_t *buf, uint32_t len, uint32_t timeout);
+extern int usb_hid_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len, uint32_t timeout);
+extern int usb_hid_write_blocking(uint8_t iface_num, const uint8_t *buf, uint32_t len, uint32_t timeout);
void msg_init(void)
{
@@ -16,14 +15,14 @@ void msg_init(void)
ssize_t msg_recv(uint8_t *iface, uint8_t *buf, size_t len)
{
*iface = 0; // TODO: return proper interface
- return USBD_HID_Rx(buf, len, 1);
+ return usb_hid_read_blocking(0x00, buf, len, 1);
}
ssize_t msg_send(uint8_t iface, const uint8_t *buf, size_t len)
{
(void)iface; // TODO: ignore interface for now
if (len > 0) {
- USBD_HID_SendReport(&hUSBDDevice, (uint8_t *)buf, len);
+ usb_hid_write_blocking(0x00, buf, len, 1);
}
return len;
}
diff --git a/micropython/firmware/main.c b/micropython/firmware/main.c
index 46309aab45..75df510507 100644
--- a/micropython/firmware/main.c
+++ b/micropython/firmware/main.c
@@ -22,6 +22,43 @@
#include "touch.h"
#include "usb.h"
+int usb_init_all(void) {
+ static const usb_dev_info_t dev_info = {
+ .vendor_id = 0x1209,
+ .product_id = 0x53C1,
+ .release_num = 0x0002,
+ .product_str = (uint8_t *)"product_str",
+ .manufacturer_str = (uint8_t *)"manufacturer_str",
+ .serial_number_str = (uint8_t *)"serial_number_str",
+ .configuration_str = (uint8_t *)"configuration_str",
+ .interface_str = (uint8_t *)"interface_str",
+ };
+ static uint8_t rx_buffer[64];
+ static const usb_hid_info_t hid_info = {
+ .iface_num = 0,
+ .ep_in = 0x81,
+ .ep_out = 0x01,
+ .subclass = 0,
+ .protocol = 0,
+ .max_packet_len = sizeof(rx_buffer),
+ .polling_interval = 1,
+ .report_desc_len = 34,
+ .report_desc = (uint8_t*)"\x06\x00\xff\x09\x01\xa1\x01\x09\x20\x15\x00\x26\xff\x00\x75\x08\x95\x40\x81\x02\x09\x21\x15\x00\x26\xff\x00\x75\x08\x95\x40\x91\x02\xc0",
+ };
+
+ if (0 != usb_init(&dev_info)) {
+ __fatal_error("usb_init failed");
+ }
+ if (0 != usb_hid_add(&hid_info)) {
+ __fatal_error("usb_hid_add failed");
+ }
+ if (0 != usb_start()) {
+ __fatal_error("usb_start failed");
+ }
+
+ return 0;
+}
+
int main(void) {
periph_init();
@@ -48,8 +85,8 @@ int main(void) {
__fatal_error("touch_init failed");
}
- if (0 != usb_init()) {
- __fatal_error("usb_init failed");
+ if (0 != usb_init_all()) {
+ __fatal_error("usb_init_all failed");
}
for (;;) {
diff --git a/micropython/firmware/mphalport.c b/micropython/firmware/mphalport.c
index 8cc1f8506b..ad7a6f3cde 100644
--- a/micropython/firmware/mphalport.c
+++ b/micropython/firmware/mphalport.c
@@ -1,17 +1,17 @@
#include "py/mphal.h"
-void USBD_CDC_TxAlways(const uint8_t *buf, uint32_t len);
-int USBD_CDC_Rx(uint8_t *buf, uint32_t len, uint32_t timeout);
+// void USBD_CDC_TxAlways(const uint8_t *buf, uint32_t len);
+// int USBD_CDC_Rx(uint8_t *buf, uint32_t len, uint32_t timeout);
int mp_hal_stdin_rx_chr(void) {
for (;;) {
- byte c;
- if (USBD_CDC_Rx(&c, 1, 0) != 0) {
- return c;
- }
+ // byte c;
+ // if (USBD_CDC_Rx(&c, 1, 0) != 0) {
+ // return c;
+ // }
}
}
void mp_hal_stdout_tx_strn(const char *str, size_t len) {
- USBD_CDC_TxAlways((const uint8_t*)str, len);
+ // USBD_CDC_TxAlways((const uint8_t*)str, len);
}
diff --git a/micropython/trezorhal/usb.c b/micropython/trezorhal/usb.c
index 2920860139..2de882bb98 100644
--- a/micropython/trezorhal/usb.c
+++ b/micropython/trezorhal/usb.c
@@ -1,15 +1,20 @@
+// TODO: max size of user strings from dev_info
+
#include STM32_HAL_H
+#include "usb.h"
#include "usbd_core.h"
-#include "usbd_desc.h"
-#define USBD_MAX_NUM_INTERFACES (3)
+#define USB_MAX_CONFIG_DESC_SIZE 128
+#define USB_MAX_STR_DESC_SIZE 256
-#define USB_MAX_CONFIG_DESC_SIZE (128)
-#define USB_MAX_STR_DESC_SIZE (256)
+#define USB_DESC_TYPE_HID 0x21
+#define USB_DESC_TYPE_REPORT 0x22
-#define USB_DESC_TYPE_HID (0x21)
-#define USB_DESC_TYPE_REPORT (0x22)
+#define HID_REQ_SET_PROTOCOL 0x0b
+#define HID_REQ_GET_PROTOCOL 0x03
+#define HID_REQ_SET_IDLE 0x0a
+#define HID_REQ_GET_IDLE 0x02
extern PCD_HandleTypeDef pcd_fs_handle;
@@ -28,6 +33,9 @@ static usb_interface_descriptor_t *usb_next_iface_desc;
static usb_string_table_t usb_str_table;
static usb_iface_t usb_ifaces[USBD_MAX_NUM_INTERFACES];
+static const USBD_DescriptorsTypeDef usb_descriptors;
+static const USBD_ClassTypeDef usb_class;
+
int usb_init(const usb_dev_info_t *dev_info) {
// Device descriptor
@@ -37,7 +45,7 @@ int usb_init(const usb_dev_info_t *dev_info) {
usb_dev_desc.bDeviceClass = 0xef; // Composite Device Class
usb_dev_desc.bDeviceSubClass = 0x02; // Common Class
usb_dev_desc.bDeviceProtocol = 0x01; // Interface Association Descriptor
- usb_dev_desc.bMaxPacketSize = USB_MAX_EP0_SIZE;
+ usb_dev_desc.bMaxPacketSize0 = USB_MAX_EP0_SIZE;
usb_dev_desc.idVendor = dev_info->vendor_id;
usb_dev_desc.idProduct = dev_info->product_id;
usb_dev_desc.bcdDevice = dev_info->release_num;
@@ -46,6 +54,13 @@ int usb_init(const usb_dev_info_t *dev_info) {
usb_dev_desc.iSerialNumber = USBD_IDX_SERIAL_STR; // Index of serial number string
usb_dev_desc.bNumConfigurations = 0x01;
+ // String table
+ 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;
+ usb_str_table.config_str = dev_info->configuration_str;
+ usb_str_table.interface_str = dev_info->interface_str;
+
// Configuration descriptor
usb_config_desc->bLength = USB_LEN_CFG_DESC;
usb_config_desc->bDescriptorType = USB_DESC_TYPE_CONFIGURATION;
@@ -60,17 +75,10 @@ int usb_init(const usb_dev_info_t *dev_info) {
usb_next_iface_desc = (usb_interface_descriptor_t *)(usb_config_buf + usb_config_desc->wTotalLength);
// Reset the iface state map
- usb_iface_list = {};
+ memset(&usb_ifaces, 0, sizeof(usb_ifaces));
- // String table
- 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;
- usb_str_table->config_str = dev_info->configuration_str;
- usb_str_table->interface_str = dev_info->interface_str;
-
- USBD_Init(&usb_dev_handle, (USBD_DescriptorsTypeDef*)&usb_descriptors, 0); // 0 == full speed
- USBD_RegisterClass(&usb_dev_handle, &usb_class);
+ USBD_Init(&usb_dev_handle, (USBD_DescriptorsTypeDef*)&usb_descriptors, USB_PHY_FS_ID);
+ USBD_RegisterClass(&usb_dev_handle, (USBD_ClassTypeDef*)&usb_class);
return 0;
}
@@ -85,36 +93,36 @@ int usb_stop(void) {
static uint8_t *usb_get_dev_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
*length = sizeof(usb_dev_desc);
- return (uint8_t *)usb_dev_desc;
+ return (uint8_t *)&usb_dev_desc;
}
static uint8_t *usb_get_langid_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
*length = sizeof(usb_langid_str_desc);
- return (uint8_t *)usb_langid_str_desc;
+ return (uint8_t *)&usb_langid_str_desc;
}
static uint8_t *usb_get_manufacturer_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
- USBD_GetString(usb_str_table.manufacturer_str, usb_str_buf, length);
+ USBD_GetString((uint8_t *)usb_str_table.manufacturer_str, usb_str_buf, length);
return usb_str_buf;
}
static uint8_t *usb_get_product_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
- USBD_GetString(usb_str_table.product_str, usb_str_buf, length);
+ USBD_GetString((uint8_t *)usb_str_table.product_str, usb_str_buf, length);
return usb_str_buf;
}
static uint8_t *usb_get_serial_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
- USBD_GetString(usb_str_table.serial_str, usb_str_buf, length);
+ USBD_GetString((uint8_t *)usb_str_table.serial_str, usb_str_buf, length);
return usb_str_buf;
}
static uint8_t *usb_get_config_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
- USBD_GetString(usb_str_table.config_str, usb_str_buf, length);
+ USBD_GetString((uint8_t *)usb_str_table.config_str, usb_str_buf, length);
return usb_str_buf;
}
static uint8_t *usb_get_interface_str_descriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
- USBD_GetString(usb_str_table.interface_str, usb_str_buf, length);
+ USBD_GetString((uint8_t *)usb_str_table.interface_str, usb_str_buf, length);
return usb_str_buf;
}
@@ -132,7 +140,7 @@ static void *usb_desc_alloc_iface(size_t desc_len) {
if (usb_config_desc->wTotalLength + desc_len > USB_MAX_CONFIG_DESC_SIZE) {
return NULL; // Not enough space in the descriptor
}
- if (usb_config_desc->bNumInterfaces + 1 >= USBD_MAX_NUM_INTERFACES)
+ if (usb_config_desc->bNumInterfaces + 1 >= USBD_MAX_NUM_INTERFACES) {
return NULL; // Already using all the interfaces
}
return usb_next_iface_desc;
@@ -144,6 +152,20 @@ static void usb_desc_add_iface(size_t desc_len) {
usb_next_iface_desc = (usb_interface_descriptor_t *)(usb_config_buf + usb_config_desc->wTotalLength);
}
+static uint8_t usb_ep_set_nak(USBD_HandleTypeDef *dev, uint8_t ep_num) {
+ PCD_HandleTypeDef *hpcd = dev->pData;
+ USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
+ USBx_OUTEP(ep_num)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
+ return USBD_OK;
+}
+
+static uint8_t usb_ep_clear_nak(USBD_HandleTypeDef *dev, uint8_t ep_num) {
+ PCD_HandleTypeDef *hpcd = dev->pData;
+ USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
+ USBx_OUTEP(ep_num)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
+ return USBD_OK;
+}
+
/* usb_hid_add adds and configures new USB HID interface according to
* configuration options passed in `info`. */
int usb_hid_add(const usb_hid_info_t *info) {
@@ -153,7 +175,7 @@ int usb_hid_add(const usb_hid_info_t *info) {
return 1; // Not enough space in the configuration descriptor
}
- if ((info->iface_num < usb_config_desc->bNumInterfaces)
+ if ((info->iface_num < usb_config_desc->bNumInterfaces) ||
(info->iface_num >= USBD_MAX_NUM_INTERFACES) ||
((info->ep_in & 0x80) == 0) ||
((info->ep_out & 0x80) != 0)) {
@@ -169,7 +191,7 @@ int usb_hid_add(const usb_hid_info_t *info) {
d->iface.bNumEndpoints = 0x02;
d->iface.bInterfaceClass = 0x03; // HID Class
d->iface.bInterfaceSubClass = info->subclass;
- d->iface.nInterfaceProtocol = info->protocol;
+ d->iface.bInterfaceProtocol = info->protocol;
d->iface.iInterface = 0x00; // Index of string descriptor describing the interface
// HID descriptor
@@ -204,25 +226,27 @@ int usb_hid_add(const usb_hid_info_t *info) {
usb_iface_t *i = &usb_ifaces[info->iface_num];
i->hid.ep_in = info->ep_in;
i->hid.ep_out = info->ep_out;
- i->hid.rx_buffer = info->hid_buffer;
+ i->hid.rx_buffer = info->rx_buffer;
i->hid.max_packet_len = info->max_packet_len;
i->hid.report_desc_len = info->report_desc_len;
i->hid.report_desc = info->report_desc;
i->hid.desc_block = d;
+
+ return 0;
}
int usb_hid_can_read(uint8_t iface_num) {
return ((iface_num < USBD_MAX_NUM_INTERFACES) &&
(usb_ifaces[iface_num].type == USB_IFACE_TYPE_HID) &&
(usb_ifaces[iface_num].hid.rx_buffer_len > 0) &&
- usb_dev_handle.dev_state == USBD_STATE_CONFIGURED);
+ (usb_dev_handle.dev_state == USBD_STATE_CONFIGURED));
}
int usb_hid_can_write(uint8_t iface_num) {
return ((iface_num < USBD_MAX_NUM_INTERFACES) &&
(usb_ifaces[iface_num].type == USB_IFACE_TYPE_HID) &&
- (usb_ifaces[iface_num].hid.is_idle) &&
- usb_dev_handle.dev_state == USBD_STATE_CONFIGURED);
+ (usb_ifaces[iface_num].hid.in_idle) &&
+ (usb_dev_handle.dev_state == USBD_STATE_CONFIGURED));
}
int usb_hid_read(uint8_t iface_num, uint8_t *buf, uint32_t len) {
@@ -256,6 +280,30 @@ int usb_hid_write(uint8_t iface_num, const uint8_t *buf, uint32_t len) {
state->in_idle = 0;
USBD_LL_Transmit(&usb_dev_handle, state->ep_in, (uint8_t *)buf, (uint16_t)len);
+
+ return len;
+}
+
+int usb_hid_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len, uint32_t timeout) {
+ uint32_t start = HAL_GetTick();
+ while (!usb_hid_can_read(iface_num)) {
+ if (HAL_GetTick() - start >= timeout) {
+ return 0; // Timeout
+ }
+ __WFI(); // Enter sleep mode, waiting for interrupt
+ }
+ return usb_hid_read(iface_num, buf, len);
+}
+
+int usb_hid_write_blocking(uint8_t iface_num, const uint8_t *buf, uint32_t len, uint32_t timeout) {
+ uint32_t start = HAL_GetTick();
+ while (!usb_hid_can_write(iface_num)) {
+ if (HAL_GetTick() - start >= timeout) {
+ return 0; // Timeout
+ }
+ __WFI(); // Enter sleep mode, waiting for interrupt
+ }
+ return usb_hid_write(iface_num, buf, len);
}
static int usb_hid_class_init(USBD_HandleTypeDef *dev, usb_hid_state_t *state, uint8_t cfg_idx) {
@@ -266,17 +314,21 @@ static int usb_hid_class_init(USBD_HandleTypeDef *dev, usb_hid_state_t *state, u
// Reset the state
state->in_idle = 1;
state->protocol = 0;
- state->idle_state = 0;
+ state->idle_rate = 0;
state->alt_setting = 0;
// Prepare Out endpoint to receive next packet
- USBD_LL_PrepareReceive(dev, hid_out_ep, state->rx_buffer, state->max_packet_len);
+ USBD_LL_PrepareReceive(dev, state->ep_out, state->rx_buffer, state->max_packet_len);
+
+ return USBD_OK;
}
static int usb_hid_class_deinit(USBD_HandleTypeDef *dev, usb_hid_state_t *state, uint8_t cfg_idx) {
// Close endpoints
USBD_LL_CloseEP(dev, state->ep_in);
USBD_LL_CloseEP(dev, state->ep_out);
+
+ return USBD_OK;
}
static int usb_hid_class_setup(USBD_HandleTypeDef *dev, usb_hid_state_t *state, USBD_SetupReqTypedef *req) {
@@ -328,7 +380,7 @@ static int usb_hid_class_setup(USBD_HandleTypeDef *dev, usb_hid_state_t *state,
break;
case USB_DESC_TYPE_REPORT:
- USBD_CtlSendData(dev, state->report_desc, MIN(req->wLength, state->report_desc_len));
+ USBD_CtlSendData(dev, (uint8_t*)state->report_desc, MIN(req->wLength, state->report_desc_len));
break;
}
break;
@@ -345,6 +397,7 @@ static uint8_t usb_hid_class_data_in(USBD_HandleTypeDef *dev, usb_hid_state_t *s
// before the end of the previous transfer.
state->in_idle = 1;
}
+ return USBD_OK;
}
static uint8_t usb_hid_class_data_out(USBD_HandleTypeDef *dev, usb_hid_state_t *state, uint8_t ep_num) {
@@ -358,6 +411,7 @@ static uint8_t usb_hid_class_data_out(USBD_HandleTypeDef *dev, usb_hid_state_t *
usb_ep_set_nak(dev, ep_num);
}
}
+ return USBD_OK;
}
static uint8_t usb_class_init(USBD_HandleTypeDef *dev, uint8_t cfg_idx) {
@@ -366,6 +420,8 @@ 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;
+ default:
+ break;
}
}
return USBD_OK;
@@ -377,6 +433,8 @@ 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;
+ default:
+ break;
}
}
return USBD_OK;
@@ -402,12 +460,14 @@ static uint8_t usb_class_ep0_rx_ready(USBD_HandleTypeDef *dev) {
return USBD_OK;
}
-static uint8_t usb_class_data_in(USBD_HandleTypeDef *pdev, 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++) {
switch (usb_ifaces[i].type) {
case USB_IFACE_TYPE_HID:
usb_hid_class_data_in(dev, &usb_ifaces[i].hid, ep_num);
break;
+ default:
+ break;
}
}
return USBD_OK;
@@ -419,6 +479,8 @@ 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;
+ default:
+ break;
}
}
return USBD_OK;
@@ -446,20 +508,6 @@ static const USBD_ClassTypeDef usb_class = {
.GetDeviceQualifierDescriptor = NULL,
};
-static uint8_t usb_ep_set_nak(USBD_HandleTypeDef *dev, uint8_t ep_num) {
- PCD_HandleTypeDef *hpcd = dev->pData;
- USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
- USBx_OUTEP(ep_num)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
- return USBD_OK;
-}
-
-static uint8_t usb_ep_clear_nak(USBD_HandleTypeDef *dev, uint8_t ep_num) {
- PCD_HandleTypeDef *hpcd = dev->pData;
- USB_OTG_GlobalTypeDef *USBx = hpcd->Instance;
- USBx_OUTEP(ep_num)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK;
- return USBD_OK;
-}
-
/**
* @brief This function handles USB-On-The-Go FS global interrupt request.
* @param None
diff --git a/micropython/trezorhal/usb.h b/micropython/trezorhal/usb.h
index e30b64690a..f171bcb135 100644
--- a/micropython/trezorhal/usb.h
+++ b/micropython/trezorhal/usb.h
@@ -66,7 +66,7 @@ typedef struct __attribute__((packed)) {
uint16_t wReportDescriptorLength;
} usb_hid_descriptor_t;
-struct __attribute__((packed)) {
+typedef struct __attribute__((packed)) {
usb_interface_descriptor_t iface;
usb_hid_descriptor_t hid;
usb_endpoint_descriptor_t ep_in;
@@ -146,9 +146,9 @@ typedef struct {
typedef enum {
USB_IFACE_TYPE_DISABLED = 0,
- USB_IFACE_TYPE_CDC = 1,
- USB_IFACE_TYPE_MSC = 2,
- USD_IFACE_TYPE_HID = 3,
+ // USB_IFACE_TYPE_CDC = 1,
+ // USB_IFACE_TYPE_MSC = 2,
+ USB_IFACE_TYPE_HID = 3,
} usb_iface_type_t;
typedef struct {
@@ -165,7 +165,10 @@ int usb_stop(void);
int usb_hid_add(const usb_hid_info_t *hid_info);
int usb_hid_can_read(uint8_t iface_num);
int usb_hid_can_write(uint8_t iface_num);
-int usb_hid_read(uint8_t iface_num, uint8_t *buf, uint32_t *len);
+int usb_hid_read(uint8_t iface_num, uint8_t *buf, uint32_t len);
int usb_hid_write(uint8_t iface_num, const uint8_t *buf, uint32_t len);
+int usb_hid_read_blocking(uint8_t iface_num, uint8_t *buf, uint32_t len, uint32_t timeout);
+int usb_hid_write_blocking(uint8_t iface_num, const uint8_t *buf, uint32_t len, uint32_t timeout);
+
#endif
diff --git a/micropython/trezorhal/usbd_conf.c b/micropython/trezorhal/usbd_conf.c
new file mode 100644
index 0000000000..1da987d89a
--- /dev/null
+++ b/micropython/trezorhal/usbd_conf.c
@@ -0,0 +1,690 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ */
+
+/**
+ ******************************************************************************
+ * @file USB_Device/CDC_Standalone/Src/usbd_conf.c
+ * @author MCD Application Team
+ * @version V1.0.1
+ * @date 26-February-2014
+ * @brief This file implements the USB Device library callbacks and MSP
+ ******************************************************************************
+ * @attention
+ *
+ *
© COPYRIGHT(c) 2014 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include STM32_HAL_H
+#include "usbd_core.h"
+#include "py/obj.h"
+#include "irq.h"
+#include "usb.h"
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+#ifdef USE_USB_FS
+PCD_HandleTypeDef pcd_fs_handle;
+#endif
+#ifdef USE_USB_HS
+PCD_HandleTypeDef pcd_hs_handle;
+#endif
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/*******************************************************************************
+ PCD BSP Routines
+*******************************************************************************/
+/**
+ * @brief Initializes the PCD MSP.
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
+{
+ GPIO_InitTypeDef GPIO_InitStruct;
+
+ if(hpcd->Instance == USB_OTG_FS)
+ {
+ /* Configure USB FS GPIOs */
+ __GPIOA_CLK_ENABLE();
+
+ GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12);
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ /* Configure VBUS Pin */
+#if defined(MICROPY_HW_USB_VBUS_DETECT_PIN)
+ // USB VBUS detect pin is always A9
+ GPIO_InitStruct.Pin = GPIO_PIN_9;
+ GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+#endif
+
+#if defined(MICROPY_HW_USB_OTG_ID_PIN)
+ // USB ID pin is always A10
+ GPIO_InitStruct.Pin = GPIO_PIN_10;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+#endif
+
+ /* Enable USB FS Clocks */
+ __USB_OTG_FS_CLK_ENABLE();
+
+#if defined (MCU_SERIES_L4)
+ /* Enable VDDUSB */
+ if(__HAL_RCC_PWR_IS_CLK_DISABLED())
+ {
+ __HAL_RCC_PWR_CLK_ENABLE();
+ HAL_PWREx_EnableVddUSB();
+ __HAL_RCC_PWR_CLK_DISABLE();
+ }
+ else
+ {
+ HAL_PWREx_EnableVddUSB();
+ }
+#endif
+
+ /* Set USBFS Interrupt priority */
+ HAL_NVIC_SetPriority(OTG_FS_IRQn, IRQ_PRI_OTG_FS, IRQ_SUBPRI_OTG_FS);
+
+ /* Enable USBFS Interrupt */
+ HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
+ }
+#if defined(USE_USB_HS)
+ else if(hpcd->Instance == USB_OTG_HS)
+ {
+#if defined(USE_USB_HS_IN_FS)
+
+ /* Configure USB FS GPIOs */
+ __GPIOB_CLK_ENABLE();
+
+ /* Configure DM DP Pins */
+ GPIO_InitStruct.Pin = (GPIO_PIN_14 | GPIO_PIN_15);
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF12_OTG_HS_FS;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+#if defined(MICROPY_HW_USB_VBUS_DETECT_PIN)
+ /* Configure VBUS Pin */
+ GPIO_InitStruct.Pin = GPIO_PIN_13;
+ GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF12_OTG_HS_FS;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+#endif
+
+#if defined(MICROPY_HW_USB_OTG_ID_PIN)
+ /* Configure ID pin */
+ GPIO_InitStruct.Pin = GPIO_PIN_12;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
+ GPIO_InitStruct.Pull = GPIO_PULLUP;
+ GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF12_OTG_HS_FS;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+#endif
+ /*
+ * Enable calling WFI and correct
+ * function of the embedded USB_FS_IN_HS phy
+ */
+ __OTGHSULPI_CLK_SLEEP_DISABLE();
+ __OTGHS_CLK_SLEEP_ENABLE();
+ /* Enable USB HS Clocks */
+ __USB_OTG_HS_CLK_ENABLE();
+
+#else // !USE_USB_HS_IN_FS
+
+ /* Configure USB HS GPIOs */
+ __GPIOA_CLK_ENABLE();
+ __GPIOB_CLK_ENABLE();
+ __GPIOC_CLK_ENABLE();
+ __GPIOH_CLK_ENABLE();
+ __GPIOI_CLK_ENABLE();
+
+ /* CLK */
+ GPIO_InitStruct.Pin = GPIO_PIN_5;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ /* D0 */
+ GPIO_InitStruct.Pin = GPIO_PIN_3;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
+ GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
+ HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
+
+ /* D1 D2 D3 D4 D5 D6 D7 */
+ GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_5 |\
+ GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
+ HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+
+ /* STP */
+ GPIO_InitStruct.Pin = GPIO_PIN_0;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
+ HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
+
+ /* NXT */
+ GPIO_InitStruct.Pin = GPIO_PIN_4;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
+ HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
+
+ /* DIR */
+ GPIO_InitStruct.Pin = GPIO_PIN_11;
+ GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
+ GPIO_InitStruct.Pull = GPIO_NOPULL;
+ GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
+ HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);
+
+ /* Enable USB HS Clocks */
+ __USB_OTG_HS_CLK_ENABLE();
+ __USB_OTG_HS_ULPI_CLK_ENABLE();
+#endif // !USE_USB_HS_IN_FS
+
+ /* Set USBHS Interrupt to the lowest priority */
+ HAL_NVIC_SetPriority(OTG_HS_IRQn, IRQ_PRI_OTG_HS, IRQ_SUBPRI_OTG_HS);
+
+ /* Enable USBHS Interrupt */
+ HAL_NVIC_EnableIRQ(OTG_HS_IRQn);
+ }
+#endif // USE_USB_HS
+}
+/**
+ * @brief DeInitializes the PCD MSP.
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+void HAL_PCD_MspDeInit(PCD_HandleTypeDef *hpcd)
+{
+ if(hpcd->Instance == USB_OTG_FS)
+ {
+ /* Disable USB FS Clocks */
+ __USB_OTG_FS_CLK_DISABLE();
+ __SYSCFG_CLK_DISABLE();
+ }
+ #if defined(USE_USB_HS)
+ else if(hpcd->Instance == USB_OTG_HS)
+ {
+ /* Disable USB FS Clocks */
+ __USB_OTG_HS_CLK_DISABLE();
+ __SYSCFG_CLK_DISABLE();
+ }
+ #endif
+}
+
+/*******************************************************************************
+ LL Driver Callbacks (PCD -> USB Device Library)
+*******************************************************************************/
+
+
+/**
+ * @brief Setup stage callback.
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd)
+{
+ USBD_LL_SetupStage(hpcd->pData, (uint8_t *)hpcd->Setup);
+}
+
+/**
+ * @brief Data Out stage callback.
+ * @param hpcd: PCD handle
+ * @param epnum: Endpoint Number
+ * @retval None
+ */
+void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+{
+ USBD_LL_DataOutStage(hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff);
+}
+
+/**
+ * @brief Data In stage callback.
+ * @param hpcd: PCD handle
+ * @param epnum: Endpoint Number
+ * @retval None
+ */
+void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+{
+ USBD_LL_DataInStage(hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff);
+}
+
+/**
+ * @brief SOF callback.
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+/*
+This is now handled by the USB CDC interface.
+void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd)
+{
+ USBD_LL_SOF(hpcd->pData);
+}
+*/
+
+/**
+ * @brief Reset callback.
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd)
+{
+ USBD_SpeedTypeDef speed = USBD_SPEED_FULL;
+
+ /* Set USB Current Speed */
+ switch(hpcd->Init.speed)
+ {
+#if defined(PCD_SPEED_HIGH)
+ case PCD_SPEED_HIGH:
+ speed = USBD_SPEED_HIGH;
+ break;
+#endif
+
+ case PCD_SPEED_FULL:
+ speed = USBD_SPEED_FULL;
+ break;
+
+ default:
+ speed = USBD_SPEED_FULL;
+ break;
+ }
+ USBD_LL_SetSpeed(hpcd->pData, speed);
+
+ /* Reset Device */
+ USBD_LL_Reset(hpcd->pData);
+}
+
+/**
+ * @brief Suspend callback.
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd)
+{
+ USBD_LL_Suspend(hpcd->pData);
+}
+
+/**
+ * @brief Resume callback.
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd)
+{
+ USBD_LL_Resume(hpcd->pData);
+}
+
+/**
+ * @brief ISOC Out Incomplete callback.
+ * @param hpcd: PCD handle
+ * @param epnum: Endpoint Number
+ * @retval None
+ */
+void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+{
+ USBD_LL_IsoOUTIncomplete(hpcd->pData, epnum);
+}
+
+/**
+ * @brief ISOC In Incomplete callback.
+ * @param hpcd: PCD handle
+ * @param epnum: Endpoint Number
+ * @retval None
+ */
+void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum)
+{
+ USBD_LL_IsoINIncomplete(hpcd->pData, epnum);
+}
+
+/**
+ * @brief Connect callback.
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd)
+{
+ USBD_LL_DevConnected(hpcd->pData);
+}
+
+/**
+ * @brief Disconnect callback.
+ * @param hpcd: PCD handle
+ * @retval None
+ */
+void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd)
+{
+ USBD_LL_DevDisconnected(hpcd->pData);
+}
+
+/*******************************************************************************
+ LL Driver Interface (USB Device Library --> PCD)
+*******************************************************************************/
+/**
+ * @brief Initializes the Low Level portion of the Device driver.
+ * @param pdev: Device handle
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_Init (USBD_HandleTypeDef *pdev)
+{
+#if defined(USE_USB_FS)
+if (pdev->id == USB_PHY_FS_ID)
+{
+ /*Set LL Driver parameters */
+ pcd_fs_handle.Instance = USB_OTG_FS;
+ pcd_fs_handle.Init.dev_endpoints = 4;
+ pcd_fs_handle.Init.use_dedicated_ep1 = 0;
+ pcd_fs_handle.Init.ep0_mps = 0x40;
+ pcd_fs_handle.Init.dma_enable = 0;
+ pcd_fs_handle.Init.low_power_enable = 0;
+ pcd_fs_handle.Init.phy_itface = PCD_PHY_EMBEDDED;
+ pcd_fs_handle.Init.Sof_enable = 1;
+ pcd_fs_handle.Init.speed = PCD_SPEED_FULL;
+#if defined(MCU_SERIES_L4)
+ pcd_fs_handle.Init.lpm_enable = DISABLE;
+ pcd_fs_handle.Init.battery_charging_enable = DISABLE;
+#endif
+#if !defined(MICROPY_HW_USB_VBUS_DETECT_PIN)
+ pcd_fs_handle.Init.vbus_sensing_enable = 0; // No VBUS Sensing on USB0
+#else
+ pcd_fs_handle.Init.vbus_sensing_enable = 1;
+#endif
+ /* Link The driver to the stack */
+ pcd_fs_handle.pData = pdev;
+ pdev->pData = &pcd_fs_handle;
+ /*Initialize LL Driver */
+ HAL_PCD_Init(&pcd_fs_handle);
+
+ HAL_PCD_SetRxFiFo(&pcd_fs_handle, 0x80);
+ HAL_PCD_SetTxFiFo(&pcd_fs_handle, 0, 0x20);
+ HAL_PCD_SetTxFiFo(&pcd_fs_handle, 1, 0x40);
+ HAL_PCD_SetTxFiFo(&pcd_fs_handle, 2, 0x20);
+ HAL_PCD_SetTxFiFo(&pcd_fs_handle, 3, 0x40);
+}
+#endif
+#if defined(USE_USB_HS)
+if (pdev->id == USB_PHY_HS_ID)
+{
+#if defined(USE_USB_HS_IN_FS)
+ /*Set LL Driver parameters */
+ pcd_hs_handle.Instance = USB_OTG_HS;
+ pcd_hs_handle.Init.dev_endpoints = 4;
+ pcd_hs_handle.Init.use_dedicated_ep1 = 0;
+ pcd_hs_handle.Init.ep0_mps = 0x40;
+ pcd_hs_handle.Init.dma_enable = 0;
+ pcd_hs_handle.Init.low_power_enable = 0;
+ pcd_hs_handle.Init.phy_itface = PCD_PHY_EMBEDDED;
+ pcd_hs_handle.Init.Sof_enable = 1;
+ pcd_hs_handle.Init.speed = PCD_SPEED_HIGH_IN_FULL;
+#if !defined(MICROPY_HW_USB_VBUS_DETECT_PIN)
+ pcd_hs_handle.Init.vbus_sensing_enable = 0; // No VBUS Sensing on USB0
+#else
+ pcd_hs_handle.Init.vbus_sensing_enable = 1;
+#endif
+ /* Link The driver to the stack */
+ pcd_hs_handle.pData = pdev;
+ pdev->pData = &pcd_hs_handle;
+ /*Initialize LL Driver */
+ HAL_PCD_Init(&pcd_hs_handle);
+
+ HAL_PCD_SetRxFiFo(&pcd_hs_handle, 0x80);
+ HAL_PCD_SetTxFiFo(&pcd_hs_handle, 0, 0x20);
+ HAL_PCD_SetTxFiFo(&pcd_hs_handle, 1, 0x40);
+ HAL_PCD_SetTxFiFo(&pcd_hs_handle, 2, 0x20);
+ HAL_PCD_SetTxFiFo(&pcd_hs_handle, 3, 0x40);
+#else // !defined(USE_USB_HS_IN_FS)
+ /*Set LL Driver parameters */
+ pcd_hs_handle.Instance = USB_OTG_HS;
+ pcd_hs_handle.Init.dev_endpoints = 6;
+ pcd_hs_handle.Init.use_dedicated_ep1 = 0;
+ pcd_hs_handle.Init.ep0_mps = 0x40;
+
+ /* Be aware that enabling USB-DMA mode will result in data being sent only by
+ multiple of 4 packet sizes. This is due to the fact that USB-DMA does
+ not allow sending data from non word-aligned addresses.
+ For this specific application, it is advised to not enable this option
+ unless required. */
+ pcd_hs_handle.Init.dma_enable = 0;
+
+ pcd_hs_handle.Init.low_power_enable = 0;
+ pcd_hs_handle.Init.phy_itface = PCD_PHY_ULPI;
+ pcd_hs_handle.Init.Sof_enable = 1;
+ pcd_hs_handle.Init.speed = PCD_SPEED_HIGH;
+ pcd_hs_handle.Init.vbus_sensing_enable = 1;
+ /* Link The driver to the stack */
+ pcd_hs_handle.pData = pdev;
+ pdev->pData = &pcd_hs_handle;
+ /*Initialize LL Driver */
+ HAL_PCD_Init(&pcd_hs_handle);
+
+ HAL_PCD_SetRxFiFo(&pcd_hs_handle, 0x200);
+ HAL_PCD_SetTxFiFo(&pcd_hs_handle, 0, 0x80);
+ HAL_PCD_SetTxFiFo(&pcd_hs_handle, 1, 0x174);
+
+#endif // !USE_USB_HS_IN_FS
+}
+#endif // USE_USB_HS
+ return USBD_OK;
+}
+
+/**
+ * @brief De-Initializes the Low Level portion of the Device driver.
+ * @param pdev: Device handle
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev)
+{
+ HAL_PCD_DeInit(pdev->pData);
+ return USBD_OK;
+}
+
+/**
+ * @brief Starts the Low Level portion of the Device driver.
+ * @param pdev: Device handle
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev)
+{
+ HAL_PCD_Start(pdev->pData);
+ return USBD_OK;
+}
+
+/**
+ * @brief Stops the Low Level portion of the Device driver.
+ * @param pdev: Device handle
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev)
+{
+ HAL_PCD_Stop(pdev->pData);
+ return USBD_OK;
+}
+
+/**
+ * @brief Opens an endpoint of the Low Level Driver.
+ * @param pdev: Device handle
+ * @param ep_addr: Endpoint Number
+ * @param ep_type: Endpoint Type
+ * @param ep_mps: Endpoint Max Packet Size
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev,
+ uint8_t ep_addr,
+ uint8_t ep_type,
+ uint16_t ep_mps)
+{
+ HAL_PCD_EP_Open(pdev->pData, ep_addr, ep_mps, ep_type);
+ return USBD_OK;
+}
+
+/**
+ * @brief Closes an endpoint of the Low Level Driver.
+ * @param pdev: Device handle
+ * @param ep_addr: Endpoint Number
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
+{
+ HAL_PCD_EP_Close(pdev->pData, ep_addr);
+ return USBD_OK;
+}
+
+/**
+ * @brief Flushes an endpoint of the Low Level Driver.
+ * @param pdev: Device handle
+ * @param ep_addr: Endpoint Number
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
+{
+ HAL_PCD_EP_Flush(pdev->pData, ep_addr);
+ return USBD_OK;
+}
+
+/**
+ * @brief Sets a Stall condition on an endpoint of the Low Level Driver.
+ * @param pdev: Device handle
+ * @param ep_addr: Endpoint Number
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
+{
+ HAL_PCD_EP_SetStall(pdev->pData, ep_addr);
+ return USBD_OK;
+}
+
+/**
+ * @brief Clears a Stall condition on an endpoint of the Low Level Driver.
+ * @param pdev: Device handle
+ * @param ep_addr: Endpoint Number
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
+{
+ HAL_PCD_EP_ClrStall(pdev->pData, ep_addr);
+ return USBD_OK;
+}
+
+/**
+ * @brief Returns Stall condition.
+ * @param pdev: Device handle
+ * @param ep_addr: Endpoint Number
+ * @retval Stall (1: yes, 0: No)
+ */
+uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
+{
+ PCD_HandleTypeDef *hpcd = pdev->pData;
+
+ if((ep_addr & 0x80) == 0x80)
+ {
+ return hpcd->IN_ep[ep_addr & 0x7F].is_stall;
+ }
+ else
+ {
+ return hpcd->OUT_ep[ep_addr & 0x7F].is_stall;
+ }
+}
+
+/**
+ * @brief Assigns an USB address to the device
+ * @param pdev: Device handle
+ * @param dev_addr: USB address
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr)
+{
+ HAL_PCD_SetAddress(pdev->pData, dev_addr);
+ return USBD_OK;
+}
+
+/**
+ * @brief Transmits data over an endpoint
+ * @param pdev: Device handle
+ * @param ep_addr: Endpoint Number
+ * @param pbuf: Pointer to data to be sent
+ * @param size: Data size
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev,
+ uint8_t ep_addr,
+ uint8_t *pbuf,
+ uint16_t size)
+{
+ HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size);
+ return USBD_OK;
+}
+
+/**
+ * @brief Prepares an endpoint for reception
+ * @param pdev: Device handle
+ * @param ep_addr: Endpoint Number
+ * @param pbuf:pointer to data to be received
+ * @param size: data size
+ * @retval USBD Status
+ */
+USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev,
+ uint8_t ep_addr,
+ uint8_t *pbuf,
+ uint16_t size)
+{
+ HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size);
+ return USBD_OK;
+}
+
+/**
+ * @brief Returns the last transfered packet size.
+ * @param pdev: Device handle
+ * @param ep_addr: Endpoint Number
+ * @retval Recived Data Size
+ */
+uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
+{
+ return HAL_PCD_EP_GetRxCount(pdev->pData, ep_addr);
+}
+
+/**
+ * @brief Delay routine for the USB Device Library
+ * @param Delay: Delay in ms
+ * @retval None
+ */
+void USBD_LL_Delay(uint32_t Delay)
+{
+ HAL_Delay(Delay);
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/micropython/trezorhal/usbd_conf.h b/micropython/trezorhal/usbd_conf.h
new file mode 100644
index 0000000000..668a5558dc
--- /dev/null
+++ b/micropython/trezorhal/usbd_conf.h
@@ -0,0 +1,94 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ */
+
+/**
+ ******************************************************************************
+ * @file USB_Device/CDC_Standalone/Inc/usbd_conf.h
+ * @author MCD Application Team
+ * @version V1.0.1
+ * @date 26-February-2014
+ * @brief General low level driver configuration
+ ******************************************************************************
+ * @attention
+ *
+ * © COPYRIGHT(c) 2014 STMicroelectronics
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
+ * You may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.st.com/software_license_agreement_liberty_v2
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __USBD_CONF_H
+#define __USBD_CONF_H
+
+/* Includes ------------------------------------------------------------------*/
+#include STM32_HAL_H
+#include
+#include
+#include
+
+#include "py/mpconfig.h"
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Common Config */
+#define USB_PHY_FS_ID 0
+#define USBD_MAX_NUM_INTERFACES 3
+#define USBD_MAX_NUM_CONFIGURATION 1
+#define USBD_SUPPORT_USER_STRING 0
+#define USBD_SELF_POWERED 0
+#define USBD_DEBUG_LEVEL 0
+
+/* Exported macro ------------------------------------------------------------*/
+/* Memory management macros */
+/*
+these should not be used because the GC is reset on a soft reset but the usb is not
+#include "gc.h"
+#define USBD_malloc gc_alloc
+#define USBD_free gc_free
+#define USBD_memset memset
+#define USBD_memcpy memcpy
+*/
+
+/* DEBUG macros */
+#if (USBD_DEBUG_LEVEL > 0)
+#define USBD_UsrLog(...) printf(__VA_ARGS__);\
+ printf("\n");
+#else
+#define USBD_UsrLog(...)
+#endif
+
+#if (USBD_DEBUG_LEVEL > 1)
+
+#define USBD_ErrLog(...) printf("ERROR: ") ;\
+ printf(__VA_ARGS__);\
+ printf("\n");
+#else
+#define USBD_ErrLog(...)
+#endif
+
+#if (USBD_DEBUG_LEVEL > 2)
+#define USBD_DbgLog(...) printf("DEBUG : ") ;\
+ printf(__VA_ARGS__);\
+ printf("\n");
+#else
+#define USBD_DbgLog(...)
+#endif
+
+/* Exported functions ------------------------------------------------------- */
+
+#endif /* __USBD_CONF_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/