mirror of
https://github.com/hathach/tinyusb.git
synced 2026-03-21 15:05:15 +00:00
add tu_hwfifo_access_t param to hwfifo API
This commit is contained in:
@ -147,8 +147,9 @@ static void stride_read(const volatile void *hwfifo, void *dest, uint8_t data_st
|
||||
#endif
|
||||
}
|
||||
|
||||
void tu_hwfifo_read(const volatile void *hwfifo, uint8_t *dest, uint16_t len, uint8_t data_stride) {
|
||||
void tu_hwfifo_read(const volatile void *hwfifo, uint8_t *dest, uint16_t len, const tu_hwfifo_access_t *access_mode) {
|
||||
// Reading full available 16/32-bit hwfifo and write to fifo
|
||||
const uint8_t data_stride = access_mode->data_stride;
|
||||
while (len >= data_stride) {
|
||||
stride_read(hwfifo, dest, data_stride);
|
||||
dest += data_stride;
|
||||
@ -159,23 +160,16 @@ void tu_hwfifo_read(const volatile void *hwfifo, uint8_t *dest, uint16_t len, ui
|
||||
|
||||
// Read odd bytes i.e 1 byte for 16 bit or 1-3 bytes for 32 bit
|
||||
if (len > 0) {
|
||||
#ifdef CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE_ODD_BYTE_SUPPORT
|
||||
// odd byte access, read byte per byte e.g for rusb2. No address stride needed
|
||||
const volatile uint8_t *src8 = (const volatile uint8_t *)hwfifo;
|
||||
for (uint16_t i = 0; i < len; ++i) {
|
||||
dest[i] = *(src8 + 3);
|
||||
}
|
||||
#else
|
||||
uint32_t tmp;
|
||||
stride_read(hwfifo, &tmp, data_stride);
|
||||
memcpy(dest, &tmp, len);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Copy from fifo to fixed address buffer (usually a tx register) with TU_FIFO_FIXED_ADDR_RW32 mode
|
||||
void tu_hwfifo_write(volatile void *hwfifo, const uint8_t *src, uint16_t len, uint8_t data_stride) {
|
||||
void tu_hwfifo_write(volatile void *hwfifo, const uint8_t *src, uint16_t len, const tu_hwfifo_access_t *access_mode) {
|
||||
// Write full available 16/32 bit words to dest
|
||||
const uint8_t data_stride = access_mode->data_stride;
|
||||
while (len >= data_stride) {
|
||||
stride_write(hwfifo, src, data_stride);
|
||||
src += data_stride;
|
||||
@ -186,21 +180,14 @@ void tu_hwfifo_write(volatile void *hwfifo, const uint8_t *src, uint16_t len, ui
|
||||
|
||||
// Write odd bytes i.e 1 byte for 16 bit or 1-3 bytes for 32 bit
|
||||
if (len > 0) {
|
||||
#ifdef CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE_ODD_BYTE_SUPPORT
|
||||
// odd byte access, write byte per byte e.g for rusb2. No address stride needed
|
||||
volatile uint8_t *dest8 = (volatile uint8_t *)hwfifo;
|
||||
for (uint16_t i = 0; i < len; ++i) {
|
||||
*(dest8 + 3) = src[i];
|
||||
}
|
||||
#else
|
||||
uint32_t tmp = 0u;
|
||||
memcpy(&tmp, src, len);
|
||||
stride_write(hwfifo, &tmp, data_stride);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void hwff_push_n(const tu_fifo_t *f, const void *app_buf, uint16_t n, uint16_t wr_ptr, uint8_t data_stride) {
|
||||
static void hwff_push_n(const tu_fifo_t *f, const void *app_buf, uint16_t n, uint16_t wr_ptr,
|
||||
const tu_hwfifo_access_t *access_mode) {
|
||||
uint16_t lin_bytes = f->depth - wr_ptr;
|
||||
uint16_t wrap_bytes = n - lin_bytes;
|
||||
uint8_t *ff_buf = f->buffer + wr_ptr;
|
||||
@ -208,14 +195,15 @@ static void hwff_push_n(const tu_fifo_t *f, const void *app_buf, uint16_t n, uin
|
||||
const volatile void *hwfifo = (const volatile void *)app_buf;
|
||||
if (n <= lin_bytes) {
|
||||
// Linear only case
|
||||
tu_hwfifo_read(hwfifo, ff_buf, n, data_stride);
|
||||
tu_hwfifo_read(hwfifo, ff_buf, n, access_mode);
|
||||
} else {
|
||||
// Wrap around case
|
||||
|
||||
// Write full words to linear part of buffer
|
||||
const uint32_t odd_mask = data_stride - 1;
|
||||
uint16_t lin_even = lin_bytes & ~odd_mask;
|
||||
tu_hwfifo_read(hwfifo, ff_buf, lin_even, data_stride);
|
||||
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);
|
||||
ff_buf += lin_even;
|
||||
|
||||
// There could be odd 1 byte (16bit) or 1-3 bytes (32bit) before the wrap-around boundary
|
||||
@ -224,7 +212,7 @@ static void hwff_push_n(const tu_fifo_t *f, const void *app_buf, uint16_t n, uin
|
||||
if (lin_odd > 0) {
|
||||
const uint8_t wrap_odd = (uint8_t)tu_min16(wrap_bytes, data_stride - lin_odd);
|
||||
uint8_t buf_temp[4];
|
||||
tu_hwfifo_read(hwfifo, buf_temp, lin_odd + wrap_odd, data_stride);
|
||||
tu_hwfifo_read(hwfifo, buf_temp, lin_odd + wrap_odd, access_mode);
|
||||
|
||||
for (uint8_t i = 0; i < lin_odd; ++i) {
|
||||
ff_buf[i] = buf_temp[i];
|
||||
@ -241,12 +229,13 @@ static void hwff_push_n(const tu_fifo_t *f, const void *app_buf, uint16_t n, uin
|
||||
|
||||
// Write data wrapped part
|
||||
if (wrap_bytes > 0) {
|
||||
tu_hwfifo_read(hwfifo, ff_buf, wrap_bytes, data_stride);
|
||||
tu_hwfifo_read(hwfifo, ff_buf, wrap_bytes, access_mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void hwff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t rd_ptr, uint8_t data_stride) {
|
||||
static void hwff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t rd_ptr,
|
||||
const tu_hwfifo_access_t *access_mode) {
|
||||
uint16_t lin_bytes = f->depth - rd_ptr;
|
||||
uint16_t wrap_bytes = n - lin_bytes; // only used if wrapped
|
||||
const uint8_t *ff_buf = f->buffer + rd_ptr;
|
||||
@ -255,14 +244,15 @@ static void hwff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t
|
||||
|
||||
if (n <= lin_bytes) {
|
||||
// Linear only case
|
||||
tu_hwfifo_write(hwfifo, ff_buf, n, data_stride);
|
||||
tu_hwfifo_write(hwfifo, ff_buf, n, access_mode);
|
||||
} else {
|
||||
// Wrap around case
|
||||
|
||||
// Read full words from linear part
|
||||
const uint32_t odd_mask = data_stride - 1;
|
||||
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_write(hwfifo, ff_buf, lin_even, data_stride);
|
||||
tu_hwfifo_write(hwfifo, ff_buf, lin_even, access_mode);
|
||||
ff_buf += lin_even;
|
||||
|
||||
// There could be odd 1 byte (16bit) or 1-3 bytes (32bit) before the wrap-around boundary
|
||||
@ -278,7 +268,7 @@ static void hwff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t
|
||||
buf_temp[lin_odd + i] = f->buffer[i];
|
||||
}
|
||||
|
||||
tu_hwfifo_write(hwfifo, buf_temp, lin_odd + wrap_odd, data_stride);
|
||||
tu_hwfifo_write(hwfifo, buf_temp, lin_odd + wrap_odd, access_mode);
|
||||
|
||||
wrap_bytes -= wrap_odd;
|
||||
ff_buf = f->buffer + wrap_odd; // wrap around
|
||||
@ -288,7 +278,7 @@ static void hwff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t
|
||||
|
||||
// Read data wrapped part
|
||||
if (wrap_bytes > 0) {
|
||||
tu_hwfifo_write(hwfifo, ff_buf, wrap_bytes, data_stride);
|
||||
tu_hwfifo_write(hwfifo, ff_buf, wrap_bytes, access_mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -376,7 +366,7 @@ static uint16_t correct_read_index(tu_fifo_t *f, uint16_t wr_idx) {
|
||||
// Works on local copies of w and r
|
||||
// Must be protected by read mutex since in case of an overflow read pointer gets modified
|
||||
uint16_t tu_fifo_peek_n_access_mode(tu_fifo_t *f, void *p_buffer, uint16_t n, uint16_t wr_idx, uint16_t rd_idx,
|
||||
uint8_t data_stride) {
|
||||
const tu_hwfifo_access_t *access_mode) {
|
||||
uint16_t count = tu_ff_overflow_count(f->depth, wr_idx, rd_idx);
|
||||
if (count == 0) {
|
||||
return 0; // nothing to peek
|
||||
@ -395,8 +385,8 @@ uint16_t tu_fifo_peek_n_access_mode(tu_fifo_t *f, void *p_buffer, uint16_t n, ui
|
||||
const uint16_t rd_ptr = idx2ptr(f->depth, rd_idx);
|
||||
|
||||
#if CFG_TUSB_FIFO_HWFIFO_API
|
||||
if (data_stride > 0) {
|
||||
hwff_pull_n(f, p_buffer, n, rd_ptr, data_stride);
|
||||
if (access_mode != NULL) {
|
||||
hwff_pull_n(f, p_buffer, n, rd_ptr, access_mode);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
@ -409,17 +399,17 @@ uint16_t tu_fifo_peek_n_access_mode(tu_fifo_t *f, void *p_buffer, uint16_t n, ui
|
||||
// Read n items without removing it from the FIFO, correct read pointer if overflowed
|
||||
uint16_t tu_fifo_peek_n(tu_fifo_t *f, void *p_buffer, uint16_t n) {
|
||||
ff_lock(f->mutex_rd);
|
||||
const uint16_t ret = tu_fifo_peek_n_access_mode(f, p_buffer, n, f->wr_idx, f->rd_idx, 0);
|
||||
const uint16_t ret = tu_fifo_peek_n_access_mode(f, p_buffer, n, f->wr_idx, f->rd_idx, NULL);
|
||||
ff_unlock(f->mutex_rd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Read n items from fifo with access mode
|
||||
uint16_t tu_fifo_read_n_access_mode(tu_fifo_t *f, void *buffer, uint16_t n, uint8_t data_stride) {
|
||||
uint16_t tu_fifo_read_n_access_mode(tu_fifo_t *f, void *buffer, uint16_t n, const tu_hwfifo_access_t *access_mode) {
|
||||
ff_lock(f->mutex_rd);
|
||||
|
||||
// Peek the data: f->rd_idx might get modified in case of an overflow so we can not use a local variable
|
||||
n = tu_fifo_peek_n_access_mode(f, buffer, n, f->wr_idx, f->rd_idx, data_stride);
|
||||
n = tu_fifo_peek_n_access_mode(f, buffer, n, f->wr_idx, f->rd_idx, access_mode);
|
||||
f->rd_idx = advance_index(f->depth, f->rd_idx, n);
|
||||
|
||||
ff_unlock(f->mutex_rd);
|
||||
@ -427,7 +417,8 @@ uint16_t tu_fifo_read_n_access_mode(tu_fifo_t *f, void *buffer, uint16_t n, uint
|
||||
}
|
||||
|
||||
// Write n items to fifo with access mode
|
||||
uint16_t tu_fifo_write_n_access_mode(tu_fifo_t *f, const void *data, uint16_t n, uint8_t data_stride) {
|
||||
uint16_t tu_fifo_write_n_access_mode(tu_fifo_t *f, const void *data, uint16_t n,
|
||||
const tu_hwfifo_access_t *access_mode) {
|
||||
if (n == 0) {
|
||||
return 0;
|
||||
}
|
||||
@ -453,7 +444,7 @@ uint16_t tu_fifo_write_n_access_mode(tu_fifo_t *f, const void *data, uint16_t n,
|
||||
// function! Since it would end up in a race condition with read functions!
|
||||
if (n >= f->depth) {
|
||||
// Only copy last part
|
||||
if (!data_stride) {
|
||||
if (access_mode == NULL) {
|
||||
buf8 += (n - f->depth);
|
||||
} else {
|
||||
// TODO should read from hw fifo to discard data, however reading an odd number could
|
||||
@ -490,8 +481,8 @@ uint16_t tu_fifo_write_n_access_mode(tu_fifo_t *f, const void *data, uint16_t n,
|
||||
TU_LOG(TU_FIFO_DBG, "actual_n = %u, wr_ptr = %u", n, wr_ptr);
|
||||
|
||||
#if CFG_TUSB_FIFO_HWFIFO_API
|
||||
if (data_stride > 0) {
|
||||
hwff_push_n(f, buf8, n, wr_ptr, data_stride);
|
||||
if (access_mode != NULL) {
|
||||
hwff_push_n(f, buf8, n, wr_ptr, access_mode);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
|
||||
@ -138,6 +138,12 @@ typedef struct {
|
||||
} linear, wrapped;
|
||||
} tu_fifo_buffer_info_t;
|
||||
|
||||
// Access mode for hardware fifo read/write
|
||||
typedef struct {
|
||||
uint8_t data_stride;
|
||||
uintptr_t param;
|
||||
} tu_hwfifo_access_t;
|
||||
|
||||
#define TU_FIFO_INIT(_buffer, _depth, _overwritable) \
|
||||
{ \
|
||||
.buffer = _buffer, \
|
||||
@ -192,7 +198,7 @@ void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info);
|
||||
// peek() will correct/re-index read pointer in case of an overflowed fifo to form a full fifo
|
||||
//--------------------------------------------------------------------+
|
||||
uint16_t tu_fifo_peek_n_access_mode(tu_fifo_t *f, void *p_buffer, uint16_t n, uint16_t wr_idx, uint16_t rd_idx,
|
||||
uint8_t data_stride);
|
||||
const tu_hwfifo_access_t *access_mode);
|
||||
bool tu_fifo_peek(tu_fifo_t *f, void *p_buffer);
|
||||
uint16_t tu_fifo_peek_n(tu_fifo_t *f, void *p_buffer, uint16_t n);
|
||||
|
||||
@ -200,10 +206,10 @@ uint16_t tu_fifo_peek_n(tu_fifo_t *f, void *p_buffer, uint16_t n);
|
||||
// Read API
|
||||
// peek() + advance read index
|
||||
//--------------------------------------------------------------------+
|
||||
uint16_t tu_fifo_read_n_access_mode(tu_fifo_t *f, void *buffer, uint16_t n, uint8_t data_stride);
|
||||
uint16_t tu_fifo_read_n_access_mode(tu_fifo_t *f, void *buffer, uint16_t n, const tu_hwfifo_access_t *access_mode);
|
||||
bool tu_fifo_read(tu_fifo_t *f, void *buffer);
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_read_n(tu_fifo_t *f, void *buffer, uint16_t n) {
|
||||
return tu_fifo_read_n_access_mode(f, buffer, n, 0);
|
||||
return tu_fifo_read_n_access_mode(f, buffer, n, NULL);
|
||||
}
|
||||
|
||||
// discard first n items from fifo i.e advance read pointer by n with mutex
|
||||
@ -213,10 +219,10 @@ uint16_t tu_fifo_discard_n(tu_fifo_t *f, uint16_t n);
|
||||
//--------------------------------------------------------------------+
|
||||
// Write API
|
||||
//--------------------------------------------------------------------+
|
||||
uint16_t tu_fifo_write_n_access_mode(tu_fifo_t *f, const void *data, uint16_t n, uint8_t data_stride);
|
||||
uint16_t tu_fifo_write_n_access_mode(tu_fifo_t *f, const void *data, uint16_t n, const tu_hwfifo_access_t *access_mode);
|
||||
bool tu_fifo_write(tu_fifo_t *f, const void *data);
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_write_n(tu_fifo_t *f, const void *data, uint16_t n) {
|
||||
return tu_fifo_write_n_access_mode(f, data, n, 0);
|
||||
return tu_fifo_write_n_access_mode(f, data, n, NULL);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
@ -225,22 +231,22 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_write_n(tu_fifo_t *f, const
|
||||
// CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE (data width) and CFG_TUSB_FIFO_HWFIFO_ADDR_STRIDE (address increment)
|
||||
// Note: these usually has opposiite direction (read/write) to/from our software FIFO (tu_fifo_t)
|
||||
//--------------------------------------------------------------------+
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_hwfifo_write_from_fifo(volatile void *hwfifo, tu_fifo_t *f,
|
||||
uint16_t n) {
|
||||
return tu_fifo_read_n_access_mode(f, (void *)(uintptr_t)hwfifo, n, CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE);
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_hwfifo_write_from_fifo(volatile void *hwfifo, tu_fifo_t *f, uint16_t n,
|
||||
const tu_hwfifo_access_t *access_mode) {
|
||||
return tu_fifo_read_n_access_mode(f, (void *)(uintptr_t)hwfifo, n, access_mode);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_hwfifo_read_to_fifo(const volatile void *hwfifo, tu_fifo_t *f,
|
||||
uint16_t n) {
|
||||
return tu_fifo_write_n_access_mode(f, (const void *)(uintptr_t)hwfifo, n, CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE);
|
||||
uint16_t n, const tu_hwfifo_access_t *access_mode) {
|
||||
return tu_fifo_write_n_access_mode(f, (const void *)(uintptr_t)hwfifo, n, access_mode);
|
||||
}
|
||||
|
||||
#if CFG_TUSB_FIFO_HWFIFO_API
|
||||
// read from hwfifo to buffer
|
||||
void tu_hwfifo_read(const volatile void *hwfifo, uint8_t *dest, uint16_t len, uint8_t data_stride);
|
||||
void tu_hwfifo_read(const volatile void *hwfifo, uint8_t *dest, uint16_t len, const tu_hwfifo_access_t *access_mode);
|
||||
|
||||
// write to hwfifo from buffer with access mode
|
||||
void tu_hwfifo_write(volatile void *hwfifo, const uint8_t *src, uint16_t len, uint8_t data_stride);
|
||||
void tu_hwfifo_write(volatile void *hwfifo, const uint8_t *src, uint16_t len, const tu_hwfifo_access_t *access_mode);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@ -285,7 +285,8 @@ static void handle_ctr_setup(uint32_t ep_id) {
|
||||
uint16_t rx_addr = btable_get_addr(ep_id, BTABLE_BUF_RX);
|
||||
uint8_t setup_packet[8] TU_ATTR_ALIGNED(4);
|
||||
|
||||
tu_hwfifo_read(PMA_BUF_AT(rx_addr), setup_packet, rx_count);
|
||||
const tu_hwfifo_access_t access_mode = {.data_stride = CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE};
|
||||
tu_hwfifo_read(PMA_BUF_AT(rx_addr), setup_packet, rx_count, &access_mode);
|
||||
|
||||
// Clear CTR RX if another setup packet arrived before this, it will be discarded
|
||||
ep_write_clear_ctr(ep_id, TUSB_DIR_OUT);
|
||||
@ -323,10 +324,11 @@ static void handle_ctr_rx(uint32_t ep_id) {
|
||||
uint16_t pma_addr = (uint16_t) btable_get_addr(ep_id, buf_id);
|
||||
fsdev_pma_buf_t *pma_buf = PMA_BUF_AT(pma_addr);
|
||||
|
||||
const tu_hwfifo_access_t access_mode = {.data_stride = CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE};
|
||||
if (xfer->ff) {
|
||||
tu_hwfifo_read_to_fifo(pma_buf, xfer->ff, rx_count);
|
||||
tu_hwfifo_read_to_fifo(pma_buf, xfer->ff, rx_count, &access_mode);
|
||||
} else {
|
||||
tu_hwfifo_read(pma_buf, xfer->buffer + xfer->queued_len, rx_count);
|
||||
tu_hwfifo_read(pma_buf, xfer->buffer + xfer->queued_len, rx_count, &access_mode);
|
||||
}
|
||||
xfer->queued_len += rx_count;
|
||||
|
||||
@ -721,10 +723,11 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) {
|
||||
uint16_t addr_ptr = (uint16_t)btable_get_addr(ep_ix, buf_id);
|
||||
fsdev_pma_buf_t *pma_buf = PMA_BUF_AT(addr_ptr);
|
||||
|
||||
const tu_hwfifo_access_t access_mode = {.data_stride = CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE};
|
||||
if (xfer->ff) {
|
||||
tu_hwfifo_write_from_fifo(pma_buf, xfer->ff, len);
|
||||
tu_hwfifo_write_from_fifo(pma_buf, xfer->ff, len, &access_mode);
|
||||
} else {
|
||||
tu_hwfifo_write(pma_buf, &(xfer->buffer[xfer->queued_len]), len);
|
||||
tu_hwfifo_write(pma_buf, &(xfer->buffer[xfer->queued_len]), len, &access_mode);
|
||||
}
|
||||
xfer->queued_len += len;
|
||||
|
||||
|
||||
@ -365,12 +365,13 @@ static uint16_t epin_write_tx_fifo(dwc2_regs_t *dwc2, uint8_t epnum) {
|
||||
}
|
||||
|
||||
// Push packet to Tx-FIFO
|
||||
const tu_hwfifo_access_t access_mode = {.data_stride = CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE};
|
||||
volatile uint32_t *tx_fifo = dwc2->fifo[epnum];
|
||||
if (xfer->ff) {
|
||||
volatile uint32_t* tx_fifo = dwc2->fifo[epnum];
|
||||
tu_hwfifo_write_from_fifo(tx_fifo, xfer->ff, xact_bytes);
|
||||
tu_hwfifo_write_from_fifo(tx_fifo, xfer->ff, xact_bytes, &access_mode);
|
||||
total_bytes_written += xact_bytes;
|
||||
} else {
|
||||
dfifo_write_packet(dwc2, epnum, xfer->buffer, xact_bytes);
|
||||
tu_hwfifo_write(tx_fifo, xfer->buffer, xact_bytes, &access_mode);
|
||||
xfer->buffer += xact_bytes;
|
||||
total_bytes_written += xact_bytes;
|
||||
}
|
||||
@ -888,10 +889,11 @@ static void handle_rxflvl_irq(uint8_t rhport) {
|
||||
|
||||
if (byte_count != 0) {
|
||||
// Read packet off RxFIFO
|
||||
const tu_hwfifo_access_t access_mode = {.data_stride = CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE};
|
||||
if (xfer->ff != NULL) {
|
||||
tu_hwfifo_read_to_fifo(rx_fifo, xfer->ff, byte_count);
|
||||
tu_hwfifo_read_to_fifo(rx_fifo, xfer->ff, byte_count, &access_mode);
|
||||
} else {
|
||||
dfifo_read_packet(dwc2, xfer->buffer, byte_count);
|
||||
tu_hwfifo_read(rx_fifo, xfer->buffer, byte_count, &access_mode);
|
||||
xfer->buffer += byte_count;
|
||||
}
|
||||
}
|
||||
|
||||
@ -264,58 +264,4 @@ bool dwc2_core_init(uint8_t rhport, bool is_highspeed, bool is_dma) {
|
||||
//
|
||||
// }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// DFIFO
|
||||
//--------------------------------------------------------------------
|
||||
// Read a single data packet from receive DFIFO
|
||||
void dfifo_read_packet(dwc2_regs_t* dwc2, uint8_t* dst, uint16_t len) {
|
||||
const volatile uint32_t* rx_fifo = dwc2->fifo[0];
|
||||
|
||||
// Reading full available 32 bit words from fifo
|
||||
uint16_t word_count = len >> 2;
|
||||
while (word_count--) {
|
||||
tu_unaligned_write32(dst, *rx_fifo);
|
||||
dst += 4;
|
||||
}
|
||||
|
||||
// Read the remaining 1-3 bytes from fifo
|
||||
const uint8_t bytes_rem = len & 0x03;
|
||||
if (bytes_rem != 0) {
|
||||
const uint32_t tmp = *rx_fifo;
|
||||
dst[0] = tu_u32_byte0(tmp);
|
||||
if (bytes_rem > 1) {
|
||||
dst[1] = tu_u32_byte1(tmp);
|
||||
}
|
||||
if (bytes_rem > 2) {
|
||||
dst[2] = tu_u32_byte2(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Write a single data packet to DFIFO
|
||||
void dfifo_write_packet(dwc2_regs_t* dwc2, uint8_t fifo_num, const uint8_t* src, uint16_t len) {
|
||||
volatile uint32_t* tx_fifo = dwc2->fifo[fifo_num];
|
||||
|
||||
// Pushing full available 32 bit words to fifo
|
||||
uint16_t word_count = len >> 2;
|
||||
while (word_count--) {
|
||||
*tx_fifo = tu_unaligned_read32(src);
|
||||
src += 4;
|
||||
}
|
||||
|
||||
// Write the remaining 1-3 bytes into fifo
|
||||
const uint8_t bytes_rem = len & 0x03;
|
||||
if (bytes_rem) {
|
||||
uint32_t tmp_word = src[0];
|
||||
if (bytes_rem > 1) {
|
||||
tmp_word |= (src[1] << 8);
|
||||
}
|
||||
if (bytes_rem > 2) {
|
||||
tmp_word |= (src[2] << 16);
|
||||
}
|
||||
|
||||
*tx_fifo = tmp_word;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -856,7 +856,8 @@ static void handle_rxflvl_irq(uint8_t rhport) {
|
||||
hcd_endpoint_t* edpt = &_hcd_data.edpt[xfer->ep_id];
|
||||
|
||||
if (byte_count > 0) {
|
||||
dfifo_read_packet(dwc2, edpt->buffer + xfer->xferred_bytes, byte_count);
|
||||
const tu_hwfifo_access_t access_mode = {.data_stride = CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE};
|
||||
tu_hwfifo_read(dwc2->fifo[0], edpt->buffer + xfer->xferred_bytes, byte_count, &access_mode);
|
||||
xfer->xferred_bytes += byte_count;
|
||||
xfer->fifo_bytes = byte_count;
|
||||
}
|
||||
@ -907,7 +908,8 @@ static bool handle_txfifo_empty(dwc2_regs_t* dwc2, bool is_periodic) {
|
||||
return true;
|
||||
}
|
||||
|
||||
dfifo_write_packet(dwc2, ch_id, edpt->buffer + xfer->fifo_bytes, xact_bytes);
|
||||
const tu_hwfifo_access_t access_mode = {.data_stride = CFG_TUSB_FIFO_HWFIFO_DATA_STRIDE};
|
||||
tu_hwfifo_write(dwc2->fifo[ch_id], edpt->buffer + xfer->fifo_bytes, xact_bytes, &access_mode);
|
||||
xfer->fifo_bytes += xact_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,7 +113,6 @@ add_ceedling_test(
|
||||
${CEEDLING_WORKDIR}/../../src/common/tusb_fifo.c
|
||||
""
|
||||
)
|
||||
target_compile_definitions(test_fifo PRIVATE CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_WIDTH=32)
|
||||
|
||||
add_ceedling_test(
|
||||
test_usbd
|
||||
|
||||
@ -40,6 +40,16 @@ tu_fifo_buffer_info_t info;
|
||||
uint8_t test_data[4096];
|
||||
uint8_t rd_buf[FIFO_SIZE];
|
||||
|
||||
static const tu_hwfifo_access_t hwfifo_access_32 = {
|
||||
.data_stride = 4,
|
||||
.param = 0,
|
||||
};
|
||||
|
||||
static const tu_hwfifo_access_t hwfifo_access_16 = {
|
||||
.data_stride = 2,
|
||||
.param = 0,
|
||||
};
|
||||
|
||||
void setUp(void) {
|
||||
tu_fifo_clear(ff);
|
||||
memset(&info, 0, sizeof(tu_fifo_buffer_info_t));
|
||||
@ -403,7 +413,7 @@ void test_write_n_fixed_addr_rw32_nowrap(void) {
|
||||
|
||||
for (uint8_t n = 1; n <= 8; n++) {
|
||||
tu_fifo_clear(ff);
|
||||
uint16_t written = tu_fifo_write_n_access_mode(ff, (const void *)®, n, 4);
|
||||
uint16_t written = tu_fifo_write_n_access_mode(ff, (const void *)®, n, &hwfifo_access_32);
|
||||
TEST_ASSERT_EQUAL(n, written);
|
||||
TEST_ASSERT_EQUAL(n, tu_fifo_count(ff));
|
||||
|
||||
@ -425,7 +435,7 @@ void test_write_n_fixed_addr_rw32_wrapped(void) {
|
||||
ff->wr_idx = FIFO_SIZE - 3;
|
||||
ff->rd_idx = FIFO_SIZE - 3;
|
||||
|
||||
uint16_t written = tu_fifo_write_n_access_mode(ff, (const void *)®, n, 4);
|
||||
uint16_t written = tu_fifo_write_n_access_mode(ff, (const void *)®, n, &hwfifo_access_32);
|
||||
TEST_ASSERT_EQUAL(n, written);
|
||||
TEST_ASSERT_EQUAL(n, tu_fifo_count(ff));
|
||||
|
||||
@ -445,7 +455,7 @@ void test_read_n_fixed_addr_rw32_nowrap(void) {
|
||||
tu_fifo_write_n(ff, pattern, 8);
|
||||
|
||||
uint32_t reg = 0;
|
||||
uint16_t read_cnt = tu_fifo_read_n_access_mode(ff, ®, n, 4);
|
||||
uint16_t read_cnt = tu_fifo_read_n_access_mode(ff, ®, n, &hwfifo_access_32);
|
||||
TEST_ASSERT_EQUAL(n, read_cnt);
|
||||
TEST_ASSERT_EQUAL(8 - n, tu_fifo_count(ff));
|
||||
|
||||
@ -469,7 +479,7 @@ void test_read_n_fixed_addr_rw32_wrapped(void) {
|
||||
}
|
||||
|
||||
uint32_t reg = 0;
|
||||
uint16_t read_cnt = tu_fifo_read_n_access_mode(ff, ®, n, 4);
|
||||
uint16_t read_cnt = tu_fifo_read_n_access_mode(ff, ®, n, &hwfifo_access_32);
|
||||
TEST_ASSERT_EQUAL(n, read_cnt);
|
||||
TEST_ASSERT_EQUAL(0, tu_fifo_count(ff));
|
||||
|
||||
@ -485,7 +495,7 @@ void test_write_n_fixed_addr_rw16_nowrap(void) {
|
||||
|
||||
for (uint8_t n = 1; n <= 6; n++) {
|
||||
tu_fifo_clear(ff);
|
||||
uint16_t written = tu_fifo_write_n_access_mode(ff, (const void *)®, n, 2);
|
||||
uint16_t written = tu_fifo_write_n_access_mode(ff, (const void *)®, n, &hwfifo_access_16);
|
||||
TEST_ASSERT_EQUAL(n, written);
|
||||
TEST_ASSERT_EQUAL(n, tu_fifo_count(ff));
|
||||
|
||||
@ -507,7 +517,7 @@ void test_write_n_fixed_addr_rw16_wrapped(void) {
|
||||
ff->wr_idx = FIFO_SIZE - 3;
|
||||
ff->rd_idx = FIFO_SIZE - 3;
|
||||
|
||||
uint16_t written = tu_fifo_write_n_access_mode(ff, (const void *)®, n, 2);
|
||||
uint16_t written = tu_fifo_write_n_access_mode(ff, (const void *)®, n, &hwfifo_access_16);
|
||||
TEST_ASSERT_EQUAL(n, written);
|
||||
TEST_ASSERT_EQUAL(n, tu_fifo_count(ff));
|
||||
|
||||
@ -526,7 +536,7 @@ void test_read_n_fixed_addr_rw16_nowrap(void) {
|
||||
tu_fifo_write_n(ff, pattern, 6);
|
||||
|
||||
uint16_t reg = 0;
|
||||
uint16_t read_cnt = tu_fifo_read_n_access_mode(ff, ®, n, 2);
|
||||
uint16_t read_cnt = tu_fifo_read_n_access_mode(ff, ®, n, &hwfifo_access_16);
|
||||
TEST_ASSERT_EQUAL(n, read_cnt);
|
||||
TEST_ASSERT_EQUAL(6 - n, tu_fifo_count(ff));
|
||||
|
||||
@ -549,7 +559,7 @@ void test_read_n_fixed_addr_rw16_wrapped(void) {
|
||||
}
|
||||
|
||||
uint16_t reg = 0;
|
||||
uint16_t read_cnt = tu_fifo_read_n_access_mode(ff, ®, n, 2);
|
||||
uint16_t read_cnt = tu_fifo_read_n_access_mode(ff, ®, n, &hwfifo_access_16);
|
||||
TEST_ASSERT_EQUAL(n, read_cnt);
|
||||
TEST_ASSERT_EQUAL(0, tu_fifo_count(ff));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user