From 9cf633f4e91194f5ed01d98355360d070008d313 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 Mar 2026 21:25:32 +0700 Subject: [PATCH] remove expensive div in HWFIFO_ADDR_NEXT_N() --- src/common/tusb_fifo.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index 991ee18ff..06d25d131 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -110,7 +110,7 @@ void tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable) { // Can support multiple i.e both 16 and 32-bit data access if needed //--------------------------------------------------------------------+ #if CFG_TUSB_FIFO_HWFIFO_API - #if CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE + #if CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE > 0 #define HWFIFO_ADDR_NEXT_N(_hwfifo, _const, _n) _hwfifo = (_const volatile void *)((uintptr_t)(_hwfifo) + _n) #else #define HWFIFO_ADDR_NEXT_N(_hwfifo, _const, _n) @@ -118,6 +118,9 @@ void tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable) { #define HWFIFO_ADDR_NEXT(_hwfifo, _const) HWFIFO_ADDR_NEXT_N(_hwfifo, _const, CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE) + // the fixed ratio works since in the only case of dynamic/multiple data_stride (rusb2): addr_stride is 0 + #define HWFIFO_ADDR_DATA_RATIO (CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE / CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE) + //------------- Write -------------// #ifndef CFG_TUSB_FIFO_HWFIFO_CUSTOM_WRITE TU_ATTR_ALWAYS_INLINE static inline void stride_write(volatile void *hwfifo, const void *src, uint8_t data_stride) { @@ -235,16 +238,16 @@ void tu_hwfifo_read(const volatile void *hwfifo, uint8_t *dest, uint16_t len, co len -= 2; HWFIFO_ADDR_NEXT_N(hwfifo, const, 2); } - #endif + #endif - #ifdef CFG_TUSB_FIFO_HWFIFO_DATA_ODD_8BIT_ACCESS + #ifdef CFG_TUSB_FIFO_HWFIFO_DATA_ODD_8BIT_ACCESS // 8-bit access is allowed for odd bytes while (len > 0) { *dest++ = *((const volatile uint8_t *)hwfifo); len--; HWFIFO_ADDR_NEXT_N(hwfifo, const, 1); } - #else + #else // Read odd bytes i.e 1 byte for 16 bit or 1-3 bytes for 32 bit if (len > 0) { uint32_t tmp; @@ -252,7 +255,7 @@ void tu_hwfifo_read(const volatile void *hwfifo, uint8_t *dest, uint16_t len, co memcpy(dest, &tmp, len); HWFIFO_ADDR_NEXT(hwfifo, const); } - #endif + #endif #endif } #endif @@ -275,15 +278,15 @@ static void hwff_push_n(const tu_fifo_t *f, const void *app_buf, uint16_t n, uin HWFIFO_ADDR_NEXT_N(hwfifo, const, lin_bytes); tu_hwfifo_read(hwfifo, f->buffer, wrap_bytes, access_mode); // wrapped part #else - // Write full words to linear part of buffer + // Write full words to the linear part of the buffer const uint8_t data_stride = access_mode->data_stride; const uint32_t odd_mask = data_stride - 1; uint16_t lin_even = lin_bytes & ~odd_mask; tu_hwfifo_read(hwfifo, ff_buf, lin_even, access_mode); - HWFIFO_ADDR_NEXT_N(hwfifo, const, (lin_even / data_stride) * CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE); + HWFIFO_ADDR_NEXT_N(hwfifo, const, lin_even * HWFIFO_ADDR_DATA_RATIO); ff_buf += lin_even; - // There could be odd 1 byte (16bit) or 1-3 bytes (32bit) before the wrap-around boundary + // There could be an odd 1 byte (16bit) or 1-3 bytes (32bit) before the wrap-around boundary // combine it with the wrapped part to form a full word for data stride const uint8_t lin_odd = lin_bytes & odd_mask; if (lin_odd > 0) { @@ -337,7 +340,7 @@ static void hwff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t const uint32_t odd_mask = data_stride - 1; uint16_t lin_even = lin_bytes & ~odd_mask; tu_hwfifo_write(hwfifo, ff_buf, lin_even, access_mode); - HWFIFO_ADDR_NEXT_N(hwfifo, , (lin_even / data_stride) * CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE); + HWFIFO_ADDR_NEXT_N(hwfifo, , lin_even * HWFIFO_ADDR_DATA_RATIO); ff_buf += lin_even; // There could be odd 1 byte (16bit) or 1-3 bytes (32bit) before the wrap-around boundary