Merge remote-tracking branch 'upstream/master' into uac2

Conflicts:
	src/device/usbd.c
	src/device/usbd.h
	src/portable/st/synopsys/dcd_synopsys.c
This commit is contained in:
Reinhard Panhuber
2020-08-16 14:08:24 +02:00
24 changed files with 213 additions and 139 deletions

View File

@@ -555,10 +555,10 @@ static void handle_ep0_nak(void)
*------------------------------------------------------------------*/
void dcd_init(uint8_t rhport)
{
(void)rhport;
USB->USB_MCTRL_REG = USB_USB_MCTRL_REG_USBEN_Msk;
tusb_vbus_changed((CRG_TOP->ANA_STATUS_REG & CRG_TOP_ANA_STATUS_REG_VBUS_AVAILABLE_Msk) != 0);
dcd_connect(rhport);
}
void dcd_int_enable(uint8_t rhport)

View File

@@ -54,6 +54,9 @@
// FIFO size in bytes
#define EP_FIFO_SIZE 1024
// Max number of IN EP FIFOs
#define EP_FIFO_NUM 5
typedef struct {
uint8_t *buffer;
uint16_t total_len;
@@ -71,6 +74,16 @@ static uint32_t _setup_packet[2];
#define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir]
static xfer_ctl_t xfer_status[EP_MAX][2];
// Keep count of how many FIFOs are in use
static uint8_t _allocated_fifos = 1; //FIFO0 is always in use
// Will either return an unused FIFO number, or 0 if all are used.
static uint8_t get_free_fifo(void)
{
if (_allocated_fifos < EP_FIFO_NUM) return _allocated_fifos++;
return 0;
}
// Setup the control endpoint 0.
static void bus_reset(void)
{
@@ -152,8 +165,6 @@ static void enum_done_processing(void)
*------------------------------------------------------------------*/
void dcd_init(uint8_t rhport)
{
(void)rhport;
ESP_LOGV(TAG, "DCD init - Start");
// A. Disconnect
@@ -191,6 +202,8 @@ void dcd_init(uint8_t rhport)
USB_ENUMDONEMSK_M |
USB_RESETDETMSK_M |
USB_DISCONNINTMSK_M; // host most only
dcd_connect(rhport);
}
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
@@ -271,8 +284,12 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt)
// - Offset: GRXFSIZ + 16 + Size*(epnum-1)
// - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n".
uint8_t fifo_num = get_free_fifo();
TU_ASSERT(fifo_num != 0);
in_ep[epnum].diepctl &= ~(USB_D_TXFNUM1_M | USB_D_EPTYPE1_M | USB_DI_SETD0PID1 | USB_D_MPS1_M);
in_ep[epnum].diepctl |= USB_D_USBACTEP1_M |
epnum << USB_D_TXFNUM1_S |
fifo_num << USB_D_TXFNUM1_S |
desc_edpt->bmAttributes.xfer << USB_D_EPTYPE1_S |
(desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? (1 << USB_DI_SETD0PID1_S) : 0) |
desc_edpt->wMaxPacketSize.size << 0;
@@ -282,8 +299,8 @@ 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 = (USB0.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);
uint16_t const fifo_size = (EP_FIFO_SIZE/4 - allocated_size) / (EP_FIFO_NUM-1);
uint32_t const fifo_offset = allocated_size + fifo_size*(fifo_num-1);
// DIEPTXF starts at FIFO #1.
USB0.dieptxf[epnum - 1] = (fifo_size << USB_NPTXFDEP_S) | fifo_offset;
@@ -361,7 +378,8 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
}
// Flush the FIFO, and wait until we have confirmed it cleared.
USB0.grstctl |= ((epnum - 1) << USB_TXFNUM_S);
uint8_t const fifo_num = ((in_ep[epnum].diepctl >> USB_D_TXFNUM1_S) & USB_D_TXFNUM1_V);
USB0.grstctl |= (fifo_num << USB_TXFNUM_S);
USB0.grstctl |= USB_TXFFLSH_M;
while ((USB0.grstctl & USB_TXFFLSH_M) != 0) ;
} else {
@@ -660,6 +678,8 @@ static void _dcd_int_handler(void* arg)
// start of reset
ESP_EARLY_LOGV(TAG, "dcd_int_handler - reset");
USB0.gintsts = USB_USBRST_M;
// FIFOs will be reassigned when the endpoints are reopen
_allocated_fifos = 1;
bus_reset();
}

View File

@@ -154,9 +154,8 @@ static void bus_reset(void)
// Initialize controller to device mode
void dcd_init (uint8_t rhport)
{
(void) rhport;
tu_memclr(_dcd_xfer, sizeof(_dcd_xfer));
dcd_connect(rhport);
}
// Enable device interrupt

View File

@@ -271,6 +271,10 @@ void dcd_disconnect(uint8_t rhport)
{
(void) rhport;
NRF_USBD->USBPULLUP = 0;
// Disable Pull-up does not trigger Power USB Removed, in fact it have no
// impact on the USB Power status at all -> need to submit unplugged event to the stack.
dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, false);
}
// connect by enabling internal pull-up resistor on D+/D-
@@ -693,6 +697,8 @@ void tusb_hal_nrf_power_event (uint32_t event)
switch ( event )
{
case USB_EVT_DETECTED:
TU_LOG2("Power USB Detect\r\n");
if ( !NRF_USBD->ENABLE )
{
/* Prepare for READY event receiving */
@@ -743,6 +749,12 @@ void tusb_hal_nrf_power_event (uint32_t event)
break;
case USB_EVT_READY:
TU_LOG2("Power USB Ready\r\n");
// Skip if pull-up is enabled and HCLK is already running.
// Application probably call this more than necessary.
if ( NRF_USBD->USBPULLUP && hfclk_running() ) break;
/* Waiting for USBD peripheral enabled */
while ( !(USBD_EVENTCAUSE_READY_Msk & NRF_USBD->EVENTCAUSE) ) { }
@@ -810,6 +822,7 @@ void tusb_hal_nrf_power_event (uint32_t event)
break;
case USB_EVT_REMOVED:
TU_LOG2("Power USB Removed\r\n");
if ( NRF_USBD->ENABLE )
{
// Abort all transfers
@@ -829,7 +842,7 @@ void tusb_hal_nrf_power_event (uint32_t event)
hfclk_disable();
dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, true);
dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) ? true : false);
}
break;

View File

@@ -181,6 +181,8 @@ void dcd_init(uint8_t rhport)
LPC_USB->UDCAH = (uint32_t) _dcd.udca;
LPC_USB->DMAIntEn = (DMA_INT_END_OF_XFER_MASK /*| DMA_INT_NEW_DD_REQUEST_MASK*/ | DMA_INT_ERROR_MASK);
dcd_connect(rhport);
// Clear pending IRQ
NVIC_ClearPendingIRQ(USB_IRQn);
}

View File

@@ -345,7 +345,8 @@ void dcd_init(uint8_t rhport)
dcd_reg->USBSTS = dcd_reg->USBSTS;
dcd_reg->USBINTR = INTR_USB | INTR_ERROR | INTR_PORT_CHANGE | INTR_RESET | INTR_SUSPEND /*| INTR_SOF*/;
dcd_reg->USBCMD &= ~0x00FF0000; // Interrupt Threshold Interval = 0
dcd_reg->USBCMD &= ~0x00FF0000; // Interrupt Threshold Interval = 0
dcd_reg->USBCMD |= USBCMD_RUN_STOP; // Connect
}
void dcd_int_enable(uint8_t rhport)

View File

@@ -205,7 +205,6 @@ static inline void reg16_clear_bits(__IO uint16_t *reg, uint16_t mask) {
void dcd_init (uint8_t rhport)
{
(void)rhport;
/* Clocks should already be enabled */
/* Use __HAL_RCC_USB_CLK_ENABLE(); to enable the clocks before calling this function */
@@ -244,7 +243,8 @@ void dcd_init (uint8_t rhport)
USB->CNTR |= USB_CNTR_RESETM | (USE_SOF ? USB_CNTR_SOFM : 0) | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM;
dcd_handle_bus_reset();
// Data-line pull-up is left disconnected.
// Enable pull-up if supported
if ( dcd_connect ) dcd_connect(rhport);
}
// Define only on MCU with internal pull-up. BSP can define on MCU without internal PU.

View File

@@ -305,6 +305,7 @@ static void set_EP0_max_pkt_size()
}
// Set turn-around timeout according to link speed
extern uint32_t SystemCoreClock;
static void set_turnaround(USB_OTG_GlobalTypeDef * usb_otg, tusb_speed_t speed)
{
usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
@@ -317,7 +318,6 @@ 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 )
@@ -439,6 +439,13 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c
((total_bytes << USB_OTG_DIEPTSIZ_XFRSIZ_Pos) & USB_OTG_DIEPTSIZ_XFRSIZ_Msk);
in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK;
// For ISO endpoint set correct odd/even bit for next frame.
if ((in_ep[epnum].DIEPCTL & USB_OTG_DIEPCTL_EPTYP) == USB_OTG_DIEPCTL_EPTYP_0)
{
// Take odd/even bit from frame counter.
uint32_t const odd_frame_now = (dev->DSTS & (1u << USB_OTG_DSTS_FNSOF_Pos));
in_ep[epnum].DIEPCTL |= (odd_frame_now ? USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Msk : USB_OTG_DIEPCTL_SODDFRM_Msk);
}
// Enable fifo empty interrupt only if there are something to put in the fifo.
if(total_bytes != 0) {
dev->DIEPEMPMSK |= (1 << epnum);
@@ -527,6 +534,8 @@ void dcd_init (uint8_t rhport)
// Enable global interrupt
usb_otg->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
dcd_connect(rhport);
}
void dcd_int_enable (uint8_t rhport)
@@ -588,13 +597,13 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
TU_ASSERT(epnum < EP_MAX);
if (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS)
if (desc_edpt->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS)
{
TU_ASSERT(desc_edpt->wMaxPacketSize.size <= (get_speed(rhport) == TUSB_SPEED_HIGH ? 512 : 64));
TU_ASSERT(desc_edpt->wMaxPacketSize.size <= (get_speed(rhport) == TUSB_SPEED_HIGH ? 1024 : 1023));
}
else
{
TU_ASSERT(desc_edpt->wMaxPacketSize.size <= (get_speed(rhport) == TUSB_SPEED_HIGH ? 1024 : 1023));
TU_ASSERT(desc_edpt->wMaxPacketSize.size <= (get_speed(rhport) == TUSB_SPEED_HIGH ? 512 : 64));
}
xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir);
@@ -771,7 +780,7 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
}
// Flush the FIFO, and wait until we have confirmed it cleared.
usb_otg->GRSTCTL |= ((epnum - 1) << USB_OTG_GRSTCTL_TXFNUM_Pos);
usb_otg->GRSTCTL |= (epnum << USB_OTG_GRSTCTL_TXFNUM_Pos);
usb_otg->GRSTCTL |= USB_OTG_GRSTCTL_TXFFLSH;
while((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH_Msk) != 0);
} else {

View File

@@ -70,8 +70,7 @@ typedef enum
SIZXY = 7
} ep_regs_index_t;
#define EP_REGS(epnum, dir) &USBOEPCNF_1 + 64*dir + 8*(epnum - 1)
#define EP_REGS(epnum, dir) ((ep_regs_t) ((uintptr_t)&USBOEPCNF_1 + 64*dir + 8*(epnum - 1)))
static void bus_reset(void)
{
@@ -134,6 +133,9 @@ void dcd_init (uint8_t rhport)
// Enable reset and wait for it before continuing.
USBIE |= RSTRIE;
// Enable pullup.
USBCNF |= PUR_EN;
USBKEYPID = 0;
}