summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorHiFiPhile <[email protected]>2024-04-29 22:22:59 +0200
committerHiFiPhile <[email protected]>2024-04-29 22:22:59 +0200
commitbf1540af4c3a57245b946c8622454c05e7fc098e (patch)
tree9ed0573097d821696b8775e4826cd555b26bdb1b /src/common
parentcba327fc384ae730287b0ab620d1f7ef50b0da3b (diff)
parent1c04d5992a020aefe16ffb2acce62d84d4899395 (diff)
Merge branch 'master' of https://github.com/hathach/tinyusb into pr/2132
Diffstat (limited to 'src/common')
-rw-r--r--src/common/tusb_common.h48
-rw-r--r--src/common/tusb_compiler.h2
-rw-r--r--src/common/tusb_debug.h42
-rw-r--r--src/common/tusb_fifo.c391
-rw-r--r--src/common/tusb_fifo.h31
-rw-r--r--src/common/tusb_mcu.h75
-rw-r--r--src/common/tusb_private.h19
-rw-r--r--src/common/tusb_timeout.h80
-rw-r--r--src/common/tusb_types.h186
-rw-r--r--src/common/tusb_verify.h59
10 files changed, 355 insertions, 578 deletions
diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h
index 957491aa9..0d4082c03 100644
--- a/src/common/tusb_common.h
+++ b/src/common/tusb_common.h
@@ -37,6 +37,7 @@
#define TU_ARRAY_SIZE(_arr) ( sizeof(_arr) / sizeof(_arr[0]) )
#define TU_MIN(_x, _y) ( ( (_x) < (_y) ) ? (_x) : (_y) )
#define TU_MAX(_x, _y) ( ( (_x) > (_y) ) ? (_x) : (_y) )
+#define TU_DIV_CEIL(n, d) (((n) + (d) - 1) / (d))
#define TU_U16(_high, _low) ((uint16_t) (((_high) << 8) | (_low)))
#define TU_U16_HIGH(_u16) ((uint8_t) (((_u16) >> 8) & 0x00ff))
@@ -53,6 +54,8 @@
#define U32_TO_U8S_LE(_u32) TU_U32_BYTE0(_u32), TU_U32_BYTE1(_u32), TU_U32_BYTE2(_u32), TU_U32_BYTE3(_u32)
#define TU_BIT(n) (1UL << (n))
+
+// Generate a mask with bit from high (31) to low (0) set, e.g TU_GENMASK(3, 0) = 0b1111
#define TU_GENMASK(h, l) ( (UINT32_MAX << (l)) & (UINT32_MAX >> (31 - (h))) )
//--------------------------------------------------------------------+
@@ -62,6 +65,7 @@
// Standard Headers
#include <stdbool.h>
#include <stdint.h>
+#include <inttypes.h>
#include <stddef.h>
#include <string.h>
#include <stdio.h>
@@ -73,8 +77,6 @@
#include "tusb_types.h"
#include "tusb_debug.h"
-#include "tusb_timeout.h" // TODO remove
-
//--------------------------------------------------------------------+
// Optional API implemented by application if needed
// TODO move to a more ovious place/file
@@ -99,10 +101,9 @@ TU_ATTR_WEAK extern void* tusb_app_phys_to_virt(void *phys_addr);
#define tu_varclr(_var) tu_memclr(_var, sizeof(*(_var)))
// This is a backport of memset_s from c11
-TU_ATTR_ALWAYS_INLINE static inline int tu_memset_s(void *dest, size_t destsz, int ch, size_t count)
-{
+TU_ATTR_ALWAYS_INLINE static inline int tu_memset_s(void *dest, size_t destsz, int ch, size_t count) {
// TODO may check if desst and src is not NULL
- if (count > destsz) {
+ if ( count > destsz ) {
return -1;
}
memset(dest, ch, count);
@@ -110,10 +111,9 @@ TU_ATTR_ALWAYS_INLINE static inline int tu_memset_s(void *dest, size_t destsz, i
}
// This is a backport of memcpy_s from c11
-TU_ATTR_ALWAYS_INLINE static inline int tu_memcpy_s(void *dest, size_t destsz, const void * src, size_t count )
-{
+TU_ATTR_ALWAYS_INLINE static inline int tu_memcpy_s(void *dest, size_t destsz, const void *src, size_t count) {
// TODO may check if desst and src is not NULL
- if (count > destsz) {
+ if ( count > destsz ) {
return -1;
}
memcpy(dest, src, count);
@@ -122,13 +122,11 @@ TU_ATTR_ALWAYS_INLINE static inline int tu_memcpy_s(void *dest, size_t destsz, c
//------------- Bytes -------------//
-TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_u32(uint8_t b3, uint8_t b2, uint8_t b1, uint8_t b0)
-{
+TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_u32(uint8_t b3, uint8_t b2, uint8_t b1, uint8_t b0) {
return ( ((uint32_t) b3) << 24) | ( ((uint32_t) b2) << 16) | ( ((uint32_t) b1) << 8) | b0;
}
-TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u16(uint8_t high, uint8_t low)
-{
+TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u16(uint8_t high, uint8_t low) {
return (uint16_t) ((((uint16_t) high) << 8) | low);
}
@@ -159,16 +157,20 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_max16 (uint16_t x, uint16_t y) {
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_max32 (uint32_t x, uint32_t y) { return (x > y) ? x : y; }
//------------- Align -------------//
-TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align(uint32_t value, uint32_t alignment)
-{
+TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align(uint32_t value, uint32_t alignment) {
return value & ((uint32_t) ~(alignment-1));
}
+TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align4 (uint32_t value) { return (value & 0xFFFFFFFCUL); }
+TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align8 (uint32_t value) { return (value & 0xFFFFFFF8UL); }
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align16 (uint32_t value) { return (value & 0xFFFFFFF0UL); }
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align32 (uint32_t value) { return (value & 0xFFFFFFE0UL); }
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align4k (uint32_t value) { return (value & 0xFFFFF000UL); }
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_offset4k(uint32_t value) { return (value & 0xFFFUL); }
+TU_ATTR_ALWAYS_INLINE static inline bool tu_is_aligned32(uint32_t value) { return (value & 0x1FUL) == 0; }
+TU_ATTR_ALWAYS_INLINE static inline bool tu_is_aligned64(uint64_t value) { return (value & 0x3FUL) == 0; }
+
//------------- Mathematics -------------//
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_div_ceil(uint32_t v, uint32_t d) { return (v + d -1)/d; }
@@ -260,11 +262,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_compiler.h b/src/common/tusb_compiler.h
index 6f07bdd53..0d5570b1c 100644
--- a/src/common/tusb_compiler.h
+++ b/src/common/tusb_compiler.h
@@ -56,7 +56,7 @@
#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
#define TU_VERIFY_STATIC _Static_assert
#elif defined(__CCRX__)
- #define TU_VERIFY_STATIC(const_expr, _mess) typedef char TU_XSTRCAT(Line, __LINE__)[(const_expr) ? 1 : 0];
+ #define TU_VERIFY_STATIC(const_expr, _mess) typedef char TU_XSTRCAT(_verify_static_, _TU_COUNTER_)[(const_expr) ? 1 : 0];
#else
#define TU_VERIFY_STATIC(const_expr, _mess) enum { TU_XSTRCAT(_verify_static_, _TU_COUNTER_) = 1/(!!(const_expr)) }
#endif
diff --git a/src/common/tusb_debug.h b/src/common/tusb_debug.h
index 36507041f..2e9f1d9cd 100644
--- a/src/common/tusb_debug.h
+++ b/src/common/tusb_debug.h
@@ -43,7 +43,7 @@
#if CFG_TUSB_DEBUG
// Enum to String for debugging purposes
-#if CFG_TUSB_DEBUG >= 2
+#if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL || CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
extern char const* const tu_str_speed[];
extern char const* const tu_str_std_request[];
extern char const* const tu_str_xfer_result[];
@@ -58,16 +58,15 @@ void tu_print_mem(void const *buf, uint32_t count, uint8_t indent);
#define tu_printf printf
#endif
-static inline void tu_print_arr(uint8_t const* buf, uint32_t bufsize)
-{
+static inline void tu_print_buf(uint8_t const* buf, uint32_t bufsize) {
for(uint32_t i=0; i<bufsize; i++) tu_printf("%02X ", buf[i]);
+ tu_printf("\r\n");
}
// Log with Level
#define TU_LOG(n, ...) TU_XSTRCAT(TU_LOG, n)(__VA_ARGS__)
#define TU_LOG_MEM(n, ...) TU_XSTRCAT3(TU_LOG, n, _MEM)(__VA_ARGS__)
-#define TU_LOG_ARR(n, ...) TU_XSTRCAT3(TU_LOG, n, _ARR)(__VA_ARGS__)
-#define TU_LOG_PTR(n, ...) TU_XSTRCAT3(TU_LOG, n, _PTR)(__VA_ARGS__)
+#define TU_LOG_BUF(n, ...) TU_XSTRCAT3(TU_LOG, n, _BUF)(__VA_ARGS__)
#define TU_LOG_INT(n, ...) TU_XSTRCAT3(TU_LOG, n, _INT)(__VA_ARGS__)
#define TU_LOG_HEX(n, ...) TU_XSTRCAT3(TU_LOG, n, _HEX)(__VA_ARGS__)
#define TU_LOG_LOCATION() tu_printf("%s: %d:\r\n", __PRETTY_FUNCTION__, __LINE__)
@@ -76,17 +75,15 @@ static inline void tu_print_arr(uint8_t const* buf, uint32_t bufsize)
// Log Level 1: Error
#define TU_LOG1 tu_printf
#define TU_LOG1_MEM tu_print_mem
-#define TU_LOG1_ARR(_x, _n) tu_print_arr((uint8_t const*)(_x), _n)
-#define TU_LOG1_PTR(_x) tu_print_arr((uint8_t const*)(_x), sizeof(*(_x)))
+#define TU_LOG1_BUF(_x, _n) tu_print_buf((uint8_t const*)(_x), _n)
#define TU_LOG1_INT(_x) tu_printf(#_x " = %ld\r\n", (unsigned long) (_x) )
-#define TU_LOG1_HEX(_x) tu_printf(#_x " = %lX\r\n", (unsigned long) (_x) )
+#define TU_LOG1_HEX(_x) tu_printf(#_x " = 0x%lX\r\n", (unsigned long) (_x) )
// Log Level 2: Warn
#if CFG_TUSB_DEBUG >= 2
#define TU_LOG2 TU_LOG1
#define TU_LOG2_MEM TU_LOG1_MEM
- #define TU_LOG2_ARR TU_LOG1_ARR
- #define TU_LOG2_PTR TU_LOG1_PTR
+ #define TU_LOG2_BUF TU_LOG1_BUF
#define TU_LOG2_INT TU_LOG1_INT
#define TU_LOG2_HEX TU_LOG1_HEX
#endif
@@ -95,30 +92,25 @@ static inline void tu_print_arr(uint8_t const* buf, uint32_t bufsize)
#if CFG_TUSB_DEBUG >= 3
#define TU_LOG3 TU_LOG1
#define TU_LOG3_MEM TU_LOG1_MEM
- #define TU_LOG3_ARR TU_LOG1_ARR
- #define TU_LOG3_PTR TU_LOG1_PTR
+ #define TU_LOG3_BUF TU_LOG1_BUF
#define TU_LOG3_INT TU_LOG1_INT
#define TU_LOG3_HEX TU_LOG1_HEX
#endif
-typedef struct
-{
+typedef struct {
uint32_t key;
const char* data;
} tu_lookup_entry_t;
-typedef struct
-{
+typedef struct {
uint16_t count;
tu_lookup_entry_t const* items;
} tu_lookup_table_t;
-static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint32_t key)
-{
+static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint32_t key) {
tu_static char not_found[11];
- for(uint16_t i=0; i<p_table->count; i++)
- {
+ for(uint16_t i=0; i<p_table->count; i++) {
if (p_table->items[i].key == key) return p_table->items[i].data;
}
@@ -133,7 +125,7 @@ static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint3
#ifndef TU_LOG
#define TU_LOG(n, ...)
#define TU_LOG_MEM(n, ...)
- #define TU_LOG_PTR(n, ...)
+ #define TU_LOG_BUF(n, ...)
#define TU_LOG_INT(n, ...)
#define TU_LOG_HEX(n, ...)
#define TU_LOG_LOCATION()
@@ -144,14 +136,14 @@ static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint3
#define TU_LOG0(...)
#define TU_LOG0_MEM(...)
-#define TU_LOG0_PTR(...)
+#define TU_LOG0_BUF(...)
#define TU_LOG0_INT(...)
#define TU_LOG0_HEX(...)
#ifndef TU_LOG1
#define TU_LOG1(...)
#define TU_LOG1_MEM(...)
- #define TU_LOG1_PTR(...)
+ #define TU_LOG1_BUF(...)
#define TU_LOG1_INT(...)
#define TU_LOG1_HEX(...)
#endif
@@ -159,7 +151,7 @@ static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint3
#ifndef TU_LOG2
#define TU_LOG2(...)
#define TU_LOG2_MEM(...)
- #define TU_LOG2_PTR(...)
+ #define TU_LOG2_BUF(...)
#define TU_LOG2_INT(...)
#define TU_LOG2_HEX(...)
#endif
@@ -167,7 +159,7 @@ static inline const char* tu_lookup_find(tu_lookup_table_t const* p_table, uint3
#ifndef TU_LOG3
#define TU_LOG3(...)
#define TU_LOG3_MEM(...)
- #define TU_LOG3_PTR(...)
+ #define TU_LOG3_BUF(...)
#define TU_LOG3_INT(...)
#define TU_LOG3_HEX(...)
#endif
diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c
index 323d3a754..76696396b 100644
--- a/src/common/tusb_fifo.c
+++ b/src/common/tusb_fifo.c
@@ -55,6 +55,16 @@ TU_ATTR_ALWAYS_INLINE static inline void _ff_unlock(osal_mutex_t mutex)
#endif
+/** \enum tu_fifo_copy_mode_t
+ * \brief 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
+ */
+typedef enum
+{
+ TU_FIFO_COPY_INC, ///< Copy from/to an increasing source/destination address - default mode
+ TU_FIFO_COPY_CST_FULL_WORDS, ///< Copy from/to a constant source/destination address - required for e.g. STM32 to write into USB hardware FIFO
+} tu_fifo_copy_mode_t;
+
bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable)
{
// Limit index space to 2*depth - this allows for a fast "modulo" calculation
@@ -138,7 +148,7 @@ static inline void _ff_push(tu_fifo_t* f, void const * app_buf, uint16_t rel)
}
// send n items to fifo WITHOUT updating write pointer
-static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t wr_ptr)
+static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t wr_ptr, tu_fifo_copy_mode_t copy_mode)
{
uint16_t const lin_count = f->depth - wr_ptr;
uint16_t const wrap_count = n - lin_count;
@@ -149,78 +159,72 @@ static void _ff_push_n(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t
// current buffer of fifo
uint8_t* ff_buf = f->buffer + (wr_ptr * f->item_size);
- if(n <= lin_count)
- {
- // Linear only
- memcpy(ff_buf, app_buf, n*f->item_size);
- }
- else
+ switch (copy_mode)
{
- // Wrap around
-
- // Write data to linear part of buffer
- memcpy(ff_buf, app_buf, lin_bytes);
-
- // Write data wrapped around
- // TU_ASSERT(nWrap_bytes <= f->depth, );
- memcpy(f->buffer, ((uint8_t const*) app_buf) + lin_bytes, wrap_bytes);
- }
-}
-
-// send n items to fifo WITHOUT updating write pointer
-// Version intended for hardware USB FIFOs where data is written to a constant address in full word copies
-static void _ff_push_n_const_addr(tu_fifo_t* f, void const * app_buf, uint16_t n, uint16_t wr_ptr)
-{
- uint16_t const lin_count = f->depth - wr_ptr;
- uint16_t const wrap_count = n - lin_count;
+ case TU_FIFO_COPY_INC:
+ if(n <= lin_count)
+ {
+ // Linear only
+ memcpy(ff_buf, app_buf, n*f->item_size);
+ }
+ else
+ {
+ // Wrap around
- uint16_t lin_bytes = lin_count * f->item_size;
- uint16_t wrap_bytes = wrap_count * f->item_size;
+ // Write data to linear part of buffer
+ memcpy(ff_buf, app_buf, lin_bytes);
- // current buffer of fifo
- uint8_t* ff_buf = f->buffer + (wr_ptr * f->item_size);
+ // Write data wrapped around
+ // TU_ASSERT(nWrap_bytes <= f->depth, );
+ memcpy(f->buffer, ((uint8_t const*) app_buf) + lin_bytes, wrap_bytes);
+ }
+ break;
- // Intended for hardware buffers from which it can be read word by word only
- if(n <= lin_count)
- {
- // Linear only
- _ff_push_const_addr(ff_buf, app_buf, n*f->item_size);
- }
- else
- {
- // Wrap around case
+ case TU_FIFO_COPY_CST_FULL_WORDS:
+ // Intended for hardware buffers from which it can be read word by word only
+ if(n <= lin_count)
+ {
+ // Linear only
+ _ff_push_const_addr(ff_buf, app_buf, n*f->item_size);
+ }
+ else
+ {
+ // Wrap around case
- // Write full words to linear part of buffer
- uint16_t nLin_4n_bytes = lin_bytes & 0xFFFC;
- _ff_push_const_addr(ff_buf, app_buf, nLin_4n_bytes);
- ff_buf += nLin_4n_bytes;
+ // Write full words to linear part of buffer
+ uint16_t nLin_4n_bytes = lin_bytes & 0xFFFC;
+ _ff_push_const_addr(ff_buf, app_buf, nLin_4n_bytes);
+ ff_buf += nLin_4n_bytes;
- // There could be odd 1-3 bytes before the wrap-around boundary
- uint8_t rem = lin_bytes & 0x03;
- if (rem > 0)
- {
- volatile const uint32_t * rx_fifo = (volatile const uint32_t *) app_buf;
+ // There could be odd 1-3 bytes before the wrap-around boundary
+ uint8_t rem = lin_bytes & 0x03;
+ if (rem > 0)
+ {
+ volatile const uint32_t * rx_fifo = (volatile const uint32_t *) app_buf;
- uint8_t remrem = (uint8_t) tu_min16(wrap_bytes, 4-rem);
- wrap_bytes -= remrem;
+ uint8_t remrem = (uint8_t) tu_min16(wrap_bytes, 4-rem);
+ wrap_bytes -= remrem;
- uint32_t tmp32 = *rx_fifo;
- uint8_t * src_u8 = ((uint8_t *) &tmp32);
+ uint32_t tmp32 = *rx_fifo;
+ uint8_t * src_u8 = ((uint8_t *) &tmp32);
- // Write 1-3 bytes before wrapped boundary
- while(rem--) *ff_buf++ = *src_u8++;
+ // Write 1-3 bytes before wrapped boundary
+ while(rem--) *ff_buf++ = *src_u8++;
- // Read more bytes to beginning to complete a word
- ff_buf = f->buffer;
- while(remrem--) *ff_buf++ = *src_u8++;
- }
- else
- {
- ff_buf = f->buffer; // wrap around to beginning
- }
+ // Read more bytes to beginning to complete a word
+ ff_buf = f->buffer;
+ while(remrem--) *ff_buf++ = *src_u8++;
+ }
+ else
+ {
+ ff_buf = f->buffer; // wrap around to beginning
+ }
- // Write data wrapped part
- if (wrap_bytes > 0) _ff_push_const_addr(ff_buf, app_buf, wrap_bytes);
+ // Write data wrapped part
+ if (wrap_bytes > 0) _ff_push_const_addr(ff_buf, app_buf, wrap_bytes);
+ }
+ break;
+ default: break;
}
}
@@ -231,7 +235,7 @@ static inline void _ff_pull(tu_fifo_t* f, void * app_buf, uint16_t rel)
}
// get n items from fifo WITHOUT updating read pointer
-static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rd_ptr)
+static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rd_ptr, tu_fifo_copy_mode_t copy_mode)
{
uint16_t const lin_count = f->depth - rd_ptr;
uint16_t const wrap_count = n - lin_count; // only used if wrapped
@@ -242,82 +246,76 @@ static void _ff_pull_n(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rd_ptr)
// current buffer of fifo
uint8_t* ff_buf = f->buffer + (rd_ptr * f->item_size);
- if ( n <= lin_count )
- {
- // Linear only
- memcpy(app_buf, ff_buf, n*f->item_size);
- }
- else
+ switch (copy_mode)
{
- // Wrap around
-
- // Read data from linear part of buffer
- memcpy(app_buf, ff_buf, lin_bytes);
-
- // Read data wrapped part
- memcpy((uint8_t*) app_buf + lin_bytes, f->buffer, wrap_bytes);
- }
-}
+ case TU_FIFO_COPY_INC:
+ if ( n <= lin_count )
+ {
+ // Linear only
+ memcpy(app_buf, ff_buf, n*f->item_size);
+ }
+ else
+ {
+ // Wrap around
-// get n items from fifo WITHOUT updating read pointer
-// Version intended for hardware USB FIFOs where data is read from a constant address in full word copies
-static void _ff_pull_n_const_addr(tu_fifo_t* f, void* app_buf, uint16_t n, uint16_t rd_ptr)
-{
- uint16_t const lin_count = f->depth - rd_ptr;
- uint16_t const wrap_count = n - lin_count; // only used if wrapped
+ // Read data from linear part of buffer
+ memcpy(app_buf, ff_buf, lin_bytes);
- uint16_t lin_bytes = lin_count * f->item_size;
- uint16_t wrap_bytes = wrap_count * f->item_size;
+ // Read data wrapped part
+ memcpy((uint8_t*) app_buf + lin_bytes, f->buffer, wrap_bytes);
+ }
+ break;
- // current buffer of fifo
- uint8_t* ff_buf = f->buffer + (rd_ptr * f->item_size);
+ case TU_FIFO_COPY_CST_FULL_WORDS:
+ if ( n <= lin_count )
+ {
+ // Linear only
+ _ff_pull_const_addr(app_buf, ff_buf, n*f->item_size);
+ }
+ else
+ {
+ // Wrap around case
- if ( n <= lin_count )
- {
- // Linear only
- _ff_pull_const_addr(app_buf, ff_buf, n*f->item_size);
- }
- else
- {
- // Wrap around case
+ // Read full words from linear part of buffer
+ uint16_t lin_4n_bytes = lin_bytes & 0xFFFC;
+ _ff_pull_const_addr(app_buf, ff_buf, lin_4n_bytes);
+ ff_buf += lin_4n_bytes;
- // Read full words from linear part of buffer
- uint16_t lin_4n_bytes = lin_bytes & 0xFFFC;
- _ff_pull_const_addr(app_buf, ff_buf, lin_4n_bytes);
- ff_buf += lin_4n_bytes;
+ // There could be odd 1-3 bytes before the wrap-around boundary
+ uint8_t rem = lin_bytes & 0x03;
+ if (rem > 0)
+ {
+ volatile uint32_t * reg_tx = (volatile uint32_t *) app_buf;
- // There could be odd 1-3 bytes before the wrap-around boundary
- uint8_t rem = lin_bytes & 0x03;
- if (rem > 0)
- {
- volatile uint32_t * reg_tx = (volatile uint32_t *) app_buf;
+ uint8_t remrem = (uint8_t) tu_min16(wrap_bytes, 4-rem);
+ wrap_bytes -= remrem;
- uint8_t remrem = (uint8_t) tu_min16(wrap_bytes, 4-rem);
- wrap_bytes -= remrem;
+ uint32_t tmp32=0;
+ uint8_t * dst_u8 = (uint8_t *)&tmp32;
- uint32_t tmp32=0;
- uint8_t * dst_u8 = (uint8_t *)&tmp32;
+ // Read 1-3 bytes before wrapped boundary
+ while(rem--) *dst_u8++ = *ff_buf++;
- // Read 1-3 bytes before wrapped boundary
- while(rem--) *dst_u8++ = *ff_buf++;
+ // Read more bytes from beginning to complete a word
+ ff_buf = f->buffer;
+ while(remrem--) *dst_u8++ = *ff_buf++;
- // Read more bytes from beginning to complete a word
- ff_buf = f->buffer;
- while(remrem--) *dst_u8++ = *ff_buf++;
+ *reg_tx = tmp32;
+ }
+ else
+ {
+ ff_buf = f->buffer; // wrap around to beginning
+ }
- *reg_tx = tmp32;
- }
- else
- {
- ff_buf = f->buffer; // wrap around to beginning
- }
+ // Read data wrapped part
+ if (wrap_bytes > 0) _ff_pull_const_addr(app_buf, ff_buf, wrap_bytes);
+ }
+ break;
- // Read data wrapped part
- if (wrap_bytes > 0) _ff_pull_const_addr(app_buf, ff_buf, wrap_bytes);
+ default: break;
}
}
-
//--------------------------------------------------------------------+
// Helper
//--------------------------------------------------------------------+
@@ -438,7 +436,7 @@ static bool _tu_fifo_peek(tu_fifo_t* f, void * p_buffer, uint16_t wr_idx, uint16
// Works on local copies of w and r
// Must be protected by mutexes since in case of an overflow read pointer gets modified
-static uint16_t _tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n, uint16_t wr_idx, uint16_t rd_idx)
+static uint16_t _tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n, uint16_t wr_idx, uint16_t rd_idx, tu_fifo_copy_mode_t copy_mode)
{
uint16_t cnt = _ff_count(f->depth, wr_idx, rd_idx);
@@ -458,40 +456,12 @@ static uint16_t _tu_fifo_peek_n(tu_fifo_t* f, void * p_buffer, uint16_t n, uint1
uint16_t rd_ptr = idx2ptr(f->depth, rd_idx);
// Peek data
- _ff_pull_n(f, p_buffer, n, rd_ptr);
+ _ff_pull_n(f, p_buffer, n, rd_ptr, copy_mode);
return n;
}
-// Works on local copies of w and r
-// Must be protected by mutexes since in case of an overflow read pointer gets modified
-// Version intended for hardware USB FIFOs where data is read from a constant address in full word copies
-static uint16_t _tu_fifo_peek_n_const_addr(tu_fifo_t* f, void * p_buffer, uint16_t n, uint16_t wr_idx, uint16_t rd_idx)
-{
- uint16_t cnt = _ff_count(f->depth, wr_idx, rd_idx);
-
- // nothing to peek
- if ( cnt == 0 ) return 0;
-
- // Check overflow and correct if required
- if ( cnt > f->depth )
- {
- rd_idx = _ff_correct_read_index(f, wr_idx);
- cnt = f->depth;
- }
-
- // Check if we can read something at and after offset - if too less is available we read what remains
- if ( cnt < n ) n = cnt;
-
- uint16_t rd_ptr = idx2ptr(f->depth, rd_idx);
-
- // Peek data
- _ff_pull_n_const_addr(f, p_buffer, n, rd_ptr);
-
- return n;
-}
-
-static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n)
+static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu_fifo_copy_mode_t copy_mode)
{
if ( n == 0 ) return 0;
@@ -520,87 +490,15 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n)
if ( n >= f->depth )
{
// Only copy last part
- buf8 += (n - f->depth) * f->item_size;
- n = f->depth;
-
- // We start writing at the read pointer's position since we fill the whole buffer
- wr_idx = rd_idx;
- }
- else
- {
- uint16_t const overflowable_count = _ff_count(f->depth, wr_idx, rd_idx);
- if (overflowable_count + n >= 2*f->depth)
+ if ( copy_mode == TU_FIFO_COPY_INC )
{
- // Double overflowed
- // Index is bigger than the allowed range [0,2*depth)
- // re-position write index to have a full fifo after pushed
- wr_idx = advance_index(f->depth, rd_idx, f->depth - n);
-
- // TODO we should also shift out n bytes from read index since we avoid changing rd index !!
- // However memmove() is expensive due to actual copying + wrapping consideration.
- // Also race condition could happen anyway if read() is invoke while moving result in corrupted memory
- // currently deliberately not implemented --> result in incorrect data read back
+ buf8 += (n - f->depth) * f->item_size;
}else
{
- // normal + single overflowed:
- // Index is in the range of [0,2*depth) and thus detect and recoverable. Recovering is handled in read()
- // Therefore we just increase write index
- // we will correct (re-position) read index later on in fifo_read() function
+ // TODO should read from hw fifo to discard data, however reading an odd number could
+ // accidentally discard data.
}
- }
- }
-
- if (n)
- {
- uint16_t wr_ptr = idx2ptr(f->depth, wr_idx);
-
- TU_LOG(TU_FIFO_DBG, "actual_n = %u, wr_ptr = %u", n, wr_ptr);
-
- // Write data
- _ff_push_n(f, buf8, n, wr_ptr);
-
- // Advance index
- f->wr_idx = advance_index(f->depth, wr_idx, n);
-
- TU_LOG(TU_FIFO_DBG, "\tnew_wr = %u\n", f->wr_idx);
- }
-
- _ff_unlock(f->mutex_wr);
- return n;
-}
-
-static uint16_t _tu_fifo_write_n_const_addr(tu_fifo_t* f, const void * data, uint16_t n)
-{
- if ( n == 0 ) return 0;
-
- _ff_lock(f->mutex_wr);
-
- uint16_t wr_idx = f->wr_idx;
- uint16_t rd_idx = f->rd_idx;
-
- uint8_t const* buf8 = (uint8_t const*) data;
-
- TU_LOG(TU_FIFO_DBG, "rd = %3u, wr = %3u, count = %3u, remain = %3u, n = %3u: ",
- rd_idx, wr_idx, _ff_count(f->depth, wr_idx, rd_idx), _ff_remaining(f->depth, wr_idx, rd_idx), n);
-
- if ( !f->overwritable )
- {
- // limit up to full
- uint16_t const remain = _ff_remaining(f->depth, wr_idx, rd_idx);
- n = tu_min16(n, remain);
- }
- else
- {
- // In over-writable mode, fifo_write() is allowed even when fifo is full. In such case,
- // oldest data in fifo i.e at read pointer data will be overwritten
- // Note: we can modify read buffer contents but we must not modify the read index itself within a write function!
- // Since it would end up in a race condition with read functions!
- if ( n >= f->depth )
- {
- // Only copy last part
- // TODO should read from hw fifo to discard data, however reading an odd number could
- // accidentally discard data.
n = f->depth;
// We start writing at the read pointer's position since we fill the whole buffer
@@ -637,12 +535,12 @@ static uint16_t _tu_fifo_write_n_const_addr(tu_fifo_t* f, const void * data, uin
TU_LOG(TU_FIFO_DBG, "actual_n = %u, wr_ptr = %u", n, wr_ptr);
// Write data
- _ff_push_n_const_addr(f, buf8, n, wr_ptr);
+ _ff_push_n(f, buf8, n, wr_ptr, copy_mode);
// Advance index
f->wr_idx = advance_index(f->depth, wr_idx, n);
- TU_LOG(TU_FIFO_DBG, "\tnew_wr = %u\n", f->wr_idx);
+ TU_LOG(TU_FIFO_DBG, "\tnew_wr = %u\r\n", f->wr_idx);
}
_ff_unlock(f->mutex_wr);
@@ -650,28 +548,13 @@ static uint16_t _tu_fifo_write_n_const_addr(tu_fifo_t* f, const void * data, uin
return n;
}
-static uint16_t _tu_fifo_read_n(tu_fifo_t* f, void * buffer, uint16_t n)
-{
- _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(f, buffer, n, f->wr_idx, f->rd_idx);
-
- // Advance read pointer
- f->rd_idx = advance_index(f->depth, f->rd_idx, n);
-
- _ff_unlock(f->mutex_rd);
- return n;
-}
-
-static uint16_t _tu_fifo_read_n_const_addr(tu_fifo_t* f, void * buffer, uint16_t n)
+static uint16_t _tu_fifo_read_n(tu_fifo_t* f, void * buffer, uint16_t n, tu_fifo_copy_mode_t copy_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_const_addr(f, buffer, n, f->wr_idx, f->rd_idx);
+ n = _tu_fifo_peek_n(f, buffer, n, f->wr_idx, f->rd_idx, copy_mode);
// Advance read pointer
f->rd_idx = advance_index(f->depth, f->rd_idx, n);
@@ -841,12 +724,12 @@ bool tu_fifo_read(tu_fifo_t* f, void * buffer)
/******************************************************************************/
uint16_t tu_fifo_read_n(tu_fifo_t* f, void * buffer, uint16_t n)
{
- return _tu_fifo_read_n(f, buffer, n);
+ return _tu_fifo_read_n(f, buffer, n, TU_FIFO_COPY_INC);
}
uint16_t tu_fifo_read_n_const_addr_full_words(tu_fifo_t* f, void * buffer, uint16_t n)
{
- return _tu_fifo_read_n_const_addr(f, buffer, n);
+ return _tu_fifo_read_n(f, buffer, n, TU_FIFO_COPY_CST_FULL_WORDS);
}
/******************************************************************************/
@@ -888,7 +771,7 @@ 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)
{
_ff_lock(f->mutex_rd);
- uint16_t ret = _tu_fifo_peek_n(f, p_buffer, n, f->wr_idx, f->rd_idx);
+ uint16_t ret = _tu_fifo_peek_n(f, p_buffer, n, f->wr_idx, f->rd_idx, TU_FIFO_COPY_INC);
_ff_unlock(f->mutex_rd);
return ret;
}
@@ -953,7 +836,7 @@ bool tu_fifo_write(tu_fifo_t* f, const void * data)
/******************************************************************************/
uint16_t tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n)
{
- return _tu_fifo_write_n(f, data, n);
+ return _tu_fifo_write_n(f, data, n, TU_FIFO_COPY_INC);
}
/******************************************************************************/
@@ -973,7 +856,7 @@ uint16_t tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n)
/******************************************************************************/
uint16_t tu_fifo_write_n_const_addr_full_words(tu_fifo_t* f, const void * data, uint16_t n)
{
- return _tu_fifo_write_n_const_addr(f, data, n);
+ return _tu_fifo_write_n(f, data, n, TU_FIFO_COPY_CST_FULL_WORDS);
}
/******************************************************************************/
diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h
index 2f60ec2f4..2d9f5e667 100644
--- a/src/common/tusb_fifo.h
+++ b/src/common/tusb_fifo.h
@@ -102,10 +102,8 @@ extern "C" {
* |
* -------------------------
* | R | 1 | 2 | W | 4 | 5 |
-
*/
-typedef struct
-{
+typedef struct {
uint8_t* buffer ; // buffer pointer
uint16_t depth ; // max items
@@ -124,16 +122,14 @@ typedef struct
} tu_fifo_t;
-typedef struct
-{
+typedef struct {
uint16_t len_lin ; ///< linear length in item size
uint16_t len_wrap ; ///< wrapped length in item size
void * ptr_lin ; ///< linear part start pointer
void * ptr_wrap ; ///< wrapped part start pointer
} tu_fifo_buffer_info_t;
-#define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable) \
-{ \
+#define TU_FIFO_INIT(_buffer, _depth, _type, _overwritable){\
.buffer = _buffer, \
.depth = _depth, \
.item_size = sizeof(_type), \
@@ -144,23 +140,18 @@ typedef struct
uint8_t _name##_buf[_depth*sizeof(_type)]; \
tu_fifo_t _name = TU_FIFO_INIT(_name##_buf, _depth, _type, _overwritable)
-
bool tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable);
bool tu_fifo_clear(tu_fifo_t *f);
bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_size, bool overwritable);
#if OSAL_MUTEX_REQUIRED
-TU_ATTR_ALWAYS_INLINE static inline
-void tu_fifo_config_mutex(tu_fifo_t *f, osal_mutex_t wr_mutex, osal_mutex_t rd_mutex)
-{
- f->mutex_wr = wr_mutex;
- f->mutex_rd = rd_mutex;
-}
-
+ TU_ATTR_ALWAYS_INLINE static inline
+ void tu_fifo_config_mutex(tu_fifo_t *f, osal_mutex_t wr_mutex, osal_mutex_t rd_mutex) {
+ f->mutex_wr = wr_mutex;
+ f->mutex_rd = rd_mutex;
+ }
#else
-
-#define tu_fifo_config_mutex(_f, _wr_mutex, _rd_mutex)
-
+ #define tu_fifo_config_mutex(_f, _wr_mutex, _rd_mutex)
#endif
bool tu_fifo_write (tu_fifo_t* f, void const * p_data);
@@ -182,8 +173,7 @@ bool tu_fifo_overflowed (tu_fifo_t* f);
void tu_fifo_correct_read_pointer (tu_fifo_t* f);
TU_ATTR_ALWAYS_INLINE static inline
-uint16_t tu_fifo_depth(tu_fifo_t* f)
-{
+uint16_t tu_fifo_depth(tu_fifo_t* f) {
return f->depth;
}
@@ -198,7 +188,6 @@ void tu_fifo_advance_read_pointer (tu_fifo_t *f, uint16_t n);
void tu_fifo_get_read_info (tu_fifo_t *f, tu_fifo_buffer_info_t *info);
void tu_fifo_get_write_info(tu_fifo_t *f, tu_fifo_buffer_info_t *info);
-
#ifdef __cplusplus
}
#endif
diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h
index 9f3be78fd..5a567f2d5 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
@@ -52,6 +58,7 @@
// NXP
//--------------------------------------------------------------------+
#if TU_CHECK_MCU(OPT_MCU_LPC11UXX, OPT_MCU_LPC13XX, OPT_MCU_LPC15XX)
+ #define TUP_USBIP_IP3511
#define TUP_DCD_ENDPOINT_MAX 5
#elif TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX)
@@ -60,14 +67,17 @@
#define TUP_OHCI_RHPORTS 2
#elif TU_CHECK_MCU(OPT_MCU_LPC51UXX)
+ #define TUP_USBIP_IP3511
#define TUP_DCD_ENDPOINT_MAX 5
-#elif TU_CHECK_MCU(OPT_MCU_LPC54XXX)
+#elif TU_CHECK_MCU(OPT_MCU_LPC54)
// TODO USB0 has 5, USB1 has 6
+ #define TUP_USBIP_IP3511
#define TUP_DCD_ENDPOINT_MAX 6
-#elif TU_CHECK_MCU(OPT_MCU_LPC55XX)
+#elif TU_CHECK_MCU(OPT_MCU_LPC55)
// TODO USB0 has 5, USB1 has 6
+ #define TUP_USBIP_IP3511
#define TUP_DCD_ENDPOINT_MAX 6
#elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX)
@@ -90,6 +100,13 @@
#define TUP_DCD_ENDPOINT_MAX 8
#define TUP_RHPORT_HIGHSPEED 1
+#elif TU_CHECK_MCU(OPT_MCU_MCXA15)
+ // USB0 is chipidea FS
+ #define TUP_USBIP_CHIPIDEA_FS
+ #define TUP_USBIP_CHIPIDEA_FS_MCX
+
+ #define TUP_DCD_ENDPOINT_MAX 16
+
#elif TU_CHECK_MCU(OPT_MCU_MIMXRT1XXX)
#define TUP_USBIP_CHIPIDEA_HS
#define TUP_USBIP_EHCI
@@ -97,7 +114,7 @@
#define TUP_DCD_ENDPOINT_MAX 8
#define TUP_RHPORT_HIGHSPEED 1
-#elif TU_CHECK_MCU(OPT_MCU_KINETIS_KL, OPT_MCU_KINETIS_K32L)
+#elif TU_CHECK_MCU(OPT_MCU_KINETIS_KL, OPT_MCU_KINETIS_K32L, OPT_MCU_KINETIS_K)
#define TUP_USBIP_CHIPIDEA_FS
#define TUP_USBIP_CHIPIDEA_FS_KINETIS
#define TUP_DCD_ENDPOINT_MAX 16
@@ -200,6 +217,11 @@
#define TUP_DCD_ENDPOINT_MAX 9
+#elif TU_CHECK_MCU(OPT_MCU_STM32H5)
+ #define TUP_USBIP_FSDEV
+ #define TUP_USBIP_FSDEV_STM32
+ #define TUP_DCD_ENDPOINT_MAX 8
+
#elif TU_CHECK_MCU(OPT_MCU_STM32G4)
// Device controller
#define TUP_USBIP_FSDEV
@@ -207,9 +229,7 @@
// TypeC controller
#define TUP_USBIP_TYPEC_STM32
-
#define TUP_DCD_ENDPOINT_MAX 8
-
#define TUP_TYPEC_RHPORTS_NUM 1
#elif TU_CHECK_MCU(OPT_MCU_STM32G0)
@@ -251,14 +271,21 @@
#elif TU_CHECK_MCU(OPT_MCU_STM32U5)
#define TUP_USBIP_DWC2
#define TUP_USBIP_DWC2_STM32
- #define TUP_DCD_ENDPOINT_MAX 6
+
+ // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY
+ #if defined(STM32U595xx) || defined(STM32U599xx) || defined(STM32U5A5xx) || defined(STM32U5A9xx) || \
+ defined(STM32U5F7xx) || defined(STM32U5F9xx) || defined(STM32U5G7xx) || defined(STM32U5G9xx)
+ #define TUP_DCD_ENDPOINT_MAX 9
+ #define TUP_RHPORT_HIGHSPEED 1
+ #else
+ #define TUP_DCD_ENDPOINT_MAX 6
+ #endif
#elif TU_CHECK_MCU(OPT_MCU_STM32L5)
#define TUP_USBIP_FSDEV
#define TUP_USBIP_FSDEV_STM32
#define TUP_DCD_ENDPOINT_MAX 8
-
//--------------------------------------------------------------------+
// Sony
//--------------------------------------------------------------------+
@@ -302,6 +329,9 @@
#define TUP_USBIP_DWC2
#define TUP_DCD_ENDPOINT_MAX 6
+#elif TU_CHECK_MCU(OPT_MCU_ESP32) && (CFG_TUD_ENABLED || !(defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421))
+ #error "MCUs are only supported with CFG_TUH_MAX3421 enabled"
+
//--------------------------------------------------------------------+
// Dialog
//--------------------------------------------------------------------+
@@ -327,6 +357,7 @@
// Renesas
//--------------------------------------------------------------------+
#elif TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N, OPT_MCU_RAXXX)
+ #define TUP_USBIP_RUSB2
#define TUP_DCD_ENDPOINT_MAX 10
//--------------------------------------------------------------------+
@@ -372,8 +403,24 @@
#elif TU_CHECK_MCU(OPT_MCU_CH32V307)
#define TUP_DCD_ENDPOINT_MAX 16
#define TUP_RHPORT_HIGHSPEED 1
+
+#elif TU_CHECK_MCU(OPT_MCU_CH32F20X)
+ #define TUP_DCD_ENDPOINT_MAX 16
+ #define TUP_RHPORT_HIGHSPEED 1
#endif
+
+//--------------------------------------------------------------------+
+// External USB controller
+//--------------------------------------------------------------------+
+
+#if defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421
+ #ifndef CFG_TUH_MAX3421_ENDPOINT_TOTAL
+ #define CFG_TUH_MAX3421_ENDPOINT_TOTAL (8 + 4*(CFG_TUH_DEVICE_MAX-1))
+ #endif
+#endif
+
+
//--------------------------------------------------------------------+
// Default Values
//--------------------------------------------------------------------+
@@ -382,8 +429,8 @@
#define TUP_MCU_MULTIPLE_CORE 0
#endif
-#ifndef TUP_DCD_ENDPOINT_MAX
- #warning "TUP_DCD_ENDPOINT_MAX is not defined for this MCU, default to 8"
+#if !defined(TUP_DCD_ENDPOINT_MAX) && defined(CFG_TUD_ENABLED) && CFG_TUD_ENABLED
+#warning "TUP_DCD_ENDPOINT_MAX is not defined for this MCU, default to 8"
#define TUP_DCD_ENDPOINT_MAX 8
#endif
@@ -397,4 +444,8 @@
#define TU_ATTR_FAST_FUNC
#endif
+#if defined(TUP_USBIP_DWC2) || defined(TUP_USBIP_FSDEV)
+ #define TUP_DCD_EDPT_ISO_ALLOC
+#endif
+
#endif
diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h
index db1ba974d..373a50256 100644
--- a/src/common/tusb_private.h
+++ b/src/common/tusb_private.h
@@ -60,7 +60,7 @@ typedef struct {
tu_fifo_t ff;
// mutex: read if ep rx, write if e tx
- OSAL_MUTEX_DEF(ff_mutex);
+ OSAL_MUTEX_DEF(ff_mutexdef);
}tu_edpt_stream_t;
@@ -87,15 +87,17 @@ bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex);
// Endpoint Stream
//--------------------------------------------------------------------+
-// Init an stream, should only be called once
+// Init an endpoint stream
bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool overwritable,
void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize);
+// Deinit an endpoint stream
+bool tu_edpt_stream_deinit(tu_edpt_stream_t* s);
+
// Open an stream for an endpoint
// hwid is either device address (host mode) or rhport (device mode)
TU_ATTR_ALWAYS_INLINE static inline
-void tu_edpt_stream_open(tu_edpt_stream_t* s, uint8_t hwid, tusb_desc_endpoint_t const *desc_ep)
-{
+void tu_edpt_stream_open(tu_edpt_stream_t* s, uint8_t hwid, tusb_desc_endpoint_t const *desc_ep) {
tu_fifo_clear(&s->ff);
s->hwid = hwid;
s->ep_addr = desc_ep->bEndpointAddress;
@@ -103,16 +105,14 @@ void tu_edpt_stream_open(tu_edpt_stream_t* s, uint8_t hwid, tusb_desc_endpoint_t
}
TU_ATTR_ALWAYS_INLINE static inline
-void tu_edpt_stream_close(tu_edpt_stream_t* s)
-{
+void tu_edpt_stream_close(tu_edpt_stream_t* s) {
s->hwid = 0;
s->ep_addr = 0;
}
// Clear fifo
TU_ATTR_ALWAYS_INLINE static inline
-bool tu_edpt_stream_clear(tu_edpt_stream_t* s)
-{
+bool tu_edpt_stream_clear(tu_edpt_stream_t* s) {
return tu_fifo_clear(&s->ff);
}
@@ -131,8 +131,7 @@ bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferr
// Get the number of bytes available for writing
TU_ATTR_ALWAYS_INLINE static inline
-uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s)
-{
+uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s) {
return (uint32_t) tu_fifo_remaining(&s->ff);
}
diff --git a/src/common/tusb_timeout.h b/src/common/tusb_timeout.h
deleted file mode 100644
index 533e67ab8..000000000
--- a/src/common/tusb_timeout.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2019 Ha Thach (tinyusb.org)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- *
- * This file is part of the TinyUSB stack.
- */
-
-/** \ingroup Group_Common Common Files
- * \defgroup Group_TimeoutTimer timeout timer
- * @{ */
-
-#ifndef _TUSB_TIMEOUT_H_
-#define _TUSB_TIMEOUT_H_
-
-#include <stdbool.h>
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct {
- uint32_t start;
- uint32_t interval;
-}tu_timeout_t;
-
-#if 0
-
-extern uint32_t tusb_hal_millis(void);
-
-static inline void tu_timeout_set(tu_timeout_t* tt, uint32_t msec)
-{
- tt->interval = msec;
- tt->start = tusb_hal_millis();
-}
-
-static inline bool tu_timeout_expired(tu_timeout_t* tt)
-{
- return ( tusb_hal_millis() - tt->start ) >= tt->interval;
-}
-
-// For used with periodic event to prevent drift
-static inline void tu_timeout_reset(tu_timeout_t* tt)
-{
- tt->start += tt->interval;
-}
-
-static inline void tu_timeout_restart(tu_timeout_t* tt)
-{
- tt->start = tusb_hal_millis();
-}
-
-#endif
-
-#ifdef __cplusplus
- }
-#endif
-
-#endif /* _TUSB_TIMEOUT_H_ */
-
-/** @} */
diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h
index fab680989..b571f9b72 100644
--- a/src/common/tusb_types.h
+++ b/src/common/tusb_types.h
@@ -24,12 +24,8 @@
* This file is part of the TinyUSB stack.
*/
-/** \ingroup group_usb_definitions
- * \defgroup USBDef_Type USB Types
- * @{ */
-
-#ifndef _TUSB_TYPES_H_
-#define _TUSB_TYPES_H_
+#ifndef TUSB_TYPES_H_
+#define TUSB_TYPES_H_
#include <stdbool.h>
#include <stdint.h>
@@ -44,43 +40,38 @@
*------------------------------------------------------------------*/
/// defined base on EHCI specs value for Endpoint Speed
-typedef enum
-{
+typedef enum {
TUSB_SPEED_FULL = 0,
TUSB_SPEED_LOW = 1,
TUSB_SPEED_HIGH = 2,
TUSB_SPEED_INVALID = 0xff,
-}tusb_speed_t;
+} tusb_speed_t;
/// defined base on USB Specs Endpoint's bmAttributes
-typedef enum
-{
+typedef enum {
TUSB_XFER_CONTROL = 0 ,
TUSB_XFER_ISOCHRONOUS ,
TUSB_XFER_BULK ,
TUSB_XFER_INTERRUPT
-}tusb_xfer_type_t;
+} tusb_xfer_type_t;
-typedef enum
-{
+typedef enum {
TUSB_DIR_OUT = 0,
TUSB_DIR_IN = 1,
TUSB_DIR_IN_MASK = 0x80
-}tusb_dir_t;
+} tusb_dir_t;
-enum
-{
+enum {
TUSB_EPSIZE_BULK_FS = 64,
- TUSB_EPSIZE_BULK_HS= 512,
+ TUSB_EPSIZE_BULK_HS = 512,
TUSB_EPSIZE_ISO_FS_MAX = 1023,
TUSB_EPSIZE_ISO_HS_MAX = 1024,
};
-/// Isochronous End Point Attributes
-typedef enum
-{
+/// Isochronous Endpoint Attributes
+typedef enum {
TUSB_ISO_EP_ATT_NO_SYNC = 0x00,
TUSB_ISO_EP_ATT_ASYNCHRONOUS = 0x04,
TUSB_ISO_EP_ATT_ADAPTIVE = 0x08,
@@ -88,11 +79,10 @@ typedef enum
TUSB_ISO_EP_ATT_DATA = 0x00, ///< Data End Point
TUSB_ISO_EP_ATT_EXPLICIT_FB = 0x10, ///< Feedback End Point
TUSB_ISO_EP_ATT_IMPLICIT_FB = 0x20, ///< Data endpoint that also serves as an implicit feedback
-}tusb_iso_ep_attribute_t;
+} tusb_iso_ep_attribute_t;
/// USB Descriptor Types
-typedef enum
-{
+typedef enum {
TUSB_DESC_DEVICE = 0x01,
TUSB_DESC_CONFIGURATION = 0x02,
TUSB_DESC_STRING = 0x03,
@@ -119,10 +109,9 @@ typedef enum
TUSB_DESC_SUPERSPEED_ENDPOINT_COMPANION = 0x30,
TUSB_DESC_SUPERSPEED_ISO_ENDPOINT_COMPANION = 0x31
-}tusb_desc_type_t;
+} tusb_desc_type_t;
-typedef enum
-{
+typedef enum {
TUSB_REQ_GET_STATUS = 0 ,
TUSB_REQ_CLEAR_FEATURE = 1 ,
TUSB_REQ_RESERVED = 2 ,
@@ -136,25 +125,22 @@ typedef enum
TUSB_REQ_GET_INTERFACE = 10 ,
TUSB_REQ_SET_INTERFACE = 11 ,
TUSB_REQ_SYNCH_FRAME = 12
-}tusb_request_code_t;
+} tusb_request_code_t;
-typedef enum
-{
+typedef enum {
TUSB_REQ_FEATURE_EDPT_HALT = 0,
TUSB_REQ_FEATURE_REMOTE_WAKEUP = 1,
TUSB_REQ_FEATURE_TEST_MODE = 2
-}tusb_request_feature_selector_t;
+} tusb_request_feature_selector_t;
-typedef enum
-{
+typedef enum {
TUSB_REQ_TYPE_STANDARD = 0,
TUSB_REQ_TYPE_CLASS,
TUSB_REQ_TYPE_VENDOR,
TUSB_REQ_TYPE_INVALID
} tusb_request_type_t;
-typedef enum
-{
+typedef enum {
TUSB_REQ_RCPT_DEVICE =0,
TUSB_REQ_RCPT_INTERFACE,
TUSB_REQ_RCPT_ENDPOINT,
@@ -162,8 +148,7 @@ typedef enum
} tusb_request_recipient_t;
// https://www.usb.org/defined-class-codes
-typedef enum
-{
+typedef enum {
TUSB_CLASS_UNSPECIFIED = 0 ,
TUSB_CLASS_AUDIO = 1 ,
TUSB_CLASS_CDC = 2 ,
@@ -187,26 +172,23 @@ typedef enum
TUSB_CLASS_MISC = 0xEF ,
TUSB_CLASS_APPLICATION_SPECIFIC = 0xFE ,
TUSB_CLASS_VENDOR_SPECIFIC = 0xFF
-}tusb_class_code_t;
+} tusb_class_code_t;
typedef enum
{
MISC_SUBCLASS_COMMON = 2
}misc_subclass_type_t;
-typedef enum
-{
+typedef enum {
MISC_PROTOCOL_IAD = 1
-}misc_protocol_type_t;
+} misc_protocol_type_t;
-typedef enum
-{
+typedef enum {
APP_SUBCLASS_USBTMC = 0x03,
APP_SUBCLASS_DFU_RUNTIME = 0x01
} app_subclass_type_t;
-typedef enum
-{
+typedef enum {
DEVICE_CAPABILITY_WIRELESS_USB = 0x01,
DEVICE_CAPABILITY_USB20_EXTENSION = 0x02,
DEVICE_CAPABILITY_SUPERSPEED_USB = 0x03,
@@ -223,11 +205,11 @@ typedef enum
DEVICE_CAPABILITY_AUTHENTICATION = 0x0E,
DEVICE_CAPABILITY_BILLBOARD_EX = 0x0F,
DEVICE_CAPABILITY_CONFIGURATION_SUMMARY = 0x10
-}device_capability_type_t;
+} device_capability_type_t;
enum {
- TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP = TU_BIT(5),
- TUSB_DESC_CONFIG_ATT_SELF_POWERED = TU_BIT(6),
+ TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP = 1u << 5,
+ TUSB_DESC_CONFIG_ATT_SELF_POWERED = 1u << 6,
};
#define TUSB_DESC_CONFIG_POWER_MA(x) ((x)/2)
@@ -235,28 +217,25 @@ enum {
//--------------------------------------------------------------------+
//
//--------------------------------------------------------------------+
-typedef enum
-{
+typedef enum {
XFER_RESULT_SUCCESS = 0,
XFER_RESULT_FAILED,
XFER_RESULT_STALLED,
XFER_RESULT_TIMEOUT,
XFER_RESULT_INVALID
-}xfer_result_t;
+} xfer_result_t;
-enum // TODO remove
-{
+// TODO remove
+enum {
DESC_OFFSET_LEN = 0,
DESC_OFFSET_TYPE = 1
};
-enum
-{
+enum {
INTERFACE_INVALID_NUMBER = 0xff
};
-typedef enum
-{
+typedef enum {
MS_OS_20_SET_HEADER_DESCRIPTOR = 0x00,
MS_OS_20_SUBSET_HEADER_CONFIGURATION = 0x01,
MS_OS_20_SUBSET_HEADER_FUNCTION = 0x02,
@@ -268,16 +247,14 @@ typedef enum
MS_OS_20_FEATURE_VENDOR_REVISION = 0x08
} microsoft_os_20_type_t;
-enum
-{
+enum {
CONTROL_STAGE_IDLE,
CONTROL_STAGE_SETUP,
CONTROL_STAGE_DATA,
CONTROL_STAGE_ACK
};
-enum
-{
+enum {
TUSB_INDEX_INVALID_8 = 0xFFu
};
@@ -290,15 +267,14 @@ TU_ATTR_PACKED_BEGIN
TU_ATTR_BIT_FIELD_ORDER_BEGIN
/// USB Device Descriptor
-typedef struct TU_ATTR_PACKED
-{
+typedef struct TU_ATTR_PACKED {
uint8_t bLength ; ///< Size of this descriptor in bytes.
uint8_t bDescriptorType ; ///< DEVICE Descriptor Type.
- uint16_t bcdUSB ; ///< BUSB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H). This field identifies the release of the USB Specification with which the device and its descriptors are compliant.
+ uint16_t bcdUSB ; ///< BUSB Specification Release Number in Binary-Coded Decimal (i.e., 2.10 is 210H).
- uint8_t bDeviceClass ; ///< Class code (assigned by the USB-IF). \li If this field is reset to zero, each interface within a configuration specifies its own class information and the various interfaces operate independently. \li If this field is set to a value between 1 and FEH, the device supports different class specifications on different interfaces and the interfaces may not operate independently. This value identifies the class definition used for the aggregate interfaces. \li If this field is set to FFH, the device class is vendor-specific.
- uint8_t bDeviceSubClass ; ///< Subclass code (assigned by the USB-IF). These codes are qualified by the value of the bDeviceClass field. \li If the bDeviceClass field is reset to zero, this field must also be reset to zero. \li If the bDeviceClass field is not set to FFH, all values are reserved for assignment by the USB-IF.
- uint8_t bDeviceProtocol ; ///< Protocol code (assigned by the USB-IF). These codes are qualified by the value of the bDeviceClass and the bDeviceSubClass fields. If a device supports class-specific protocols on a device basis as opposed to an interface basis, this code identifies the protocols that the device uses as defined by the specification of the device class. \li If this field is reset to zero, the device does not use class-specific protocols on a device basis. However, it may use classspecific protocols on an interface basis. \li If this field is set to FFH, the device uses a vendor-specific protocol on a device basis.
+ uint8_t bDeviceClass ; ///< Class code (assigned by the USB-IF).
+ uint8_t bDeviceSubClass ; ///< Subclass code (assigned by the USB-IF).
+ uint8_t bDeviceProtocol ; ///< Protocol code (assigned by the USB-IF).
uint8_t bMaxPacketSize0 ; ///< Maximum packet size for endpoint zero (only 8, 16, 32, or 64 are valid). For HS devices is fixed to 64.
uint16_t idVendor ; ///< Vendor ID (assigned by the USB-IF).
@@ -314,8 +290,7 @@ typedef struct TU_ATTR_PACKED
TU_VERIFY_STATIC( sizeof(tusb_desc_device_t) == 18, "size is not correct");
// USB Binary Device Object Store (BOS) Descriptor
-typedef struct TU_ATTR_PACKED
-{
+typedef struct TU_ATTR_PACKED {
uint8_t bLength ; ///< Size of this descriptor in bytes
uint8_t bDescriptorType ; ///< CONFIGURATION Descriptor Type
uint16_t wTotalLength ; ///< Total length of data returned for this descriptor
@@ -325,8 +300,7 @@ typedef struct TU_ATTR_PACKED
TU_VERIFY_STATIC( sizeof(tusb_desc_bos_t) == 5, "size is not correct");
/// USB Configuration Descriptor
-typedef struct TU_ATTR_PACKED
-{
+typedef struct TU_ATTR_PACKED {
uint8_t bLength ; ///< Size of this descriptor in bytes
uint8_t bDescriptorType ; ///< CONFIGURATION Descriptor Type
uint16_t wTotalLength ; ///< Total length of data returned for this configuration. Includes the combined length of all descriptors (configuration, interface, endpoint, and class- or vendor-specific) returned for this configuration.
@@ -341,8 +315,7 @@ typedef struct TU_ATTR_PACKED
TU_VERIFY_STATIC( sizeof(tusb_desc_configuration_t) == 9, "size is not correct");
/// USB Interface Descriptor
-typedef struct TU_ATTR_PACKED
-{
+typedef struct TU_ATTR_PACKED {
uint8_t bLength ; ///< Size of this descriptor in bytes
uint8_t bDescriptorType ; ///< INTERFACE Descriptor Type
@@ -358,8 +331,7 @@ typedef struct TU_ATTR_PACKED
TU_VERIFY_STATIC( sizeof(tusb_desc_interface_t) == 9, "size is not correct");
/// USB Endpoint Descriptor
-typedef struct TU_ATTR_PACKED
-{
+typedef struct TU_ATTR_PACKED {
uint8_t bLength ; // Size of this descriptor in bytes
uint8_t bDescriptorType ; // ENDPOINT Descriptor Type
@@ -379,8 +351,7 @@ typedef struct TU_ATTR_PACKED
TU_VERIFY_STATIC( sizeof(tusb_desc_endpoint_t) == 7, "size is not correct");
/// USB Other Speed Configuration Descriptor
-typedef struct TU_ATTR_PACKED
-{
+typedef struct TU_ATTR_PACKED {
uint8_t bLength ; ///< Size of descriptor
uint8_t bDescriptorType ; ///< Other_speed_Configuration Type
uint16_t wTotalLength ; ///< Total length of data returned
@@ -393,8 +364,7 @@ typedef struct TU_ATTR_PACKED
} tusb_desc_other_speed_t;
/// USB Device Qualifier Descriptor
-typedef struct TU_ATTR_PACKED
-{
+typedef struct TU_ATTR_PACKED {
uint8_t bLength ; ///< Size of descriptor
uint8_t bDescriptorType ; ///< Device Qualifier Type
uint16_t bcdUSB ; ///< USB specification version number (e.g., 0200H for V2.00)
@@ -411,8 +381,7 @@ typedef struct TU_ATTR_PACKED
TU_VERIFY_STATIC( sizeof(tusb_desc_device_qualifier_t) == 10, "size is not correct");
/// USB Interface Association Descriptor (IAD ECN)
-typedef struct TU_ATTR_PACKED
-{
+typedef struct TU_ATTR_PACKED {
uint8_t bLength ; ///< Size of descriptor
uint8_t bDescriptorType ; ///< Other_speed_Configuration Type
@@ -426,17 +395,17 @@ typedef struct TU_ATTR_PACKED
uint8_t iFunction ; ///< Index of the string descriptor describing the interface association.
} tusb_desc_interface_assoc_t;
+TU_VERIFY_STATIC( sizeof(tusb_desc_interface_assoc_t) == 8, "size is not correct");
+
// USB String Descriptor
-typedef struct TU_ATTR_PACKED
-{
+typedef struct TU_ATTR_PACKED {
uint8_t bLength ; ///< Size of this descriptor in bytes
uint8_t bDescriptorType ; ///< Descriptor Type
uint16_t unicode_string[];
} tusb_desc_string_t;
// USB Binary Device Object Store (BOS)
-typedef struct TU_ATTR_PACKED
-{
+typedef struct TU_ATTR_PACKED {
uint8_t bLength;
uint8_t bDescriptorType ;
uint8_t bDevCapabilityType;
@@ -445,9 +414,8 @@ typedef struct TU_ATTR_PACKED
uint8_t CapabilityData[];
} tusb_desc_bos_platform_t;
-// USB WebuSB URL Descriptor
-typedef struct TU_ATTR_PACKED
-{
+// USB WebUSB URL Descriptor
+typedef struct TU_ATTR_PACKED {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bScheme;
@@ -455,8 +423,7 @@ typedef struct TU_ATTR_PACKED
} tusb_desc_webusb_url_t;
// DFU Functional Descriptor
-typedef struct TU_ATTR_PACKED
-{
+typedef struct TU_ATTR_PACKED {
uint8_t bLength;
uint8_t bDescriptorType;
@@ -481,7 +448,7 @@ typedef struct TU_ATTR_PACKED
//
//--------------------------------------------------------------------+
-typedef struct TU_ATTR_PACKED{
+typedef struct TU_ATTR_PACKED {
union {
struct TU_ATTR_PACKED {
uint8_t recipient : 5; ///< Recipient type tusb_request_recipient_t.
@@ -500,7 +467,6 @@ typedef struct TU_ATTR_PACKED{
TU_VERIFY_STATIC( sizeof(tusb_control_request_t) == 8, "size is not correct");
-
TU_ATTR_PACKED_END // End of all packed definitions
TU_ATTR_BIT_FIELD_ORDER_END
@@ -509,36 +475,25 @@ TU_ATTR_BIT_FIELD_ORDER_END
//--------------------------------------------------------------------+
// Get direction from Endpoint address
-TU_ATTR_ALWAYS_INLINE static inline tusb_dir_t tu_edpt_dir(uint8_t addr)
-{
+TU_ATTR_ALWAYS_INLINE static inline tusb_dir_t tu_edpt_dir(uint8_t addr) {
return (addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT;
}
// Get Endpoint number from address
-TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_number(uint8_t addr)
-{
+TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_number(uint8_t addr) {
return (uint8_t)(addr & (~TUSB_DIR_IN_MASK));
}
-TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_addr(uint8_t num, uint8_t dir)
-{
+TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_addr(uint8_t num, uint8_t dir) {
return (uint8_t)(num | (dir ? TUSB_DIR_IN_MASK : 0));
}
-TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const* desc_ep)
-{
- return tu_le16toh(desc_ep->wMaxPacketSize) & TU_GENMASK(10, 0);
+TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const* desc_ep) {
+ return tu_le16toh(desc_ep->wMaxPacketSize) & 0x7FF;
}
#if CFG_TUSB_DEBUG
-TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_dir_str(tusb_dir_t dir)
-{
- tu_static const char *str[] = {"out", "in"};
- return str[dir];
-}
-
-TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_type_str(tusb_xfer_type_t t)
-{
+TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_type_str(tusb_xfer_type_t t) {
tu_static const char *str[] = {"control", "isochronous", "bulk", "interrupt"};
return str[t];
}
@@ -549,21 +504,18 @@ TU_ATTR_ALWAYS_INLINE static inline const char *tu_edpt_type_str(tusb_xfer_type_
//--------------------------------------------------------------------+
// return next descriptor
-TU_ATTR_ALWAYS_INLINE static inline uint8_t const * tu_desc_next(void const* desc)
-{
+TU_ATTR_ALWAYS_INLINE static inline uint8_t const * tu_desc_next(void const* desc) {
uint8_t const* desc8 = (uint8_t const*) desc;
return desc8 + desc8[DESC_OFFSET_LEN];
}
// get descriptor type
-TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_type(void const* desc)
-{
+TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_type(void const* desc) {
return ((uint8_t const*) desc)[DESC_OFFSET_TYPE];
}
// get descriptor length
-TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_len(void const* desc)
-{
+TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_len(void const* desc) {
return ((uint8_t const*) desc)[DESC_OFFSET_LEN];
}
@@ -580,6 +532,4 @@ uint8_t const * tu_desc_find3(uint8_t const* desc, uint8_t const* end, uint8_t b
}
#endif
-#endif /* _TUSB_TYPES_H_ */
-
-/** @} */
+#endif // TUSB_TYPES_H_
diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h
index 12355e8be..0a9549c99 100644
--- a/src/common/tusb_verify.h
+++ b/src/common/tusb_verify.h
@@ -56,12 +56,8 @@
* #define TU_VERIFY(cond) if(cond) return false;
* #define TU_VERIFY(cond,ret) if(cond) return ret;
*
- * #define TU_VERIFY_HDLR(cond,handler) if(cond) {handler; return false;}
- * #define TU_VERIFY_HDLR(cond,ret,handler) if(cond) {handler; return ret;}
- *
* #define TU_ASSERT(cond) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return false;}
* #define TU_ASSERT(cond,ret) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return ret;}
- *
*------------------------------------------------------------------*/
#ifdef __cplusplus
@@ -79,15 +75,16 @@
#define _MESS_FAILED() do {} while (0)
#endif
-// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7, M33
-#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__)
+// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7, M33. M55
+#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8_1M_MAIN__) || \
+ defined(__ARM7M__) || defined (__ARM7EM__) || defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__)
#define TU_BREAKPOINT() do \
{ \
volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \
if ( (*ARM_CM_DHCSR) & 1UL ) __asm("BKPT #0\n"); /* Only halt mcu if debugger is attached */ \
} while(0)
-#elif defined(__riscv)
+#elif defined(__riscv) && !TUP_MCU_ESPRESSIF
#define TU_BREAKPOINT() do { __asm("ebreak\n"); } while(0)
#elif defined(_mips)
@@ -97,40 +94,23 @@
#define TU_BREAKPOINT() do {} while (0)
#endif
-/*------------------------------------------------------------------*/
-/* Macro Generator
- *------------------------------------------------------------------*/
-
// Helper to implement optional parameter for TU_VERIFY Macro family
#define _GET_3RD_ARG(arg1, arg2, arg3, ...) arg3
-#define _GET_4TH_ARG(arg1, arg2, arg3, arg4, ...) arg4
-
-/*------------- Generator for TU_VERIFY and TU_VERIFY_HDLR -------------*/
-#define TU_VERIFY_DEFINE(_cond, _handler, _ret) do \
-{ \
- if ( !(_cond) ) { _handler; return _ret; } \
-} while(0)
/*------------------------------------------------------------------*/
/* TU_VERIFY
* - TU_VERIFY_1ARGS : return false if failed
* - TU_VERIFY_2ARGS : return provided value if failed
*------------------------------------------------------------------*/
-#define TU_VERIFY_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, , false)
-#define TU_VERIFY_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, , _ret)
+#define TU_VERIFY_DEFINE(_cond, _ret) \
+ do { \
+ if ( !(_cond) ) { return _ret; } \
+ } while(0)
-#define TU_VERIFY(...) _GET_3RD_ARG(__VA_ARGS__, TU_VERIFY_2ARGS, TU_VERIFY_1ARGS, UNUSED)(__VA_ARGS__)
+#define TU_VERIFY_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, false)
+#define TU_VERIFY_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, _ret)
-
-/*------------------------------------------------------------------*/
-/* TU_VERIFY WITH HANDLER
- * - TU_VERIFY_HDLR_2ARGS : execute handler, return false if failed
- * - TU_VERIFY_HDLR_3ARGS : execute handler, return provided error if failed
- *------------------------------------------------------------------*/
-#define TU_VERIFY_HDLR_2ARGS(_cond, _handler) TU_VERIFY_DEFINE(_cond, _handler, false)
-#define TU_VERIFY_HDLR_3ARGS(_cond, _handler, _ret) TU_VERIFY_DEFINE(_cond, _handler, _ret)
-
-#define TU_VERIFY_HDLR(...) _GET_4TH_ARG(__VA_ARGS__, TU_VERIFY_HDLR_3ARGS, TU_VERIFY_HDLR_2ARGS,UNUSED)(__VA_ARGS__)
+#define TU_VERIFY(...) _GET_3RD_ARG(__VA_ARGS__, TU_VERIFY_2ARGS, TU_VERIFY_1ARGS, _dummy)(__VA_ARGS__)
/*------------------------------------------------------------------*/
/* ASSERT
@@ -138,19 +118,20 @@
* - 1 arg : return false if failed
* - 2 arg : return error if failed
*------------------------------------------------------------------*/
-#define ASSERT_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); TU_BREAKPOINT(), false)
-#define ASSERT_2ARGS(_cond, _ret) TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); TU_BREAKPOINT(), _ret)
+#define TU_ASSERT_DEFINE(_cond, _ret) \
+ do { \
+ if ( !(_cond) ) { _MESS_FAILED(); TU_BREAKPOINT(); return _ret; } \
+ } while(0)
+
+#define TU_ASSERT_1ARGS(_cond) TU_ASSERT_DEFINE(_cond, false)
+#define TU_ASSERT_2ARGS(_cond, _ret) TU_ASSERT_DEFINE(_cond, _ret)
#ifndef TU_ASSERT
-#define TU_ASSERT(...) _GET_3RD_ARG(__VA_ARGS__, ASSERT_2ARGS, ASSERT_1ARGS,UNUSED)(__VA_ARGS__)
+#define TU_ASSERT(...) _GET_3RD_ARG(__VA_ARGS__, TU_ASSERT_2ARGS, TU_ASSERT_1ARGS, _dummy)(__VA_ARGS__)
#endif
-/*------------------------------------------------------------------*/
-/* ASSERT HDLR
- *------------------------------------------------------------------*/
-
#ifdef __cplusplus
}
#endif
-#endif /* TUSB_VERIFY_H_ */
+#endif