diff --git a/src/portable/nuvoton/nuc121/dcd_nuc121.c b/src/portable/nuvoton/nuc121/dcd_nuc121.c index 4e0a583e..25d723d9 100644 --- a/src/portable/nuvoton/nuc121/dcd_nuc121.c +++ b/src/portable/nuvoton/nuc121/dcd_nuc121.c @@ -148,6 +148,37 @@ static void dcd_in_xfer(struct xfer_ctl_t *xfer, USBD_EP_T *ep) ep->MXPLD = bytes_now; } +/* called by dcd_init() as well as by the ISR during a USB bus reset */ +static void bus_reset(void) +{ + USBD->STBUFSEG = PERIPH_SETUP_BUF_BASE; + + for (enum ep_enum ep_index = PERIPH_EP0; ep_index < PERIPH_MAX_EP; ep_index++) + { + USBD->EP[ep_index].CFG = 0; + USBD->EP[ep_index].CFGP = 0; + } + + /* allocate the default EP0 endpoints */ + + USBD->EP[PERIPH_EP0].CFG = USBD_CFG_CSTALL_Msk | USBD_CFG_EPMODE_IN; + USBD->EP[PERIPH_EP0].BUFSEG = PERIPH_EP0_BUF_BASE; + xfer_table[PERIPH_EP0].max_packet_size = PERIPH_EP0_BUF_LEN; + + USBD->EP[PERIPH_EP1].CFG = USBD_CFG_CSTALL_Msk | USBD_CFG_EPMODE_OUT; + USBD->EP[PERIPH_EP1].BUFSEG = PERIPH_EP1_BUF_BASE; + xfer_table[PERIPH_EP1].max_packet_size = PERIPH_EP1_BUF_LEN; + + /* USB RAM beyond what we've allocated above is available to the user */ + bufseg_addr = PERIPH_EP2_BUF_BASE; + + /* Reset USB device address */ + USBD->FADDR = 0; + + /* reset EP0_IN flag */ + active_ep0_xfer = false; +} + /* centralized location for USBD interrupt enable bit mask */ static const uint32_t enabled_irqs = USBD_INTSTS_VBDETIF_Msk | USBD_INTSTS_BUSIF_Msk | USBD_INTSTS_SETUP_Msk | USBD_INTSTS_USBIF_Msk | USBD_INTSTS_SOFIF_Msk; @@ -167,25 +198,7 @@ void dcd_init(uint8_t rhport) usb_detach(); - USBD->STBUFSEG = PERIPH_SETUP_BUF_BASE; - - for (enum ep_enum ep_index = PERIPH_EP0; ep_index < PERIPH_MAX_EP; ep_index++) - { - USBD->EP[ep_index].CFGP &= ~USBD_CFG_STATE_Msk; - } - - /* allocate the default EP0 endpoints */ - - USBD->EP[PERIPH_EP0].CFG = USBD_CFG_CSTALL_Msk | USBD_CFG_EPMODE_IN; - USBD->EP[PERIPH_EP0].BUFSEG = PERIPH_EP0_BUF_BASE; - xfer_table[PERIPH_EP0].max_packet_size = PERIPH_EP0_BUF_LEN; - - USBD->EP[PERIPH_EP1].CFG = USBD_CFG_CSTALL_Msk | USBD_CFG_EPMODE_OUT; - USBD->EP[PERIPH_EP1].BUFSEG = PERIPH_EP1_BUF_BASE; - xfer_table[PERIPH_EP1].max_packet_size = PERIPH_EP1_BUF_LEN; - - /* USB RAM beyond what we've allocated above is available to the user */ - bufseg_addr = PERIPH_EP2_BUF_BASE; + bus_reset(); usb_attach(); @@ -329,15 +342,7 @@ void USBD_IRQHandler(void) /* USB bus reset */ USBD->ATTR |= USBD_ATTR_USBEN_Msk | USBD_ATTR_PHYEN_Msk; - /* Reset all endpoints to DATA0 */ - for(enum ep_enum ep_index = PERIPH_EP0; ep_index < PERIPH_MAX_EP; ep_index++) - USBD->EP[ep_index].CFG &= ~USBD_CFG_DSQSYNC_Msk; - - /* Reset USB device address */ - USBD->FADDR = 0; - - /* reset EP0_IN flag */ - active_ep0_xfer = false; + bus_reset(); dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true); } diff --git a/src/portable/nxp/transdimension/dcd_transdimension.c b/src/portable/nxp/transdimension/dcd_transdimension.c index 2ec7ae51..77e355ed 100644 --- a/src/portable/nxp/transdimension/dcd_transdimension.c +++ b/src/portable/nxp/transdimension/dcd_transdimension.c @@ -1,4 +1,4 @@ -/* +/* * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) @@ -313,6 +313,10 @@ void dcd_init(uint8_t rhport) // TODO Force fullspeed on non-highspeed port // dcd_reg->PORTSC1 = PORTSC1_FORCE_FULL_SPEED; + #if defined(__CORTEX_M) && __CORTEX_M == 7 && __DCACHE_PRESENT == 1 + SCB_CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t)); + #endif + dcd_reg->ENDPTLISTADDR = (uint32_t) _dcd_data.qhd; // Endpoint List Address has to be 2K alignment dcd_reg->USBSTS = dcd_reg->USBSTS; dcd_reg->USBINTR = INTR_USB | INTR_ERROR | INTR_PORT_CHANGE | INTR_RESET | INTR_SUSPEND | INTR_SOF; @@ -419,6 +423,10 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) p_qhd->max_package_size = p_endpoint_desc->wMaxPacketSize.size; p_qhd->qtd_overlay.next = QTD_NEXT_INVALID; + #if defined(__CORTEX_M) && __CORTEX_M == 7 && __DCACHE_PRESENT == 1 + SCB_CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t)); + #endif + // Enable EP Control DCD_REGS[rhport]->ENDPTCTRL[epnum] |= ((p_endpoint_desc->bmAttributes.xfer << 2) | ENDPTCTRL_ENABLE | ENDPTCTRL_TOGGLE_RESET) << (dir ? 16 : 0); @@ -441,10 +449,19 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t dcd_qhd_t * p_qhd = &_dcd_data.qhd[ep_idx]; dcd_qtd_t * p_qtd = &_dcd_data.qtd[ep_idx]; + // Force the CPU to flush the buffer. We increase the size by 32 because the call aligns the + // address to 32-byte boundaries. + #if defined(__CORTEX_M) && __CORTEX_M == 7 && __DCACHE_PRESENT == 1 + SCB_CleanInvalidateDCache_by_Addr((uint32_t*) buffer, total_bytes + 31); + #endif + //------------- Prepare qtd -------------// qtd_init(p_qtd, buffer, total_bytes); p_qtd->int_on_complete = true; p_qhd->qtd_overlay.next = (uint32_t) p_qtd; // link qtd to qhd + #if defined(__CORTEX_M) && __CORTEX_M == 7 && __DCACHE_PRESENT == 1 + SCB_CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t)); + #endif // start transfer DCD_REGS[rhport]->ENDPTPRIME = TU_BIT( ep_idx2bit(ep_idx) ) ; @@ -484,6 +501,11 @@ void dcd_isr(uint8_t rhport) } } + // Make sure we read the latest version of _dcd_data. + #if defined(__CORTEX_M) && __CORTEX_M == 7 && __DCACHE_PRESENT == 1 + SCB_CleanInvalidateDCache_by_Addr((uint32_t*) &_dcd_data, sizeof(dcd_data_t)); + #endif + // TODO disconnection does not generate interrupt !!!!!! // if (int_status & INTR_PORT_CHANGE) // {