Merge branch 'master' into pr2091
This commit is contained in:
@@ -64,6 +64,7 @@ function(add_tinyusb TARGET)
|
||||
-Wnull-dereference
|
||||
-Wuninitialized
|
||||
-Wunused
|
||||
-Wunused-function
|
||||
-Wreturn-type
|
||||
-Wredundant-decls
|
||||
)
|
||||
|
||||
@@ -113,21 +113,21 @@
|
||||
// EP IN software buffers and mutexes
|
||||
#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING
|
||||
#if CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ > 0
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_1[CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_1[CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ];
|
||||
#if CFG_FIFO_MUTEX
|
||||
osal_mutex_def_t ep_in_ff_mutex_wr_1; // No need for read mutex as only USB driver reads from FIFO
|
||||
#endif
|
||||
#endif // CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ > 0
|
||||
|
||||
#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ > 0
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_2[CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_2[CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ];
|
||||
#if CFG_FIFO_MUTEX
|
||||
osal_mutex_def_t ep_in_ff_mutex_wr_2; // No need for read mutex as only USB driver reads from FIFO
|
||||
#endif
|
||||
#endif // CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SW_BUF_SZ > 0
|
||||
|
||||
#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ > 0
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_3[CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_in_sw_buf_3[CFG_TUD_AUDIO_FUNC_3_EP_IN_SW_BUF_SZ];
|
||||
#if CFG_FIFO_MUTEX
|
||||
osal_mutex_def_t ep_in_ff_mutex_wr_3; // No need for read mutex as only USB driver reads from FIFO
|
||||
#endif
|
||||
@@ -139,36 +139,36 @@
|
||||
// - the software encoding is used - in this case the linear buffers serve as a target memory where logical channels are encoded into
|
||||
#if CFG_TUD_AUDIO_ENABLE_EP_IN && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_ENCODING)
|
||||
#if CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX > 0
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_1[CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_1[CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX];
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX > 0
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_2[CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_2[CFG_TUD_AUDIO_FUNC_2_EP_IN_SZ_MAX];
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX > 0
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_3[CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_in_3[CFG_TUD_AUDIO_FUNC_3_EP_IN_SZ_MAX];
|
||||
#endif
|
||||
#endif // CFG_TUD_AUDIO_ENABLE_EP_IN && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_DECODING)
|
||||
|
||||
// EP OUT software buffers and mutexes
|
||||
#if CFG_TUD_AUDIO_ENABLE_EP_OUT && !CFG_TUD_AUDIO_ENABLE_DECODING
|
||||
#if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ > 0
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_1[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_1[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ];
|
||||
#if CFG_FIFO_MUTEX
|
||||
osal_mutex_def_t ep_out_ff_mutex_rd_1; // No need for write mutex as only USB driver writes into FIFO
|
||||
#endif
|
||||
#endif // CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ > 0
|
||||
|
||||
#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ > 0
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_2[CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_2[CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ];
|
||||
#if CFG_FIFO_MUTEX
|
||||
osal_mutex_def_t ep_out_ff_mutex_rd_2; // No need for write mutex as only USB driver writes into FIFO
|
||||
#endif
|
||||
#endif // CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SW_BUF_SZ > 0
|
||||
|
||||
#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ > 0
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_3[CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t audio_ep_out_sw_buf_3[CFG_TUD_AUDIO_FUNC_3_EP_OUT_SW_BUF_SZ];
|
||||
#if CFG_FIFO_MUTEX
|
||||
osal_mutex_def_t ep_out_ff_mutex_rd_3; // No need for write mutex as only USB driver writes into FIFO
|
||||
#endif
|
||||
@@ -180,27 +180,27 @@
|
||||
// - the software encoding is used - in this case the linear buffers serve as a target memory where logical channels are encoded into
|
||||
#if CFG_TUD_AUDIO_ENABLE_EP_OUT && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_DECODING)
|
||||
#if CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX > 0
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_1[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_1[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX];
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX > 0
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_2[CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_2[CFG_TUD_AUDIO_FUNC_2_EP_OUT_SZ_MAX];
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX > 0
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_3[CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t lin_buf_out_3[CFG_TUD_AUDIO_FUNC_3_EP_OUT_SZ_MAX];
|
||||
#endif
|
||||
#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && (USE_LINEAR_BUFFER || CFG_TUD_AUDIO_ENABLE_DECODING)
|
||||
|
||||
// Control buffers
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_1[CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_1[CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ];
|
||||
|
||||
#if CFG_TUD_AUDIO > 1
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_2[CFG_TUD_AUDIO_FUNC_2_CTRL_BUF_SZ];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_2[CFG_TUD_AUDIO_FUNC_2_CTRL_BUF_SZ];
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_AUDIO > 2
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_3[CFG_TUD_AUDIO_FUNC_3_CTRL_BUF_SZ];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t ctrl_buf_3[CFG_TUD_AUDIO_FUNC_3_CTRL_BUF_SZ];
|
||||
#endif
|
||||
|
||||
// Active alternate setting of interfaces
|
||||
@@ -217,7 +217,7 @@ uint8_t alt_setting_3[CFG_TUD_AUDIO_FUNC_3_N_AS_INT];
|
||||
// Software encoding/decoding support FIFOs
|
||||
#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_ENCODING
|
||||
#if CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ > 0
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_1[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_1[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_TX_SUPP_SW_FIFO_SZ];
|
||||
tu_fifo_t tx_supp_ff_1[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO];
|
||||
#if CFG_FIFO_MUTEX
|
||||
osal_mutex_def_t tx_supp_ff_mutex_wr_1[CFG_TUD_AUDIO_FUNC_1_N_TX_SUPP_SW_FIFO]; // No need for read mutex as only USB driver reads from FIFO
|
||||
@@ -225,7 +225,7 @@ uint8_t alt_setting_3[CFG_TUD_AUDIO_FUNC_3_N_AS_INT];
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_TX_SUPP_SW_FIFO_SZ > 0
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_2[CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_2_TX_SUPP_SW_FIFO_SZ];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_2[CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_2_TX_SUPP_SW_FIFO_SZ];
|
||||
tu_fifo_t tx_supp_ff_2[CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO];
|
||||
#if CFG_FIFO_MUTEX
|
||||
osal_mutex_def_t tx_supp_ff_mutex_wr_2[CFG_TUD_AUDIO_FUNC_2_N_TX_SUPP_SW_FIFO]; // No need for read mutex as only USB driver reads from FIFO
|
||||
@@ -233,7 +233,7 @@ uint8_t alt_setting_3[CFG_TUD_AUDIO_FUNC_3_N_AS_INT];
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_TX_SUPP_SW_FIFO_SZ > 0
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_3[CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_3_TX_SUPP_SW_FIFO_SZ];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t tx_supp_ff_buf_3[CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_3_TX_SUPP_SW_FIFO_SZ];
|
||||
tu_fifo_t tx_supp_ff_3[CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO];
|
||||
#if CFG_FIFO_MUTEX
|
||||
osal_mutex_def_t tx_supp_ff_mutex_wr_3[CFG_TUD_AUDIO_FUNC_3_N_TX_SUPP_SW_FIFO]; // No need for read mutex as only USB driver reads from FIFO
|
||||
@@ -243,7 +243,7 @@ uint8_t alt_setting_3[CFG_TUD_AUDIO_FUNC_3_N_AS_INT];
|
||||
|
||||
#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_DECODING
|
||||
#if CFG_TUD_AUDIO_FUNC_1_RX_SUPP_SW_FIFO_SZ > 0
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_1[CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_RX_SUPP_SW_FIFO_SZ];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_1[CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_1_RX_SUPP_SW_FIFO_SZ];
|
||||
tu_fifo_t rx_supp_ff_1[CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO];
|
||||
#if CFG_FIFO_MUTEX
|
||||
osal_mutex_def_t rx_supp_ff_mutex_rd_1[CFG_TUD_AUDIO_FUNC_1_N_RX_SUPP_SW_FIFO]; // No need for write mutex as only USB driver writes into FIFO
|
||||
@@ -251,7 +251,7 @@ uint8_t alt_setting_3[CFG_TUD_AUDIO_FUNC_3_N_AS_INT];
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_AUDIO > 1 && CFG_TUD_AUDIO_FUNC_2_RX_SUPP_SW_FIFO_SZ > 0
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_2[CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_2_RX_SUPP_SW_FIFO_SZ];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_2[CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_2_RX_SUPP_SW_FIFO_SZ];
|
||||
tu_fifo_t rx_supp_ff_2[CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO];
|
||||
#if CFG_FIFO_MUTEX
|
||||
osal_mutex_def_t rx_supp_ff_mutex_rd_2[CFG_TUD_AUDIO_FUNC_2_N_RX_SUPP_SW_FIFO]; // No need for write mutex as only USB driver writes into FIFO
|
||||
@@ -259,7 +259,7 @@ uint8_t alt_setting_3[CFG_TUD_AUDIO_FUNC_3_N_AS_INT];
|
||||
#endif
|
||||
|
||||
#if CFG_TUD_AUDIO > 2 && CFG_TUD_AUDIO_FUNC_3_RX_SUPP_SW_FIFO_SZ > 0
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_3_RX_SUPP_SW_FIFO_SZ];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN uint8_t rx_supp_ff_buf_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO][CFG_TUD_AUDIO_FUNC_3_RX_SUPP_SW_FIFO_SZ];
|
||||
tu_fifo_t rx_supp_ff_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO];
|
||||
#if CFG_FIFO_MUTEX
|
||||
osal_mutex_def_t rx_supp_ff_mutex_rd_3[CFG_TUD_AUDIO_FUNC_3_N_RX_SUPP_SW_FIFO]; // No need for write mutex as only USB driver writes into FIFO
|
||||
@@ -416,7 +416,7 @@ typedef struct
|
||||
//--------------------------------------------------------------------+
|
||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
CFG_TUSB_MEM_SECTION audiod_function_t _audiod_fct[CFG_TUD_AUDIO];
|
||||
CFG_TUD_MEM_SECTION audiod_function_t _audiod_fct[CFG_TUD_AUDIO];
|
||||
|
||||
#if CFG_TUD_AUDIO_ENABLE_EP_OUT
|
||||
static bool audiod_rx_done_cb(uint8_t rhport, audiod_function_t* audio, uint16_t n_bytes_received);
|
||||
|
||||
@@ -55,7 +55,7 @@ typedef struct
|
||||
//--------------------------------------------------------------------+
|
||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
CFG_TUSB_MEM_SECTION btd_interface_t _btd_itf;
|
||||
CFG_TUD_MEM_SECTION btd_interface_t _btd_itf;
|
||||
|
||||
static bool bt_tx_data(uint8_t ep, void *data, uint16_t len)
|
||||
{
|
||||
|
||||
@@ -33,6 +33,13 @@
|
||||
|
||||
#include "cdc_device.h"
|
||||
|
||||
// Level where CFG_TUSB_DEBUG must be at least for this driver is logged
|
||||
#ifndef CFG_TUD_CDC_LOG_LEVEL
|
||||
#define CFG_TUD_CDC_LOG_LEVEL CFG_TUD_LOG_LEVEL
|
||||
#endif
|
||||
|
||||
#define TU_LOG_DRV(...) TU_LOG(CFG_TUD_CDC_LOG_LEVEL, __VA_ARGS__)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO CONSTANT TYPEDEF
|
||||
//--------------------------------------------------------------------+
|
||||
@@ -76,7 +83,7 @@ typedef struct
|
||||
//--------------------------------------------------------------------+
|
||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
CFG_TUSB_MEM_SECTION tu_static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC];
|
||||
CFG_TUD_MEM_SECTION tu_static cdcd_interface_t _cdcd_itf[CFG_TUD_CDC];
|
||||
|
||||
static bool _prep_out_transaction (cdcd_interface_t* p_cdc)
|
||||
{
|
||||
@@ -353,7 +360,7 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t
|
||||
case CDC_REQUEST_SET_LINE_CODING:
|
||||
if (stage == CONTROL_STAGE_SETUP)
|
||||
{
|
||||
TU_LOG2(" Set Line Coding\r\n");
|
||||
TU_LOG_DRV(" Set Line Coding\r\n");
|
||||
tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t));
|
||||
}
|
||||
else if ( stage == CONTROL_STAGE_ACK)
|
||||
@@ -365,7 +372,7 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t
|
||||
case CDC_REQUEST_GET_LINE_CODING:
|
||||
if (stage == CONTROL_STAGE_SETUP)
|
||||
{
|
||||
TU_LOG2(" Get Line Coding\r\n");
|
||||
TU_LOG_DRV(" Get Line Coding\r\n");
|
||||
tud_control_xfer(rhport, request, &p_cdc->line_coding, sizeof(cdc_line_coding_t));
|
||||
}
|
||||
break;
|
||||
@@ -390,7 +397,7 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t
|
||||
// Disable fifo overwriting if DTR bit is set
|
||||
tu_fifo_set_overwritable(&p_cdc->tx_ff, !dtr);
|
||||
|
||||
TU_LOG2(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts);
|
||||
TU_LOG_DRV(" Set Control Line State: DTR = %d, RTS = %d\r\n", dtr, rts);
|
||||
|
||||
// Invoke callback
|
||||
if ( tud_cdc_line_state_cb ) tud_cdc_line_state_cb(itf, dtr, rts);
|
||||
@@ -403,7 +410,7 @@ bool cdcd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t
|
||||
}
|
||||
else if (stage == CONTROL_STAGE_ACK)
|
||||
{
|
||||
TU_LOG2(" Send Break\r\n");
|
||||
TU_LOG_DRV(" Send Break\r\n");
|
||||
if ( tud_cdc_send_break_cb ) tud_cdc_send_break_cb(itf, request->wValue);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -33,9 +33,12 @@
|
||||
|
||||
#include "cdc_host.h"
|
||||
|
||||
// Debug level, TUSB_CFG_DEBUG must be at least this level for debug message
|
||||
#define CDCH_DEBUG 2
|
||||
#define TU_LOG_DRV(...) TU_LOG(CDCH_DEBUG, __VA_ARGS__)
|
||||
// Level where CFG_TUSB_DEBUG must be at least for this driver is logged
|
||||
#ifndef CFG_TUH_CDC_LOG_LEVEL
|
||||
#define CFG_TUH_CDC_LOG_LEVEL CFG_TUH_LOG_LEVEL
|
||||
#endif
|
||||
|
||||
#define TU_LOG_DRV(...) TU_LOG(CFG_TUH_CDC_LOG_LEVEL, __VA_ARGS__)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Host CDC Interface
|
||||
|
||||
@@ -37,6 +37,13 @@
|
||||
// MACRO CONSTANT TYPEDEF
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Level where CFG_TUSB_DEBUG must be at least for this driver is logged
|
||||
#ifndef CFG_TUD_DFU_LOG_LEVEL
|
||||
#define CFG_TUD_DFU_LOG_LEVEL CFG_TUD_LOG_LEVEL
|
||||
#endif
|
||||
|
||||
#define TU_LOG_DRV(...) TU_LOG(CFG_TUD_DFU_LOG_LEVEL, __VA_ARGS__)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
@@ -56,7 +63,7 @@ typedef struct
|
||||
} dfu_state_ctx_t;
|
||||
|
||||
// Only a single dfu state is allowed
|
||||
CFG_TUSB_MEM_SECTION tu_static dfu_state_ctx_t _dfu_ctx;
|
||||
CFG_TUD_MEM_SECTION tu_static dfu_state_ctx_t _dfu_ctx;
|
||||
|
||||
static void reset_state(void)
|
||||
{
|
||||
@@ -205,7 +212,7 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque
|
||||
{
|
||||
TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE);
|
||||
|
||||
TU_LOG2(" DFU State : %s, Status: %s\r\n", tu_lookup_find(&_dfu_state_table, _dfu_ctx.state), tu_lookup_find(&_dfu_status_table, _dfu_ctx.status));
|
||||
TU_LOG_DRV(" DFU State : %s, Status: %s\r\n", tu_lookup_find(&_dfu_state_table, _dfu_ctx.state), tu_lookup_find(&_dfu_status_table, _dfu_ctx.status));
|
||||
|
||||
if ( request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD )
|
||||
{
|
||||
@@ -235,7 +242,7 @@ bool dfu_moded_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_reque
|
||||
}
|
||||
else if ( request->bmRequestType_bit.type == TUSB_REQ_TYPE_CLASS )
|
||||
{
|
||||
TU_LOG2(" DFU Request: %s\r\n", tu_lookup_find(&_dfu_request_table, request->bRequest));
|
||||
TU_LOG_DRV(" DFU Request: %s\r\n", tu_lookup_find(&_dfu_request_table, request->bRequest));
|
||||
|
||||
// Class request
|
||||
switch ( request->bRequest )
|
||||
|
||||
@@ -37,6 +37,13 @@
|
||||
// MACRO CONSTANT TYPEDEF
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Level where CFG_TUSB_DEBUG must be at least for this driver is logged
|
||||
#ifndef CFG_TUD_DFU_RUNTIME_LOG_LEVEL
|
||||
#define CFG_TUD_DFU_RUNTIME_LOG_LEVEL CFG_TUD_LOG_LEVEL
|
||||
#endif
|
||||
|
||||
#define TU_LOG_DRV(...) TU_LOG(CFG_TUD_DFU_RUNTIME_LOG_LEVEL, __VA_ARGS__)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
@@ -99,7 +106,7 @@ bool dfu_rtd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request
|
||||
{
|
||||
case DFU_REQUEST_DETACH:
|
||||
{
|
||||
TU_LOG2(" DFU RT Request: DETACH\r\n");
|
||||
TU_LOG_DRV(" DFU RT Request: DETACH\r\n");
|
||||
tud_control_status(rhport, request);
|
||||
tud_dfu_runtime_reboot_to_dfu_cb();
|
||||
}
|
||||
@@ -107,7 +114,7 @@ bool dfu_rtd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request
|
||||
|
||||
case DFU_REQUEST_GETSTATUS:
|
||||
{
|
||||
TU_LOG2(" DFU RT Request: GETSTATUS\r\n");
|
||||
TU_LOG_DRV(" DFU RT Request: GETSTATUS\r\n");
|
||||
dfu_status_response_t resp;
|
||||
// Status = OK, Poll timeout is ignored during RT, State = APP_IDLE, IString = 0
|
||||
TU_VERIFY(tu_memset_s(&resp, sizeof(resp), 0x00, sizeof(resp))==0);
|
||||
@@ -117,7 +124,7 @@ bool dfu_rtd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request
|
||||
|
||||
default:
|
||||
{
|
||||
TU_LOG2(" DFU RT Unexpected Request: %d\r\n", request->bRequest);
|
||||
TU_LOG_DRV(" DFU RT Unexpected Request: %d\r\n", request->bRequest);
|
||||
return false; // stall unsupported request
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ typedef struct
|
||||
tusb_hid_descriptor_hid_t const * hid_descriptor;
|
||||
} hidd_interface_t;
|
||||
|
||||
CFG_TUSB_MEM_SECTION tu_static hidd_interface_t _hidd_itf[CFG_TUD_HID];
|
||||
CFG_TUD_MEM_SECTION tu_static hidd_interface_t _hidd_itf[CFG_TUD_HID];
|
||||
|
||||
/*------------- Helpers -------------*/
|
||||
static inline uint8_t get_index_by_itfnum(uint8_t itf_num)
|
||||
|
||||
@@ -33,10 +33,12 @@
|
||||
|
||||
#include "hid_host.h"
|
||||
|
||||
// Debug level, TUSB_CFG_DEBUG must be at least this level for debug message
|
||||
#define HIDH_DEBUG 2
|
||||
#define TU_LOG_DRV(...) TU_LOG(HIDH_DEBUG, __VA_ARGS__)
|
||||
// Level where CFG_TUSB_DEBUG must be at least for this driver is logged
|
||||
#ifndef CFG_TUH_HID_LOG_LEVEL
|
||||
#define CFG_TUH_HID_LOG_LEVEL CFG_TUH_LOG_LEVEL
|
||||
#endif
|
||||
|
||||
#define TU_LOG_DRV(...) TU_LOG(CFG_TUH_HID_LOG_LEVEL, __VA_ARGS__)
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO CONSTANT TYPEDEF
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
@@ -82,7 +82,7 @@ typedef struct
|
||||
//--------------------------------------------------------------------+
|
||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
CFG_TUSB_MEM_SECTION midid_interface_t _midid_itf[CFG_TUD_MIDI];
|
||||
CFG_TUD_MEM_SECTION midid_interface_t _midid_itf[CFG_TUD_MIDI];
|
||||
|
||||
bool tud_midi_n_mounted (uint8_t itf)
|
||||
{
|
||||
|
||||
@@ -53,7 +53,7 @@ enum {
|
||||
};
|
||||
|
||||
/// \brief MassStorage Protocol.
|
||||
/// \details CBI only approved to use with full-speed floopy disk & should not used with highspeed or device other than floopy
|
||||
/// \details CBI only approved to use with full-speed floppy disk & should not used with highspeed or device other than floppy
|
||||
typedef enum
|
||||
{
|
||||
MSC_PROTOCOL_CBI = 0 , ///< Control/Bulk/Interrupt protocol (with command completion interrupt)
|
||||
@@ -97,7 +97,7 @@ typedef struct TU_ATTR_PACKED
|
||||
{
|
||||
uint32_t signature ; ///< Signature that helps identify this data packet as a CSW. The signature field shall contain the value 53425355h (little endian), indicating CSW.
|
||||
uint32_t tag ; ///< The device shall set this field to the value received in the dCBWTag of the associated CBW.
|
||||
uint32_t data_residue ; ///< For Data-Out the device shall report in the dCSWDataResiduethe difference between the amount of data expected as stated in the dCBWDataTransferLength, and the actual amount of data processed by the device. For Data-In the device shall report in the dCSWDataResiduethe difference between the amount of data expected as stated in the dCBWDataTransferLengthand the actual amount of relevant data sent by the device
|
||||
uint32_t data_residue ; ///< For Data-Out the device shall report in the dCSWDataResidue the difference between the amount of data expected as stated in the dCBWDataTransferLength, and the actual amount of data processed by the device. For Data-In the device shall report in the dCSWDataResiduethe difference between the amount of data expected as stated in the dCBWDataTransferLengthand the actual amount of relevant data sent by the device
|
||||
uint8_t status ; ///< indicates the success or failure of the command. Values from \ref msc_csw_status_t
|
||||
}msc_csw_t;
|
||||
|
||||
@@ -120,14 +120,14 @@ typedef enum
|
||||
SCSI_CMD_REQUEST_SENSE = 0x03, ///< The SCSI Request Sense command is part of the SCSI computer protocol standard. This command is used to obtain sense data -- status/error information -- from a target device.
|
||||
SCSI_CMD_READ_FORMAT_CAPACITY = 0x23, ///< The command allows the Host to request a list of the possible format capacities for an installed writable media. This command also has the capability to report the writable capacity for a media when it is installed
|
||||
SCSI_CMD_READ_10 = 0x28, ///< The READ (10) command requests that the device server read the specified logical block(s) and transfer them to the data-in buffer.
|
||||
SCSI_CMD_WRITE_10 = 0x2A, ///< The WRITE (10) command requests thatthe device server transfer the specified logical block(s) from the data-out buffer and write them.
|
||||
SCSI_CMD_WRITE_10 = 0x2A, ///< The WRITE (10) command requests that the device server transfer the specified logical block(s) from the data-out buffer and write them.
|
||||
}scsi_cmd_type_t;
|
||||
|
||||
/// SCSI Sense Key
|
||||
typedef enum
|
||||
{
|
||||
SCSI_SENSE_NONE = 0x00, ///< no specific Sense Key. This would be the case for a successful command
|
||||
SCSI_SENSE_RECOVERED_ERROR = 0x01, ///< ndicates the last command completed successfully with some recovery action performed by the disc drive.
|
||||
SCSI_SENSE_RECOVERED_ERROR = 0x01, ///< Indicates the last command completed successfully with some recovery action performed by the disc drive.
|
||||
SCSI_SENSE_NOT_READY = 0x02, ///< Indicates the logical unit addressed cannot be accessed.
|
||||
SCSI_SENSE_MEDIUM_ERROR = 0x03, ///< Indicates the command terminated with a non-recovered error condition.
|
||||
SCSI_SENSE_HARDWARE_ERROR = 0x04, ///< Indicates the disc drive detected a nonrecoverable hardware failure while performing the command or during a self test.
|
||||
@@ -138,7 +138,7 @@ typedef enum
|
||||
SCSI_SENSE_ABORTED_COMMAND = 0x0b, ///< Indicates the disc drive aborted the command.
|
||||
SCSI_SENSE_EQUAL = 0x0c, ///< Indicates a SEARCH DATA command has satisfied an equal comparison.
|
||||
SCSI_SENSE_VOLUME_OVERFLOW = 0x0d, ///< Indicates a buffered peripheral device has reached the end of medium partition and data remains in the buffer that has not been written to the medium.
|
||||
SCSI_SENSE_MISCOMPARE = 0x0e ///< ndicates that the source data did not match the data read from the medium.
|
||||
SCSI_SENSE_MISCOMPARE = 0x0e ///< Indicates that the source data did not match the data read from the medium.
|
||||
}scsi_sense_key_type_t;
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
@@ -34,13 +34,16 @@
|
||||
|
||||
#include "msc_device.h"
|
||||
|
||||
// Level where CFG_TUSB_DEBUG must be at least for this driver is logged
|
||||
#ifndef CFG_TUD_MSC_LOG_LEVEL
|
||||
#define CFG_TUD_MSC_LOG_LEVEL CFG_TUD_LOG_LEVEL
|
||||
#endif
|
||||
|
||||
#define TU_LOG_DRV(...) TU_LOG(CFG_TUD_MSC_LOG_LEVEL, __VA_ARGS__)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO CONSTANT TYPEDEF
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Can be selectively disabled to reduce logging when troubleshooting other driver
|
||||
#define MSC_DEBUG 2
|
||||
|
||||
enum
|
||||
{
|
||||
MSC_STAGE_CMD = 0,
|
||||
@@ -71,8 +74,8 @@ typedef struct
|
||||
uint8_t add_sense_qualifier;
|
||||
}mscd_interface_t;
|
||||
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static mscd_interface_t _mscd_itf;
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static uint8_t _mscd_buf[CFG_TUD_MSC_EP_BUFSIZE];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static mscd_interface_t _mscd_itf;
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static uint8_t _mscd_buf[CFG_TUD_MSC_EP_BUFSIZE];
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||
@@ -164,7 +167,7 @@ uint8_t rdwr10_validate_cmd(msc_cbw_t const* cbw)
|
||||
{
|
||||
if ( block_count )
|
||||
{
|
||||
TU_LOG(MSC_DEBUG, " SCSI case 2 (Hn < Di) or case 3 (Hn < Do) \r\n");
|
||||
TU_LOG_DRV(" SCSI case 2 (Hn < Di) or case 3 (Hn < Do) \r\n");
|
||||
status = MSC_CSW_STATUS_PHASE_ERROR;
|
||||
}else
|
||||
{
|
||||
@@ -174,22 +177,22 @@ uint8_t rdwr10_validate_cmd(msc_cbw_t const* cbw)
|
||||
{
|
||||
if ( SCSI_CMD_READ_10 == cbw->command[0] && !is_data_in(cbw->dir) )
|
||||
{
|
||||
TU_LOG(MSC_DEBUG, " SCSI case 10 (Ho <> Di)\r\n");
|
||||
TU_LOG_DRV(" SCSI case 10 (Ho <> Di)\r\n");
|
||||
status = MSC_CSW_STATUS_PHASE_ERROR;
|
||||
}
|
||||
else if ( SCSI_CMD_WRITE_10 == cbw->command[0] && is_data_in(cbw->dir) )
|
||||
{
|
||||
TU_LOG(MSC_DEBUG, " SCSI case 8 (Hi <> Do)\r\n");
|
||||
TU_LOG_DRV(" SCSI case 8 (Hi <> Do)\r\n");
|
||||
status = MSC_CSW_STATUS_PHASE_ERROR;
|
||||
}
|
||||
else if ( 0 == block_count )
|
||||
{
|
||||
TU_LOG(MSC_DEBUG, " SCSI case 4 Hi > Dn (READ10) or case 9 Ho > Dn (WRITE10) \r\n");
|
||||
TU_LOG_DRV(" SCSI case 4 Hi > Dn (READ10) or case 9 Ho > Dn (WRITE10) \r\n");
|
||||
status = MSC_CSW_STATUS_FAILED;
|
||||
}
|
||||
else if ( cbw->total_bytes / block_count == 0 )
|
||||
{
|
||||
TU_LOG(MSC_DEBUG, " Computed block size = 0. SCSI case 7 Hi < Di (READ10) or case 13 Ho < Do (WRIT10)\r\n");
|
||||
TU_LOG_DRV(" Computed block size = 0. SCSI case 7 Hi < Di (READ10) or case 13 Ho < Do (WRIT10)\r\n");
|
||||
status = MSC_CSW_STATUS_PHASE_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -352,7 +355,7 @@ bool mscd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t
|
||||
switch ( request->bRequest )
|
||||
{
|
||||
case MSC_REQ_RESET:
|
||||
TU_LOG(MSC_DEBUG, " MSC BOT Reset\r\n");
|
||||
TU_LOG_DRV(" MSC BOT Reset\r\n");
|
||||
TU_VERIFY(request->wValue == 0 && request->wLength == 0);
|
||||
|
||||
// driver state reset
|
||||
@@ -363,7 +366,7 @@ bool mscd_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t
|
||||
|
||||
case MSC_REQ_GET_MAX_LUN:
|
||||
{
|
||||
TU_LOG(MSC_DEBUG, " MSC Get Max Lun\r\n");
|
||||
TU_LOG_DRV(" MSC Get Max Lun\r\n");
|
||||
TU_VERIFY(request->wValue == 0 && request->wLength == 1);
|
||||
|
||||
uint8_t maxlun = 1;
|
||||
@@ -400,7 +403,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
|
||||
|
||||
if ( !(xferred_bytes == sizeof(msc_cbw_t) && p_cbw->signature == MSC_CBW_SIGNATURE) )
|
||||
{
|
||||
TU_LOG(MSC_DEBUG, " SCSI CBW is not valid\r\n");
|
||||
TU_LOG_DRV(" SCSI CBW is not valid\r\n");
|
||||
|
||||
// BOT 6.6.1 If CBW is not valid stall both endpoints until reset recovery
|
||||
p_msc->stage = MSC_STAGE_NEED_RESET;
|
||||
@@ -412,7 +415,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
|
||||
return false;
|
||||
}
|
||||
|
||||
TU_LOG(MSC_DEBUG, " SCSI Command [Lun%u]: %s\r\n", p_cbw->lun, tu_lookup_find(&_msc_scsi_cmd_table, p_cbw->command[0]));
|
||||
TU_LOG_DRV(" SCSI Command [Lun%u]: %s\r\n", p_cbw->lun, tu_lookup_find(&_msc_scsi_cmd_table, p_cbw->command[0]));
|
||||
//TU_LOG_MEM(MSC_DEBUG, p_cbw, xferred_bytes, 2);
|
||||
|
||||
p_csw->signature = MSC_CSW_SIGNATURE;
|
||||
@@ -457,7 +460,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
|
||||
{
|
||||
if (p_cbw->total_bytes > sizeof(_mscd_buf))
|
||||
{
|
||||
TU_LOG(MSC_DEBUG, " SCSI reject non READ10/WRITE10 with large data\r\n");
|
||||
TU_LOG_DRV(" SCSI reject non READ10/WRITE10 with large data\r\n");
|
||||
fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED);
|
||||
}else
|
||||
{
|
||||
@@ -479,7 +482,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
|
||||
if ( resplen < 0 )
|
||||
{
|
||||
// unsupported command
|
||||
TU_LOG(MSC_DEBUG, " SCSI unsupported or failed command\r\n");
|
||||
TU_LOG_DRV(" SCSI unsupported or failed command\r\n");
|
||||
fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED);
|
||||
}
|
||||
else if (resplen == 0)
|
||||
@@ -514,7 +517,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
|
||||
break;
|
||||
|
||||
case MSC_STAGE_DATA:
|
||||
TU_LOG(MSC_DEBUG, " SCSI Data [Lun%u]\r\n", p_cbw->lun);
|
||||
TU_LOG_DRV(" SCSI Data [Lun%u]\r\n", p_cbw->lun);
|
||||
//TU_LOG_MEM(MSC_DEBUG, _mscd_buf, xferred_bytes, 2);
|
||||
|
||||
if (SCSI_CMD_READ_10 == p_cbw->command[0])
|
||||
@@ -546,7 +549,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
|
||||
if ( cb_result < 0 )
|
||||
{
|
||||
// unsupported command
|
||||
TU_LOG(MSC_DEBUG, " SCSI unsupported command\r\n");
|
||||
TU_LOG_DRV(" SCSI unsupported command\r\n");
|
||||
fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED);
|
||||
}else
|
||||
{
|
||||
@@ -575,7 +578,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
|
||||
// Wait for the Status phase to complete
|
||||
if( (ep_addr == p_msc->ep_in) && (xferred_bytes == sizeof(msc_csw_t)) )
|
||||
{
|
||||
TU_LOG(MSC_DEBUG, " SCSI Status [Lun%u] = %u\r\n", p_cbw->lun, p_csw->status);
|
||||
TU_LOG_DRV(" SCSI Status [Lun%u] = %u\r\n", p_cbw->lun, p_csw->status);
|
||||
// TU_LOG_MEM(MSC_DEBUG, p_csw, xferred_bytes, 2);
|
||||
|
||||
// Invoke complete callback if defined
|
||||
@@ -845,7 +848,7 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc)
|
||||
if ( nbytes < 0 )
|
||||
{
|
||||
// negative means error -> endpoint is stalled & status in CSW set to failed
|
||||
TU_LOG(MSC_DEBUG, " tud_msc_read10_cb() return -1\r\n");
|
||||
TU_LOG_DRV(" tud_msc_read10_cb() return -1\r\n");
|
||||
|
||||
// set sense
|
||||
set_sense_medium_not_present(p_cbw->lun);
|
||||
@@ -907,7 +910,7 @@ static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint3
|
||||
if ( nbytes < 0 )
|
||||
{
|
||||
// negative means error -> failed this scsi op
|
||||
TU_LOG(MSC_DEBUG, " tud_msc_write10_cb() return -1\r\n");
|
||||
TU_LOG_DRV(" tud_msc_write10_cb() return -1\r\n");
|
||||
|
||||
// update actual byte before failed
|
||||
p_msc->xferred_len += xferred_bytes;
|
||||
|
||||
@@ -33,9 +33,12 @@
|
||||
|
||||
#include "msc_host.h"
|
||||
|
||||
// Debug level, TUSB_CFG_DEBUG must be at least this level for debug message
|
||||
#define MSCH_DEBUG 2
|
||||
#define TU_LOG_MSCH(...) TU_LOG(MSCH_DEBUG, __VA_ARGS__)
|
||||
// Level where CFG_TUSB_DEBUG must be at least for this driver is logged
|
||||
#ifndef CFG_TUH_MSC_LOG_LEVEL
|
||||
#define CFG_TUH_MSC_LOG_LEVEL CFG_TUH_LOG_LEVEL
|
||||
#endif
|
||||
|
||||
#define TU_LOG_DRV(...) TU_LOG(CFG_TUH_MSC_LOG_LEVEL, __VA_ARGS__)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO CONSTANT TYPEDEF
|
||||
@@ -308,7 +311,7 @@ void msch_close(uint8_t dev_addr)
|
||||
msch_interface_t* p_msc = get_itf(dev_addr);
|
||||
TU_VERIFY(p_msc->configured, );
|
||||
|
||||
TU_LOG_MSCH(" MSCh close addr = %d\r\n", dev_addr);
|
||||
TU_LOG_DRV(" MSCh close addr = %d\r\n", dev_addr);
|
||||
|
||||
// invoke Application Callback
|
||||
if (p_msc->mounted) {
|
||||
@@ -426,7 +429,7 @@ bool msch_set_config(uint8_t dev_addr, uint8_t itf_num)
|
||||
p_msc->configured = true;
|
||||
|
||||
//------------- Get Max Lun -------------//
|
||||
TU_LOG_MSCH("MSC Get Max Lun\r\n");
|
||||
TU_LOG_DRV("MSC Get Max Lun\r\n");
|
||||
tusb_control_request_t const request =
|
||||
{
|
||||
.bmRequestType_bit =
|
||||
@@ -465,7 +468,7 @@ static void config_get_maxlun_complete (tuh_xfer_t* xfer)
|
||||
p_msc->max_lun++; // MAX LUN is minus 1 by specs
|
||||
|
||||
// TODO multiple LUN support
|
||||
TU_LOG_MSCH("SCSI Test Unit Ready\r\n");
|
||||
TU_LOG_DRV("SCSI Test Unit Ready\r\n");
|
||||
uint8_t const lun = 0;
|
||||
tuh_msc_test_unit_ready(daddr, lun, config_test_unit_ready_complete, 0);
|
||||
}
|
||||
@@ -478,14 +481,14 @@ static bool config_test_unit_ready_complete(uint8_t dev_addr, tuh_msc_complete_d
|
||||
if (csw->status == 0)
|
||||
{
|
||||
// Unit is ready, read its capacity
|
||||
TU_LOG_MSCH("SCSI Read Capacity\r\n");
|
||||
TU_LOG_DRV("SCSI Read Capacity\r\n");
|
||||
tuh_msc_read_capacity(dev_addr, cbw->lun, (scsi_read_capacity10_resp_t*) ((void*) _msch_buffer), config_read_capacity_complete, 0);
|
||||
}else
|
||||
{
|
||||
// Note: During enumeration, some device fails Test Unit Ready and require a few retries
|
||||
// with Request Sense to start working !!
|
||||
// TODO limit number of retries
|
||||
TU_LOG_MSCH("SCSI Request Sense\r\n");
|
||||
TU_LOG_DRV("SCSI Request Sense\r\n");
|
||||
TU_ASSERT(tuh_msc_request_sense(dev_addr, cbw->lun, _msch_buffer, config_request_sense_complete, 0));
|
||||
}
|
||||
|
||||
|
||||
@@ -61,10 +61,10 @@ typedef struct
|
||||
#define CFG_TUD_NET_PACKET_PREFIX_LEN sizeof(rndis_data_packet_t)
|
||||
#define CFG_TUD_NET_PACKET_SUFFIX_LEN 0
|
||||
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static
|
||||
uint8_t received[CFG_TUD_NET_PACKET_PREFIX_LEN + CFG_TUD_NET_MTU + CFG_TUD_NET_PACKET_PREFIX_LEN];
|
||||
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static
|
||||
uint8_t transmitted[CFG_TUD_NET_PACKET_PREFIX_LEN + CFG_TUD_NET_MTU + CFG_TUD_NET_PACKET_PREFIX_LEN];
|
||||
|
||||
struct ecm_notify_struct
|
||||
@@ -94,8 +94,8 @@ tu_static const struct ecm_notify_struct ecm_notify_csc =
|
||||
.uplink = 9728000,
|
||||
};
|
||||
|
||||
// TODO remove CFG_TUSB_MEM_SECTION, control internal buffer is already in this special section
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static union
|
||||
// TODO remove CFG_TUD_MEM_SECTION, control internal buffer is already in this special section
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static union
|
||||
{
|
||||
uint8_t rndis_buf[120];
|
||||
struct ecm_notify_struct ecm_buf;
|
||||
@@ -104,8 +104,8 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static union
|
||||
//--------------------------------------------------------------------+
|
||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
// TODO remove CFG_TUSB_MEM_SECTION
|
||||
CFG_TUSB_MEM_SECTION tu_static netd_interface_t _netd_itf;
|
||||
// TODO remove CFG_TUD_MEM_SECTION
|
||||
CFG_TUD_MEM_SECTION tu_static netd_interface_t _netd_itf;
|
||||
|
||||
tu_static bool can_xmit;
|
||||
|
||||
|
||||
@@ -34,6 +34,13 @@
|
||||
#include "device/usbd_pvt.h"
|
||||
#include "net_device.h"
|
||||
|
||||
// Level where CFG_TUSB_DEBUG must be at least for this driver is logged
|
||||
#ifndef CFG_TUD_NCM_LOG_LEVEL
|
||||
#define CFG_TUD_NCM_LOG_LEVEL CFG_TUD_LOG_LEVEL
|
||||
#endif
|
||||
|
||||
#define TU_LOG_DRV(...) TU_LOG(CFG_TUD_NCM_LOG_LEVEL, __VA_ARGS__)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO CONSTANT TYPEDEF
|
||||
//--------------------------------------------------------------------+
|
||||
@@ -130,7 +137,7 @@ typedef struct
|
||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_parameters = {
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_parameters = {
|
||||
.wLength = sizeof(ntb_parameters_t),
|
||||
.bmNtbFormatsSupported = 0x01,
|
||||
.dwNtbInMaxSize = CFG_TUD_NCM_IN_NTB_MAX_SIZE,
|
||||
@@ -145,9 +152,9 @@ CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static const ntb_parameters_t ntb_par
|
||||
.wNtbOutMaxDatagrams = 0
|
||||
};
|
||||
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static transmit_ntb_t transmit_ntb[2];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static transmit_ntb_t transmit_ntb[2];
|
||||
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static uint8_t receive_ntb[CFG_TUD_NCM_OUT_NTB_MAX_SIZE];
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static uint8_t receive_ntb[CFG_TUD_NCM_OUT_NTB_MAX_SIZE];
|
||||
|
||||
tu_static ncm_interface_t ncm_interface;
|
||||
|
||||
@@ -473,13 +480,13 @@ bool tud_network_can_xmit(uint16_t size)
|
||||
TU_VERIFY(ncm_interface.itf_data_alt == 1);
|
||||
|
||||
if (ncm_interface.datagram_count >= ncm_interface.max_datagrams_per_ntb) {
|
||||
TU_LOG2("NTB full [by count]\r\n");
|
||||
TU_LOG_DRV("NTB full [by count]\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t next_datagram_offset = ncm_interface.next_datagram_offset;
|
||||
if (next_datagram_offset + size > ncm_interface.ntb_in_size) {
|
||||
TU_LOG2("ntb full [by size]\r\n");
|
||||
TU_LOG_DRV("ntb full [by size]\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ typedef struct
|
||||
usbtmc_capabilities_specific_t const * capabilities;
|
||||
} usbtmc_interface_state_t;
|
||||
|
||||
CFG_TUSB_MEM_SECTION tu_static usbtmc_interface_state_t usbtmc_state =
|
||||
CFG_TUD_MEM_SECTION tu_static usbtmc_interface_state_t usbtmc_state =
|
||||
{
|
||||
.itf_id = 0xFF,
|
||||
};
|
||||
|
||||
2
src/class/vendor/vendor_device.c
vendored
2
src/class/vendor/vendor_device.c
vendored
@@ -59,7 +59,7 @@ typedef struct
|
||||
CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_VENDOR_EPSIZE];
|
||||
} vendord_interface_t;
|
||||
|
||||
CFG_TUSB_MEM_SECTION tu_static vendord_interface_t _vendord_itf[CFG_TUD_VENDOR];
|
||||
CFG_TUD_MEM_SECTION tu_static vendord_interface_t _vendord_itf[CFG_TUD_VENDOR];
|
||||
|
||||
#define ITF_MEM_RESET_SIZE offsetof(vendord_interface_t, rx_ff)
|
||||
|
||||
|
||||
@@ -34,6 +34,13 @@
|
||||
|
||||
#include "video_device.h"
|
||||
|
||||
// Level where CFG_TUSB_DEBUG must be at least for this driver is logged
|
||||
#ifndef CFG_TUD_VIDEO_LOG_LEVEL
|
||||
#define CFG_TUD_VIDEO_LOG_LEVEL CFG_TUD_LOG_LEVEL
|
||||
#endif
|
||||
|
||||
#define TU_LOG_DRV(...) TU_LOG(CFG_TUD_VIDEO_LOG_LEVEL, __VA_ARGS__)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO CONSTANT TYPEDEF
|
||||
//--------------------------------------------------------------------+
|
||||
@@ -130,8 +137,8 @@ typedef struct TU_ATTR_PACKED {
|
||||
//--------------------------------------------------------------------+
|
||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
CFG_TUSB_MEM_SECTION tu_static videod_interface_t _videod_itf[CFG_TUD_VIDEO];
|
||||
CFG_TUSB_MEM_SECTION tu_static videod_streaming_interface_t _videod_streaming_itf[CFG_TUD_VIDEO_STREAMING];
|
||||
CFG_TUD_MEM_SECTION tu_static videod_interface_t _videod_itf[CFG_TUD_VIDEO];
|
||||
CFG_TUD_MEM_SECTION tu_static videod_streaming_interface_t _videod_streaming_itf[CFG_TUD_VIDEO_STREAMING];
|
||||
|
||||
tu_static uint8_t const _cap_get = 0x1u; /* support for GET */
|
||||
tu_static uint8_t const _cap_get_set = 0x3u; /* support for GET and SET */
|
||||
@@ -609,17 +616,17 @@ static bool _close_vc_itf(uint8_t rhport, videod_interface_t *self)
|
||||
* @param[in] altnum The target alternate setting number. */
|
||||
static bool _open_vc_itf(uint8_t rhport, videod_interface_t *self, uint_fast8_t altnum)
|
||||
{
|
||||
TU_LOG2(" open VC %d\n", altnum);
|
||||
TU_LOG_DRV(" open VC %d\n", altnum);
|
||||
uint8_t const *beg = self->beg;
|
||||
uint8_t const *end = beg + self->len;
|
||||
|
||||
/* The first descriptor is a video control interface descriptor. */
|
||||
uint8_t const *cur = _find_desc_itf(beg, end, _desc_itfnum(beg), altnum);
|
||||
TU_LOG2(" cur %d\n", cur - beg);
|
||||
TU_LOG_DRV(" cur %d\n", cur - beg);
|
||||
TU_VERIFY(cur < end);
|
||||
|
||||
tusb_desc_vc_itf_t const *vc = (tusb_desc_vc_itf_t const *)cur;
|
||||
TU_LOG2(" bInCollection %d\n", vc->ctl.bInCollection);
|
||||
TU_LOG_DRV(" bInCollection %d\n", vc->ctl.bInCollection);
|
||||
/* Support for up to 2 streaming interfaces only. */
|
||||
TU_ASSERT(vc->ctl.bInCollection <= CFG_TUD_VIDEO_STREAMING);
|
||||
|
||||
@@ -628,7 +635,7 @@ static bool _open_vc_itf(uint8_t rhport, videod_interface_t *self, uint_fast8_t
|
||||
|
||||
/* Advance to the next descriptor after the class-specific VC interface header descriptor. */
|
||||
cur += vc->std.bLength + vc->ctl.bLength;
|
||||
TU_LOG2(" bNumEndpoints %d\n", vc->std.bNumEndpoints);
|
||||
TU_LOG_DRV(" bNumEndpoints %d\n", vc->std.bNumEndpoints);
|
||||
/* Open the notification endpoint if it exist. */
|
||||
if (vc->std.bNumEndpoints) {
|
||||
/* Support for 1 endpoint only. */
|
||||
@@ -662,7 +669,7 @@ static bool _init_vs_configuration(videod_streaming_interface_t *stm)
|
||||
static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint_fast8_t altnum)
|
||||
{
|
||||
uint_fast8_t i;
|
||||
TU_LOG2(" reopen VS %d\n", altnum);
|
||||
TU_LOG_DRV(" reopen VS %d\n", altnum);
|
||||
uint8_t const *desc = _videod_itf[stm->index_vc].beg;
|
||||
|
||||
/* Close endpoints of previous settings. */
|
||||
@@ -672,7 +679,7 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint
|
||||
uint8_t ep_adr = _desc_ep_addr(desc + ofs_ep);
|
||||
usbd_edpt_close(rhport, ep_adr);
|
||||
stm->desc.ep[i] = 0;
|
||||
TU_LOG2(" close EP%02x\n", ep_adr);
|
||||
TU_LOG_DRV(" close EP%02x\n", ep_adr);
|
||||
}
|
||||
|
||||
/* clear transfer management information */
|
||||
@@ -709,12 +716,12 @@ static bool _open_vs_itf(uint8_t rhport, videod_streaming_interface_t *stm, uint
|
||||
}
|
||||
TU_ASSERT(usbd_edpt_open(rhport, ep));
|
||||
stm->desc.ep[i] = (uint16_t) (cur - desc);
|
||||
TU_LOG2(" open EP%02x\n", _desc_ep_addr(cur));
|
||||
TU_LOG_DRV(" open EP%02x\n", _desc_ep_addr(cur));
|
||||
}
|
||||
if (altnum) {
|
||||
stm->state = VS_STATE_STREAMING;
|
||||
}
|
||||
TU_LOG2(" done\n");
|
||||
TU_LOG_DRV(" done\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,8 @@
|
||||
#define U32_TO_U8S_LE(_u32) TU_U32_BYTE0(_u32), TU_U32_BYTE1(_u32), TU_U32_BYTE2(_u32), TU_U32_BYTE3(_u32)
|
||||
|
||||
#define TU_BIT(n) (1UL << (n))
|
||||
|
||||
// Generate a mask with bit from high (31) to low (0) set, e.g TU_GENMASK(3, 0) = 0b1111
|
||||
#define TU_GENMASK(h, l) ( (UINT32_MAX << (l)) & (UINT32_MAX >> (31 - (h))) )
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
@@ -99,10 +101,9 @@ TU_ATTR_WEAK extern void* tusb_app_phys_to_virt(void *phys_addr);
|
||||
#define tu_varclr(_var) tu_memclr(_var, sizeof(*(_var)))
|
||||
|
||||
// This is a backport of memset_s from c11
|
||||
TU_ATTR_ALWAYS_INLINE static inline int tu_memset_s(void *dest, size_t destsz, int ch, size_t count)
|
||||
{
|
||||
TU_ATTR_ALWAYS_INLINE static inline int tu_memset_s(void *dest, size_t destsz, int ch, size_t count) {
|
||||
// TODO may check if desst and src is not NULL
|
||||
if (count > destsz) {
|
||||
if ( count > destsz ) {
|
||||
return -1;
|
||||
}
|
||||
memset(dest, ch, count);
|
||||
@@ -110,10 +111,9 @@ TU_ATTR_ALWAYS_INLINE static inline int tu_memset_s(void *dest, size_t destsz, i
|
||||
}
|
||||
|
||||
// This is a backport of memcpy_s from c11
|
||||
TU_ATTR_ALWAYS_INLINE static inline int tu_memcpy_s(void *dest, size_t destsz, const void * src, size_t count )
|
||||
{
|
||||
TU_ATTR_ALWAYS_INLINE static inline int tu_memcpy_s(void *dest, size_t destsz, const void *src, size_t count) {
|
||||
// TODO may check if desst and src is not NULL
|
||||
if (count > destsz) {
|
||||
if ( count > destsz ) {
|
||||
return -1;
|
||||
}
|
||||
memcpy(dest, src, count);
|
||||
@@ -169,6 +169,9 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align32 (uint32_t value) { retur
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_align4k (uint32_t value) { return (value & 0xFFFFF000UL); }
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_offset4k(uint32_t value) { return (value & 0xFFFUL); }
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline bool tu_is_aligned32(uint32_t value) { return (value & 0x1FUL) == 0; }
|
||||
TU_ATTR_ALWAYS_INLINE static inline bool tu_is_aligned64(uint64_t value) { return (value & 0x3FUL) == 0; }
|
||||
|
||||
//------------- Mathematics -------------//
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_div_ceil(uint32_t v, uint32_t d) { return (v + d -1)/d; }
|
||||
|
||||
|
||||
@@ -43,9 +43,6 @@
|
||||
#define CFG_TUD_TASK_QUEUE_SZ 16
|
||||
#endif
|
||||
|
||||
// Debug level of USBD
|
||||
#define USBD_DBG 2
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Device Data
|
||||
//--------------------------------------------------------------------+
|
||||
@@ -81,7 +78,7 @@ tu_static usbd_device_t _usbd_dev;
|
||||
//--------------------------------------------------------------------+
|
||||
// Class Driver
|
||||
//--------------------------------------------------------------------+
|
||||
#if CFG_TUSB_DEBUG >= 2
|
||||
#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
|
||||
#define DRIVER_NAME(_name) .name = _name,
|
||||
#else
|
||||
#define DRIVER_NAME(_name)
|
||||
@@ -308,7 +305,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event,
|
||||
//--------------------------------------------------------------------+
|
||||
// Debug
|
||||
//--------------------------------------------------------------------+
|
||||
#if CFG_TUSB_DEBUG >= 2
|
||||
#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
|
||||
tu_static char const* const _usbd_event_str[DCD_EVENT_COUNT] =
|
||||
{
|
||||
"Invalid" ,
|
||||
@@ -330,7 +327,7 @@ void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback)
|
||||
usbd_class_driver_t const * driver = get_driver(i);
|
||||
if ( driver && driver->control_xfer_cb == callback )
|
||||
{
|
||||
TU_LOG(USBD_DBG, " %s control complete\r\n", driver->name);
|
||||
TU_LOG_USBD(" %s control complete\r\n", driver->name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -396,10 +393,10 @@ bool tud_init (uint8_t rhport)
|
||||
// skip if already initialized
|
||||
if ( tud_inited() ) return true;
|
||||
|
||||
TU_LOG(USBD_DBG, "USBD init on controller %u\r\n", rhport);
|
||||
TU_LOG_INT(USBD_DBG, sizeof(usbd_device_t));
|
||||
TU_LOG_INT(USBD_DBG, sizeof(tu_fifo_t));
|
||||
TU_LOG_INT(USBD_DBG, sizeof(tu_edpt_stream_t));
|
||||
TU_LOG_USBD("USBD init on controller %u\r\n", rhport);
|
||||
TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(usbd_device_t));
|
||||
TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(tu_fifo_t));
|
||||
TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(tu_edpt_stream_t));
|
||||
|
||||
tu_varclr(&_usbd_dev);
|
||||
|
||||
@@ -424,7 +421,7 @@ bool tud_init (uint8_t rhport)
|
||||
{
|
||||
usbd_class_driver_t const * driver = get_driver(i);
|
||||
TU_ASSERT(driver);
|
||||
TU_LOG(USBD_DBG, "%s init\r\n", driver->name);
|
||||
TU_LOG_USBD("%s init\r\n", driver->name);
|
||||
driver->init();
|
||||
}
|
||||
|
||||
@@ -496,21 +493,21 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
|
||||
dcd_event_t event;
|
||||
if ( !osal_queue_receive(_usbd_q, &event, timeout_ms) ) return;
|
||||
|
||||
#if CFG_TUSB_DEBUG >= 2
|
||||
if (event.event_id == DCD_EVENT_SETUP_RECEIVED) TU_LOG(USBD_DBG, "\r\n"); // extra line for setup
|
||||
TU_LOG(USBD_DBG, "USBD %s ", event.event_id < DCD_EVENT_COUNT ? _usbd_event_str[event.event_id] : "CORRUPTED");
|
||||
#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
|
||||
TU_LOG_USBD("USBD %s ", event.event_id < DCD_EVENT_COUNT ? _usbd_event_str[event.event_id] : "CORRUPTED");
|
||||
#endif
|
||||
|
||||
switch ( event.event_id )
|
||||
{
|
||||
case DCD_EVENT_BUS_RESET:
|
||||
TU_LOG(USBD_DBG, ": %s Speed\r\n", tu_str_speed[event.bus_reset.speed]);
|
||||
TU_LOG_USBD(": %s Speed\r\n", tu_str_speed[event.bus_reset.speed]);
|
||||
usbd_reset(event.rhport);
|
||||
_usbd_dev.speed = event.bus_reset.speed;
|
||||
break;
|
||||
|
||||
case DCD_EVENT_UNPLUGGED:
|
||||
TU_LOG(USBD_DBG, "\r\n");
|
||||
TU_LOG_USBD("\r\n");
|
||||
usbd_reset(event.rhport);
|
||||
|
||||
// invoke callback
|
||||
@@ -518,8 +515,8 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
|
||||
break;
|
||||
|
||||
case DCD_EVENT_SETUP_RECEIVED:
|
||||
TU_LOG_PTR(USBD_DBG, &event.setup_received);
|
||||
TU_LOG(USBD_DBG, "\r\n");
|
||||
TU_LOG_PTR(CFG_TUD_LOG_LEVEL, &event.setup_received);
|
||||
TU_LOG_USBD("\r\n");
|
||||
|
||||
// Mark as connected after receiving 1st setup packet.
|
||||
// But it is easier to set it every time instead of wasting time to check then set
|
||||
@@ -534,7 +531,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
|
||||
// Process control request
|
||||
if ( !process_control_request(event.rhport, &event.setup_received) )
|
||||
{
|
||||
TU_LOG(USBD_DBG, " Stall EP0\r\n");
|
||||
TU_LOG_USBD(" Stall EP0\r\n");
|
||||
// Failed -> stall both control endpoint IN and OUT
|
||||
dcd_edpt_stall(event.rhport, 0);
|
||||
dcd_edpt_stall(event.rhport, 0 | TUSB_DIR_IN_MASK);
|
||||
@@ -548,7 +545,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
|
||||
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||
uint8_t const ep_dir = tu_edpt_dir(ep_addr);
|
||||
|
||||
TU_LOG(USBD_DBG, "on EP %02X with %u bytes\r\n", ep_addr, (unsigned int) event.xfer_complete.len);
|
||||
TU_LOG_USBD("on EP %02X with %u bytes\r\n", ep_addr, (unsigned int) event.xfer_complete.len);
|
||||
|
||||
_usbd_dev.ep_status[epnum][ep_dir].busy = 0;
|
||||
_usbd_dev.ep_status[epnum][ep_dir].claimed = 0;
|
||||
@@ -563,7 +560,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
|
||||
usbd_class_driver_t const * driver = get_driver( _usbd_dev.ep2drv[epnum][ep_dir] );
|
||||
TU_ASSERT(driver, );
|
||||
|
||||
TU_LOG(USBD_DBG, " %s xfer callback\r\n", driver->name);
|
||||
TU_LOG_USBD(" %s xfer callback\r\n", driver->name);
|
||||
driver->xfer_cb(event.rhport, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len);
|
||||
}
|
||||
}
|
||||
@@ -575,27 +572,27 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
|
||||
// e.g suspend -> resume -> unplug/plug. Skip suspend/resume if not connected
|
||||
if ( _usbd_dev.connected )
|
||||
{
|
||||
TU_LOG(USBD_DBG, ": Remote Wakeup = %u\r\n", _usbd_dev.remote_wakeup_en);
|
||||
TU_LOG_USBD(": Remote Wakeup = %u\r\n", _usbd_dev.remote_wakeup_en);
|
||||
if (tud_suspend_cb) tud_suspend_cb(_usbd_dev.remote_wakeup_en);
|
||||
}else
|
||||
{
|
||||
TU_LOG(USBD_DBG, " Skipped\r\n");
|
||||
TU_LOG_USBD(" Skipped\r\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case DCD_EVENT_RESUME:
|
||||
if ( _usbd_dev.connected )
|
||||
{
|
||||
TU_LOG(USBD_DBG, "\r\n");
|
||||
TU_LOG_USBD("\r\n");
|
||||
if (tud_resume_cb) tud_resume_cb();
|
||||
}else
|
||||
{
|
||||
TU_LOG(USBD_DBG, " Skipped\r\n");
|
||||
TU_LOG_USBD(" Skipped\r\n");
|
||||
}
|
||||
break;
|
||||
|
||||
case USBD_EVENT_FUNC_CALL:
|
||||
TU_LOG(USBD_DBG, "\r\n");
|
||||
TU_LOG_USBD("\r\n");
|
||||
if ( event.func_call.func ) event.func_call.func(event.func_call.param);
|
||||
break;
|
||||
|
||||
@@ -620,7 +617,7 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr)
|
||||
static bool invoke_class_control(uint8_t rhport, usbd_class_driver_t const * driver, tusb_control_request_t const * request)
|
||||
{
|
||||
usbd_control_set_complete_callback(driver->control_xfer_cb);
|
||||
TU_LOG(USBD_DBG, " %s control request\r\n", driver->name);
|
||||
TU_LOG_USBD(" %s control request\r\n", driver->name);
|
||||
return driver->control_xfer_cb(rhport, CONTROL_STAGE_SETUP, request);
|
||||
}
|
||||
|
||||
@@ -641,11 +638,11 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
|
||||
return tud_vendor_control_xfer_cb(rhport, CONTROL_STAGE_SETUP, p_request);
|
||||
}
|
||||
|
||||
#if CFG_TUSB_DEBUG >= 2
|
||||
#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
|
||||
if (TUSB_REQ_TYPE_STANDARD == p_request->bmRequestType_bit.type && p_request->bRequest <= TUSB_REQ_SYNCH_FRAME)
|
||||
{
|
||||
TU_LOG(USBD_DBG, " %s", tu_str_std_request[p_request->bRequest]);
|
||||
if (TUSB_REQ_GET_DESCRIPTOR != p_request->bRequest) TU_LOG(USBD_DBG, "\r\n");
|
||||
TU_LOG_USBD(" %s", tu_str_std_request[p_request->bRequest]);
|
||||
if (TUSB_REQ_GET_DESCRIPTOR != p_request->bRequest) TU_LOG_USBD("\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -701,7 +698,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
|
||||
if ( _usbd_dev.cfg_num )
|
||||
{
|
||||
// already configured: need to clear all endpoints and driver first
|
||||
TU_LOG(USBD_DBG, " 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);
|
||||
|
||||
// close all non-control endpoints, cancel all pending transfers if any
|
||||
dcd_edpt_close_all(rhport);
|
||||
@@ -730,7 +727,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
|
||||
// Only support remote wakeup for device feature
|
||||
TU_VERIFY(TUSB_REQ_FEATURE_REMOTE_WAKEUP == p_request->wValue);
|
||||
|
||||
TU_LOG(USBD_DBG, " Enable Remote Wakeup\r\n");
|
||||
TU_LOG_USBD(" Enable Remote Wakeup\r\n");
|
||||
|
||||
// Host may enable remote wake up before suspending especially HID device
|
||||
_usbd_dev.remote_wakeup_en = true;
|
||||
@@ -741,7 +738,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const
|
||||
// Only support remote wakeup for device feature
|
||||
TU_VERIFY(TUSB_REQ_FEATURE_REMOTE_WAKEUP == p_request->wValue);
|
||||
|
||||
TU_LOG(USBD_DBG, " Disable Remote Wakeup\r\n");
|
||||
TU_LOG_USBD(" Disable Remote Wakeup\r\n");
|
||||
|
||||
// Host may disable remote wake up after resuming
|
||||
_usbd_dev.remote_wakeup_en = false;
|
||||
@@ -924,7 +921,7 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num)
|
||||
if ( (sizeof(tusb_desc_interface_t) <= drv_len) && (drv_len <= remaining_len) )
|
||||
{
|
||||
// Open successfully
|
||||
TU_LOG(USBD_DBG, " %s opened\r\n", driver->name);
|
||||
TU_LOG_USBD(" %s opened\r\n", driver->name);
|
||||
|
||||
// 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)
|
||||
@@ -983,7 +980,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
|
||||
{
|
||||
case TUSB_DESC_DEVICE:
|
||||
{
|
||||
TU_LOG(USBD_DBG, " Device\r\n");
|
||||
TU_LOG_USBD(" Device\r\n");
|
||||
|
||||
void* desc_device = (void*) (uintptr_t) tud_descriptor_device_cb();
|
||||
|
||||
@@ -1007,7 +1004,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
|
||||
|
||||
case TUSB_DESC_BOS:
|
||||
{
|
||||
TU_LOG(USBD_DBG, " BOS\r\n");
|
||||
TU_LOG_USBD(" BOS\r\n");
|
||||
|
||||
// requested by host if USB > 2.0 ( i.e 2.1 or 3.x )
|
||||
if (!tud_descriptor_bos_cb) return false;
|
||||
@@ -1029,12 +1026,12 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
|
||||
|
||||
if ( desc_type == TUSB_DESC_CONFIGURATION )
|
||||
{
|
||||
TU_LOG(USBD_DBG, " 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);
|
||||
}else
|
||||
{
|
||||
// Host only request this after getting Device Qualifier descriptor
|
||||
TU_LOG(USBD_DBG, " Other Speed Configuration\r\n");
|
||||
TU_LOG_USBD(" Other Speed Configuration\r\n");
|
||||
TU_VERIFY( tud_descriptor_other_speed_configuration_cb );
|
||||
desc_config = (uintptr_t) tud_descriptor_other_speed_configuration_cb(desc_index);
|
||||
}
|
||||
@@ -1050,7 +1047,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
|
||||
|
||||
case TUSB_DESC_STRING:
|
||||
{
|
||||
TU_LOG(USBD_DBG, " String[%u]\r\n", desc_index);
|
||||
TU_LOG_USBD(" String[%u]\r\n", desc_index);
|
||||
|
||||
// String Descriptor always uses the desc set from user
|
||||
uint8_t const* desc_str = (uint8_t const*) tud_descriptor_string_cb(desc_index, tu_le16toh(p_request->wIndex));
|
||||
@@ -1063,7 +1060,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
|
||||
|
||||
case TUSB_DESC_DEVICE_QUALIFIER:
|
||||
{
|
||||
TU_LOG(USBD_DBG, " Device Qualifier\r\n");
|
||||
TU_LOG_USBD(" Device Qualifier\r\n");
|
||||
|
||||
TU_VERIFY( tud_descriptor_device_qualifier_cb );
|
||||
|
||||
@@ -1248,7 +1245,7 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
|
||||
// TODO skip ready() check for now since enumeration also use this API
|
||||
// TU_VERIFY(tud_ready());
|
||||
|
||||
TU_LOG(USBD_DBG, " Queue EP %02X with %u bytes ...\r\n", ep_addr, total_bytes);
|
||||
TU_LOG_USBD(" Queue EP %02X with %u bytes ...\r\n", ep_addr, total_bytes);
|
||||
|
||||
// Attempt to transfer on a busy endpoint, sound like an race condition !
|
||||
TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0);
|
||||
@@ -1265,7 +1262,7 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t
|
||||
// DCD error, mark endpoint as ready to allow next transfer
|
||||
_usbd_dev.ep_status[epnum][dir].busy = 0;
|
||||
_usbd_dev.ep_status[epnum][dir].claimed = 0;
|
||||
TU_LOG(USBD_DBG, "FAILED\r\n");
|
||||
TU_LOG_USBD("FAILED\r\n");
|
||||
TU_BREAKPOINT();
|
||||
return false;
|
||||
}
|
||||
@@ -1282,7 +1279,7 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16
|
||||
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||
uint8_t const dir = tu_edpt_dir(ep_addr);
|
||||
|
||||
TU_LOG(USBD_DBG, " Queue ISO EP %02X with %u bytes ... ", ep_addr, total_bytes);
|
||||
TU_LOG_USBD(" Queue ISO EP %02X with %u bytes ... ", ep_addr, total_bytes);
|
||||
|
||||
// Attempt to transfer on a busy endpoint, sound like an race condition !
|
||||
TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0);
|
||||
@@ -1293,14 +1290,14 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16
|
||||
|
||||
if (dcd_edpt_xfer_fifo(rhport, ep_addr, ff, total_bytes))
|
||||
{
|
||||
TU_LOG(USBD_DBG, "OK\r\n");
|
||||
TU_LOG_USBD("OK\r\n");
|
||||
return true;
|
||||
}else
|
||||
{
|
||||
// DCD error, mark endpoint as ready to allow next transfer
|
||||
_usbd_dev.ep_status[epnum][dir].busy = 0;
|
||||
_usbd_dev.ep_status[epnum][dir].claimed = 0;
|
||||
TU_LOG(USBD_DBG, "failed\r\n");
|
||||
TU_LOG_USBD("failed\r\n");
|
||||
TU_BREAKPOINT();
|
||||
return false;
|
||||
}
|
||||
@@ -1326,7 +1323,7 @@ void usbd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
|
||||
// only stalled if currently cleared
|
||||
if ( !_usbd_dev.ep_status[epnum][dir].stalled )
|
||||
{
|
||||
TU_LOG(USBD_DBG, " Stall EP %02X\r\n", ep_addr);
|
||||
TU_LOG_USBD(" Stall EP %02X\r\n", ep_addr);
|
||||
dcd_edpt_stall(rhport, ep_addr);
|
||||
_usbd_dev.ep_status[epnum][dir].stalled = 1;
|
||||
_usbd_dev.ep_status[epnum][dir].busy = 1;
|
||||
@@ -1343,7 +1340,7 @@ void usbd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
|
||||
// only clear if currently stalled
|
||||
if ( _usbd_dev.ep_status[epnum][dir].stalled )
|
||||
{
|
||||
TU_LOG(USBD_DBG, " Clear Stall EP %02X\r\n", ep_addr);
|
||||
TU_LOG_USBD(" Clear Stall EP %02X\r\n", ep_addr);
|
||||
dcd_edpt_clear_stall(rhport, ep_addr);
|
||||
_usbd_dev.ep_status[epnum][dir].stalled = 0;
|
||||
_usbd_dev.ep_status[epnum][dir].busy = 0;
|
||||
@@ -1371,7 +1368,7 @@ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr)
|
||||
rhport = _usbd_rhport;
|
||||
|
||||
TU_ASSERT(dcd_edpt_close, /**/);
|
||||
TU_LOG(USBD_DBG, " CLOSING Endpoint: 0x%02X\r\n", ep_addr);
|
||||
TU_LOG_USBD(" CLOSING Endpoint: 0x%02X\r\n", ep_addr);
|
||||
|
||||
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||
uint8_t const dir = tu_edpt_dir(ep_addr);
|
||||
|
||||
@@ -32,10 +32,7 @@
|
||||
#include "tusb.h"
|
||||
#include "device/usbd_pvt.h"
|
||||
|
||||
// Debug level of USBD Control
|
||||
#define USBD_CONTROL_DEBUG 2
|
||||
|
||||
#if CFG_TUSB_DEBUG >= USBD_CONTROL_DEBUG
|
||||
#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
|
||||
extern void usbd_driver_print_control_complete_name(usbd_control_xfer_cb_t callback);
|
||||
#endif
|
||||
|
||||
@@ -58,7 +55,7 @@ typedef struct
|
||||
|
||||
tu_static usbd_control_xfer_t _ctrl_xfer;
|
||||
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN
|
||||
tu_static uint8_t _usbd_ctrl_buf[CFG_TUD_ENDPOINT0_SIZE];
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
@@ -191,7 +188,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result
|
||||
{
|
||||
TU_VERIFY(_ctrl_xfer.buffer);
|
||||
memcpy(_ctrl_xfer.buffer, _usbd_ctrl_buf, xferred_bytes);
|
||||
TU_LOG_MEM(USBD_CONTROL_DEBUG, _usbd_ctrl_buf, xferred_bytes, 2);
|
||||
TU_LOG_MEM(CFG_TUD_LOG_LEVEL, _usbd_ctrl_buf, xferred_bytes, 2);
|
||||
}
|
||||
|
||||
_ctrl_xfer.total_xferred += (uint16_t) xferred_bytes;
|
||||
@@ -208,7 +205,7 @@ bool usbd_control_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t result
|
||||
// callback can still stall control in status phase e.g out data does not make sense
|
||||
if ( _ctrl_xfer.complete_cb )
|
||||
{
|
||||
#if CFG_TUSB_DEBUG >= USBD_CONTROL_DEBUG
|
||||
#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
|
||||
usbd_driver_print_control_complete_name(_ctrl_xfer.complete_cb);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -33,13 +33,20 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Level where CFG_TUSB_DEBUG must be at least for USBD is logged
|
||||
#ifndef CFG_TUD_LOG_LEVEL
|
||||
#define CFG_TUD_LOG_LEVEL 2
|
||||
#endif
|
||||
|
||||
#define TU_LOG_USBD(...) TU_LOG(CFG_TUD_LOG_LEVEL, __VA_ARGS__)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Class Driver API
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#if CFG_TUSB_DEBUG >= 2
|
||||
#if CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
|
||||
char const* name;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -110,15 +110,15 @@ typedef struct
|
||||
|
||||
// clean/flush data cache: write cache -> memory.
|
||||
// Required before an DMA TX transfer to make sure data is in memory
|
||||
void hcd_dcache_clean(void const* addr, uint32_t data_size) TU_ATTR_WEAK;
|
||||
bool hcd_dcache_clean(void const* addr, uint32_t data_size) TU_ATTR_WEAK;
|
||||
|
||||
// invalidate data cache: mark cache as invalid, next read will read from memory
|
||||
// Required BOTH before and after an DMA RX transfer
|
||||
void hcd_dcache_invalidate(void const* addr, uint32_t data_size) TU_ATTR_WEAK;
|
||||
bool hcd_dcache_invalidate(void const* addr, uint32_t data_size) TU_ATTR_WEAK;
|
||||
|
||||
// clean and invalidate data cache
|
||||
// Required before an DMA transfer where memory is both read/write by DMA
|
||||
void hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_WEAK;
|
||||
bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_WEAK;
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Controller API
|
||||
@@ -171,11 +171,15 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
|
||||
// Submit a transfer, when complete hcd_event_xfer_complete() must be invoked
|
||||
bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen);
|
||||
|
||||
// Abort a queued transfer. Note: it can only abort transfer that has not been started
|
||||
// Return true if a queued transfer is aborted, false if there is no transfer to abort
|
||||
bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr);
|
||||
|
||||
// Submit a special transfer to send 8-byte Setup Packet, when complete hcd_event_xfer_complete() must be invoked
|
||||
bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]);
|
||||
|
||||
// clear stall, data toggle is also reset to DATA0
|
||||
bool hcd_edpt_clear_stall(uint8_t daddr, uint8_t ep_addr);
|
||||
bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr);
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// USBH implemented API
|
||||
|
||||
@@ -45,8 +45,8 @@ typedef struct
|
||||
uint8_t itf_num;
|
||||
uint8_t ep_in;
|
||||
uint8_t port_count;
|
||||
uint8_t status_change; // data from status change interrupt endpoint
|
||||
|
||||
CFG_TUH_MEM_ALIGN uint8_t status_change;
|
||||
CFG_TUH_MEM_ALIGN hub_port_status_response_t port_status;
|
||||
CFG_TUH_MEM_ALIGN hub_status_response_t hub_status;
|
||||
} hub_interface_t;
|
||||
|
||||
125
src/host/usbh.c
125
src/host/usbh.c
@@ -38,18 +38,13 @@
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
#ifndef CFG_TUH_TASK_QUEUE_SZ
|
||||
#define CFG_TUH_TASK_QUEUE_SZ 16
|
||||
#define CFG_TUH_TASK_QUEUE_SZ 16
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUH_INTERFACE_MAX
|
||||
#define CFG_TUH_INTERFACE_MAX 8
|
||||
#define CFG_TUH_INTERFACE_MAX 8
|
||||
#endif
|
||||
|
||||
// Debug level, TUSB_CFG_DEBUG must be at least this level for debug message
|
||||
#define USBH_DEBUG 2
|
||||
|
||||
#define TU_LOG_USBH(...) TU_LOG(USBH_DEBUG, __VA_ARGS__)
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// USBH-HCD common data structure
|
||||
//--------------------------------------------------------------------+
|
||||
@@ -256,7 +251,7 @@ static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t
|
||||
|
||||
#if CFG_TUSB_OS == OPT_OS_NONE
|
||||
// TODO rework time-related function later
|
||||
void osal_task_delay(uint32_t msec)
|
||||
TU_ATTR_WEAK void osal_task_delay(uint32_t msec)
|
||||
{
|
||||
const uint32_t start = hcd_frame_number(_usbh_controller);
|
||||
while ( ( hcd_frame_number(_usbh_controller) - start ) < msec ) {}
|
||||
@@ -322,12 +317,12 @@ bool tuh_init(uint8_t controller_id)
|
||||
if ( tuh_inited() ) return true;
|
||||
|
||||
TU_LOG_USBH("USBH init on controller %u\r\n", controller_id);
|
||||
TU_LOG_INT(USBH_DEBUG, sizeof(usbh_device_t));
|
||||
TU_LOG_INT(USBH_DEBUG, sizeof(hcd_event_t));
|
||||
TU_LOG_INT(USBH_DEBUG, sizeof(_ctrl_xfer));
|
||||
TU_LOG_INT(USBH_DEBUG, sizeof(tuh_xfer_t));
|
||||
TU_LOG_INT(USBH_DEBUG, sizeof(tu_fifo_t));
|
||||
TU_LOG_INT(USBH_DEBUG, sizeof(tu_edpt_stream_t));
|
||||
TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(usbh_device_t));
|
||||
TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(hcd_event_t));
|
||||
TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(_ctrl_xfer));
|
||||
TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(tuh_xfer_t));
|
||||
TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(tu_fifo_t));
|
||||
TU_LOG_INT(CFG_TUH_LOG_LEVEL, sizeof(tu_edpt_stream_t));
|
||||
|
||||
// Event queue
|
||||
_usbh_q = osal_queue_create( &_usbh_qdef );
|
||||
@@ -450,39 +445,28 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr)
|
||||
TU_LOG_USBH("on EP %02X with %u bytes: %s\r\n", ep_addr, (unsigned int) event.xfer_complete.len,
|
||||
tu_str_xfer_result[event.xfer_complete.result]);
|
||||
|
||||
if (event.dev_addr == 0)
|
||||
{
|
||||
if (event.dev_addr == 0) {
|
||||
// device 0 only has control endpoint
|
||||
TU_ASSERT(epnum == 0, );
|
||||
usbh_control_xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
usbh_device_t* dev = get_device(event.dev_addr);
|
||||
TU_VERIFY(dev && dev->connected, );
|
||||
|
||||
dev->ep_status[epnum][ep_dir].busy = 0;
|
||||
dev->ep_status[epnum][ep_dir].claimed = 0;
|
||||
|
||||
if ( 0 == epnum )
|
||||
{
|
||||
usbh_control_xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len);
|
||||
}else
|
||||
{
|
||||
uint8_t drv_id = dev->ep2drv[epnum][ep_dir];
|
||||
if(drv_id < USBH_CLASS_DRIVER_COUNT)
|
||||
{
|
||||
TU_LOG_USBH("%s xfer callback\r\n", usbh_class_drivers[drv_id].name);
|
||||
usbh_class_drivers[drv_id].xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result, event.xfer_complete.len);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if CFG_TUH_API_EDPT_XFER
|
||||
tuh_xfer_cb_t complete_cb = dev->ep_callback[epnum][ep_dir].complete_cb;
|
||||
if ( complete_cb )
|
||||
{
|
||||
tuh_xfer_t xfer =
|
||||
{
|
||||
if ( 0 == epnum ) {
|
||||
usbh_control_xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result,
|
||||
event.xfer_complete.len);
|
||||
}else {
|
||||
// Prefer application callback over built-in one if available. This occurs when tuh_edpt_xfer() is used
|
||||
// with enabled driver e.g HID endpoint
|
||||
#if CFG_TUH_API_EDPT_XFER
|
||||
tuh_xfer_cb_t const complete_cb = dev->ep_callback[epnum][ep_dir].complete_cb;
|
||||
if ( complete_cb ) {
|
||||
// re-construct xfer info
|
||||
tuh_xfer_t xfer = {
|
||||
.daddr = event.dev_addr,
|
||||
.ep_addr = ep_addr,
|
||||
.result = event.xfer_complete.result,
|
||||
@@ -491,16 +475,21 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr)
|
||||
.buffer = NULL, // not available
|
||||
.complete_cb = complete_cb,
|
||||
.user_data = dev->ep_callback[epnum][ep_dir].user_data
|
||||
};
|
||||
};
|
||||
|
||||
complete_cb(&xfer);
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
complete_cb(&xfer);
|
||||
}else
|
||||
#endif
|
||||
{
|
||||
uint8_t const drv_id = dev->ep2drv[epnum][ep_dir];
|
||||
if ( drv_id < USBH_CLASS_DRIVER_COUNT ) {
|
||||
TU_LOG_USBH("%s xfer callback\r\n", usbh_class_drivers[drv_id].name);
|
||||
usbh_class_drivers[drv_id].xfer_cb(event.dev_addr, ep_addr, (xfer_result_t) event.xfer_complete.result,
|
||||
event.xfer_complete.len);
|
||||
} else {
|
||||
// no driver/callback responsible for this transfer
|
||||
TU_ASSERT(false, );
|
||||
TU_ASSERT(false,);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -565,7 +554,7 @@ bool tuh_control_xfer (tuh_xfer_t* xfer)
|
||||
TU_LOG_USBH("[%u:%u] %s: ", rhport, daddr,
|
||||
(xfer->setup->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME) ?
|
||||
tu_str_std_request[xfer->setup->bRequest] : "Class Request");
|
||||
TU_LOG_PTR(USBH_DEBUG, xfer->setup);
|
||||
TU_LOG_PTR(CFG_TUH_LOG_LEVEL, xfer->setup);
|
||||
TU_LOG_USBH("\r\n");
|
||||
|
||||
if (xfer->complete_cb)
|
||||
@@ -671,7 +660,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result
|
||||
if (request->wLength)
|
||||
{
|
||||
TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, dev_addr);
|
||||
TU_LOG_MEM(USBH_DEBUG, _ctrl_xfer.buffer, xferred_bytes, 2);
|
||||
TU_LOG_MEM(CFG_TUH_LOG_LEVEL, _ctrl_xfer.buffer, xferred_bytes, 2);
|
||||
}
|
||||
|
||||
_ctrl_xfer.actual_len = (uint16_t) xferred_bytes;
|
||||
@@ -714,6 +703,25 @@ bool tuh_edpt_xfer(tuh_xfer_t* xfer)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tuh_edpt_abort_xfer(uint8_t daddr, uint8_t ep_addr) {
|
||||
usbh_device_t* dev = get_device(daddr);
|
||||
TU_VERIFY(dev);
|
||||
|
||||
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||
uint8_t const dir = tu_edpt_dir(ep_addr);
|
||||
|
||||
// skip if not busy
|
||||
TU_VERIFY(dev->ep_status[epnum][dir].busy);
|
||||
|
||||
bool const ret = hcd_edpt_abort_xfer(dev->rhport, daddr, ep_addr);
|
||||
if (ret) {
|
||||
// mark as ready if transfer is aborted
|
||||
dev->ep_status[epnum][dir].busy = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// USBH API For Class Driver
|
||||
//--------------------------------------------------------------------+
|
||||
@@ -745,7 +753,7 @@ void usbh_int_set(bool enabled)
|
||||
// Endpoint API
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// TODO has some duplication code with device, refactor later
|
||||
// Claim an endpoint for transfer
|
||||
bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr)
|
||||
{
|
||||
// Note: addr0 only use tuh_control_xfer
|
||||
@@ -761,7 +769,7 @@ bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr)
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO has some duplication code with device, refactor later
|
||||
// Release an claimed endpoint due to failed transfer attempt
|
||||
bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr)
|
||||
{
|
||||
// Note: addr0 only use tuh_control_xfer
|
||||
@@ -777,7 +785,7 @@ bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr)
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO has some duplication code with device, refactor later
|
||||
// Submit an transfer
|
||||
bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes,
|
||||
tuh_xfer_cb_t complete_cb, uintptr_t user_data)
|
||||
{
|
||||
@@ -791,7 +799,7 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b
|
||||
uint8_t const dir = tu_edpt_dir(ep_addr);
|
||||
tu_edpt_state_t* ep_state = &dev->ep_status[epnum][dir];
|
||||
|
||||
TU_LOG_USBH(" Queue EP %02X with %u bytes ... ", ep_addr, total_bytes);
|
||||
TU_LOG_USBH(" Queue EP %02X with %u bytes ... \r\n", ep_addr, total_bytes);
|
||||
|
||||
// Attempt to transfer on a busy endpoint, sound like an race condition !
|
||||
TU_ASSERT(ep_state->busy == 0);
|
||||
@@ -844,14 +852,13 @@ bool tuh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep)
|
||||
return hcd_edpt_open(usbh_get_rhport(dev_addr), dev_addr, desc_ep);
|
||||
}
|
||||
|
||||
bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr)
|
||||
{
|
||||
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||
uint8_t const dir = tu_edpt_dir(ep_addr);
|
||||
|
||||
bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr) {
|
||||
usbh_device_t* dev = get_device(dev_addr);
|
||||
TU_VERIFY(dev);
|
||||
|
||||
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||
uint8_t const dir = tu_edpt_dir(ep_addr);
|
||||
|
||||
return dev->ep_status[epnum][dir].busy;
|
||||
}
|
||||
|
||||
@@ -1186,7 +1193,7 @@ static void process_removing_device(uint8_t rhport, uint8_t hub_addr, uint8_t hu
|
||||
TU_LOG_USBH("Device unplugged address = %u\r\n", daddr);
|
||||
|
||||
if (is_hub_addr(daddr)) {
|
||||
TU_LOG(USBH_DEBUG, " is a HUB device %u\r\n", daddr);
|
||||
TU_LOG(CFG_TUH_LOG_LEVEL, " is a HUB device %u\r\n", daddr);
|
||||
|
||||
// Submit removed event If the device itself is a hub (un-rolled recursive)
|
||||
// TODO a better to unroll recursrive is using array of removing_hubs and mark it here
|
||||
@@ -1657,7 +1664,7 @@ static bool _parse_configuration_descriptor(uint8_t dev_addr, tusb_desc_configur
|
||||
|
||||
if( drv_id >= USBH_CLASS_DRIVER_COUNT )
|
||||
{
|
||||
TU_LOG(USBH_DEBUG, "Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n",
|
||||
TU_LOG(CFG_TUH_LOG_LEVEL, "Interface %u: class = %u subclass = %u protocol = %u is not supported\r\n",
|
||||
desc_itf->bInterfaceNumber, desc_itf->bInterfaceClass, desc_itf->bInterfaceSubClass, desc_itf->bInterfaceProtocol);
|
||||
}
|
||||
}
|
||||
@@ -1695,7 +1702,7 @@ void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num)
|
||||
|
||||
if (is_hub_addr(dev_addr))
|
||||
{
|
||||
TU_LOG(USBH_DEBUG, "HUB address = %u is mounted\r\n", dev_addr);
|
||||
TU_LOG(CFG_TUH_LOG_LEVEL, "HUB address = %u is mounted\r\n", dev_addr);
|
||||
}else
|
||||
{
|
||||
// Invoke callback if available
|
||||
|
||||
@@ -172,8 +172,12 @@ bool tuh_control_xfer(tuh_xfer_t* xfer);
|
||||
// - sync : blocking if complete callback is NULL.
|
||||
bool tuh_edpt_xfer(tuh_xfer_t* xfer);
|
||||
|
||||
// Open an non-control endpoint
|
||||
bool tuh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep);
|
||||
// Open a non-control endpoint
|
||||
bool tuh_edpt_open(uint8_t daddr, tusb_desc_endpoint_t const * desc_ep);
|
||||
|
||||
// Abort a queued transfer. Note: it can only abort transfer that has not been started
|
||||
// Return true if a queued transfer is aborted, false if there is no transfer to abort
|
||||
bool tuh_edpt_abort_xfer(uint8_t daddr, uint8_t ep_addr);
|
||||
|
||||
// Set Configuration (control transfer)
|
||||
// config_num = 0 will un-configure device. Note: config_num = config_descriptor_index + 1
|
||||
|
||||
@@ -35,6 +35,13 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Level where CFG_TUSB_DEBUG must be at least for USBH is logged
|
||||
#ifndef CFG_TUH_LOG_LEVEL
|
||||
#define CFG_TUH_LOG_LEVEL 2
|
||||
#endif
|
||||
|
||||
#define TU_LOG_USBH(...) TU_LOG(CFG_TUH_LOG_LEVEL, __VA_ARGS__)
|
||||
|
||||
enum {
|
||||
USBH_EPSIZE_BULK_MAX = (TUH_OPT_HIGH_SPEED ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS)
|
||||
};
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
#if CFG_TUH_ENABLED
|
||||
// currently only needed/available in host mode
|
||||
void osal_task_delay(uint32_t msec);
|
||||
TU_ATTR_WEAK void osal_task_delay(uint32_t msec);
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
@@ -51,7 +51,7 @@ extern int8_t board_ft9xx_vbus(void);
|
||||
extern int board_uart_write(void const *buf, int len);
|
||||
|
||||
// Static array to store an incoming SETUP request for processing by tinyusb.
|
||||
CFG_TUSB_MEM_SECTION CFG_TUSB_MEM_ALIGN
|
||||
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN
|
||||
static uint8_t _ft9xx_setup_packet[8];
|
||||
|
||||
struct ft9xx_xfer_state
|
||||
|
||||
@@ -116,7 +116,7 @@ typedef struct
|
||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
// BDT(Buffer Descriptor Table) must be 256-byte aligned
|
||||
CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd;
|
||||
CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd;
|
||||
|
||||
TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" );
|
||||
|
||||
|
||||
@@ -68,25 +68,34 @@ TU_ATTR_ALWAYS_INLINE static inline bool imxrt_is_cache_mem(uintptr_t addr) {
|
||||
return !(0x20000000 <= addr && addr < 0x20100000);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void imxrt_dcache_clean(void const* addr, uint32_t data_size) {
|
||||
TU_ATTR_ALWAYS_INLINE static inline bool imxrt_dcache_clean(void const* addr, uint32_t data_size) {
|
||||
const uintptr_t addr32 = (uintptr_t) addr;
|
||||
if (imxrt_is_cache_mem(addr32)) {
|
||||
TU_ASSERT(tu_is_aligned32(addr32));
|
||||
SCB_CleanDCache_by_Addr((uint32_t *) addr32, (int32_t) data_size);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void imxrt_dcache_invalidate(void const* addr, uint32_t data_size) {
|
||||
TU_ATTR_ALWAYS_INLINE static inline bool imxrt_dcache_invalidate(void const* addr, uint32_t data_size) {
|
||||
const uintptr_t addr32 = (uintptr_t) addr;
|
||||
if (imxrt_is_cache_mem(addr32)) {
|
||||
// Invalidating does not push cached changes back to RAM so we need to be
|
||||
// *very* careful when we do it. If we're not aligned, then we risk resetting
|
||||
// values back to their RAM state.
|
||||
TU_ASSERT(tu_is_aligned32(addr32));
|
||||
SCB_InvalidateDCache_by_Addr((void*) addr32, (int32_t) data_size);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void imxrt_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
|
||||
TU_ATTR_ALWAYS_INLINE static inline bool imxrt_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
|
||||
const uintptr_t addr32 = (uintptr_t) addr;
|
||||
if (imxrt_is_cache_mem(addr32)) {
|
||||
TU_ASSERT(tu_is_aligned32(addr32));
|
||||
SCB_CleanInvalidateDCache_by_Addr((uint32_t *) addr32, (int32_t) data_size);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -175,7 +175,7 @@ typedef struct {
|
||||
dcd_qtd_t qtd[TUP_DCD_ENDPOINT_MAX][2] TU_ATTR_ALIGNED(32);
|
||||
}dcd_data_t;
|
||||
|
||||
CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(2048)
|
||||
CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(2048)
|
||||
static dcd_data_t _dcd_data;
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
@@ -41,16 +41,16 @@
|
||||
#if CFG_TUSB_MCU == OPT_MCU_MIMXRT1XXX
|
||||
#include "ci_hs_imxrt.h"
|
||||
|
||||
void hcd_dcache_clean(void const* addr, uint32_t data_size) {
|
||||
imxrt_dcache_clean(addr, data_size);
|
||||
bool hcd_dcache_clean(void const* addr, uint32_t data_size) {
|
||||
return imxrt_dcache_clean(addr, data_size);
|
||||
}
|
||||
|
||||
void hcd_dcache_invalidate(void const* addr, uint32_t data_size) {
|
||||
imxrt_dcache_invalidate(addr, data_size);
|
||||
bool hcd_dcache_invalidate(void const* addr, uint32_t data_size) {
|
||||
return imxrt_dcache_invalidate(addr, data_size);
|
||||
}
|
||||
|
||||
void hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
|
||||
imxrt_dcache_clean_invalidate(addr, data_size);
|
||||
bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
|
||||
return imxrt_dcache_clean_invalidate(addr, data_size);
|
||||
}
|
||||
|
||||
#elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX)
|
||||
|
||||
@@ -48,8 +48,8 @@
|
||||
#ifdef TUP_USBIP_CHIPIDEA_HS
|
||||
// NXP Transdimension: 8 elements
|
||||
#define FRAMELIST_SIZE_BIT_VALUE 7u
|
||||
#define FRAMELIST_SIZE_USBCMD_VALUE (((FRAMELIST_SIZE_BIT_VALUE & 3) << EHCI_USBCMD_POS_FRAMELIST_SIZE) | \
|
||||
((FRAMELIST_SIZE_BIT_VALUE >> 2) << EHCI_USBCMD_POS_NXP_FRAMELIST_SIZE_MSB))
|
||||
#define FRAMELIST_SIZE_USBCMD_VALUE (((FRAMELIST_SIZE_BIT_VALUE & 3) << EHCI_USBCMD_FRAMELIST_SIZE_SHIFT) | \
|
||||
((FRAMELIST_SIZE_BIT_VALUE >> 2) << EHCI_USBCMD_CHIPIDEA_FRAMELIST_SIZE_MSB_SHIFT))
|
||||
#else
|
||||
// STD EHCI: 256 elements
|
||||
#define FRAMELIST_SIZE_BIT_VALUE 2u
|
||||
@@ -126,52 +126,50 @@ static inline void print_intr(uint32_t intr) {
|
||||
//--------------------------------------------------------------------+
|
||||
// PROTOTYPE
|
||||
//--------------------------------------------------------------------+
|
||||
static inline ehci_link_t* get_period_head(uint8_t rhport, uint32_t interval_ms)
|
||||
{
|
||||
(void) rhport;
|
||||
return (ehci_link_t*) &ehci_data.period_head_arr[ tu_log2( tu_min32(FRAMELIST_SIZE, interval_ms) ) ];
|
||||
}
|
||||
|
||||
static inline ehci_qhd_t* qhd_control(uint8_t dev_addr)
|
||||
{
|
||||
return &ehci_data.control[dev_addr].qhd;
|
||||
}
|
||||
// weak dcache for non-cacheable MCU
|
||||
TU_ATTR_WEAK bool hcd_dcache_clean(void const* addr, uint32_t data_size) { (void) addr; (void) data_size; return true; }
|
||||
TU_ATTR_WEAK bool hcd_dcache_invalidate(void const* addr, uint32_t data_size) { (void) addr; (void) data_size; return true; }
|
||||
TU_ATTR_WEAK bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) { (void) addr; (void) data_size; return true; }
|
||||
|
||||
static inline ehci_qhd_t* qhd_async_head(uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
// control qhd of dev0 is used as async head
|
||||
return qhd_control(0);
|
||||
}
|
||||
|
||||
static inline ehci_qtd_t* qtd_control(uint8_t dev_addr)
|
||||
{
|
||||
return &ehci_data.control[dev_addr].qtd;
|
||||
}
|
||||
|
||||
|
||||
static inline ehci_qhd_t* qhd_next (ehci_qhd_t const * p_qhd);
|
||||
static inline ehci_qhd_t* qhd_find_free (void);
|
||||
static inline ehci_qhd_t* qhd_get_from_addr (uint8_t dev_addr, uint8_t ep_addr);
|
||||
TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_control(uint8_t dev_addr);
|
||||
TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_next (ehci_qhd_t const * p_qhd);
|
||||
TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_find_free (void);
|
||||
static ehci_qhd_t* qhd_get_from_addr (uint8_t dev_addr, uint8_t ep_addr);
|
||||
static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc);
|
||||
static void qhd_attach_qtd(ehci_qhd_t *qhd, ehci_qtd_t *qtd);
|
||||
static void qhd_remove_qtd(ehci_qhd_t *qhd);
|
||||
|
||||
static inline ehci_qtd_t* qtd_find_free (void);
|
||||
TU_ATTR_ALWAYS_INLINE static inline ehci_qtd_t* qtd_control(uint8_t dev_addr);
|
||||
TU_ATTR_ALWAYS_INLINE static inline ehci_qtd_t* qtd_find_free (void);
|
||||
static void qtd_init (ehci_qtd_t* qtd, void const* buffer, uint16_t total_bytes);
|
||||
|
||||
static inline void list_insert (ehci_link_t *current, ehci_link_t *new, uint8_t new_type);
|
||||
static inline ehci_link_t* list_next (ehci_link_t const *p_link);
|
||||
TU_ATTR_ALWAYS_INLINE static inline ehci_link_t* list_get_period_head(uint8_t rhport, uint32_t interval_ms);
|
||||
TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* list_get_async_head(uint8_t rhport);
|
||||
TU_ATTR_ALWAYS_INLINE static inline void list_insert (ehci_link_t *current, ehci_link_t *new, uint8_t new_type);
|
||||
TU_ATTR_ALWAYS_INLINE static inline ehci_link_t* list_next (ehci_link_t const *p_link);
|
||||
static void list_remove_qhd_by_daddr(ehci_link_t* list_head, uint8_t dev_addr);
|
||||
|
||||
TU_ATTR_WEAK void hcd_dcache_clean(void const* addr, uint32_t data_size) {
|
||||
(void) addr; (void) data_size;
|
||||
static void ehci_disable_schedule(ehci_registers_t* regs, bool is_period) {
|
||||
// maybe have a timeout for status
|
||||
if (is_period) {
|
||||
regs->command_bm.periodic_enable = 0;
|
||||
while(regs->status_bm.periodic_status) {}
|
||||
} else {
|
||||
regs->command_bm.async_enable = 0;
|
||||
while(regs->status_bm.async_status) {} // should have a timeout
|
||||
}
|
||||
}
|
||||
|
||||
TU_ATTR_WEAK void hcd_dcache_invalidate(void const* addr, uint32_t data_size) {
|
||||
(void) addr; (void) data_size;
|
||||
}
|
||||
|
||||
TU_ATTR_WEAK void hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) {
|
||||
(void) addr; (void) data_size;
|
||||
static void ehci_enable_schedule(ehci_registers_t* regs, bool is_period) {
|
||||
// maybe have a timeout for status
|
||||
if (is_period) {
|
||||
regs->command_bm.periodic_enable = 1;
|
||||
while ( 0 == regs->status_bm.periodic_status ) {}
|
||||
} else {
|
||||
regs->command_bm.async_enable = 1;
|
||||
while( 0 == regs->status_bm.async_status ) {}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
@@ -228,43 +226,6 @@ tusb_speed_t hcd_port_speed_get(uint8_t rhport)
|
||||
return (tusb_speed_t) ehci_data.regs->portsc_bm.nxp_port_speed; // NXP specific port speed
|
||||
}
|
||||
|
||||
static void list_remove_qhd_by_daddr(ehci_link_t* list_head, uint8_t dev_addr) {
|
||||
ehci_link_t* prev = list_head;
|
||||
|
||||
while (prev && !prev->terminate) {
|
||||
ehci_qhd_t* qhd = (ehci_qhd_t*) (uintptr_t) list_next(prev);
|
||||
|
||||
// done if loop back to head
|
||||
if ( (uintptr_t) qhd == (uintptr_t) list_head) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ( qhd->dev_addr == dev_addr ) {
|
||||
// TODO deactivate all TD, wait for QHD to inactive before removal
|
||||
prev->address = qhd->next.address;
|
||||
|
||||
// EHCI 4.8.2 link the removed qhd's next to async head (which always reachable by Host Controller)
|
||||
qhd->next.address = ((uint32_t) list_head) | (EHCI_QTYPE_QHD << 1);
|
||||
|
||||
if ( qhd->int_smask )
|
||||
{
|
||||
// period list queue element is guarantee to be free in the next frame (1 ms)
|
||||
qhd->used = 0;
|
||||
}else
|
||||
{
|
||||
// async list use async advance handshake
|
||||
// mark as removing, will completely re-usable when async advance isr occurs
|
||||
qhd->removing = 1;
|
||||
}
|
||||
|
||||
hcd_dcache_clean(qhd, sizeof(ehci_qhd_t));
|
||||
hcd_dcache_clean(prev, sizeof(ehci_qhd_t));
|
||||
}else {
|
||||
prev = list_next(prev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close all opened endpoint belong to this device
|
||||
void hcd_device_close(uint8_t rhport, uint8_t daddr)
|
||||
{
|
||||
@@ -274,7 +235,7 @@ void hcd_device_close(uint8_t rhport, uint8_t daddr)
|
||||
}
|
||||
|
||||
// Remove from async list
|
||||
list_remove_qhd_by_daddr((ehci_link_t *) qhd_async_head(rhport), daddr);
|
||||
list_remove_qhd_by_daddr((ehci_link_t *) list_get_async_head(rhport), daddr);
|
||||
|
||||
// Remove from all interval period list
|
||||
for(uint8_t i = 0; i < TU_ARRAY_SIZE(ehci_data.period_head_arr); i++) {
|
||||
@@ -286,37 +247,42 @@ void hcd_device_close(uint8_t rhport, uint8_t daddr)
|
||||
}
|
||||
|
||||
static void init_periodic_list(uint8_t rhport) {
|
||||
(void) rhport;
|
||||
|
||||
// Build the polling interval tree with 1 ms, 2 ms, 4 ms and 8 ms (framesize) only
|
||||
for ( uint32_t i = 0; i < TU_ARRAY_SIZE(ehci_data.period_head_arr); i++ ) {
|
||||
ehci_data.period_head_arr[i].int_smask = 1; // queue head in period list must have smask non-zero
|
||||
ehci_data.period_head_arr[i].qtd_overlay.halted = 1; // dummy node, always inactive
|
||||
}
|
||||
|
||||
ehci_link_t * const framelist = ehci_data.period_framelist;
|
||||
ehci_link_t * const period_1ms = get_period_head(rhport, 1u);
|
||||
|
||||
// TODO EHCI_FRAMELIST_SIZE with other size than 8
|
||||
// all links --> period_head_arr[0] (1ms)
|
||||
// 0, 2, 4, 6 etc --> period_head_arr[1] (2ms)
|
||||
// 1, 5 --> period_head_arr[2] (4ms)
|
||||
// 3 --> period_head_arr[3] (8ms)
|
||||
|
||||
// TODO EHCI_FRAMELIST_SIZE with other size than 8
|
||||
ehci_link_t * const framelist = ehci_data.period_framelist;
|
||||
ehci_link_t * const head_1ms = (ehci_link_t *) &ehci_data.period_head_arr[0];
|
||||
ehci_link_t * const head_2ms = (ehci_link_t *) &ehci_data.period_head_arr[1];
|
||||
ehci_link_t * const head_4ms = (ehci_link_t *) &ehci_data.period_head_arr[2];
|
||||
ehci_link_t * const head_8ms = (ehci_link_t *) &ehci_data.period_head_arr[3];
|
||||
|
||||
for (uint32_t i = 0; i < FRAMELIST_SIZE; i++) {
|
||||
framelist[i].address = (uint32_t) period_1ms;
|
||||
framelist[i].address = (uint32_t) head_1ms;
|
||||
framelist[i].type = EHCI_QTYPE_QHD;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < FRAMELIST_SIZE; i += 2) {
|
||||
list_insert(framelist + i, get_period_head(rhport, 2u), EHCI_QTYPE_QHD);
|
||||
list_insert(framelist + i, head_2ms, EHCI_QTYPE_QHD);
|
||||
}
|
||||
|
||||
for (uint32_t i = 1; i < FRAMELIST_SIZE; i += 4) {
|
||||
list_insert(framelist + i, get_period_head(rhport, 4u), EHCI_QTYPE_QHD);
|
||||
list_insert(framelist + i, head_4ms, EHCI_QTYPE_QHD);
|
||||
}
|
||||
|
||||
list_insert(framelist + 3, get_period_head(rhport, 8u), EHCI_QTYPE_QHD);
|
||||
list_insert(framelist + 3, head_8ms, EHCI_QTYPE_QHD);
|
||||
|
||||
period_1ms->terminate = 1;
|
||||
head_1ms->terminate = 1;
|
||||
}
|
||||
|
||||
bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg)
|
||||
@@ -341,18 +307,18 @@ bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg)
|
||||
regs->status = (EHCI_INT_MASK_ALL & ~EHCI_INT_MASK_PORT_CHANGE);
|
||||
|
||||
// Enable interrupts
|
||||
regs->inten = EHCI_INT_MASK_ERROR | EHCI_INT_MASK_PORT_CHANGE | EHCI_INT_MASK_ASYNC_ADVANCE |
|
||||
EHCI_INT_MASK_NXP_PERIODIC | EHCI_INT_MASK_NXP_ASYNC | EHCI_INT_MASK_FRAMELIST_ROLLOVER;
|
||||
regs->inten = EHCI_INT_MASK_USB | EHCI_INT_MASK_ERROR | EHCI_INT_MASK_PORT_CHANGE |
|
||||
EHCI_INT_MASK_ASYNC_ADVANCE | EHCI_INT_MASK_FRAMELIST_ROLLOVER;
|
||||
|
||||
//------------- Asynchronous List -------------//
|
||||
ehci_qhd_t * const async_head = qhd_async_head(rhport);
|
||||
ehci_qhd_t * const async_head = list_get_async_head(rhport);
|
||||
tu_memclr(async_head, sizeof(ehci_qhd_t));
|
||||
|
||||
async_head->next.address = (uint32_t) async_head; // circular list, next is itself
|
||||
async_head->next.type = EHCI_QTYPE_QHD;
|
||||
async_head->head_list_flag = 1;
|
||||
async_head->qtd_overlay.halted = 1; // inactive most of time
|
||||
async_head->qtd_overlay.next.terminate = 1; // TODO removed if verified
|
||||
async_head->next.address = (uint32_t) async_head; // circular list, next is itself
|
||||
async_head->next.type = EHCI_QTYPE_QHD;
|
||||
async_head->head_list_flag = 1;
|
||||
async_head->qtd_overlay.halted = 1; // inactive most of time
|
||||
async_head->qtd_overlay.next.terminate = 1; // TODO removed if verified
|
||||
|
||||
regs->async_list_addr = (uint32_t) async_head;
|
||||
|
||||
@@ -366,8 +332,7 @@ bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg)
|
||||
regs->nxp_tt_control = 0;
|
||||
|
||||
//------------- USB CMD Register -------------//
|
||||
regs->command |= TU_BIT(EHCI_USBCMD_POS_RUN_STOP) | TU_BIT(EHCI_USBCMD_POS_ASYNC_ENABLE) |
|
||||
TU_BIT(EHCI_USBCMD_POS_PERIOD_ENABLE) | // TODO enable period list only there is int/iso endpoint
|
||||
regs->command |= EHCI_USBCMD_RUN_STOP | EHCI_USBCMD_PERIOD_SCHEDULE_ENABLE | EHCI_USBCMD_ASYNC_SCHEDULE_ENABLE |
|
||||
FRAMELIST_SIZE_USBCMD_VALUE;
|
||||
|
||||
//------------- ConfigFlag Register (skip) -------------//
|
||||
@@ -377,7 +342,7 @@ bool ehci_init(uint8_t rhport, uint32_t capability_reg, uint32_t operatial_reg)
|
||||
if (ehci_data.cap_regs->hcsparams_bm.port_power_control) {
|
||||
// mask out all change bits since they are Write 1 to clear
|
||||
uint32_t portsc = (regs->portsc & ~EHCI_PORTSC_MASK_W1C);
|
||||
portsc |= ECHI_PORTSC_MASK_PORT_POWER;
|
||||
portsc |= EHCI_PORTSC_MASK_PORT_POWER;
|
||||
|
||||
regs->portsc = portsc;
|
||||
}
|
||||
@@ -426,11 +391,11 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
|
||||
{
|
||||
case TUSB_XFER_CONTROL:
|
||||
case TUSB_XFER_BULK:
|
||||
list_head = (ehci_link_t*) qhd_async_head(rhport);
|
||||
list_head = (ehci_link_t*) list_get_async_head(rhport);
|
||||
break;
|
||||
|
||||
case TUSB_XFER_INTERRUPT:
|
||||
list_head = get_period_head(rhport, p_qhd->interval_ms);
|
||||
list_head = list_get_period_head(rhport, p_qhd->interval_ms);
|
||||
break;
|
||||
|
||||
case TUSB_XFER_ISOCHRONOUS:
|
||||
@@ -439,10 +404,8 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
TU_ASSERT(list_head);
|
||||
|
||||
// TODO might need to disable async/period list
|
||||
list_insert(list_head, (ehci_link_t*) p_qhd, EHCI_QTYPE_QHD);
|
||||
|
||||
hcd_dcache_clean(p_qhd, sizeof(ehci_qhd_t));
|
||||
@@ -476,20 +439,25 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
|
||||
uint8_t const epnum = tu_edpt_number(ep_addr);
|
||||
uint8_t const dir = tu_edpt_dir(ep_addr);
|
||||
|
||||
ehci_qhd_t* qhd;
|
||||
ehci_qhd_t* qhd = qhd_get_from_addr(dev_addr, ep_addr);
|
||||
ehci_qtd_t* qtd;
|
||||
|
||||
if (epnum == 0) {
|
||||
qhd = qhd_control(dev_addr);
|
||||
qtd = qtd_control(dev_addr);
|
||||
// Control endpoint never be stalled. Skip reset Data Toggle since it is fixed per stage
|
||||
if (qhd->qtd_overlay.halted) {
|
||||
qhd->qtd_overlay.halted = false;
|
||||
}
|
||||
|
||||
qtd = qtd_control(dev_addr);
|
||||
qtd_init(qtd, buffer, buflen);
|
||||
|
||||
// first data toggle is always 1 (data & setup stage)
|
||||
qtd->data_toggle = 1;
|
||||
qtd->pid = dir ? EHCI_PID_IN : EHCI_PID_OUT;
|
||||
} else {
|
||||
qhd = qhd_get_from_addr(dev_addr, ep_addr);
|
||||
// skip if endpoint is halted
|
||||
TU_VERIFY(!qhd->qtd_overlay.halted);
|
||||
|
||||
qtd = qtd_find_free();
|
||||
TU_ASSERT(qtd);
|
||||
|
||||
@@ -510,12 +478,45 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hcd_edpt_clear_stall(uint8_t daddr, uint8_t ep_addr)
|
||||
{
|
||||
bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
||||
(void) rhport;
|
||||
|
||||
// TODO ISO not supported yet
|
||||
ehci_qhd_t* qhd = qhd_get_from_addr(dev_addr, ep_addr);
|
||||
ehci_qtd_t * volatile qtd = qhd->attached_qtd;
|
||||
TU_VERIFY(qtd != NULL); // no queued transfer
|
||||
|
||||
hcd_dcache_invalidate(qtd, sizeof(ehci_qtd_t));
|
||||
TU_VERIFY(qtd->active); // transfer is already complete
|
||||
|
||||
// HC is still processing, disable HC list schedule before making changes
|
||||
bool const is_period = (qhd->interval_ms > 0);
|
||||
|
||||
ehci_disable_schedule(ehci_data.regs, is_period);
|
||||
|
||||
// check active bit again just in case HC has just processed the TD
|
||||
bool const still_active = qtd->active;
|
||||
if (still_active) {
|
||||
// remove TD from QH overlay
|
||||
qhd->qtd_overlay.next.terminate = 1;
|
||||
hcd_dcache_clean(qhd, sizeof(ehci_qhd_t));
|
||||
|
||||
// remove TD from QH software list
|
||||
qhd_remove_qtd(qhd);
|
||||
}
|
||||
|
||||
ehci_enable_schedule(ehci_data.regs, is_period);
|
||||
|
||||
return still_active; // true if removed an active transfer
|
||||
}
|
||||
|
||||
bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t daddr, uint8_t ep_addr) {
|
||||
(void) rhport;
|
||||
ehci_qhd_t *qhd = qhd_get_from_addr(daddr, ep_addr);
|
||||
qhd->qtd_overlay.halted = 0;
|
||||
qhd->qtd_overlay.data_toggle = 0;
|
||||
hcd_dcache_clean_invalidate(qhd, sizeof(ehci_qhd_t));
|
||||
// TODO reset data toggle ?
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -541,71 +542,77 @@ void async_advance_isr(uint8_t rhport)
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline
|
||||
void port_connect_status_change_isr(uint8_t rhport)
|
||||
{
|
||||
void port_connect_status_change_isr(uint8_t rhport) {
|
||||
// NOTE There is an sequence plug->unplug->…..-> plug if device is powering with pre-plugged device
|
||||
if (ehci_data.regs->portsc_bm.current_connect_status)
|
||||
{
|
||||
if ( ehci_data.regs->portsc_bm.current_connect_status ) {
|
||||
hcd_port_reset(rhport);
|
||||
hcd_event_device_attach(rhport, true);
|
||||
}else // device unplugged
|
||||
} else // device unplugged
|
||||
{
|
||||
hcd_event_device_remove(rhport, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Check queue head for potential transfer complete (successful or error)
|
||||
TU_ATTR_ALWAYS_INLINE static inline
|
||||
void qhd_xfer_complete_isr(ehci_qhd_t * qhd) {
|
||||
// examine TD attached to queue head
|
||||
ehci_qtd_t * volatile qtd = (ehci_qtd_t * volatile) qhd->attached_qtd;
|
||||
if (qtd == NULL) return; // no TD attached
|
||||
hcd_dcache_invalidate(qtd, sizeof(ehci_qtd_t));
|
||||
hcd_dcache_invalidate(qhd, sizeof(ehci_qhd_t)); // HC may have updated the overlay
|
||||
volatile ehci_qtd_t *qtd_overlay = &qhd->qtd_overlay;
|
||||
|
||||
// TD is still active, no need to process
|
||||
if (qtd->active) {
|
||||
return;
|
||||
}
|
||||
// process non-active (completed) QHD with attached (scheduled) TD
|
||||
if ( !qtd_overlay->active && qhd->attached_qtd != NULL ) {
|
||||
xfer_result_t xfer_result;
|
||||
|
||||
uint8_t dir = (qtd->pid == EHCI_PID_IN) ? 1 : 0;
|
||||
uint32_t const xferred_bytes = qtd->expected_bytes - qtd->total_bytes;
|
||||
|
||||
// invalidate dcache if IN transfer
|
||||
if (dir == 1 && qhd->attached_buffer != 0 && xferred_bytes > 0) {
|
||||
hcd_dcache_invalidate((void*) qhd->attached_buffer, xferred_bytes);
|
||||
}
|
||||
|
||||
// remove and free TD before invoking callback
|
||||
qhd->attached_qtd = NULL;
|
||||
qhd->attached_buffer = 0;
|
||||
qtd->used = 0; // free QTD
|
||||
|
||||
// notify usbh
|
||||
uint8_t const ep_addr = tu_edpt_addr(qhd->ep_number, dir);
|
||||
hcd_event_xfer_complete(qhd->dev_addr, ep_addr, xferred_bytes, XFER_RESULT_SUCCESS, true);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline
|
||||
void async_list_xfer_complete_isr(ehci_qhd_t * const async_head)
|
||||
{
|
||||
ehci_qhd_t *p_qhd = async_head;
|
||||
do
|
||||
{
|
||||
hcd_dcache_invalidate(p_qhd, sizeof(ehci_qhd_t));
|
||||
|
||||
// halted or error is processed in error isr
|
||||
if ( !p_qhd->qtd_overlay.halted ) {
|
||||
qhd_xfer_complete_isr(p_qhd);
|
||||
if ( qtd_overlay->halted ) {
|
||||
if (qtd_overlay->xact_err || qtd_overlay->err_count == 0 || qtd_overlay->buffer_err || qtd_overlay->babble_err) {
|
||||
// Error count = 0 often occurs when device disconnected, or other bus-related error
|
||||
xfer_result = XFER_RESULT_FAILED;
|
||||
TU_LOG3(" QHD xfer err count: %d\n", qtd_overlay->err_count);
|
||||
// TU_BREAKPOINT(); // TODO skip unplugged device
|
||||
}else {
|
||||
// no error bits are set, endpoint is halted due to STALL
|
||||
xfer_result = XFER_RESULT_STALLED;
|
||||
}
|
||||
} else {
|
||||
xfer_result = XFER_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
p_qhd = qhd_next(p_qhd);
|
||||
}while(p_qhd != async_head); // async list traversal, stop if loop around
|
||||
ehci_qtd_t * volatile qtd = qhd->attached_qtd;
|
||||
hcd_dcache_invalidate(qtd, sizeof(ehci_qtd_t)); // HC may have written back TD
|
||||
|
||||
uint8_t const dir = (qtd->pid == EHCI_PID_IN) ? 1 : 0;
|
||||
uint32_t const xferred_bytes = qtd->expected_bytes - qtd->total_bytes;
|
||||
|
||||
// invalidate dcache if IN transfer with data
|
||||
if (dir == 1 && qhd->attached_buffer != 0 && xferred_bytes > 0) {
|
||||
hcd_dcache_invalidate((void*) qhd->attached_buffer, xferred_bytes);
|
||||
}
|
||||
|
||||
// remove and free TD before invoking callback
|
||||
qhd_remove_qtd(qhd);
|
||||
|
||||
// notify usbh
|
||||
uint8_t const ep_addr = tu_edpt_addr(qhd->ep_number, dir);
|
||||
hcd_event_xfer_complete(qhd->dev_addr, ep_addr, xferred_bytes, xfer_result, true);
|
||||
}
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline
|
||||
void period_list_xfer_complete_isr(uint8_t rhport, uint32_t interval_ms)
|
||||
void proccess_async_xfer_isr(ehci_qhd_t * const list_head)
|
||||
{
|
||||
uint32_t const period_1ms_addr = (uint32_t) get_period_head(rhport, 1u);
|
||||
ehci_link_t next_link = * get_period_head(rhport, interval_ms);
|
||||
ehci_qhd_t *qhd = list_head;
|
||||
|
||||
do {
|
||||
qhd_xfer_complete_isr(qhd);
|
||||
qhd = qhd_next(qhd);
|
||||
} while ( qhd != list_head ); // async list traversal, stop if loop around
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline
|
||||
void process_period_xfer_isr(uint8_t rhport, uint32_t interval_ms)
|
||||
{
|
||||
uint32_t const period_1ms_addr = (uint32_t) list_get_period_head(rhport, 1u);
|
||||
ehci_link_t next_link = *list_get_period_head(rhport, interval_ms);
|
||||
|
||||
while (!next_link.terminate) {
|
||||
if (interval_ms > 1 && period_1ms_addr == tu_align32(next_link.address)) {
|
||||
@@ -618,22 +625,13 @@ void period_list_xfer_complete_isr(uint8_t rhport, uint32_t interval_ms)
|
||||
switch (next_link.type) {
|
||||
case EHCI_QTYPE_QHD: {
|
||||
ehci_qhd_t *qhd = (ehci_qhd_t *) entry_addr;
|
||||
hcd_dcache_invalidate(qhd, sizeof(ehci_qhd_t));
|
||||
|
||||
if (!qhd->qtd_overlay.halted) {
|
||||
qhd_xfer_complete_isr(qhd);
|
||||
}
|
||||
qhd_xfer_complete_isr(qhd);
|
||||
}
|
||||
break;
|
||||
|
||||
// TODO support hs/fs ISO
|
||||
case EHCI_QTYPE_ITD:
|
||||
// TODO support hs ISO
|
||||
break;
|
||||
|
||||
case EHCI_QTYPE_SITD:
|
||||
// TODO support split ISO
|
||||
break;
|
||||
|
||||
case EHCI_QTYPE_FSTN:
|
||||
default:
|
||||
break;
|
||||
@@ -643,108 +641,6 @@ void period_list_xfer_complete_isr(uint8_t rhport, uint32_t interval_ms)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO merge with qhd_xfer_complete_isr()
|
||||
TU_ATTR_ALWAYS_INLINE static inline
|
||||
void qhd_xfer_error_isr(ehci_qhd_t * qhd)
|
||||
{
|
||||
volatile ehci_qtd_t *qtd_overlay = &qhd->qtd_overlay;
|
||||
|
||||
// TD has error
|
||||
if (qtd_overlay->halted) {
|
||||
xfer_result_t xfer_result;
|
||||
|
||||
if (qtd_overlay->xact_err || qtd_overlay->err_count == 0 || qtd_overlay->buffer_err || qtd_overlay->babble_err) {
|
||||
// Error count = 0 often occurs when device disconnected, or other bus-related error
|
||||
xfer_result = XFER_RESULT_FAILED;
|
||||
}else {
|
||||
// no error bits are set, endpoint is halted due to STALL
|
||||
xfer_result = XFER_RESULT_STALLED;
|
||||
}
|
||||
|
||||
// if (XFER_RESULT_FAILED == xfer_result ) {
|
||||
// TU_LOG1(" QHD xfer err count: %d\n", qtd_overlay->err_count);
|
||||
// TU_BREAKPOINT(); // TODO skip unplugged device
|
||||
// }
|
||||
|
||||
ehci_qtd_t * volatile qtd = (ehci_qtd_t * volatile) qhd->attached_qtd;
|
||||
TU_ASSERT(qtd, ); // No TD yet, probably a race condition or cache issue !?
|
||||
|
||||
hcd_dcache_invalidate(qtd, sizeof(ehci_qtd_t));
|
||||
|
||||
uint8_t dir = (qtd->pid == EHCI_PID_IN) ? 1 : 0;
|
||||
uint32_t const xferred_bytes = qtd->expected_bytes - qtd->total_bytes;
|
||||
|
||||
// invalidate dcache if IN transfer
|
||||
if (dir == 1 && qhd->attached_buffer != 0 && xferred_bytes > 0) {
|
||||
hcd_dcache_invalidate((void*) qhd->attached_buffer, xferred_bytes);
|
||||
}
|
||||
|
||||
// remove and free TD before invoking callback
|
||||
qhd->attached_qtd = NULL;
|
||||
qhd->attached_buffer = 0;
|
||||
qtd->used = 0; // free QTD
|
||||
|
||||
if (0 == qhd->ep_number ) {
|
||||
// control cannot be halted
|
||||
qhd->qtd_overlay.next.terminate = 1;
|
||||
qhd->qtd_overlay.alternate.terminate = 1;
|
||||
qhd->qtd_overlay.halted = 0;
|
||||
|
||||
hcd_dcache_clean(qhd, sizeof(ehci_qhd_t));
|
||||
}
|
||||
|
||||
// notify usbh
|
||||
uint8_t const ep_addr = tu_edpt_addr(qhd->ep_number, dir);
|
||||
hcd_event_xfer_complete(qhd->dev_addr, ep_addr, xferred_bytes, xfer_result, true);
|
||||
}
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline
|
||||
void xfer_error_isr(uint8_t rhport)
|
||||
{
|
||||
//------------- async list -------------//
|
||||
ehci_qhd_t * const async_head = qhd_async_head(rhport);
|
||||
ehci_qhd_t *p_qhd = async_head;
|
||||
do
|
||||
{
|
||||
hcd_dcache_invalidate(p_qhd, sizeof(ehci_qhd_t));
|
||||
qhd_xfer_error_isr( p_qhd );
|
||||
p_qhd = qhd_next(p_qhd);
|
||||
}while(p_qhd != async_head); // async list traversal, stop if loop around
|
||||
|
||||
//------------- TODO refractor period list -------------//
|
||||
uint32_t const period_1ms_addr = (uint32_t) get_period_head(rhport, 1u);
|
||||
for (uint32_t interval_ms=1; interval_ms <= FRAMELIST_SIZE; interval_ms *= 2)
|
||||
{
|
||||
ehci_link_t next_item = * get_period_head(rhport, interval_ms);
|
||||
|
||||
// TODO abstract max loop guard for period
|
||||
while( !next_item.terminate &&
|
||||
!(interval_ms > 1 && period_1ms_addr == tu_align32(next_item.address)) )
|
||||
{
|
||||
switch ( next_item.type )
|
||||
{
|
||||
case EHCI_QTYPE_QHD:
|
||||
{
|
||||
ehci_qhd_t *p_qhd_int = (ehci_qhd_t *) tu_align32(next_item.address);
|
||||
hcd_dcache_invalidate(p_qhd_int, sizeof(ehci_qhd_t));
|
||||
|
||||
qhd_xfer_error_isr(p_qhd_int);
|
||||
}
|
||||
break;
|
||||
|
||||
// TODO support hs/fs ISO
|
||||
case EHCI_QTYPE_ITD:
|
||||
case EHCI_QTYPE_SITD:
|
||||
case EHCI_QTYPE_FSTN:
|
||||
default: break;
|
||||
}
|
||||
|
||||
next_item = *list_next(&next_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------- Host Controller Driver's Interrupt Handler -------------//
|
||||
void hcd_int_handler(uint8_t rhport)
|
||||
{
|
||||
@@ -776,29 +672,16 @@ void hcd_int_handler(uint8_t rhport)
|
||||
regs->status = EHCI_INT_MASK_PORT_CHANGE; // Acknowledge
|
||||
}
|
||||
|
||||
if (int_status & EHCI_INT_MASK_ERROR) {
|
||||
xfer_error_isr(rhport);
|
||||
regs->status = EHCI_INT_MASK_ERROR; // Acknowledge
|
||||
}
|
||||
// A USB transfer is completed (OK or error)
|
||||
uint32_t const usb_int = int_status & (EHCI_INT_MASK_USB | EHCI_INT_MASK_ERROR);
|
||||
if (usb_int) {
|
||||
proccess_async_xfer_isr(list_get_async_head(rhport));
|
||||
|
||||
//------------- some QTD/SITD/ITD with IOC set is completed -------------//
|
||||
if (int_status & EHCI_INT_MASK_NXP_ASYNC) {
|
||||
async_list_xfer_complete_isr(qhd_async_head(rhport));
|
||||
regs->status = EHCI_INT_MASK_NXP_ASYNC; // Acknowledge
|
||||
}
|
||||
|
||||
if (int_status & EHCI_INT_MASK_NXP_PERIODIC)
|
||||
{
|
||||
for (uint32_t i=1; i <= FRAMELIST_SIZE; i *= 2)
|
||||
{
|
||||
period_list_xfer_complete_isr(rhport, i);
|
||||
for ( uint32_t i = 1; i <= FRAMELIST_SIZE; i *= 2 ) {
|
||||
process_period_xfer_isr(rhport, i);
|
||||
}
|
||||
regs->status = EHCI_INT_MASK_NXP_PERIODIC; // Acknowledge
|
||||
}
|
||||
|
||||
if (int_status & EHCI_INT_MASK_USB) {
|
||||
// TODO standard EHCI xfer complete
|
||||
regs->status = EHCI_INT_MASK_USB; // Acknowledge
|
||||
regs->status = usb_int; // Acknowledge
|
||||
}
|
||||
|
||||
//------------- There is some removed async previously -------------//
|
||||
@@ -810,35 +693,103 @@ void hcd_int_handler(uint8_t rhport)
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// HELPER
|
||||
// List Managing Helper
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Get head of periodic list
|
||||
TU_ATTR_ALWAYS_INLINE static inline ehci_link_t* list_get_period_head(uint8_t rhport, uint32_t interval_ms) {
|
||||
(void) rhport;
|
||||
return (ehci_link_t*) &ehci_data.period_head_arr[ tu_log2( tu_min32(FRAMELIST_SIZE, interval_ms) ) ];
|
||||
}
|
||||
|
||||
//------------- queue head helper -------------//
|
||||
static inline ehci_qhd_t* qhd_find_free (void)
|
||||
// Get head of async list
|
||||
TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* list_get_async_head(uint8_t rhport) {
|
||||
(void) rhport;
|
||||
return qhd_control(0); // control qhd of dev0 is used as async head
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline ehci_link_t* list_next(ehci_link_t const *p_link) {
|
||||
return (ehci_link_t*) tu_align32(p_link->address);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline void list_insert(ehci_link_t *current, ehci_link_t *new, uint8_t new_type)
|
||||
{
|
||||
for (uint32_t i=0; i<QHD_MAX; i++)
|
||||
{
|
||||
new->address = current->address;
|
||||
current->address = ((uint32_t) new) | (new_type << 1);
|
||||
}
|
||||
|
||||
// Remove all queue head belong to this device address
|
||||
static void list_remove_qhd_by_daddr(ehci_link_t* list_head, uint8_t dev_addr) {
|
||||
ehci_link_t* prev = list_head;
|
||||
|
||||
while (prev && !prev->terminate) {
|
||||
ehci_qhd_t* qhd = (ehci_qhd_t*) (uintptr_t) list_next(prev);
|
||||
|
||||
// done if loop back to head
|
||||
if ( (uintptr_t) qhd == (uintptr_t) list_head) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ( qhd->dev_addr == dev_addr ) {
|
||||
// TODO deactivate all TD, wait for QHD to inactive before removal
|
||||
prev->address = qhd->next.address;
|
||||
|
||||
// EHCI 4.8.2 link the removed qhd's next to async head (which always reachable by Host Controller)
|
||||
qhd->next.address = ((uint32_t) list_head) | (EHCI_QTYPE_QHD << 1);
|
||||
|
||||
if ( qhd->int_smask )
|
||||
{
|
||||
// period list queue element is guarantee to be free in the next frame (1 ms)
|
||||
qhd->used = 0;
|
||||
}else
|
||||
{
|
||||
// async list use async advance handshake
|
||||
// mark as removing, will completely re-usable when async advance isr occurs
|
||||
qhd->removing = 1;
|
||||
}
|
||||
|
||||
hcd_dcache_clean(qhd, sizeof(ehci_qhd_t));
|
||||
hcd_dcache_clean(prev, sizeof(ehci_qhd_t));
|
||||
}else {
|
||||
prev = list_next(prev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Queue Header helper
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Get queue head for control transfer (always available)
|
||||
TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t* qhd_control(uint8_t dev_addr) {
|
||||
return &ehci_data.control[dev_addr].qhd;
|
||||
}
|
||||
|
||||
// Find a free queue head
|
||||
TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t *qhd_find_free(void) {
|
||||
for ( uint32_t i = 0; i < QHD_MAX; i++ ) {
|
||||
if ( !ehci_data.qhd_pool[i].used ) return &ehci_data.qhd_pool[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline ehci_qhd_t* qhd_next(ehci_qhd_t const * p_qhd)
|
||||
{
|
||||
return (ehci_qhd_t*) tu_align32(p_qhd->next.address);
|
||||
// Next queue head link
|
||||
TU_ATTR_ALWAYS_INLINE static inline ehci_qhd_t *qhd_next(ehci_qhd_t const *p_qhd) {
|
||||
return (ehci_qhd_t *) tu_align32(p_qhd->next.address);
|
||||
}
|
||||
|
||||
static inline ehci_qhd_t* qhd_get_from_addr(uint8_t dev_addr, uint8_t ep_addr)
|
||||
{
|
||||
ehci_qhd_t* qhd_pool = ehci_data.qhd_pool;
|
||||
// Get queue head from device + endpoint address
|
||||
static ehci_qhd_t *qhd_get_from_addr(uint8_t dev_addr, uint8_t ep_addr) {
|
||||
if ( 0 == tu_edpt_number(ep_addr) ) {
|
||||
return qhd_control(dev_addr);
|
||||
}
|
||||
|
||||
for(uint32_t i=0; i<QHD_MAX; i++)
|
||||
{
|
||||
ehci_qhd_t *qhd_pool = ehci_data.qhd_pool;
|
||||
|
||||
for ( uint32_t i = 0; i < QHD_MAX; i++ ) {
|
||||
if ( (qhd_pool[i].dev_addr == dev_addr) &&
|
||||
ep_addr == tu_edpt_addr(qhd_pool[i].ep_number, qhd_pool[i].pid) )
|
||||
{
|
||||
ep_addr == tu_edpt_addr(qhd_pool[i].ep_number, qhd_pool[i].pid) ) {
|
||||
return &qhd_pool[i];
|
||||
}
|
||||
}
|
||||
@@ -846,6 +797,7 @@ static inline ehci_qhd_t* qhd_get_from_addr(uint8_t dev_addr, uint8_t ep_addr)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Init queue head with endpoint descriptor
|
||||
static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc)
|
||||
{
|
||||
// address 0 is used as async head, which always on the list --> cannot be cleared (ehci halted otherwise)
|
||||
@@ -920,6 +872,7 @@ static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t c
|
||||
}
|
||||
}
|
||||
|
||||
// Attach a TD to queue head
|
||||
static void qhd_attach_qtd(ehci_qhd_t *qhd, ehci_qtd_t *qtd) {
|
||||
qhd->attached_qtd = qtd;
|
||||
qhd->attached_buffer = qtd->buffer[0];
|
||||
@@ -931,17 +884,35 @@ static void qhd_attach_qtd(ehci_qhd_t *qhd, ehci_qtd_t *qtd) {
|
||||
hcd_dcache_clean_invalidate(qhd, sizeof(ehci_qhd_t));
|
||||
}
|
||||
|
||||
// Remove an attached TD from queue head
|
||||
static void qhd_remove_qtd(ehci_qhd_t *qhd) {
|
||||
ehci_qtd_t * volatile qtd = qhd->attached_qtd;
|
||||
|
||||
//------------- TD helper -------------//
|
||||
static inline ehci_qtd_t *qtd_find_free(void) {
|
||||
qhd->attached_qtd = NULL;
|
||||
qhd->attached_buffer = 0;
|
||||
hcd_dcache_clean(qhd, sizeof(ehci_qhd_t));
|
||||
|
||||
qtd->used = 0; // free QTD
|
||||
hcd_dcache_clean(qtd, sizeof(ehci_qtd_t));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Queue TD helper
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
// Get TD for control transfer (always available)
|
||||
TU_ATTR_ALWAYS_INLINE static inline ehci_qtd_t* qtd_control(uint8_t dev_addr) {
|
||||
return &ehci_data.control[dev_addr].qtd;
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline ehci_qtd_t *qtd_find_free(void) {
|
||||
for (uint32_t i = 0; i < QTD_MAX; i++) {
|
||||
if (!ehci_data.qtd_pool[i].used) return &ehci_data.qtd_pool[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void qtd_init(ehci_qtd_t* qtd, void const* buffer, uint16_t total_bytes)
|
||||
{
|
||||
static void qtd_init(ehci_qtd_t* qtd, void const* buffer, uint16_t total_bytes) {
|
||||
tu_memclr(qtd, sizeof(ehci_qtd_t));
|
||||
qtd->used = 1;
|
||||
|
||||
@@ -955,24 +926,9 @@ static void qtd_init(ehci_qtd_t* qtd, void const* buffer, uint16_t total_bytes)
|
||||
qtd->expected_bytes = total_bytes;
|
||||
|
||||
qtd->buffer[0] = (uint32_t) buffer;
|
||||
for(uint8_t i=1; i<5; i++)
|
||||
{
|
||||
for(uint8_t i=1; i<5; i++) {
|
||||
qtd->buffer[i] |= tu_align4k(qtd->buffer[i - 1] ) + 4096;
|
||||
}
|
||||
}
|
||||
|
||||
//------------- List Managing Helper -------------//
|
||||
|
||||
// insert at head
|
||||
static inline void list_insert(ehci_link_t *current, ehci_link_t *new, uint8_t new_type)
|
||||
{
|
||||
new->address = current->address;
|
||||
current->address = ((uint32_t) new) | (new_type << 1);
|
||||
}
|
||||
|
||||
static inline ehci_link_t* list_next(ehci_link_t const *p_link)
|
||||
{
|
||||
return (ehci_link_t*) tu_align32(p_link->address);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -278,23 +278,24 @@ enum {
|
||||
EHCI_INT_MASK_PERIODIC_SCHED_STATUS = TU_BIT(14),
|
||||
EHCI_INT_MASK_ASYNC_SCHED_STATUS = TU_BIT(15),
|
||||
|
||||
EHCI_INT_MASK_NXP_ASYNC = TU_BIT(18),
|
||||
EHCI_INT_MASK_NXP_PERIODIC = TU_BIT(19),
|
||||
|
||||
EHCI_INT_MASK_ALL =
|
||||
EHCI_INT_MASK_USB | EHCI_INT_MASK_ERROR | EHCI_INT_MASK_PORT_CHANGE |
|
||||
EHCI_INT_MASK_FRAMELIST_ROLLOVER | EHCI_INT_MASK_PCI_HOST_SYSTEM_ERROR |
|
||||
EHCI_INT_MASK_ASYNC_ADVANCE | EHCI_INT_MASK_NXP_SOF |
|
||||
EHCI_INT_MASK_NXP_ASYNC | EHCI_INT_MASK_NXP_PERIODIC
|
||||
EHCI_INT_MASK_ASYNC_ADVANCE | EHCI_INT_MASK_NXP_SOF
|
||||
};
|
||||
|
||||
enum {
|
||||
EHCI_USBCMD_POS_RUN_STOP = 0,
|
||||
EHCI_USBCMD_POS_FRAMELIST_SIZE = 2,
|
||||
EHCI_USBCMD_POS_PERIOD_ENABLE = 4,
|
||||
EHCI_USBCMD_POS_ASYNC_ENABLE = 5,
|
||||
EHCI_USBCMD_POS_NXP_FRAMELIST_SIZE_MSB = 15,
|
||||
EHCI_USBCMD_POS_INTERRUPT_THRESHOLD = 16
|
||||
EHCI_USBCMD_FRAMELIST_SIZE_SHIFT = 2, // [2..3]
|
||||
EHCI_USBCMD_CHIPIDEA_FRAMELIST_SIZE_MSB_SHIFT = 15,
|
||||
EHCI_USBCMD_INTERRUPT_THRESHOLD_SHIFT = 16
|
||||
};
|
||||
|
||||
enum {
|
||||
EHCI_USBCMD_RUN_STOP = TU_BIT(0), // [0..0] 1 = Run, 0 = Stop
|
||||
EHCI_USBCMD_HCRESET = TU_BIT(1), // [1..1] SW write 1 to reset HC, clear by HC when complete
|
||||
EHCI_USBCMD_PERIOD_SCHEDULE_ENABLE = TU_BIT(4), // [4..4] Enable periodic schedule
|
||||
EHCI_USBCMD_ASYNC_SCHEDULE_ENABLE = TU_BIT(5), // [5..5] Enable async schedule
|
||||
EHCI_USBCMD_INTR_ON_ASYNC_ADVANCE_DOORBELL = TU_BIT(6), // [6..6] Tell HC to interrupt next time it advances async list. Clear by HC
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -306,7 +307,7 @@ enum {
|
||||
EHCI_PORTSC_MASK_FORCE_RESUME = TU_BIT(6),
|
||||
EHCI_PORTSC_MASK_PORT_SUSPEND = TU_BIT(7),
|
||||
EHCI_PORTSC_MASK_PORT_RESET = TU_BIT(8),
|
||||
ECHI_PORTSC_MASK_PORT_POWER = TU_BIT(12),
|
||||
EHCI_PORTSC_MASK_PORT_POWER = TU_BIT(12),
|
||||
|
||||
EHCI_PORTSC_MASK_W1C =
|
||||
EHCI_PORTSC_MASK_CONNECT_STATUS_CHANGE |
|
||||
|
||||
@@ -822,9 +822,17 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *b
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
||||
(void) rhport;
|
||||
(void) dev_addr;
|
||||
(void) ep_addr;
|
||||
// TODO not implemented yet
|
||||
return false;
|
||||
}
|
||||
|
||||
// clear stall, data toggle is also reset to DATA0
|
||||
bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr)
|
||||
{
|
||||
bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
||||
(void) rhport;
|
||||
unsigned const pipenum = find_pipe(dev_addr, ep_addr);
|
||||
if (!pipenum) return false;
|
||||
hw_endpoint_t volatile *regs = edpt_regs(pipenum - 1);
|
||||
|
||||
@@ -189,7 +189,7 @@ typedef struct
|
||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
// BDT(Buffer Descriptor Table) must be 256-byte aligned
|
||||
CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) volatile static dcd_data_t _dcd;
|
||||
CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(512) volatile static dcd_data_t _dcd;
|
||||
|
||||
#if TU_PIC_INT_SIZE == 4
|
||||
TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" );
|
||||
|
||||
@@ -77,7 +77,7 @@ static tusb_speed_t get_speed(void);
|
||||
static void dcd_transmit_packet(xfer_ctl_t * xfer, uint8_t ep_ix);
|
||||
|
||||
// DMA descriptors shouldn't be placed in ITCM !
|
||||
CFG_TUSB_MEM_SECTION static dma_desc_t dma_desc[6];
|
||||
CFG_TUD_MEM_SECTION static dma_desc_t dma_desc[6];
|
||||
|
||||
static xfer_ctl_t xfer_status[EP_MAX];
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ typedef struct
|
||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
// BDT(Buffer Descriptor Table) must be 256-byte aligned
|
||||
CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd;
|
||||
CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd;
|
||||
|
||||
TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" );
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ typedef struct
|
||||
// INTERNAL OBJECT & FUNCTION DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
// BDT(Buffer Descriptor Table) must be 256-byte aligned
|
||||
CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd;
|
||||
CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd;
|
||||
|
||||
TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" );
|
||||
|
||||
|
||||
@@ -562,8 +562,16 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr)
|
||||
{
|
||||
bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
||||
(void) rhport;
|
||||
(void) dev_addr;
|
||||
(void) ep_addr;
|
||||
// TODO not implemented yet
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
||||
(void) rhport;
|
||||
if (!tu_edpt_number(ep_addr)) return true;
|
||||
int num = find_pipe(dev_addr, ep_addr);
|
||||
if (num < 0) return false;
|
||||
|
||||
@@ -92,7 +92,7 @@ typedef struct
|
||||
|
||||
} dcd_data_t;
|
||||
|
||||
CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(128) static dcd_data_t _dcd;
|
||||
CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(128) static dcd_data_t _dcd;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
|
||||
@@ -176,11 +176,11 @@ typedef struct
|
||||
// EP list must be 256-byte aligned
|
||||
// Some MCU controller may require this variable to be placed in specific SRAM region.
|
||||
// For example: LPC55s69 port1 Highspeed must be USB_RAM (0x40100000)
|
||||
// Use CFG_TUSB_MEM_SECTION to place it accordingly.
|
||||
CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(256) static dcd_data_t _dcd;
|
||||
// Use CFG_TUD_MEM_SECTION to place it accordingly.
|
||||
CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(256) static dcd_data_t _dcd;
|
||||
|
||||
// Dummy buffer to fix ZLPs overwriting the buffer (probably an USB/DMA controller bug)
|
||||
CFG_TUSB_MEM_SECTION TU_ATTR_ALIGNED(64) static uint8_t dummy[8];
|
||||
CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(64) static uint8_t dummy[8];
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// Multiple Controllers
|
||||
|
||||
@@ -341,19 +341,24 @@ static void ed_init(ohci_ed_t *p_ed, uint8_t dev_addr, uint16_t ep_size, uint8_t
|
||||
p_ed->is_interrupt_xfer = (xfer_type == TUSB_XFER_INTERRUPT ? 1 : 0);
|
||||
}
|
||||
|
||||
static void gtd_init(ohci_gtd_t* p_td, uint8_t* data_ptr, uint16_t total_bytes)
|
||||
{
|
||||
static void gtd_init(ohci_gtd_t *p_td, uint8_t *data_ptr, uint16_t total_bytes) {
|
||||
tu_memclr(p_td, sizeof(ohci_gtd_t));
|
||||
|
||||
p_td->used = 1;
|
||||
p_td->expected_bytes = total_bytes;
|
||||
p_td->used = 1;
|
||||
p_td->expected_bytes = total_bytes;
|
||||
|
||||
p_td->buffer_rounding = 1; // less than queued length is not a error
|
||||
p_td->delay_interrupt = OHCI_INT_ON_COMPLETE_NO;
|
||||
p_td->condition_code = OHCI_CCODE_NOT_ACCESSED;
|
||||
p_td->buffer_rounding = 1; // less than queued length is not a error
|
||||
p_td->delay_interrupt = OHCI_INT_ON_COMPLETE_NO;
|
||||
p_td->condition_code = OHCI_CCODE_NOT_ACCESSED;
|
||||
|
||||
p_td->current_buffer_pointer = _phys_addr(data_ptr);
|
||||
p_td->buffer_end = total_bytes ? (_phys_addr(data_ptr + total_bytes - 1)) : (uint8_t *)p_td->current_buffer_pointer;
|
||||
uint8_t *cbp = (uint8_t *) _phys_addr(data_ptr);
|
||||
|
||||
p_td->current_buffer_pointer = cbp;
|
||||
if ( total_bytes ) {
|
||||
p_td->buffer_end = _phys_addr(data_ptr + total_bytes - 1);
|
||||
} else {
|
||||
p_td->buffer_end = cbp;
|
||||
}
|
||||
}
|
||||
|
||||
static ohci_ed_t * ed_from_addr(uint8_t dev_addr, uint8_t ep_addr)
|
||||
@@ -487,7 +492,7 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet
|
||||
ohci_ed_t* ed = &ohci_data.control[dev_addr].ed;
|
||||
ohci_gtd_t *qtd = &ohci_data.control[dev_addr].gtd;
|
||||
|
||||
gtd_init(qtd, (uint8_t*) setup_packet, 8);
|
||||
gtd_init(qtd, (uint8_t*)(uintptr_t) setup_packet, 8);
|
||||
qtd->index = dev_addr;
|
||||
qtd->pid = PID_SETUP;
|
||||
qtd->data_toggle = GTD_DT_DATA0;
|
||||
@@ -543,8 +548,16 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr)
|
||||
{
|
||||
bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
||||
(void) rhport;
|
||||
(void) dev_addr;
|
||||
(void) ep_addr;
|
||||
// TODO not implemented yet
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
||||
(void) rhport;
|
||||
ohci_ed_t * const p_ed = ed_from_addr(dev_addr, ep_addr);
|
||||
|
||||
p_ed->is_stalled = 0;
|
||||
|
||||
@@ -105,7 +105,7 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr)
|
||||
uint32_t hcd_frame_number(uint8_t rhport)
|
||||
{
|
||||
(void) rhport;
|
||||
return 0;
|
||||
return pio_usb_host_get_frame_number();
|
||||
}
|
||||
|
||||
void hcd_int_enable(uint8_t rhport)
|
||||
@@ -138,6 +138,11 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
|
||||
return pio_usb_host_endpoint_transfer(pio_rhport, dev_addr, ep_addr, buffer, buflen);
|
||||
}
|
||||
|
||||
bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
||||
uint8_t const pio_rhport = RHPORT_PIO(rhport);
|
||||
return pio_usb_host_endpoint_abort_transfer(pio_rhport, dev_addr, ep_addr);
|
||||
}
|
||||
|
||||
bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8])
|
||||
{
|
||||
uint8_t const pio_rhport = RHPORT_PIO(rhport);
|
||||
@@ -158,8 +163,8 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet
|
||||
// return busy;
|
||||
//}
|
||||
|
||||
bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr)
|
||||
{
|
||||
bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
||||
(void) rhport;
|
||||
(void) dev_addr;
|
||||
(void) ep_addr;
|
||||
|
||||
|
||||
@@ -576,6 +576,14 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
||||
(void) rhport;
|
||||
(void) dev_addr;
|
||||
(void) ep_addr;
|
||||
// TODO not implemented yet
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8])
|
||||
{
|
||||
(void) rhport;
|
||||
@@ -617,8 +625,8 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet
|
||||
return true;
|
||||
}
|
||||
|
||||
bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr)
|
||||
{
|
||||
bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
||||
(void) rhport;
|
||||
(void) dev_addr;
|
||||
(void) ep_addr;
|
||||
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
#error "Unsupported MCU"
|
||||
#endif
|
||||
|
||||
#define TU_RUSB2_DCD_DBG 0
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO TYPEDEF CONSTANT ENUM
|
||||
//--------------------------------------------------------------------+
|
||||
@@ -444,7 +446,7 @@ static bool process_pipe_xfer(int buffer_type, uint8_t ep_addr, void* buffer, ui
|
||||
*ctr = RUSB2_PIPE_CTR_PID_BUF;
|
||||
}
|
||||
}
|
||||
// TU_LOG1("X %x %d %d\r\n", ep_addr, total_bytes, buffer_type);
|
||||
TU_LOG(TU_RUSB2_DCD_DBG ,"X %x %d %d\r\n", ep_addr, total_bytes, buffer_type);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -487,7 +489,7 @@ static void process_pipe_brdy(uint8_t rhport, unsigned num)
|
||||
dcd_event_xfer_complete(rhport, pipe->ep,
|
||||
pipe->length - pipe->remaining,
|
||||
XFER_RESULT_SUCCESS, true);
|
||||
// TU_LOG1("C %d %d\r\n", num, pipe->length - pipe->remaining);
|
||||
TU_LOG(TU_RUSB2_DCD_DBG, "C %d %d\r\n", num, pipe->length - pipe->remaining);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -691,7 +693,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
|
||||
if (dir || (xfer != TUSB_XFER_BULK)) {
|
||||
*ctr = RUSB2_PIPE_CTR_PID_BUF;
|
||||
}
|
||||
// TU_LOG1("O %d %x %x\r\n", RUSB2->PIPESEL, RUSB2->PIPECFG, RUSB2->PIPEMAXP);
|
||||
TU_LOG(TU_RUSB2_DCD_DBG, "O %d %x %x\r\n", RUSB2->PIPESEL, RUSB2->PIPECFG, RUSB2->PIPEMAXP);
|
||||
dcd_int_enable(rhport);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
#error "Unsupported MCU"
|
||||
#endif
|
||||
|
||||
#define TU_RUSB2_HCD_DBG 0
|
||||
|
||||
//--------------------------------------------------------------------+
|
||||
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
|
||||
//--------------------------------------------------------------------+
|
||||
@@ -116,7 +118,7 @@ static unsigned find_pipe(unsigned xfer)
|
||||
for (int i = 3; i <= 5; ++i) {
|
||||
if (0 == _hcd.pipe[i].ep) return i;
|
||||
}
|
||||
for (int i = 1; i <= 1; ++i) {
|
||||
for (int i = 1; i <= 2; ++i) {
|
||||
if (0 == _hcd.pipe[i].ep) return i;
|
||||
}
|
||||
break;
|
||||
@@ -409,10 +411,11 @@ static void process_pipe_nrdy(uint8_t rhport, unsigned num)
|
||||
(void)rhport;
|
||||
xfer_result_t result;
|
||||
uint16_t volatile *ctr = get_pipectr(num);
|
||||
// TU_LOG1("NRDY %d %x\n", num, *ctr);
|
||||
TU_LOG(TU_RUSB2_HCD_DBG, "NRDY %d %x\n", num, *ctr);
|
||||
switch (*ctr & RUSB2_PIPE_CTR_PID_Msk) {
|
||||
default: return;
|
||||
case RUSB2_PIPE_CTR_PID_STALL: result = XFER_RESULT_STALLED; break;
|
||||
case RUSB2_PIPE_CTR_PID_STALL2: result = XFER_RESULT_STALLED; break;
|
||||
case RUSB2_PIPE_CTR_PID_NAK: result = XFER_RESULT_FAILED; break;
|
||||
}
|
||||
pipe_state_t *pipe = &_hcd.pipe[num];
|
||||
@@ -441,7 +444,7 @@ static void process_pipe_brdy(uint8_t rhport, unsigned num)
|
||||
hcd_event_xfer_complete(pipe->dev, pipe->ep,
|
||||
pipe->length - pipe->remaining,
|
||||
XFER_RESULT_SUCCESS, true);
|
||||
// TU_LOG1("C %d %d\r\n", num, pipe->length - pipe->remaining);
|
||||
TU_LOG(TU_RUSB2_HCD_DBG, "C %d %d\r\n", num, pipe->length - pipe->remaining);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -586,7 +589,7 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr)
|
||||
uint8_t *ep = &_hcd.ep[dev_addr - 1][0][0];
|
||||
for (int i = 0; i < 2 * 15; ++i, ++ep) {
|
||||
unsigned num = *ep;
|
||||
if (!num || dev_addr != _hcd.pipe[num].dev) continue;
|
||||
if (!num || (dev_addr != _hcd.pipe[num].dev)) continue;
|
||||
|
||||
ctr = (uint16_t volatile*)&RUSB2->PIPE_CTR[num - 1];
|
||||
*ctr = 0;
|
||||
@@ -608,7 +611,7 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr)
|
||||
bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8])
|
||||
{
|
||||
(void)rhport;
|
||||
// TU_LOG1("S %d %x\n", dev_addr, RUSB2->DCPCTR);
|
||||
TU_LOG(TU_RUSB2_HCD_DBG, "S %d %x\n", dev_addr, RUSB2->DCPCTR);
|
||||
|
||||
TU_ASSERT(dev_addr < 6); /* USBa can only handle addresses from 0 to 5. */
|
||||
TU_ASSERT(0 == RUSB2->DCPCTR_b.SUREQ);
|
||||
@@ -701,14 +704,22 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *b
|
||||
{
|
||||
bool r;
|
||||
hcd_int_disable(rhport);
|
||||
// TU_LOG1("X %d %x %u\n", dev_addr, ep_addr, buflen);
|
||||
TU_LOG(TU_RUSB2_HCD_DBG, "X %d %x %u\n", dev_addr, ep_addr, buflen);
|
||||
r = process_edpt_xfer(dev_addr, ep_addr, buffer, buflen);
|
||||
hcd_int_enable(rhport);
|
||||
return r;
|
||||
}
|
||||
|
||||
bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr)
|
||||
{
|
||||
bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
||||
(void) rhport;
|
||||
(void) dev_addr;
|
||||
(void) ep_addr;
|
||||
// TODO not implemented yet
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
|
||||
(void) rhport;
|
||||
uint16_t volatile *ctr = addr_to_pipectr(dev_addr, ep_addr);
|
||||
TU_ASSERT(ctr);
|
||||
|
||||
@@ -745,7 +756,7 @@ void hcd_int_handler(uint8_t rhport)
|
||||
/* clear active bits except VALID (don't write 0 to already cleared bits according to the HW manual) */
|
||||
RUSB2->INTSTS1 = ~((RUSB2_INTSTS1_SACK_Msk | RUSB2_INTSTS1_SIGN_Msk | RUSB2_INTSTS1_ATTCH_Msk | RUSB2_INTSTS1_DTCH_Msk) & is1);
|
||||
RUSB2->INTSTS0 = ~((RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_NRDY_Msk | RUSB2_INTSTS0_BEMP_Msk) & is0);
|
||||
// TU_LOG1("IS %04x %04x\n", is0, is1);
|
||||
TU_LOG(TU_RUSB2_HCD_DBG, "IS %04x %04x\n", is0, is1);
|
||||
is1 &= RUSB2->INTENB1;
|
||||
is0 &= RUSB2->INTENB0;
|
||||
|
||||
|
||||
@@ -31,9 +31,22 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wstrict-prototypes"
|
||||
#pragma GCC diagnostic ignored "-Wundef"
|
||||
|
||||
// extra push due to https://github.com/renesas/fsp/pull/278
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
|
||||
/* renesas fsp api */
|
||||
#include "bsp_api.h"
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#define RUSB2_REG_BASE (0x40090000)
|
||||
|
||||
#if defined(__ICCARM__)
|
||||
|
||||
@@ -1568,6 +1568,7 @@ TU_ATTR_BIT_FIELD_ORDER_END
|
||||
#define RUSB2_PIPE_CTR_PID_NAK (0U << RUSB2_PIPE_CTR_PID_Pos) /* NAK response */
|
||||
#define RUSB2_PIPE_CTR_PID_BUF (1U << RUSB2_PIPE_CTR_PID_Pos) /* BUF response (depends buffer state) */
|
||||
#define RUSB2_PIPE_CTR_PID_STALL (2U << RUSB2_PIPE_CTR_PID_Pos) /* STALL response */
|
||||
#define RUSB2_PIPE_CTR_PID_STALL2 (3U << RUSB2_PIPE_CTR_PID_Pos) /* Also STALL response */
|
||||
|
||||
#define RUSB2_DVSTCTR0_RHST_LS (1U << RUSB2_DVSTCTR0_RHST_Pos) /* Low-speed connection */
|
||||
#define RUSB2_DVSTCTR0_RHST_FS (2U << RUSB2_DVSTCTR0_RHST_Pos) /* Full-speed connection */
|
||||
|
||||
@@ -295,15 +295,14 @@
|
||||
#define CFG_TUSB_DEBUG 0
|
||||
#endif
|
||||
|
||||
// TODO MEM_SECTION can be different for host and device controller
|
||||
// should use CFG_TUD_MEM_SECTION, CFG_TUH_MEM_SECTION
|
||||
// Memory section for placing buffer used for usb transferring. If MEM_SECTION is different for
|
||||
// host and device use: CFG_TUD_MEM_SECTION, CFG_TUH_MEM_SECTION instead
|
||||
#ifndef CFG_TUSB_MEM_SECTION
|
||||
#define CFG_TUSB_MEM_SECTION
|
||||
#endif
|
||||
|
||||
// alignment requirement of buffer used for endpoint transferring
|
||||
// TODO MEM_ALIGN can be different for host and device controller
|
||||
// should use CFG_TUD_MEM_ALIGN, CFG_TUH_MEM_ALIGN
|
||||
// Alignment requirement of buffer used for usb transferring. if MEM_ALIGN is different for
|
||||
// host and device controller use: CFG_TUD_MEM_ALIGN, CFG_TUH_MEM_ALIGN instead
|
||||
#ifndef CFG_TUSB_MEM_ALIGN
|
||||
#define CFG_TUSB_MEM_ALIGN TU_ATTR_ALIGNED(4)
|
||||
#endif
|
||||
@@ -321,24 +320,14 @@
|
||||
// Device Options (Default)
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
// Attribute to place data in accessible RAM for device controller
|
||||
// default to CFG_TUSB_MEM_SECTION for backward-compatible
|
||||
// Attribute to place data in accessible RAM for device controller (default: CFG_TUSB_MEM_SECTION)
|
||||
#ifndef CFG_TUD_MEM_SECTION
|
||||
#ifdef CFG_TUSB_MEM_SECTION
|
||||
#define CFG_TUD_MEM_SECTION CFG_TUSB_MEM_SECTION
|
||||
#else
|
||||
#define CFG_TUD_MEM_SECTION
|
||||
#endif
|
||||
#define CFG_TUD_MEM_SECTION CFG_TUSB_MEM_SECTION
|
||||
#endif
|
||||
|
||||
// Attribute to align memory for device controller
|
||||
// default to CFG_TUSB_MEM_ALIGN for backward-compatible
|
||||
// Attribute to align memory for device controller (default: CFG_TUSB_MEM_ALIGN)
|
||||
#ifndef CFG_TUD_MEM_ALIGN
|
||||
#ifdef CFG_TUSB_MEM_ALIGN
|
||||
#define CFG_TUD_MEM_ALIGN CFG_TUSB_MEM_ALIGN
|
||||
#else
|
||||
#define CFG_TUD_MEM_ALIGN TU_ATTR_ALIGNED(4)
|
||||
#endif
|
||||
#define CFG_TUD_MEM_ALIGN CFG_TUSB_MEM_ALIGN
|
||||
#endif
|
||||
|
||||
#ifndef CFG_TUD_ENDPOINT0_SIZE
|
||||
@@ -419,19 +408,14 @@
|
||||
#endif
|
||||
#endif // CFG_TUH_ENABLED
|
||||
|
||||
// Attribute to place data in accessible RAM for host controller
|
||||
// default to CFG_TUSB_MEM_SECTION for backward-compatible
|
||||
// Attribute to place data in accessible RAM for host controller (default: CFG_TUSB_MEM_SECTION)
|
||||
#ifndef CFG_TUH_MEM_SECTION
|
||||
#ifdef CFG_TUSB_MEM_SECTION
|
||||
#define CFG_TUH_MEM_SECTION CFG_TUSB_MEM_SECTION
|
||||
#else
|
||||
#define CFG_TUH_MEM_SECTION
|
||||
#endif
|
||||
#define CFG_TUH_MEM_SECTION CFG_TUSB_MEM_SECTION
|
||||
#endif
|
||||
|
||||
// Attribute to align memory for host controller
|
||||
#ifndef CFG_TUH_MEM_ALIGN
|
||||
#define CFG_TUH_MEM_ALIGN TU_ATTR_ALIGNED(4)
|
||||
#define CFG_TUH_MEM_ALIGN CFG_TUSB_MEM_ALIGN
|
||||
#endif
|
||||
|
||||
//------------- CLASS -------------//
|
||||
|
||||
Reference in New Issue
Block a user