From e9109f36ba873062812b37f2c40fc88bbf48af67 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 17 Aug 2024 16:34:24 +0700 Subject: [PATCH] refactor fifo configure/setup for dynamic and static fifo --- src/portable/mentor/musb/dcd_musb.c | 90 +++++++++++++++++++++++---- src/portable/mentor/musb/musb_max32.h | 39 ++++++------ src/portable/mentor/musb/musb_ti.h | 3 + src/portable/mentor/musb/musb_type.h | 3 +- 4 files changed, 103 insertions(+), 32 deletions(-) diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 36690c952..e9d907828 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -41,7 +41,6 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); // Following symbols must be defined by port header // - musb_dcd_int_enable/disable/clear/get_enable // - musb_dcd_int_handler_enter/exit -// - musb_dcd_setup_fifo: Configuration of the EP's FIFO #if defined(TUP_USBIP_MUSB_TI) #include "musb_ti.h" #elif defined(TUP_USBIP_MUSB_ADI) @@ -88,19 +87,78 @@ typedef struct *------------------------------------------------------------------*/ static dcd_data_t _dcd; -TU_ATTR_ALWAYS_INLINE static inline void fifo_reset(musb_regs_t* musb, unsigned epnum, unsigned dir_in) { - musb->index = epnum; - const uint8_t is_rx = 1 - dir_in; - #if MUSB_CFG_DYNAMIC_FIFO + +// musb is configured to use dynamic FIFO sizing. +// FF Size is encodded: 1 << (fifo_size[3:0] + 3) = 8 << fifo_size[3:0] +// FF Address is 8*ff_addr[12:0] +// First 64 bytes are reserved for EP0 +static uint32_t alloced_fifo_bytes; + +TU_ATTR_ALWAYS_INLINE static inline void fifo_reset(musb_regs_t* musb, unsigned epnum, unsigned dir_in) { + const uint8_t is_rx = 1 - dir_in; + musb->index = epnum; musb->fifo_size[is_rx] = 0; musb->fifo_addr[is_rx] = 0; -#elif defined(TUP_USBIP_MUSB_ADI) +} + +TU_ATTR_ALWAYS_INLINE static inline bool fifo_configure(musb_regs_t* musb, unsigned epnum, unsigned dir_in, unsigned mps) { + // ffsize is log2(mps) - 3 (round up) + uint8_t ffsize = 28 - tu_min8(28, __builtin_clz(mps)); + // round up to the next power of 2 + if ((8u << ffsize) < mps) { + ++ffsize; + mps = 8 << ffsize; + } + + TU_ASSERT(alloced_fifo_bytes + mps <= MUSB_CFG_DYNAMIC_FIFO_SIZE); + const uint8_t is_rx = 1 - dir_in; + musb->index = epnum; + musb->fifo_addr[is_rx] = alloced_fifo_bytes / 8; + musb->fifo_size[is_rx] = ffsize; + + alloced_fifo_bytes += mps; + + return true; +} + +#else +TU_ATTR_ALWAYS_INLINE static inline void fifo_reset(musb_regs_t* musb, unsigned epnum, unsigned dir_in) { + const uint8_t is_rx = 1 - dir_in; + musb->index = epnum; + + #if defined(TUP_USBIP_MUSB_ADI) // Analog have custom double buffered in csrh register, disable it musb->indexed_csr.maxp_csr[is_rx].csrh |= MUSB_CSRH_DISABLE_DOUBLE_PACKET(is_rx); -#endif + #else + // disable double bufeffered in extended register + #endif } +TU_ATTR_ALWAYS_INLINE static inline bool fifo_configure(musb_regs_t* musb, unsigned epnum, unsigned dir_in, unsigned mps) { + (void) mps; + const uint8_t is_rx = 1 - dir_in; + musb->index = epnum; + + uint8_t csrh = 0; + +#if defined(TUP_USBIP_MUSB_ADI) + csrh = MUSB_CSRH_DISABLE_DOUBLE_PACKET(is_rx); +#endif + +#if MUSB_CFG_SHARED_FIFO + if (dir_in) { + csrh |= MUSB_CSRH_TX_MODE; + } +#endif + + musb->indexed_csr.maxp_csr[is_rx].csrh |= csrh; + + return true; +} + +#endif + static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) { volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; @@ -463,6 +521,11 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) // faddr = 0, index = 0, flushes all ep fifos, clears all ep csr, enabled all ep interrupts static void process_bus_reset(uint8_t rhport) { musb_regs_t* musb = MUSB_REGS(rhport); + +#if MUSB_CFG_DYNAMIC_FIFO + alloced_fifo_bytes = CFG_TUD_ENDPOINT0_SIZE; +#endif + /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), a control transfer state is SETUP or STATUS stage. */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; _dcd.status_out = 0; @@ -594,8 +657,8 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) pipe->length = 0; pipe->remaining = 0; - musb_regs_t* musb_regs = MUSB_REGS(rhport); - musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); + musb_regs_t* musb = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn); const uint8_t is_rx = 1 - dir_in; ep_csr->maxp_csr[is_rx].maxp = mps; @@ -606,10 +669,10 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) csrl |= MUSB_CSRL_FLUSH_FIFO(is_rx); } ep_csr->maxp_csr[is_rx].csrl = csrl; - musb_regs->intren_ep[is_rx] |= TU_BIT(epn); + musb->intren_ep[is_rx] |= TU_BIT(epn); /* Setup FIFO */ - musb_dcd_setup_fifo(rhport, epn, dir_in, mps); + fifo_configure(musb, epn, dir_in, mps); return true; } @@ -619,6 +682,7 @@ void dcd_edpt_close_all(uint8_t rhport) musb_regs_t* musb = MUSB_REGS(rhport); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); + musb->intr_txen = 1; /* Enable only EP0 */ musb->intr_rxen = 0; for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { @@ -640,13 +704,15 @@ void dcd_edpt_close_all(uint8_t rhport) fifo_reset(musb, i, 0); fifo_reset(musb, i, 1); - } + alloced_fifo_bytes = CFG_TUD_ENDPOINT0_SIZE; + if (ie) musb_dcd_int_enable(rhport); } void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + // FIXME: we should implement iso_alloc() and iso_activate() unsigned const epn = tu_edpt_number(ep_addr); unsigned const dir_in = tu_edpt_dir(ep_addr); musb_regs_t* musb = MUSB_REGS(rhport); diff --git a/src/portable/mentor/musb/musb_max32.h b/src/portable/mentor/musb/musb_max32.h index 73f63ee2e..1320239c9 100644 --- a/src/portable/mentor/musb/musb_max32.h +++ b/src/portable/mentor/musb/musb_max32.h @@ -34,7 +34,8 @@ extern "C" { #include "mxc_device.h" #include "usbhs_regs.h" -#define MUSB_CFG_DYNAMIC_FIFO 0 +#define MUSB_CFG_SHARED_FIFO 1 // shared FIFO for TX and RX endpoints +#define MUSB_CFG_DYNAMIC_FIFO 0 // dynamic EP FIFO sizing const uintptr_t MUSB_BASES[] = { MXC_BASE_USBHS }; @@ -141,24 +142,24 @@ static inline void musb_dcd_phy_init(uint8_t rhport) { hs_phy->m31_phy_ponrst = 1; } -static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) { - (void) mps; - - //Most likely the caller has already grabbed the right register block. But - //as a precaution save and restore the register bank anyways - unsigned saved_index = musb_periph_inst[rhport]->index; - - musb_periph_inst[rhport]->index = epnum; - - //Disable double buffering - if (dir_in) { - musb_periph_inst[rhport]->incsru |= (MXC_F_USBHS_INCSRU_DPKTBUFDIS | MXC_F_USBHS_INCSRU_MODE); - } else { - musb_periph_inst[rhport]->outcsru |= (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS); - } - - musb_periph_inst[rhport]->index = saved_index; -} +// static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) { +// (void) mps; +// +// //Most likely the caller has already grabbed the right register block. But +// //as a precaution save and restore the register bank anyways +// unsigned saved_index = musb_periph_inst[rhport]->index; +// +// musb_periph_inst[rhport]->index = epnum; +// +// //Disable double buffering +// if (dir_in) { +// musb_periph_inst[rhport]->incsru |= (MXC_F_USBHS_INCSRU_DPKTBUFDIS | MXC_F_USBHS_INCSRU_MODE); +// } else { +// musb_periph_inst[rhport]->outcsru |= (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS); +// } +// +// musb_periph_inst[rhport]->index = saved_index; +// } #endif // CFG_TUD_ENABLED diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h index e43b3d3c0..7c15b61ad 100644 --- a/src/portable/mentor/musb/musb_ti.h +++ b/src/portable/mentor/musb/musb_ti.h @@ -42,6 +42,7 @@ #error "Unsupported MCUs" #endif +#define MUSB_CFG_SHARED_FIFO 0 #define MUSB_CFG_DYNAMIC_FIFO 1 #define MUSB_CFG_DYNAMIC_FIFO_SIZE 4096 @@ -91,6 +92,7 @@ static inline void musb_dcd_int_handler_exit(uint8_t rhport) { //Nothing to do for this part } +#if 0 typedef struct { uint_fast16_t beg; /* offset of including first element */ uint_fast16_t end; /* offset of excluding the last element */ @@ -224,6 +226,7 @@ static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned musb_periph_inst[rhport]->RXFIFOSZ = size_in_log2_minus3; } } +#endif #endif // CFG_TUD_ENABLED diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index ee0187270..08f26edbd 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -261,7 +261,7 @@ typedef struct TU_ATTR_PACKED { //------------- Non-Indexed Endpoint CSRs -------------// // TI tm4c can access this directly, but should use indexed_csr for portability - musb_ep_csr_t ep_csr[16]; // 0x100-0x1FF: EP0-15 CSR + musb_ep_csr_t abs_csr[16]; // 0x100-0x1FF: EP0-15 CSR } musb_regs_t; TU_VERIFY_STATIC(sizeof(musb_regs_t) == 0x200, "size is not correct"); @@ -307,6 +307,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // 0x13, 0x17: TX/RX CSRH #define MUSB_CSRH_DISABLE_DOUBLE_PACKET(_rx) (1u << 1) +#define MUSB_CSRH_TX_MODE (1u << 5) // 1 = TX, 0 = RX. only relevant for SHARED FIFO //*****************************************************************************