moving esp32s2 to dwc2, abstract dwc2_set_turnaround()

This commit is contained in:
hathach 2021-10-25 15:51:41 +07:00
parent a0202df920
commit 4ccf60954d
No known key found for this signature in database
GPG Key ID: 2FA891220FBFD581
8 changed files with 222 additions and 101 deletions

View File

@ -27,5 +27,5 @@ target_sources(${COMPONENT_TARGET} PUBLIC
"${TOP}/src/class/net/ncm_device.c"
"${TOP}/src/class/usbtmc/usbtmc_device.c"
"${TOP}/src/class/vendor/vendor_device.c"
"${TOP}/src/portable/espressif/esp32sx/dcd_esp32sx.c"
"${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c"
)

View File

@ -28,8 +28,7 @@ CFLAGS += \
-mstrict-align \
-nostdlib -nostartfiles \
-DCFG_TUSB_MCU=OPT_MCU_GD32VF103 \
-DDOWNLOAD_MODE=DOWNLOAD_MODE_FLASHXIP \
-DGD32VF103
-DDOWNLOAD_MODE=DOWNLOAD_MODE_FLASHXIP
# mcu driver cause following warnings
CFLAGS += -Wno-error=unused-parameter

View File

@ -36,13 +36,13 @@
// - PORT_HIGHSPEED: mask to indicate which port support highspeed mode, bit0 for port0 and so on.
//------------- NXP -------------//
#if TU_CHECK_MCU(LPC11UXX) || TU_CHECK_MCU(LPC13XX) || TU_CHECK_MCU(LPC15XX)
#if TU_CHECK_MCU(LPC11UXX, LPC13XX, LPC15XX)
#define DCD_ATTR_ENDPOINT_MAX 5
#elif TU_CHECK_MCU(LPC175X_6X) || TU_CHECK_MCU(LPC177X_8X) || TU_CHECK_MCU(LPC40XX)
#elif TU_CHECK_MCU(LPC175X_6X, LPC177X_8X, LPC40XX)
#define DCD_ATTR_ENDPOINT_MAX 16
#elif TU_CHECK_MCU(LPC18XX) || TU_CHECK_MCU(LPC43XX)
#elif TU_CHECK_MCU(LPC18XX, LPC43XX)
// TODO USB0 has 6, USB1 has 4
#define DCD_ATTR_ENDPOINT_MAX 6
@ -60,7 +60,7 @@
#elif TU_CHECK_MCU(MIMXRT10XX)
#define DCD_ATTR_ENDPOINT_MAX 8
#elif TU_CHECK_MCU(MKL25ZXX) || TU_CHECK_MCU(K32L2BXX)
#elif TU_CHECK_MCU(MKL25ZXX, K32L2BXX)
#define DCD_ATTR_ENDPOINT_MAX 16
#elif TU_CHECK_MCU(MM32F327X)
@ -72,8 +72,8 @@
#define DCD_ATTR_ENDPOINT_MAX 9
//------------- Microchip -------------//
#elif TU_CHECK_MCU(SAMD21) || TU_CHECK_MCU(SAMD51) || TU_CHECK_MCU(SAME5X) || \
TU_CHECK_MCU(SAMD11) || TU_CHECK_MCU(SAML21) || TU_CHECK_MCU(SAML22)
#elif TU_CHECK_MCU(SAMD21, SAMD51, SAME5X) || \
TU_CHECK_MCU(SAMD11, SAML21, SAML22)
#define DCD_ATTR_ENDPOINT_MAX 8
#elif TU_CHECK_MCU(SAMG)
@ -119,7 +119,7 @@
#define DCD_ATTR_ENDPOINT_MAX 9
#define DCD_ATTR_DWC2_STM32
#elif TU_CHECK_MCU(STM32L0) || TU_CHECK_MCU(STM32L1)
#elif TU_CHECK_MCU(STM32L0, STM32L1)
#define DCD_ATTR_ENDPOINT_MAX 8
#elif TU_CHECK_MCU(STM32L4)
@ -157,7 +157,7 @@
#define DCD_ATTR_ENDPOINT_MAX 12
//------------- Espressif -------------//
#elif TU_CHECK_MCU(ESP32S2) || TU_CHECK_MCU(ESP32S3)
#elif TU_CHECK_MCU(ESP32S2, ESP32S3)
#define DCD_ATTR_ENDPOINT_MAX 6
//------------- Dialog -------------//

View File

@ -30,13 +30,16 @@
#include "tusb_option.h"
#include "device/dcd_attr.h"
#if TUSB_OPT_DEVICE_ENABLED && (defined(DCD_ATTR_DWC2_STM32) || TU_CHECK_MCU(GD32VF103))
#if TUSB_OPT_DEVICE_ENABLED && \
( defined(DCD_ATTR_DWC2_STM32) || TU_CHECK_MCU(ESP32S2, ESP32S3, GD32VF103) )
#include "device/dcd.h"
#include "dwc2_type.h"
#if defined(DCD_ATTR_DWC2_STM32)
#include "dwc2_stm32.h"
#elif TU_CHECK_MCU(ESP32S2, ESP32S3)
#include "dwc2_esp32.h"
#elif TU_CHECK_MCU(GD32VF103)
#include "dwc2_gd32.h"
#else
@ -72,7 +75,7 @@ typedef struct {
typedef volatile uint32_t * usb_fifo_t;
xfer_ctl_t xfer_status[EP_MAX][2];
xfer_ctl_t xfer_status[DWC2_EP_MAX][2];
#define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir]
// EP0 transfers are limited to 1 packet - larger sizes has to be split
@ -85,7 +88,7 @@ static bool _out_ep_closed; // Flag to check if RX FIFO si
// Calculate the RX FIFO size according to recommendations from reference manual
static inline uint16_t calc_rx_ff_size(uint16_t ep_size)
{
return 15 + 2*(ep_size/4) + 2*EP_MAX;
return 15 + 2*(ep_size/4) + 2*DWC2_EP_MAX;
}
static void update_grxfsiz(uint8_t rhport)
@ -96,7 +99,7 @@ static void update_grxfsiz(uint8_t rhport)
// Determine largest EP size for RX FIFO
uint16_t max_epsize = 0;
for (uint8_t epnum = 0; epnum < EP_MAX; epnum++)
for (uint8_t epnum = 0; epnum < DWC2_EP_MAX; epnum++)
{
max_epsize = tu_max16(max_epsize, xfer_status[epnum][TUSB_DIR_OUT].max_size);
}
@ -122,7 +125,7 @@ static void bus_reset(uint8_t rhport)
dev->DCFG &= ~DCFG_DAD_Msk;
// 1. NAK for all OUT endpoints
for(uint8_t n = 0; n < EP_MAX; n++) {
for(uint8_t n = 0; n < DWC2_EP_MAX; n++) {
out_ep[n].DOEPCTL |= DOEPCTL_SNAK;
}
@ -171,11 +174,11 @@ static void bus_reset(uint8_t rhport)
// - 2 for each used OUT endpoint
//
// Therefore GRXFSIZ = 13 + 1 + 1 + 2 x (Largest-EPsize/4) + 2 x EPOUTnum
// - FullSpeed (64 Bytes ): GRXFSIZ = 15 + 2 x 16 + 2 x EP_MAX = 47 + 2 x EP_MAX
// - Highspeed (512 bytes): GRXFSIZ = 15 + 2 x 128 + 2 x EP_MAX = 271 + 2 x EP_MAX
// - FullSpeed (64 Bytes ): GRXFSIZ = 15 + 2 x 16 + 2 x DWC2_EP_MAX = 47 + 2 x DWC2_EP_MAX
// - Highspeed (512 bytes): GRXFSIZ = 15 + 2 x 128 + 2 x DWC2_EP_MAX = 271 + 2 x DWC2_EP_MAX
//
// NOTE: Largest-EPsize & EPOUTnum is actual used endpoints in configuration. Since DCD has no knowledge
// of the overall picture yet. We will use the worst scenario: largest possible + EP_MAX
// of the overall picture yet. We will use the worst scenario: largest possible + DWC2_EP_MAX
//
// For Isochronous, largest EP size can be 1023/1024 for FS/HS respectively. In addition if multiple ISO
// are enabled at least "2 x (Largest-EPsize/4) + 1" are recommended. Maybe provide a macro for application to
@ -186,7 +189,7 @@ static void bus_reset(uint8_t rhport)
_allocated_fifo_words_tx = 16;
// Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word )
core->DIEPTXF0_HNPTXFSIZ = (16 << TX0FD_Pos) | (EP_FIFO_SIZE/4 - _allocated_fifo_words_tx);
core->DIEPTXF0_HNPTXFSIZ = (16 << TX0FD_Pos) | (DWC2_EP_FIFO_SIZE/4 - _allocated_fifo_words_tx);
// Fixed control EP0 size to 64 bytes
in_ep[0].DIEPCTL &= ~(0x03 << DIEPCTL_MPSIZ_Pos);
@ -197,47 +200,6 @@ static void bus_reset(uint8_t rhport)
core->GINTMSK |= GINTMSK_OEPINT | GINTMSK_IEPINT;
}
// Set turn-around timeout according to link speed
extern uint32_t SystemCoreClock;
static void set_turnaround(dwc2_core_t * core, tusb_speed_t speed)
{
core->GUSBCFG &= ~GUSBCFG_TRDT;
if ( speed == TUSB_SPEED_HIGH )
{
// Use fixed 0x09 for Highspeed
core->GUSBCFG |= (0x09 << GUSBCFG_TRDT_Pos);
}
else
{
// Turnaround timeout depends on the MCU clock
uint32_t turnaround;
if ( SystemCoreClock >= 32000000U )
turnaround = 0x6U;
else if ( SystemCoreClock >= 27500000U )
turnaround = 0x7U;
else if ( SystemCoreClock >= 24000000U )
turnaround = 0x8U;
else if ( SystemCoreClock >= 21800000U )
turnaround = 0x9U;
else if ( SystemCoreClock >= 20000000U )
turnaround = 0xAU;
else if ( SystemCoreClock >= 18500000U )
turnaround = 0xBU;
else if ( SystemCoreClock >= 17200000U )
turnaround = 0xCU;
else if ( SystemCoreClock >= 16000000U )
turnaround = 0xDU;
else if ( SystemCoreClock >= 15000000U )
turnaround = 0xEU;
else
turnaround = 0xFU;
// Fullspeed depends on MCU clocks, but we will use 0x06 for 32+ Mhz
core->GUSBCFG |= (turnaround << GUSBCFG_TRDT_Pos);
}
}
static tusb_speed_t get_speed(uint8_t rhport)
{
@ -368,6 +330,8 @@ void dcd_init (uint8_t rhport)
// peripheral in each Reference Manual.
dwc2_core_t * core = CORE_REG(rhport);
// check GSNPSID
// No HNP/SRP (no OTG support), program timeout later.
if ( rhport == 1 )
{
@ -422,7 +386,7 @@ void dcd_init (uint8_t rhport)
// If USB host misbehaves during status portion of control xfer
// (non zero-length packet), send STALL back and discard.
dev->DCFG |= DCFG_NZLSOHSK;
dev->DCFG |= DCFG_NZLSOHSK;
set_speed(rhport, TUD_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL);
@ -457,16 +421,6 @@ void dcd_set_address (uint8_t rhport, uint8_t dev_addr)
dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0);
}
static void remote_wakeup_delay(void)
{
// try to delay for 1 ms
uint32_t count = SystemCoreClock / 1000;
while ( count-- )
{
__NOP();
}
}
void dcd_remote_wakeup(uint8_t rhport)
{
(void) rhport;
@ -482,7 +436,7 @@ void dcd_remote_wakeup(uint8_t rhport)
core->GINTMSK |= GINTMSK_SOFM;
// Per specs: remote wakeup signal bit must be clear within 1-15ms
remote_wakeup_delay();
dwc2_remote_wakeup_delay();
dev->DCTL &= ~DCTL_RWUSIG;
}
@ -518,7 +472,7 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress);
uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress);
TU_ASSERT(epnum < EP_MAX);
TU_ASSERT(epnum < DWC2_EP_MAX);
xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir);
xfer->max_size = tu_edpt_packet_size(desc_edpt);
@ -534,7 +488,7 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
// If size_rx needs to be extended check if possible and if so enlarge it
if (core->GRXFSIZ < sz)
{
TU_ASSERT(sz + _allocated_fifo_words_tx <= EP_FIFO_SIZE/4);
TU_ASSERT(sz + _allocated_fifo_words_tx <= DWC2_EP_FIFO_SIZE/4);
// Enlarge RX FIFO
core->GRXFSIZ = sz;
@ -571,15 +525,15 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
// - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n".
// Check if free space is available
TU_ASSERT(_allocated_fifo_words_tx + fifo_size + core->GRXFSIZ <= EP_FIFO_SIZE/4);
TU_ASSERT(_allocated_fifo_words_tx + fifo_size + core->GRXFSIZ <= DWC2_EP_FIFO_SIZE/4);
_allocated_fifo_words_tx += fifo_size;
TU_LOG(2, " Allocated %u bytes at offset %u", fifo_size*4, EP_FIFO_SIZE-_allocated_fifo_words_tx*4);
TU_LOG(2, " Allocated %u bytes at offset %u", fifo_size*4, DWC2_EP_FIFO_SIZE-_allocated_fifo_words_tx*4);
// DIEPTXF starts at FIFO #1.
// Both TXFD and TXSA are in unit of 32-bit words.
core->DIEPTXF[epnum - 1] = (fifo_size << DIEPTXF_INEPTXFD_Pos) | (EP_FIFO_SIZE/4 - _allocated_fifo_words_tx);
core->DIEPTXF[epnum - 1] = (fifo_size << DIEPTXF_INEPTXFD_Pos) | (DWC2_EP_FIFO_SIZE/4 - _allocated_fifo_words_tx);
in_ep[epnum].DIEPCTL |= (1 << DIEPCTL_USBAEP_Pos) |
(epnum << DIEPCTL_TXFNUM_Pos) |
@ -606,7 +560,7 @@ void dcd_edpt_close_all (uint8_t rhport)
// Disable non-control interrupt
dev->DAINTMSK = (1 << DAINTMSK_OEPM_Pos) | (1 << DAINTMSK_IEPM_Pos);
for(uint8_t n = 1; n < EP_MAX; n++)
for(uint8_t n = 1; n < DWC2_EP_MAX; n++)
{
// disable OUT endpoint
out_ep[n].DOEPCTL = 0;
@ -756,7 +710,7 @@ void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr)
uint16_t const fifo_size = (core->DIEPTXF[epnum - 1] & DIEPTXF_INEPTXFD_Msk) >> DIEPTXF_INEPTXFD_Pos;
uint16_t const fifo_start = (core->DIEPTXF[epnum - 1] & DIEPTXF_INEPTXSA_Msk) >> DIEPTXF_INEPTXSA_Pos;
// For now only the last opened endpoint can be closed without fuss.
TU_ASSERT(fifo_start == EP_FIFO_SIZE/4 - _allocated_fifo_words_tx,);
TU_ASSERT(fifo_start == DWC2_EP_FIFO_SIZE/4 - _allocated_fifo_words_tx,);
_allocated_fifo_words_tx -= fifo_size;
}
else
@ -920,7 +874,7 @@ static void handle_rxflvl_ints(uint8_t rhport, dwc2_epout_t * out_ep) {
static void handle_epout_ints(uint8_t rhport, dwc2_device_t * dev, dwc2_epout_t * out_ep) {
// DAINT for a given EP clears when DOEPINTx is cleared.
// OEPINT will be cleared when DAINT's out bits are cleared.
for(uint8_t n = 0; n < EP_MAX; n++) {
for(uint8_t n = 0; n < DWC2_EP_MAX; n++) {
xfer_ctl_t * xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT);
if(dev->DAINT & (1 << (DAINT_OEPINT_Pos + n))) {
@ -949,7 +903,7 @@ static void handle_epout_ints(uint8_t rhport, dwc2_device_t * dev, dwc2_epout_t
static void handle_epin_ints(uint8_t rhport, dwc2_device_t * dev, dwc2_epin_t * in_ep) {
// DAINT for a given EP clears when DIEPINTx is cleared.
// IEPINT will be cleared when DAINT's out bits are cleared.
for ( uint8_t n = 0; n < EP_MAX; n++ )
for ( uint8_t n = 0; n < DWC2_EP_MAX; n++ )
{
xfer_ctl_t *xfer = XFER_CTL_BASE(n, TUSB_DIR_IN);
@ -1040,7 +994,7 @@ void dcd_int_handler(uint8_t rhport)
tusb_speed_t const speed = get_speed(rhport);
set_turnaround(core, speed);
dwc2_set_turnaround(core, speed);
dcd_event_bus_reset(rhport, speed, true);
}

View File

@ -0,0 +1,82 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2021, Ha Thach (tinyusb.org)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* This file is part of the TinyUSB stack.
*/
#ifndef _DWC2_ESP32_H_
#define _DWC2_ESP32_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "esp_intr_alloc.h"
#include "soc/periph_defs.h"
//#include "soc/usb_periph.h"
#define DWC2_REG_BASE 0x60080000UL
#define DWC2_EP_MAX 5 // USB_OUT_EP_NUM
#define DWC2_EP_FIFO_SIZE 1024
// #define EP_FIFO_NUM 5
static intr_handle_t usb_ih;
static void dcd_int_handler_wrap(void* arg)
{
(void) arg;
dcd_int_handler(0);
}
static inline void dcd_dwc2_int_enable (uint8_t rhport)
{
(void) rhport;
esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, dcd_int_handler_wrap, NULL, &usb_ih);
}
static inline void dcd_dwc2_int_disable (uint8_t rhport)
{
(void) rhport;
esp_intr_free(usb_ih);
}
static inline void dwc2_remote_wakeup_delay(void)
{
vTaskDelay(pdMS_TO_TICKS(1));
}
static inline void dwc2_set_turnaround(dwc2_core_t * core, tusb_speed_t speed)
{
(void) core;
(void) speed;
// keep the reset value
}
#ifdef __cplusplus
}
#endif
#endif /* _DWC2_ESP32_H_ */

View File

@ -28,14 +28,18 @@
#ifndef DWC2_GD32_H_
#define DWC2_GD32_H_
// for remote wakeup delay
#define __NOP() __asm volatile ("nop")
#ifdef __cplusplus
extern "C" {
#endif
// These numbers are the same for the whole GD32VF103 family.
#define DWC2_REG_BASE 0x50000000UL
#define EP_MAX 4
#define EP_FIFO_SIZE 1280
#define RHPORT_IRQn 86
#define DWC2_REG_BASE 0x50000000UL
#define DWC2_EP_MAX 4
#define DWC2_EP_FIFO_SIZE 1280
#define RHPORT_IRQn 86
extern uint32_t SystemCoreClock;
// The GD32VF103 is a RISC-V MCU, which implements the ECLIC Core-Local
// Interrupt Controller by Nuclei. It is nearly API compatible to the
@ -66,4 +70,25 @@ static inline void dcd_dwc2_int_disable (uint8_t rhport)
__eclic_disable_interrupt(RHPORT_IRQn);
}
TU_ATTR_ALWAYS_INLINE
static inline void dwc2_remote_wakeup_delay(void)
{
// try to delay for 1 ms
uint32_t count = SystemCoreClock / 1000;
while ( count-- ) __asm volatile ("nop");
}
static inline void dwc2_set_turnaround(dwc2_core_t * core, tusb_speed_t speed)
{
(void) core;
(void) speed;
// keep the reset value
}
#ifdef __cplusplus
}
#endif
#endif /* DWC2_GD32_H_ */

View File

@ -24,8 +24,12 @@
* This file is part of the TinyUSB stack.
*/
#ifndef _TUSB_DWC2_STM32_H_
#define _TUSB_DWC2_STM32_H_
#ifndef _DWC2_STM32_H_
#define _DWC2_STM32_H_
#ifdef __cplusplus
extern "C" {
#endif
// EP_MAX : Max number of bi-directional endpoints including EP0
// EP_FIFO_SIZE : Size of dedicated USB SRAM
@ -71,19 +75,21 @@
// On STM32 we associate Port0 to OTG_FS, and Port1 to OTG_HS
#if TUD_OPT_RHPORT == 0
#define EP_MAX EP_MAX_FS
#define EP_FIFO_SIZE EP_FIFO_SIZE_FS
#define DWC2_REG_BASE USB_OTG_FS_PERIPH_BASE
#define RHPORT_IRQn OTG_FS_IRQn
#define DWC2_REG_BASE USB_OTG_FS_PERIPH_BASE
#define DWC2_EP_MAX EP_MAX_FS
#define DWC2_EP_FIFO_SIZE EP_FIFO_SIZE_FS
#define RHPORT_IRQn OTG_FS_IRQn
#else
#define EP_MAX EP_MAX_HS
#define EP_FIFO_SIZE EP_FIFO_SIZE_HS
#define DWC2_REG_BASE USB_OTG_HS_PERIPH_BASE
#define RHPORT_IRQn OTG_HS_IRQn
#define DWC2_REG_BASE USB_OTG_HS_PERIPH_BASE
#define DWC2_EP_MAX EP_MAX_HS
#define DWC2_EP_FIFO_SIZE EP_FIFO_SIZE_HS
#define RHPORT_IRQn OTG_HS_IRQn
#endif
extern uint32_t SystemCoreClock;
TU_ATTR_ALWAYS_INLINE
static inline void dcd_dwc2_int_enable(uint8_t rhport)
{
@ -98,4 +104,59 @@ static inline void dcd_dwc2_int_disable (uint8_t rhport)
NVIC_DisableIRQ(RHPORT_IRQn);
}
#endif /* DWC2_STM32_H_ */
TU_ATTR_ALWAYS_INLINE
static inline void dwc2_remote_wakeup_delay(void)
{
// try to delay for 1 ms
uint32_t count = SystemCoreClock / 1000;
while ( count-- ) __NOP();
}
// Set turn-around timeout according to link speed
static inline void dwc2_set_turnaround(dwc2_core_t * core, tusb_speed_t speed)
{
core->GUSBCFG &= ~GUSBCFG_TRDT;
if ( speed == TUSB_SPEED_HIGH )
{
// Use fixed 0x09 for Highspeed
core->GUSBCFG |= (0x09 << GUSBCFG_TRDT_Pos);
}
else
{
// Turnaround timeout depends on the MCU clock
uint32_t turnaround;
if ( SystemCoreClock >= 32000000U )
turnaround = 0x6U;
else if ( SystemCoreClock >= 27500000U )
turnaround = 0x7U;
else if ( SystemCoreClock >= 24000000U )
turnaround = 0x8U;
else if ( SystemCoreClock >= 21800000U )
turnaround = 0x9U;
else if ( SystemCoreClock >= 20000000U )
turnaround = 0xAU;
else if ( SystemCoreClock >= 18500000U )
turnaround = 0xBU;
else if ( SystemCoreClock >= 17200000U )
turnaround = 0xCU;
else if ( SystemCoreClock >= 16000000U )
turnaround = 0xDU;
else if ( SystemCoreClock >= 15000000U )
turnaround = 0xEU;
else
turnaround = 0xFU;
// Fullspeed depends on MCU clocks, but we will use 0x06 for 32+ Mhz
core->GUSBCFG |= (turnaround << GUSBCFG_TRDT_Pos);
}
}
#ifdef __cplusplus
}
#endif
#endif /* _DWC2_STM32_H_ */

View File

@ -131,7 +131,7 @@
// Helper to check if configured MCU is one of listed
// Apply _TU_CHECK_MCU with || as separator to list of input
#define _TU_CHECK_MCU(_m) (CFG_TUSB_MCU == OPT_MCU_##_m)
#define TU_CHECK_MCU(...) TU_ARGS_APPLY(_TU_CHECK_MCU, ||, __VA_ARGS__)
#define TU_CHECK_MCU(...) (TU_ARGS_APPLY(_TU_CHECK_MCU, ||, __VA_ARGS__))
//--------------------------------------------------------------------+
// Supported OS