Fixed more alert found by PVS-Studio

This commit is contained in:
hathach
2025-11-03 16:36:07 +07:00
parent 22f01aea0d
commit 8979af34c0
25 changed files with 224 additions and 208 deletions

View File

@ -23,8 +23,8 @@
* *
*/ */
#ifndef _USB_DESCRIPTORS_H_ #ifndef USB_DESCRIPTORS_H_
#define _USB_DESCRIPTORS_H_ #define USB_DESCRIPTORS_H_
// #include "tusb.h" // #include "tusb.h"

View File

@ -123,7 +123,7 @@ void cdc_task(void) {
static uint32_t btn_prev = 0; static uint32_t btn_prev = 0;
static cdc_notify_uart_state_t uart_state = { .value = 0 }; static cdc_notify_uart_state_t uart_state = { .value = 0 };
const uint32_t btn = board_button_read(); const uint32_t btn = board_button_read();
if ((btn_prev == 0) && btn) { if ((btn_prev == 0u) && btn) {
uart_state.dsr ^= 1; uart_state.dsr ^= 1;
tud_cdc_notify_uart_state(&uart_state); tud_cdc_notify_uart_state(&uart_state);
} }

View File

@ -29,33 +29,26 @@
#include "common.h" #include "common.h"
// Invoked when cdc when line state changed e.g connected/disconnected // Invoked when cdc when line state changed e.g connected/disconnected
void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) {
{
(void) itf; (void) itf;
(void) rts; (void) rts;
if (dtr) if (dtr) {
{
// Terminal connected // Terminal connected
} } else {
else
{
// Terminal disconnected // Terminal disconnected
} }
} }
// Invoked when CDC interface received data from host // Invoked when CDC interface received data from host
void tud_cdc_rx_cb(uint8_t itf) void tud_cdc_rx_cb(uint8_t itf) {
{
uint8_t buf[64]; uint8_t buf[64];
uint32_t count; uint32_t count;
// connected() check for DTR bit // connected() check for DTR bit
// Most but not all terminal client set this when making connection // Most but not all terminal client set this when making connection
if (tud_cdc_connected()) if (tud_cdc_connected()) {
{ if (tud_cdc_available()) {
if (tud_cdc_available()) // data is available
{
count = tud_cdc_n_read(itf, buf, sizeof(buf)); count = tud_cdc_n_read(itf, buf, sizeof(buf));
(void) count; (void) count;

View File

@ -24,8 +24,8 @@
* *
*/ */
#ifndef _USB_DESCRIPTORS_H_ #ifndef USB_DESCRIPTORS_H_
#define _USB_DESCRIPTORS_H_ #define USB_DESCRIPTORS_H_
// #include "tusb.h" // #include "tusb.h"

View File

@ -29,8 +29,8 @@
* Author: Simon Goldschmidt * Author: Simon Goldschmidt
* *
*/ */
#ifndef __LWIPOPTS_H__ #ifndef LWIPOPTS_H__
#define __LWIPOPTS_H__ #define LWIPOPTS_H__
/* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */ /* Prevent having to link sys_arch.c (we don't test the API layers in unit tests) */
#define NO_SYS 1 #define NO_SYS 1

View File

@ -23,8 +23,8 @@
* *
*/ */
#ifndef _USB_DESCRIPTORS_H_ #ifndef USB_DESCRIPTORS_H_
#define _USB_DESCRIPTORS_H_ #define USB_DESCRIPTORS_H_
enum enum
{ {

View File

@ -23,8 +23,8 @@
* *
*/ */
#ifndef _USB_DESCRIPTORS_H_ #ifndef USB_DESCRIPTORS_H_
#define _USB_DESCRIPTORS_H_ #define USB_DESCRIPTORS_H_
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// UAC2 DESCRIPTOR TEMPLATES // UAC2 DESCRIPTOR TEMPLATES

View File

@ -46,9 +46,9 @@ static void cdc_app_task(void* param);
void cdc_app_init(void) { void cdc_app_init(void) {
#if configSUPPORT_STATIC_ALLOCATION #if configSUPPORT_STATIC_ALLOCATION
xTaskCreateStatic(cdc_app_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, cdc_stack, &cdc_taskdef); (void) xTaskCreateStatic(cdc_app_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, cdc_stack, &cdc_taskdef);
#else #else
xTaskCreate(cdc_app_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, NULL); (void) xTaskCreate(cdc_app_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, NULL);
#endif #endif
} }
@ -57,7 +57,9 @@ static size_t get_console_inputs(uint8_t *buf, size_t bufsize) {
size_t count = 0; size_t count = 0;
while (count < bufsize) { while (count < bufsize) {
int ch = board_getchar(); int ch = board_getchar();
if (ch <= 0) break; if (ch <= 0) {
break;
}
buf[count] = (uint8_t) ch; buf[count] = (uint8_t) ch;
count++; count++;

View File

@ -51,8 +51,7 @@ int sys_read(int fhdl, char *buf, size_t count) TU_ATTR_USED;
int sys_write(int fhdl, const char *buf, size_t count) { int sys_write(int fhdl, const char *buf, size_t count) {
(void) fhdl; (void) fhdl;
SEGGER_RTT_Write(0, buf, (int) count); return (int) SEGGER_RTT_Write(0, buf, (int) count);
return (int) count;
} }
int sys_read(int fhdl, char *buf, size_t count) { int sys_read(int fhdl, char *buf, size_t count) {
@ -159,7 +158,7 @@ int board_getchar(void) {
} }
void board_putchar(int c) { void board_putchar(int c) {
sys_write(0, (const char*)&c, 1); (void) sys_write(0, (const char*)&c, 1);
} }
uint32_t tusb_time_millis_api(void) { uint32_t tusb_time_millis_api(void) {

View File

@ -165,7 +165,7 @@ static inline size_t board_usb_get_serial(uint16_t desc_str1[], size_t max_chars
'0', '1', '2', '3', '4', '5', '6', '7', '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
}; };
const uint8_t nibble = (uint8_t) ((uid[i] >> (j * 4)) & 0xf); const uint8_t nibble = (uint8_t) ((uid[i] >> (j * 4u)) & 0xfu);
desc_str1[i * 2 + (1 - j)] = nibble_to_hex[nibble]; // UTF-16-LE desc_str1[i * 2 + (1 - j)] = nibble_to_hex[nibble]; // UTF-16-LE
} }
} }

View File

@ -193,9 +193,9 @@ typedef enum {
} cdc_line_coding_stopbits_t; } cdc_line_coding_stopbits_t;
#define CDC_LINE_CODING_STOP_BITS_TEXT(STOP_BITS) ( \ #define CDC_LINE_CODING_STOP_BITS_TEXT(STOP_BITS) ( \
STOP_BITS == CDC_LINE_CODING_STOP_BITS_1 ? "1" : \ (STOP_BITS) == CDC_LINE_CODING_STOP_BITS_1 ? "1" : \
STOP_BITS == CDC_LINE_CODING_STOP_BITS_1_5 ? "1.5" : \ (STOP_BITS) == CDC_LINE_CODING_STOP_BITS_1_5 ? "1.5" : \
STOP_BITS == CDC_LINE_CODING_STOP_BITS_2 ? "2" : "?" ) (STOP_BITS) == CDC_LINE_CODING_STOP_BITS_2 ? "2" : "?" )
// TODO Backward compatible for typos. Maybe removed in the future release // TODO Backward compatible for typos. Maybe removed in the future release
#define CDC_LINE_CONDING_STOP_BITS_1 CDC_LINE_CODING_STOP_BITS_1 #define CDC_LINE_CONDING_STOP_BITS_1 CDC_LINE_CODING_STOP_BITS_1
@ -211,11 +211,11 @@ typedef enum {
} cdc_line_coding_parity_t; } cdc_line_coding_parity_t;
#define CDC_LINE_CODING_PARITY_CHAR(PARITY) ( \ #define CDC_LINE_CODING_PARITY_CHAR(PARITY) ( \
PARITY == CDC_LINE_CODING_PARITY_NONE ? 'N' : \ (PARITY) == CDC_LINE_CODING_PARITY_NONE ? 'N' : \
PARITY == CDC_LINE_CODING_PARITY_ODD ? 'O' : \ (PARITY) == CDC_LINE_CODING_PARITY_ODD ? 'O' : \
PARITY == CDC_LINE_CODING_PARITY_EVEN ? 'E' : \ (PARITY) == CDC_LINE_CODING_PARITY_EVEN ? 'E' : \
PARITY == CDC_LINE_CODING_PARITY_MARK ? 'M' : \ (PARITY) == CDC_LINE_CODING_PARITY_MARK ? 'M' : \
PARITY == CDC_LINE_CODING_PARITY_SPACE ? 'S' : '?' ) (PARITY) == CDC_LINE_CODING_PARITY_SPACE ? 'S' : '?' )
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// Management Element Notification (Notification Endpoint) // Management Element Notification (Notification Endpoint)

View File

@ -464,7 +464,9 @@ static bool _update_streaming_parameters(videod_streaming_interface_t const *stm
uint_fast8_t fmtnum = param->bFormatIndex; uint_fast8_t fmtnum = param->bFormatIndex;
TU_ASSERT(vs && fmtnum <= vs->stm.bNumFormats); TU_ASSERT(vs && fmtnum <= vs->stm.bNumFormats);
if (0 == fmtnum) { if (0 == fmtnum) {
if (1 < vs->stm.bNumFormats) return true; /* Need to negotiate all variables. */ if (1 < vs->stm.bNumFormats) {
return true; /* Need to negotiate all variables. */
}
fmtnum = 1; fmtnum = 1;
param->bFormatIndex = 1; param->bFormatIndex = 1;
} }
@ -1259,7 +1261,7 @@ bool tud_video_n_frame_xfer(uint_fast8_t ctl_idx, uint_fast8_t stm_idx, void *bu
videod_streaming_interface_t *stm = _get_instance_streaming(ctl_idx, stm_idx); videod_streaming_interface_t *stm = _get_instance_streaming(ctl_idx, stm_idx);
videod_streaming_epbuf_t *stm_epbuf = &_videod_streaming_epbuf[ctl_idx]; videod_streaming_epbuf_t *stm_epbuf = &_videod_streaming_epbuf[ctl_idx];
if ( NULL == stm || 0 == stm->desc.ep[0] || stm->buffer) { if (NULL == stm || 0 == stm->desc.ep[0] || stm->buffer) {
return false; return false;
} }
if (stm->state == VS_STATE_PROBING) { if (stm->state == VS_STATE_PROBING) {

View File

@ -111,7 +111,7 @@ extern void* tusb_app_phys_to_virt(void *phys_addr);
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
//------------- Mem -------------// //------------- Mem -------------//
#define tu_memclr(buffer, size) memset((buffer), 0, (size)) #define tu_memclr(buffer, size) (void) memset((buffer), 0, (size))
#define tu_varclr(_var) tu_memclr(_var, sizeof(*(_var))) #define tu_varclr(_var) tu_memclr(_var, sizeof(*(_var)))
// This is a backport of memset_s from c11 // This is a backport of memset_s from c11
@ -121,6 +121,10 @@ TU_ATTR_ALWAYS_INLINE static inline int tu_memset_s(void *dest, size_t destsz, i
return -1; return -1;
} }
if (count == 0u) {
return 0;
}
if (count > destsz) { if (count > destsz) {
return -1; return -1;
} }
@ -131,13 +135,15 @@ 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 // 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) {
// Validate parameters
if (dest == NULL) { if (dest == NULL) {
return -1; return -1;
} }
// For memcpy, src may be NULL only if count == 0. Reject otherwise. if (count == 0u) {
if (src == NULL && count != 0u) { return 0;
}
if (src == NULL) {
return -1; return -1;
} }
@ -230,7 +236,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_round_up(uint32_t v, uint32_t f)
// TODO use clz TODO remove // TODO use clz TODO remove
TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_log2(uint32_t value) { TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_log2(uint32_t value) {
uint8_t result = 0; uint8_t result = 0;
while ((value >>= 1) != 0) { while (value >>= 1) {
result++; result++;
} }
return result; return result;

View File

@ -77,19 +77,19 @@
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
/* Count number of arguments of __VA_ARGS__ /* Count number of arguments of __VA_ARGS__
* - reference www.stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments * - reference www.stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments
* - _GET_NTH_ARG() takes args >= N (64) but only expand to Nth one (64th) * - TU_GET_NTH_ARG() takes args >= N (64) but only expand to Nth one (64th)
* - _RSEQ_N() is reverse sequential to N to add padding to have * - TU_NARG_RSEQ_N() is reverse sequential to N to add padding to have
* Nth position is the same as the number of arguments * Nth position is the same as the number of arguments
* - ##__VA_ARGS__ is used to deal with 0 paramerter (swallows comma) * - ##__VA_ARGS__ is used to deal with 0 paramerter (swallows comma)
*------------------------------------------------------------------*/ *------------------------------------------------------------------*/
#if !defined(__CCRX__) #if defined(__CCRX__)
#define TU_ARGS_NUM(...) _TU_NARG(_0, ##__VA_ARGS__, _RSEQ_N()) #define TU_ARGS_NUM(...) TU_NARG_IMPL(_0, __VA_ARGS__, TU_NARG_RSEQ_N())
#else #else
#define TU_ARGS_NUM(...) _TU_NARG(_0, __VA_ARGS__, _RSEQ_N()) #define TU_ARGS_NUM(...) TU_NARG_IMPL(_0, ##__VA_ARGS__, TU_NARG_RSEQ_N())
#endif #endif
#define _TU_NARG(...) _GET_NTH_ARG(__VA_ARGS__) #define TU_NARG_IMPL(...) TU_GET_NTH_ARG(__VA_ARGS__)
#define _GET_NTH_ARG( \ #define TU_GET_NTH_ARG( \
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \ _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \ _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \ _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
@ -97,7 +97,7 @@
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \ _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \ _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
_61,_62,_63,N,...) N _61,_62,_63,N,...) N
#define _RSEQ_N() \ #define TU_NARG_RSEQ_N() \
62,61,60, \ 62,61,60, \
59,58,57,56,55,54,53,52,51,50, \ 59,58,57,56,55,54,53,52,51,50, \
49,48,47,46,45,44,43,42,41,40, \ 49,48,47,46,45,44,43,42,41,40, \

View File

@ -38,14 +38,16 @@
#if OSAL_MUTEX_REQUIRED #if OSAL_MUTEX_REQUIRED
TU_ATTR_ALWAYS_INLINE static inline void _ff_lock(osal_mutex_t mutex) TU_ATTR_ALWAYS_INLINE static inline void _ff_lock(osal_mutex_t mutex) {
{ if (mutex) {
if (mutex) osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER); osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER);
}
} }
TU_ATTR_ALWAYS_INLINE static inline void _ff_unlock(osal_mutex_t mutex) TU_ATTR_ALWAYS_INLINE static inline void _ff_unlock(osal_mutex_t mutex) {
{ if (mutex) {
if (mutex) osal_mutex_unlock(mutex); osal_mutex_unlock(mutex);
}
} }
#else #else
@ -59,8 +61,7 @@ TU_ATTR_ALWAYS_INLINE static inline void _ff_unlock(osal_mutex_t mutex)
* \brief Write modes intended to allow special read and write functions to be able to * \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 * copy data to and from USB hardware FIFOs as needed for e.g. STM32s and others
*/ */
typedef enum typedef enum {
{
TU_FIFO_COPY_INC, ///< Copy from/to an increasing source/destination address - default mode TU_FIFO_COPY_INC, ///< Copy from/to an increasing source/destination address - default mode
#ifdef TUP_MEM_CONST_ADDR #ifdef TUP_MEM_CONST_ADDR
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_CST_FULL_WORDS, ///< Copy from/to a constant source/destination address - required for e.g. STM32 to write into USB hardware FIFO
@ -72,7 +73,9 @@ bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_si
// Limit index space to 2*depth - this allows for a fast "modulo" calculation // Limit index space to 2*depth - this allows for a fast "modulo" calculation
// but limits the maximum depth to 2^16/2 = 2^15 and buffer overflows are detectable // but limits the maximum depth to 2^16/2 = 2^15 and buffer overflows are detectable
// only if overflow happens once (important for unsupervised DMA applications) // only if overflow happens once (important for unsupervised DMA applications)
if (depth > 0x8000) return false; if (depth > 0x8000) {
return false;
}
_ff_lock(f->mutex_wr); _ff_lock(f->mutex_wr);
_ff_lock(f->mutex_rd); _ff_lock(f->mutex_rd);
@ -98,22 +101,19 @@ bool tu_fifo_config(tu_fifo_t *f, void* buffer, uint16_t depth, uint16_t item_si
// Intended to be used to read from hardware USB FIFO in e.g. STM32 where all data is read from a constant address // Intended to be used to read from hardware USB FIFO in e.g. STM32 where all data is read from a constant address
// Code adapted from dcd_synopsys.c // Code adapted from dcd_synopsys.c
// TODO generalize with configurable 1 byte or 4 byte each read // TODO generalize with configurable 1 byte or 4 byte each read
static void _ff_push_const_addr(uint8_t * ff_buf, const void * app_buf, uint16_t len) static void _ff_push_const_addr(uint8_t * ff_buf, const void * app_buf, uint16_t len) {
{
volatile const uint32_t * reg_rx = (volatile const uint32_t *) app_buf; volatile const uint32_t * reg_rx = (volatile const uint32_t *) app_buf;
// Reading full available 32 bit words from const app address // Reading full available 32 bit words from const app address
uint16_t full_words = len >> 2; uint16_t full_words = len >> 2;
while(full_words--) while(full_words--) {
{
tu_unaligned_write32(ff_buf, *reg_rx); tu_unaligned_write32(ff_buf, *reg_rx);
ff_buf += 4; ff_buf += 4;
} }
// Read the remaining 1-3 bytes from const app address // Read the remaining 1-3 bytes from const app address
uint8_t const bytes_rem = len & 0x03; uint8_t const bytes_rem = len & 0x03;
if ( bytes_rem ) if (bytes_rem) {
{
uint32_t tmp32 = *reg_rx; uint32_t tmp32 = *reg_rx;
memcpy(ff_buf, &tmp32, bytes_rem); memcpy(ff_buf, &tmp32, bytes_rem);
} }
@ -121,22 +121,19 @@ static void _ff_push_const_addr(uint8_t * ff_buf, const void * app_buf, uint16_t
// Intended to be used to write to hardware USB FIFO in e.g. STM32 // Intended to be used to write to hardware USB FIFO in e.g. STM32
// where all data is written to a constant address in full word copies // where all data is written to a constant address in full word copies
static void _ff_pull_const_addr(void * app_buf, const uint8_t * ff_buf, uint16_t len) static void _ff_pull_const_addr(void * app_buf, const uint8_t * ff_buf, uint16_t len) {
{
volatile uint32_t * reg_tx = (volatile uint32_t *) app_buf; volatile uint32_t * reg_tx = (volatile uint32_t *) app_buf;
// Write full available 32 bit words to const address // Write full available 32 bit words to const address
uint16_t full_words = len >> 2; uint16_t full_words = len >> 2;
while(full_words--) while(full_words--) {
{
*reg_tx = tu_unaligned_read32(ff_buf); *reg_tx = tu_unaligned_read32(ff_buf);
ff_buf += 4; ff_buf += 4;
} }
// Write the remaining 1-3 bytes into const address // Write the remaining 1-3 bytes into const address
uint8_t const bytes_rem = len & 0x03; uint8_t const bytes_rem = len & 0x03;
if ( bytes_rem ) if (bytes_rem) {
{
uint32_t tmp32 = 0; uint32_t tmp32 = 0;
memcpy(&tmp32, ff_buf, bytes_rem); memcpy(&tmp32, ff_buf, bytes_rem);
@ -146,8 +143,7 @@ static void _ff_pull_const_addr(void * app_buf, const uint8_t * ff_buf, uint16_t
#endif #endif
// send one item to fifo WITHOUT updating write pointer // send one item to fifo WITHOUT updating write pointer
static inline void _ff_push(tu_fifo_t* f, void const * app_buf, uint16_t rel) static inline void _ff_push(tu_fifo_t* f, void const * app_buf, uint16_t rel) {
{
memcpy(f->buffer + (rel * f->item_size), app_buf, f->item_size); memcpy(f->buffer + (rel * f->item_size), app_buf, f->item_size);
} }

View File

@ -141,7 +141,7 @@ uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s);
// Complete read transfer by writing EP -> FIFO. Must be called in the transfer complete callback // Complete read transfer by writing EP -> FIFO. Must be called in the transfer complete callback
TU_ATTR_ALWAYS_INLINE static inline TU_ATTR_ALWAYS_INLINE static inline
void tu_edpt_stream_read_xfer_complete(tu_edpt_stream_t* s, uint32_t xferred_bytes) { void tu_edpt_stream_read_xfer_complete(tu_edpt_stream_t* s, uint32_t xferred_bytes) {
if (tu_fifo_depth(&s->ff)) { if (0 != tu_fifo_depth(&s->ff)) {
tu_fifo_write_n(&s->ff, s->ep_buf, (uint16_t) xferred_bytes); tu_fifo_write_n(&s->ff, s->ep_buf, (uint16_t) xferred_bytes);
} }
} }
@ -149,7 +149,7 @@ void tu_edpt_stream_read_xfer_complete(tu_edpt_stream_t* s, uint32_t xferred_byt
// Complete read transfer with provided buffer // Complete read transfer with provided buffer
TU_ATTR_ALWAYS_INLINE static inline 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) { void tu_edpt_stream_read_xfer_complete_with_buf(tu_edpt_stream_t* s, const void * buf, uint32_t xferred_bytes) {
if (tu_fifo_depth(&s->ff)) { if (0 != 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);
} }
} }

View File

@ -548,7 +548,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_edpt_number(uint8_t addr) {
} }
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)); return (uint8_t) (num | (dir == TUSB_DIR_IN ? TUSB_DIR_IN_MASK : 0u));
} }
TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const* desc_ep) { TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const* desc_ep) {

View File

@ -78,7 +78,7 @@
defined(__ARM7M__) || defined (__ARM7EM__) || defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) defined(__ARM7M__) || defined (__ARM7EM__) || defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__)
#define TU_BREAKPOINT() do { \ #define TU_BREAKPOINT() do { \
volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \
if (0 != ((*ARM_CM_DHCSR) & 1UL)) {__asm("BKPT #0\n");} /* Only halt mcu if debugger is attached */ \ if (0 != ((*ARM_CM_DHCSR) & 1UL)) { __asm("BKPT #0\n"); } /* Only halt mcu if debugger is attached */ \
} while(0) } while(0)
#elif defined(__riscv) && !TUSB_MCU_VENDOR_ESPRESSIF #elif defined(__riscv) && !TUSB_MCU_VENDOR_ESPRESSIF
@ -98,7 +98,7 @@
*------------------------------------------------------------------*/ *------------------------------------------------------------------*/
#define TU_VERIFY_DEFINE(_cond, _ret) \ #define TU_VERIFY_DEFINE(_cond, _ret) \
do { \ do { \
if ( !(_cond) ) { return _ret; } \ if (!(_cond)) { return _ret; } \
} while(0) } while(0)
#define TU_VERIFY_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, false) #define TU_VERIFY_1ARGS(_cond) TU_VERIFY_DEFINE(_cond, false)

View File

@ -214,7 +214,7 @@ TU_ATTR_ALWAYS_INLINE static inline void dcd_event_setup_received(uint8_t rhport
dcd_event_t event; dcd_event_t event;
event.rhport = rhport; event.rhport = rhport;
event.event_id = DCD_EVENT_SETUP_RECEIVED; event.event_id = DCD_EVENT_SETUP_RECEIVED;
memcpy(&event.setup_received, setup, sizeof(tusb_control_request_t)); (void) memcpy(&event.setup_received, setup, sizeof(tusb_control_request_t));
dcd_event_handler(&event, in_isr); dcd_event_handler(&event, in_isr);
} }

View File

@ -354,6 +354,8 @@ TU_ATTR_ALWAYS_INLINE static inline usbd_class_driver_t const * get_driver(uint8
driver = &_app_driver[drvid]; driver = &_app_driver[drvid];
} else if (drvid < TOTAL_DRIVER_COUNT && BUILTIN_DRIVER_COUNT > 0) { } else if (drvid < TOTAL_DRIVER_COUNT && BUILTIN_DRIVER_COUNT > 0) {
driver = &_usbd_driver[drvid - _app_driver_count]; driver = &_usbd_driver[drvid - _app_driver_count];
} else {
// nothing to do
} }
return driver; return driver;
} }
@ -572,7 +574,7 @@ bool tud_deinit(uint8_t rhport) {
// Deinit device controller driver // Deinit device controller driver
dcd_int_disable(rhport); dcd_int_disable(rhport);
dcd_disconnect(rhport); dcd_disconnect(rhport);
dcd_deinit(rhport); TU_VERIFY(dcd_deinit(rhport));
// Deinit class drivers // Deinit class drivers
for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) {
@ -594,7 +596,6 @@ bool tud_deinit(uint8_t rhport) {
#endif #endif
_usbd_rhport = RHPORT_INVALID; _usbd_rhport = RHPORT_INVALID;
return true; return true;
} }
@ -606,8 +607,8 @@ static void configuration_reset(uint8_t rhport) {
} }
tu_varclr(&_usbd_dev); tu_varclr(&_usbd_dev);
memset(_usbd_dev.itf2drv, DRVID_INVALID, sizeof(_usbd_dev.itf2drv)); // invalid mapping (void) memset(_usbd_dev.itf2drv, DRVID_INVALID, sizeof(_usbd_dev.itf2drv)); // invalid mapping
memset(_usbd_dev.ep2drv, DRVID_INVALID, sizeof(_usbd_dev.ep2drv)); // invalid mapping (void) memset(_usbd_dev.ep2drv, DRVID_INVALID, sizeof(_usbd_dev.ep2drv)); // invalid mapping
} }
static void usbd_reset(uint8_t rhport) { static void usbd_reset(uint8_t rhport) {
@ -638,12 +639,16 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) {
(void) in_isr; // not implemented yet (void) in_isr; // not implemented yet
// Skip if stack is not initialized // Skip if stack is not initialized
if (!tud_inited()) return; if (!tud_inited()) {
return;
}
// Loop until there is no more events in the queue // Loop until there is no more events in the queue
while (1) { while (1) {
dcd_event_t event; dcd_event_t event;
if (!osal_queue_receive(_usbd_q, &event, timeout_ms)) return; if (!osal_queue_receive(_usbd_q, &event, timeout_ms)) {
return;
}
#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL #if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
if (event.event_id == DCD_EVENT_SETUP_RECEIVED) TU_LOG_USBD("\r\n"); // extra line for setup if (event.event_id == DCD_EVENT_SETUP_RECEIVED) TU_LOG_USBD("\r\n"); // extra line for setup
@ -667,7 +672,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) {
TU_ASSERT(_usbd_queued_setup > 0,); TU_ASSERT(_usbd_queued_setup > 0,);
_usbd_queued_setup--; _usbd_queued_setup--;
TU_LOG_BUF(CFG_TUD_LOG_LEVEL, &event.setup_received, 8); TU_LOG_BUF(CFG_TUD_LOG_LEVEL, &event.setup_received, 8);
if (_usbd_queued_setup) { if (_usbd_queued_setup != 0) {
TU_LOG_USBD(" Skipped since there is other SETUP in queue\r\n"); TU_LOG_USBD(" Skipped since there is other SETUP in queue\r\n");
break; break;
} }
@ -703,8 +708,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) {
_usbd_dev.ep_status[epnum][ep_dir].claimed = 0; _usbd_dev.ep_status[epnum][ep_dir].claimed = 0;
if (0 == epnum) { if (0 == epnum) {
usbd_control_xfer_cb(event.rhport, ep_addr, (xfer_result_t) event.xfer_complete.result, usbd_control_xfer_cb(event.rhport, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len);
event.xfer_complete.len);
} else { } else {
usbd_class_driver_t const* driver = get_driver(_usbd_dev.ep2drv[epnum][ep_dir]); usbd_class_driver_t const* driver = get_driver(_usbd_dev.ep2drv[epnum][ep_dir]);
TU_ASSERT(driver,); TU_ASSERT(driver,);
@ -738,7 +742,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) {
case USBD_EVENT_FUNC_CALL: case USBD_EVENT_FUNC_CALL:
TU_LOG_USBD("\r\n"); TU_LOG_USBD("\r\n");
if (event.func_call.func) { if (event.func_call.func != NULL) {
event.func_call.func(event.func_call.param); event.func_call.func(event.func_call.param);
} }
break; break;
@ -792,7 +796,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
} }
#endif #endif
switch ( p_request->bmRequestType_bit.recipient ) { switch (p_request->bmRequestType_bit.recipient) { //-V2520
//------------- Device Requests e.g in enumeration -------------// //------------- Device Requests e.g in enumeration -------------//
case TUSB_REQ_RCPT_DEVICE: case TUSB_REQ_RCPT_DEVICE:
if ( TUSB_REQ_TYPE_CLASS == p_request->bmRequestType_bit.type ) { if ( TUSB_REQ_TYPE_CLASS == p_request->bmRequestType_bit.type ) {
@ -806,13 +810,13 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
return invoke_class_control(rhport, driver, p_request); return invoke_class_control(rhport, driver, p_request);
} }
if ( TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type ) { if (TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type) {
// Non-standard request is not supported // Non-standard request is not supported
TU_BREAKPOINT(); TU_BREAKPOINT();
return false; return false;
} }
switch ( p_request->bRequest ) { switch (p_request->bRequest) { //-V2520
case TUSB_REQ_SET_ADDRESS: case TUSB_REQ_SET_ADDRESS:
// Depending on mcu, status phase could be sent either before or after changing device address, // Depending on mcu, status phase could be sent either before or after changing device address,
// or even require stack to not response with status at all // or even require stack to not response with status at all
@ -834,18 +838,15 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
// Only process if new configure is different // Only process if new configure is different
if (_usbd_dev.cfg_num != cfg_num) { if (_usbd_dev.cfg_num != cfg_num) {
if ( _usbd_dev.cfg_num ) { if (_usbd_dev.cfg_num != 0) {
// already configured: need to clear all endpoints and driver first // already configured: need to clear all endpoints and driver first
TU_LOG_USBD(" Clear current Configuration (%u) before switching\r\n", _usbd_dev.cfg_num); TU_LOG_USBD(" Clear current Configuration (%u) before switching\r\n", _usbd_dev.cfg_num);
// disable SOF
dcd_sof_enable(rhport, false); dcd_sof_enable(rhport, false);
// close all non-control endpoints, cancel all pending transfers if any
dcd_edpt_close_all(rhport); dcd_edpt_close_all(rhport);
// close all drivers and current configured state except bus speed // close all drivers and current configured state except bus speed
uint8_t const speed = _usbd_dev.speed; const uint8_t speed = _usbd_dev.speed;
configuration_reset(rhport); configuration_reset(rhport);
_usbd_dev.speed = speed; // restore speed _usbd_dev.speed = speed; // restore speed
@ -853,18 +854,15 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
_usbd_dev.cfg_num = cfg_num; _usbd_dev.cfg_num = cfg_num;
// Handle the new configuration and execute the corresponding callback // Handle the new configuration
if ( cfg_num ) { if (cfg_num == 0) {
// switch to new configuration if not zero tud_umount_cb();
} else {
if (!process_set_config(rhport, cfg_num)) { if (!process_set_config(rhport, cfg_num)) {
TU_MESS_FAILED();
TU_BREAKPOINT();
_usbd_dev.cfg_num = 0; _usbd_dev.cfg_num = 0;
return false; TU_ASSERT(false);
} }
tud_mount_cb(); tud_mount_cb();
} else {
tud_umount_cb();
} }
} }
@ -873,11 +871,11 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
break; break;
case TUSB_REQ_GET_DESCRIPTOR: case TUSB_REQ_GET_DESCRIPTOR:
TU_VERIFY( process_get_descriptor(rhport, p_request) ); TU_VERIFY(process_get_descriptor(rhport, p_request));
break; break;
case TUSB_REQ_SET_FEATURE: case TUSB_REQ_SET_FEATURE:
switch(p_request->wValue) { switch(p_request->wValue) { //-V2520
case TUSB_REQ_FEATURE_REMOTE_WAKEUP: case TUSB_REQ_FEATURE_REMOTE_WAKEUP:
TU_LOG_USBD(" Enable Remote Wakeup\r\n"); TU_LOG_USBD(" Enable Remote Wakeup\r\n");
// Host may enable remote wake up before suspending especially HID device // Host may enable remote wake up before suspending especially HID device
@ -897,7 +895,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
tud_control_status(rhport, p_request); tud_control_status(rhport, p_request);
break; break;
} }
#endif /* CFG_TUD_TEST_MODE */ #endif
// Stall unsupported feature selector // Stall unsupported feature selector
default: return false; default: return false;
@ -907,7 +905,6 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
case TUSB_REQ_CLEAR_FEATURE: case TUSB_REQ_CLEAR_FEATURE:
// Only support remote wakeup for device feature // Only support remote wakeup for device feature
TU_VERIFY(TUSB_REQ_FEATURE_REMOTE_WAKEUP == p_request->wValue); TU_VERIFY(TUSB_REQ_FEATURE_REMOTE_WAKEUP == p_request->wValue);
TU_LOG_USBD(" Disable Remote Wakeup\r\n"); TU_LOG_USBD(" Disable Remote Wakeup\r\n");
// Host may disable remote wake up after resuming // Host may disable remote wake up after resuming
@ -939,23 +936,23 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
// all requests to Interface (STD or Class) is forwarded to class driver. // all requests to Interface (STD or Class) is forwarded to class driver.
// notable requests are: GET HID REPORT DESCRIPTOR, SET_INTERFACE, GET_INTERFACE // notable requests are: GET HID REPORT DESCRIPTOR, SET_INTERFACE, GET_INTERFACE
if ( !invoke_class_control(rhport, driver, p_request) ) { if (!invoke_class_control(rhport, driver, p_request)) {
// For GET_INTERFACE and SET_INTERFACE, it is mandatory to respond even if the class // For GET_INTERFACE and SET_INTERFACE, it is mandatory to respond even if the class
// driver doesn't use alternate settings or implement this // driver doesn't use alternate settings or implement this
TU_VERIFY(TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type); TU_VERIFY(TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type);
switch(p_request->bRequest) {
case TUSB_REQ_GET_INTERFACE:
case TUSB_REQ_SET_INTERFACE:
// Clear complete callback if driver set since it can also stall the request. // Clear complete callback if driver set since it can also stall the request.
usbd_control_set_complete_callback(NULL); usbd_control_set_complete_callback(NULL);
if (TUSB_REQ_GET_INTERFACE == p_request->bRequest) { switch (p_request->bRequest) { //-V2520
case TUSB_REQ_GET_INTERFACE: {
uint8_t alternate = 0; uint8_t alternate = 0;
tud_control_xfer(rhport, p_request, &alternate, 1); tud_control_xfer(rhport, p_request, &alternate, 1);
}else { break;
tud_control_status(rhport, p_request);
} }
case TUSB_REQ_SET_INTERFACE:
tud_control_status(rhport, p_request);
break; break;
default: return false; default: return false;
@ -973,15 +970,15 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
TU_ASSERT(ep_num < TU_ARRAY_SIZE(_usbd_dev.ep2drv) ); TU_ASSERT(ep_num < TU_ARRAY_SIZE(_usbd_dev.ep2drv) );
usbd_class_driver_t const * driver = get_driver(_usbd_dev.ep2drv[ep_num][ep_dir]); usbd_class_driver_t const * driver = get_driver(_usbd_dev.ep2drv[ep_num][ep_dir]);
if ( TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type ) { if (TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type) {
// Forward class request to its driver // Forward class request to its driver
TU_VERIFY(driver); TU_VERIFY(driver);
return invoke_class_control(rhport, driver, p_request); return invoke_class_control(rhport, driver, p_request);
} else { } else {
// Handle STD request to endpoint // Handle STD request to endpoint
switch ( p_request->bRequest ) { switch (p_request->bRequest) { //-V2520
case TUSB_REQ_GET_STATUS: { case TUSB_REQ_GET_STATUS: {
uint16_t status = usbd_edpt_stalled(rhport, ep_addr) ? 0x0001 : 0x0000; uint16_t status = usbd_edpt_stalled(rhport, ep_addr) ? 0x0001u : 0x0000u;
tud_control_xfer(rhport, p_request, &status, 2); tud_control_xfer(rhport, p_request, &status, 2);
} }
break; break;
@ -996,7 +993,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
} }
} }
if (driver) { if (driver != NULL) {
// Some classes such as USBTMC needs to clear/re-init its buffer when receiving CLEAR_FEATURE request // Some classes such as USBTMC needs to clear/re-init its buffer when receiving CLEAR_FEATURE request
// We will also forward std request targeted endpoint to class drivers as well // We will also forward std request targeted endpoint to class drivers as well
@ -1006,7 +1003,9 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
usbd_control_set_complete_callback(NULL); usbd_control_set_complete_callback(NULL);
// skip ZLP status if driver already did that // skip ZLP status if driver already did that
if ( !_usbd_dev.ep_status[0][TUSB_DIR_IN].busy ) tud_control_status(rhport, p_request); if (!_usbd_dev.ep_status[0][TUSB_DIR_IN].busy) {
tud_control_status(rhport, p_request);
}
} }
} }
break; break;
@ -1017,8 +1016,8 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
return false; return false;
} }
} }
}
break; break;
}
// Unknown recipient // Unknown recipient
default: default:
@ -1081,10 +1080,11 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num)
// Some drivers use 2 or more interfaces but may not have IAD e.g MIDI (always) or // Some drivers use 2 or more interfaces but may not have IAD e.g MIDI (always) or
// BTH (even CDC) with class in device descriptor (single interface) // BTH (even CDC) with class in device descriptor (single interface)
if ( assoc_itf_count == 1) if (assoc_itf_count == 1) {
{
#if CFG_TUD_CDC #if CFG_TUD_CDC
if ( driver->open == cdcd_open ) assoc_itf_count = 2; if ( driver->open == cdcd_open ) {
assoc_itf_count = 2;
}
#endif #endif
#if CFG_TUD_MIDI #if CFG_TUD_MIDI
@ -1158,8 +1158,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
tusb_desc_type_t const desc_type = (tusb_desc_type_t) tu_u16_high(p_request->wValue); tusb_desc_type_t const desc_type = (tusb_desc_type_t) tu_u16_high(p_request->wValue);
uint8_t const desc_index = tu_u16_low( p_request->wValue ); uint8_t const desc_index = tu_u16_low( p_request->wValue );
switch(desc_type) switch(desc_type) { //-V2520
{
case TUSB_DESC_DEVICE: { case TUSB_DESC_DEVICE: {
TU_LOG_USBD(" Device\r\n"); TU_LOG_USBD(" Device\r\n");
@ -1187,7 +1186,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
// requested by host if USB > 2.0 ( i.e 2.1 or 3.x ) // requested by host if USB > 2.0 ( i.e 2.1 or 3.x )
uintptr_t desc_bos = (uintptr_t) tud_descriptor_bos_cb(); uintptr_t desc_bos = (uintptr_t) tud_descriptor_bos_cb();
TU_VERIFY(desc_bos); TU_VERIFY(desc_bos != 0);
// Use offsetof to avoid pointer to the odd/misaligned address // Use offsetof to avoid pointer to the odd/misaligned address
uint16_t const total_len = tu_le16toh( tu_unaligned_read16((const void*) (desc_bos + offsetof(tusb_desc_bos_t, wTotalLength))) ); uint16_t const total_len = tu_le16toh( tu_unaligned_read16((const void*) (desc_bos + offsetof(tusb_desc_bos_t, wTotalLength))) );
@ -1203,12 +1202,12 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
if ( desc_type == TUSB_DESC_CONFIGURATION ) { if ( desc_type == TUSB_DESC_CONFIGURATION ) {
TU_LOG_USBD(" Configuration[%u]\r\n", desc_index); TU_LOG_USBD(" Configuration[%u]\r\n", desc_index);
desc_config = (uintptr_t) tud_descriptor_configuration_cb(desc_index); desc_config = (uintptr_t) tud_descriptor_configuration_cb(desc_index);
TU_ASSERT(desc_config); TU_ASSERT(desc_config != 0);
}else { }else {
// Host only request this after getting Device Qualifier descriptor // Host only request this after getting Device Qualifier descriptor
TU_LOG_USBD(" Other Speed Configuration\r\n"); TU_LOG_USBD(" Other Speed Configuration\r\n");
desc_config = (uintptr_t) tud_descriptor_other_speed_configuration_cb(desc_index); desc_config = (uintptr_t) tud_descriptor_other_speed_configuration_cb(desc_index);
TU_VERIFY(desc_config); TU_VERIFY(desc_config != 0);
} }
// Use offsetof to avoid pointer to the odd/misaligned address // Use offsetof to avoid pointer to the odd/misaligned address
@ -1218,8 +1217,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
} }
// break; // unreachable // break; // unreachable
case TUSB_DESC_STRING: case TUSB_DESC_STRING: {
{
TU_LOG_USBD(" String[%u]\r\n", desc_index); TU_LOG_USBD(" String[%u]\r\n", desc_index);
// String Descriptor always uses the desc set from user // String Descriptor always uses the desc set from user

View File

@ -95,7 +95,9 @@ bool tud_suspended(void);
// Check if device is ready to transfer // Check if device is ready to transfer
TU_ATTR_ALWAYS_INLINE static inline TU_ATTR_ALWAYS_INLINE static inline
bool tud_ready(void) { bool tud_ready(void) {
return tud_mounted() && !tud_suspended(); const bool is_mounted = tud_mounted();
const bool is_suspended = tud_suspended();
return is_mounted && !is_suspended;
} }
// Remote wake up host, only if suspended and enabled by host // Remote wake up host, only if suspended and enabled by host
@ -421,7 +423,7 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
TUD_AUDIO10_DESC_SELECTOR_UNIT_ONE_PIN_LEN, TUSB_DESC_CS_INTERFACE, AUDIO10_CS_AC_INTERFACE_SELECTOR_UNIT, _unitid, 1, _srcid, _stridx TUD_AUDIO10_DESC_SELECTOR_UNIT_ONE_PIN_LEN, TUSB_DESC_CS_INTERFACE, AUDIO10_CS_AC_INTERFACE_SELECTOR_UNIT, _unitid, 1, _srcid, _stridx
/* Feature Unit Descriptor UAC1 (4.3.2.5) - Variable Channels */ /* Feature Unit Descriptor UAC1 (4.3.2.5) - Variable Channels */
#define TUD_AUDIO10_DESC_FEATURE_UNIT_LEN(_nchannels) (7 + (_nchannels + 1) * 2) #define TUD_AUDIO10_DESC_FEATURE_UNIT_LEN(_nchannels) (7 + ((_nchannels) + 1) * 2)
// Feature Unit descriptor, take list of control bitmaps for master channel + each channel as variable arguments // Feature Unit descriptor, take list of control bitmaps for master channel + each channel as variable arguments
#define TUD_AUDIO10_DESC_FEATURE_UNIT(_unitid, _srcid, _stridx, ...) \ #define TUD_AUDIO10_DESC_FEATURE_UNIT(_unitid, _srcid, _stridx, ...) \
TUD_AUDIO10_DESC_FEATURE_UNIT_LEN(TU_ARGS_NUM(__VA_ARGS__) - 1), TUSB_DESC_CS_INTERFACE, AUDIO10_CS_AC_INTERFACE_FEATURE_UNIT, _unitid, _srcid, 2, TU_ARGS_APPLY_EXPAND(U16_TO_U8S_LE, __VA_ARGS__), _stridx TUD_AUDIO10_DESC_FEATURE_UNIT_LEN(TU_ARGS_NUM(__VA_ARGS__) - 1), TUSB_DESC_CS_INTERFACE, AUDIO10_CS_AC_INTERFACE_FEATURE_UNIT, _unitid, _srcid, 2, TU_ARGS_APPLY_EXPAND(U16_TO_U8S_LE, __VA_ARGS__), _stridx
@ -539,7 +541,7 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
TUD_AUDIO20_DESC_OUTPUT_TERM_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AC_INTERFACE_OUTPUT_TERMINAL, _termid, U16_TO_U8S_LE(_termtype), _assocTerm, _srcid, _clkid, U16_TO_U8S_LE(_ctrl), _stridx TUD_AUDIO20_DESC_OUTPUT_TERM_LEN, TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AC_INTERFACE_OUTPUT_TERMINAL, _termid, U16_TO_U8S_LE(_termtype), _assocTerm, _srcid, _clkid, U16_TO_U8S_LE(_ctrl), _stridx
/* Feature Unit Descriptor(4.7.2.8) */ /* Feature Unit Descriptor(4.7.2.8) */
#define TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(_nchannels) (6 + (_nchannels + 1) * 4) #define TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(_nchannels) (6 + ((_nchannels) + 1) * 4)
#define TUD_AUDIO20_DESC_FEATURE_UNIT(_unitid, _srcid, _stridx, ...) \ #define TUD_AUDIO20_DESC_FEATURE_UNIT(_unitid, _srcid, _stridx, ...) \
TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(TU_ARGS_NUM(__VA_ARGS__) - 1), TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AC_INTERFACE_FEATURE_UNIT, _unitid, _srcid, TU_ARGS_APPLY_EXPAND(U32_TO_U8S_LE, __VA_ARGS__), _stridx TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(TU_ARGS_NUM(__VA_ARGS__) - 1), TUSB_DESC_CS_INTERFACE, AUDIO20_CS_AC_INTERFACE_FEATURE_UNIT, _unitid, _srcid, TU_ARGS_APPLY_EXPAND(U32_TO_U8S_LE, __VA_ARGS__), _stridx
@ -728,7 +730,7 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
// Calculate wMaxPacketSize of Endpoints // Calculate wMaxPacketSize of Endpoints
#define TUD_AUDIO_EP_SIZE(_is_highspeed, _maxFrequency, _nBytesPerSample, _nChannels) \ #define TUD_AUDIO_EP_SIZE(_is_highspeed, _maxFrequency, _nBytesPerSample, _nChannels) \
((((_maxFrequency + (_is_highspeed ? 7999 : 999)) / (_is_highspeed ? 8000 : 1000)) + 1) * _nBytesPerSample * _nChannels) (((((_maxFrequency) + ((_is_highspeed) ? 7999 : 999)) / ((_is_highspeed) ? 8000 : 1000)) + 1) * (_nBytesPerSample) * (_nChannels))
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
@ -807,44 +809,44 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ
// Interface number, Alternate count, starting string index, attributes, detach timeout, transfer size // Interface number, Alternate count, starting string index, attributes, detach timeout, transfer size
// Note: Alternate count must be numeric or macro, string index is increased by one for each Alt interface // Note: Alternate count must be numeric or macro, string index is increased by one for each Alt interface
#define TUD_DFU_DESCRIPTOR(_itfnum, _alt_count, _stridx, _attr, _timeout, _xfer_size) \ #define TUD_DFU_DESCRIPTOR(_itfnum, _alt_count, _stridx, _attr, _timeout, _xfer_size) \
TU_XSTRCAT(_TUD_DFU_ALT_,_alt_count)(_itfnum, 0, _stridx), \ TU_XSTRCAT(TUD_DFU_ALT_,_alt_count)(_itfnum, 0, _stridx), \
/* Function */ \ /* Function */ \
9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0101) 9, DFU_DESC_FUNCTIONAL, _attr, U16_TO_U8S_LE(_timeout), U16_TO_U8S_LE(_xfer_size), U16_TO_U8S_LE(0x0101)
#define _TUD_DFU_ALT(_itfnum, _alt, _stridx) \ #define TUD_DFU_ALT(_itfnum, _alt, _stridx) \
/* Interface */ \ /* Interface */ \
9, TUSB_DESC_INTERFACE, _itfnum, _alt, 0, TUD_DFU_APP_CLASS, TUD_DFU_APP_SUBCLASS, DFU_PROTOCOL_DFU, _stridx 9, TUSB_DESC_INTERFACE, _itfnum, _alt, 0, TUD_DFU_APP_CLASS, TUD_DFU_APP_SUBCLASS, DFU_PROTOCOL_DFU, _stridx
#define _TUD_DFU_ALT_1(_itfnum, _alt_count, _stridx) \ #define TUD_DFU_ALT_1(_itfnum, _alt_count, _stridx) \
_TUD_DFU_ALT(_itfnum, _alt_count, _stridx) TUD_DFU_ALT(_itfnum, _alt_count, _stridx)
#define _TUD_DFU_ALT_2(_itfnum, _alt_count, _stridx) \ #define TUD_DFU_ALT_2(_itfnum, _alt_count, _stridx) \
_TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \ TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \
_TUD_DFU_ALT_1(_itfnum, _alt_count+1, _stridx+1) TUD_DFU_ALT_1(_itfnum, _alt_count+1, _stridx+1)
#define _TUD_DFU_ALT_3(_itfnum, _alt_count, _stridx) \ #define TUD_DFU_ALT_3(_itfnum, _alt_count, _stridx) \
_TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \ TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \
_TUD_DFU_ALT_2(_itfnum, _alt_count+1, _stridx+1) TUD_DFU_ALT_2(_itfnum, _alt_count+1, _stridx+1)
#define _TUD_DFU_ALT_4(_itfnum, _alt_count, _stridx) \ #define TUD_DFU_ALT_4(_itfnum, _alt_count, _stridx) \
_TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \ TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \
_TUD_DFU_ALT_3(_itfnum, _alt_count+1, _stridx+1) TUD_DFU_ALT_3(_itfnum, _alt_count+1, _stridx+1)
#define _TUD_DFU_ALT_5(_itfnum, _alt_count, _stridx) \ #define TUD_DFU_ALT_5(_itfnum, _alt_count, _stridx) \
_TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \ TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \
_TUD_DFU_ALT_4(_itfnum, _alt_count+1, _stridx+1) TUD_DFU_ALT_4(_itfnum, _alt_count+1, _stridx+1)
#define _TUD_DFU_ALT_6(_itfnum, _alt_count, _stridx) \ #define TUD_DFU_ALT_6(_itfnum, _alt_count, _stridx) \
_TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \ TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \
_TUD_DFU_ALT_5(_itfnum, _alt_count+1, _stridx+1) TUD_DFU_ALT_5(_itfnum, _alt_count+1, _stridx+1)
#define _TUD_DFU_ALT_7(_itfnum, _alt_count, _stridx) \ #define TUD_DFU_ALT_7(_itfnum, _alt_count, _stridx) \
_TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \ TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \
_TUD_DFU_ALT_6(_itfnum, _alt_count+1, _stridx+1) TUD_DFU_ALT_6(_itfnum, _alt_count+1, _stridx+1)
#define _TUD_DFU_ALT_8(_itfnum, _alt_count, _stridx) \ #define TUD_DFU_ALT_8(_itfnum, _alt_count, _stridx) \
_TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \ TUD_DFU_ALT(_itfnum, _alt_count, _stridx), \
_TUD_DFU_ALT_7(_itfnum, _alt_count+1, _stridx+1) TUD_DFU_ALT_7(_itfnum, _alt_count+1, _stridx+1)
//--------------------------------------------------------------------+ //--------------------------------------------------------------------+
// CDC-ECM Descriptor Templates // CDC-ECM Descriptor Templates

View File

@ -117,7 +117,9 @@ bool usbd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endp
// Check if endpoint is ready (not busy and not stalled) // Check if endpoint is ready (not busy and not stalled)
TU_ATTR_ALWAYS_INLINE static inline TU_ATTR_ALWAYS_INLINE static inline
bool usbd_edpt_ready(uint8_t rhport, uint8_t ep_addr) { bool usbd_edpt_ready(uint8_t rhport, uint8_t ep_addr) {
return !usbd_edpt_busy(rhport, ep_addr) && !usbd_edpt_stalled(rhport, ep_addr); const bool is_busy = usbd_edpt_busy(rhport, ep_addr);
const bool is_stalled = usbd_edpt_stalled(rhport, ep_addr);
return !is_busy && !is_stalled;
} }
// Enable SOF interrupt // Enable SOF interrupt

View File

@ -85,6 +85,12 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t dwc2_ep_count(const dwc2_regs_t* dwc
#endif #endif
} }
//--------------------------------------------------------------------+
//
//--------------------------------------------------------------------+
TU_ATTR_ALWAYS_INLINE static inline bool edpt_is_enabled(dwc2_dep_t* dep) {
return (dep->ctl & EPCTL_EPENA) != 0;
}
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// DMA // DMA
@ -117,7 +123,7 @@ static void dma_setup_prepare(uint8_t rhport) {
dwc2_regs_t* dwc2 = DWC2_REG(rhport); dwc2_regs_t* dwc2 = DWC2_REG(rhport);
if (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a) { if (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a) {
if(dwc2->epout[0].doepctl & DOEPCTL_EPENA) { if(edpt_is_enabled(&dwc2->epout[0])) {
return; return;
} }
} }
@ -200,7 +206,7 @@ static bool dfifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) {
} }
} else { } else {
// Check IN endpoints concurrently active limit // Check IN endpoints concurrently active limit
if(dwc2_controller->ep_in_count) { if(0 != dwc2_controller->ep_in_count) {
TU_ASSERT(_dcd_data.allocated_epin_count < dwc2_controller->ep_in_count); TU_ASSERT(_dcd_data.allocated_epin_count < dwc2_controller->ep_in_count);
_dcd_data.allocated_epin_count++; _dcd_data.allocated_epin_count++;
} }
@ -217,10 +223,10 @@ static bool dfifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) {
// Both TXFD and TXSA are in unit of 32-bit words. // Both TXFD and TXSA are in unit of 32-bit words.
if (epnum == 0) { if (epnum == 0) {
dwc2->dieptxf0 = (fifo_size << DIEPTXF0_TX0FD_Pos) | _dcd_data.dfifo_top; dwc2->dieptxf0 = ((uint32_t) fifo_size << DIEPTXF0_TX0FD_Pos) | _dcd_data.dfifo_top;
} else { } else {
// DIEPTXF starts at FIFO #1. // DIEPTXF starts at FIFO #1.
dwc2->dieptxf[epnum - 1] = (fifo_size << DIEPTXF_INEPTXFD_Pos) | _dcd_data.dfifo_top; dwc2->dieptxf[epnum - 1] = ((uint32_t) fifo_size << DIEPTXF_INEPTXFD_Pos) | _dcd_data.dfifo_top;
} }
} }
@ -238,10 +244,10 @@ static void dfifo_device_init(uint8_t rhport) {
if (is_dma) { if (is_dma) {
_dcd_data.dfifo_top -= 2 * dwc2_controller->ep_count; _dcd_data.dfifo_top -= 2 * dwc2_controller->ep_count;
} }
dwc2->gdfifocfg = (_dcd_data.dfifo_top << GDFIFOCFG_EPINFOBASE_SHIFT) | _dcd_data.dfifo_top; dwc2->gdfifocfg = ((uint32_t) _dcd_data.dfifo_top << GDFIFOCFG_EPINFOBASE_SHIFT) | _dcd_data.dfifo_top;
// Allocate FIFO for EP0 IN // Allocate FIFO for EP0 IN
dfifo_alloc(rhport, 0x80, CFG_TUD_ENDPOINT0_SIZE); (void) dfifo_alloc(rhport, 0x80, CFG_TUD_ENDPOINT0_SIZE);
} }
@ -282,16 +288,18 @@ static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) {
const uint8_t dir = tu_edpt_dir(ep_addr); const uint8_t dir = tu_edpt_dir(ep_addr);
dwc2_dep_t* dep = &dwc2->ep[dir == TUSB_DIR_IN ? 0 : 1][epnum]; dwc2_dep_t* dep = &dwc2->ep[dir == TUSB_DIR_IN ? 0 : 1][epnum];
const uint32_t stall_mask = (stall ? EPCTL_STALL : 0);
if (dir == TUSB_DIR_IN) { if (dir == TUSB_DIR_IN) {
if (!(dep->diepctl & DIEPCTL_EPENA)) { if (!edpt_is_enabled(dep)) {
dep->diepctl |= DIEPCTL_SNAK | (stall ? DIEPCTL_STALL : 0); dep->diepctl |= DIEPCTL_SNAK | stall_mask;
} else { } else {
// Stop transmitting packets and NAK IN xfers. // Stop transmitting packets and NAK IN xfers.
dep->diepctl |= DIEPCTL_SNAK; dep->diepctl |= DIEPCTL_SNAK;
while ((dep->diepint & DIEPINT_INEPNE) == 0) {} while ((dep->diepint & DIEPINT_INEPNE) == 0) {}
// Disable the endpoint. // Disable the endpoint.
dep->diepctl |= DIEPCTL_EPDIS | (stall ? DIEPCTL_STALL : 0); dep->diepctl |= DIEPCTL_EPDIS | stall_mask;
while ((dep->diepint & DIEPINT_EPDISD_Msk) == 0) {} while ((dep->diepint & DIEPINT_EPDISD_Msk) == 0) {}
dep->diepint = DIEPINT_EPDISD; dep->diepint = DIEPINT_EPDISD;
@ -300,9 +308,10 @@ static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) {
// Flush the FIFO, and wait until we have confirmed it cleared. // Flush the FIFO, and wait until we have confirmed it cleared.
dfifo_flush_tx(dwc2, epnum); dfifo_flush_tx(dwc2, epnum);
} else { } else {
// Only disable currently enabled non-control endpoint if (!edpt_is_enabled(dep) || epnum == 0) {
if ((epnum == 0) || !(dep->doepctl & DOEPCTL_EPENA)) { // non-control not-enabled: stall if set
dep->doepctl |= stall ? DOEPCTL_STALL : 0; // For EP0 Out, keep it enabled to receive SETUP packets
dep->doepctl |= stall_mask;
} else { } else {
// Asserting GONAK is required to STALL an OUT endpoint. // Asserting GONAK is required to STALL an OUT endpoint.
// Simpler to use polling here, we don't use the "B"OUTNAKEFF interrupt // Simpler to use polling here, we don't use the "B"OUTNAKEFF interrupt
@ -312,7 +321,7 @@ static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) {
while ((dwc2->gintsts & GINTSTS_BOUTNAKEFF_Msk) == 0) {} while ((dwc2->gintsts & GINTSTS_BOUTNAKEFF_Msk) == 0) {}
// Ditto here disable the endpoint. // Ditto here disable the endpoint.
dep->doepctl |= DOEPCTL_EPDIS | (stall ? DOEPCTL_STALL : 0); dep->doepctl |= DOEPCTL_EPDIS | stall_mask;
while ((dep->doepint & DOEPINT_EPDISD_Msk) == 0) {} while ((dep->doepint & DOEPINT_EPDISD_Msk) == 0) {}
dep->doepint = DOEPINT_EPDISD; dep->doepint = DOEPINT_EPDISD;
@ -360,7 +369,7 @@ static void edpt_schedule_packets(uint8_t rhport, const uint8_t epnum, const uin
if (depctl.type == DEPCTL_EPTYPE_ISOCHRONOUS && xfer->interval == 1) { if (depctl.type == DEPCTL_EPTYPE_ISOCHRONOUS && xfer->interval == 1) {
const dwc2_dsts_t dsts = {.value = dwc2->dsts}; const dwc2_dsts_t dsts = {.value = dwc2->dsts};
const uint32_t odd_now = dsts.frame_number & 1u; const uint32_t odd_now = dsts.frame_number & 1u;
if (odd_now) { if (odd_now != 0) {
depctl.set_data0_iso_even = 1; depctl.set_data0_iso_even = 1;
} else { } else {
depctl.set_data1_iso_odd = 1; depctl.set_data1_iso_odd = 1;
@ -379,7 +388,7 @@ static void edpt_schedule_packets(uint8_t rhport, const uint8_t epnum, const uin
// Enable tx fifo empty interrupt only if there is data. Note must after depctl enable // Enable tx fifo empty interrupt only if there is data. Note must after depctl enable
if (dir == TUSB_DIR_IN && total_bytes != 0) { if (dir == TUSB_DIR_IN && total_bytes != 0) {
dwc2->diepempmsk |= (1u << epnum); dwc2->diepempmsk |= (1u << epnum); //-V629
} }
} }
} }
@ -551,7 +560,7 @@ void dcd_edpt_close_all(uint8_t rhport) {
for (uint8_t n = 1; n < ep_count; n++) { for (uint8_t n = 1; n < ep_count; n++) {
for (uint8_t d = 0; d < 2; d++) { for (uint8_t d = 0; d < 2; d++) {
dwc2_dep_t* dep = &dwc2->ep[d][n]; dwc2_dep_t* dep = &dwc2->ep[d][n];
if (dep->ctl & EPCTL_EPENA) { if (edpt_is_enabled(dep)) {
dep->ctl |= EPCTL_SNAK | EPCTL_EPDIS; dep->ctl |= EPCTL_SNAK | EPCTL_EPDIS;
} }
xfer_status[n][1-d].max_size = 0; xfer_status[n][1-d].max_size = 0;
@ -643,9 +652,13 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) {
dwc2_regs_t* dwc2 = DWC2_REG(rhport); dwc2_regs_t* dwc2 = DWC2_REG(rhport);
edpt_disable(rhport, ep_addr, true); edpt_disable(rhport, ep_addr, true);
if((tu_edpt_number(ep_addr) == 0) && dma_device_enabled(dwc2)) {
// For control endpoint, prepare to receive SETUP packet
if (tu_edpt_number(ep_addr) == 0) {
if (dma_device_enabled(dwc2)) {
dma_setup_prepare(rhport); dma_setup_prepare(rhport);
} }
}
} }
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) {
@ -681,8 +694,9 @@ static void handle_bus_reset(uint8_t rhport) {
// Disable all IN endpoints // Disable all IN endpoints
for (uint8_t n = 0; n < ep_count; n++) { for (uint8_t n = 0; n < ep_count; n++) {
if (dwc2->epin[n].diepctl & DIEPCTL_EPENA) { dwc2_dep_t* dep = &dwc2->epin[n];
dwc2->epin[n].diepctl |= DIEPCTL_SNAK | DIEPCTL_EPDIS; if (edpt_is_enabled(dep)) {
dep->diepctl |= DIEPCTL_SNAK | DIEPCTL_EPDIS;
} }
} }
@ -807,9 +821,9 @@ static void handle_rxflvl_irq(uint8_t rhport) {
const uint16_t byte_count = grxstsp.byte_count; const uint16_t byte_count = grxstsp.byte_count;
xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT);
if (byte_count) { if (byte_count != 0) {
// Read packet off RxFIFO // Read packet off RxFIFO
if (xfer->ff) { if (xfer->ff != NULL) {
tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void*) (uintptr_t) rx_fifo, byte_count); tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void*) (uintptr_t) rx_fifo, byte_count);
} else { } else {
dfifo_read_packet(dwc2, xfer->buffer, byte_count); dfifo_read_packet(dwc2, xfer->buffer, byte_count);
@ -836,7 +850,7 @@ static void handle_rxflvl_irq(uint8_t rhport) {
// the specified OUT endpoint which will be handled by handle_epout_irq() // the specified OUT endpoint which will be handled by handle_epout_irq()
break; break;
default: break; default: break; // nothing to do
} }
} }
@ -844,7 +858,7 @@ static void handle_epout_slave(uint8_t rhport, uint8_t epnum, dwc2_doepint_t doe
if (doepint_bm.setup_phase_done) { if (doepint_bm.setup_phase_done) {
// Cleanup previous pending EP0 IN transfer if any // Cleanup previous pending EP0 IN transfer if any
dwc2_dep_t* epin0 = &DWC2_REG(rhport)->epin[0]; dwc2_dep_t* epin0 = &DWC2_REG(rhport)->epin[0];
if (epin0->diepctl & DIEPCTL_EPENA) { if (edpt_is_enabled(epin0)) {
edpt_disable(rhport, 0x80, false); edpt_disable(rhport, 0x80, false);
} }
dcd_event_setup_received(rhport, _dcd_usbbuf.setup_packet, true); dcd_event_setup_received(rhport, _dcd_usbbuf.setup_packet, true);
@ -858,7 +872,6 @@ static void handle_epout_slave(uint8_t rhport, uint8_t epnum, dwc2_doepint_t doe
// can is set when GRXSTS_PKTSTS_SETUP_RX is popped therefore they can bet set before/together with setup_phase_done // can is set when GRXSTS_PKTSTS_SETUP_RX is popped therefore they can bet set before/together with setup_phase_done
if (!doepint_bm.status_phase_rx && !doepint_bm.setup_packet_rx) { if (!doepint_bm.status_phase_rx && !doepint_bm.setup_packet_rx) {
xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT);
if ((epnum == 0) && _dcd_data.ep0_pending[TUSB_DIR_OUT]) { if ((epnum == 0) && _dcd_data.ep0_pending[TUSB_DIR_OUT]) {
// EP0 can only handle one packet, Schedule another packet to be received. // EP0 can only handle one packet, Schedule another packet to be received.
edpt_schedule_packets(rhport, epnum, TUSB_DIR_OUT); edpt_schedule_packets(rhport, epnum, TUSB_DIR_OUT);
@ -875,7 +888,7 @@ static void handle_epin_slave(uint8_t rhport, uint8_t epnum, dwc2_diepint_t diep
xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_IN); xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_IN);
if (diepint_bm.xfer_complete) { if (diepint_bm.xfer_complete) {
if ((epnum == 0) && _dcd_data.ep0_pending[TUSB_DIR_IN]) { if ((epnum == 0) && (0 != _dcd_data.ep0_pending[TUSB_DIR_IN])) {
// EP0 can only handle one packet. Schedule another packet to be transmitted. // EP0 can only handle one packet. Schedule another packet to be transmitted.
edpt_schedule_packets(rhport, epnum, TUSB_DIR_IN); edpt_schedule_packets(rhport, epnum, TUSB_DIR_IN);
} else { } else {
@ -886,7 +899,7 @@ static void handle_epin_slave(uint8_t rhport, uint8_t epnum, dwc2_diepint_t diep
// TX FIFO empty bit is read-only. It will only be cleared by hardware when written bytes is more than // TX FIFO empty bit is read-only. It will only be cleared by hardware when written bytes is more than
// - 64 bytes or // - 64 bytes or
// - Half/Empty of TX FIFO size (configured by GAHBCFG.TXFELVL) // - Half/Empty of TX FIFO size (configured by GAHBCFG.TXFELVL)
if (diepint_bm.txfifo_empty && (dwc2->diepempmsk & (1 << epnum))) { if (diepint_bm.txfifo_empty && tu_bit_test(dwc2->diepempmsk, epnum)) {
dwc2_ep_tsize_t tsiz = {.value = epin->tsiz}; dwc2_ep_tsize_t tsiz = {.value = epin->tsiz};
const uint16_t remain_packets = tsiz.packet_count; const uint16_t remain_packets = tsiz.packet_count;
@ -902,7 +915,7 @@ static void handle_epin_slave(uint8_t rhport, uint8_t epnum, dwc2_diepint_t diep
} }
// Push packet to Tx-FIFO // Push packet to Tx-FIFO
if (xfer->ff) { if (xfer->ff != NULL) {
volatile uint32_t* tx_fifo = dwc2->fifo[epnum]; volatile uint32_t* tx_fifo = dwc2->fifo[epnum];
tu_fifo_read_n_const_addr_full_words(xfer->ff, (void*)(uintptr_t)tx_fifo, xact_bytes); tu_fifo_read_n_const_addr_full_words(xfer->ff, (void*)(uintptr_t)tx_fifo, xact_bytes);
} else { } else {
@ -927,7 +940,7 @@ static void handle_epout_dma(uint8_t rhport, uint8_t epnum, dwc2_doepint_t doepi
if (doepint_bm.setup_phase_done) { if (doepint_bm.setup_phase_done) {
// Cleanup previous pending EP0 IN transfer if any // Cleanup previous pending EP0 IN transfer if any
dwc2_dep_t* epin0 = &DWC2_REG(rhport)->epin[0]; dwc2_dep_t* epin0 = &DWC2_REG(rhport)->epin[0];
if (epin0->diepctl & DIEPCTL_EPENA) { if (edpt_is_enabled(epin0)) {
edpt_disable(rhport, 0x80, false); edpt_disable(rhport, 0x80, false);
} }
dma_setup_prepare(rhport); dma_setup_prepare(rhport);
@ -993,7 +1006,7 @@ static void handle_ep_irq(uint8_t rhport, uint8_t dir) {
// DAINT for a given EP clears when DEPINTx is cleared. // DAINT for a given EP clears when DEPINTx is cleared.
// EPINT will be cleared when DAINT bits are cleared. // EPINT will be cleared when DAINT bits are cleared.
for (uint8_t epnum = 0; epnum < ep_count; epnum++) { for (uint8_t epnum = 0; epnum < ep_count; epnum++) {
if (dwc2->daint & TU_BIT(daint_offset + epnum)) { if (tu_bit_test(dwc2->daint,daint_offset + epnum)) {
dwc2_dep_t* epout = &ep_base[epnum]; dwc2_dep_t* epout = &ep_base[epnum];
union { union {
uint32_t value; uint32_t value;
@ -1002,7 +1015,7 @@ static void handle_ep_irq(uint8_t rhport, uint8_t dir) {
} intr; } intr;
intr.value = epout->intr; intr.value = epout->intr;
epout->intr = intr.value; // Clear interrupt epout->intr = intr.value; // Clear interrupt //-V::2584::{otg_int}
if (is_dma) { if (is_dma) {
#if CFG_TUD_DWC2_DMA_ENABLE #if CFG_TUD_DWC2_DMA_ENABLE
@ -1037,6 +1050,7 @@ static void handle_ep_irq(uint8_t rhport, uint8_t dir) {
Note: when OTG_MULTI_PROC_INTRPT = 1, Device Each endpoint interrupt deachint/deachmsk/diepeachmsk/doepeachmsk Note: when OTG_MULTI_PROC_INTRPT = 1, Device Each endpoint interrupt deachint/deachmsk/diepeachmsk/doepeachmsk
are combined to generate dedicated interrupt line for each endpoint. are combined to generate dedicated interrupt line for each endpoint.
*/ */
//-V::2584::{gintsts} PVS-Studio suppression
void dcd_int_handler(uint8_t rhport) { void dcd_int_handler(uint8_t rhport) {
dwc2_regs_t* dwc2 = DWC2_REG(rhport); dwc2_regs_t* dwc2 = DWC2_REG(rhport);
const uint32_t gintmask = dwc2->gintmsk; const uint32_t gintmask = dwc2->gintmsk;

View File

@ -176,7 +176,9 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_int_set(uint8_t rhport, tusb_role_
TU_ATTR_ALWAYS_INLINE static inline void dwc2_remote_wakeup_delay(void) { TU_ATTR_ALWAYS_INLINE static inline void dwc2_remote_wakeup_delay(void) {
// try to delay for 1 ms // try to delay for 1 ms
uint32_t count = SystemCoreClock / 1000; uint32_t count = SystemCoreClock / 1000;
while (count--) __NOP(); while (count--) {
__NOP();
}
} }
// MCU specific PHY init, called BEFORE core reset // MCU specific PHY init, called BEFORE core reset

View File

@ -1435,7 +1435,7 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size");
#define DAINTMSK_OEPM_Msk (0xFFFFUL << DAINTMSK_OEPM_Pos) // 0xFFFF0000 #define DAINTMSK_OEPM_Msk (0xFFFFUL << DAINTMSK_OEPM_Pos) // 0xFFFF0000
#define DAINTMSK_OEPM DAINTMSK_OEPM_Msk // OUT EP interrupt mask bits #define DAINTMSK_OEPM DAINTMSK_OEPM_Msk // OUT EP interrupt mask bits
#define DAINT_SHIFT(_dir) ((_dir == TUSB_DIR_IN) ? 0 : 16) #define DAINT_SHIFT(_dir) (((_dir) == TUSB_DIR_IN) ? 0 : 16)
#if 0 #if 0
/******************** Bit definition for OTG register ********************/ /******************** Bit definition for OTG register ********************/