use unaligned access read for hw fifo
This commit is contained in:
		@@ -260,11 +260,21 @@ TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16(void* mem, uint16_
 | 
				
			|||||||
#else
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MCU that could access unaligned memory natively
 | 
					// 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 uint32_t tu_unaligned_read32(const void *mem) {
 | 
				
			||||||
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_unaligned_read16  (const void* mem) { return *((uint16_t const *) mem); }
 | 
					  return *((uint32_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 uint16_t tu_unaligned_read16(const void *mem) {
 | 
				
			||||||
TU_ATTR_ALWAYS_INLINE static inline void     tu_unaligned_write16 (void* mem, uint16_t value ) { *((uint16_t*) mem) = value; }
 | 
					  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;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -34,10 +34,16 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
//------------- Unaligned Memory Access -------------//
 | 
					//------------- Unaligned Memory Access -------------//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ARMv7+ (M3-M7, M23-M33) can access unaligned memory
 | 
					#ifdef __ARM_ARCH
 | 
				
			||||||
#if (defined(__ARM_ARCH) && (__ARM_ARCH >= 7))
 | 
					  // ARM Architecture set __ARM_FEATURE_UNALIGNED to 1 for mcu supports unaligned access
 | 
				
			||||||
  #define TUP_ARCH_STRICT_ALIGN   0
 | 
					  #if defined(__ARM_FEATURE_UNALIGNED) && __ARM_FEATURE_UNALIGNED == 1
 | 
				
			||||||
 | 
					    #define TUP_ARCH_STRICT_ALIGN   0
 | 
				
			||||||
 | 
					  #else
 | 
				
			||||||
 | 
					    #define TUP_ARCH_STRICT_ALIGN   1
 | 
				
			||||||
 | 
					  #endif
 | 
				
			||||||
#else
 | 
					#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
 | 
					  #define TUP_ARCH_STRICT_ALIGN   1
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -220,6 +220,11 @@ static inline void pipe_wait_for_ready(rusb2_reg_t * rusb, unsigned num)
 | 
				
			|||||||
  while ( !rusb->D0FIFOCTR_b.FRDY ) {}
 | 
					  while ( !rusb->D0FIFOCTR_b.FRDY ) {}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//--------------------------------------------------------------------+
 | 
				
			||||||
 | 
					// Pipe FIFO
 | 
				
			||||||
 | 
					//--------------------------------------------------------------------+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Write data buffer --> hw fifo
 | 
				
			||||||
static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len)
 | 
					static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#if (CFG_TUSB_RHPORT1_MODE & OPT_MODE_DEVICE)
 | 
					#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;
 | 
					  volatile hw_fifo16_t *reg = (volatile hw_fifo16_t*) fifo;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  uintptr_t addr = (uintptr_t)buf;
 | 
					  uint8_t const* buf8 = (uint8_t const*) buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  while (len >= 2) {
 | 
					  while (len >= 2) {
 | 
				
			||||||
    reg->u16 = *(const uint16_t *)addr;
 | 
					    reg->u16 = tu_unaligned_read16(buf8);
 | 
				
			||||||
    addr += 2;
 | 
					    buf8 += 2;
 | 
				
			||||||
    len  -= 2;
 | 
					    len  -= 2;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (len > 0) {
 | 
					  if (len > 0) {
 | 
				
			||||||
    reg->u8 = *(const uint8_t *)addr;
 | 
					    reg->u8 = *buf8;
 | 
				
			||||||
    ++addr;
 | 
					    ++buf8;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Read data buffer <-- hw fifo
 | 
				
			||||||
static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len)
 | 
					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 */
 | 
					  volatile uint8_t *reg = (volatile uint8_t*)fifo;  /* byte access is always at base register address */
 | 
				
			||||||
  while (len--) *p++ = *reg;
 | 
					  while (len--) *p++ = *reg;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigned len, unsigned dir)
 | 
					// Write data sw fifo --> hw fifo
 | 
				
			||||||
{
 | 
					static void pipe_write_packet_ff(tu_fifo_t *f, volatile void *fifo, uint16_t total_len) {
 | 
				
			||||||
  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},
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  tu_fifo_buffer_info_t info;
 | 
					  tu_fifo_buffer_info_t info;
 | 
				
			||||||
  ops[dir].tu_fifo_get_info(f, &info);
 | 
					  tu_fifo_get_read_info(f, &info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  unsigned total_len = len;
 | 
					  uint16_t count = tu_min16(total_len, info.len_lin);
 | 
				
			||||||
  len = TU_MIN(total_len, info.len_lin);
 | 
					  pipe_write_packet(info.ptr_lin, fifo, count);
 | 
				
			||||||
  ops[dir].pipe_read_write(info.ptr_lin, fifo, len);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  unsigned rem = total_len - len;
 | 
					  uint16_t rem = total_len - count;
 | 
				
			||||||
  if (rem) {
 | 
					  if (rem) {
 | 
				
			||||||
    len = TU_MIN(rem, info.len_wrap);
 | 
					    rem = tu_min16(rem, info.len_wrap);
 | 
				
			||||||
    ops[dir].pipe_read_write(info.ptr_wrap, fifo, len);
 | 
					    pipe_write_packet(info.ptr_wrap, fifo, rem);
 | 
				
			||||||
    rem -= len;
 | 
					    count += rem;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  ops[dir].tu_fifo_advance(f, total_len - 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;
 | 
				
			||||||
 | 
					  tu_fifo_get_write_info(f, &info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  uint16_t count = tu_min16(total_len, info.len_lin);
 | 
				
			||||||
 | 
					  pipe_read_packet(info.ptr_lin, fifo, count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  uint16_t rem = total_len - count;
 | 
				
			||||||
 | 
					  if (rem) {
 | 
				
			||||||
 | 
					    rem = tu_min16(rem, info.len_wrap);
 | 
				
			||||||
 | 
					    pipe_read_packet(info.ptr_wrap, fifo, rem);
 | 
				
			||||||
 | 
					    count += rem;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  tu_fifo_advance_write_pointer(f, count);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//--------------------------------------------------------------------+
 | 
				
			||||||
 | 
					// Pipe Transfer
 | 
				
			||||||
 | 
					//--------------------------------------------------------------------+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool pipe0_xfer_in(rusb2_reg_t* rusb)
 | 
					static bool pipe0_xfer_in(rusb2_reg_t* rusb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  pipe_state_t *pipe = &_dcd.pipe[0];
 | 
					  pipe_state_t *pipe = &_dcd.pipe[0];
 | 
				
			||||||
@@ -292,7 +311,7 @@ static bool pipe0_xfer_in(rusb2_reg_t* rusb)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  if (len) {
 | 
					  if (len) {
 | 
				
			||||||
    if (pipe->ff) {
 | 
					    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 {
 | 
					    } else {
 | 
				
			||||||
      pipe_write_packet(buf, (volatile void*)&rusb->CFIFO, len);
 | 
					      pipe_write_packet(buf, (volatile void*)&rusb->CFIFO, len);
 | 
				
			||||||
      pipe->buf = (uint8_t*)buf + len;
 | 
					      pipe->buf = (uint8_t*)buf + len;
 | 
				
			||||||
@@ -319,7 +338,7 @@ static bool pipe0_xfer_out(rusb2_reg_t* rusb)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  if (len) {
 | 
					  if (len) {
 | 
				
			||||||
    if (pipe->ff) {
 | 
					    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 {
 | 
					    } else {
 | 
				
			||||||
      pipe_read_packet(buf, (volatile void*)&rusb->CFIFO, len);
 | 
					      pipe_read_packet(buf, (volatile void*)&rusb->CFIFO, len);
 | 
				
			||||||
      pipe->buf = (uint8_t*)buf + 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 (len) {
 | 
				
			||||||
    if (pipe->ff) {
 | 
					    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 {
 | 
					    } else {
 | 
				
			||||||
      pipe_write_packet(buf, (volatile void*)&rusb->D0FIFO, len);
 | 
					      pipe_write_packet(buf, (volatile void*)&rusb->D0FIFO, len);
 | 
				
			||||||
      pipe->buf = (uint8_t*)buf + 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 (len) {
 | 
				
			||||||
    if (pipe->ff) {
 | 
					    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 {
 | 
					    } else {
 | 
				
			||||||
      pipe_read_packet(buf, (volatile void*)&rusb->D0FIFO, len);
 | 
					      pipe_read_packet(buf, (volatile void*)&rusb->D0FIFO, len);
 | 
				
			||||||
      pipe->buf = (uint8_t*)buf + len;
 | 
					      pipe->buf = (uint8_t*)buf + len;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user