diff options
author | Damien George <damien.p.george@gmail.com> | 2018-02-01 17:57:44 +1100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2018-02-01 17:57:44 +1100 |
commit | db702ba722fdf266a653d885e568c0088d109d13 (patch) | |
tree | 365f5a629b1c07801cbbe89a6b23d848019729b9 | |
parent | 71312d0bd10d47e958cca71ed6f6ce5bbdc93f88 (diff) |
stm32/usbdev: Add support for high-speed USB device mode.
This patch adds support in the USBD configuration and CDC-MSC-HID class for
high-speed USB mode. To enable it the board configuration must define
USE_USB_HS, and either not define USE_USB_HS_IN_FS, or be an STM32F723 or
STM32F733 MCU which have a built-in HS PHY. High-speed mode is then
selected dynamically by passing "high_speed=True" to the pyb.usb_mode()
function, otherwise it defaults to full-speed mode.
This patch has been tested on an STM32F733.
-rw-r--r-- | ports/stm32/usb.c | 13 | ||||
-rw-r--r-- | ports/stm32/usbd_cdc_interface.c | 2 | ||||
-rw-r--r-- | ports/stm32/usbd_cdc_interface.h | 2 | ||||
-rw-r--r-- | ports/stm32/usbd_conf.c | 34 | ||||
-rw-r--r-- | ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h | 41 | ||||
-rw-r--r-- | ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid0.h | 1 | ||||
-rw-r--r-- | ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c | 118 | ||||
-rw-r--r-- | ports/stm32/usbdev/core/inc/usbd_core.h | 2 | ||||
-rw-r--r-- | ports/stm32/usbdev/core/src/usbd_core.c | 2 |
9 files changed, 175 insertions, 40 deletions
diff --git a/ports/stm32/usb.c b/ports/stm32/usb.c index 634c9e6f4..e134781b4 100644 --- a/ports/stm32/usb.c +++ b/ports/stm32/usb.c @@ -114,6 +114,8 @@ void pyb_usb_init0(void) { bool pyb_usb_dev_init(uint16_t vid, uint16_t pid, usb_device_mode_t mode, USBD_HID_ModeInfoTypeDef *hid_info) { #ifdef USE_DEVICE_MODE + bool high_speed = (mode & USBD_MODE_HIGH_SPEED) != 0; + mode &= 0x7f; usb_device_t *usb_dev = &usb_device; if (!usb_dev->enabled) { // only init USB once in the device's power-lifetime @@ -147,7 +149,7 @@ bool pyb_usb_dev_init(uint16_t vid, uint16_t pid, usb_device_mode_t mode, USBD_H } // start the USB device - USBD_LL_Init(usbd); + USBD_LL_Init(usbd, high_speed); USBD_LL_Start(usbd); usb_dev->enabled = true; } @@ -215,6 +217,9 @@ STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t * { MP_QSTR_vid, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = USBD_VID} }, { MP_QSTR_pid, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} }, { MP_QSTR_hid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = (mp_obj_t)&pyb_usb_hid_mouse_obj} }, + #if USBD_SUPPORT_HS_MODE + { MP_QSTR_high_speed, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + #endif }; // fetch the current usb mode -> pyb.usb_mode() @@ -323,6 +328,12 @@ STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t * MP_STATE_PORT(pyb_hid_report_desc) = items[4]; } + #if USBD_SUPPORT_HS_MODE + if (args[4].u_bool) { + mode |= USBD_MODE_HIGH_SPEED; + } + #endif + // init the USB device if (!pyb_usb_dev_init(vid, pid, mode, &hid_info)) { goto bad_mode; diff --git a/ports/stm32/usbd_cdc_interface.c b/ports/stm32/usbd_cdc_interface.c index 2e9fba917..23085510c 100644 --- a/ports/stm32/usbd_cdc_interface.c +++ b/ports/stm32/usbd_cdc_interface.c @@ -198,7 +198,7 @@ void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) { // the host waits for all data to arrive (ie, waits for a packet < max packet size). // To flush a packet of exactly max packet size, we need to send a zero-size packet. // See eg http://www.cypress.com/?id=4&rID=92719 - cdc->tx_need_empty_packet = (buffsize > 0 && buffsize % CDC_DATA_FS_MAX_PACKET_SIZE == 0 && cdc->tx_buf_ptr_out_shadow == cdc->tx_buf_ptr_in); + cdc->tx_need_empty_packet = (buffsize > 0 && buffsize % usbd_cdc_max_packet(usbd->pdev) == 0 && cdc->tx_buf_ptr_out_shadow == cdc->tx_buf_ptr_in); } } } diff --git a/ports/stm32/usbd_cdc_interface.h b/ports/stm32/usbd_cdc_interface.h index 98b8fc077..44926085a 100644 --- a/ports/stm32/usbd_cdc_interface.h +++ b/ports/stm32/usbd_cdc_interface.h @@ -37,7 +37,7 @@ typedef struct _usbd_cdc_itf_t { usbd_cdc_msc_hid_state_t *usbd; // the parent USB device - uint8_t rx_packet_buf[CDC_DATA_FS_MAX_PACKET_SIZE]; // received data from USB OUT endpoint is stored in this buffer + uint8_t rx_packet_buf[CDC_DATA_MAX_PACKET_SIZE]; // received data from USB OUT endpoint is stored in this buffer uint8_t rx_user_buf[USBD_CDC_RX_DATA_SIZE]; // received data is buffered here until the user reads it volatile uint16_t rx_buf_put; // circular buffer index uint16_t rx_buf_get; // circular buffer index diff --git a/ports/stm32/usbd_conf.c b/ports/stm32/usbd_conf.c index d39144851..910c748d8 100644 --- a/ports/stm32/usbd_conf.c +++ b/ports/stm32/usbd_conf.c @@ -152,10 +152,19 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd) * Enable calling WFI and correct
* function of the embedded USB_FS_IN_HS phy
*/
- __OTGHSULPI_CLK_SLEEP_DISABLE();
- __OTGHS_CLK_SLEEP_ENABLE();
+ __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_DISABLE();
+ __HAL_RCC_USB_OTG_HS_CLK_SLEEP_ENABLE();
+
/* Enable USB HS Clocks */
- __USB_OTG_HS_CLK_ENABLE();
+
+ #if defined(STM32F723xx) || defined(STM32F733xx)
+ // Needs to remain awake during sleep or else __WFI() will disable the USB
+ __HAL_RCC_USB_OTG_HS_ULPI_CLK_SLEEP_ENABLE();
+ __HAL_RCC_OTGPHYC_CLK_ENABLE();
+ __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE();
+ #endif
+
+ __HAL_RCC_USB_OTG_HS_CLK_ENABLE();
#else // !USE_USB_HS_IN_FS
@@ -399,7 +408,7 @@ void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) * @param pdev: Device handle
* @retval USBD Status
*/
-USBD_StatusTypeDef USBD_LL_Init (USBD_HandleTypeDef *pdev)
+USBD_StatusTypeDef USBD_LL_Init (USBD_HandleTypeDef *pdev, int high_speed)
{
#if defined(USE_USB_FS)
if (pdev->id == USB_PHY_FS_ID)
@@ -447,25 +456,34 @@ if (pdev->id == USB_PHY_HS_ID) pcd_hs_handle.Init.ep0_mps = 0x40;
pcd_hs_handle.Init.dma_enable = 0;
pcd_hs_handle.Init.low_power_enable = 0;
+ #if defined(STM32F723xx) || defined(STM32F733xx)
+ pcd_hs_handle.Init.phy_itface = USB_OTG_HS_EMBEDDED_PHY;
+ #else
pcd_hs_handle.Init.phy_itface = PCD_PHY_EMBEDDED;
+ #endif
pcd_hs_handle.Init.Sof_enable = 1;
- pcd_hs_handle.Init.speed = PCD_SPEED_HIGH_IN_FULL;
+ if (high_speed) {
+ pcd_hs_handle.Init.speed = PCD_SPEED_HIGH;
+ } else {
+ 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
+ pcd_hs_handle.Init.use_external_vbus = 0;
/* 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_SetRxFiFo(&pcd_hs_handle, 0x200);
HAL_PCD_SetTxFiFo(&pcd_hs_handle, 0, 0x20);
- HAL_PCD_SetTxFiFo(&pcd_hs_handle, 1, 0x40);
+ HAL_PCD_SetTxFiFo(&pcd_hs_handle, 1, 0x100);
HAL_PCD_SetTxFiFo(&pcd_hs_handle, 2, 0x20);
- HAL_PCD_SetTxFiFo(&pcd_hs_handle, 3, 0x40);
+ HAL_PCD_SetTxFiFo(&pcd_hs_handle, 3, 0xc0);
#else // !defined(USE_USB_HS_IN_FS)
/*Set LL Driver parameters */
pcd_hs_handle.Instance = USB_OTG_HS;
diff --git a/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h b/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h index c2e7c17fe..600d86379 100644 --- a/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h +++ b/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid.h @@ -5,13 +5,30 @@ #include "usbd_msc_bot.h" #include "usbd_msc_scsi.h" #include "usbd_ioreq.h" +#include STM32_HAL_H + +// Work out if we should support USB high-speed device mode +#if defined(USE_USB_HS) \ + && (!defined(USE_USB_HS_IN_FS) || defined(STM32F723xx) || defined(STM32F733xx)) +#define USBD_SUPPORT_HS_MODE (1) +#else +#define USBD_SUPPORT_HS_MODE (0) +#endif // Needed for the CDC+MSC+HID state and should be maximum of all template // config descriptors defined in usbd_cdc_msc_hid.c #define MAX_TEMPLATE_CONFIG_DESC_SIZE (107) // CDC, MSC and HID packet sizes +#define MSC_FS_MAX_PACKET (64) +#define MSC_HS_MAX_PACKET (512) #define CDC_DATA_FS_MAX_PACKET_SIZE (64) // endpoint IN & OUT packet size +#define CDC_DATA_HS_MAX_PACKET_SIZE (512) // endpoint IN & OUT packet size +#if USBD_SUPPORT_HS_MODE +#define CDC_DATA_MAX_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE +#else +#define CDC_DATA_MAX_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE +#endif #define MSC_MEDIA_PACKET (2048) // was 8192; how low can it go whilst still working? #define HID_DATA_FS_MAX_PACKET_SIZE (64) // endpoint IN & OUT packet size @@ -32,7 +49,7 @@ typedef struct { } USBD_CDC_LineCodingTypeDef; typedef struct { - uint32_t data[CDC_DATA_FS_MAX_PACKET_SIZE/4]; /* Force 32bits alignment */ + uint32_t data[CDC_DATA_MAX_PACKET_SIZE / 4]; // Force 32bits alignment uint8_t CmdOpCode; uint8_t CmdLength; @@ -126,6 +143,28 @@ extern const uint8_t USBD_HID_KEYBOARD_ReportDesc[USBD_HID_KEYBOARD_REPORT_DESC_ extern const USBD_ClassTypeDef USBD_CDC_MSC_HID; +static inline uint32_t usbd_msc_max_packet(USBD_HandleTypeDef *pdev) { + #if USBD_SUPPORT_HS_MODE + if (pdev->dev_speed == USBD_SPEED_HIGH) { + return MSC_HS_MAX_PACKET; + } else + #endif + { + return MSC_FS_MAX_PACKET; + } +} + +static inline uint32_t usbd_cdc_max_packet(USBD_HandleTypeDef *pdev) { + #if USBD_SUPPORT_HS_MODE + if (pdev->dev_speed == USBD_SPEED_HIGH) { + return CDC_DATA_HS_MAX_PACKET_SIZE; + } else + #endif + { + return CDC_DATA_FS_MAX_PACKET_SIZE; + } +} + // returns 0 on success, -1 on failure int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_ModeInfoTypeDef *hid_info); // returns the current usb mode diff --git a/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid0.h b/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid0.h index 08882bb1a..3bf7bccfd 100644 --- a/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid0.h +++ b/ports/stm32/usbdev/class/inc/usbd_cdc_msc_hid0.h @@ -37,6 +37,7 @@ typedef enum { USBD_MODE_CDC_MSC = 0x03, USBD_MODE_CDC_HID = 0x05, USBD_MODE_MSC_HID = 0x06, + USBD_MODE_HIGH_SPEED = 0x80, // or with one of the above } usb_device_mode_t; typedef struct _USBD_HID_ModeInfoTypeDef { diff --git a/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c b/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c index e566f34e8..394fceb75 100644 --- a/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c +++ b/ports/stm32/usbdev/class/src/usbd_cdc_msc_hid.c @@ -29,10 +29,20 @@ #include "usbd_cdc_msc_hid.h" #define MSC_TEMPLATE_CONFIG_DESC_SIZE (32) +#define MSC_TEMPLATE_MSC_DESC_OFFSET (9) #define CDC_TEMPLATE_CONFIG_DESC_SIZE (67) #define CDC_MSC_TEMPLATE_CONFIG_DESC_SIZE (98) +#define CDC_MSC_TEMPLATE_MSC_DESC_OFFSET (9) +#define CDC_MSC_TEMPLATE_CDC_DESC_OFFSET (40) #define CDC_HID_TEMPLATE_CONFIG_DESC_SIZE (107) #define CDC_HID_TEMPLATE_HID_DESC_OFFSET (9) +#define CDC_HID_TEMPLATE_CDC_DESC_OFFSET (49) +#define CDC_TEMPLATE_CDC_DESC_OFFSET (9) +#define CDC_DESC_OFFSET_INTR_INTERVAL (34) +#define CDC_DESC_OFFSET_OUT_MAX_PACKET_LO (48) +#define CDC_DESC_OFFSET_OUT_MAX_PACKET_HI (49) +#define CDC_DESC_OFFSET_IN_MAX_PACKET_LO (55) +#define CDC_DESC_OFFSET_IN_MAX_PACKET_HI (56) #define HID_DESC_OFFSET_SUBCLASS (6) #define HID_DESC_OFFSET_PROTOCOL (7) #define HID_DESC_OFFSET_SUBDESC (9) @@ -59,10 +69,7 @@ #define USB_DESC_TYPE_ASSOCIATION (0x0b) #define CDC_CMD_PACKET_SIZE (8) // Control Endpoint Packet size -#define CDC_DATA_IN_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE -#define CDC_DATA_OUT_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE -#define MSC_MAX_PACKET (0x40) #define BOT_GET_MAX_LUN (0xfe) #define BOT_RESET (0xff) @@ -73,8 +80,7 @@ #define HID_REQ_SET_IDLE (0x0a) #define HID_REQ_GET_IDLE (0x02) -/* -// this is used only in high-speed mode, which we don't support +#if USBD_SUPPORT_HS_MODE // USB Standard Device Descriptor __ALIGN_BEGIN static uint8_t USBD_CDC_MSC_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = { USB_LEN_DEV_QUALIFIER_DESC, @@ -84,11 +90,11 @@ __ALIGN_BEGIN static uint8_t USBD_CDC_MSC_HID_DeviceQualifierDesc[USB_LEN_DEV_QU 0x00, 0x00, 0x00, - 0x40, // same for CDC and MSC (latter being MSC_MAX_PACKET), HID is 0x04 + 0x40, // same for CDC and MSC (latter being MSC_FS_MAX_PACKET), HID is 0x04 0x01, 0x00, }; -*/ +#endif // USB MSC device Configuration Descriptor static const uint8_t msc_template_config_desc[MSC_TEMPLATE_CONFIG_DESC_SIZE] = { @@ -124,8 +130,8 @@ static const uint8_t msc_template_config_desc[MSC_TEMPLATE_CONFIG_DESC_SIZE] = { USB_DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint descriptor type MSC_IN_EP, // bEndpointAddress: IN, address 3 0x02, // bmAttributes: Bulk endpoint type - LOBYTE(MSC_MAX_PACKET), // wMaxPacketSize - HIBYTE(MSC_MAX_PACKET), + LOBYTE(MSC_FS_MAX_PACKET), // wMaxPacketSize + HIBYTE(MSC_FS_MAX_PACKET), 0x00, // bInterval: ignore for Bulk transfer // Endpoint OUT descriptor @@ -133,8 +139,8 @@ static const uint8_t msc_template_config_desc[MSC_TEMPLATE_CONFIG_DESC_SIZE] = { USB_DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint descriptor type MSC_OUT_EP, // bEndpointAddress: OUT, address 3 0x02, // bmAttributes: Bulk endpoint type - LOBYTE(MSC_MAX_PACKET), // wMaxPacketSize - HIBYTE(MSC_MAX_PACKET), + LOBYTE(MSC_FS_MAX_PACKET), // wMaxPacketSize + HIBYTE(MSC_FS_MAX_PACKET), 0x00, // bInterval: ignore for Bulk transfer }; @@ -172,8 +178,8 @@ static const uint8_t cdc_msc_template_config_desc[CDC_MSC_TEMPLATE_CONFIG_DESC_S USB_DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint descriptor type MSC_IN_EP, // bEndpointAddress: IN, address 3 0x02, // bmAttributes: Bulk endpoint type - LOBYTE(MSC_MAX_PACKET), // wMaxPacketSize - HIBYTE(MSC_MAX_PACKET), + LOBYTE(MSC_FS_MAX_PACKET), // wMaxPacketSize + HIBYTE(MSC_FS_MAX_PACKET), 0x00, // bInterval: ignore for Bulk transfer // Endpoint OUT descriptor @@ -181,8 +187,8 @@ static const uint8_t cdc_msc_template_config_desc[CDC_MSC_TEMPLATE_CONFIG_DESC_S USB_DESC_TYPE_ENDPOINT, // bDescriptorType: Endpoint descriptor type MSC_OUT_EP, // bEndpointAddress: OUT, address 3 0x02, // bmAttributes: Bulk endpoint type - LOBYTE(MSC_MAX_PACKET), // wMaxPacketSize - HIBYTE(MSC_MAX_PACKET), + LOBYTE(MSC_FS_MAX_PACKET), // wMaxPacketSize + HIBYTE(MSC_FS_MAX_PACKET), 0x00, // bInterval: ignore for Bulk transfer //========================================================================== @@ -663,27 +669,31 @@ int USBD_SelectMode(usbd_cdc_msc_hid_state_t *usbd, uint32_t mode, USBD_HID_Mode } static uint8_t USBD_CDC_MSC_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { + #if !USBD_SUPPORT_HS_MODE if (pdev->dev_speed == USBD_SPEED_HIGH) { // can't handle high speed return 1; } + #endif usbd_cdc_msc_hid_state_t *usbd = pdev->pClassData; if (usbd->usbd_mode & USBD_MODE_CDC) { // CDC VCP component + int mp = usbd_cdc_max_packet(pdev); + // Open EP IN USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK, - CDC_DATA_IN_PACKET_SIZE); + mp); // Open EP OUT USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK, - CDC_DATA_OUT_PACKET_SIZE); + mp); // Open Command IN EP USBD_LL_OpenEP(pdev, @@ -699,23 +709,25 @@ static uint8_t USBD_CDC_MSC_HID_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx) { usbd->CDC_ClassData.RxState = 0; // Prepare Out endpoint to receive next packet - USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, buf, CDC_DATA_OUT_PACKET_SIZE); + USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, buf, mp); } if (usbd->usbd_mode & USBD_MODE_MSC) { // MSC component + int mp = usbd_msc_max_packet(pdev); + // Open EP OUT USBD_LL_OpenEP(pdev, MSC_OUT_EP, USBD_EP_TYPE_BULK, - MSC_MAX_PACKET); + mp); // Open EP IN USBD_LL_OpenEP(pdev, MSC_IN_EP, USBD_EP_TYPE_BULK, - MSC_MAX_PACKET); + mp); // Init the BOT layer MSC_BOT_Init(pdev); @@ -903,10 +915,10 @@ static uint8_t USBD_CDC_MSC_HID_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTyp USBD_LL_CloseEP(pdev, (uint8_t)req->wIndex); if((((uint8_t)req->wIndex) & 0x80) == 0x80) { // Open EP IN - USBD_LL_OpenEP(pdev, MSC_IN_EP, USBD_EP_TYPE_BULK, MSC_MAX_PACKET); + USBD_LL_OpenEP(pdev, MSC_IN_EP, USBD_EP_TYPE_BULK, usbd_msc_max_packet(pdev)); } else { // Open EP OUT - USBD_LL_OpenEP(pdev, MSC_OUT_EP, USBD_EP_TYPE_BULK, MSC_MAX_PACKET); + USBD_LL_OpenEP(pdev, MSC_OUT_EP, USBD_EP_TYPE_BULK, usbd_msc_max_packet(pdev)); } // Handle BOT error MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex); @@ -1000,18 +1012,66 @@ static uint8_t USBD_CDC_MSC_HID_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum) static uint8_t *USBD_CDC_MSC_HID_GetCfgDesc(USBD_HandleTypeDef *pdev, uint16_t *length) { usbd_cdc_msc_hid_state_t *usbd = pdev->pClassData; + + #if USBD_SUPPORT_HS_MODE + uint8_t *cdc_desc = NULL; + uint8_t *msc_desc = NULL; + switch (usbd->usbd_mode) { + case USBD_MODE_MSC: + msc_desc = usbd->usbd_config_desc + MSC_TEMPLATE_MSC_DESC_OFFSET; + break; + + case USBD_MODE_CDC_MSC: + cdc_desc = usbd->usbd_config_desc + CDC_MSC_TEMPLATE_CDC_DESC_OFFSET; + msc_desc = usbd->usbd_config_desc + CDC_MSC_TEMPLATE_MSC_DESC_OFFSET; + break; + + case USBD_MODE_CDC_HID: + cdc_desc = usbd->usbd_config_desc + CDC_HID_TEMPLATE_CDC_DESC_OFFSET; + break; + + case USBD_MODE_CDC: + cdc_desc = usbd->usbd_config_desc + CDC_TEMPLATE_CDC_DESC_OFFSET; + break; + } + + // configure CDC descriptors, if needed + if (cdc_desc != NULL) { + uint32_t mp = usbd_cdc_max_packet(pdev); + cdc_desc[CDC_DESC_OFFSET_OUT_MAX_PACKET_LO] = LOBYTE(mp); + cdc_desc[CDC_DESC_OFFSET_OUT_MAX_PACKET_HI] = HIBYTE(mp); + cdc_desc[CDC_DESC_OFFSET_IN_MAX_PACKET_LO] = LOBYTE(mp); + cdc_desc[CDC_DESC_OFFSET_IN_MAX_PACKET_HI] = HIBYTE(mp); + uint8_t interval; // polling interval in frames of 1ms + if (pdev->dev_speed == USBD_SPEED_HIGH) { + interval = 0x09; + } else { + interval = 0x20; + } + cdc_desc[CDC_DESC_OFFSET_INTR_INTERVAL] = interval; + } + + if (msc_desc != NULL) { + uint32_t mp = usbd_msc_max_packet(pdev); + msc_desc[13] = LOBYTE(mp); + msc_desc[14] = HIBYTE(mp); + msc_desc[20] = LOBYTE(mp); + msc_desc[21] = HIBYTE(mp); + } + #endif + *length = usbd->usbd_config_desc_size; return usbd->usbd_config_desc; } -// this is used only in high-speed mode, which we don't support uint8_t *USBD_CDC_MSC_HID_GetDeviceQualifierDescriptor(USBD_HandleTypeDef *pdev, uint16_t *length) { - /* + #if USBD_SUPPORT_HS_MODE *length = sizeof(USBD_CDC_MSC_HID_DeviceQualifierDesc); return USBD_CDC_MSC_HID_DeviceQualifierDesc; - */ + #else *length = 0; return NULL; + #endif } // data received on non-control OUT endpoint @@ -1031,12 +1091,15 @@ uint8_t USBD_CDC_TransmitPacket(usbd_cdc_msc_hid_state_t *usbd, size_t len, cons // prepare OUT endpoint for reception uint8_t USBD_CDC_ReceivePacket(usbd_cdc_msc_hid_state_t *usbd, uint8_t *buf) { // Suspend or Resume USB Out process + + #if !USBD_SUPPORT_HS_MODE if (usbd->pdev->dev_speed == USBD_SPEED_HIGH) { return USBD_FAIL; } + #endif // Prepare Out endpoint to receive next packet - USBD_LL_PrepareReceive(usbd->pdev, CDC_OUT_EP, buf, CDC_DATA_OUT_PACKET_SIZE); + USBD_LL_PrepareReceive(usbd->pdev, CDC_OUT_EP, buf, usbd_cdc_max_packet(usbd->pdev)); return USBD_OK; } @@ -1044,9 +1107,12 @@ uint8_t USBD_CDC_ReceivePacket(usbd_cdc_msc_hid_state_t *usbd, uint8_t *buf) { // prepare OUT endpoint for reception uint8_t USBD_HID_ReceivePacket(usbd_cdc_msc_hid_state_t *usbd, uint8_t *buf) { // Suspend or Resume USB Out process + + #if !USBD_SUPPORT_HS_MODE if (usbd->pdev->dev_speed == USBD_SPEED_HIGH) { return USBD_FAIL; } + #endif // Prepare Out endpoint to receive next packet uint16_t mps_out = diff --git a/ports/stm32/usbdev/core/inc/usbd_core.h b/ports/stm32/usbdev/core/inc/usbd_core.h index 3178d4a4b..fb1d541f6 100644 --- a/ports/stm32/usbdev/core/inc/usbd_core.h +++ b/ports/stm32/usbdev/core/inc/usbd_core.h @@ -111,7 +111,7 @@ USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev); USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev);
/* USBD Low Level Driver */
-USBD_StatusTypeDef USBD_LL_Init (USBD_HandleTypeDef *pdev);
+USBD_StatusTypeDef USBD_LL_Init (USBD_HandleTypeDef *pdev, int high_speed);
USBD_StatusTypeDef USBD_LL_DeInit (USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev);
USBD_StatusTypeDef USBD_LL_Stop (USBD_HandleTypeDef *pdev);
diff --git a/ports/stm32/usbdev/core/src/usbd_core.c b/ports/stm32/usbdev/core/src/usbd_core.c index ae5b99626..23d2bc09f 100644 --- a/ports/stm32/usbdev/core/src/usbd_core.c +++ b/ports/stm32/usbdev/core/src/usbd_core.c @@ -119,7 +119,7 @@ USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef * pdev->dev_state = USBD_STATE_DEFAULT;
pdev->id = id;
/* Initialize low level driver */
- USBD_LL_Init(pdev);
+ USBD_LL_Init(pdev, 0);
return USBD_OK;
}
|