Merge branch 'master' into hwfifo_post

This commit is contained in:
hathach
2025-12-10 16:02:25 +07:00
12 changed files with 597 additions and 340 deletions

View File

@ -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_ */
/// @}

View File

@ -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);
}
}

View File

@ -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];

View File

@ -821,7 +821,7 @@ static void channel_xfer_in_retry(dwc2_regs_t* dwc2, uint8_t ch_id, uint32_t hci
}
}
#if CFG_TUSB_DEBUG
#if CFG_TUSB_DEBUG && 0
TU_ATTR_ALWAYS_INLINE static inline void print_hcint(uint32_t hcint) {
const char* str[] = {
"XFRC", "HALTED", "AHBERR", "STALL",

View File

@ -338,6 +338,10 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove
void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize) {
(void) is_tx;
if (CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED == 0 && (ff_buf == NULL || ff_bufsize == 0)) {
return false;
}
s->is_host = is_host;
tu_fifo_config(&s->ff, ff_buf, ff_bufsize, 1, overwritable);
@ -367,7 +371,7 @@ bool tu_edpt_stream_deinit(tu_edpt_stream_t *s) {
return true;
}
TU_ATTR_ALWAYS_INLINE static inline bool stream_claim(uint8_t hwid, tu_edpt_stream_t* s) {
static bool stream_claim(uint8_t hwid, tu_edpt_stream_t *s) {
if (s->is_host) {
#if CFG_TUH_ENABLED
return usbh_edpt_claim(hwid, s->ep_addr);
@ -380,7 +384,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool stream_claim(uint8_t hwid, tu_edpt_stre
return false;
}
TU_ATTR_ALWAYS_INLINE static inline bool stream_xfer(uint8_t hwid, tu_edpt_stream_t* s, uint16_t count) {
static bool stream_xfer(uint8_t hwid, tu_edpt_stream_t *s, uint16_t count) {
if (s->is_host) {
#if CFG_TUH_ENABLED
return usbh_edpt_xfer(hwid, s->ep_addr, count ? s->ep_buf : NULL, count);
@ -397,7 +401,7 @@ TU_ATTR_ALWAYS_INLINE static inline bool stream_xfer(uint8_t hwid, tu_edpt_strea
return false;
}
TU_ATTR_ALWAYS_INLINE static inline bool stream_release(uint8_t hwid, tu_edpt_stream_t* s) {
static bool stream_release(uint8_t hwid, tu_edpt_stream_t *s) {
if (s->is_host) {
#if CFG_TUH_ENABLED
return usbh_edpt_release(hwid, s->ep_addr);
@ -446,8 +450,9 @@ uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s) {
}
uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t *s, const void *buffer, uint32_t bufsize) {
TU_VERIFY(bufsize > 0); // TODO support ZLP
TU_VERIFY(bufsize > 0);
#if CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED
if (0 == tu_fifo_depth(&s->ff)) {
// non-fifo mode
TU_VERIFY(stream_claim(hwid, s), 0);
@ -463,7 +468,9 @@ uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t *s, const void *buf
TU_ASSERT(stream_xfer(hwid, s, (uint16_t) xact_len), 0);
return xact_len;
} else {
} else
#endif
{
const uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize);
// flush if fifo has more than packet size or
@ -475,10 +482,9 @@ uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t *s, const void *buf
}
}
uint32_t tu_edpt_stream_write_available(uint8_t hwid, tu_edpt_stream_t* s) {
if (tu_fifo_depth(&s->ff) > 0) {
return (uint32_t) tu_fifo_remaining(&s->ff);
} else {
uint32_t tu_edpt_stream_write_available(uint8_t hwid, tu_edpt_stream_t *s) {
#if CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED
if (0 == tu_fifo_depth(&s->ff)) {
// non-fifo mode
bool is_busy = true;
if (s->is_host) {
@ -491,20 +497,28 @@ uint32_t tu_edpt_stream_write_available(uint8_t hwid, tu_edpt_stream_t* s) {
#endif
}
return is_busy ? 0 : s->ep_bufsize;
} else
#endif
{
(void)hwid;
return (uint32_t)tu_fifo_remaining(&s->ff);
}
}
//--------------------------------------------------------------------+
// Stream Read
//--------------------------------------------------------------------+
uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s) {
uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t *s) {
#if CFG_TUSB_EDPT_STREAM_NO_FIFO_ENABLED
if (0 == tu_fifo_depth(&s->ff)) {
// non-fifo mode: RX need ep buffer
TU_VERIFY(s->ep_buf != NULL, 0);
TU_VERIFY(stream_claim(hwid, s), 0);
TU_ASSERT(stream_xfer(hwid, s, s->ep_bufsize), 0);
return s->ep_bufsize;
} else {
} else
#endif
{
uint16_t available = tu_fifo_remaining(&s->ff);
// Prepare for incoming data but only allow what we can store in the ring buffer.