mirror of
https://github.com/hathach/tinyusb.git
synced 2025-12-01 12:24:17 +00:00
Fixed more alert found by PVS-Studio
This commit is contained in:
@ -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"
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
@ -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"
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -23,8 +23,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _USB_DESCRIPTORS_H_
|
#ifndef USB_DESCRIPTORS_H_
|
||||||
#define _USB_DESCRIPTORS_H_
|
#define USB_DESCRIPTORS_H_
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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++;
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -192,10 +192,10 @@ typedef enum {
|
|||||||
CDC_LINE_CODING_STOP_BITS_2 = 2, // 2 bits
|
CDC_LINE_CODING_STOP_BITS_2 = 2, // 2 bits
|
||||||
} 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)
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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, \
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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) {
|
||||||
|
|||||||
@ -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)
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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,17 +871,17 @@ 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
|
||||||
_usbd_dev.remote_wakeup_en = true;
|
_usbd_dev.remote_wakeup_en = true;
|
||||||
tud_control_status(rhport, p_request);
|
tud_control_status(rhport, p_request);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if CFG_TUD_TEST_MODE
|
#if CFG_TUD_TEST_MODE
|
||||||
case TUSB_REQ_FEATURE_TEST_MODE: {
|
case TUSB_REQ_FEATURE_TEST_MODE: {
|
||||||
@ -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,13 +905,12 @@ 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
|
||||||
_usbd_dev.remote_wakeup_en = false;
|
_usbd_dev.remote_wakeup_en = false;
|
||||||
tud_control_status(rhport, p_request);
|
tud_control_status(rhport, p_request);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TUSB_REQ_GET_STATUS: {
|
case TUSB_REQ_GET_STATUS: {
|
||||||
// Device status bit mask
|
// Device status bit mask
|
||||||
@ -939,24 +936,24 @@ 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) {
|
// Clear complete callback if driver set since it can also stall the request.
|
||||||
case TUSB_REQ_GET_INTERFACE:
|
usbd_control_set_complete_callback(NULL);
|
||||||
case TUSB_REQ_SET_INTERFACE:
|
|
||||||
// Clear complete callback if driver set since it can also stall the request.
|
|
||||||
usbd_control_set_complete_callback(NULL);
|
|
||||||
|
|
||||||
if (TUSB_REQ_GET_INTERFACE == p_request->bRequest) {
|
switch (p_request->bRequest) { //-V2520
|
||||||
uint8_t alternate = 0;
|
case TUSB_REQ_GET_INTERFACE: {
|
||||||
tud_control_xfer(rhport, p_request, &alternate, 1);
|
uint8_t alternate = 0;
|
||||||
}else {
|
tud_control_xfer(rhport, p_request, &alternate, 1);
|
||||||
tud_control_status(rhport, p_request);
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
case TUSB_REQ_SET_INTERFACE:
|
||||||
|
tud_control_status(rhport, p_request);
|
||||||
|
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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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,8 +652,12 @@ 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)) {
|
|
||||||
dma_setup_prepare(rhport);
|
// For control endpoint, prepare to receive SETUP packet
|
||||||
|
if (tu_edpt_number(ep_addr) == 0) {
|
||||||
|
if (dma_device_enabled(dwc2)) {
|
||||||
|
dma_setup_prepare(rhport);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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;
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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 ********************/
|
||||||
|
|||||||
Reference in New Issue
Block a user