summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorhathach <[email protected]>2025-12-12 21:38:48 +0700
committerhathach <[email protected]>2025-12-12 21:38:48 +0700
commitbb1495966d189dc2fb001bc9f3b7908a02a971bb (patch)
tree63c5044798267aa414a1073f3f7c3976cae65797 /src/common
parent686e975e4737e668577a66213910841036422752 (diff)
parent02da4e81c77fd7e77ff0b92c616519358c6db4ee (diff)
Merge branch 'refs/heads/master' into audio_open
Diffstat (limited to 'src/common')
-rw-r--r--src/common/tusb_common.h5
-rw-r--r--src/common/tusb_compiler.h84
-rw-r--r--src/common/tusb_fifo.c13
-rw-r--r--src/common/tusb_fifo.h11
-rw-r--r--src/common/tusb_private.h94
5 files changed, 93 insertions, 114 deletions
diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h
index b53fa5c02..d74760608 100644
--- a/src/common/tusb_common.h
+++ b/src/common/tusb_common.h
@@ -388,10 +388,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_desc_subtype(void const* desc) {
}
TU_ATTR_ALWAYS_INLINE static inline bool tu_desc_in_bounds(const uint8_t *p_desc, const uint8_t *desc_end) {
- if (p_desc >= desc_end) {
- return false;
- }
- return tu_desc_next(p_desc) <= desc_end;
+ return p_desc < desc_end && tu_desc_next(p_desc) <= desc_end;
}
// find descriptor that match byte1 (type)
diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h
index 7719790d1..f20834cea 100644
--- a/src/common/tusb_compiler.h
+++ b/src/common/tusb_compiler.h
@@ -24,21 +24,13 @@
* This file is part of the TinyUSB stack.
*/
-/** \ingroup Group_Common
- * \defgroup Group_Compiler Compiler
- * \brief Group_Compiler brief
- * @{ */
-
-#ifndef TUSB_COMPILER_H_
-#define TUSB_COMPILER_H_
+#pragma once
#define TU_TOKEN(x) x
#define TU_STRING(x) #x ///< stringify without expand
#define TU_XSTRING(x) TU_STRING(x) ///< expand then stringify
-
#define TU_STRCAT(a, b) a##b ///< concat without expand
#define TU_STRCAT3(a, b, c) a##b##c ///< concat without expand
-
#define TU_XSTRCAT(a, b) TU_STRCAT(a, b) ///< expand then concat
#define TU_XSTRCAT3(a, b, c) TU_STRCAT3(a, b, c) ///< expand then concat 3 tokens
@@ -139,18 +131,20 @@
#define TU_FUNC_OPTIONAL_ARG(func, ...) TU_XSTRCAT(func##_arg, TU_ARGS_NUM(__VA_ARGS__))(__VA_ARGS__)
//--------------------------------------------------------------------+
-// Compiler porting with Attribute and Endian
+// Compiler Attribute Abstraction
//--------------------------------------------------------------------+
+#if defined(__GNUC__) || defined(__ICCARM__) || defined(__TI_COMPILER_VERSION__)
+ #if defined(__ICCARM__)
+ #include <intrinsics.h> // for builtin functions
+ #endif
-// TODO refactor since __attribute__ is supported across many compiler
-#if defined(__GNUC__)
- #define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes)))
- #define TU_ATTR_SECTION(sec_name) __attribute__ ((section(#sec_name)))
- #define TU_ATTR_PACKED __attribute__ ((packed))
- #define TU_ATTR_WEAK __attribute__ ((weak))
- // #define TU_ATTR_WEAK_ALIAS(f) __attribute__ ((weak, alias(#f)))
- #ifndef TU_ATTR_ALWAYS_INLINE // allow to override for debug
- #define TU_ATTR_ALWAYS_INLINE __attribute__ ((always_inline))
+ #define TU_ATTR_ALIGNED(Bytes) __attribute__((aligned(Bytes)))
+ #define TU_ATTR_SECTION(sec_name) __attribute__((section(#sec_name)))
+ #define TU_ATTR_PACKED __attribute__((packed))
+ #define TU_ATTR_WEAK __attribute__((weak))
+// #define TU_ATTR_WEAK_ALIAS(f) __attribute__ ((weak, alias(#f)))
+ #ifndef TU_ATTR_ALWAYS_INLINE // allow to override for debug
+ #define TU_ATTR_ALWAYS_INLINE __attribute__((always_inline))
#endif
#define TU_ATTR_DEPRECATED(mess) __attribute__ ((deprecated(mess))) // warn if function with this attribute is used
#define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused
@@ -161,18 +155,17 @@
#define TU_ATTR_BIT_FIELD_ORDER_BEGIN
#define TU_ATTR_BIT_FIELD_ORDER_END
- #if __GNUC__ < 5
- #define TU_ATTR_FALLTHROUGH do {} while (0) /* fallthrough */
+ #if (defined(__has_attribute) && __has_attribute(__fallthrough__)) || defined(__TI_COMPILER_VERSION__)
+ #define TU_ATTR_FALLTHROUGH __attribute__((fallthrough))
#else
- #if __has_attribute(__fallthrough__)
- #define TU_ATTR_FALLTHROUGH __attribute__((fallthrough))
- #else
- #define TU_ATTR_FALLTHROUGH do {} while (0) /* fallthrough */
- #endif
+ #define TU_ATTR_FALLTHROUGH \
+ do { \
+ } while (0) /* fallthrough */
#endif
- // Endian conversion use well-known host to network (big endian) naming
- #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+// Endian conversion use well-known host to network (big endian) naming
+// For TI ARM compiler, __BYTE_ORDER__ is not defined for MSP430 but still LE
+ #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ || defined(__MSP430__)
#define TU_BYTE_ORDER TU_LITTLE_ENDIAN
#else
#define TU_BYTE_ORDER TU_BIG_ENDIAN
@@ -190,39 +183,12 @@
#define TU_BSWAP32(u32) (__builtin_bswap32(u32))
#endif
- #ifndef __ARMCC_VERSION
// List of obsolete callback function that is renamed and should not be defined.
// Put it here since only gcc support this pragma
- #pragma GCC poison tud_vendor_control_request_cb
- #endif
-
-#elif defined(__TI_COMPILER_VERSION__)
- #define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes)))
- #define TU_ATTR_SECTION(sec_name) __attribute__ ((section(#sec_name)))
- #define TU_ATTR_PACKED __attribute__ ((packed))
- #define TU_ATTR_WEAK __attribute__ ((weak))
- // #define TU_ATTR_WEAK_ALIAS(f) __attribute__ ((weak, alias(#f)))
- #define TU_ATTR_ALWAYS_INLINE __attribute__ ((always_inline))
- #define TU_ATTR_DEPRECATED(mess) __attribute__ ((deprecated(mess))) // warn if function with this attribute is used
- #define TU_ATTR_UNUSED __attribute__ ((unused)) // Function/Variable is meant to be possibly unused
- #define TU_ATTR_USED __attribute__ ((used))
- #define TU_ATTR_FALLTHROUGH __attribute__((fallthrough))
-
- #define TU_ATTR_PACKED_BEGIN
- #define TU_ATTR_PACKED_END
- #define TU_ATTR_BIT_FIELD_ORDER_BEGIN
- #define TU_ATTR_BIT_FIELD_ORDER_END
-
- // __BYTE_ORDER is defined in the TI ARM compiler, but not MSP430 (which is little endian)
- #if ((__BYTE_ORDER__) == (__ORDER_LITTLE_ENDIAN__)) || defined(__MSP430__)
- #define TU_BYTE_ORDER TU_LITTLE_ENDIAN
- #else
- #define TU_BYTE_ORDER TU_BIG_ENDIAN
+ #if !defined(__ARMCC_VERSION) && !defined(__ICCARM__)
+ #pragma GCC poison tud_vendor_control_request_cb
#endif
- #define TU_BSWAP16(u16) (__builtin_bswap16(u16))
- #define TU_BSWAP32(u32) (__builtin_bswap32(u32))
-
#elif defined(__ICCARM__)
#include <intrinsics.h>
#define TU_ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes)))
@@ -316,7 +282,3 @@
#else
#error Byte order is undefined
#endif
-
-#endif /* TUSB_COMPILER_H_ */
-
-/// @}
diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c
index 06b0d6a58..e97b6ccce 100644
--- a/src/common/tusb_fifo.c
+++ b/src/common/tusb_fifo.c
@@ -84,7 +84,7 @@ bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, uint16_t item_si
}
// clear fifo by resetting read and write indices
-bool tu_fifo_clear(tu_fifo_t *f) {
+void tu_fifo_clear(tu_fifo_t *f) {
ff_lock(f->mutex_wr);
ff_lock(f->mutex_rd);
@@ -93,13 +93,12 @@ bool tu_fifo_clear(tu_fifo_t *f) {
ff_unlock(f->mutex_wr);
ff_unlock(f->mutex_rd);
- return true;
}
// Change the fifo overwritable mode
-bool tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable) {
+void tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable) {
if (f->overwritable == overwritable) {
- return true;
+ return;
}
ff_lock(f->mutex_wr);
@@ -109,8 +108,6 @@ bool tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable) {
ff_unlock(f->mutex_wr);
ff_unlock(f->mutex_rd);
-
- return true;
}
//--------------------------------------------------------------------+
@@ -292,7 +289,7 @@ static void ff_pull_n(const tu_fifo_t *f, void *app_buf, uint16_t n, uint16_t rd
// Advance an absolute index
// "absolute" index is only in the range of [0..2*depth)
-TU_ATTR_ALWAYS_INLINE static inline uint16_t advance_index(uint16_t depth, uint16_t idx, uint16_t offset) {
+static uint16_t advance_index(uint16_t depth, uint16_t idx, uint16_t offset) {
// We limit the index space of p such that a correct wrap around happens
// Check for a wrap around or if we are in unused index space - This has to be checked first!!
// We are exploiting the wrap around to the correct index
@@ -316,7 +313,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t idx2ptr(uint16_t depth, uint16_t id
// Works on local copies of w
// When an overwritable fifo is overflowed, rd_idx will be re-index so that it forms a full fifo
-TU_ATTR_ALWAYS_INLINE static inline uint16_t correct_read_index(tu_fifo_t *f, uint16_t wr_idx) {
+static uint16_t correct_read_index(tu_fifo_t *f, uint16_t wr_idx) {
uint16_t rd_idx;
if (wr_idx >= f->depth) {
rd_idx = wr_idx - f->depth;
diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h
index 42f154bca..2e2a0db6f 100644
--- a/src/common/tusb_fifo.h
+++ b/src/common/tusb_fifo.h
@@ -157,8 +157,8 @@ 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_set_overwritable(tu_fifo_t *f, bool overwritable);
-bool tu_fifo_clear(tu_fifo_t *f);
+void tu_fifo_set_overwritable(tu_fifo_t *f, bool overwritable);
+void tu_fifo_clear(tu_fifo_t *f);
#if OSAL_MUTEX_REQUIRED
TU_ATTR_ALWAYS_INLINE static inline
@@ -224,10 +224,11 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_fifo_write_n(tu_fifo_t *f, const
//--------------------------------------------------------------------+
// return overflowable count (index difference), which can be used to determine both fifo count and an overflow state
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_ff_overflow_count(uint16_t depth, uint16_t wr_idx, uint16_t rd_idx) {
- if (wr_idx >= rd_idx) {
- return (uint16_t)(wr_idx - rd_idx);
+ const int32_t diff = (int32_t)wr_idx - (int32_t)rd_idx;
+ if (diff >= 0) {
+ return (uint16_t)diff;
} else {
- return (uint16_t)(2 * depth - (rd_idx - wr_idx));
+ return (uint16_t)(2 * depth + diff);
}
}
diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h
index 8643bb020..10e12c2af 100644
--- a/src/common/tusb_private.h
+++ b/src/common/tusb_private.h
@@ -33,6 +33,18 @@
extern "C" {
#endif
+//--------------------------------------------------------------------+
+// Configuration
+//--------------------------------------------------------------------+
+
+#if CFG_TUD_ENABLED && CFG_TUD_VENDOR && (CFG_TUD_VENDOR_TX_BUFSIZE == 0 || CFG_TUD_VENDOR_RX_BUFSIZE == 0)
+ #define CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED 1
+#endif
+
+#ifndef CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED
+ #define CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED 0
+#endif
+
#define TUP_USBIP_CONTROLLER_NUM 2
extern tusb_role_t _tusb_rhport_role[TUP_USBIP_CONTROLLER_NUM];
@@ -50,36 +62,40 @@ typedef struct TU_ATTR_PACKED {
volatile uint8_t busy : 1;
volatile uint8_t stalled : 1;
volatile uint8_t claimed : 1;
-}tu_edpt_state_t;
+} tu_edpt_state_t;
typedef struct {
- struct TU_ATTR_PACKED {
- bool is_host : 1; // 1: host, 0: device
- bool is_mps512 : 1; // 1: 512, 0: 64 since stream is used for Bulk only
- };
+ uint8_t hwid; // device: rhport, host: daddr
+ bool is_host; // 1: host, 0: device
uint8_t ep_addr;
- uint16_t ep_bufsize;
+ uint16_t mps;
+ uint16_t ep_bufsize;
uint8_t *ep_buf; // set to NULL to use xfer_fifo when CFG_TUD_EDPT_DEDICATED_HWFIFO = 1
tu_fifo_t ff;
// mutex: read if rx, otherwise write
OSAL_MUTEX_DEF(ff_mutexdef);
-
}tu_edpt_stream_t;
//--------------------------------------------------------------------+
// Endpoint
//--------------------------------------------------------------------+
-// Check if endpoint descriptor is valid per USB specs
-bool tu_edpt_validate(tusb_desc_endpoint_t const * desc_ep, tusb_speed_t speed, bool is_host);
-
-// Bind all endpoint of a interface descriptor to class driver
-void tu_edpt_bind_driver(uint8_t ep2drv[][2], tusb_desc_interface_t const* p_desc, uint16_t desc_len, uint8_t driver_id);
+// Check if endpoint descriptor is valid per USB specs if debug is enabled
+#if CFG_TUSB_DEBUG
+bool tu_edpt_validate(const tusb_desc_endpoint_t *desc_ep, tusb_speed_t speed);
+#else
+TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_validate(const tusb_desc_endpoint_t *desc_ep, tusb_speed_t speed) {
+ (void)desc_ep;
+ (void)speed;
+ return true;
+}
+#endif
-// Calculate total length of n interfaces (depending on IAD)
-uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len);
+// Bind drivers to all interfaces and endpoints in the provided configuration descriptor
+bool tu_bind_driver_to_ep_itf(uint8_t driver_id, uint8_t ep2drv[][2], uint8_t itf2drv[], uint8_t itf_max,
+ const uint8_t *p_desc, uint16_t desc_len);
// Claim an endpoint with provided mutex
bool tu_edpt_claim(tu_edpt_state_t* ep_state, osal_mutex_t mutex);
@@ -92,16 +108,28 @@ bool tu_edpt_release(tu_edpt_state_t* ep_state, osal_mutex_t mutex);
//--------------------------------------------------------------------+
// 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);
+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);
+TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_deinit(tu_edpt_stream_t *s) {
+ (void)s;
+#if OSAL_MUTEX_REQUIRED
+ if (s->ff.mutex_wr) {
+ osal_mutex_delete(s->ff.mutex_wr);
+ }
+ if (s->ff.mutex_rd) {
+ osal_mutex_delete(s->ff.mutex_rd);
+ }
+#endif
+}
// Open an endpoint stream
-TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_open(tu_edpt_stream_t* s, tusb_desc_endpoint_t const *desc_ep) {
+TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_open(tu_edpt_stream_t *s, uint8_t hwid,
+ const tusb_desc_endpoint_t *desc_ep) {
+ s->hwid = hwid;
s->ep_addr = desc_ep->bEndpointAddress;
- s->is_mps512 = tu_edpt_packet_size(desc_ep) == 512;
+ s->mps = tu_edpt_packet_size(desc_ep);
}
TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_is_opened(const tu_edpt_stream_t *s) {
@@ -112,8 +140,8 @@ TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_close(tu_edpt_stream_t*
s->ep_addr = 0;
}
-TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_clear(tu_edpt_stream_t* s) {
- return tu_fifo_clear(&s->ff);
+TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_clear(tu_edpt_stream_t *s) {
+ tu_fifo_clear(&s->ff);
}
TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_empty(tu_edpt_stream_t *s) {
@@ -125,42 +153,40 @@ TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_empty(tu_edpt_stream_t *
//--------------------------------------------------------------------+
// Write to stream
-uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize);
+uint32_t tu_edpt_stream_write(tu_edpt_stream_t *s, const void *buffer, uint32_t bufsize);
// Start an usb transfer if endpoint is not busy. Return number of queued bytes
-uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s);
+uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t *s);
// Start an zero-length packet if needed
-bool tu_edpt_stream_write_zlp_if_needed(uint8_t hwid, tu_edpt_stream_t* s, uint32_t last_xferred_bytes);
+bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t *s, uint32_t last_xferred_bytes);
// Get the number of bytes available for writing to FIFO
// Note: if no fifo, return endpoint size if not busy, 0 otherwise
-uint32_t tu_edpt_stream_write_available(uint8_t hwid, tu_edpt_stream_t* s);
+uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t *s);
//--------------------------------------------------------------------+
// Stream Read
//--------------------------------------------------------------------+
// Read from stream
-uint32_t tu_edpt_stream_read(uint8_t hwid, tu_edpt_stream_t* s, void* buffer, uint32_t bufsize);
+uint32_t tu_edpt_stream_read(tu_edpt_stream_t *s, void *buffer, uint32_t bufsize);
// Start an usb transfer if endpoint is not busy
-uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s);
+uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t *s);
// Complete read transfer by writing EP -> FIFO. Must be called in the transfer complete callback
TU_ATTR_ALWAYS_INLINE static inline
void tu_edpt_stream_read_xfer_complete(tu_edpt_stream_t* s, uint32_t xferred_bytes) {
- if (0u != tu_fifo_depth(&s->ff) && s->ep_buf != NULL) {
- tu_fifo_write_n(&s->ff, s->ep_buf, (uint16_t) xferred_bytes);
+ if (s->ep_buf != NULL) {
+ tu_fifo_write_n(&s->ff, s->ep_buf, (uint16_t)xferred_bytes);
}
}
// Complete read transfer with provided buffer
TU_ATTR_ALWAYS_INLINE static inline
void tu_edpt_stream_read_xfer_complete_with_buf(tu_edpt_stream_t *s, const void *buf, uint32_t xferred_bytes) {
- if (0u != tu_fifo_depth(&s->ff)) {
- tu_fifo_write_n(&s->ff, buf, (uint16_t) xferred_bytes);
- }
+ tu_fifo_write_n(&s->ff, buf, (uint16_t)xferred_bytes);
}
// Get the number of bytes available for reading
@@ -172,10 +198,6 @@ TU_ATTR_ALWAYS_INLINE static inline bool tu_edpt_stream_peek(tu_edpt_stream_t *s
return tu_fifo_peek(&s->ff, ch);
}
-TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_edpt_stream_discard(tu_edpt_stream_t *s, uint32_t len) {
- return (uint32_t)tu_fifo_discard_n(&s->ff, (uint16_t)len);
-}
-
#ifdef __cplusplus
}
#endif