summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhathach <[email protected]>2023-07-07 12:27:18 +0700
committerhathach <[email protected]>2023-07-07 12:27:18 +0700
commit4c156100fafa682407f1a9a459d8b8800a029446 (patch)
tree3ac906f69a3193821a3719e330721ecb1afbb69c
parent4bbacb10089856fd6cd6e4c54da8ab2dc8575c60 (diff)
use unaligned access read for hw fifo
-rw-r--r--src/common/tusb_common.h18
-rw-r--r--src/common/tusb_mcu.h12
-rw-r--r--src/portable/renesas/rusb2/dcd_rusb2.c77
3 files changed, 71 insertions, 36 deletions
diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h
index 957491aa9..576cb123f 100644
--- a/src/common/tusb_common.h
+++ b/src/common/tusb_common.h
@@ -260,11 +260,21 @@ TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16(void* mem, uint16_
#else
// MCU that could access unaligned memory natively
-TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_unaligned_read32 (const void* mem) { return *((uint32_t const *) mem); }
-TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_unaligned_read16 (const void* mem) { return *((uint16_t const *) mem); }
+TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_unaligned_read32(const void *mem) {
+ return *((uint32_t const *) mem);
+}
+
+TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_unaligned_read16(const void *mem) {
+ return *((uint16_t const *) mem);
+}
-TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write32 (void* mem, uint32_t value ) { *((uint32_t*) mem) = value; }
-TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16 (void* mem, uint16_t value ) { *((uint16_t*) mem) = value; }
+TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write32(void *mem, uint32_t value) {
+ *((uint32_t *) mem) = value;
+}
+
+TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16(void *mem, uint16_t value) {
+ *((uint16_t *) mem) = value;
+}
#endif
diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h
index 496ebfc85..89f89182e 100644
--- a/src/common/tusb_mcu.h
+++ b/src/common/tusb_mcu.h
@@ -34,10 +34,16 @@
//------------- Unaligned Memory Access -------------//
-// ARMv7+ (M3-M7, M23-M33) can access unaligned memory
-#if (defined(__ARM_ARCH) && (__ARM_ARCH >= 7))
- #define TUP_ARCH_STRICT_ALIGN 0
+#ifdef __ARM_ARCH
+ // ARM Architecture set __ARM_FEATURE_UNALIGNED to 1 for mcu supports unaligned access
+ #if defined(__ARM_FEATURE_UNALIGNED) && __ARM_FEATURE_UNALIGNED == 1
+ #define TUP_ARCH_STRICT_ALIGN 0
+ #else
+ #define TUP_ARCH_STRICT_ALIGN 1
+ #endif
#else
+ // TODO default to strict align for others
+ // Should investigate other architecture such as risv, xtensa, mips for optimal setting
#define TUP_ARCH_STRICT_ALIGN 1
#endif
diff --git a/src/portable/renesas/rusb2/dcd_rusb2.c b/src/portable/renesas/rusb2/dcd_rusb2.c
index 81b60b3bc..464929224 100644
--- a/src/portable/renesas/rusb2/dcd_rusb2.c
+++ b/src/portable/renesas/rusb2/dcd_rusb2.c
@@ -220,6 +220,11 @@ static inline void pipe_wait_for_ready(rusb2_reg_t * rusb, unsigned num)
while ( !rusb->D0FIFOCTR_b.FRDY ) {}
}
+//--------------------------------------------------------------------+
+// Pipe FIFO
+//--------------------------------------------------------------------+
+
+// Write data buffer --> hw fifo
static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len)
{
#if (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE)
@@ -228,54 +233,68 @@ static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len)
volatile hw_fifo16_t *reg = (volatile hw_fifo16_t*) fifo;
#endif
- uintptr_t addr = (uintptr_t)buf;
+ uint8_t const* buf8 = (uint8_t const*) buf;
while (len >= 2) {
- reg->u16 = *(const uint16_t *)addr;
- addr += 2;
+ reg->u16 = tu_unaligned_read16(buf8);
+ buf8 += 2;
len -= 2;
}
if (len > 0) {
- reg->u8 = *(const uint8_t *)addr;
- ++addr;
+ reg->u8 = *buf8;
+ ++buf8;
}
}
+// Read data buffer <-- hw fifo
static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len)
{
- uint8_t *p = (uint8_t*)buf;
+ uint8_t *p = (uint8_t*)buf;
volatile uint8_t *reg = (volatile uint8_t*)fifo; /* byte access is always at base register address */
while (len--) *p++ = *reg;
}
-static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigned len, unsigned dir)
-{
- static const struct {
- void (*tu_fifo_get_info)(tu_fifo_t *f, tu_fifo_buffer_info_t *info);
- void (*tu_fifo_advance)(tu_fifo_t *f, uint16_t n);
- void (*pipe_read_write)(void *buf, volatile void *fifo, unsigned len);
- } ops[] = {
- /* OUT */ {tu_fifo_get_write_info,tu_fifo_advance_write_pointer,pipe_read_packet},
- /* IN */ {tu_fifo_get_read_info, tu_fifo_advance_read_pointer, pipe_write_packet},
- };
+// Write data sw fifo --> hw fifo
+static void pipe_write_packet_ff(tu_fifo_t *f, volatile void *fifo, uint16_t total_len) {
+ tu_fifo_buffer_info_t info;
+ tu_fifo_get_read_info(f, &info);
+
+ uint16_t count = tu_min16(total_len, info.len_lin);
+ pipe_write_packet(info.ptr_lin, fifo, count);
+
+ uint16_t rem = total_len - count;
+ if (rem) {
+ rem = tu_min16(rem, info.len_wrap);
+ pipe_write_packet(info.ptr_wrap, fifo, rem);
+ count += rem;
+ }
+
+ tu_fifo_advance_read_pointer(f, count);
+}
+// Read data sw fifo <-- hw fifo
+static void pipe_read_packet_ff(tu_fifo_t *f, volatile void *fifo, uint16_t total_len) {
tu_fifo_buffer_info_t info;
- ops[dir].tu_fifo_get_info(f, &info);
+ tu_fifo_get_write_info(f, &info);
- unsigned total_len = len;
- len = TU_MIN(total_len, info.len_lin);
- ops[dir].pipe_read_write(info.ptr_lin, fifo, len);
+ uint16_t count = tu_min16(total_len, info.len_lin);
+ pipe_read_packet(info.ptr_lin, fifo, count);
- unsigned rem = total_len - len;
+ uint16_t rem = total_len - count;
if (rem) {
- len = TU_MIN(rem, info.len_wrap);
- ops[dir].pipe_read_write(info.ptr_wrap, fifo, len);
- rem -= len;
+ rem = tu_min16(rem, info.len_wrap);
+ pipe_read_packet(info.ptr_wrap, fifo, rem);
+ count += rem;
}
- ops[dir].tu_fifo_advance(f, total_len - rem);
+
+ tu_fifo_advance_write_pointer(f, count);
}
+//--------------------------------------------------------------------+
+// Pipe Transfer
+//--------------------------------------------------------------------+
+
static bool pipe0_xfer_in(rusb2_reg_t* rusb)
{
pipe_state_t *pipe = &_dcd.pipe[0];
@@ -292,7 +311,7 @@ static bool pipe0_xfer_in(rusb2_reg_t* rusb)
if (len) {
if (pipe->ff) {
- pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&rusb->CFIFO, len, TUSB_DIR_IN);
+ pipe_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&rusb->CFIFO, len);
} else {
pipe_write_packet(buf, (volatile void*)&rusb->CFIFO, len);
pipe->buf = (uint8_t*)buf + len;
@@ -319,7 +338,7 @@ static bool pipe0_xfer_out(rusb2_reg_t* rusb)
if (len) {
if (pipe->ff) {
- pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&rusb->CFIFO, len, TUSB_DIR_OUT);
+ pipe_read_packet_ff((tu_fifo_t*)buf, (volatile void*)&rusb->CFIFO, len);
} else {
pipe_read_packet(buf, (volatile void*)&rusb->CFIFO, len);
pipe->buf = (uint8_t*)buf + len;
@@ -357,7 +376,7 @@ static bool pipe_xfer_in(rusb2_reg_t* rusb, unsigned num)
if (len) {
if (pipe->ff) {
- pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&rusb->D0FIFO, len, TUSB_DIR_IN);
+ pipe_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&rusb->D0FIFO, len);
} else {
pipe_write_packet(buf, (volatile void*)&rusb->D0FIFO, len);
pipe->buf = (uint8_t*)buf + len;
@@ -391,7 +410,7 @@ static bool pipe_xfer_out(rusb2_reg_t* rusb, unsigned num)
if (len) {
if (pipe->ff) {
- pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&rusb->D0FIFO, len, TUSB_DIR_OUT);
+ pipe_read_packet_ff((tu_fifo_t*)buf, (volatile void*)&rusb->D0FIFO, len);
} else {
pipe_read_packet(buf, (volatile void*)&rusb->D0FIFO, len);
pipe->buf = (uint8_t*)buf + len;