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****/