summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorhathach <[email protected]>2025-12-31 17:45:20 +0700
committerhathach <[email protected]>2025-12-31 17:48:09 +0700
commit9b5c7761cc6ea816cf35f330cb269030256be7ca (patch)
tree5702272964fdc44601671aa0cbc971325d9539dd /src/common
parentf20ad05d71919dd5656aa7f92b9e27582744348a (diff)
add separate tu_hwifo_*() with data from buffer/software fifo. Remove duplicated packet write/read for fsdev
Diffstat (limited to 'src/common')
-rw-r--r--src/common/tusb_fifo.c43
-rw-r--r--src/common/tusb_fifo.h26
2 files changed, 44 insertions, 25 deletions
diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c
index bc4ee180c..a46bee955 100644
--- a/src/common/tusb_fifo.c
+++ b/src/common/tusb_fifo.c
@@ -128,14 +128,15 @@ enum {
STRIDE_REMAIN_MASK = sizeof(stride_item_t) - 1u
};
-// Copy to fifo from fixed address buffer (usually a rx register) with TU_FIFO_FIXED_ADDR_RW32 mode
-static void ff_push_stride(uint8_t *ff_buf, const volatile stride_item_t *src, uint16_t len) {
- // Reading full available 16/32-bit src and write to fifo
+void tu_hwfifo_read(const volatile void *hwfifo, uint8_t *dest, uint16_t len) {
+ const volatile stride_item_t *src = (const volatile stride_item_t *)hwfifo;
+
+ // Reading full available 16/32-bit hwfifo and write to fifo
uint16_t n_items = len >> (CFG_TUSB_FIFO_ACCESS_DATA_STRIDE >> 1); // len / data_stride;
while (n_items--) {
const stride_item_t tmp = *src;
- stride_unaligned_write(ff_buf, tmp);
- ff_buf += sizeof(stride_item_t);
+ stride_unaligned_write(dest, tmp);
+ dest += sizeof(stride_item_t);
#if CFG_TUSB_FIFO_ACCESS_ADDR_STRIDE
src = (const volatile stride_item_t *)((uintptr_t)src + CFG_TUSB_FIFO_ACCESS_ADDR_STRIDE);
@@ -146,17 +147,19 @@ static void ff_push_stride(uint8_t *ff_buf, const volatile stride_item_t *src, u
const uint8_t bytes_rem = len & STRIDE_REMAIN_MASK;
if (bytes_rem) {
const stride_item_t tmp = *src;
- memcpy(ff_buf, &tmp, bytes_rem);
+ memcpy(dest, &tmp, bytes_rem);
}
}
// Copy from fifo to fixed address buffer (usually a tx register) with TU_FIFO_FIXED_ADDR_RW32 mode
-static void ff_pull_stride(volatile stride_item_t *dest, const uint8_t *ff_buf, uint16_t len) {
+void tu_hwfifo_write(volatile void *hwfifo, const uint8_t *src, uint16_t len) {
+ volatile stride_item_t *dest = (volatile stride_item_t *)hwfifo;
+
// Write full available 16/32 bit words to dest
uint16_t n_items = len >> (CFG_TUSB_FIFO_ACCESS_DATA_STRIDE >> 1); // len / data_stride;
while (n_items--) {
- *dest = stride_unaligned_read(ff_buf);
- ff_buf += sizeof(stride_item_t);
+ *dest = stride_unaligned_read(src);
+ src += sizeof(stride_item_t);
#if CFG_TUSB_FIFO_ACCESS_ADDR_STRIDE
dest = (volatile stride_item_t *)((uintptr_t)dest + CFG_TUSB_FIFO_ACCESS_ADDR_STRIDE);
@@ -167,7 +170,7 @@ static void ff_pull_stride(volatile stride_item_t *dest, const uint8_t *ff_buf,
const uint8_t bytes_rem = len & STRIDE_REMAIN_MASK;
if (bytes_rem) {
stride_item_t tmp = 0u;
- memcpy(&tmp, ff_buf, bytes_rem);
+ memcpy(&tmp, src, bytes_rem);
*dest = tmp;
}
}
@@ -182,23 +185,23 @@ static void ff_push_n(const tu_fifo_t *f, const void *app_buf, uint16_t n, uint1
#if CFG_TUD_EDPT_DEDICATED_HWFIFO
if (stride_mode) {
- const volatile stride_item_t *stride_src = (const volatile stride_item_t *)app_buf;
+ const volatile stride_item_t *hwfifo = (const volatile stride_item_t *)app_buf;
if (n <= lin_bytes) {
// Linear only case
- ff_push_stride(ff_buf, stride_src, n);
+ tu_hwfifo_read(hwfifo, ff_buf, n);
} else {
// Wrap around case
// Write full words to linear part of buffer
uint16_t lin_nitems_bytes = lin_bytes & ~STRIDE_REMAIN_MASK;
- ff_push_stride(ff_buf, stride_src, lin_nitems_bytes);
+ tu_hwfifo_read(hwfifo, ff_buf, 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 & STRIDE_REMAIN_MASK;
if (rem > 0) {
const uint8_t remrem = (uint8_t)tu_min16(wrap_bytes, sizeof(stride_item_t) - rem);
- const stride_item_t tmp = *stride_src;
+ const stride_item_t tmp = *hwfifo;
tu_scatter_write32(tmp, ff_buf, rem, f->buffer, remrem);
wrap_bytes -= remrem;
@@ -209,7 +212,7 @@ static void ff_push_n(const tu_fifo_t *f, const void *app_buf, uint16_t n, uint1
// Write data wrapped part
if (wrap_bytes > 0) {
- ff_push_stride(ff_buf, stride_src, wrap_bytes);
+ tu_hwfifo_read(hwfifo, ff_buf, wrap_bytes);
}
}
} else
@@ -236,17 +239,17 @@ static void ff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t rd
#if CFG_TUD_EDPT_DEDICATED_HWFIFO
if (stride_mode) {
- volatile stride_item_t *stride_dst = (volatile stride_item_t *)app_buf;
+ volatile stride_item_t *hwfifo = (volatile stride_item_t *)app_buf;
if (n <= lin_bytes) {
// Linear only case
- ff_pull_stride(stride_dst, ff_buf, n);
+ tu_hwfifo_write(hwfifo, ff_buf, n);
} else {
// Wrap around case
// Read full words from linear part
uint16_t lin_nitems_bytes = lin_bytes & ~STRIDE_REMAIN_MASK;
- ff_pull_stride(stride_dst, ff_buf, lin_nitems_bytes);
+ tu_hwfifo_write(hwfifo, ff_buf, 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
@@ -255,7 +258,7 @@ static void ff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t rd
const uint8_t remrem = (uint8_t)tu_min16(wrap_bytes, sizeof(stride_item_t) - rem);
const stride_item_t scatter = (stride_item_t)tu_scatter_read32(ff_buf, rem, f->buffer, remrem);
- *stride_dst = scatter;
+ *hwfifo = scatter;
wrap_bytes -= remrem;
ff_buf = f->buffer + remrem; // wrap around
@@ -265,7 +268,7 @@ static void ff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t rd
// Read data wrapped part
if (wrap_bytes > 0) {
- ff_pull_stride(stride_dst, ff_buf, wrap_bytes);
+ tu_hwfifo_write(hwfifo, ff_buf, wrap_bytes);
}
}
} else
diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h
index 53c5f6e56..f28f54749 100644
--- a/src/common/tusb_fifo.h
+++ b/src/common/tusb_fifo.h
@@ -204,9 +204,6 @@ 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, false);
}
-TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_read_to_hwfifo(tu_fifo_t *f, void *buffer, uint16_t n) {
- return tu_fifo_read_n_access_mode(f, buffer, n, true);
-}
// discard first n items from fifo i.e advance read pointer by n with mutex
// return number of discarded items
@@ -220,10 +217,29 @@ 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, false);
}
-TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_write_from_hwfifo(tu_fifo_t *f, const void *data, uint16_t n) {
- return tu_fifo_write_n_access_mode(f, data, n, true);
+
+//--------------------------------------------------------------------+
+// Hardware FIFO API
+// Special hardware FIFO/Buffer to hold USB data, usually requires certain access method these can be configured with
+// CFG_TUSB_FIFO_ACCESS_DATA_STRIDE (data width) and CFG_TUSB_FIFO_ACCESS_ADDR_STRIDE (address increment)
+// Note: these usually has opposiite direction (read/write) to/from our software FIFO (tu_fifo_t)
+//--------------------------------------------------------------------+
+#if CFG_TUD_EDPT_DEDICATED_HWFIFO
+TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_hwfifo_write_from_fifo(tu_fifo_t *f, void *hwfifo, uint16_t n) {
+ return tu_fifo_read_n_access_mode(f, hwfifo, n, true);
}
+TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_hwfifo_read_to_fifo(tu_fifo_t *f, const void *hwfifo, uint16_t n) {
+ return tu_fifo_write_n_access_mode(f, hwfifo, n, true);
+}
+
+// read from hwfifo to buffer
+void tu_hwfifo_read(const volatile void *hwfifo, uint8_t *dest, uint16_t len);
+
+// write to hwfifo from buffer
+void tu_hwfifo_write(volatile void *hwfifo, const uint8_t *src, uint16_t len);
+#endif
+
//--------------------------------------------------------------------+
// Internal Helper Local
// work on local copies of read/write indices in order to only access them once for re-entrancy