tusb_fifo remove item_size make it fifo of bytes

This commit is contained in:
hathach
2025-12-30 18:09:54 +07:00
parent 0a9e05f47a
commit 4e43988980
11 changed files with 137 additions and 184 deletions

View File

@ -674,17 +674,17 @@ void audiod_init(void) {
switch (i) {
#if CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ > 0
case 0:
tu_fifo_config(&audio->ep_in_ff, ep_in_sw_buf.buf_1, CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ, 1, true);
tu_fifo_config(&audio->ep_in_ff, ep_in_sw_buf.buf_1, CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ, true);
break;
#endif
#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ > 0
case 1:
tu_fifo_config(&audio->ep_in_ff, ep_in_sw_buf.buf_2, CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ, 1, true);
tu_fifo_config(&audio->ep_in_ff, ep_in_sw_buf.buf_2, CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ, true);
break;
#endif
#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ > 0
case 2:
tu_fifo_config(&audio->ep_in_ff, ep_in_sw_buf.buf_3, CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ, 1, true);
tu_fifo_config(&audio->ep_in_ff, ep_in_sw_buf.buf_3, CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ, true);
break;
#endif
}
@ -716,17 +716,17 @@ void audiod_init(void) {
switch (i) {
#if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ > 0
case 0:
tu_fifo_config(&audio->ep_out_ff, ep_out_sw_buf.buf_1, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ, 1, true);
tu_fifo_config(&audio->ep_out_ff, ep_out_sw_buf.buf_1, CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ, true);
break;
#endif
#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ > 0
case 1:
tu_fifo_config(&audio->ep_out_ff, ep_out_sw_buf.buf_2, CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ, 1, true);
tu_fifo_config(&audio->ep_out_ff, ep_out_sw_buf.buf_2, CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ, true);
break;
#endif
#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ > 0
case 2:
tu_fifo_config(&audio->ep_out_ff, ep_out_sw_buf.buf_3, CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ, 1, true);
tu_fifo_config(&audio->ep_out_ff, ep_out_sw_buf.buf_3, CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ, true);
break;
#endif
}

View File

@ -59,7 +59,7 @@ TU_ATTR_ALWAYS_INLINE static inline void ff_unlock(osal_mutex_t mutex) {
//--------------------------------------------------------------------+
// Setup API
//--------------------------------------------------------------------+
bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, uint16_t item_size, bool overwritable) {
bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, bool overwritable) {
// Limit index space to 2*depth - this allows for a fast "modulo" calculation
// but limits the maximum depth to 2^16/2 = 2^15 and buffer overflows are detectable
// only if overflow happens once (important for unsupervised DMA applications)
@ -72,7 +72,6 @@ bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, uint16_t item_si
f->buffer = (uint8_t *)buffer;
f->depth = depth;
f->item_size = (uint16_t)(item_size & 0x7FFFu);
f->overwritable = overwritable;
f->rd_idx = 0u;
f->wr_idx = 0u;
@ -130,7 +129,10 @@ enum {
};
// Copy to fifo from fixed address buffer (usually a rx register) with TU_FIFO_FIXED_ADDR_RW32 mode
static void ff_push_fixed_addr(uint8_t *ff_buf, const volatile fixed_access_item_t *reg_rx, uint16_t len) {
static void ff_push_access_mode(uint8_t *ff_buf, const volatile fixed_access_item_t *reg_rx, uint16_t len,
uint8_t data_stride, uint8_t addr_stride) {
(void)data_stride;
(void)addr_stride;
// Reading full available 16/32-bit data from const app address
uint16_t n_items = len / sizeof(fixed_access_item_t);
while (n_items--) {
@ -167,86 +169,70 @@ static void ff_pull_fixed_addr(volatile fixed_access_item_t *reg_tx, const uint8
#endif
// send n items to fifo WITHOUT updating write pointer
static void ff_push_n(const tu_fifo_t *f, const void *app_buf, uint16_t n, uint16_t wr_ptr,
tu_fifo_access_mode_t copy_mode) {
const uint16_t lin_count = f->depth - wr_ptr;
const uint16_t wrap_count = n - lin_count;
static void ff_push_n(const tu_fifo_t *f, const void *app_buf, uint16_t n, uint16_t wr_ptr, uint8_t data_stride,
uint8_t addr_stride) {
uint16_t lin_bytes = f->depth - wr_ptr;
uint16_t wrap_bytes = n - lin_bytes;
uint8_t *ff_buf = f->buffer + wr_ptr;
uint16_t lin_bytes = lin_count * f->item_size;
uint16_t wrap_bytes = wrap_count * f->item_size;
#if CFG_TUSB_FIFO_MULTI_BYTES_ACCESS
if (data_stride > 1) {
const volatile fixed_access_item_t *reg_rx = (volatile const fixed_access_item_t *)app_buf;
if (n <= lin_bytes) {
// Linear only
ff_push_access_mode(ff_buf, reg_rx, n, data_stride, addr_stride);
} else {
// Wrap around
// current buffer of fifo
uint8_t *ff_buf = f->buffer + (wr_ptr * f->item_size);
// Write full words to linear part of buffer
uint16_t lin_nitems_bytes = lin_bytes & ~FIXED_ACCESS_REMAINDER_MASK;
ff_push_access_mode(ff_buf, reg_rx, lin_nitems_bytes, data_stride, addr_stride);
ff_buf += lin_nitems_bytes;
switch (copy_mode) {
case TU_FIFO_INC_ADDR_RW8:
if (n <= lin_count) {
// Linear only
memcpy(ff_buf, app_buf, n * f->item_size);
// There could be odd 1 byte (16bit) or 1-3 bytes (32bit) before the wrap-around boundary
const uint8_t rem = lin_bytes & FIXED_ACCESS_REMAINDER_MASK;
if (rem > 0) {
const uint8_t remrem = (uint8_t)tu_min16(wrap_bytes, sizeof(fixed_access_item_t) - rem);
const fixed_access_item_t tmp = *reg_rx;
tu_scatter_write32(tmp, ff_buf, rem, f->buffer, remrem);
wrap_bytes -= remrem;
ff_buf = f->buffer + remrem; // wrap around
} else {
// Wrap around
memcpy(ff_buf, app_buf, lin_bytes); // linear part
memcpy(f->buffer, ((const uint8_t *)app_buf) + lin_bytes, wrap_bytes); // wrapped part
ff_buf = f->buffer; // wrap around to beginning
}
break;
#if CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_WIDTH
case TU_FIFO_FIXED_ADDR_RW32: {
const volatile fixed_access_item_t *reg_rx = (volatile const fixed_access_item_t *)app_buf;
if (n <= lin_count) {
// Linear only
ff_push_fixed_addr(ff_buf, reg_rx, n * f->item_size);
} else {
// Wrap around
// Write full words to linear part of buffer
uint16_t lin_nitems_bytes = lin_bytes & ~FIXED_ACCESS_REMAINDER_MASK;
ff_push_fixed_addr(ff_buf, reg_rx, lin_nitems_bytes);
ff_buf += lin_nitems_bytes;
// There could be odd 1 byte (16bit) or 1-3 bytes (32bit) before the wrap-around boundary
const uint8_t rem = lin_bytes & FIXED_ACCESS_REMAINDER_MASK;
if (rem > 0) {
const uint8_t remrem = (uint8_t)tu_min16(wrap_bytes, sizeof(fixed_access_item_t) - rem);
const fixed_access_item_t tmp = *reg_rx;
tu_scatter_write32(tmp, ff_buf, rem, f->buffer, remrem);
wrap_bytes -= remrem;
ff_buf = f->buffer + remrem; // wrap around
} else {
ff_buf = f->buffer; // wrap around to beginning
}
// Write data wrapped part
if (wrap_bytes > 0) {
ff_push_fixed_addr(ff_buf, reg_rx, wrap_bytes);
}
// Write data wrapped part
if (wrap_bytes > 0) {
ff_push_access_mode(ff_buf, reg_rx, wrap_bytes, data_stride, addr_stride);
}
break;
}
} else
#endif
default:
break; // unknown mode
{
// single byte access
if (n <= lin_bytes) {
// Linear only
memcpy(ff_buf, app_buf, n);
} else {
// Wrap around
memcpy(ff_buf, app_buf, lin_bytes); // linear part
memcpy(f->buffer, ((const uint8_t *)app_buf) + lin_bytes, wrap_bytes); // wrapped part
}
}
}
// get n items from fifo WITHOUT updating read pointer
static void ff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t rd_ptr, tu_fifo_access_mode_t copy_mode) {
const uint16_t lin_count = f->depth - rd_ptr;
const uint16_t wrap_count = n - lin_count; // only used if wrapped
uint16_t lin_bytes = lin_count * f->item_size;
uint16_t wrap_bytes = wrap_count * f->item_size;
// current buffer of fifo
const uint8_t *ff_buf = f->buffer + (rd_ptr * f->item_size);
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;
switch (copy_mode) {
case TU_FIFO_INC_ADDR_RW8:
if (n <= lin_count) {
if (n <= lin_bytes) {
// Linear only
memcpy(app_buf, ff_buf, n * f->item_size);
memcpy(app_buf, ff_buf, n);
} else {
// Wrap around
memcpy(app_buf, ff_buf, lin_bytes); // linear part
@ -258,9 +244,9 @@ static void ff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t rd
case TU_FIFO_FIXED_ADDR_RW32: {
volatile fixed_access_item_t *reg_tx = (volatile fixed_access_item_t *)app_buf;
if (n <= lin_count) {
if (n <= lin_bytes) {
// Linear only
ff_pull_fixed_addr(reg_tx, ff_buf, n * f->item_size);
ff_pull_fixed_addr(reg_tx, ff_buf, n);
} else {
// Wrap around case
@ -389,7 +375,8 @@ uint16_t tu_fifo_read_n_access_mode(tu_fifo_t *f, void *buffer, uint16_t n, tu_f
}
// 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, tu_fifo_access_mode_t access_mode) {
uint16_t tu_fifo_write_n_access_mode(tu_fifo_t *f, const void *data, uint16_t n, uint8_t data_stride,
uint8_t addr_stride) {
if (n == 0) {
return 0;
}
@ -415,8 +402,8 @@ 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 (access_mode == TU_FIFO_INC_ADDR_RW8) {
buf8 += (n - f->depth) * f->item_size;
if (data_stride == TU_FIFO_INC_ADDR_RW8) {
buf8 += (n - f->depth);
} else {
// TODO should read from hw fifo to discard data, however reading an odd number could
// accidentally discard data.
@ -451,7 +438,7 @@ uint16_t tu_fifo_write_n_access_mode(tu_fifo_t *f, const void *data, uint16_t n,
const uint16_t wr_ptr = idx2ptr(f->depth, wr_idx);
TU_LOG(TU_FIFO_DBG, "actual_n = %u, wr_ptr = %u", n, wr_ptr);
ff_push_n(f, buf8, n, wr_ptr, access_mode);
ff_push_n(f, buf8, n, wr_ptr, data_stride, addr_stride);
f->wr_idx = advance_index(f->depth, wr_idx, n);
TU_LOG(TU_FIFO_DBG, "\tnew_wr = %u\r\n", f->wr_idx);
@ -491,7 +478,7 @@ static bool ff_peek_local(tu_fifo_t *f, void *buf, uint16_t wr_idx, uint16_t rd_
}
const uint16_t rd_ptr = idx2ptr(f->depth, rd_idx);
memcpy(buf, f->buffer + (rd_ptr * f->item_size), f->item_size);
memcpy(buf, f->buffer + rd_ptr, 1);
return true;
}
@ -526,7 +513,7 @@ bool tu_fifo_write(tu_fifo_t *f, const void *data) {
ret = false;
} else {
const uint16_t wr_ptr = idx2ptr(f->depth, wr_idx);
memcpy(f->buffer + (wr_ptr * f->item_size), data, f->item_size);
memcpy(f->buffer + wr_ptr, data, 1);
f->wr_idx = advance_index(f->depth, wr_idx, 1);
ret = true;
}

View File

@ -58,6 +58,9 @@ extern "C" {
#define CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_WIDTH 0
#endif
#ifndef CFG_TUSB_FIFO_MULTI_BYTES_ACCESS
#define CFG_TUSB_FIFO_MULTI_BYTES_ACCESS 0
#endif
/* Write/Read "pointer" is in the range of: 0 .. depth - 1, and is used to get the fifo data.
* Write/Read "index" is always in the range of: 0 .. 2*depth-1
@ -118,13 +121,9 @@ extern "C" {
typedef struct {
uint8_t *buffer; // buffer pointer
uint16_t depth; // max items
bool overwritable; // ovwerwritable when full
struct TU_ATTR_PACKED {
uint16_t item_size : 15; // size of each item
bool overwritable : 1; // ovwerwritable when full
};
volatile uint16_t wr_idx; // write index
volatile uint16_t wr_idx; // write index TODO maybe can drop volatile
volatile uint16_t rd_idx; // read index
#if OSAL_MUTEX_REQUIRED
@ -141,17 +140,16 @@ typedef struct {
} linear, wrapped;
} tu_fifo_buffer_info_t;
#define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable) \
{ \
.buffer = _buffer, \
.depth = _depth, \
.item_size = sizeof(_type), \
.overwritable = _overwritable, \
#define TU_FIFO_INIT(_buffer, _depth, _overwritable) \
{ \
.buffer = _buffer, \
.depth = _depth, \
.overwritable = _overwritable, \
}
#define TU_FIFO_DEF(_name, _depth, _type, _overwritable) \
uint8_t _name##_buf[_depth*sizeof(_type)]; \
tu_fifo_t _name = TU_FIFO_INIT(_name##_buf, _depth, _type, _overwritable)
#define TU_FIFO_DEF(_name, _depth, _overwritable) \
uint8_t _name##_buf[_depth]; \
tu_fifo_t _name = TU_FIFO_INIT(_name##_buf, _depth, _overwritable)
// Write modes intended to allow special read and write functions to be able to
// copy data to and from USB hardware FIFOs as needed for e.g. STM32s and others
@ -163,7 +161,7 @@ typedef enum {
//--------------------------------------------------------------------+
// Setup API
//--------------------------------------------------------------------+
bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, uint16_t item_size, bool overwritable);
bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, bool overwritable);
void tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable);
void tu_fifo_clear(tu_fifo_t *f);
@ -223,14 +221,11 @@ 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, tu_fifo_access_mode_t access_mode);
uint16_t tu_fifo_write_n_access_mode(tu_fifo_t *f, const void *data, uint16_t n, uint8_t data_stride,
uint8_t addr_stride);
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, TU_FIFO_INC_ADDR_RW8);
}
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_write_n_fixed_addr(tu_fifo_t *f, const void *data, uint16_t n) {
return tu_fifo_write_n_access_mode(f, data, n, TU_FIFO_FIXED_ADDR_RW32);
return tu_fifo_write_n_access_mode(f, data, n, 1, 1);
}
//--------------------------------------------------------------------+

View File

@ -96,10 +96,12 @@
* - TU_VERIFY_1ARGS : return false if failed
* - TU_VERIFY_2ARGS : return provided value if failed
*------------------------------------------------------------------*/
#define TU_VERIFY_DEFINE(_cond, _ret) \
do { \
if (!(_cond)) { return _ret; } \
} while(0)
#define TU_VERIFY_DEFINE(_cond, _ret) \
do { \
if (!(_cond)) { \
return _ret; \
} \
} while (0)
#define TU_VERIFY_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, false)
#define TU_VERIFY_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, _ret)

View File

@ -157,18 +157,18 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hd
typedef struct {
void (* interrupt_set)(bool enabled);
uint16_t item_size;
tu_fifo_t ff;
} osal_queue_def_t;
typedef osal_queue_def_t* osal_queue_t;
// _int_set is used as mutex in OS NONE (disable/enable USB ISR)
#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \
uint8_t _name##_buf[_depth*sizeof(_type)]; \
osal_queue_def_t _name = { \
.interrupt_set = _int_set, \
.ff = TU_FIFO_INIT(_name##_buf, _depth, _type, false) \
}
#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \
uint8_t _name##_buf[_depth * sizeof(_type)]; \
osal_queue_def_t _name = {.interrupt_set = _int_set, \
.item_size = sizeof(_type), \
.ff = TU_FIFO_INIT(_name##_buf, _depth * sizeof(_type), false)}
TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) {
tu_fifo_clear(&qdef->ff);
@ -184,7 +184,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, v
(void) msec; // not used, always behave as msec = 0
qhdl->interrupt_set(false);
const bool success = tu_fifo_read(&qhdl->ff, data);
const bool success = tu_fifo_read_n(&qhdl->ff, data, qhdl->item_size);
qhdl->interrupt_set(true);
return success;
@ -195,7 +195,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void
qhdl->interrupt_set(false);
}
const bool success = tu_fifo_write(&qhdl->ff, data);
const bool success = tu_fifo_write_n(&qhdl->ff, data, qhdl->item_size);
if (!in_isr) {
qhdl->interrupt_set(true);

View File

@ -47,40 +47,39 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) {
// Spinlock API
//--------------------------------------------------------------------+
typedef critical_section_t osal_spinlock_t; // pico implement critical section with spinlock
#define OSAL_SPINLOCK_DEF(_name, _int_set) \
osal_spinlock_t _name
#define OSAL_SPINLOCK_DEF(_name, _int_set) osal_spinlock_t _name
TU_ATTR_ALWAYS_INLINE static inline void osal_spin_init(osal_spinlock_t *ctx) {
critical_section_init(ctx);
}
TU_ATTR_ALWAYS_INLINE static inline void osal_spin_lock(osal_spinlock_t *ctx, bool in_isr) {
(void) in_isr;
(void)in_isr;
critical_section_enter_blocking(ctx);
}
TU_ATTR_ALWAYS_INLINE static inline void osal_spin_unlock(osal_spinlock_t *ctx, bool in_isr) {
(void) in_isr;
(void)in_isr;
critical_section_exit(ctx);
}
//--------------------------------------------------------------------+
// Binary Semaphore API
//--------------------------------------------------------------------+
typedef struct semaphore osal_semaphore_def_t, * osal_semaphore_t;
typedef struct semaphore osal_semaphore_def_t, *osal_semaphore_t;
TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) {
TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t *semdef) {
sem_init(semdef, 0, 255);
return semdef;
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) {
(void) semd_hdl;
(void)semd_hdl;
return true; // nothing to do
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) {
(void) in_isr;
(void)in_isr;
return sem_release(sem_hdl);
}
@ -96,15 +95,15 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t s
// MUTEX API
// Within tinyusb, mutex is never used in ISR context
//--------------------------------------------------------------------+
typedef struct mutex osal_mutex_def_t, * osal_mutex_t;
typedef struct mutex osal_mutex_def_t, *osal_mutex_t;
TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) {
TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t *mdef) {
mutex_init(mdef);
return mdef;
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) {
(void) mutex_hdl;
(void)mutex_hdl;
return true; // nothing to do
}
@ -123,46 +122,45 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hd
#include "common/tusb_fifo.h"
typedef struct {
tu_fifo_t ff;
uint16_t item_size;
tu_fifo_t ff;
struct critical_section critsec; // osal_queue may be used in IRQs, so need critical section
} osal_queue_def_t;
typedef osal_queue_def_t* osal_queue_t;
typedef osal_queue_def_t *osal_queue_t;
// role device/host is used by OS NONE for mutex (disable usb isr) only
#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \
uint8_t _name##_buf[_depth*sizeof(_type)]; \
osal_queue_def_t _name = { \
.ff = TU_FIFO_INIT(_name##_buf, _depth, _type, false) \
}
#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \
uint8_t _name##_buf[_depth * sizeof(_type)]; \
osal_queue_def_t _name = {.item_size = sizeof(_type), .ff = TU_FIFO_INIT(_name##_buf, _depth * sizeof(_type), false)}
TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) {
TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t *qdef) {
critical_section_init(&qdef->critsec);
(void) tu_fifo_clear(&qdef->ff);
return (osal_queue_t) qdef;
tu_fifo_clear(&qdef->ff);
return (osal_queue_t)qdef;
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) {
osal_queue_def_t* qdef = (osal_queue_def_t*) qhdl;
osal_queue_def_t *qdef = (osal_queue_def_t *)qhdl;
critical_section_deinit(&qdef->critsec);
return true;
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) {
(void) msec; // not used, always behave as msec = 0
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void *data, uint32_t msec) {
(void)msec; // not used, always behave as msec = 0
critical_section_enter_blocking(&qhdl->critsec);
bool success = tu_fifo_read(&qhdl->ff, data);
bool success = tu_fifo_read_n(&qhdl->ff, data, qhdl->item_size);
critical_section_exit(&qhdl->critsec);
return success;
}
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const* data, bool in_isr) {
(void) in_isr;
TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, const void *data, bool in_isr) {
(void)in_isr;
critical_section_enter_blocking(&qhdl->critsec);
bool success = tu_fifo_write(&qhdl->ff, data);
bool success = tu_fifo_write_n(&qhdl->ff, data, qhdl->item_size);
critical_section_exit(&qhdl->critsec);
return success;

View File

@ -345,10 +345,9 @@ static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) {
}
}
static uint16_t epin_write_tx_fifo(uint8_t rhport, uint8_t epnum) {
dwc2_regs_t* dwc2 = DWC2_REG(rhport);
dwc2_dep_t* const epin = &dwc2->ep[0][epnum];
xfer_ctl_t* const xfer = XFER_CTL_BASE(epnum, TUSB_DIR_IN);
static uint16_t epin_write_tx_fifo(dwc2_regs_t *dwc2, uint8_t epnum) {
dwc2_dep_t *const epin = &dwc2->ep[0][epnum];
xfer_ctl_t *const xfer = XFER_CTL_BASE(epnum, TUSB_DIR_IN);
dwc2_ep_tsize_t tsiz = {.value = epin->tsiz};
const uint16_t remain_packets = tsiz.packet_count;
@ -438,7 +437,7 @@ static void edpt_schedule_packets(uint8_t rhport, const uint8_t epnum, const uin
dep->diepctl = depctl.value; // enable endpoint
if (dir == TUSB_DIR_IN && total_bytes != 0) {
const uint16_t xferred_bytes = epin_write_tx_fifo(rhport, epnum);
const uint16_t xferred_bytes = epin_write_tx_fifo(dwc2, epnum);
// Enable TXFE interrupt if there are still data to be sent
// EP0 only sends one packet at a time, so no need to check for EP0
@ -689,9 +688,6 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to
// into the USB buffer!
bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t total_bytes, bool is_isr) {
(void) is_isr;
// USB buffers always work in bytes so to avoid unnecessary divisions we demand item_size = 1
TU_ASSERT(ff->item_size == 1);
uint8_t const epnum = tu_edpt_number(ep_addr);
uint8_t const dir = tu_edpt_dir(ep_addr);
xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, dir);
@ -893,7 +889,8 @@ static void handle_rxflvl_irq(uint8_t rhport) {
if (byte_count != 0) {
// Read packet off RxFIFO
if (xfer->ff != NULL) {
tu_fifo_write_n_access_mode(xfer->ff, (const void *)(uintptr_t)rx_fifo, byte_count, TU_FIFO_FIXED_ADDR_RW32);
tu_fifo_write_n_access_mode(xfer->ff, (const void *)(uintptr_t)rx_fifo, byte_count, TU_FIFO_FIXED_ADDR_RW32,
0);
} else {
dfifo_read_packet(dwc2, xfer->buffer, byte_count);
xfer->buffer += byte_count;
@ -967,7 +964,7 @@ static void handle_epin_slave(uint8_t rhport, uint8_t epnum, dwc2_diepint_t diep
// - 64 bytes or
// - Half/Empty of TX FIFO size (configured by GAHBCFG.TXFELVL)
if (diepint_bm.txfifo_empty && tu_bit_test(dwc2->diepempmsk, epnum)) {
epin_write_tx_fifo(rhport, epnum);
epin_write_tx_fifo(dwc2, epnum);
// Turn off TXFE if all bytes are written.
dwc2_ep_tsize_t tsiz = {.value = epin->tsiz};

View File

@ -316,7 +316,7 @@ bool tu_edpt_stream_init(tu_edpt_stream_t *s, bool is_host, bool is_tx, bool ove
#endif
s->is_host = is_host;
tu_fifo_config(&s->ff, ff_buf, ff_bufsize, 1, overwritable);
tu_fifo_config(&s->ff, ff_buf, ff_bufsize, overwritable);
#if OSAL_MUTEX_REQUIRED
if (ff_buf != NULL && ff_bufsize > 0) {

View File

@ -307,6 +307,7 @@
#if defined(TUP_USBIP_DWC2)
#if CFG_TUD_DWC2_SLAVE_ENABLE && !CFG_TUD_DWC2_DMA_ENABLE
#define CFG_TUD_EDPT_DEDICATED_HWFIFO 1
#define CFG_TUSB_FIFO_MULTI_BYTES_ACCESS 1
#endif
#if CFG_TUH_DWC2_SLAVE_ENABLE && !CFG_TUH_DWC2_DMA_ENABLE

View File

@ -129,6 +129,7 @@
:test:
- _UNITY_TEST_
- CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_WIDTH=32
- CFG_TUSB_FIFO_MULTI_BYTES_ACCESS=1
:release: []
# Enable to inject name of a test as a unique compilation symbol into its respective executable build.

View File

@ -32,7 +32,7 @@
#define FIFO_SIZE 64
uint8_t tu_ff_buf[FIFO_SIZE * sizeof(uint8_t)];
tu_fifo_t tu_ff = TU_FIFO_INIT(tu_ff_buf, FIFO_SIZE, uint8_t, false);
tu_fifo_t tu_ff = TU_FIFO_INIT(tu_ff_buf, FIFO_SIZE, false);
tu_fifo_t *ff = &tu_ff;
tu_fifo_buffer_info_t info;
@ -68,34 +68,6 @@ void test_normal(void) {
}
}
void test_item_size(void) {
uint8_t ff4_buf[FIFO_SIZE * sizeof(uint32_t)];
tu_fifo_t ff4 = TU_FIFO_INIT(ff4_buf, FIFO_SIZE, uint32_t, false);
uint32_t data4[2 * FIFO_SIZE];
for (uint32_t i = 0; i < sizeof(data4) / 4; i++) {
data4[i] = i;
}
// fill up fifo
tu_fifo_write_n(&ff4, data4, FIFO_SIZE);
uint32_t rd_buf4[FIFO_SIZE];
uint16_t rd_count;
// read 0 -> 4
rd_count = tu_fifo_read_n(&ff4, rd_buf4, 5);
TEST_ASSERT_EQUAL(5, rd_count);
TEST_ASSERT_EQUAL_UINT32_ARRAY(data4, rd_buf4, rd_count); // 0 -> 4
tu_fifo_write_n(&ff4, data4 + FIFO_SIZE, 5);
// read all 5 -> 68
rd_count = tu_fifo_read_n(&ff4, rd_buf4, FIFO_SIZE);
TEST_ASSERT_EQUAL(FIFO_SIZE, rd_count);
TEST_ASSERT_EQUAL_UINT32_ARRAY(data4 + 5, rd_buf4, rd_count); // 5 -> 68
}
void test_read_n(void) {
uint16_t rd_count;
@ -362,7 +334,7 @@ void test_rd_idx_wrap(void) {
uint8_t buf[10];
uint8_t dst[10];
tu_fifo_config(&ff10, buf, 10, 1, 1);
tu_fifo_config(&ff10, buf, 10, 1);
uint16_t n;
@ -431,7 +403,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 *)&reg, n, TU_FIFO_FIXED_ADDR_RW32);
uint16_t written = tu_fifo_write_n_access_mode(ff, (const void *)&reg, n, sizeof(uint32_t), 0);
TEST_ASSERT_EQUAL(n, written);
TEST_ASSERT_EQUAL(n, tu_fifo_count(ff));
@ -453,7 +425,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 *)&reg, n, TU_FIFO_FIXED_ADDR_RW32);
uint16_t written = tu_fifo_write_n_access_mode(ff, (const void *)&reg, n, sizeof(uint32_t), 0);
TEST_ASSERT_EQUAL(n, written);
TEST_ASSERT_EQUAL(n, tu_fifo_count(ff));