From fad088719e7cc4d1cab9216eb81567dd67af65f7 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 26 May 2020 15:21:23 +0700 Subject: merge CFG_TUSB_RHPORT1_MODE into CFG_TUSB_RHPORT0_MODE each port is 1 byte for easy maintenance --- src/tusb_option.h | 50 ++++++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/tusb_option.h b/src/tusb_option.h index 9e6a2b532..472656424 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -114,44 +114,50 @@ /** \addtogroup group_configuration * @{ */ + //-------------------------------------------------------------------- -// CONTROLLER -// Only 1 roothub port can be configured to be device and/or host. -// tinyusb does not support dual devices or dual host configuration +// RootHub Mode Configuration +// +// Each byte of the CFG_TUSB_RHPORTx_MODE contains operation mode for +// a roothub port (device or host). Therefore each macro can have up to +// 4 ports. //-------------------------------------------------------------------- -/** \defgroup group_mode Controller Mode Selection - * \brief CFG_TUSB_CONTROLLER_N_MODE must be defined with these - * @{ */ + +// Lower 4-bit is operational mode #define OPT_MODE_NONE 0x00 ///< Disabled #define OPT_MODE_DEVICE 0x01 ///< Device Mode #define OPT_MODE_HOST 0x02 ///< Host Mode -#define OPT_MODE_HIGH_SPEED 0x10 ///< High speed -/** @} */ + +// Higher 4-bit is max operational speed (corresponding to tusb_speed_t) +#define OPT_MODE_FULL_SPEED 0x00 ///< Max Full Speed +#define OPT_MODE_LOW_SPEED 0x10 ///< Max Low Speed +#define OPT_MODE_HIGH_SPEED 0x20 ///< Max High Speed + #ifndef CFG_TUSB_RHPORT0_MODE #define CFG_TUSB_RHPORT0_MODE OPT_MODE_NONE #endif -#ifndef CFG_TUSB_RHPORT1_MODE - #define CFG_TUSB_RHPORT1_MODE OPT_MODE_NONE -#endif +//#ifndef CFG_TUSB_RHPORT1_MODE +// #define CFG_TUSB_RHPORT1_MODE OPT_MODE_NONE +//#endif -#if ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) && (CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST)) || \ - ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) && (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE)) - #error "tinyusb does not support same modes on more than 1 roothub port" +#if ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST ) && (CFG_TUSB_RHPORT0_MODE & (OPT_MODE_HOST << 8)) ) || \ + ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) && (CFG_TUSB_RHPORT0_MODE & (OPT_MODE_DEVICE << 8)) ) + #error "TinyUSB currently does not support same modes on more than 1 roothub port" #endif // Which roothub port is configured as host -#define TUH_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) ? 0 : ((CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST) ? 1 : -1) ) +#define TUH_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) ? 0 : ((CFG_TUSB_RHPORT0_MODE & (OPT_MODE_HOST << 8)) ? 1 : -1) ) #define TUSB_OPT_HOST_ENABLED ( TUH_OPT_RHPORT >= 0 ) // Which roothub port is configured as device -#define TUD_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) ? 0 : ((CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE) ? 1 : -1) ) +#define TUD_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) ? 0 : ((CFG_TUSB_RHPORT0_MODE & (OPT_MODE_DEVICE << 8)) ? 1 : -1) ) #if TUD_OPT_RHPORT == 0 -#define TUD_OPT_HIGH_SPEED ( CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED ) + #define TUD_OPT_HIGH_SPEED ( CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED ) #else -#define TUD_OPT_HIGH_SPEED ( CFG_TUSB_RHPORT1_MODE & OPT_MODE_HIGH_SPEED ) + #define TUD_OPT_HIGH_SPEED ( CFG_TUSB_RHPORT0_MODE & (OPT_MODE_HIGH_SPEED << 8) ) #endif #define TUSB_OPT_DEVICE_ENABLED ( TUD_OPT_RHPORT >= 0 ) @@ -168,15 +174,15 @@ // place data in accessible RAM for usb controller #ifndef CFG_TUSB_MEM_SECTION -#define CFG_TUSB_MEM_SECTION + #define CFG_TUSB_MEM_SECTION #endif #ifndef CFG_TUSB_MEM_ALIGN -#define CFG_TUSB_MEM_ALIGN TU_ATTR_ALIGNED(4) + #define CFG_TUSB_MEM_ALIGN TU_ATTR_ALIGNED(4) #endif #ifndef CFG_TUSB_OS -#define CFG_TUSB_OS OPT_OS_NONE + #define CFG_TUSB_OS OPT_OS_NONE #endif //-------------------------------------------------------------------- @@ -184,7 +190,7 @@ //-------------------------------------------------------------------- #ifndef CFG_TUD_ENDPOINT0_SIZE - #define CFG_TUD_ENDPOINT0_SIZE 64 + #define CFG_TUD_ENDPOINT0_SIZE 64 #endif #ifndef CFG_TUD_CDC -- cgit v1.3.1 From b7ab60aa44ff7803161196b579eafd6c26321df7 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 26 May 2020 15:52:02 +0700 Subject: suporting multiple port (OTG FS + HS) for stm32 --- src/portable/st/synopsys/dcd_synopsys.c | 149 +++++++++++++++++--------------- 1 file changed, 80 insertions(+), 69 deletions(-) (limited to 'src') diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index 717a59db6..ee987b0de 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -82,6 +82,33 @@ #include "device/dcd.h" +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + +typedef struct +{ + uint32_t regs; // registers + const IRQn_Type irqnum; // IRQ number +// const uint8_t ep_count; // Max bi-directional Endpoints +}dcd_rhport_t; + +// To be consistent across stm32 port. We will number OTG_FS as Rhport0, and OTG_HS as Rhport1 +static const dcd_rhport_t _dcd_rhport[] = +{ + { .regs = USB_OTG_FS_PERIPH_BASE, .irqnum = OTG_FS_IRQn } + +#ifdef USB_OTG_HS + ,{ .regs = USB_OTG_HS_PERIPH_BASE, .irqnum = OTG_HS_IRQn } +#endif +}; + +#define DEVICE_BASE(_port) (USB_OTG_DeviceTypeDef *) (_dcd_rhport[_port].regs + USB_OTG_DEVICE_BASE) +#define OUT_EP_BASE(_port) (USB_OTG_OUTEndpointTypeDef *) (_dcd_rhport[_port].regs + USB_OTG_OUT_ENDPOINT_BASE) +#define IN_EP_BASE(_port) (USB_OTG_INEndpointTypeDef *) (_dcd_rhport[_port].regs + USB_OTG_IN_ENDPOINT_BASE) +#define FIFO_BASE(_port, _x) ((volatile uint32_t *) (_dcd_rhport[_port].regs + USB_OTG_FIFO_BASE + (_x) * USB_OTG_FIFO_SIZE)) + + /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ @@ -90,11 +117,6 @@ // We disable SOF for now until needed later on #define USE_SOF 0 -#define DEVICE_BASE (USB_OTG_DeviceTypeDef *) (USB_OTG_FS_PERIPH_BASE + USB_OTG_DEVICE_BASE) -#define OUT_EP_BASE (USB_OTG_OUTEndpointTypeDef *) (USB_OTG_FS_PERIPH_BASE + USB_OTG_OUT_ENDPOINT_BASE) -#define IN_EP_BASE (USB_OTG_INEndpointTypeDef *) (USB_OTG_FS_PERIPH_BASE + USB_OTG_IN_ENDPOINT_BASE) -#define FIFO_BASE(_x) ((volatile uint32_t *) (USB_OTG_FS_PERIPH_BASE + USB_OTG_FIFO_BASE + (_x) * USB_OTG_FIFO_SIZE)) - static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[6]; static uint8_t _setup_offs; // We store up to 3 setup packets. @@ -113,9 +135,10 @@ xfer_ctl_t xfer_status[EP_MAX][2]; // Setup the control endpoint 0. -static void bus_reset(void) { - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE; - USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE; +static void bus_reset(uint8_t rhport) +{ + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); for(uint8_t n = 0; n < EP_MAX; n++) { out_ep[n].DOEPCTL |= USB_OTG_DOEPCTL_SNAK; @@ -163,9 +186,11 @@ static void bus_reset(void) { USB_OTG_FS->GINTMSK |= USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT; } -static void end_of_reset(void) { - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE; - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE; +static void end_of_reset(uint8_t rhport) +{ + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); + // On current silicon on the Full Speed core, speed is fixed to Full Speed. // However, keep for debugging and in case Low Speed is ever supported. uint32_t enum_spd = (dev->DSTS & USB_OTG_DSTS_ENUMSPD_Msk) >> USB_OTG_DSTS_ENUMSPD_Pos; @@ -191,8 +216,6 @@ static void end_of_reset(void) { *------------------------------------------------------------------*/ void dcd_init (uint8_t rhport) { - (void) rhport; - // Programming model begins in the last section of the chapter on the USB // peripheral in each Reference Manual. USB_OTG_FS->GAHBCFG |= USB_OTG_GAHBCFG_GINT; @@ -210,7 +233,7 @@ void dcd_init (uint8_t rhport) // the core to stop working/require reset. USB_OTG_FS->GINTMSK |= USB_OTG_GINTMSK_OTGINT | USB_OTG_GINTMSK_MMISM; - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE; + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); // If USB host misbehaves during status portion of control xfer // (non zero-length packet), send STALL back and discard. Full speed. @@ -226,21 +249,17 @@ void dcd_init (uint8_t rhport) void dcd_int_enable (uint8_t rhport) { - (void) rhport; - NVIC_EnableIRQ(OTG_FS_IRQn); + NVIC_EnableIRQ(_dcd_rhport[rhport].irqnum); } void dcd_int_disable (uint8_t rhport) { - (void) rhport; - NVIC_DisableIRQ(OTG_FS_IRQn); + NVIC_EnableIRQ(_dcd_rhport[rhport].irqnum); } void dcd_set_address (uint8_t rhport, uint8_t dev_addr) { - (void) rhport; - - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE; + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); dev->DCFG |= (dev_addr << USB_OTG_DCFG_DAD_Pos) & USB_OTG_DCFG_DAD_Msk; // Response with status after changing device address @@ -254,16 +273,14 @@ void dcd_remote_wakeup(uint8_t rhport) void dcd_connect(uint8_t rhport) { - (void) rhport; - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE; + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); dev->DCTL &= ~USB_OTG_DCTL_SDIS; } void dcd_disconnect(uint8_t rhport) { - (void) rhport; - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE; + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); dev->DCTL |= USB_OTG_DCTL_SDIS; } @@ -275,10 +292,9 @@ void dcd_disconnect(uint8_t rhport) bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) { - (void) rhport; - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE; - USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE; - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE; + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); + USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); @@ -345,10 +361,9 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) { - (void) rhport; - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE; - USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE; - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE; + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); + USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); @@ -393,10 +408,9 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t // (send STALL versus NAK handshakes back). Refactor into resuable function. void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) { - (void) rhport; - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE; - USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE; - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE; + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); + USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); @@ -445,9 +459,8 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) { - (void) rhport; - USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE; - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE; + USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); + USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); @@ -480,8 +493,8 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) // TODO: Split into "receive on endpoint 0" and "receive generic"; endpoint 0's // DOEPTSIZ register is smaller than the others, and so is insufficient for // determining how much of an OUT transfer is actually remaining. -static void receive_packet(xfer_ctl_t * xfer, /* USB_OTG_OUTEndpointTypeDef * out_ep, */ uint16_t xfer_size) { - usb_fifo_t rx_fifo = FIFO_BASE(0); +static void receive_packet(uint8_t rhport, xfer_ctl_t * xfer, /* USB_OTG_OUTEndpointTypeDef * out_ep, */ uint16_t xfer_size) { + usb_fifo_t rx_fifo = FIFO_BASE(rhport, 0); // See above TODO // uint16_t remaining = (out_ep->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ_Msk) >> USB_OTG_DOEPTSIZ_XFRSIZ_Pos; @@ -539,8 +552,8 @@ static void receive_packet(xfer_ctl_t * xfer, /* USB_OTG_OUTEndpointTypeDef * ou } // Write a single data packet to EPIN FIFO -static void write_fifo_packet(uint8_t fifo_num, uint8_t * src, uint16_t len){ - usb_fifo_t tx_fifo = FIFO_BASE(fifo_num); +static void write_fifo_packet(uint8_t rhport, uint8_t fifo_num, uint8_t * src, uint16_t len){ + usb_fifo_t tx_fifo = FIFO_BASE(rhport, fifo_num); // Pushing full available 32 bit words to fifo uint16_t full_words = len >> 2; @@ -564,8 +577,8 @@ static void write_fifo_packet(uint8_t fifo_num, uint8_t * src, uint16_t len){ } } -static void read_rx_fifo(USB_OTG_OUTEndpointTypeDef * out_ep) { - usb_fifo_t rx_fifo = FIFO_BASE(0); +static void read_rx_fifo(uint8_t rhport, USB_OTG_OUTEndpointTypeDef * out_ep) { + usb_fifo_t rx_fifo = FIFO_BASE(rhport, 0); // Pop control word off FIFO (completed xfers will have 2 control words, // we only pop one ctl word each interrupt). @@ -580,7 +593,7 @@ static void read_rx_fifo(USB_OTG_OUTEndpointTypeDef * out_ep) { case 0x02: // Out packet recvd { xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); - receive_packet(xfer, bcnt); + receive_packet(rhport, xfer, bcnt); } break; case 0x03: // Out packet done (Interrupt) @@ -605,7 +618,7 @@ static void read_rx_fifo(USB_OTG_OUTEndpointTypeDef * out_ep) { } } -static void handle_epout_ints(USB_OTG_DeviceTypeDef * dev, USB_OTG_OUTEndpointTypeDef * out_ep) { +static void handle_epout_ints(uint8_t rhport, USB_OTG_DeviceTypeDef * dev, USB_OTG_OUTEndpointTypeDef * 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++) { @@ -615,7 +628,7 @@ static void handle_epout_ints(USB_OTG_DeviceTypeDef * dev, USB_OTG_OUTEndpointTy // SETUP packet Setup Phase done. if(out_ep[n].DOEPINT & USB_OTG_DOEPINT_STUP) { out_ep[n].DOEPINT = USB_OTG_DOEPINT_STUP; - dcd_event_setup_received(0, (uint8_t*) &_setup_packet[2*_setup_offs], true); + dcd_event_setup_received(rhport, (uint8_t*) &_setup_packet[2*_setup_offs], true); _setup_offs = 0; } @@ -631,7 +644,7 @@ static void handle_epout_ints(USB_OTG_DeviceTypeDef * dev, USB_OTG_OUTEndpointTy // Transfer complete if short packet or total len is transferred if(xfer->short_packet || (xfer->queued_len == xfer->total_len)) { xfer->short_packet = false; - dcd_event_xfer_complete(0, n, xfer->queued_len, XFER_RESULT_SUCCESS, true); + dcd_event_xfer_complete(rhport, n, xfer->queued_len, XFER_RESULT_SUCCESS, true); } else { // Schedule another packet to be received. out_ep[n].DOEPTSIZ |= (1 << USB_OTG_DOEPTSIZ_PKTCNT_Pos) | \ @@ -643,7 +656,7 @@ static void handle_epout_ints(USB_OTG_DeviceTypeDef * dev, USB_OTG_OUTEndpointTy } } -static void handle_epin_ints(USB_OTG_DeviceTypeDef * dev, USB_OTG_INEndpointTypeDef * in_ep) { +static void handle_epin_ints(uint8_t rhport, USB_OTG_DeviceTypeDef * dev, USB_OTG_INEndpointTypeDef * 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++ ) @@ -657,7 +670,7 @@ static void handle_epin_ints(USB_OTG_DeviceTypeDef * dev, USB_OTG_INEndpointType if ( in_ep[n].DIEPINT & USB_OTG_DIEPINT_XFRC ) { in_ep[n].DIEPINT = USB_OTG_DIEPINT_XFRC; - dcd_event_xfer_complete(0, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); + dcd_event_xfer_complete(rhport, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); } // XFER FIFO empty @@ -686,7 +699,7 @@ static void handle_epin_ints(USB_OTG_DeviceTypeDef * dev, USB_OTG_INEndpointType xfer->queued_len = xfer->total_len - remaining_bytes; // Push packet to Tx-FIFO - write_fifo_packet(n, (xfer->buffer + xfer->queued_len), packet_size); + write_fifo_packet(rhport, n, (xfer->buffer + xfer->queued_len), packet_size); } // Turn off TXFE if all bytes are written. @@ -699,20 +712,18 @@ static void handle_epin_ints(USB_OTG_DeviceTypeDef * dev, USB_OTG_INEndpointType } } -void dcd_int_handler(uint8_t rhport) { - - (void) rhport; - - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE; - USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE; - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE; +void dcd_int_handler(uint8_t rhport) +{ + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); + USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); uint32_t int_status = USB_OTG_FS->GINTSTS; if(int_status & USB_OTG_GINTSTS_USBRST) { // USBRST is start of reset. USB_OTG_FS->GINTSTS = USB_OTG_GINTSTS_USBRST; - bus_reset(); + bus_reset(rhport); } if(int_status & USB_OTG_GINTSTS_ENUMDNE) { @@ -720,20 +731,20 @@ void dcd_int_handler(uint8_t rhport) { // always expect the same value. This interrupt is considered // the end of reset. USB_OTG_FS->GINTSTS = USB_OTG_GINTSTS_ENUMDNE; - end_of_reset(); - dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true); + end_of_reset(rhport); + dcd_event_bus_signal(rhport, DCD_EVENT_BUS_RESET, true); } if(int_status & USB_OTG_GINTSTS_USBSUSP) { USB_OTG_FS->GINTSTS = USB_OTG_GINTSTS_USBSUSP; - dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); } if(int_status & USB_OTG_GINTSTS_WKUINT) { USB_OTG_FS->GINTSTS = USB_OTG_GINTSTS_WKUINT; - dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); + dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); } if(int_status & USB_OTG_GINTSTS_OTGINT) @@ -743,7 +754,7 @@ void dcd_int_handler(uint8_t rhport) { if (otg_int & USB_OTG_GOTGINT_SEDET) { - dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, true); + dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); } USB_OTG_FS->GOTGINT = otg_int; @@ -761,20 +772,20 @@ void dcd_int_handler(uint8_t rhport) { // Mask out RXFLVL while reading data from FIFO USB_OTG_FS->GINTMSK &= ~USB_OTG_GINTMSK_RXFLVLM; - read_rx_fifo(out_ep); + read_rx_fifo(rhport, out_ep); USB_OTG_FS->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM; } // OUT endpoint interrupt handling. if(int_status & USB_OTG_GINTSTS_OEPINT) { // OEPINT is read-only - handle_epout_ints(dev, out_ep); + handle_epout_ints(rhport, dev, out_ep); } // IN endpoint interrupt handling. if(int_status & USB_OTG_GINTSTS_IEPINT) { // IEPINT bit read-only - handle_epin_ints(dev, in_ep); + handle_epin_ints(rhport, dev, in_ep); } } -- cgit v1.3.1 From 947c3eb10dee55e7c05bee8e10d21a225e311263 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 26 May 2020 16:07:48 +0700 Subject: multiple port support for global otg base --- src/portable/st/synopsys/dcd_synopsys.c | 65 +++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index ee987b0de..b68794712 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -103,6 +103,7 @@ static const dcd_rhport_t _dcd_rhport[] = #endif }; +#define GLOBAL_BASE(_port) ((USB_OTG_GlobalTypeDef*) _dcd_rhport[_port].regs) #define DEVICE_BASE(_port) (USB_OTG_DeviceTypeDef *) (_dcd_rhport[_port].regs + USB_OTG_DEVICE_BASE) #define OUT_EP_BASE(_port) (USB_OTG_OUTEndpointTypeDef *) (_dcd_rhport[_port].regs + USB_OTG_OUT_ENDPOINT_BASE) #define IN_EP_BASE(_port) (USB_OTG_INEndpointTypeDef *) (_dcd_rhport[_port].regs + USB_OTG_IN_ENDPOINT_BASE) @@ -137,6 +138,7 @@ xfer_ctl_t xfer_status[EP_MAX][2]; // Setup the control endpoint 0. static void bus_reset(uint8_t rhport) { + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); @@ -176,14 +178,14 @@ static void bus_reset(uint8_t rhport) // * 1 location for global NAK (not required/used here). // * It is recommended to allocate 2 times the largest packet size, therefore // Recommended value = 10 + 1 + 2 x (16+2) = 47 --> Let's make it 52 - USB_OTG_FS->GRXFSIZ = 52; + usb_otg->GRXFSIZ = 52; // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word ) - USB_OTG_FS->DIEPTXF0_HNPTXFSIZ = (16 << USB_OTG_TX0FD_Pos) | (USB_OTG_FS->GRXFSIZ & 0x0000ffffUL); + usb_otg->DIEPTXF0_HNPTXFSIZ = (16 << USB_OTG_TX0FD_Pos) | (usb_otg->GRXFSIZ & 0x0000ffffUL); out_ep[0].DOEPTSIZ |= (3 << USB_OTG_DOEPTSIZ_STUPCNT_Pos); - USB_OTG_FS->GINTMSK |= USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT; + usb_otg->GINTMSK |= USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT; } static void end_of_reset(uint8_t rhport) @@ -216,22 +218,24 @@ static void end_of_reset(uint8_t rhport) *------------------------------------------------------------------*/ void dcd_init (uint8_t rhport) { + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); + // Programming model begins in the last section of the chapter on the USB // peripheral in each Reference Manual. - USB_OTG_FS->GAHBCFG |= USB_OTG_GAHBCFG_GINT; + usb_otg->GAHBCFG |= USB_OTG_GAHBCFG_GINT; // No HNP/SRP (no OTG support), program timeout later, turnaround // programmed for 32+ MHz. // TODO: PHYSEL is read-only on some cores (STM32F407). Worth gating? - USB_OTG_FS->GUSBCFG |= (0x06 << USB_OTG_GUSBCFG_TRDT_Pos) | USB_OTG_GUSBCFG_PHYSEL; + usb_otg->GUSBCFG |= (0x06 << USB_OTG_GUSBCFG_TRDT_Pos) | USB_OTG_GUSBCFG_PHYSEL; // Clear all interrupts - USB_OTG_FS->GINTSTS |= USB_OTG_FS->GINTSTS; + usb_otg->GINTSTS |= usb_otg->GINTSTS; // Required as part of core initialization. // TODO: How should mode mismatch be handled? It will cause // the core to stop working/require reset. - USB_OTG_FS->GINTMSK |= USB_OTG_GINTMSK_OTGINT | USB_OTG_GINTMSK_MMISM; + usb_otg->GINTMSK |= USB_OTG_GINTMSK_OTGINT | USB_OTG_GINTMSK_MMISM; USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); @@ -239,12 +243,12 @@ void dcd_init (uint8_t rhport) // (non zero-length packet), send STALL back and discard. Full speed. dev->DCFG |= USB_OTG_DCFG_NZLSOHSK | (3 << USB_OTG_DCFG_DSPD_Pos); - USB_OTG_FS->GINTMSK |= USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_ENUMDNEM | + usb_otg->GINTMSK |= USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_WUIM | USB_OTG_GINTMSK_RXFLVLM | (USE_SOF ? USB_OTG_GINTMSK_SOFM : 0); // Enable USB transceiver. - USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_PWRDWN; + usb_otg->GCCFG |= USB_OTG_GCCFG_PWRDWN; } void dcd_int_enable (uint8_t rhport) @@ -292,6 +296,7 @@ void dcd_disconnect(uint8_t rhport) bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) { + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); @@ -348,12 +353,12 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) // Both TXFD and TXSA are in unit of 32-bit words. // IN FIFO 0 was configured during enumeration, hence the "+ 16". - uint16_t const allocated_size = (USB_OTG_FS->GRXFSIZ & 0x0000ffff) + 16; + uint16_t const allocated_size = (usb_otg->GRXFSIZ & 0x0000ffff) + 16; uint16_t const fifo_size = (EP_FIFO_SIZE/4 - allocated_size) / (EP_MAX-1); uint32_t const fifo_offset = allocated_size + fifo_size*(epnum-1); // DIEPTXF starts at FIFO #1. - USB_OTG_FS->DIEPTXF[epnum - 1] = (fifo_size << USB_OTG_DIEPTXF_INEPTXFD_Pos) | fifo_offset; + usb_otg->DIEPTXF[epnum - 1] = (fifo_size << USB_OTG_DIEPTXF_INEPTXFD_Pos) | fifo_offset; } return true; @@ -408,6 +413,7 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t // (send STALL versus NAK handshakes back). Refactor into resuable function. void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) { + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); @@ -431,9 +437,9 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) } // Flush the FIFO, and wait until we have confirmed it cleared. - USB_OTG_FS->GRSTCTL |= ((epnum - 1) << USB_OTG_GRSTCTL_TXFNUM_Pos); - USB_OTG_FS->GRSTCTL |= USB_OTG_GRSTCTL_TXFFLSH; - while((USB_OTG_FS->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH_Msk) != 0); + usb_otg->GRSTCTL |= ((epnum - 1) << USB_OTG_GRSTCTL_TXFNUM_Pos); + usb_otg->GRSTCTL |= USB_OTG_GRSTCTL_TXFFLSH; + while((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH_Msk) != 0); } else { // Only disable currently enabled non-control endpoint if ( (epnum == 0) || !(out_ep[epnum].DOEPCTL & USB_OTG_DOEPCTL_EPENA) ){ @@ -444,7 +450,7 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) // anyway, and it can't be cleared by user code. If this while loop never // finishes, we have bigger problems than just the stack. dev->DCTL |= USB_OTG_DCTL_SGONAK; - while((USB_OTG_FS->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF_Msk) == 0); + while((usb_otg->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF_Msk) == 0); // Ditto here- disable the endpoint. out_ep[epnum].DOEPCTL |= (USB_OTG_DOEPCTL_STALL | USB_OTG_DOEPCTL_EPDIS); @@ -577,12 +583,14 @@ static void write_fifo_packet(uint8_t rhport, uint8_t fifo_num, uint8_t * src, u } } -static void read_rx_fifo(uint8_t rhport, USB_OTG_OUTEndpointTypeDef * out_ep) { +static void read_rx_fifo(uint8_t rhport, USB_OTG_OUTEndpointTypeDef * out_ep) +{ + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); usb_fifo_t rx_fifo = FIFO_BASE(rhport, 0); // Pop control word off FIFO (completed xfers will have 2 control words, // we only pop one ctl word each interrupt). - uint32_t ctl_word = USB_OTG_FS->GRXSTSP; + uint32_t ctl_word = usb_otg->GRXSTSP; uint8_t pktsts = (ctl_word & USB_OTG_GRXSTSP_PKTSTS_Msk) >> USB_OTG_GRXSTSP_PKTSTS_Pos; uint8_t epnum = (ctl_word & USB_OTG_GRXSTSP_EPNUM_Msk) >> USB_OTG_GRXSTSP_EPNUM_Pos; uint16_t bcnt = (ctl_word & USB_OTG_GRXSTSP_BCNT_Msk) >> USB_OTG_GRXSTSP_BCNT_Pos; @@ -714,15 +722,16 @@ static void handle_epin_ints(uint8_t rhport, USB_OTG_DeviceTypeDef * dev, USB_OT void dcd_int_handler(uint8_t rhport) { + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); - uint32_t int_status = USB_OTG_FS->GINTSTS; + uint32_t int_status = usb_otg->GINTSTS; if(int_status & USB_OTG_GINTSTS_USBRST) { // USBRST is start of reset. - USB_OTG_FS->GINTSTS = USB_OTG_GINTSTS_USBRST; + usb_otg->GINTSTS = USB_OTG_GINTSTS_USBRST; bus_reset(rhport); } @@ -730,40 +739,40 @@ void dcd_int_handler(uint8_t rhport) // ENUMDNE detects speed of the link. For full-speed, we // always expect the same value. This interrupt is considered // the end of reset. - USB_OTG_FS->GINTSTS = USB_OTG_GINTSTS_ENUMDNE; + usb_otg->GINTSTS = USB_OTG_GINTSTS_ENUMDNE; end_of_reset(rhport); dcd_event_bus_signal(rhport, DCD_EVENT_BUS_RESET, true); } if(int_status & USB_OTG_GINTSTS_USBSUSP) { - USB_OTG_FS->GINTSTS = USB_OTG_GINTSTS_USBSUSP; + usb_otg->GINTSTS = USB_OTG_GINTSTS_USBSUSP; dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); } if(int_status & USB_OTG_GINTSTS_WKUINT) { - USB_OTG_FS->GINTSTS = USB_OTG_GINTSTS_WKUINT; + usb_otg->GINTSTS = USB_OTG_GINTSTS_WKUINT; dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); } if(int_status & USB_OTG_GINTSTS_OTGINT) { // OTG INT bit is read-only - uint32_t const otg_int = USB_OTG_FS->GOTGINT; + uint32_t const otg_int = usb_otg->GOTGINT; if (otg_int & USB_OTG_GOTGINT_SEDET) { dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); } - USB_OTG_FS->GOTGINT = otg_int; + usb_otg->GOTGINT = otg_int; } #if USE_SOF if(int_status & USB_OTG_GINTSTS_SOF) { - USB_OTG_FS->GINTSTS = USB_OTG_GINTSTS_SOF; - dcd_event_bus_signal(0, DCD_EVENT_SOF, true); + usb_otg->GINTSTS = USB_OTG_GINTSTS_SOF; + dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); } #endif @@ -771,9 +780,9 @@ void dcd_int_handler(uint8_t rhport) // RXFLVL bit is read-only // Mask out RXFLVL while reading data from FIFO - USB_OTG_FS->GINTMSK &= ~USB_OTG_GINTMSK_RXFLVLM; + usb_otg->GINTMSK &= ~USB_OTG_GINTMSK_RXFLVLM; read_rx_fifo(rhport, out_ep); - USB_OTG_FS->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM; + usb_otg->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM; } // OUT endpoint interrupt handling. -- cgit v1.3.1 From 0482f0d6867835d3dbb3939452fbcfaf9727b555 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 26 May 2020 22:11:26 +0700 Subject: update h743eval with rhport=1 highspeed --- hw/bsp/stm32h743eval/board.mk | 7 +-- hw/bsp/stm32h743eval/stm32h743eval.c | 97 ++++++++++++++++++++++++++++++++---- src/tusb_option.h | 4 -- test/test/support/tusb_config.h | 5 -- 4 files changed, 89 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/hw/bsp/stm32h743eval/board.mk b/hw/bsp/stm32h743eval/board.mk index 5044cdc08..68d142435 100644 --- a/hw/bsp/stm32h743eval/board.mk +++ b/hw/bsp/stm32h743eval/board.mk @@ -8,11 +8,8 @@ CFLAGS += \ -nostdlib -nostartfiles \ -DSTM32H743xx \ -DCFG_TUSB_MCU=OPT_MCU_STM32H7 \ - -# Board specific for using usb ports -CFLAGS += \ - -DCFG_BOARD_DEVICE_RHPORT_NUM=1 \ - -DCFG_BOARD_DEVICE_RHPORT_HIGHSPEED + -DBOARD_DEVICE_RHPORT_NUM=1 \ + -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED # suppress warning caused by vendor mcu driver CFLAGS += -Wno-error=maybe-uninitialized diff --git a/hw/bsp/stm32h743eval/stm32h743eval.c b/hw/bsp/stm32h743eval/stm32h743eval.c index 5a7934ea2..fd3d33047 100644 --- a/hw/bsp/stm32h743eval/stm32h743eval.c +++ b/hw/bsp/stm32h743eval/stm32h743eval.c @@ -32,11 +32,22 @@ //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ + +// Despite being call USB2_OTG +// OTG_FS is marked as RHPort0 by TinyUSB to be consistent across stm32 port void OTG_FS_IRQHandler(void) { tud_int_handler(0); } +// Despite being call USB2_OTG +// OTG_HS is marked as RHPort1 by TinyUSB to be consistent across stm32 port +void OTG_HS_IRQHandler(void) +{ + tud_int_handler(1); +} + + //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ @@ -53,7 +64,7 @@ void OTG_FS_IRQHandler(void) // enable all LED, Button, Uart, USB clock static void all_rcc_clk_enable(void) { - __HAL_RCC_GPIOA_CLK_ENABLE(); // LED, USB D+, D- + __HAL_RCC_GPIOA_CLK_ENABLE(); // LED __HAL_RCC_GPIOC_CLK_ENABLE(); // Button // __HAL_RCC_GPIOD_CLK_ENABLE(); // Uart tx, rx // __HAL_RCC_USART3_CLK_ENABLE(); // Uart module @@ -187,17 +198,13 @@ void board_init(void) GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); -#if CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE - - // USB1 HS (ULPI Phy), internal FS PHY - // PB12 ID, PB13 VBUS, PB14 DM, PB15 DP - -#endif - -#if CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE - // USB2 FS Pin Init +#if BOARD_DEVICE_RHPORT_NUM == 0 + // Despite being call USB2_OTG + // OTG_FS is marked as RHPort0 by TinyUSB to be consistent across stm32 port // PA9 VUSB, PA10 ID, PA11 DM, PA12 DP + __HAL_RCC_GPIOA_CLK_ENABLE(); + /* Configure DM DP Pins */ GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; @@ -228,6 +235,76 @@ void board_init(void) // Enable VBUS sense (B device) via pin PA9 USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBDEN; #endif + +#if BOARD_DEVICE_RHPORT_NUM == 1 + // Despite being call USB2_OTG + // OTG_HS is marked as RHPort1 by TinyUSB to be consistent across stm32 port + __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_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG2_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_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG2_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_OTG2_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_OTG2_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_OTG2_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_OTG2_HS; + HAL_GPIO_Init(GPIOI, &GPIO_InitStruct); + __HAL_RCC_USB1_OTG_HS_ULPI_CLK_ENABLE(); + + /* Enable USB HS Clocks */ + __HAL_RCC_USB1_OTG_HS_CLK_ENABLE(); + + // No VBUS sense + USB_OTG_HS->GCCFG &= ~USB_OTG_GCCFG_VBDEN; + + // Force device mode + // USB_OTG_HS->GUSBCFG &= ~USB_OTG_GUSBCFG_FHMOD; + // USB_OTG_HS->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD; + + // B-peripheral session valid override enabl +// USB_OTG_HS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN; +// USB_OTG_HS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL; +#endif // rhport = 1 + } //--------------------------------------------------------------------+ diff --git a/src/tusb_option.h b/src/tusb_option.h index 472656424..c251d578a 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -138,10 +138,6 @@ #define CFG_TUSB_RHPORT0_MODE OPT_MODE_NONE #endif -//#ifndef CFG_TUSB_RHPORT1_MODE -// #define CFG_TUSB_RHPORT1_MODE OPT_MODE_NONE -//#endif - #if ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST ) && (CFG_TUSB_RHPORT0_MODE & (OPT_MODE_HOST << 8)) ) || \ ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) && (CFG_TUSB_RHPORT0_MODE & (OPT_MODE_DEVICE << 8)) ) #error "TinyUSB currently does not support same modes on more than 1 roothub port" diff --git a/test/test/support/tusb_config.h b/test/test/support/tusb_config.h index 5258513ec..76f975323 100644 --- a/test/test/support/tusb_config.h +++ b/test/test/support/tusb_config.h @@ -43,12 +43,7 @@ #define CFG_TUSB_MCU OPT_MCU_NRF5X #endif -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) -#else -#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE -#endif - #define CFG_TUSB_OS OPT_OS_NONE // CFG_TUSB_DEBUG is defined by compiler in DEBUG build -- cgit v1.3.1 From b4804d1592901ee202f661f4e44e621a05aca315 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 26 May 2020 22:15:38 +0700 Subject: random clean up for tdi --- src/portable/nxp/transdimension/dcd_transdimension.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/portable/nxp/transdimension/dcd_transdimension.c b/src/portable/nxp/transdimension/dcd_transdimension.c index 7baf43e23..68cf145ea 100644 --- a/src/portable/nxp/transdimension/dcd_transdimension.c +++ b/src/portable/nxp/transdimension/dcd_transdimension.c @@ -236,7 +236,7 @@ typedef struct { dcd_registers_t* regs; // registers const IRQn_Type irqnum; // IRQ number - const uint8_t ep_count; // Max bi-directional Endpoints + const uint8_t ep_count; // Max bi-directional Endpoints }dcd_controller_t; #if CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX @@ -244,7 +244,7 @@ typedef struct // Therefore QHD_MAX is 2 x max endpoint count #define QHD_MAX (8*2) - dcd_controller_t _dcd_controller[] = + static const dcd_controller_t _dcd_controller[] = { // RT1010 and RT1020 only has 1 USB controller #if FSL_FEATURE_SOC_USBHS_COUNT == 1 @@ -258,7 +258,7 @@ typedef struct #else #define QHD_MAX (6*2) - dcd_controller_t _dcd_controller[] = + static const dcd_controller_t _dcd_controller[] = { { .regs = (dcd_registers_t*) LPC_USB0_BASE, .irqnum = USB0_IRQn, .ep_count = 6 }, { .regs = (dcd_registers_t*) LPC_USB1_BASE, .irqnum = USB1_IRQn, .ep_count = 4 } -- cgit v1.3.1 From d4bf777c943659a4e985ce8514ef077c5bf2b40d Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 27 May 2020 11:01:33 +0700 Subject: try to get synopsys work with OTG HS + external PHY --- src/device/usbd.c | 1 + src/portable/st/synopsys/dcd_synopsys.c | 80 +++++++++++++++++++++++++++------ 2 files changed, 68 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index f7918c07e..bd892e389 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -384,6 +384,7 @@ void tud_task (void) { case DCD_EVENT_BUS_RESET: usbd_reset(event.rhport); + // TODO DCD should report operational speed (LS/FS/HS) break; case DCD_EVENT_UNPLUGGED: diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index b68794712..8ca67dbb4 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -99,7 +99,7 @@ static const dcd_rhport_t _dcd_rhport[] = { .regs = USB_OTG_FS_PERIPH_BASE, .irqnum = OTG_FS_IRQn } #ifdef USB_OTG_HS - ,{ .regs = USB_OTG_HS_PERIPH_BASE, .irqnum = OTG_HS_IRQn } + ,{ .regs = USB_OTG_HS_PERIPH_BASE, .irqnum = OTG_HS_IRQn } #endif }; @@ -218,16 +218,48 @@ static void end_of_reset(uint8_t rhport) *------------------------------------------------------------------*/ void dcd_init (uint8_t rhport) { + dcd_disconnect(rhport); + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); - // Programming model begins in the last section of the chapter on the USB - // peripheral in each Reference Manual. - usb_otg->GAHBCFG |= USB_OTG_GAHBCFG_GINT; + // No HNP/SRP (no OTG support), program timeout later. +#if TUD_OPT_HIGH_SPEED // TODO may pass parameter instead of using macro for HighSpeed + if ( rhport == 1 ) + { + // Highspeed with external ULPI PHY + + // deactivate internal PHY + usb_otg->GCCFG &= ~USB_OTG_GCCFG_PWRDWN; + + // On selected MCUs HS port1 can be used with external PHY via ULPI interface + // Select ULPI highspeed PHY with default external VBUS Indicator and Drive + usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL | + USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI); + + // Turn around time for Highspeed is 0x09 + usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT; + usb_otg->GUSBCFG |= (0x09 << USB_OTG_GUSBCFG_TRDT_Pos); + }else +#endif + { + // Turn around programmed for 32+ MHz is 0x06 + usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT; + usb_otg->GUSBCFG |= (0x06 << USB_OTG_GUSBCFG_TRDT_Pos) | USB_OTG_GUSBCFG_PHYSEL; + } + + // Reset core after selecting PHY + // Wait AHB IDLE, reset then wait until it is cleared + while ((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U) {} + usb_otg->GRSTCTL |= USB_OTG_GRSTCTL_CSRST; + while ((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST) {} + + // Force device mode + usb_otg->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD; + + TU_LOG2_LOCATION(); - // No HNP/SRP (no OTG support), program timeout later, turnaround - // programmed for 32+ MHz. - // TODO: PHYSEL is read-only on some cores (STM32F407). Worth gating? - usb_otg->GUSBCFG |= (0x06 << USB_OTG_GUSBCFG_TRDT_Pos) | USB_OTG_GUSBCFG_PHYSEL; + // Restart PHY clock + *((volatile uint32_t *)(_dcd_rhport[rhport].regs + USB_OTG_PCGCCTL_BASE)) = 0; // Clear all interrupts usb_otg->GINTSTS |= usb_otg->GINTSTS; @@ -241,14 +273,33 @@ 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. Full speed. - dev->DCFG |= USB_OTG_DCFG_NZLSOHSK | (3 << USB_OTG_DCFG_DSPD_Pos); + dev->DCFG |= USB_OTG_DCFG_NZLSOHSK; + +#if TUD_OPT_HIGH_SPEED + if ( rhport == 1 ) + { + // high speed = 0x00 + dev->DCFG &= ~(3 << USB_OTG_DCFG_DSPD_Pos); + + // Transceiver delay, necessary for some ULPI PHYs + dev->DCFG |= (1 << 14); + } +#endif + { + // full speed with internal phy + dev->DCFG |= (3 << USB_OTG_DCFG_DSPD_Pos); + + // Enable USB transceiver. + usb_otg->GCCFG |= USB_OTG_GCCFG_PWRDWN; + } usb_otg->GINTMSK |= USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_ENUMDNEM | - USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_WUIM | - USB_OTG_GINTMSK_RXFLVLM | (USE_SOF ? USB_OTG_GINTMSK_SOFM : 0); + USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_WUIM | + USB_OTG_GINTMSK_RXFLVLM | (USE_SOF ? USB_OTG_GINTMSK_SOFM : 0); - // Enable USB transceiver. - usb_otg->GCCFG |= USB_OTG_GCCFG_PWRDWN; + // Programming model begins in the last section of the chapter on the USB + // peripheral in each Reference Manual. + usb_otg->GAHBCFG |= USB_OTG_GAHBCFG_GINT; } void dcd_int_enable (uint8_t rhport) @@ -739,6 +790,9 @@ void dcd_int_handler(uint8_t rhport) // ENUMDNE detects speed of the link. For full-speed, we // always expect the same value. This interrupt is considered // the end of reset. + + TU_LOG2_HEX(dev->DSTS); + usb_otg->GINTSTS = USB_OTG_GINTSTS_ENUMDNE; end_of_reset(rhport); dcd_event_bus_signal(rhport, DCD_EVENT_BUS_RESET, true); -- cgit v1.3.1 From 5ffba8536dfaa4602e3e7f1c94be124bfeb3a5ae Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 31 May 2020 19:41:22 +0700 Subject: able to detect as hs --- hw/bsp/stm32h743eval/stm32h743eval.c | 13 +++++++++---- src/common/tusb_common.h | 4 +++- src/portable/st/synopsys/dcd_synopsys.c | 10 ++++++---- 3 files changed, 18 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/hw/bsp/stm32h743eval/stm32h743eval.c b/hw/bsp/stm32h743eval/stm32h743eval.c index d149c1230..836f1ecab 100644 --- a/hw/bsp/stm32h743eval/stm32h743eval.c +++ b/hw/bsp/stm32h743eval/stm32h743eval.c @@ -265,6 +265,7 @@ void board_init(void) #endif #if BOARD_DEVICE_RHPORT_NUM == 1 + // Despite being call USB2_OTG // OTG_HS is marked as RHPort1 by TinyUSB to be consistent across stm32 port __GPIOA_CLK_ENABLE(); @@ -316,6 +317,8 @@ void board_init(void) GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Alternate = GPIO_AF10_OTG2_HS; HAL_GPIO_Init(GPIOI, &GPIO_InitStruct); + + // Enable ULPI clock __HAL_RCC_USB1_OTG_HS_ULPI_CLK_ENABLE(); /* Enable USB HS Clocks */ @@ -325,12 +328,14 @@ void board_init(void) USB_OTG_HS->GCCFG &= ~USB_OTG_GCCFG_VBDEN; // Force device mode - // USB_OTG_HS->GUSBCFG &= ~USB_OTG_GUSBCFG_FHMOD; - // USB_OTG_HS->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD; + USB_OTG_HS->GUSBCFG &= ~USB_OTG_GUSBCFG_FHMOD; + USB_OTG_HS->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD; // B-peripheral session valid override enabl -// USB_OTG_HS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN; -// USB_OTG_HS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL; + USB_OTG_HS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN; + USB_OTG_HS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL; + + HAL_PWREx_EnableUSBVoltageDetector(); #endif // rhport = 1 } diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index f144cda73..d77893b6b 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -241,9 +241,9 @@ void tu_print_var(uint8_t const* buf, uint32_t bufsize) #define TU_LOG2 TU_LOG1 #define TU_LOG2_MEM TU_LOG1_MEM #define TU_LOG2_VAR TU_LOG1_VAR - #define TU_LOG2_LOCATION() TU_LOG1_LOCATION() #define TU_LOG2_INT TU_LOG1_INT #define TU_LOG2_HEX TU_LOG1_HEX + #define TU_LOG2_LOCATION() TU_LOG1_LOCATION() #endif @@ -277,6 +277,7 @@ static inline char const* lookup_find(lookup_table_t const* p_table, uint32_t ke #define TU_LOG1_VAR(...) #define TU_LOG1_INT(...) #define TU_LOG1_HEX(...) + #define TU_LOG1_LOCATION() #endif #ifndef TU_LOG2 @@ -285,6 +286,7 @@ static inline char const* lookup_find(lookup_table_t const* p_table, uint32_t ke #define TU_LOG2_VAR(...) #define TU_LOG2_INT(...) #define TU_LOG2_HEX(...) + #define TU_LOG2_LOCATION() #endif #ifdef __cplusplus diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index 8ca67dbb4..fe6fe5cea 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -197,6 +197,8 @@ static void end_of_reset(uint8_t rhport) // However, keep for debugging and in case Low Speed is ever supported. uint32_t enum_spd = (dev->DSTS & USB_OTG_DSTS_ENUMSPD_Msk) >> USB_OTG_DSTS_ENUMSPD_Pos; + // TODO set turnaround in GUSBCFG accordingly to the speed + // Maximum packet size for EP 0 is set for both directions by writing // DIEPCTL. if(enum_spd == 0x03) { @@ -239,7 +241,8 @@ void dcd_init (uint8_t rhport) // Turn around time for Highspeed is 0x09 usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT; usb_otg->GUSBCFG |= (0x09 << USB_OTG_GUSBCFG_TRDT_Pos); - }else + } + else #endif { // Turn around programmed for 32+ MHz is 0x06 @@ -256,8 +259,6 @@ void dcd_init (uint8_t rhport) // Force device mode usb_otg->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD; - TU_LOG2_LOCATION(); - // Restart PHY clock *((volatile uint32_t *)(_dcd_rhport[rhport].regs + USB_OTG_PCGCCTL_BASE)) = 0; @@ -282,8 +283,9 @@ void dcd_init (uint8_t rhport) dev->DCFG &= ~(3 << USB_OTG_DCFG_DSPD_Pos); // Transceiver delay, necessary for some ULPI PHYs - dev->DCFG |= (1 << 14); + //dev->DCFG |= (1 << 14); } + else #endif { // full speed with internal phy -- cgit v1.3.1 From f771afe6af894a5f3ee029756d4521b56d74c1c0 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 31 May 2020 23:43:29 +0700 Subject: fixed EP0 size to 64 since LS is not supported in device mode - set turn-around and report actual speed in Enum Done - add dcd_event_bus_reset() helper to report speed --- src/device/dcd.h | 15 ++++-- src/device/usbd.c | 9 +++- src/portable/st/synopsys/dcd_synopsys.c | 85 ++++++++++++++++----------------- 3 files changed, 62 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/device/dcd.h b/src/device/dcd.h index 68798c259..a4635346b 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -60,11 +60,17 @@ typedef struct TU_ATTR_ALIGNED(4) uint8_t rhport; uint8_t event_id; - union { - // USBD_EVT_SETUP_RECEIVED + union + { + // BUS RESET + struct { + tusb_speed_t speed; + } bus_reset; + + // SETUP_RECEIVED tusb_control_request_t setup_received; - // USBD_EVT_XFER_COMPLETE + // XFER_COMPLETE struct { uint8_t ep_addr; uint8_t result; @@ -143,6 +149,9 @@ extern void dcd_event_handler(dcd_event_t const * event, bool in_isr); // helper to send bus signal event extern void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr); +// helper to send bus reset event +extern void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr); + // helper to send setup received extern void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr); diff --git a/src/device/usbd.c b/src/device/usbd.c index bd892e389..275792ab9 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -920,7 +920,14 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr) void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr) { - dcd_event_t event = { .rhport = rhport, .event_id = eid, }; + dcd_event_t event = { .rhport = rhport, .event_id = eid }; + dcd_event_handler(&event, in_isr); +} + +void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr) +{ + dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_BUS_RESET }; + event.bus_reset.speed = speed; dcd_event_handler(&event, in_isr); } diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index fe6fe5cea..ed16308da 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -109,6 +109,13 @@ static const dcd_rhport_t _dcd_rhport[] = #define IN_EP_BASE(_port) (USB_OTG_INEndpointTypeDef *) (_dcd_rhport[_port].regs + USB_OTG_IN_ENDPOINT_BASE) #define FIFO_BASE(_port, _x) ((volatile uint32_t *) (_dcd_rhport[_port].regs + USB_OTG_FIFO_BASE + (_x) * USB_OTG_FIFO_SIZE)) +enum +{ + DCD_HIGH_SPEED = 0, // Highspeed mode + DCD_FULL_SPEED_USE_HS = 1, // Full speed in Highspeed port (probably with internal PHY) + DCD_FULL_SPEED = 3, // Full speed with internal PHY +}; + /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM @@ -141,6 +148,7 @@ static void bus_reset(uint8_t rhport) USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); + USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); for(uint8_t n = 0; n < EP_MAX; n++) { out_ep[n].DOEPCTL |= USB_OTG_DOEPCTL_SNAK; @@ -183,34 +191,29 @@ static void bus_reset(uint8_t rhport) // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word ) usb_otg->DIEPTXF0_HNPTXFSIZ = (16 << USB_OTG_TX0FD_Pos) | (usb_otg->GRXFSIZ & 0x0000ffffUL); + // Fixed control EP0 size to 64 bytes + in_ep[0].DIEPCTL &= ~(0x03 << USB_OTG_DIEPCTL_MPSIZ_Pos); + xfer_status[0][TUSB_DIR_OUT].max_size = xfer_status[0][TUSB_DIR_IN].max_size = 64; + out_ep[0].DOEPTSIZ |= (3 << USB_OTG_DOEPTSIZ_STUPCNT_Pos); usb_otg->GINTMSK |= USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT; } -static void end_of_reset(uint8_t rhport) +// speed is native DCD speed +static void set_turnaround(USB_OTG_GlobalTypeDef * usb_otg, uint32_t speed) { - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); + usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT; - // On current silicon on the Full Speed core, speed is fixed to Full Speed. - // However, keep for debugging and in case Low Speed is ever supported. - uint32_t enum_spd = (dev->DSTS & USB_OTG_DSTS_ENUMSPD_Msk) >> USB_OTG_DSTS_ENUMSPD_Pos; - - // TODO set turnaround in GUSBCFG accordingly to the speed - - // Maximum packet size for EP 0 is set for both directions by writing - // DIEPCTL. - if(enum_spd == 0x03) { - // 64 bytes - in_ep[0].DIEPCTL &= ~(0x03 << USB_OTG_DIEPCTL_MPSIZ_Pos); - xfer_status[0][TUSB_DIR_OUT].max_size = 64; - xfer_status[0][TUSB_DIR_IN].max_size = 64; - } else { - // 8 bytes - in_ep[0].DIEPCTL |= (0x03 << USB_OTG_DIEPCTL_MPSIZ_Pos); - xfer_status[0][TUSB_DIR_OUT].max_size = 8; - xfer_status[0][TUSB_DIR_IN].max_size = 8; + if ( speed == DCD_HIGH_SPEED ) + { + // Use fixed 0x09 for Highspeed + usb_otg->GUSBCFG |= (0x09 << USB_OTG_GUSBCFG_TRDT_Pos); + } + else + { + // Fullspeed depends on MCU clocks, but we will use 0x06 for 32+ Mhz + usb_otg->GUSBCFG |= (0x06 << USB_OTG_GUSBCFG_TRDT_Pos); } } @@ -220,7 +223,8 @@ static void end_of_reset(uint8_t rhport) *------------------------------------------------------------------*/ void dcd_init (uint8_t rhport) { - dcd_disconnect(rhport); + // Programming model begins in the last section of the chapter on the USB + // peripheral in each Reference Manual. USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); @@ -238,16 +242,15 @@ void dcd_init (uint8_t rhport) usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL | USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI); - // Turn around time for Highspeed is 0x09 - usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT; - usb_otg->GUSBCFG |= (0x09 << USB_OTG_GUSBCFG_TRDT_Pos); + set_turnaround(usb_otg, DCD_HIGH_SPEED); } else #endif { - // Turn around programmed for 32+ MHz is 0x06 - usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT; - usb_otg->GUSBCFG |= (0x06 << USB_OTG_GUSBCFG_TRDT_Pos) | USB_OTG_GUSBCFG_PHYSEL; + set_turnaround(usb_otg, DCD_FULL_SPEED); + + // Enable internal PHY + usb_otg->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL; } // Reset core after selecting PHY @@ -256,9 +259,6 @@ void dcd_init (uint8_t rhport) usb_otg->GRSTCTL |= USB_OTG_GRSTCTL_CSRST; while ((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST) {} - // Force device mode - usb_otg->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD; - // Restart PHY clock *((volatile uint32_t *)(_dcd_rhport[rhport].regs + USB_OTG_PCGCCTL_BASE)) = 0; @@ -273,7 +273,7 @@ void dcd_init (uint8_t rhport) USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); // If USB host misbehaves during status portion of control xfer - // (non zero-length packet), send STALL back and discard. Full speed. + // (non zero-length packet), send STALL back and discard. dev->DCFG |= USB_OTG_DCFG_NZLSOHSK; #if TUD_OPT_HIGH_SPEED @@ -288,10 +288,10 @@ void dcd_init (uint8_t rhport) else #endif { - // full speed with internal phy + // full speed with internal PHY dev->DCFG |= (3 << USB_OTG_DCFG_DSPD_Pos); - // Enable USB transceiver. + // Enable internal USB transceiver. usb_otg->GCCFG |= USB_OTG_GCCFG_PWRDWN; } @@ -299,8 +299,8 @@ void dcd_init (uint8_t rhport) USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_WUIM | USB_OTG_GINTMSK_RXFLVLM | (USE_SOF ? USB_OTG_GINTMSK_SOFM : 0); - // Programming model begins in the last section of the chapter on the USB - // peripheral in each Reference Manual. + + // Enable global interrupt usb_otg->GAHBCFG |= USB_OTG_GAHBCFG_GINT; } @@ -789,15 +789,14 @@ void dcd_int_handler(uint8_t rhport) } if(int_status & USB_OTG_GINTSTS_ENUMDNE) { - // ENUMDNE detects speed of the link. For full-speed, we - // always expect the same value. This interrupt is considered - // the end of reset. - - TU_LOG2_HEX(dev->DSTS); + // ENUMDNE is the end of reset where speed of the link is detected usb_otg->GINTSTS = USB_OTG_GINTSTS_ENUMDNE; - end_of_reset(rhport); - dcd_event_bus_signal(rhport, DCD_EVENT_BUS_RESET, true); + + uint32_t const enum_spd = (dev->DSTS & USB_OTG_DSTS_ENUMSPD_Msk) >> USB_OTG_DSTS_ENUMSPD_Pos; + + set_turnaround(usb_otg, enum_spd); + dcd_event_bus_reset(rhport, (enum_spd == DCD_HIGH_SPEED) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); } if(int_status & USB_OTG_GINTSTS_USBSUSP) -- cgit v1.3.1 From 710c54f8cbee2134334262cf872f538909b264c5 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 1 Jun 2020 01:36:09 +0700 Subject: allow hs ep open with 512 bytes --- examples/device/cdc_msc/src/usb_descriptors.c | 2 +- src/portable/st/synopsys/dcd_synopsys.c | 30 ++++++++++++++++++--------- 2 files changed, 21 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/examples/device/cdc_msc/src/usb_descriptors.c b/examples/device/cdc_msc/src/usb_descriptors.c index 7b22d46a7..62ab4f10f 100644 --- a/examples/device/cdc_msc/src/usb_descriptors.c +++ b/examples/device/cdc_msc/src/usb_descriptors.c @@ -123,7 +123,7 @@ uint8_t const desc_configuration[] = TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64), // Interface number, string index, EP Out & EP In address, EP size - TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 512 : 64), + TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, TUD_OPT_HIGH_SPEED ? 512 : 64), }; diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index ed16308da..739361da9 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -185,8 +185,9 @@ static void bus_reset(uint8_t rhport) // * 16 for largest packet size of 64 bytes. ( TODO Highspeed is 512 bytes) // * 1 location for global NAK (not required/used here). // * It is recommended to allocate 2 times the largest packet size, therefore - // Recommended value = 10 + 1 + 2 x (16+2) = 47 --> Let's make it 52 - usb_otg->GRXFSIZ = 52; + // Recommended value = 10 + 1 + 2 x (16+2) = 47. To make it scale better with large FIFO size + // and work better with Highspeed. We use 1/5 of total FIFO size + usb_otg->GRXFSIZ = (EP_FIFO_SIZE/4)/5; // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word ) usb_otg->DIEPTXF0_HNPTXFSIZ = (16 << USB_OTG_TX0FD_Pos) | (usb_otg->GRXFSIZ & 0x0000ffffUL); @@ -201,11 +202,11 @@ static void bus_reset(uint8_t rhport) } // speed is native DCD speed -static void set_turnaround(USB_OTG_GlobalTypeDef * usb_otg, uint32_t speed) +static void set_turnaround(USB_OTG_GlobalTypeDef * usb_otg, tusb_speed_t speed) { usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT; - if ( speed == DCD_HIGH_SPEED ) + if ( speed == TUSB_SPEED_HIGH ) { // Use fixed 0x09 for Highspeed usb_otg->GUSBCFG |= (0x09 << USB_OTG_GUSBCFG_TRDT_Pos); @@ -217,6 +218,12 @@ static void set_turnaround(USB_OTG_GlobalTypeDef * usb_otg, uint32_t speed) } } +static tusb_speed_t get_speed(USB_OTG_DeviceTypeDef* dev) +{ + uint32_t const enum_spd = (dev->DSTS & USB_OTG_DSTS_ENUMSPD_Msk) >> USB_OTG_DSTS_ENUMSPD_Pos; + return (enum_spd == DCD_HIGH_SPEED) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL; +} + /*------------------------------------------------------------------*/ /* Controller API @@ -242,12 +249,12 @@ void dcd_init (uint8_t rhport) usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL | USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI); - set_turnaround(usb_otg, DCD_HIGH_SPEED); + set_turnaround(usb_otg, TUSB_SPEED_HIGH); } else #endif { - set_turnaround(usb_otg, DCD_FULL_SPEED); + set_turnaround(usb_otg, TUSB_SPEED_FULL); // Enable internal PHY usb_otg->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL; @@ -357,9 +364,11 @@ 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(desc_edpt->wMaxPacketSize.size <= 64); TU_ASSERT(epnum < EP_MAX); + // TODO ISO endpoint can be up to 1024 bytes + TU_ASSERT(desc_edpt->wMaxPacketSize.size <= (get_speed(dev) == TUSB_SPEED_HIGH ? 512 : 64)); + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); xfer->max_size = desc_edpt->wMaxPacketSize.size; @@ -447,6 +456,7 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t ((total_bytes & USB_OTG_DIEPTSIZ_XFRSIZ_Msk) << USB_OTG_DIEPTSIZ_XFRSIZ_Pos); in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK; + // Enable fifo empty interrupt only if there are something to put in the fifo. if(total_bytes != 0) { dev->DIEPEMPMSK |= (1 << epnum); @@ -793,10 +803,10 @@ void dcd_int_handler(uint8_t rhport) usb_otg->GINTSTS = USB_OTG_GINTSTS_ENUMDNE; - uint32_t const enum_spd = (dev->DSTS & USB_OTG_DSTS_ENUMSPD_Msk) >> USB_OTG_DSTS_ENUMSPD_Pos; + tusb_speed_t const speed = get_speed(dev); - set_turnaround(usb_otg, enum_spd); - dcd_event_bus_reset(rhport, (enum_spd == DCD_HIGH_SPEED) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); + set_turnaround(usb_otg, speed); + dcd_event_bus_reset(rhport, speed, true); } if(int_status & USB_OTG_GINTSTS_USBSUSP) -- cgit v1.3.1 From e92118635cc8055a5ca599eaf9919d99a55bf584 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 1 Jun 2020 13:40:18 +0700 Subject: adding speed detect on bus reset --- hw/bsp/stm32h743eval/board.mk | 2 +- src/device/usbd.c | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/hw/bsp/stm32h743eval/board.mk b/hw/bsp/stm32h743eval/board.mk index 5c6c6ea4f..cbf37a95d 100644 --- a/hw/bsp/stm32h743eval/board.mk +++ b/hw/bsp/stm32h743eval/board.mk @@ -48,7 +48,7 @@ FREERTOS_PORT = ARM_CM7/r0p1 # For flash-jlink target JLINK_DEVICE = stm32h743xi -JLINK_IF = jtag +JLINK_IF = swd # flash target using on-board stlink flash: flash-stlink diff --git a/src/device/usbd.c b/src/device/usbd.c index 275792ab9..eeb5011ec 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -40,7 +40,8 @@ //--------------------------------------------------------------------+ // Device Data //--------------------------------------------------------------------+ -typedef struct { +typedef struct +{ struct TU_ATTR_PACKED { volatile uint8_t connected : 1; @@ -53,6 +54,8 @@ typedef struct { uint8_t self_powered : 1; // configuration descriptor's attribute }; + uint8_t speed; + uint8_t itf2drv[16]; // map interface number to driver (0xff is invalid) uint8_t ep2drv[8][2]; // map endpoint to driver ( 0xff is invalid ) @@ -384,7 +387,7 @@ void tud_task (void) { case DCD_EVENT_BUS_RESET: usbd_reset(event.rhport); - // TODO DCD should report operational speed (LS/FS/HS) + _usbd_dev.speed = event.bus_reset.speed; break; case DCD_EVENT_UNPLUGGED: -- cgit v1.3.1 From a347de6e50e98b339a1605dc927c0417e79b86a5 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 14 Jun 2020 18:28:45 +0700 Subject: revert CFG_TUSB_RHPORT0_MODE to previous way --- examples/device/cdc_msc/src/tusb_config.h | 9 ++++++++- hw/bsp/stm32h743eval/stm32h743eval.c | 3 +-- src/tusb_option.h | 23 ++++++++++++----------- 3 files changed, 21 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/examples/device/cdc_msc/src/tusb_config.h b/examples/device/cdc_msc/src/tusb_config.h index 9beb9f6a2..b05d219c6 100644 --- a/examples/device/cdc_msc/src/tusb_config.h +++ b/examples/device/cdc_msc/src/tusb_config.h @@ -56,7 +56,14 @@ #endif // Device mode with rhport and speed defined by board.mk -#define CFG_TUSB_RHPORT0_MODE ((OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) << (8*BOARD_DEVICE_RHPORT_NUM)) +#if BOARD_DEVICE_RHPORT_NUM == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#elif BOARD_DEVICE_RHPORT_NUM == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#else + #error "Incorrect RHPort configuration" +#endif + #define CFG_TUSB_OS OPT_OS_NONE // CFG_TUSB_DEBUG is defined by compiler in DEBUG build diff --git a/hw/bsp/stm32h743eval/stm32h743eval.c b/hw/bsp/stm32h743eval/stm32h743eval.c index 836f1ecab..a28110920 100644 --- a/hw/bsp/stm32h743eval/stm32h743eval.c +++ b/hw/bsp/stm32h743eval/stm32h743eval.c @@ -262,9 +262,8 @@ void board_init(void) // Enable VBUS sense (B device) via pin PA9 USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBDEN; -#endif -#if BOARD_DEVICE_RHPORT_NUM == 1 +#elif BOARD_DEVICE_RHPORT_NUM == 1 // Despite being call USB2_OTG // OTG_HS is marked as RHPort1 by TinyUSB to be consistent across stm32 port diff --git a/src/tusb_option.h b/src/tusb_option.h index c251d578a..01bb1301a 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -117,10 +117,7 @@ //-------------------------------------------------------------------- // RootHub Mode Configuration -// -// Each byte of the CFG_TUSB_RHPORTx_MODE contains operation mode for -// a roothub port (device or host). Therefore each macro can have up to -// 4 ports. +// CFG_TUSB_RHPORTx_MODE contains operation mode and speed for that port //-------------------------------------------------------------------- // Lower 4-bit is operational mode @@ -138,27 +135,31 @@ #define CFG_TUSB_RHPORT0_MODE OPT_MODE_NONE #endif -#if ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST ) && (CFG_TUSB_RHPORT0_MODE & (OPT_MODE_HOST << 8)) ) || \ - ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) && (CFG_TUSB_RHPORT0_MODE & (OPT_MODE_DEVICE << 8)) ) + +#ifndef CFG_TUSB_RHPORT1_MODE + #define CFG_TUSB_RHPORT1_MODE OPT_MODE_NONE +#endif + +#if ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST ) && (CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST )) || \ + ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) && (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE)) #error "TinyUSB currently does not support same modes on more than 1 roothub port" #endif // Which roothub port is configured as host -#define TUH_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) ? 0 : ((CFG_TUSB_RHPORT0_MODE & (OPT_MODE_HOST << 8)) ? 1 : -1) ) +#define TUH_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) ? 0 : ((CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST) ? 1 : -1) ) #define TUSB_OPT_HOST_ENABLED ( TUH_OPT_RHPORT >= 0 ) // Which roothub port is configured as device -#define TUD_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) ? 0 : ((CFG_TUSB_RHPORT0_MODE & (OPT_MODE_DEVICE << 8)) ? 1 : -1) ) +#define TUD_OPT_RHPORT ( (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) ? 0 : ((CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE) ? 1 : -1) ) #if TUD_OPT_RHPORT == 0 - #define TUD_OPT_HIGH_SPEED ( CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED ) +#define TUD_OPT_HIGH_SPEED ( CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED ) #else - #define TUD_OPT_HIGH_SPEED ( CFG_TUSB_RHPORT0_MODE & (OPT_MODE_HIGH_SPEED << 8) ) +#define TUD_OPT_HIGH_SPEED ( CFG_TUSB_RHPORT1_MODE & OPT_MODE_HIGH_SPEED ) #endif #define TUSB_OPT_DEVICE_ENABLED ( TUD_OPT_RHPORT >= 0 ) - //--------------------------------------------------------------------+ // COMMON OPTIONS //--------------------------------------------------------------------+ -- cgit v1.3.1 From 95966c22010bf01579f39847624395724298c459 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 14 Jun 2020 18:29:02 +0700 Subject: improve usbd log for control transfer --- src/device/usbd.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/device/usbd.c b/src/device/usbd.c index eeb5011ec..c337f1be1 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -380,17 +380,21 @@ void tud_task (void) if ( !osal_queue_receive(_usbd_q, &event) ) return; - TU_LOG2("USBD %s", event.event_id < DCD_EVENT_COUNT ? _usbd_event_str[event.event_id] : "CORRUPTED"); - TU_LOG2("%s", (event.event_id != DCD_EVENT_XFER_COMPLETE && event.event_id != DCD_EVENT_SETUP_RECEIVED) ? "\r\n" : " "); +#if CFG_TUSB_DEBUG >= 2 + if (event.event_id == DCD_EVENT_SETUP_RECEIVED) TU_LOG2("\r\n"); // extra line for setup + TU_LOG2("USBD %s ", event.event_id < DCD_EVENT_COUNT ? _usbd_event_str[event.event_id] : "CORRUPTED"); +#endif switch ( event.event_id ) { case DCD_EVENT_BUS_RESET: + TU_LOG2("\r\n"); usbd_reset(event.rhport); _usbd_dev.speed = event.bus_reset.speed; break; case DCD_EVENT_UNPLUGGED: + TU_LOG2("\r\n"); usbd_reset(event.rhport); // invoke callback @@ -442,14 +446,17 @@ void tud_task (void) break; case DCD_EVENT_SUSPEND: + TU_LOG2("\r\n"); if (tud_suspend_cb) tud_suspend_cb(_usbd_dev.remote_wakeup_en); break; case DCD_EVENT_RESUME: + TU_LOG2("\r\n"); if (tud_resume_cb) tud_resume_cb(); break; case DCD_EVENT_SOF: + TU_LOG2("\r\n"); for ( uint8_t i = 0; i < USBD_CLASS_DRIVER_COUNT; i++ ) { if ( _usbd_driver[i].sof ) @@ -460,6 +467,7 @@ void tud_task (void) break; case USBD_EVENT_FUNC_CALL: + TU_LOG2("\r\n"); if ( event.func_call.func ) event.func_call.func(event.func_call.param); break; -- cgit v1.3.1 From f438aedccba2b48d4ea9e606c3529c9fd6cb6985 Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 14 Jun 2020 18:29:38 +0700 Subject: overwrite setup packet --- src/portable/st/synopsys/dcd_synopsys.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index 739361da9..39d8fe73d 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -125,8 +125,7 @@ enum // We disable SOF for now until needed later on #define USE_SOF 0 -static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[6]; -static uint8_t _setup_offs; // We store up to 3 setup packets. +static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2]; typedef struct { uint8_t * buffer; @@ -670,17 +669,14 @@ static void read_rx_fifo(uint8_t rhport, USB_OTG_OUTEndpointTypeDef * out_ep) case 0x03: // Out packet done (Interrupt) break; case 0x04: // Setup packet done (Interrupt) - _setup_offs = 2 - ((out_ep[epnum].DOEPTSIZ & USB_OTG_DOEPTSIZ_STUPCNT_Msk) >> USB_OTG_DOEPTSIZ_STUPCNT_Pos); out_ep[epnum].DOEPTSIZ |= (3 << USB_OTG_DOEPTSIZ_STUPCNT_Pos); break; case 0x06: // Setup packet recvd { - uint8_t setup_left = ((out_ep[epnum].DOEPTSIZ & USB_OTG_DOEPTSIZ_STUPCNT_Msk) >> USB_OTG_DOEPTSIZ_STUPCNT_Pos); - // We can receive up to three setup packets in succession, but // only the last one is valid. - _setup_packet[4 - 2*setup_left] = (* rx_fifo); - _setup_packet[5 - 2*setup_left] = (* rx_fifo); + _setup_packet[0] = (* rx_fifo); + _setup_packet[1] = (* rx_fifo); } break; default: // Invalid @@ -699,8 +695,7 @@ static void handle_epout_ints(uint8_t rhport, USB_OTG_DeviceTypeDef * dev, USB_O // SETUP packet Setup Phase done. if(out_ep[n].DOEPINT & USB_OTG_DOEPINT_STUP) { out_ep[n].DOEPINT = USB_OTG_DOEPINT_STUP; - dcd_event_setup_received(rhport, (uint8_t*) &_setup_packet[2*_setup_offs], true); - _setup_offs = 0; + dcd_event_setup_received(rhport, (uint8_t*) &_setup_packet[0], true); } // OUT XFER complete (single packet). @@ -736,7 +731,6 @@ static void handle_epin_ints(uint8_t rhport, USB_OTG_DeviceTypeDef * dev, USB_OT if ( dev->DAINT & (1 << (USB_OTG_DAINT_IEPINT_Pos + n)) ) { - // IN XFER complete (entire xfer). if ( in_ep[n].DIEPINT & USB_OTG_DIEPINT_XFRC ) { -- cgit v1.3.1 From 4399dd1b068ae5ffff4b78848d69a41aa1915045 Mon Sep 17 00:00:00 2001 From: Jan Dümpelmann Date: Fri, 15 May 2020 18:21:44 +0200 Subject: cherry pick PR399 commit : Interrupt time improvements --- src/portable/st/synopsys/dcd_synopsys.c | 133 +++++++++++--------------------- 1 file changed, 46 insertions(+), 87 deletions(-) (limited to 'src') diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index 39d8fe73d..24cfadfe4 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -130,9 +130,7 @@ static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2]; typedef struct { uint8_t * buffer; uint16_t total_len; - uint16_t queued_len; uint16_t max_size; - bool short_packet; } xfer_ctl_t; typedef volatile uint32_t * usb_fifo_t; @@ -437,8 +435,6 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); xfer->buffer = buffer; xfer->total_len = total_bytes; - xfer->queued_len = 0; - xfer->short_packet = false; uint16_t num_packets = (total_bytes / xfer->max_size); uint8_t short_packet_size = total_bytes % xfer->max_size; @@ -461,9 +457,10 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t dev->DIEPEMPMSK |= (1 << epnum); } } else { - // Each complete packet for OUT xfers triggers XFRC. - out_ep[epnum].DOEPTSIZ |= (1 << USB_OTG_DOEPTSIZ_PKTCNT_Pos) | - ((xfer->max_size & USB_OTG_DOEPTSIZ_XFRSIZ_Msk) << USB_OTG_DOEPTSIZ_XFRSIZ_Pos); + // A full OUT transfer (multiple packets, possibly) triggers XFRC. + out_ep[epnum].DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT_Msk | USB_OTG_DOEPTSIZ_XFRSIZ); + out_ep[epnum].DOEPTSIZ |= (num_packets << USB_OTG_DOEPTSIZ_PKTCNT_Pos) | + ((total_bytes << USB_OTG_DOEPTSIZ_XFRSIZ_Pos) & USB_OTG_DOEPTSIZ_XFRSIZ_Msk); out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK; } @@ -558,65 +555,33 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) /*------------------------------------------------------------------*/ -// TODO: Split into "receive on endpoint 0" and "receive generic"; endpoint 0's -// DOEPTSIZ register is smaller than the others, and so is insufficient for -// determining how much of an OUT transfer is actually remaining. -static void receive_packet(uint8_t rhport, xfer_ctl_t * xfer, /* USB_OTG_OUTEndpointTypeDef * out_ep, */ uint16_t xfer_size) { +// Read a single data packet from receive FIFO +static void read_fifo_packet(uint8_t rhport, uint8_t * dst, uint16_t len){ usb_fifo_t rx_fifo = FIFO_BASE(rhport, 0); - // See above TODO - // uint16_t remaining = (out_ep->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ_Msk) >> USB_OTG_DOEPTSIZ_XFRSIZ_Pos; - // xfer->queued_len = xfer->total_len - remaining; - - uint16_t remaining = xfer->total_len - xfer->queued_len; - uint16_t to_recv_size; - - if(remaining <= xfer->max_size) { - // Avoid buffer overflow. - to_recv_size = (xfer_size > remaining) ? remaining : xfer_size; - } else { - // Room for full packet, choose recv_size based on what the microcontroller - // claims. - to_recv_size = (xfer_size > xfer->max_size) ? xfer->max_size : xfer_size; - } - - uint8_t to_recv_rem = to_recv_size % 4; - uint16_t to_recv_size_aligned = to_recv_size - to_recv_rem; - - // Do not assume xfer buffer is aligned. - uint8_t * base = (xfer->buffer + xfer->queued_len); - - // This for loop always runs at least once- skip if less than 4 bytes - // to collect. - if(to_recv_size >= 4) { - for(uint16_t i = 0; i < to_recv_size_aligned; i += 4) { - uint32_t tmp = (* rx_fifo); - base[i] = tmp & 0x000000FF; - base[i + 1] = (tmp & 0x0000FF00) >> 8; - base[i + 2] = (tmp & 0x00FF0000) >> 16; - base[i + 3] = (tmp & 0xFF000000) >> 24; - } + // Reading full available 32 bit words from fifo + uint16_t full_words = len >> 2; + for(uint16_t i = 0; i < full_words; i++) { + uint32_t tmp = *rx_fifo; + dst[0] = tmp & 0x000000FF; + dst[1] = (tmp & 0x0000FF00) >> 8; + dst[2] = (tmp & 0x00FF0000) >> 16; + dst[3] = (tmp & 0xFF000000) >> 24; + dst += 4; } - // Do not read invalid bytes from RX FIFO. - if(to_recv_rem != 0) { - uint32_t tmp = (* rx_fifo); - uint8_t * last_32b_bound = base + to_recv_size_aligned; - - last_32b_bound[0] = tmp & 0x000000FF; - if(to_recv_rem > 1) { - last_32b_bound[1] = (tmp & 0x0000FF00) >> 8; + // Read the remaining 1-3 bytes from fifo + uint8_t bytes_rem = len & 0x03; + if(bytes_rem != 0) { + uint32_t tmp = *rx_fifo; + dst[0] = tmp & 0x000000FF; + if(bytes_rem > 1) { + dst[1] = (tmp & 0x0000FF00) >> 8; } - if(to_recv_rem > 2) { - last_32b_bound[2] = (tmp & 0x00FF0000) >> 16; + if(bytes_rem > 2) { + dst[2] = (tmp & 0x00FF0000) >> 16; } } - - xfer->queued_len += xfer_size; - - // Per USB spec, a short OUT packet (including length 0) is always - // indicative of the end of a transfer (at least for ctl, bulk, int). - xfer->short_packet = (xfer_size < xfer->max_size); } // Write a single data packet to EPIN FIFO @@ -645,13 +610,11 @@ static void write_fifo_packet(uint8_t rhport, uint8_t fifo_num, uint8_t * src, u } } -static void read_rx_fifo(uint8_t rhport, USB_OTG_OUTEndpointTypeDef * out_ep) -{ +static void handle_rxflvl_ints(uint8_t rhport, USB_OTG_OUTEndpointTypeDef * out_ep) { USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); usb_fifo_t rx_fifo = FIFO_BASE(rhport, 0); - // Pop control word off FIFO (completed xfers will have 2 control words, - // we only pop one ctl word each interrupt). + // Pop control word off FIFO uint32_t ctl_word = usb_otg->GRXSTSP; uint8_t pktsts = (ctl_word & USB_OTG_GRXSTSP_PKTSTS_Msk) >> USB_OTG_GRXSTSP_PKTSTS_Pos; uint8_t epnum = (ctl_word & USB_OTG_GRXSTSP_EPNUM_Msk) >> USB_OTG_GRXSTSP_EPNUM_Pos; @@ -663,7 +626,13 @@ static void read_rx_fifo(uint8_t rhport, USB_OTG_OUTEndpointTypeDef * out_ep) case 0x02: // Out packet recvd { xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); - receive_packet(rhport, xfer, bcnt); + + // Use BCNT to calculate correct bytes before data entry popped out from RxFIFO + uint16_t remaining_bytes = ((out_ep[epnum].DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ_Msk) \ + >> USB_OTG_DOEPTSIZ_XFRSIZ_Pos) + bcnt; + + // Read packet off RxFIFO + read_fifo_packet(rhport, (xfer->buffer + xfer->total_len - remaining_bytes), bcnt); } break; case 0x03: // Out packet done (Interrupt) @@ -698,25 +667,10 @@ static void handle_epout_ints(uint8_t rhport, USB_OTG_DeviceTypeDef * dev, USB_O dcd_event_setup_received(rhport, (uint8_t*) &_setup_packet[0], true); } - // OUT XFER complete (single packet). + // OUT XFER complete if(out_ep[n].DOEPINT & USB_OTG_DOEPINT_XFRC) { out_ep[n].DOEPINT = USB_OTG_DOEPINT_XFRC; - - // TODO: Because of endpoint 0's constrained size, we handle XFRC - // on a packet-basis. The core can internally handle multiple OUT - // packets; it would be more efficient to only trigger XFRC on a - // completed transfer for non-0 endpoints. - - // Transfer complete if short packet or total len is transferred - if(xfer->short_packet || (xfer->queued_len == xfer->total_len)) { - xfer->short_packet = false; - dcd_event_xfer_complete(rhport, n, xfer->queued_len, XFER_RESULT_SUCCESS, true); - } else { - // Schedule another packet to be received. - out_ep[n].DOEPTSIZ |= (1 << USB_OTG_DOEPTSIZ_PKTCNT_Pos) | \ - ((xfer->max_size & USB_OTG_DOEPTSIZ_XFRSIZ_Msk) << USB_OTG_DOEPTSIZ_XFRSIZ_Pos); - out_ep[n].DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK; - } + dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); } } } @@ -760,11 +714,8 @@ static void handle_epin_ints(uint8_t rhport, USB_OTG_DeviceTypeDef * dev, USB_OT break; } - // TODO: queued_len can be removed later - xfer->queued_len = xfer->total_len - remaining_bytes; - // Push packet to Tx-FIFO - write_fifo_packet(rhport, n, (xfer->buffer + xfer->queued_len), packet_size); + write_fifo_packet(rhport, n, (xfer->buffer + xfer->total_len - remaining_bytes), packet_size); } // Turn off TXFE if all bytes are written. @@ -835,12 +786,20 @@ void dcd_int_handler(uint8_t rhport) } #endif - if(int_status & USB_OTG_GINTSTS_RXFLVL) { + // Use while loop to handle more than one fifo data entry + // within a single interrupt call + while(usb_otg->GINTSTS & USB_OTG_GINTSTS_RXFLVL) { // RXFLVL bit is read-only // Mask out RXFLVL while reading data from FIFO usb_otg->GINTMSK &= ~USB_OTG_GINTMSK_RXFLVLM; - read_rx_fifo(rhport, out_ep); + + // Loop until all available packets were handled + do { + handle_rxflvl_ints(rhport, out_ep); + int_status = usb_otg->GINTSTS; + } while(int_status & USB_OTG_GINTSTS_RXFLVL); + usb_otg->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM; } -- cgit v1.3.1 From 2dd1be13e5780509cc6ab4e5877dd8c4ffe77e45 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 15 Jun 2020 23:17:49 +0700 Subject: Enhance EP FIFO allocation for both Fullspeed and Highspeed - Update shared RX FIFO calculation with FS/HS - IN FIFO EP - Interrupt -> use EPSize - Bulk/ISO -> use max(EPSize, remaining-fifo / non-opened-EPIN) --- src/portable/st/synopsys/dcd_synopsys.c | 113 +++++++++++++++++++++----------- 1 file changed, 76 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index 24cfadfe4..030c089aa 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -116,7 +116,6 @@ enum DCD_FULL_SPEED = 3, // Full speed with internal PHY }; - /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ @@ -138,6 +137,8 @@ typedef volatile uint32_t * usb_fifo_t; xfer_ctl_t xfer_status[EP_MAX][2]; #define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] +// FIFO RAM allocation so far in words +static uint16_t _allocated_fifo_words; // Setup the control endpoint 0. static void bus_reset(uint8_t rhport) @@ -147,6 +148,8 @@ static void bus_reset(uint8_t rhport) USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); + tu_memclr(xfer_status, sizeof(xfer_status)); + for(uint8_t n = 0; n < EP_MAX; n++) { out_ep[n].DOEPCTL |= USB_OTG_DOEPCTL_SNAK; } @@ -177,17 +180,36 @@ static void bus_reset(uint8_t rhport) // - Each EP IN needs at least max packet size, 16 words is sufficient for EP0 IN // // - All EP OUT shared a unique OUT FIFO which uses - // * 10 locations in hardware for setup packets + setup control words (up to 3 setup packets). - // * 2 locations for OUT endpoint control words. - // * 16 for largest packet size of 64 bytes. ( TODO Highspeed is 512 bytes) - // * 1 location for global NAK (not required/used here). - // * It is recommended to allocate 2 times the largest packet size, therefore - // Recommended value = 10 + 1 + 2 x (16+2) = 47. To make it scale better with large FIFO size - // and work better with Highspeed. We use 1/5 of total FIFO size - usb_otg->GRXFSIZ = (EP_FIFO_SIZE/4)/5; + // - 13 for setup packets + control words (up to 3 setup packets). + // - 1 for global NAK (not required/used here). + // - Largest-EPsize / 4 + 1. ( FS: 64 bytes, HS: 512 bytes). Recommended is "2 x (Largest-EPsize/4) + 1" + // - 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 + // + // 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 + // + // FIXME: 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 + // overwrite this. + +#if TUD_OPT_HIGH_SPEED + _allocated_fifo_words = 271 + 2*EP_MAX; +#else + _allocated_fifo_words = 47 + 2*EP_MAX; +#endif + + usb_otg->GRXFSIZ = _allocated_fifo_words; // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word ) - usb_otg->DIEPTXF0_HNPTXFSIZ = (16 << USB_OTG_TX0FD_Pos) | (usb_otg->GRXFSIZ & 0x0000ffffUL); + usb_otg->DIEPTXF0_HNPTXFSIZ = (16 << USB_OTG_TX0FD_Pos) | _allocated_fifo_words; + + _allocated_fifo_words += 16; + + // TU_LOG2_INT(_allocated_fifo_words); // Fixed control EP0 size to 64 bytes in_ep[0].DIEPCTL &= ~(0x03 << USB_OTG_DIEPCTL_MPSIZ_Pos); @@ -221,7 +243,6 @@ static tusb_speed_t get_speed(USB_OTG_DeviceTypeDef* dev) return (enum_spd == DCD_HIGH_SPEED) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL; } - /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ @@ -242,9 +263,11 @@ void dcd_init (uint8_t rhport) usb_otg->GCCFG &= ~USB_OTG_GCCFG_PWRDWN; // On selected MCUs HS port1 can be used with external PHY via ULPI interface - // Select ULPI highspeed PHY with default external VBUS Indicator and Drive - usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL | - USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI); + // Init ULPI Interface + usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL); + + // Select default internal VBUS Indicator and Drive for ULPI + usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI); set_turnaround(usb_otg, TUSB_SPEED_HIGH); } @@ -303,7 +326,6 @@ void dcd_init (uint8_t rhport) USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_WUIM | USB_OTG_GINTMSK_RXFLVLM | (USE_SOF ? USB_OTG_GINTMSK_SOFM : 0); - // Enable global interrupt usb_otg->GAHBCFG |= USB_OTG_GAHBCFG_GINT; } @@ -397,10 +419,40 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) // | ( Shared ) | // --------------- 0 // - // Since OUT FIFO = GRXFSIZ, FIFO 0 = 16, for simplicity, we equally allocated for the rest of endpoints - // - Size : (FIFO_SIZE/4 - GRXFSIZ - 16) / (EP_MAX-1) - // - Offset: GRXFSIZ + 16 + Size*(epnum-1) + // In FIFO is allocated by following rules: // - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n". + // - Offset: allocated so far + // - Size + // - Interrupt is EPSize + // - Bulk/ISO is max(EPSize, remaining-fifo / non-opened-EPIN) + + uint16_t const fifo_remaining = EP_FIFO_SIZE/4 - _allocated_fifo_words; + uint16_t fifo_size = desc_edpt->wMaxPacketSize.size / 4; + + if ( desc_edpt->bmAttributes.xfer != TUSB_XFER_INTERRUPT ) + { + uint8_t opened = 0; + for(uint8_t i = 0; i < EP_MAX; i++) + { + if ( (i != epnum) && (xfer_status[i][TUSB_DIR_IN].max_size > 0) ) opened++; + } + + // EP Size or equally divided of remaining whichever is larger + fifo_size = tu_max16(fifo_size, fifo_remaining / (EP_MAX - opened)); + } + + + // FIFO overflows, we probably need a better allocating scheme + TU_ASSERT(fifo_size <= fifo_remaining); + + // DIEPTXF starts at FIFO #1. + // Both TXFD and TXSA are in unit of 32-bit words. + usb_otg->DIEPTXF[epnum - 1] = (fifo_size << USB_OTG_DIEPTXF_INEPTXFD_Pos) | _allocated_fifo_words; + + _allocated_fifo_words += fifo_size; + + //TU_LOG2_INT(fifo_size); + //TU_LOG2_INT(_allocated_fifo_words); in_ep[epnum].DIEPCTL |= (1 << USB_OTG_DIEPCTL_USBAEP_Pos) | (epnum << USB_OTG_DIEPCTL_TXFNUM_Pos) | @@ -409,15 +461,6 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) (desc_edpt->wMaxPacketSize.size << USB_OTG_DIEPCTL_MPSIZ_Pos); dev->DAINTMSK |= (1 << (USB_OTG_DAINTMSK_IEPM_Pos + epnum)); - - // Both TXFD and TXSA are in unit of 32-bit words. - // IN FIFO 0 was configured during enumeration, hence the "+ 16". - uint16_t const allocated_size = (usb_otg->GRXFSIZ & 0x0000ffff) + 16; - uint16_t const fifo_size = (EP_FIFO_SIZE/4 - allocated_size) / (EP_MAX-1); - uint32_t const fifo_offset = allocated_size + fifo_size*(epnum-1); - - // DIEPTXF starts at FIFO #1. - usb_otg->DIEPTXF[epnum - 1] = (fifo_size << USB_OTG_DIEPTXF_INEPTXFD_Pos) | fifo_offset; } return true; @@ -433,8 +476,8 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t uint8_t const dir = tu_edpt_dir(ep_addr); xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); - xfer->buffer = buffer; - xfer->total_len = total_bytes; + xfer->buffer = buffer; + xfer->total_len = total_bytes; uint16_t num_packets = (total_bytes / xfer->max_size); uint8_t short_packet_size = total_bytes % xfer->max_size; @@ -533,20 +576,16 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) if(dir == TUSB_DIR_IN) { in_ep[epnum].DIEPCTL &= ~USB_OTG_DIEPCTL_STALL; - uint8_t eptype = (in_ep[epnum].DIEPCTL & USB_OTG_DIEPCTL_EPTYP_Msk) >> \ - USB_OTG_DIEPCTL_EPTYP_Pos; - // Required by USB spec to reset DATA toggle bit to DATA0 on interrupt - // and bulk endpoints. + uint8_t eptype = (in_ep[epnum].DIEPCTL & USB_OTG_DIEPCTL_EPTYP_Msk) >> USB_OTG_DIEPCTL_EPTYP_Pos; + // Required by USB spec to reset DATA toggle bit to DATA0 on interrupt and bulk endpoints. if(eptype == 2 || eptype == 3) { in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM; } } else { out_ep[epnum].DOEPCTL &= ~USB_OTG_DOEPCTL_STALL; - uint8_t eptype = (out_ep[epnum].DOEPCTL & USB_OTG_DOEPCTL_EPTYP_Msk) >> \ - USB_OTG_DOEPCTL_EPTYP_Pos; - // Required by USB spec to reset DATA toggle bit to DATA0 on interrupt - // and bulk endpoints. + uint8_t eptype = (out_ep[epnum].DOEPCTL & USB_OTG_DOEPCTL_EPTYP_Msk) >> USB_OTG_DOEPCTL_EPTYP_Pos; + // Required by USB spec to reset DATA toggle bit to DATA0 on interrupt and bulk endpoints. if(eptype == 2 || eptype == 3) { out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM; } -- cgit v1.3.1 From 667eaa6dd693226d2595e2d19aa3f4798f0a4092 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 16 Jun 2020 00:03:52 +0700 Subject: fix stm32h743 priority with freeRTOS --- hw/bsp/stm32h743eval/stm32h743eval.c | 12 ++++++++---- src/portable/st/synopsys/dcd_synopsys.c | 9 +++++++-- 2 files changed, 15 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/hw/bsp/stm32h743eval/stm32h743eval.c b/hw/bsp/stm32h743eval/stm32h743eval.c index 8bafc32cb..772edf33c 100644 --- a/hw/bsp/stm32h743eval/stm32h743eval.c +++ b/hw/bsp/stm32h743eval/stm32h743eval.c @@ -185,10 +185,14 @@ void board_init(void) SystemClock_Config(); all_rcc_clk_enable(); - #if CFG_TUSB_OS == OPT_OS_NONE - // 1ms tick timer - SysTick_Config(SystemCoreClock / 1000); - #endif + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); + +#if CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(OTG_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + NVIC_SetPriority(OTG_HS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif GPIO_InitTypeDef GPIO_InitStruct; diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index 030c089aa..d636e581c 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -48,36 +48,41 @@ (CFG_TUSB_MCU == OPT_MCU_STM32L4 && defined(STM32L4_SYNOPSYS)) \ ) -// TODO Support OTG_HS // EP_MAX : Max number of bi-directional endpoints including EP0 // EP_FIFO_SIZE : Size of dedicated USB SRAM #if CFG_TUSB_MCU == OPT_MCU_STM32F1 #include "stm32f1xx.h" #define EP_MAX 4 #define EP_FIFO_SIZE 1280 + #elif CFG_TUSB_MCU == OPT_MCU_STM32F2 #include "stm32f2xx.h" #define EP_MAX USB_OTG_FS_MAX_IN_ENDPOINTS #define EP_FIFO_SIZE USB_OTG_FS_TOTAL_FIFO_SIZE + #elif CFG_TUSB_MCU == OPT_MCU_STM32F4 #include "stm32f4xx.h" #define EP_MAX USB_OTG_FS_MAX_IN_ENDPOINTS #define EP_FIFO_SIZE USB_OTG_FS_TOTAL_FIFO_SIZE + #elif CFG_TUSB_MCU == OPT_MCU_STM32H7 #include "stm32h7xx.h" #define EP_MAX 9 #define EP_FIFO_SIZE 4096 - // TODO The official name of the USB FS peripheral on H7 is "USB2_OTG_FS". + #elif CFG_TUSB_MCU == OPT_MCU_STM32F7 #include "stm32f7xx.h" #define EP_MAX 6 #define EP_FIFO_SIZE 1280 + #elif CFG_TUSB_MCU == OPT_MCU_STM32L4 #include "stm32l4xx.h" #define EP_MAX 6 #define EP_FIFO_SIZE 1280 + #else #error "Unsupported MCUs" + #endif #include "device/dcd.h" -- cgit v1.3.1 From 2b1c7730b719c6d4abd7d1bfbfdb80b0d64ee892 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 16 Jun 2020 00:53:06 +0700 Subject: fix hs port1 build with net endpoint --- src/class/net/net_device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/class/net/net_device.h b/src/class/net/net_device.h index 67cd99933..964bc8a00 100644 --- a/src/class/net/net_device.h +++ b/src/class/net/net_device.h @@ -37,7 +37,7 @@ #include "netif/ethernet.h" /* declared here, NOT in usb_descriptors.c, so that the driver can intelligently ZLP as needed */ -#define CFG_TUD_NET_ENDPOINT_SIZE ((CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 512 : 64) +#define CFG_TUD_NET_ENDPOINT_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) /* Maximum Tranmission Unit (in bytes) of the network, including Ethernet header */ #define CFG_TUD_NET_MTU (1500 + SIZEOF_ETH_HDR) -- cgit v1.3.1 From 05bfd9ac4a804f6f8053bdbc8ee83813ad623fa0 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 23 Jun 2020 13:07:33 +0200 Subject: dcd_synopsys: Handle HS and FS IP in one device FIXME: Allow run-time selection to allow to handle both HS and FS with one file F746 HS port enumerates with error config 1 interface 2 altsetting 0 bulk endpoint 0x3 has invalid maxpacket 64 --- src/portable/st/synopsys/dcd_synopsys.c | 44 ++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index 845aecf1e..6e26fd09a 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -53,33 +53,39 @@ // EP_FIFO_SIZE : Size of dedicated USB SRAM #if CFG_TUSB_MCU == OPT_MCU_STM32F1 #include "stm32f1xx.h" - #define EP_MAX 4 - #define EP_FIFO_SIZE 1280 + #define EP_MAX_FS 4 + #define EP_FIFO_SIZE_FS 1280 #elif CFG_TUSB_MCU == OPT_MCU_STM32F2 #include "stm32f2xx.h" - #define EP_MAX USB_OTG_FS_MAX_IN_ENDPOINTS - #define EP_FIFO_SIZE USB_OTG_FS_TOTAL_FIFO_SIZE + #define EP_MAX_FS USB_OTG_FS_MAX_IN_ENDPOINTS + #define EP_FIFO_SIZE_FS USB_OTG_FS_TOTAL_FIFO_SIZE #elif CFG_TUSB_MCU == OPT_MCU_STM32F4 #include "stm32f4xx.h" - #define EP_MAX USB_OTG_FS_MAX_IN_ENDPOINTS - #define EP_FIFO_SIZE USB_OTG_FS_TOTAL_FIFO_SIZE + #define EP_MAX_FS USB_OTG_FS_MAX_IN_ENDPOINTS + #define EP_FIFO_SIZE_FS USB_OTG_FS_TOTAL_FIFO_SIZE + #define EP_MAX_HS USB_OTG_HS_MAX_IN_ENDPOINTS + #define EP_FIFO_SIZE_HS USB_OTG_HS_TOTAL_FIFO_SIZE #elif CFG_TUSB_MCU == OPT_MCU_STM32H7 #include "stm32h7xx.h" - #define EP_MAX 9 - #define EP_FIFO_SIZE 4096 + #define EP_MAX_FS 9 + #define EP_FIFO_SIZE_FS 4096 + #define EP_MAX_HS 9 + #define EP_FIFO_SIZE_HS 4096 #elif CFG_TUSB_MCU == OPT_MCU_STM32F7 #include "stm32f7xx.h" - #define EP_MAX 6 - #define EP_FIFO_SIZE 1280 + #define EP_MAX_FS 6 + #define EP_FIFO_SIZE_FS 1280 + #define EP_MAX_HS 9 + #define EP_FIFO_SIZE_HS 4096 #elif CFG_TUSB_MCU == OPT_MCU_STM32L4 #include "stm32l4xx.h" - #define EP_MAX 6 - #define EP_FIFO_SIZE 1280 + #define EP_MAX_FS 6 + #define EP_FIFO_SIZE_FS 1280 #else #error "Unsupported MCUs" @@ -140,7 +146,15 @@ typedef struct { typedef volatile uint32_t * usb_fifo_t; -xfer_ctl_t xfer_status[EP_MAX][2]; +#if TUD_OPT_RHPORT == 1 +xfer_ctl_t xfer_status[EP_MAX_HS][2]; +# define EP_MAX EP_MAX_HS +# define EP_FIFO_SIZE EP_FIFO_SIZE_HS +#else +xfer_ctl_t xfer_status[EP_MAX_FS][2]; +# define EP_MAX EP_MAX_FS +# define EP_FIFO_SIZE EP_FIFO_SIZE_FS +#endif #define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] // EP0 transfers are limited to 1 packet - larger sizes has to be split @@ -206,9 +220,9 @@ static void bus_reset(uint8_t rhport) // overwrite this. #if TUD_OPT_HIGH_SPEED - _allocated_fifo_words = 271 + 2*EP_MAX; + _allocated_fifo_words = 271 + 2*EP_MAX_HS; #else - _allocated_fifo_words = 47 + 2*EP_MAX; + _allocated_fifo_words = 47 + 2*EP_MAX_FS; #endif usb_otg->GRXFSIZ = _allocated_fifo_words; -- cgit v1.3.1 From 30a18e260562194b0541584600a0cfc88b1ef178 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 24 Jun 2020 16:25:23 +0200 Subject: stm32f723disco: USB HS enumerates. --- hw/bsp/stm32f723disco/stm32f723disco.c | 6 ++- src/portable/st/synopsys/dcd_synopsys.c | 87 ++++++++++++++++++++++++++++++--- 2 files changed, 85 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/hw/bsp/stm32f723disco/stm32f723disco.c b/hw/bsp/stm32f723disco/stm32f723disco.c index 03057edc7..eeedd2a66 100644 --- a/hw/bsp/stm32f723disco/stm32f723disco.c +++ b/hw/bsp/stm32f723disco/stm32f723disco.c @@ -217,7 +217,7 @@ void board_init(void) 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_VERY_HIGH; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); @@ -231,8 +231,12 @@ void board_init(void) GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); + /* Enable PHYC Clocks */ + __HAL_RCC_OTGPHYC_CLK_ENABLE(); + /* Enable USB HS Clocks */ __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); + __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE(); // Enable VBUS sense (B device) via pin PA9 USB_OTG_HS->GCCFG &= ~USB_OTG_GCCFG_VBDEN; diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index 6e26fd09a..ba3cc3460 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -27,6 +27,7 @@ */ #include "tusb_option.h" +#include "../../../../hw/bsp//board.h" #if defined (STM32F105x8) || defined (STM32F105xB) || defined (STM32F105xC) || \ defined (STM32F107xB) || defined (STM32F107xC) @@ -147,14 +148,13 @@ typedef struct { typedef volatile uint32_t * usb_fifo_t; #if TUD_OPT_RHPORT == 1 -xfer_ctl_t xfer_status[EP_MAX_HS][2]; # define EP_MAX EP_MAX_HS # define EP_FIFO_SIZE EP_FIFO_SIZE_HS #else -xfer_ctl_t xfer_status[EP_MAX_FS][2]; # define EP_MAX EP_MAX_FS # define EP_FIFO_SIZE EP_FIFO_SIZE_FS #endif +xfer_ctl_t xfer_status[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 @@ -220,9 +220,9 @@ static void bus_reset(uint8_t rhport) // overwrite this. #if TUD_OPT_HIGH_SPEED - _allocated_fifo_words = 271 + 2*EP_MAX_HS; + _allocated_fifo_words = 271 + 2*EP_MAX; #else - _allocated_fifo_words = 47 + 2*EP_MAX_FS; + _allocated_fifo_words = 47 + 2*EP_MAX; #endif usb_otg->GRXFSIZ = _allocated_fifo_words; @@ -301,6 +301,59 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c } +# if defined(USB_HS_PHYC) && TUD_OPT_HIGH_SPEED +static bool USB_HS_PHYCInit(void) +{ + USB_HS_PHYC_GlobalTypeDef *usb_hs_phyc = (USB_HS_PHYC_GlobalTypeDef *)USB_HS_PHYC_CONTROLLER_BASE; + // Enable LDO + usb_hs_phyc->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE; + int32_t count = 2000000; + while(1) { + if (usb_hs_phyc->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) + break; + TU_ASSERT(count > 0); + } + uint32_t phyc_pll = 0; + switch (HSE_VALUE) { + case 12000000: + phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12MHZ; + break; + case 12500000: + phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12_5MHZ; + break; + case 16000000: + phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_16MHZ; + break; + case 24000000: + phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_24MHZ; + break; + case 25000000: + phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_25MHZ; + break; + case 32000000: + // Value not defined in header + phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_Msk; + break; + default: + TU_ASSERT(0); + } + usb_hs_phyc->USB_HS_PHYC_PLL = phyc_pll; + + // Use magic value as in stm32f7xx_ll_usb. +# if !defined (USB_HS_PHYC_TUNE_VALUE) +# define USB_HS_PHYC_TUNE_VALUE 0x00000F13U /*!< Value of USB HS PHY Tune */ +# endif /* USB_HS_PHYC_TUNE_VALUE */ + // Control the tuning interface of the High Speed PHY */ + usb_hs_phyc->USB_HS_PHYC_TUNE |= USB_HS_PHYC_TUNE_VALUE; + + // Enable PLL internal PHY + usb_hs_phyc->USB_HS_PHYC_PLL = phyc_pll | USB_HS_PHYC_PLL_PLLEN; + + board_delay(2); + return true; +} +# endif + /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ @@ -315,12 +368,31 @@ void dcd_init (uint8_t rhport) #if TUD_OPT_HIGH_SPEED // TODO may pass parameter instead of using macro for HighSpeed if ( rhport == 1 ) { - // Highspeed with external ULPI PHY - // deactivate internal PHY usb_otg->GCCFG &= ~USB_OTG_GCCFG_PWRDWN; - // On selected MCUs HS port1 can be used with external PHY via ULPI interface + // TODO may pass parameter instead of using macro for HighSpeed +#if defined(USB_HS_PHYC) + // Highspeed with embedded UTMI PHYC + // Init The UTMI Interface + usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL); + + // Select vbus source + usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI); + + // Select UTMI Interace + usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_ULPI_UTMI_SEL; + usb_otg->GCCFG |= USB_OTG_GCCFG_PHYHSEN; + + //Enables control of a High Speed USB PHY + USB_HS_PHYCInit(); + + // Disable external VBUS detection + usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_ULPIEVBUSD; + +# else// On selected MCUs HS port1 can be used with external PHY via ULPI interface + // Highspeed with external ULPI PHY + // Init ULPI Interface usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL); @@ -328,6 +400,7 @@ void dcd_init (uint8_t rhport) usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI); set_turnaround(usb_otg, TUSB_SPEED_HIGH); +# endif } else #endif -- cgit v1.3.1 From ed1b670c55053c1fdb6b5ec0c543fe81d95989e4 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 1 Jul 2020 17:57:37 +0700 Subject: clean up code --- src/portable/st/synopsys/dcd_synopsys.c | 48 +++++++++++++-------------------- 1 file changed, 19 insertions(+), 29 deletions(-) (limited to 'src') diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index ba3cc3460..f6d064228 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -243,7 +243,7 @@ static void bus_reset(uint8_t rhport) usb_otg->GINTMSK |= USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT; } -// speed is native DCD speed +// Set turn-around timeout according to link speed static void set_turnaround(USB_OTG_GlobalTypeDef * usb_otg, tusb_speed_t speed) { usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT; @@ -368,47 +368,40 @@ void dcd_init (uint8_t rhport) #if TUD_OPT_HIGH_SPEED // TODO may pass parameter instead of using macro for HighSpeed if ( rhport == 1 ) { + // On selected MCUs HS port1 can be used with external PHY via ULPI interface + // deactivate internal PHY usb_otg->GCCFG &= ~USB_OTG_GCCFG_PWRDWN; - // TODO may pass parameter instead of using macro for HighSpeed -#if defined(USB_HS_PHYC) - // Highspeed with embedded UTMI PHYC // Init The UTMI Interface usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL); - // Select vbus source + // Select default internal VBUS Indicator and Drive for ULPI usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI); - // Select UTMI Interace +#if defined(USB_HS_PHYC) + // Highspeed with embedded UTMI PHYC + + // Select UTMI Interface usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_ULPI_UTMI_SEL; usb_otg->GCCFG |= USB_OTG_GCCFG_PHYHSEN; - //Enables control of a High Speed USB PHY + // Enables control of a High Speed USB PHY USB_HS_PHYCInit(); // Disable external VBUS detection usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_ULPIEVBUSD; +#endif -# else// On selected MCUs HS port1 can be used with external PHY via ULPI interface // Highspeed with external ULPI PHY - - // Init ULPI Interface - usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL); - - // Select default internal VBUS Indicator and Drive for ULPI - usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI); - set_turnaround(usb_otg, TUSB_SPEED_HIGH); -# endif - } - else + } else #endif { - set_turnaround(usb_otg, TUSB_SPEED_FULL); - // Enable internal PHY usb_otg->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL; + + set_turnaround(usb_otg, TUSB_SPEED_FULL); } // Reset core after selecting PHY @@ -434,20 +427,17 @@ void dcd_init (uint8_t rhport) // (non zero-length packet), send STALL back and discard. dev->DCFG |= USB_OTG_DCFG_NZLSOHSK; -#if TUD_OPT_HIGH_SPEED + // Clear speed bits + dev->DCFG &= ~(3 << USB_OTG_DCFG_DSPD_Pos); + if ( rhport == 1 ) { - // high speed = 0x00 - dev->DCFG &= ~(3 << USB_OTG_DCFG_DSPD_Pos); - - // Transceiver delay, necessary for some ULPI PHYs - //dev->DCFG |= (1 << 14); + if ( !TUD_OPT_HIGH_SPEED ) dev->DCFG |= ((TUD_OPT_HIGH_SPEED ? DCD_HIGH_SPEED : DCD_FULL_SPEED_USE_HS) << USB_OTG_DCFG_DSPD_Pos); } else -#endif { - // full speed with internal PHY - dev->DCFG |= (3 << USB_OTG_DCFG_DSPD_Pos); + // full speed = 0x03 + dev->DCFG |= (DCD_FULL_SPEED << USB_OTG_DCFG_DSPD_Pos); // Enable internal USB transceiver. usb_otg->GCCFG |= USB_OTG_GCCFG_PWRDWN; -- cgit v1.3.1 From e3974d6869fb091609ccffc342031dc779a37f7e Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 1 Jul 2020 18:44:52 +0700 Subject: correctly set turn around according to cpu clock help to run with low speed mcu --- src/portable/st/synopsys/dcd_synopsys.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index 7ba6b2378..ee8cab5c4 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -255,8 +255,33 @@ static void set_turnaround(USB_OTG_GlobalTypeDef * usb_otg, tusb_speed_t speed) } else { + // Turnaround timeout depends on the MCU clock + extern uint32_t SystemCoreClock; + 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 - usb_otg->GUSBCFG |= (0x06 << USB_OTG_GUSBCFG_TRDT_Pos); + usb_otg->GUSBCFG |= (turnaround << USB_OTG_GUSBCFG_TRDT_Pos); } } -- cgit v1.3.1 From d2450abaafee659cd30ba2fbd14ff9bdb06f6725 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 1 Jul 2020 18:49:58 +0700 Subject: only set turnaround in reset complete --- src/portable/st/synopsys/dcd_synopsys.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'src') diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index ee8cab5c4..2adaa762e 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -417,16 +417,11 @@ void dcd_init (uint8_t rhport) // Disable external VBUS detection usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_ULPIEVBUSD; #endif - - // Highspeed with external ULPI PHY - set_turnaround(usb_otg, TUSB_SPEED_HIGH); } else #endif { // Enable internal PHY usb_otg->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL; - - set_turnaround(usb_otg, TUSB_SPEED_FULL); } // Reset core after selecting PHY @@ -457,7 +452,7 @@ void dcd_init (uint8_t rhport) if ( rhport == 1 ) { - if ( !TUD_OPT_HIGH_SPEED ) dev->DCFG |= ((TUD_OPT_HIGH_SPEED ? DCD_HIGH_SPEED : DCD_FULL_SPEED_USE_HS) << USB_OTG_DCFG_DSPD_Pos); + dev->DCFG |= ((TUD_OPT_HIGH_SPEED ? DCD_HIGH_SPEED : DCD_FULL_SPEED_USE_HS) << USB_OTG_DCFG_DSPD_Pos); } else { -- cgit v1.3.1 From 196bdbc7024fcfd3f94e4609cee6580df5bab70b Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 1 Jul 2020 14:45:07 +0200 Subject: st/synopsys/dcd_synopsys.c: Remove USBC PHY PLL stabilization delay for now While the ST code has a 2 ms stabilization delay for the USBC PHY PLL, running without this delay showed no problem for at leat 10 USB un/replug cycles. Observe for problems! --- src/portable/st/synopsys/dcd_synopsys.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index ba3cc3460..4a372348a 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -27,7 +27,6 @@ */ #include "tusb_option.h" -#include "../../../../hw/bsp//board.h" #if defined (STM32F105x8) || defined (STM32F105xB) || defined (STM32F105xC) || \ defined (STM32F107xB) || defined (STM32F107xC) @@ -349,7 +348,12 @@ static bool USB_HS_PHYCInit(void) // Enable PLL internal PHY usb_hs_phyc->USB_HS_PHYC_PLL = phyc_pll | USB_HS_PHYC_PLL_PLLEN; - board_delay(2); + /* Original ST code has 2 ms delay for PLL stabilization. + * Primitive test shows that more than 10 USB un/replug cycle + * showed no error with enumeration + * //#include "../../../../hw/bsp//board.h" + * //board_delay(2); + */ return true; } # endif -- cgit v1.3.1 From 4966fb2e13ca2629763e76d82b67e531c3e20ede Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 Jul 2020 01:22:26 +0700 Subject: clean up --- src/portable/st/synopsys/dcd_synopsys.c | 99 +++++++++++++-------------------- 1 file changed, 39 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index d5e36a97a..03238f8e2 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -147,12 +147,13 @@ typedef struct { typedef volatile uint32_t * usb_fifo_t; #if TUD_OPT_RHPORT == 1 -# define EP_MAX EP_MAX_HS -# define EP_FIFO_SIZE EP_FIFO_SIZE_HS + #define EP_MAX EP_MAX_HS + #define EP_FIFO_SIZE EP_FIFO_SIZE_HS #else -# define EP_MAX EP_MAX_FS -# define EP_FIFO_SIZE EP_FIFO_SIZE_FS + #define EP_MAX EP_MAX_FS + #define EP_FIFO_SIZE EP_FIFO_SIZE_FS #endif + xfer_ctl_t xfer_status[EP_MAX][2]; #define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] @@ -325,63 +326,44 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c } -# if defined(USB_HS_PHYC) && TUD_OPT_HIGH_SPEED +#if defined(USB_HS_PHYC) && TUD_OPT_HIGH_SPEED static bool USB_HS_PHYCInit(void) { - USB_HS_PHYC_GlobalTypeDef *usb_hs_phyc = (USB_HS_PHYC_GlobalTypeDef *)USB_HS_PHYC_CONTROLLER_BASE; - // Enable LDO - usb_hs_phyc->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE; - int32_t count = 2000000; - while(1) { - if (usb_hs_phyc->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) - break; - TU_ASSERT(count > 0); - } - uint32_t phyc_pll = 0; - switch (HSE_VALUE) { - case 12000000: - phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12MHZ; - break; - case 12500000: - phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12_5MHZ; - break; - case 16000000: - phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_16MHZ; - break; - case 24000000: - phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_24MHZ; - break; - case 25000000: - phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_25MHZ; - break; - case 32000000: - // Value not defined in header - phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_Msk; - break; + USB_HS_PHYC_GlobalTypeDef *usb_hs_phyc = (USB_HS_PHYC_GlobalTypeDef*) USB_HS_PHYC_CONTROLLER_BASE; + + // Enable LDO + usb_hs_phyc->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE; + + // Wait until LDO ready + while ( 0 == (usb_hs_phyc->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) ) {} + + uint32_t phyc_pll = 0; + switch ( HSE_VALUE ) + { + case 12000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12MHZ ; break; + case 12500000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12_5MHZ ; break; + case 16000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_16MHZ ; break; + case 24000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_24MHZ ; break; + case 25000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_25MHZ ; break; + case 32000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_Msk ; break; // Value not defined in header default: - TU_ASSERT(0); - } - usb_hs_phyc->USB_HS_PHYC_PLL = phyc_pll; - - // Use magic value as in stm32f7xx_ll_usb. -# if !defined (USB_HS_PHYC_TUNE_VALUE) -# define USB_HS_PHYC_TUNE_VALUE 0x00000F13U /*!< Value of USB HS PHY Tune */ -# endif /* USB_HS_PHYC_TUNE_VALUE */ - // Control the tuning interface of the High Speed PHY */ - usb_hs_phyc->USB_HS_PHYC_TUNE |= USB_HS_PHYC_TUNE_VALUE; - - // Enable PLL internal PHY - usb_hs_phyc->USB_HS_PHYC_PLL = phyc_pll | USB_HS_PHYC_PLL_PLLEN; - - /* Original ST code has 2 ms delay for PLL stabilization. - * Primitive test shows that more than 10 USB un/replug cycle - * showed no error with enumeration - * //#include "../../../../hw/bsp//board.h" - * //board_delay(2); - */ - return true; + TU_ASSERT(0); + } + usb_hs_phyc->USB_HS_PHYC_PLL = phyc_pll; + + // Control the tuning interface of the High Speed PHY + // Use magic value from ST driver + usb_hs_phyc->USB_HS_PHYC_TUNE |= 0x00000F13U; + + // Enable PLL internal PHY + usb_hs_phyc->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN; + + // Original ST code has 2 ms delay for PLL stabilization. + // Primitive test shows that more than 10 USB un/replug cycle showed no error with enumeration + + return true; } -# endif +#endif /*------------------------------------------------------------------*/ /* Controller API @@ -417,9 +399,6 @@ void dcd_init (uint8_t rhport) // Enables control of a High Speed USB PHY USB_HS_PHYCInit(); - - // Disable external VBUS detection - usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_ULPIEVBUSD; #endif } else #endif -- cgit v1.3.1 From 9a290febcdd7aaa50657f3d31da31bd493fa3a0e Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 Jul 2020 11:58:40 +0700 Subject: change default port some stm bsp - f769disco default port is highspeed port1 - remove PORT0 on stlink since the board only populated HS connector --- hw/bsp/stlinkv3mini/board.mk | 12 ++----- hw/bsp/stm32f723disco/board.mk | 9 ++--- hw/bsp/stm32h743eval/board.mk | 13 ++++++-- src/portable/st/synopsys/dcd_synopsys.c | 58 ++++++++++++++++++--------------- 4 files changed, 49 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/hw/bsp/stlinkv3mini/board.mk b/hw/bsp/stlinkv3mini/board.mk index 8576eeaa8..1a64c3735 100644 --- a/hw/bsp/stlinkv3mini/board.mk +++ b/hw/bsp/stlinkv3mini/board.mk @@ -1,5 +1,3 @@ -PORT ?= 1 - CFLAGS += \ -flto \ -mthumb \ @@ -11,14 +9,8 @@ CFLAGS += \ -DSTM32F723xx \ -DHSE_VALUE=25000000 \ -DCFG_TUSB_MCU=OPT_MCU_STM32F7 \ - -DBOARD_DEVICE_RHPORT_NUM=$(PORT) - -ifeq ($(PORT), 1) -CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED -$(info "PORT1 HS") -else -$(info "PORT0") -endif + -DBOARD_DEVICE_RHPORT_NUM=1 \ + -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED # mcu driver cause following warnings CFLAGS += -Wno-error=shadow -Wno-error=cast-align diff --git a/hw/bsp/stm32f723disco/board.mk b/hw/bsp/stm32f723disco/board.mk index 2bd3b0756..2cf3ac633 100644 --- a/hw/bsp/stm32f723disco/board.mk +++ b/hw/bsp/stm32f723disco/board.mk @@ -1,4 +1,5 @@ -PORT ?= 0 +# Default is Highspeed port +PORT ?= 1 CFLAGS += \ -flto \ @@ -14,10 +15,10 @@ CFLAGS += \ -DBOARD_DEVICE_RHPORT_NUM=$(PORT) ifeq ($(PORT), 1) -CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED -$(info "PORT1 HS") + CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED + $(info "PORT1 High Speed") else -$(info "PORT0") + $(info "PORT0 Full Speed") endif # mcu driver cause following warnings diff --git a/hw/bsp/stm32h743eval/board.mk b/hw/bsp/stm32h743eval/board.mk index cbf37a95d..47d592c58 100644 --- a/hw/bsp/stm32h743eval/board.mk +++ b/hw/bsp/stm32h743eval/board.mk @@ -1,3 +1,6 @@ +# Default is Highspeed port +PORT ?= 1 + CFLAGS += \ -flto \ -mthumb \ @@ -8,8 +11,14 @@ CFLAGS += \ -nostdlib -nostartfiles \ -DSTM32H743xx \ -DCFG_TUSB_MCU=OPT_MCU_STM32H7 \ - -DBOARD_DEVICE_RHPORT_NUM=1 \ - -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED + -DBOARD_DEVICE_RHPORT_NUM=$(PORT) + +ifeq ($(PORT), 1) + CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED + $(info "PORT1 High Speed") +else + $(info "PORT0 Full Speed") +endif # suppress warning caused by vendor mcu driver CFLAGS += -Wno-error=maybe-uninitialized -Wno-error=cast-align diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index 03238f8e2..a2d1983c2 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -390,7 +390,7 @@ void dcd_init (uint8_t rhport) // Select default internal VBUS Indicator and Drive for ULPI usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI); -#if defined(USB_HS_PHYC) + #if defined(USB_HS_PHYC) // Highspeed with embedded UTMI PHYC // Select UTMI Interface @@ -399,8 +399,9 @@ void dcd_init (uint8_t rhport) // Enables control of a High Speed USB PHY USB_HS_PHYCInit(); -#endif - } else + #endif + } + else #endif { // Enable internal PHY @@ -770,43 +771,46 @@ static void handle_rxflvl_ints(uint8_t rhport, USB_OTG_OUTEndpointTypeDef * out_ switch(pktsts) { case 0x01: // Global OUT NAK (Interrupt) - break; + break; + case 0x02: // Out packet recvd - { - xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); + { + xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); - // Read packet off RxFIFO - read_fifo_packet(rhport, xfer->buffer, bcnt); + // Read packet off RxFIFO + read_fifo_packet(rhport, xfer->buffer, bcnt); - // Increment pointer to xfer data - xfer->buffer += bcnt; + // Increment pointer to xfer data + xfer->buffer += bcnt; - // Truncate transfer length in case of short packet - if(bcnt < xfer->max_size) { - xfer->total_len -= (out_ep[epnum].DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ_Msk) >> USB_OTG_DOEPTSIZ_XFRSIZ_Pos; - if(epnum == 0) { - xfer->total_len -= ep0_pending[TUSB_DIR_OUT]; - ep0_pending[TUSB_DIR_OUT] = 0; - } + // Truncate transfer length in case of short packet + if(bcnt < xfer->max_size) { + xfer->total_len -= (out_ep[epnum].DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ_Msk) >> USB_OTG_DOEPTSIZ_XFRSIZ_Pos; + if(epnum == 0) { + xfer->total_len -= ep0_pending[TUSB_DIR_OUT]; + ep0_pending[TUSB_DIR_OUT] = 0; } } - break; + } + break; + case 0x03: // Out packet done (Interrupt) break; + case 0x04: // Setup packet done (Interrupt) out_ep[epnum].DOEPTSIZ |= (3 << USB_OTG_DOEPTSIZ_STUPCNT_Pos); - break; + break; + case 0x06: // Setup packet recvd - { - // We can receive up to three setup packets in succession, but - // only the last one is valid. - _setup_packet[0] = (* rx_fifo); - _setup_packet[1] = (* rx_fifo); - } - break; + // We can receive up to three setup packets in succession, but + // only the last one is valid. + _setup_packet[0] = (* rx_fifo); + _setup_packet[1] = (* rx_fifo); + break; + default: // Invalid TU_BREAKPOINT(); - break; + break; } } -- cgit v1.3.1 From 4cec866994f32f729844d0159e14c178f5aa904f Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 Jul 2020 14:57:00 +0700 Subject: correct HSE_VALUE in hal_conf - although it is define in CFLAGS, it is worth to correct to be consistent with other build - extract set_speed() --- README.md | 2 +- docs/boards.md | 5 ++ hw/bsp/stlinkv3mini/stm32f7xx_hal_conf.h | 2 +- hw/bsp/stm32f723disco/stm32f7xx_hal_conf.h | 2 +- hw/bsp/stm32f769disco/stm32f7xx_hal_conf.h | 2 +- src/portable/st/synopsys/dcd_synopsys.c | 106 ++++++++++++++++------------- 6 files changed, 66 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/README.md b/README.md index f9a7d0b73..8246ff460 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ The stack supports the following MCUs: - LPC Series: 11Uxx, 13xx, 175x_6x, 177x_8x, 18xx, 40xx, 43xx, 51Uxx, 54xxx, 55xx - iMX RT Series: RT1011, RT1015, RT1021, RT1052, RT1062, RT1064 - **Sony:** CXD56 -- **ST:** STM32 series: L0, F0, F1, F2, F3, F4, F7, H7 (device only) +- **ST:** STM32 series: L0, F0, F1, F2, F3, F4, F7, H7 both FullSpeed and HighSpeed - **TI:** MSP430 - **[ValentyUSB](https://github.com/im-tomu/valentyusb)** eptri diff --git a/docs/boards.md b/docs/boards.md index 57b1410bc..d3dcec375 100644 --- a/docs/boards.md +++ b/docs/boards.md @@ -85,6 +85,7 @@ This code base already had supported for a handful of following boards (sorted a - [Adafruit Feather STM32F405](https://www.adafruit.com/product/4382) - [Micro Python PyBoard v1.1](https://store.micropython.org/product/PYBv1.1) +- [STLink-V3 Mini](https://www.st.com/en/development-tools/stlink-v3mini.html) - [STM32 L035c8 Discovery](https://www.st.com/en/evaluation-tools/32l0538discovery.html) - [STM32 F070rb Nucleo](https://www.st.com/en/evaluation-tools/nucleo-f070rb.html) - [STM32 F072rb Discovery](https://www.st.com/en/evaluation-tools/32f072bdiscovery.html) @@ -96,9 +97,13 @@ This code base already had supported for a handful of following boards (sorted a - STM32 F411ce Black Pill - [STM32 F411ve Discovery](https://www.st.com/en/evaluation-tools/32f411ediscovery.html) - [STM32 F412zg Discovery](https://www.st.com/en/evaluation-tools/32f412gdiscovery.html) +- [STM32 F723e Discovery](https://www.st.com/en/evaluation-tools/32f723ediscovery.html) - [STM32 F746zg Nucleo](https://www.st.com/en/evaluation-tools/nucleo-f746zg.html) +- [STM32 F746g Discovery](https://www.st.com/en/evaluation-tools/32f746gdiscovery.html) - [STM32 F767zi Nucleo](https://www.st.com/en/evaluation-tools/nucleo-f767zi.html) +- [STM32 F769i Discovery](https://www.st.com/en/evaluation-tools/32f769idiscovery.html) - [STM32 H743zi Nucleo](https://www.st.com/en/evaluation-tools/nucleo-h743zi.html) +- [STM32 H743i Evaluation](https://www.st.com/en/evaluation-tools/stm32h743i-eval.html) ### TI diff --git a/hw/bsp/stlinkv3mini/stm32f7xx_hal_conf.h b/hw/bsp/stlinkv3mini/stm32f7xx_hal_conf.h index 03dec8f0d..581f0e46a 100644 --- a/hw/bsp/stlinkv3mini/stm32f7xx_hal_conf.h +++ b/hw/bsp/stlinkv3mini/stm32f7xx_hal_conf.h @@ -87,7 +87,7 @@ * (when HSE is used as system clock source, directly or through the PLL). */ #if !defined (HSE_VALUE) - #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */ + #define HSE_VALUE ((uint32_t)25000000U) /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (HSE_STARTUP_TIMEOUT) diff --git a/hw/bsp/stm32f723disco/stm32f7xx_hal_conf.h b/hw/bsp/stm32f723disco/stm32f7xx_hal_conf.h index 03dec8f0d..581f0e46a 100644 --- a/hw/bsp/stm32f723disco/stm32f7xx_hal_conf.h +++ b/hw/bsp/stm32f723disco/stm32f7xx_hal_conf.h @@ -87,7 +87,7 @@ * (when HSE is used as system clock source, directly or through the PLL). */ #if !defined (HSE_VALUE) - #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */ + #define HSE_VALUE ((uint32_t)25000000U) /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (HSE_STARTUP_TIMEOUT) diff --git a/hw/bsp/stm32f769disco/stm32f7xx_hal_conf.h b/hw/bsp/stm32f769disco/stm32f7xx_hal_conf.h index 03dec8f0d..581f0e46a 100644 --- a/hw/bsp/stm32f769disco/stm32f7xx_hal_conf.h +++ b/hw/bsp/stm32f769disco/stm32f7xx_hal_conf.h @@ -87,7 +87,7 @@ * (when HSE is used as system clock source, directly or through the PLL). */ #if !defined (HSE_VALUE) - #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */ + #define HSE_VALUE ((uint32_t)25000000U) /*!< Value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (HSE_STARTUP_TIMEOUT) diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index a2d1983c2..50984c830 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -285,47 +285,33 @@ static void set_turnaround(USB_OTG_GlobalTypeDef * usb_otg, tusb_speed_t speed) } } -static tusb_speed_t get_speed(USB_OTG_DeviceTypeDef* dev) +static tusb_speed_t get_speed(uint8_t rhport) { + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); uint32_t const enum_spd = (dev->DSTS & USB_OTG_DSTS_ENUMSPD_Msk) >> USB_OTG_DSTS_ENUMSPD_Pos; return (enum_spd == DCD_HIGH_SPEED) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL; } -static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t const dir, uint16_t const num_packets, uint16_t total_bytes) { - USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); - USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); +static void set_speed(uint8_t rhport, tusb_speed_t speed) +{ + uint32_t bitvalue; - // EP0 is limited to one packet each xfer - // We use multiple transaction of xfer->max_size length to get a whole transfer done - if(epnum == 0) { - xfer_ctl_t * const xfer = XFER_CTL_BASE(epnum, dir); - total_bytes = tu_min16(ep0_pending[dir], xfer->max_size); - ep0_pending[dir] -= total_bytes; + if ( rhport == 1 ) + { + bitvalue = ((TUSB_SPEED_HIGH == speed) ? DCD_HIGH_SPEED : DCD_FULL_SPEED_USE_HS); + } + else + { + bitvalue = DCD_FULL_SPEED; } - // IN and OUT endpoint xfers are interrupt-driven, we just schedule them here. - if(dir == TUSB_DIR_IN) { - // A full IN transfer (multiple packets, possibly) triggers XFRC. - in_ep[epnum].DIEPTSIZ = (num_packets << USB_OTG_DIEPTSIZ_PKTCNT_Pos) | - ((total_bytes << USB_OTG_DIEPTSIZ_XFRSIZ_Pos) & USB_OTG_DIEPTSIZ_XFRSIZ_Msk); - - in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK; - // Enable fifo empty interrupt only if there are something to put in the fifo. - if(total_bytes != 0) { - dev->DIEPEMPMSK |= (1 << epnum); - } - } else { - // A full OUT transfer (multiple packets, possibly) triggers XFRC. - out_ep[epnum].DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT_Msk | USB_OTG_DOEPTSIZ_XFRSIZ); - out_ep[epnum].DOEPTSIZ |= (num_packets << USB_OTG_DOEPTSIZ_PKTCNT_Pos) | - ((total_bytes << USB_OTG_DOEPTSIZ_XFRSIZ_Pos) & USB_OTG_DOEPTSIZ_XFRSIZ_Msk); + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); - out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK; - } + // Clear and set speed bits + dev->DCFG &= ~(3 << USB_OTG_DCFG_DSPD_Pos); + dev->DCFG |= (bitvalue << USB_OTG_DCFG_DSPD_Pos); } - #if defined(USB_HS_PHYC) && TUD_OPT_HIGH_SPEED static bool USB_HS_PHYCInit(void) { @@ -338,6 +324,8 @@ static bool USB_HS_PHYCInit(void) while ( 0 == (usb_hs_phyc->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) ) {} uint32_t phyc_pll = 0; + + // TODO Try to get HSE_VALUE from registers instead of depending CFLAGS switch ( HSE_VALUE ) { case 12000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12MHZ ; break; @@ -365,6 +353,40 @@ static bool USB_HS_PHYCInit(void) } #endif +static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t const dir, uint16_t const num_packets, uint16_t total_bytes) { + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); + USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); + USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); + + // EP0 is limited to one packet each xfer + // We use multiple transaction of xfer->max_size length to get a whole transfer done + if(epnum == 0) { + xfer_ctl_t * const xfer = XFER_CTL_BASE(epnum, dir); + total_bytes = tu_min16(ep0_pending[dir], xfer->max_size); + ep0_pending[dir] -= total_bytes; + } + + // IN and OUT endpoint xfers are interrupt-driven, we just schedule them here. + if(dir == TUSB_DIR_IN) { + // A full IN transfer (multiple packets, possibly) triggers XFRC. + in_ep[epnum].DIEPTSIZ = (num_packets << USB_OTG_DIEPTSIZ_PKTCNT_Pos) | + ((total_bytes << USB_OTG_DIEPTSIZ_XFRSIZ_Pos) & USB_OTG_DIEPTSIZ_XFRSIZ_Msk); + + in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK; + // Enable fifo empty interrupt only if there are something to put in the fifo. + if(total_bytes != 0) { + dev->DIEPEMPMSK |= (1 << epnum); + } + } else { + // A full OUT transfer (multiple packets, possibly) triggers XFRC. + out_ep[epnum].DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT_Msk | USB_OTG_DOEPTSIZ_XFRSIZ); + out_ep[epnum].DOEPTSIZ |= (num_packets << USB_OTG_DOEPTSIZ_PKTCNT_Pos) | + ((total_bytes << USB_OTG_DOEPTSIZ_XFRSIZ_Pos) & USB_OTG_DOEPTSIZ_XFRSIZ_Msk); + + out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK; + } +} + /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ @@ -431,21 +453,10 @@ void dcd_init (uint8_t rhport) // (non zero-length packet), send STALL back and discard. dev->DCFG |= USB_OTG_DCFG_NZLSOHSK; - // Clear speed bits - dev->DCFG &= ~(3 << USB_OTG_DCFG_DSPD_Pos); - - if ( rhport == 1 ) - { - dev->DCFG |= ((TUD_OPT_HIGH_SPEED ? DCD_HIGH_SPEED : DCD_FULL_SPEED_USE_HS) << USB_OTG_DCFG_DSPD_Pos); - } - else - { - // full speed = 0x03 - dev->DCFG |= (DCD_FULL_SPEED << USB_OTG_DCFG_DSPD_Pos); + set_speed(rhport, TUD_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL); - // Enable internal USB transceiver. - usb_otg->GCCFG |= USB_OTG_GCCFG_PWRDWN; - } + // Enable internal USB transceiver. + if ( rhport == 0 ) usb_otg->GCCFG |= USB_OTG_GCCFG_PWRDWN; usb_otg->GINTMSK |= USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_WUIM | @@ -511,7 +522,7 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) TU_ASSERT(epnum < EP_MAX); // TODO ISO endpoint can be up to 1024 bytes - TU_ASSERT(desc_edpt->wMaxPacketSize.size <= (get_speed(dev) == TUSB_SPEED_HIGH ? 512 : 64)); + TU_ASSERT(desc_edpt->wMaxPacketSize.size <= (get_speed(rhport) == TUSB_SPEED_HIGH ? 512 : 64)); xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir); xfer->max_size = desc_edpt->wMaxPacketSize.size; @@ -575,9 +586,6 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) _allocated_fifo_words += fifo_size; - //TU_LOG2_INT(fifo_size); - //TU_LOG2_INT(_allocated_fifo_words); - in_ep[epnum].DIEPCTL |= (1 << USB_OTG_DIEPCTL_USBAEP_Pos) | (epnum << USB_OTG_DIEPCTL_TXFNUM_Pos) | (desc_edpt->bmAttributes.xfer << USB_OTG_DIEPCTL_EPTYP_Pos) | @@ -925,7 +933,7 @@ void dcd_int_handler(uint8_t rhport) usb_otg->GINTSTS = USB_OTG_GINTSTS_ENUMDNE; - tusb_speed_t const speed = get_speed(dev); + tusb_speed_t const speed = get_speed(rhport); set_turnaround(usb_otg, speed); dcd_event_bus_reset(rhport, speed, true); -- cgit v1.3.1 From a09a86d29931adf801d4293df879ec54164f689d Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 Jul 2020 01:19:02 +0700 Subject: fix NVIC disable typo --- src/portable/st/synopsys/dcd_synopsys.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index 50984c830..288b4e50c 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -340,7 +340,7 @@ static bool USB_HS_PHYCInit(void) usb_hs_phyc->USB_HS_PHYC_PLL = phyc_pll; // Control the tuning interface of the High Speed PHY - // Use magic value from ST driver + // Use magic value (USB_HS_PHYC_TUNE_VALUE) from ST driver usb_hs_phyc->USB_HS_PHYC_TUNE |= 0x00000F13U; // Enable PLL internal PHY @@ -473,7 +473,7 @@ void dcd_int_enable (uint8_t rhport) void dcd_int_disable (uint8_t rhport) { - NVIC_EnableIRQ(_dcd_rhport[rhport].irqnum); + NVIC_DisableIRQ(_dcd_rhport[rhport].irqnum); } void dcd_set_address (uint8_t rhport, uint8_t dev_addr) -- cgit v1.3.1 From ad5ae8c31d286d17fc8bab81b42a19d77173aadb Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 Jul 2020 14:50:39 +0700 Subject: update per review --- src/portable/st/synopsys/dcd_synopsys.c | 89 +++++++++++++++++---------------- 1 file changed, 47 insertions(+), 42 deletions(-) (limited to 'src') diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index 288b4e50c..ff227b55b 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -28,6 +28,10 @@ #include "tusb_option.h" +// Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval) +// We disable SOF for now until needed later on +#define USE_SOF 0 + #if defined (STM32F105x8) || defined (STM32F105xB) || defined (STM32F105xC) || \ defined (STM32F107xB) || defined (STM32F107xC) #define STM32F1_SYNOPSYS @@ -95,31 +99,28 @@ #include "device/dcd.h" //--------------------------------------------------------------------+ -// +// MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ -typedef struct -{ - uint32_t regs; // registers - const IRQn_Type irqnum; // IRQ number -// const uint8_t ep_count; // Max bi-directional Endpoints -}dcd_rhport_t; - -// To be consistent across stm32 port. We will number OTG_FS as Rhport0, and OTG_HS as Rhport1 -static const dcd_rhport_t _dcd_rhport[] = -{ - { .regs = USB_OTG_FS_PERIPH_BASE, .irqnum = OTG_FS_IRQn } +// 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 RHPORT_REGS_BASE USB_OTG_FS_PERIPH_BASE + #define RHPORT_IRQn OTG_FS_IRQn -#ifdef USB_OTG_HS - ,{ .regs = USB_OTG_HS_PERIPH_BASE, .irqnum = OTG_HS_IRQn } +#else + #define EP_MAX EP_MAX_HS + #define EP_FIFO_SIZE EP_FIFO_SIZE_HS + #define RHPORT_REGS_BASE USB_OTG_HS_PERIPH_BASE + #define RHPORT_IRQn OTG_HS_IRQn #endif -}; -#define GLOBAL_BASE(_port) ((USB_OTG_GlobalTypeDef*) _dcd_rhport[_port].regs) -#define DEVICE_BASE(_port) (USB_OTG_DeviceTypeDef *) (_dcd_rhport[_port].regs + USB_OTG_DEVICE_BASE) -#define OUT_EP_BASE(_port) (USB_OTG_OUTEndpointTypeDef *) (_dcd_rhport[_port].regs + USB_OTG_OUT_ENDPOINT_BASE) -#define IN_EP_BASE(_port) (USB_OTG_INEndpointTypeDef *) (_dcd_rhport[_port].regs + USB_OTG_IN_ENDPOINT_BASE) -#define FIFO_BASE(_port, _x) ((volatile uint32_t *) (_dcd_rhport[_port].regs + USB_OTG_FIFO_BASE + (_x) * USB_OTG_FIFO_SIZE)) +#define GLOBAL_BASE(_port) ((USB_OTG_GlobalTypeDef*) RHPORT_REGS_BASE) +#define DEVICE_BASE(_port) (USB_OTG_DeviceTypeDef *) (RHPORT_REGS_BASE + USB_OTG_DEVICE_BASE) +#define OUT_EP_BASE(_port) (USB_OTG_OUTEndpointTypeDef *) (RHPORT_REGS_BASE + USB_OTG_OUT_ENDPOINT_BASE) +#define IN_EP_BASE(_port) (USB_OTG_INEndpointTypeDef *) (RHPORT_REGS_BASE + USB_OTG_IN_ENDPOINT_BASE) +#define FIFO_BASE(_port, _x) ((volatile uint32_t *) (RHPORT_REGS_BASE + USB_OTG_FIFO_BASE + (_x) * USB_OTG_FIFO_SIZE)) enum { @@ -128,14 +129,6 @@ enum DCD_FULL_SPEED = 3, // Full speed with internal PHY }; -/*------------------------------------------------------------------*/ -/* MACRO TYPEDEF CONSTANT ENUM - *------------------------------------------------------------------*/ - -// Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval) -// We disable SOF for now until needed later on -#define USE_SOF 0 - static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2]; typedef struct { @@ -146,14 +139,6 @@ typedef struct { typedef volatile uint32_t * usb_fifo_t; -#if TUD_OPT_RHPORT == 1 - #define EP_MAX EP_MAX_HS - #define EP_FIFO_SIZE EP_FIFO_SIZE_HS -#else - #define EP_MAX EP_MAX_FS - #define EP_FIFO_SIZE EP_FIFO_SIZE_FS -#endif - xfer_ctl_t xfer_status[EP_MAX][2]; #define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] @@ -166,6 +151,8 @@ static uint16_t _allocated_fifo_words; // Setup the control endpoint 0. static void bus_reset(uint8_t rhport) { + (void) rhport; + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); @@ -287,6 +274,7 @@ static void set_turnaround(USB_OTG_GlobalTypeDef * usb_otg, tusb_speed_t speed) static tusb_speed_t get_speed(uint8_t rhport) { + (void) rhport; USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); uint32_t const enum_spd = (dev->DSTS & USB_OTG_DSTS_ENUMSPD_Msk) >> USB_OTG_DSTS_ENUMSPD_Pos; return (enum_spd == DCD_HIGH_SPEED) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL; @@ -353,7 +341,10 @@ static bool USB_HS_PHYCInit(void) } #endif -static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t const dir, uint16_t const num_packets, uint16_t total_bytes) { +static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t const dir, uint16_t const num_packets, uint16_t total_bytes) +{ + (void) rhport; + USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); @@ -437,7 +428,7 @@ void dcd_init (uint8_t rhport) while ((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST) {} // Restart PHY clock - *((volatile uint32_t *)(_dcd_rhport[rhport].regs + USB_OTG_PCGCCTL_BASE)) = 0; + *((volatile uint32_t *)(RHPORT_REGS_BASE + USB_OTG_PCGCCTL_BASE)) = 0; // Clear all interrupts usb_otg->GINTSTS |= usb_otg->GINTSTS; @@ -468,12 +459,14 @@ void dcd_init (uint8_t rhport) void dcd_int_enable (uint8_t rhport) { - NVIC_EnableIRQ(_dcd_rhport[rhport].irqnum); + (void) rhport; + NVIC_EnableIRQ(RHPORT_IRQn); } void dcd_int_disable (uint8_t rhport) { - NVIC_DisableIRQ(_dcd_rhport[rhport].irqnum); + (void) rhport; + NVIC_DisableIRQ(RHPORT_IRQn); } void dcd_set_address (uint8_t rhport, uint8_t dev_addr) @@ -492,6 +485,7 @@ void dcd_remote_wakeup(uint8_t rhport) void dcd_connect(uint8_t rhport) { + (void) rhport; USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); dev->DCTL &= ~USB_OTG_DCTL_SDIS; @@ -499,6 +493,7 @@ void dcd_connect(uint8_t rhport) void dcd_disconnect(uint8_t rhport) { + (void) rhport; USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); dev->DCTL |= USB_OTG_DCTL_SDIS; @@ -633,6 +628,8 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t // (send STALL versus NAK handshakes back). Refactor into resuable function. void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) { + (void) rhport; + USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport); USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); @@ -685,6 +682,8 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) { + (void) rhport; + USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport); USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport); @@ -713,7 +712,10 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) /*------------------------------------------------------------------*/ // Read a single data packet from receive FIFO -static void read_fifo_packet(uint8_t rhport, uint8_t * dst, uint16_t len){ +static void read_fifo_packet(uint8_t rhport, uint8_t * dst, uint16_t len) +{ + (void) rhport; + usb_fifo_t rx_fifo = FIFO_BASE(rhport, 0); // Reading full available 32 bit words from fifo @@ -742,7 +744,10 @@ static void read_fifo_packet(uint8_t rhport, uint8_t * dst, uint16_t len){ } // Write a single data packet to EPIN FIFO -static void write_fifo_packet(uint8_t rhport, uint8_t fifo_num, uint8_t * src, uint16_t len){ +static void write_fifo_packet(uint8_t rhport, uint8_t fifo_num, uint8_t * src, uint16_t len) +{ + (void) rhport; + usb_fifo_t tx_fifo = FIFO_BASE(rhport, fifo_num); // Pushing full available 32 bit words to fifo -- cgit v1.3.1 From fd3817818921981aa67e1fb845f926c010444fea Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 1 Jul 2020 23:07:18 +0200 Subject: STM32/OTG_HS: Allow OTG_HS port to run at FS speed. Add "REDUCE_SPEED=1" to the compile options. --- hw/bsp/stlinkv3mini/board.mk | 18 ++++++++++++++++-- hw/bsp/stm32f723disco/board.mk | 13 +++++++++---- hw/bsp/stm32f746disco/board.mk | 10 ++++++++-- hw/bsp/stm32f769disco/board.mk | 11 ++++++++++- hw/mcu/nordic/nrfx | 2 +- src/portable/st/synopsys/dcd_synopsys.c | 8 +++----- 6 files changed, 47 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/hw/bsp/stlinkv3mini/board.mk b/hw/bsp/stlinkv3mini/board.mk index 1a64c3735..47148ec4d 100644 --- a/hw/bsp/stlinkv3mini/board.mk +++ b/hw/bsp/stlinkv3mini/board.mk @@ -1,3 +1,6 @@ +PORT ?= 1 +REDUCE_SPEED ?= 0 + CFLAGS += \ -flto \ -mthumb \ @@ -9,8 +12,19 @@ CFLAGS += \ -DSTM32F723xx \ -DHSE_VALUE=25000000 \ -DCFG_TUSB_MCU=OPT_MCU_STM32F7 \ - -DBOARD_DEVICE_RHPORT_NUM=1 \ - -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED + -DBOARD_DEVICE_RHPORT_NUM=$(PORT) + +ifeq ($(PORT), 1) + ifeq ($(REDUCE_SPEED), 0) +CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED +$(info "Using OTG_HS in HS mode") + else +CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_FULL_SPEED +$(info "Using OTG_HS in FS mode") + endif +else +$(info "Using OTG_FS") +endif # mcu driver cause following warnings CFLAGS += -Wno-error=shadow -Wno-error=cast-align diff --git a/hw/bsp/stm32f723disco/board.mk b/hw/bsp/stm32f723disco/board.mk index 2cf3ac633..47148ec4d 100644 --- a/hw/bsp/stm32f723disco/board.mk +++ b/hw/bsp/stm32f723disco/board.mk @@ -1,5 +1,5 @@ -# Default is Highspeed port PORT ?= 1 +REDUCE_SPEED ?= 0 CFLAGS += \ -flto \ @@ -15,10 +15,15 @@ CFLAGS += \ -DBOARD_DEVICE_RHPORT_NUM=$(PORT) ifeq ($(PORT), 1) - CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED - $(info "PORT1 High Speed") + ifeq ($(REDUCE_SPEED), 0) +CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED +$(info "Using OTG_HS in HS mode") + else +CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_FULL_SPEED +$(info "Using OTG_HS in FS mode") + endif else - $(info "PORT0 Full Speed") +$(info "Using OTG_FS") endif # mcu driver cause following warnings diff --git a/hw/bsp/stm32f746disco/board.mk b/hw/bsp/stm32f746disco/board.mk index 76a54cdfd..d7329a28f 100644 --- a/hw/bsp/stm32f746disco/board.mk +++ b/hw/bsp/stm32f746disco/board.mk @@ -1,4 +1,5 @@ PORT ?= 0 +REDUCE_SPEED ?= 0 CFLAGS += \ -flto \ @@ -14,10 +15,15 @@ CFLAGS += \ -DBOARD_DEVICE_RHPORT_NUM=$(PORT) ifeq ($(PORT), 1) + ifeq ($(REDUCE_SPEED), 0) CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED -$(info "PORT1 HS") +$(info "Using OTG_HS in HS mode") + else +CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_FULL_SPEED +$(info "Using OTG_HS in FS mode") + endif else -$(info "PORT0") +$(info "Using OTG_FS") endif # mcu driver cause following warnings diff --git a/hw/bsp/stm32f769disco/board.mk b/hw/bsp/stm32f769disco/board.mk index 62c05cca5..43b677ddd 100644 --- a/hw/bsp/stm32f769disco/board.mk +++ b/hw/bsp/stm32f769disco/board.mk @@ -1,3 +1,5 @@ +REDUCE_SPEED ?= 0 + CFLAGS += \ -flto \ -mthumb \ @@ -10,7 +12,14 @@ CFLAGS += \ -DHSE_VALUE=25000000 \ -DCFG_TUSB_MCU=OPT_MCU_STM32F7 \ -DBOARD_DEVICE_RHPORT_NUM=1 \ - -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED + +ifeq ($(REDUCE_SPEED), 0) +CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED +$(info "Using OTG_HS in HS mode") +else +CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_FULL_SPEED +$(info "Using OTG_HS in FS mode") +endif # suppress warning caused by vendor mcu driver CFLAGS += -Wno-error=cast-align -Wno-error=shadow diff --git a/hw/mcu/nordic/nrfx b/hw/mcu/nordic/nrfx index a5397bea5..281cc2e17 160000 --- a/hw/mcu/nordic/nrfx +++ b/hw/mcu/nordic/nrfx @@ -1 +1 @@ -Subproject commit a5397bea558fb4b6838081a22d1ee679289d7417 +Subproject commit 281cc2e178fd9a470d844b3afdea9eb322a0b0e8 diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index 50984c830..6c3a10b00 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -312,7 +312,8 @@ static void set_speed(uint8_t rhport, tusb_speed_t speed) dev->DCFG |= (bitvalue << USB_OTG_DCFG_DSPD_Pos); } -#if defined(USB_HS_PHYC) && TUD_OPT_HIGH_SPEED + +#if defined(USB_HS_PHYC) static bool USB_HS_PHYCInit(void) { USB_HS_PHYC_GlobalTypeDef *usb_hs_phyc = (USB_HS_PHYC_GlobalTypeDef*) USB_HS_PHYC_CONTROLLER_BASE; @@ -398,7 +399,6 @@ void dcd_init (uint8_t rhport) USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport); // No HNP/SRP (no OTG support), program timeout later. -#if TUD_OPT_HIGH_SPEED // TODO may pass parameter instead of using macro for HighSpeed if ( rhport == 1 ) { // On selected MCUs HS port1 can be used with external PHY via ULPI interface @@ -421,10 +421,8 @@ void dcd_init (uint8_t rhport) // Enables control of a High Speed USB PHY USB_HS_PHYCInit(); - #endif - } - else #endif + } else { // Enable internal PHY usb_otg->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL; -- cgit v1.3.1 From 0fd074afd85d84f162ddebbc9b8e009f9136809b Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 8 Jul 2020 16:29:48 +0700 Subject: change REDUCE_SPEED=0/1 to explicitly SPEED=high/full update readme, boards.md to add link to new stm boards --- docs/boards.md | 2 ++ examples/readme.md | 31 +++++++++++++++++++++---------- hw/bsp/stlinkv3mini/board.mk | 13 +++++++------ hw/bsp/stm32f723disco/board.mk | 18 +++++++++--------- hw/bsp/stm32f746disco/board.mk | 18 +++++++++--------- hw/bsp/stm32f769disco/board.mk | 14 ++++++++------ src/portable/st/synopsys/dcd_synopsys.c | 2 +- 7 files changed, 57 insertions(+), 41 deletions(-) (limited to 'src') diff --git a/docs/boards.md b/docs/boards.md index d3dcec375..271ca2844 100644 --- a/docs/boards.md +++ b/docs/boards.md @@ -87,6 +87,7 @@ This code base already had supported for a handful of following boards (sorted a - [Micro Python PyBoard v1.1](https://store.micropython.org/product/PYBv1.1) - [STLink-V3 Mini](https://www.st.com/en/development-tools/stlink-v3mini.html) - [STM32 L035c8 Discovery](https://www.st.com/en/evaluation-tools/32l0538discovery.html) +- [STM32 L4R5zi Nucleo](https://www.st.com/en/evaluation-tools/nucleo-l4r5zi.html) - [STM32 F070rb Nucleo](https://www.st.com/en/evaluation-tools/nucleo-f070rb.html) - [STM32 F072rb Discovery](https://www.st.com/en/evaluation-tools/32f072bdiscovery.html) - STM32 F103c Blue Pill @@ -104,6 +105,7 @@ This code base already had supported for a handful of following boards (sorted a - [STM32 F769i Discovery](https://www.st.com/en/evaluation-tools/32f769idiscovery.html) - [STM32 H743zi Nucleo](https://www.st.com/en/evaluation-tools/nucleo-h743zi.html) - [STM32 H743i Evaluation](https://www.st.com/en/evaluation-tools/stm32h743i-eval.html) +- [STM32 H745i Discovery](https://www.st.com/en/evaluation-tools/stm32h745i-disco.html) ### TI diff --git a/examples/readme.md b/examples/readme.md index 790427cd2..f6cd380b6 100644 --- a/examples/readme.md +++ b/examples/readme.md @@ -32,28 +32,39 @@ Then compile with `make BOARD=[your_board] all`, for example $ make BOARD=feather_nrf52840_express all ``` +**Port Selection** -To compile for debugging with debug symbols add DEBUG=1, for example +If a board has several ports, one port is chosen by default in the individual board.mk file. Use option `PORT=x` To choose another port. For example to select the HS port of a STM32F746Disco board, use: ``` -$ make BOARD=feather_nrf52840_express DEBUG=1 all -If a board has several ports, one port is choosen by default in the individual board.mk file. Choose another port with PORT=x. For example to select the HS port of a STM32F746Disco board, use: +$ make BOARD=stm32f746disco PORT=1 all +``` + +**Port Speed** + +A MCU can support multiple operational speed. By default, the example build system will use the fastest supported on the board. Use option `SPEED=full/high` e.g To force F723 operate at full instead of default high speed ``` -$ make BOARD=stm32f746disco PORT=1 all +$ make BOARD=stm32f746disco SPEED=full all ``` -### Debug Log +### Debug + +To compile for debugging with debug symbols add `DEBUG=1`, for example + +``` +$ make BOARD=feather_nrf52840_express DEBUG=1 all +``` -### Log Level +#### Log Should you have an issue running example and/or submitting an bug report. You could enable TinyUSB built-in debug logging with optional `LOG=`. LOG=1 will only print out error message, LOG=2 print more information with on-going events. LOG=3 or higher is not used yet. ``` -$ make LOG=2 BOARD=feather_nrf52840_express all +$ make BOARD=feather_nrf52840_express LOG=2 all ``` -### Logger +#### Logger By default log message is printed via on-board UART which is slow and take lots of CPU time comparing to USB speed. If your board support on-board/external debugger, it would be more efficient to use it for logging. There are 2 protocols: @@ -67,8 +78,8 @@ By default log message is printed via on-board UART which is slow and take lots - Software viewer should be provided along with your debugger driver. ``` -$ make LOG=2 LOGGER=rtt BOARD=feather_nrf52840_express all -$ make LOG=2 LOGGER=swo BOARD=feather_nrf52840_express all +$ make BOARD=feather_nrf52840_express LOG=2 LOGGER=rtt all +$ make BOARD=feather_nrf52840_express LOG=2 LOGGER=swo all ``` ## Flash diff --git a/hw/bsp/stlinkv3mini/board.mk b/hw/bsp/stlinkv3mini/board.mk index b77fb5a51..4ca6cfd68 100644 --- a/hw/bsp/stlinkv3mini/board.mk +++ b/hw/bsp/stlinkv3mini/board.mk @@ -1,6 +1,6 @@ # Only OTG-HS has a connector on this board -REDUCE_SPEED ?= 0 +SPEED ?= high CFLAGS += \ -flto \ @@ -14,12 +14,13 @@ CFLAGS += \ -DHSE_VALUE=25000000 \ -DCFG_TUSB_MCU=OPT_MCU_STM32F7 \ -DBOARD_DEVICE_RHPORT_NUM=1 -ifeq ($(REDUCE_SPEED), 0) -CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED -$(info "Using OTG_HS in HS mode") + +ifeq ($(SPEED), high) + CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED + $(info "Using OTG_HS in HighSpeed mode") else -CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_FULL_SPEED -$(info "Using OTG_HS in FS mode") + CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_FULL_SPEED + $(info "Using OTG_HS in FullSpeed mode") endif # mcu driver cause following warnings diff --git a/hw/bsp/stm32f723disco/board.mk b/hw/bsp/stm32f723disco/board.mk index 47148ec4d..9ec23bfde 100644 --- a/hw/bsp/stm32f723disco/board.mk +++ b/hw/bsp/stm32f723disco/board.mk @@ -1,5 +1,5 @@ PORT ?= 1 -REDUCE_SPEED ?= 0 +SPEED ?= high CFLAGS += \ -flto \ @@ -15,15 +15,15 @@ CFLAGS += \ -DBOARD_DEVICE_RHPORT_NUM=$(PORT) ifeq ($(PORT), 1) - ifeq ($(REDUCE_SPEED), 0) -CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED -$(info "Using OTG_HS in HS mode") - else -CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_FULL_SPEED -$(info "Using OTG_HS in FS mode") - endif + ifeq ($(SPEED), high) + CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED + $(info "Using OTG_HS in HighSpeed mode") + else + CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_FULL_SPEED + $(info "Using OTG_HS in FullSpeed mode") + endif else -$(info "Using OTG_FS") + $(info "Using OTG_FS") endif # mcu driver cause following warnings diff --git a/hw/bsp/stm32f746disco/board.mk b/hw/bsp/stm32f746disco/board.mk index d7329a28f..48cb3f141 100644 --- a/hw/bsp/stm32f746disco/board.mk +++ b/hw/bsp/stm32f746disco/board.mk @@ -1,5 +1,5 @@ PORT ?= 0 -REDUCE_SPEED ?= 0 +SPEED ?= high CFLAGS += \ -flto \ @@ -15,15 +15,15 @@ CFLAGS += \ -DBOARD_DEVICE_RHPORT_NUM=$(PORT) ifeq ($(PORT), 1) - ifeq ($(REDUCE_SPEED), 0) -CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED -$(info "Using OTG_HS in HS mode") - else -CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_FULL_SPEED -$(info "Using OTG_HS in FS mode") - endif + ifeq ($(SPEED), high) + CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED + $(info "Using OTG_HS in HighSpeed mode") + else + CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_FULL_SPEED + $(info "Using OTG_HS in FullSpeed mode") + endif else -$(info "Using OTG_FS") + $(info "Using OTG_FS") endif # mcu driver cause following warnings diff --git a/hw/bsp/stm32f769disco/board.mk b/hw/bsp/stm32f769disco/board.mk index 43b677ddd..962dddc68 100644 --- a/hw/bsp/stm32f769disco/board.mk +++ b/hw/bsp/stm32f769disco/board.mk @@ -1,4 +1,6 @@ -REDUCE_SPEED ?= 0 +# Only OTG-HS has a connector on this board + +SPEED ?= high CFLAGS += \ -flto \ @@ -13,12 +15,12 @@ CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_STM32F7 \ -DBOARD_DEVICE_RHPORT_NUM=1 \ -ifeq ($(REDUCE_SPEED), 0) -CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED -$(info "Using OTG_HS in HS mode") +ifeq ($(SPEED), high) + CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_HIGH_SPEED + $(info "Using OTG_HS in HighSpeed mode") else -CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_FULL_SPEED -$(info "Using OTG_HS in FS mode") + CFLAGS += -DBOARD_DEVICE_RHPORT_SPEED=OPT_MODE_FULL_SPEED + $(info "Using OTG_HS in FullSpeed mode") endif # suppress warning caused by vendor mcu driver diff --git a/src/portable/st/synopsys/dcd_synopsys.c b/src/portable/st/synopsys/dcd_synopsys.c index 35b7f44f9..7eb63e52f 100644 --- a/src/portable/st/synopsys/dcd_synopsys.c +++ b/src/portable/st/synopsys/dcd_synopsys.c @@ -403,7 +403,7 @@ void dcd_init (uint8_t rhport) // Select default internal VBUS Indicator and Drive for ULPI usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI); - #if defined(USB_HS_PHYC) +#if defined(USB_HS_PHYC) // Highspeed with embedded UTMI PHYC // Select UTMI Interface -- cgit v1.3.1