From b83350fa103f9a7f11acde2859e0a4066a5163ff Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Fri, 28 Apr 2023 18:38:34 +0200 Subject: [PATCH] renesas_ra: support HS port --- hw/bsp/ra/family.mk | 2 + src/portable/renesas/rusb2/dcd_rusb2.c | 112 +++++++++++++++++++++---- src/portable/renesas/rusb2/hcd_rusb2.c | 60 +++++++++---- src/portable/renesas/rusb2/rusb2_ra.c | 16 ++++ src/portable/renesas/rusb2/rusb2_ra.h | 37 ++++++-- 5 files changed, 189 insertions(+), 38 deletions(-) create mode 100644 src/portable/renesas/rusb2/rusb2_ra.c diff --git a/hw/bsp/ra/family.mk b/hw/bsp/ra/family.mk index d48272e61a..3ed17f79f3 100644 --- a/hw/bsp/ra/family.mk +++ b/hw/bsp/ra/family.mk @@ -22,6 +22,7 @@ CFLAGS += \ SRC_C += \ src/portable/renesas/rusb2/dcd_rusb2.c \ src/portable/renesas/rusb2/hcd_rusb2.c \ + src/portable/renesas/rusb2/rusb2_ra.c \ hw/mcu/renesas/fsp/ra/fsp/src/bsp/cmsis/Device/RENESAS/Source/startup.c \ hw/mcu/renesas/fsp/ra/fsp/src/bsp/cmsis/Device/RENESAS/Source/system.c \ hw/mcu/renesas/fsp/ra/fsp/src/bsp/mcu/all/bsp_clocks.c \ @@ -47,6 +48,7 @@ INC += \ $(TOP)/hw/mcu/renesas/fsp/ra/fsp/inc \ $(TOP)/hw/mcu/renesas/fsp/ra/fsp/inc/api \ $(TOP)/hw/mcu/renesas/fsp/ra/fsp/inc/instances \ + $(TOP)/hw/mcu/renesas/fsp/ra/fsp/src/bsp/mcu/all \ $(TOP)/$(FSP_MCU_DIR) \ $(TOP)/$(FSP_BOARD_DIR) diff --git a/src/portable/renesas/rusb2/dcd_rusb2.c b/src/portable/renesas/rusb2/dcd_rusb2.c index 78584125fd..39cbd223fb 100644 --- a/src/portable/renesas/rusb2/dcd_rusb2.c +++ b/src/portable/renesas/rusb2/dcd_rusb2.c @@ -41,6 +41,15 @@ #include "rusb2_rx.h" #elif TU_CHECK_MCU(OPT_MCU_RAXXX) #include "rusb2_ra.h" + #if defined(RENESAS_CORTEX_M23) + #define D0FIFO CFIFO + #define D0FIFOSEL CFIFOSEL + #define D0FIFOSEL_b CFIFOSEL_b + #define D1FIFOSEL CFIFOSEL + #define D1FIFOSEL_b CFIFOSEL_b + #define D0FIFOCTR CFIFOCTR + #define D0FIFOCTR_b CFIFOCTR_b + #endif #else #error "Unsupported MCU" #endif @@ -52,8 +61,10 @@ /* LINK core registers */ #if defined(__CCRX__) #define RUSB2 ((RUSB2_REG_t __evenaccess*) RUSB2_REG_BASE) +#elif (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE) +#define RUSB2 ((R_USB_HS0_Type*)R_USB_HS0_BASE) #else - #define RUSB2 ((RUSB2_REG_t*) RUSB2_REG_BASE) +#define RUSB2 ((R_USB_FS0_Type*)R_USB_FS0_BASE) #endif /* Start of definition of packed structs (used by the CCRX toolchain) */ @@ -75,8 +86,20 @@ typedef struct TU_ATTR_PACKED { typedef union TU_ATTR_PACKED { struct { - volatile uint16_t u8: 8; - volatile uint16_t : 0; + volatile uint32_t : 24; + volatile uint32_t u8: 8; + }; + struct { + volatile uint32_t : 16; + volatile uint32_t u16: 16; + }; + volatile uint32_t u32; +} hw_fifo32_t; + +typedef union TU_ATTR_PACKED { + struct { + volatile uint16_t u8: 8; + volatile uint16_t : 0; }; volatile uint16_t u16; } hw_fifo_t; @@ -107,6 +130,10 @@ typedef struct //--------------------------------------------------------------------+ static dcd_data_t _dcd; +#ifndef FIRST_BULK_PIPE +#define FIRST_BULK_PIPE 3 +#endif + static unsigned find_pipe(unsigned xfer) { switch (xfer) { @@ -116,7 +143,7 @@ static unsigned find_pipe(unsigned xfer) } break; case TUSB_XFER_BULK: - for (int i = 3; i <= 5; ++i) { + for (int i = FIRST_BULK_PIPE; i <= 5; ++i) { if (0 == _dcd.pipe[i].ep) return i; } for (int i = 1; i <= 1; ++i) { @@ -185,16 +212,26 @@ static inline void pipe_wait_for_ready(unsigned num) static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) { +#if (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE) + volatile hw_fifo32_t *reg = (volatile hw_fifo32_t*) fifo; +#else volatile hw_fifo_t *reg = (volatile hw_fifo_t*) fifo; +#endif uintptr_t addr = (uintptr_t)buf; +#if 0 //(CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE) + while (len >= 4) { + reg->u32 = *(const uint32_t *)addr; + addr += 4; + len -= 4; + } +#endif while (len >= 2) { reg->u16 = *(const uint16_t *)addr; addr += 2; len -= 2; } - if (len) { - reg->u8 = *(const uint8_t *)addr; - ++addr; + if (len > 0) { + reg->u8 = *(const uint16_t *)addr; } } @@ -378,8 +415,13 @@ static bool process_pipe0_xfer(int buffer_type, uint8_t ep_addr, void* buffer, u { /* configure fifo direction and access unit settings */ if (ep_addr) { /* IN, 2 bytes */ + #if 0 //(CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE) + RUSB2->CFIFOSEL = RUSB2_CFIFOSEL_ISEL_WRITE | RUSB2_FIFOSEL_MBW_32BIT | + (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0); + #else RUSB2->CFIFOSEL = RUSB2_CFIFOSEL_ISEL_WRITE | RUSB2_FIFOSEL_MBW_16BIT | - (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0); + (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0); + #endif while (!(RUSB2->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE)) ; } else { /* OUT, a byte */ RUSB2->CFIFOSEL = RUSB2_FIFOSEL_MBW_8BIT; @@ -519,12 +561,17 @@ static void process_bus_reset(uint8_t rhport) ++ctr; } tu_varclr(&_dcd); + +#if (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE) + dcd_event_bus_reset(rhport, TUSB_SPEED_HIGH, true); +#else dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); +#endif } static void process_set_address(uint8_t rhport) { - const uint32_t addr = RUSB2->USBADDR_b.USBADDR; + const uint32_t addr = RUSB2->USBADDR & 0xFF; if (!addr) return; const tusb_control_request_t setup_packet = { #if defined(__CCRX__) @@ -572,34 +619,53 @@ void dcd_init(uint8_t rhport) { (void)rhport; -#if 0 // previously present in the rx driver before generalization - uint32_t pswi = disable_interrupt(); - SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | SYSTEM_PRCR_PRC1; - MSTP(USB0) = 0; - SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY; - enable_interrupt(pswi); -#endif - +#if (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE) + RUSB2->SYSCFG_b.HSE = 1; + RUSB2->PHYSET_b.DIRPD = 0; + R_BSP_SoftwareDelay((uint32_t) 1, BSP_DELAY_UNITS_MILLISECONDS); + RUSB2->PHYSET_b.PLLRESET = 0; + //RUSB2->PHYSET_b.REPSTART = 1; + RUSB2->SYSCFG_b.DRPD = 0; + RUSB2->SYSCFG_b.USBE = 1; + RUSB2->LPSTS_b.SUSPENDM = 1; + while (!RUSB2->PLLSTA_b.PLLLOCK); + //RUSB2->BUSWAIT |= 0x0F00U; + //RUSB2->PHYSET_b.REPSEL = 1; + RUSB2->CFIFOSEL_b.MBW = 1; + RUSB2->D0FIFOSEL_b.MBW = 1; + RUSB2->D1FIFOSEL_b.MBW = 1; + RUSB2->INTSTS0 = 0; +#else RUSB2->SYSCFG_b.SCKE = 1; while (!RUSB2->SYSCFG_b.SCKE) ; RUSB2->SYSCFG_b.DRPD = 0; RUSB2->SYSCFG_b.DCFM = 0; RUSB2->SYSCFG_b.USBE = 1; +#endif // MCU specific PHY init rusb2_phy_init(); +#if (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) RUSB2->PHYSLEW = 0x5; RUSB2->DPUSR0R_FS_b.FIXPHY0 = 0u; /* USB_BASE Transceiver Output fixed */ + #define USB_VDCEN (0x0080U) /* b7: Regulator ON/OFF control */ + RUSB2->USBMC = (uint16_t) (RUSB2->USBMC | (USB_VDCEN)); +#endif + /* Setup default control pipe */ RUSB2->DCPMAXP_b.MXPS = 64; RUSB2->INTENB0 = RUSB2_INTSTS0_VBINT_Msk | RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_BEMP_Msk | RUSB2_INTSTS0_DVST_Msk | RUSB2_INTSTS0_CTRT_Msk | (USE_SOF ? RUSB2_INTSTS0_SOFR_Msk : 0) | - RUSB2_INTSTS0_RESM_Msk; + RUSB2_INTSTS0_RESM_Msk | RUSB2_INTSTS0_NRDY_Msk; RUSB2->BEMPENB = 1; RUSB2->BRDYENB = 1; +#if (CFG_TUSB_RHPORT0_MODE & OPT_MODE_DEVICE) + RUSB2->SYSCFG_b.DPRPU = 1; /* necessary in this position */ +#endif + if (RUSB2->INTSTS0_b.VBSTS) { dcd_connect(rhport); } @@ -630,6 +696,10 @@ void dcd_remote_wakeup(uint8_t rhport) void dcd_connect(uint8_t rhport) { (void)rhport; + #if (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE) + RUSB2->SYSCFG_b.CNEN = 1; + R_BSP_SoftwareDelay((uint32_t) 10, BSP_DELAY_UNITS_MILLISECONDS); + #endif RUSB2->SYSCFG_b.DPRPU = 1; } @@ -672,6 +742,9 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) /* setup pipe */ dcd_int_disable(rhport); + #if (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE) + RUSB2->PIPEBUF = 0x7C08; + #endif RUSB2->PIPESEL = num; RUSB2->PIPEMAXP = mps; volatile uint16_t *ctr = get_pipectr(num); @@ -826,6 +899,9 @@ void dcd_int_handler(uint8_t rhport) break; } } + if (is0 & RUSB2_INTSTS0_NRDY_Msk) { + RUSB2->NRDYSTS = 0; + } if (is0 & RUSB2_INTSTS0_CTRT_Msk) { if (is0 & RUSB2_INTSTS0_CTSQ_CTRL_RDATA) { /* A setup packet has been received. */ diff --git a/src/portable/renesas/rusb2/hcd_rusb2.c b/src/portable/renesas/rusb2/hcd_rusb2.c index e4743223e7..70a2528a2d 100644 --- a/src/portable/renesas/rusb2/hcd_rusb2.c +++ b/src/portable/renesas/rusb2/hcd_rusb2.c @@ -47,9 +47,11 @@ /* LINK core registers */ #if defined(__CCRX__) - #define RUSB2 ((RUSB2_REG_t __evenaccess*) RUSB2_REG_BASE) +#define RUSB2 ((RUSB2_REG_t __evenaccess*)RUSB2_REG_BASE) +#elif (CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST) +#define RUSB2 ((R_USB_HS0_Type*)R_USB_HS0_BASE) #else - #define RUSB2 ((RUSB2_REG_t*) RUSB2_REG_BASE) +#define RUSB2 ((R_USB_FS0_Type*)R_USB_FS0_BASE) #endif TU_ATTR_PACKED_BEGIN @@ -477,31 +479,49 @@ bool hcd_init(uint8_t rhport) { (void)rhport; -#if 0 // previously present in the rx driver before generalization - uint32_t pswi = disable_interrupt(); - SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | SYSTEM_PRCR_PRC1; - MSTP(USB0) = 0; - SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY; - enable_interrupt(pswi); -#endif - - RUSB2->SYSCFG_b.SCKE = 1; - while (!RUSB2->SYSCFG_b.SCKE) ; - RUSB2->SYSCFG_b.DPRPU = 0; - RUSB2->SYSCFG_b.DRPD = 0; +#if (CFG_TUSB_RHPORT1_MODE & OPT_MODE_HOST) + RUSB2->SYSCFG_b.HSE = 1; + RUSB2->PHYSET_b.HSEB = 0; + RUSB2->PHYSET_b.DIRPD = 0; + R_BSP_SoftwareDelay((uint32_t) 1, BSP_DELAY_UNITS_MILLISECONDS); + RUSB2->PHYSET_b.PLLRESET = 0; + RUSB2->LPSTS_b.SUSPENDM = 1; + while (!RUSB2->PLLSTA_b.PLLLOCK); + RUSB2->SYSCFG_b.DRPD = 1; RUSB2->SYSCFG_b.DCFM = 1; + RUSB2->SYSCFG_b.DPRPU = 0; + RUSB2->SYSCFG_b.CNEN = 1; + RUSB2->BUSWAIT |= 0x0F00U; + RUSB2->SOFCFG_b.INTL = 1; + RUSB2->DVSTCTR0_b.VBUSEN = 1; + RUSB2->CFIFOSEL_b.MBW = 1; + RUSB2->D0FIFOSEL_b.MBW = 1; + RUSB2->D1FIFOSEL_b.MBW = 1; + RUSB2->INTSTS0 = 0; + for (volatile int i = 0; i < 30000; ++i) ; + RUSB2->SYSCFG_b.USBE = 1; +#else + /* HOST DEVICE Full SPEED */ + RUSB2->SYSCFG_b.SCKE = 1; /* USB Clock enable */ + while (!RUSB2->SYSCFG_b.SCKE) ; + RUSB2->SYSCFG_b.DPRPU = 0; /* D+ pull up enable - 0/disable in host mode */ + RUSB2->SYSCFG_b.DRPD = 1; /* D+/D- pull down - 1/in Host mode (pag.834)*/ + RUSB2->SYSCFG_b.DCFM = 1; /* HOST or Device - 1/HOST */ RUSB2->DVSTCTR0_b.VBUSEN = 1; RUSB2->SYSCFG_b.DRPD = 1; for (volatile int i = 0; i < 30000; ++i) ; RUSB2->SYSCFG_b.USBE = 1; +#endif // MCU specific PHY init rusb2_phy_init(); +#if (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HOST) RUSB2->PHYSLEW = 0x5; RUSB2->DPUSR0R_FS_b.FIXPHY0 = 0u; /* Transceiver Output fixed */ +#endif /* Setup default control pipe */ RUSB2->DCPCFG = RUSB2_PIPECFG_SHTNAK_Msk; @@ -739,9 +759,10 @@ void hcd_int_handler(uint8_t rhport) 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, 20, 8, 19, 18}; #endif - + static unsigned char attach_attempt = 0; unsigned is1 = RUSB2->INTSTS1; unsigned is0 = RUSB2->INTSTS0; + /* clear active bits except VALID (don't write 0 to already cleared bits according to the HW manual) */ RUSB2->INTSTS1 = ~((RUSB2_INTSTS1_SACK_Msk | RUSB2_INTSTS1_SIGN_Msk | RUSB2_INTSTS1_ATTCH_Msk | RUSB2_INTSTS1_DTCH_Msk) & is1); RUSB2->INTSTS0 = ~((RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_NRDY_Msk | RUSB2_INTSTS0_BEMP_Msk) & is0); @@ -752,12 +773,21 @@ void hcd_int_handler(uint8_t rhport) if (is1 & RUSB2_INTSTS1_SACK_Msk) { /* Set DATA1 in advance for the next transfer. */ RUSB2->DCPCTR_b.SQSET = 1; + attach_attempt = 0; hcd_event_xfer_complete(RUSB2->DCPMAXP_b.DEVSEL, tu_edpt_addr(0, TUSB_DIR_OUT), 8, XFER_RESULT_SUCCESS, true); } if (is1 & RUSB2_INTSTS1_SIGN_Msk) { hcd_event_xfer_complete(RUSB2->DCPMAXP_b.DEVSEL, tu_edpt_addr(0, TUSB_DIR_OUT), 8, XFER_RESULT_FAILED, true); + if(attach_attempt > 0) { + RUSB2->DVSTCTR0_b.UACT = 1; + _hcd.need_reset = true; + RUSB2->INTENB1 = (RUSB2->INTENB1 & ~RUSB2_INTSTS1_ATTCH_Msk) | RUSB2_INTSTS1_DTCH_Msk; + hcd_event_device_attach(rhport, true); + } + attach_attempt--; } if (is1 & RUSB2_INTSTS1_ATTCH_Msk) { + attach_attempt = 10; RUSB2->DVSTCTR0_b.UACT = 1; _hcd.need_reset = true; RUSB2->INTENB1 = (RUSB2->INTENB1 & ~RUSB2_INTSTS1_ATTCH_Msk) | RUSB2_INTSTS1_DTCH_Msk; diff --git a/src/portable/renesas/rusb2/rusb2_ra.c b/src/portable/renesas/rusb2/rusb2_ra.c new file mode 100644 index 0000000000..2b6ce7b2fc --- /dev/null +++ b/src/portable/renesas/rusb2/rusb2_ra.c @@ -0,0 +1,16 @@ +#include "tusb_option.h" +#include "rusb2_ra.h" + +#ifdef CFG_TUSB_RHPORT0_MODE +IRQn_Type _usb_fs_irqn = USBFS_INT_IRQn; +void tud_set_irq_usbfs(IRQn_Type q) { + _usb_fs_irqn = q; +} +#endif + +#ifdef CFG_TUSB_RHPORT1_MODE +IRQn_Type _usb_hs_irqn = USBHS_USB_INT_RESUME_IRQn; +void tud_set_irq_usbhs(IRQn_Type q) { + _usb_hs_irqn = q; +} +#endif \ No newline at end of file diff --git a/src/portable/renesas/rusb2/rusb2_ra.h b/src/portable/renesas/rusb2/rusb2_ra.h index 5785850ccf..b18b506e5c 100644 --- a/src/portable/renesas/rusb2/rusb2_ra.h +++ b/src/portable/renesas/rusb2/rusb2_ra.h @@ -34,18 +34,45 @@ extern "C" { /* renesas fsp api */ #include "bsp_api.h" -#define RUSB2_REG_BASE (0x40090000) +extern IRQn_Type _usb_fs_irqn; +extern IRQn_Type _usb_hs_irqn; TU_ATTR_ALWAYS_INLINE static inline void rusb2_int_enable(uint8_t rhport) { - (void) rhport; - NVIC_EnableIRQ(TU_IRQn); +#ifdef CFG_TUSB_RHPORT1_MODE +#if (CFG_TUSB_RHPORT1_MODE != 0) + if (rhport == 1) { + NVIC_EnableIRQ(_usb_hs_irqn); + } +#endif +#endif + +#ifdef CFG_TUSB_RHPORT0_MODE +#if (CFG_TUSB_RHPORT0_MODE != 0) + if (rhport == 0) { + NVIC_EnableIRQ(_usb_fs_irqn); + } +#endif +#endif } TU_ATTR_ALWAYS_INLINE static inline void rusb2_int_disable(uint8_t rhport) { - (void) rhport; - NVIC_DisableIRQ(TU_IRQn); +#ifdef CFG_TUSB_RHPORT1_MODE +#if (CFG_TUSB_RHPORT1_MODE != 0) + if (rhport == 1) { + NVIC_DisableIRQ(_usb_hs_irqn); + } +#endif +#endif + +#ifdef CFG_TUSB_RHPORT0_MODE +#if (CFG_TUSB_RHPORT0_MODE != 0) + if (rhport == 0) { + NVIC_DisableIRQ(_usb_fs_irqn); + } +#endif +#endif } // MCU specific PHY init