diff options
| author | hathach <[email protected]> | 2023-08-04 12:07:39 +0700 |
|---|---|---|
| committer | hathach <[email protected]> | 2023-08-04 12:07:39 +0700 |
| commit | 81aca17d6e9a17d5f37e7ff04988257a0be4ec3e (patch) | |
| tree | 22cac9af80dae48e558490cb068132d1c7a679f0 /src | |
| parent | cfc146e18fe2aa0df4d77d435d4a4b7053361cd7 (diff) | |
| parent | 61f00c0c4dab0469c2e8ebad8eda1a26ae742e46 (diff) | |
Merge branch 'master' into blackf407VE
Diffstat (limited to 'src')
63 files changed, 1982 insertions, 1431 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8f7f38589..076e1e1eb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -64,6 +64,7 @@ function(add_tinyusb TARGET) -Wnull-dereference -Wuninitialized -Wunused + -Wunused-function -Wreturn-type -Wredundant-decls ) diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index e5dbe988a..1a7ce7870 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -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); diff --git a/src/class/bth/bth_device.c b/src/class/bth/bth_device.c index f96bb3552..c5c74d26a 100755 --- a/src/class/bth/bth_device.c +++ b/src/class/bth/bth_device.c @@ -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) { diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 5adce521d..70d9c2e24 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -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; diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index ce9f27c33..40ebd331d 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -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 @@ -973,7 +976,7 @@ static uint32_t ftdi_232bm_baud_to_divisor(uint32_t baud) static bool ftdi_sio_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { uint16_t const divisor = (uint16_t) ftdi_232bm_baud_to_divisor(baudrate); - TU_LOG_DRV("CDC FTDI Set BaudRate = %lu, divisor = 0x%04x\n", baudrate, divisor); + TU_LOG_DRV("CDC FTDI Set BaudRate = %lu, divisor = 0x%04x\r\n", baudrate, divisor); p_cdc->user_control_cb = complete_cb; _ftdi_requested_baud = baudrate; @@ -1108,7 +1111,7 @@ static bool cp210x_ifc_enable(cdch_interface_t* p_cdc, uint16_t enabled, tuh_xfe } static bool cp210x_set_baudrate(cdch_interface_t* p_cdc, uint32_t baudrate, tuh_xfer_cb_t complete_cb, uintptr_t user_data) { - TU_LOG_DRV("CDC CP210x Set BaudRate = %lu\n", baudrate); + TU_LOG_DRV("CDC CP210x Set BaudRate = %lu\r\n", baudrate); uint32_t baud_le = tu_htole32(baudrate); p_cdc->user_control_cb = complete_cb; return cp210x_set_request(p_cdc, CP210X_SET_BAUDRATE, 0, (uint8_t *) &baud_le, 4, diff --git a/src/class/dfu/dfu_device.c b/src/class/dfu/dfu_device.c index 464c4bd6b..3e7c13dea 100644 --- a/src/class/dfu/dfu_device.c +++ b/src/class/dfu/dfu_device.c @@ -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 ) diff --git a/src/class/dfu/dfu_rt_device.c b/src/class/dfu/dfu_rt_device.c index 7b77b3f8f..a940d8d62 100644 --- a/src/class/dfu/dfu_rt_device.c +++ b/src/class/dfu/dfu_rt_device.c @@ -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 } } diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 9240fe2ca..5637ea6b4 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -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) diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 6abe298e5..4253170d4 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -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 //--------------------------------------------------------------------+ diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index e3e7826da..052372a93 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -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) { diff --git a/src/class/msc/msc.h b/src/class/msc/msc.h index 7f25a29ba..bbfd35a43 100644 --- a/src/class/msc/msc.h +++ b/src/class/msc/msc.h @@ -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; //--------------------------------------------------------------------+ diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 159a11259..2589dcd2c 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -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; diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index d32c0adb0..a65208d69 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -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)); } diff --git a/src/class/net/ecm_rndis_device.c b/src/class/net/ecm_rndis_device.c index 8ac7cbd01..762425732 100644 --- a/src/class/net/ecm_rndis_device.c +++ b/src/class/net/ecm_rndis_device.c @@ -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; diff --git a/src/class/net/ncm_device.c b/src/class/net/ncm_device.c index 9e9580249..226c42c4e 100644 --- a/src/class/net/ncm_device.c +++ b/src/class/net/ncm_device.c @@ -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; } diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 4e320a778..573654d58 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -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, }; diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index 93596ee33..389a29696 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -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) diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 91f452afc..3b29454a3 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -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\r\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\r\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\r\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\r\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\r\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\r\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\r\n", _desc_ep_addr(cur)); } if (altnum) { stm->state = VS_STATE_STREAMING; } - TU_LOG2(" done\n"); + TU_LOG_DRV(" done\r\n"); return true; } diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 957491aa9..25f85e501 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -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; } @@ -260,11 +263,21 @@ TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16(void* mem, uint16_ #else // MCU that could access unaligned memory natively -TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_unaligned_read32 (const void* mem) { return *((uint32_t const *) mem); } -TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_unaligned_read16 (const void* mem) { return *((uint16_t const *) mem); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_unaligned_read32(const void *mem) { + return *((uint32_t const *) mem); +} -TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write32 (void* mem, uint32_t value ) { *((uint32_t*) mem) = value; } -TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16 (void* mem, uint16_t value ) { *((uint16_t*) mem) = value; } +TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_unaligned_read16(const void *mem) { + return *((uint16_t const *) mem); +} + +TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write32(void *mem, uint32_t value) { + *((uint32_t *) mem) = value; +} + +TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16(void *mem, uint16_t value) { + *((uint16_t *) mem) = value; +} #endif diff --git a/src/common/tusb_fifo.c b/src/common/tusb_fifo.c index a52c92267..d6c3db4ce 100644 --- a/src/common/tusb_fifo.c +++ b/src/common/tusb_fifo.c @@ -539,7 +539,7 @@ static uint16_t _tu_fifo_write_n(tu_fifo_t* f, const void * data, uint16_t n, tu // Advance index f->wr_idx = advance_index(f->depth, wr_idx, n); - TU_LOG(TU_FIFO_DBG, "\tnew_wr = %u\n", f->wr_idx); + TU_LOG(TU_FIFO_DBG, "\tnew_wr = %u\r\n", f->wr_idx); } _ff_unlock(f->mutex_wr); diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 9f3be78fd..89f89182e 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -34,10 +34,16 @@ //------------- Unaligned Memory Access -------------// -// ARMv7+ (M3-M7, M23-M33) can access unaligned memory -#if (defined(__ARM_ARCH) && (__ARM_ARCH >= 7)) - #define TUP_ARCH_STRICT_ALIGN 0 +#ifdef __ARM_ARCH + // ARM Architecture set __ARM_FEATURE_UNALIGNED to 1 for mcu supports unaligned access + #if defined(__ARM_FEATURE_UNALIGNED) && __ARM_FEATURE_UNALIGNED == 1 + #define TUP_ARCH_STRICT_ALIGN 0 + #else + #define TUP_ARCH_STRICT_ALIGN 1 + #endif #else + // TODO default to strict align for others + // Should investigate other architecture such as risv, xtensa, mips for optimal setting #define TUP_ARCH_STRICT_ALIGN 1 #endif @@ -327,6 +333,7 @@ // Renesas //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N, OPT_MCU_RAXXX) + #define TUP_USBIP_RUSB2 #define TUP_DCD_ENDPOINT_MAX 10 //--------------------------------------------------------------------+ diff --git a/src/device/usbd.c b/src/device/usbd.c index 44c2530ce..9429cf664 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -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); diff --git a/src/device/usbd_control.c b/src/device/usbd_control.c index 2afe967b5..76d062e40 100644 --- a/src/device/usbd_control.c +++ b/src/device/usbd_control.c @@ -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 diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 8393d3469..940b2858b 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -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 diff --git a/src/host/hcd.h b/src/host/hcd.h index 3355c18b2..d77dd6e2f 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -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 diff --git a/src/host/hub.c b/src/host/hub.c index 182bd6ce8..16dd534d2 100644 --- a/src/host/hub.c +++ b/src/host/hub.c @@ -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; diff --git a/src/host/usbh.c b/src/host/usbh.c index f3e9d3858..49f8c78f1 100644 --- a/src/host/usbh.c +++ b/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 diff --git a/src/host/usbh.h b/src/host/usbh.h index 0f969a46a..0d56f40c9 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -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 diff --git a/src/host/usbh_classdriver.h b/src/host/usbh_classdriver.h index be9811641..308b4418a 100644 --- a/src/host/usbh_classdriver.h +++ b/src/host/usbh_classdriver.h @@ -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) }; diff --git a/src/osal/osal_freertos.h b/src/osal/osal_freertos.h index 477f64892..501e0bddd 100644 --- a/src/osal/osal_freertos.h +++ b/src/osal/osal_freertos.h @@ -52,53 +52,60 @@ extern "C" { typedef SemaphoreHandle_t osal_semaphore_t; typedef SemaphoreHandle_t osal_mutex_t; - -// _int_set is not used with an RTOS -#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ - static _type _name##_##buf[_depth];\ - osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf }; +typedef QueueHandle_t osal_queue_t; typedef struct { uint16_t depth; uint16_t item_sz; void* buf; + +#if defined(configQUEUE_REGISTRY_SIZE) && (configQUEUE_REGISTRY_SIZE>0) + char const* name; +#endif + #if configSUPPORT_STATIC_ALLOCATION StaticQueue_t sq; #endif -}osal_queue_def_t; +} osal_queue_def_t; -typedef QueueHandle_t osal_queue_t; +#if defined(configQUEUE_REGISTRY_SIZE) && (configQUEUE_REGISTRY_SIZE>0) + #define _OSAL_Q_NAME(_name) .name = #_name +#else + #define _OSAL_Q_NAME(_name) +#endif + +// _int_set is not used with an RTOS +#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ + static _type _name##_##buf[_depth];\ + osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf, _OSAL_Q_NAME(_name) }; //--------------------------------------------------------------------+ // TASK API //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE static inline uint32_t _osal_ms2tick(uint32_t msec) -{ - if (msec == OSAL_TIMEOUT_WAIT_FOREVER) return portMAX_DELAY; - if (msec == 0) return 0; +TU_ATTR_ALWAYS_INLINE static inline uint32_t _osal_ms2tick(uint32_t msec) { + if ( msec == OSAL_TIMEOUT_WAIT_FOREVER ) return portMAX_DELAY; + if ( msec == 0 ) return 0; uint32_t ticks = pdMS_TO_TICKS(msec); // configTICK_RATE_HZ is less than 1000 and 1 tick > 1 ms // we still need to delay at least 1 tick - if (ticks == 0) ticks =1 ; + if ( ticks == 0 ) ticks = 1; return ticks; } -TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) -{ - vTaskDelay( pdMS_TO_TICKS(msec) ); +TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { + vTaskDelay(pdMS_TO_TICKS(msec)); } //--------------------------------------------------------------------+ // Semaphore API //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef) -{ +TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t *semdef) { #if configSUPPORT_STATIC_ALLOCATION return xSemaphoreCreateBinaryStatic(semdef); #else @@ -107,14 +114,10 @@ TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_ #endif } -TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) -{ - if ( !in_isr ) - { +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { + if ( !in_isr ) { return xSemaphoreGive(sem_hdl) != 0; - } - else - { + } else { BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t res = xSemaphoreGiveFromISR(sem_hdl, &xHigherPriorityTaskWoken); @@ -129,13 +132,11 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t se } } -TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { return xSemaphoreTake(sem_hdl, _osal_ms2tick(msec)); } -TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) -{ +TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) { xQueueReset(sem_hdl); } @@ -143,8 +144,7 @@ TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t c // MUTEX API (priority inheritance) //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef) -{ +TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t *mdef) { #if configSUPPORT_STATIC_ALLOCATION return xSemaphoreCreateMutexStatic(mdef); #else @@ -153,13 +153,11 @@ TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_de #endif } -TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { return osal_semaphore_wait(mutex_hdl, msec); } -TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { return xSemaphoreGive(mutex_hdl); } @@ -167,33 +165,35 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hd // QUEUE API //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) -{ +TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { + osal_queue_t q; + #if configSUPPORT_STATIC_ALLOCATION - return xQueueCreateStatic(qdef->depth, qdef->item_sz, (uint8_t*) qdef->buf, &qdef->sq); + q = xQueueCreateStatic(qdef->depth, qdef->item_sz, (uint8_t*) qdef->buf, &qdef->sq); #else - return xQueueCreate(qdef->depth, qdef->item_sz); + q = xQueueCreate(qdef->depth, qdef->item_sz); #endif + +#if defined(configQUEUE_REGISTRY_SIZE) && (configQUEUE_REGISTRY_SIZE>0) + vQueueAddToRegistry(q, qdef->name); +#endif + + return q; } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { return xQueueReceive(qhdl, data, _osal_ms2tick(msec)); } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr) -{ - if ( !in_isr ) - { +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const *data, bool in_isr) { + if ( !in_isr ) { return xQueueSendToBack(qhdl, data, OSAL_TIMEOUT_WAIT_FOREVER) != 0; - } - else - { + } else { BaseType_t xHigherPriorityTaskWoken = pdFALSE; BaseType_t res = xQueueSendToBackFromISR(qhdl, data, &xHigherPriorityTaskWoken); #if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3 - // not needed after https://github.com/espressif/esp-idf/commit/c5fd79547ac9b7bae06fa660e9f814d18d3390b7 + // not needed after https://github.com/espressif/esp-idf/commit/c5fd79547ac9b7bae06fa660e9f814d18d3390b7 (IDF v5) if ( xHigherPriorityTaskWoken ) portYIELD_FROM_ISR(); #else portYIELD_FROM_ISR(xHigherPriorityTaskWoken); @@ -203,13 +203,12 @@ TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void } } -TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) -{ +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { return uxQueueMessagesWaiting(qhdl) == 0; } #ifdef __cplusplus - } +} #endif #endif diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index 5f407378e..76e77c25d 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -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 //--------------------------------------------------------------------+ diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index 95dfda49c..f02415904 100644 --- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -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 diff --git a/src/portable/chipidea/ci_fs/dcd_ci_fs.c b/src/portable/chipidea/ci_fs/dcd_ci_fs.c index 37265df8b..9327e09d8 100644 --- a/src/portable/chipidea/ci_fs/dcd_ci_fs.c +++ b/src/portable/chipidea/ci_fs/dcd_ci_fs.c @@ -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" ); diff --git a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h index c14f00431..c59c107ff 100644 --- a/src/portable/chipidea/ci_hs/ci_hs_imxrt.h +++ b/src/portable/chipidea/ci_hs/ci_hs_imxrt.h @@ -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 diff --git a/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h b/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h index 2e84c93e7..178eec419 100644 --- a/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h +++ b/src/portable/chipidea/ci_hs/ci_hs_lpc18_43.h @@ -27,9 +27,18 @@ #ifndef _CI_HS_LPC18_43_H_ #define _CI_HS_LPC18_43_H_ +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + // LPCOpen for 18xx & 43xx #include "chip.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + static const ci_hs_controller_t _ci_controller[] = { { .reg_base = LPC_USB0_BASE, .irqnum = USB0_IRQn }, diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index f50550d33..f9ec666e5 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -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; //--------------------------------------------------------------------+ diff --git a/src/portable/chipidea/ci_hs/hcd_ci_hs.c b/src/portable/chipidea/ci_hs/hcd_ci_hs.c index 56167b8f6..6ee91e18e 100644 --- a/src/portable/chipidea/ci_hs/hcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/hcd_ci_hs.c @@ -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) diff --git a/src/portable/dialog/da146xx/dcd_da146xx.c b/src/portable/dialog/da146xx/dcd_da146xx.c index 961da81d6..d1e85c2df 100644 --- a/src/portable/dialog/da146xx/dcd_da146xx.c +++ b/src/portable/dialog/da146xx/dcd_da146xx.c @@ -651,7 +651,7 @@ static void handle_epx_tx_ev(xfer_ctl_t *xfer) } if (txs & USB_USB_TXS1_REG_USB_TX_URUN_Msk) { - TU_LOG1("EP %d FIFO underrun\n", epnum); + TU_LOG1("EP %d FIFO underrun\r\n", epnum); } // Start next or repeated packet. start_tx_packet(xfer); diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index 38711e382..9be24c888 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -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; -} - -TU_ATTR_WEAK void hcd_dcache_invalidate(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_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; + 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; + } - // invalidate dcache if IN transfer - if (dir == 1 && qhd->attached_buffer != 0 && xferred_bytes > 0) { - hcd_dcache_invalidate((void*) qhd->attached_buffer, xferred_bytes); - } + ehci_qtd_t * volatile qtd = qhd->attached_qtd; + hcd_dcache_invalidate(qtd, sizeof(ehci_qtd_t)); // HC may have written back TD - // remove and free TD before invoking callback - qhd->attached_qtd = NULL; - qhd->attached_buffer = 0; - qtd->used = 0; // free QTD + 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_SUCCESS, true); + // 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 async_list_xfer_complete_isr(ehci_qhd_t * const async_head) +void proccess_async_xfer_isr(ehci_qhd_t * const list_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); - } + ehci_qhd_t *qhd = list_head; - p_qhd = qhd_next(p_qhd); - }while(p_qhd != async_head); // async list traversal, stop if loop around + 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 period_list_xfer_complete_isr(uint8_t rhport, uint32_t interval_ms) +void process_period_xfer_isr(uint8_t rhport, uint32_t interval_ms) { - uint32_t const period_1ms_addr = (uint32_t) get_period_head(rhport, 1u); - ehci_link_t next_link = * get_period_head(rhport, 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 - } - - //------------- 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 - } + // 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)); - 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) ) ]; +} + +// 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); +} -//------------- queue head helper -------------// -static inline ehci_qhd_t* qhd_find_free (void) +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++) - { - if ( !ehci_data.qhd_pool[i].used ) return &ehci_data.qhd_pool[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; + + 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; +} -//------------- TD helper -------------// -static inline ehci_qtd_t *qtd_find_free(void) { +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 diff --git a/src/portable/ehci/ehci.h b/src/portable/ehci/ehci.h index 8338fb419..457adc1d3 100644 --- a/src/portable/ehci/ehci.h +++ b/src/portable/ehci/ehci.h @@ -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_FRAMELIST_SIZE_SHIFT = 2, // [2..3] + EHCI_USBCMD_CHIPIDEA_FRAMELIST_SIZE_MSB_SHIFT = 15, + EHCI_USBCMD_INTERRUPT_THRESHOLD_SHIFT = 16 }; 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_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 | diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 487761847..3c0114e41 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -317,7 +317,7 @@ static bool handle_xfer_in(uint_fast8_t ep_addr) const unsigned mps = regs->TXMAXP; const unsigned len = TU_MIN(mps, rem); void *buf = pipe->buf; - // TU_LOG1(" %p mps %d len %d rem %d\n", buf, mps, len, rem); + // TU_LOG1(" %p mps %d len %d rem %d\r\n", buf, mps, len, rem); if (len) { if (_dcd.pipe_buf_is_fifo[TUSB_DIR_IN] & TU_BIT(epnum_minus1)) { pipe_read_write_packet_ff(buf, &USB0->FIFO1_WORD + epnum_minus1, len, TUSB_DIR_IN); @@ -328,7 +328,7 @@ static bool handle_xfer_in(uint_fast8_t ep_addr) pipe->remaining = rem - len; } regs->TXCSRL = USB_TXCSRL1_TXRDY; - // TU_LOG1(" TXCSRL%d = %x %d\n", epnum_minus1 + 1, regs->TXCSRL, rem - len); + // TU_LOG1(" TXCSRL%d = %x %d\r\n", epnum_minus1 + 1, regs->TXCSRL, rem - len); return false; } @@ -337,7 +337,7 @@ static bool handle_xfer_out(uint_fast8_t ep_addr) unsigned epnum_minus1 = tu_edpt_number(ep_addr) - 1; pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; volatile hw_endpoint_t *regs = edpt_regs(epnum_minus1); - // TU_LOG1(" RXCSRL%d = %x\n", epnum_minus1 + 1, regs->RXCSRL); + // TU_LOG1(" RXCSRL%d = %x\r\n", epnum_minus1 + 1, regs->RXCSRL); TU_ASSERT(regs->RXCSRL & USB_RXCSRL1_RXRDY); @@ -399,14 +399,14 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ * may have already finished and received the next setup packet * without calling this function, so we have no choice but to * invoke the callback function of status packet here. */ - // TU_LOG1(" STATUS OUT USB0->CSRL0 = %x\n", USB0->CSRL0); + // TU_LOG1(" STATUS OUT USB0->CSRL0 = %x\r\n", USB0->CSRL0); _dcd.status_out = 0; if (req == REQUEST_TYPE_INVALID) { dcd_event_xfer_complete(rhport, ep_addr, total_bytes, XFER_RESULT_SUCCESS, false); } else { /* The next setup packet has already been received, it aborts * invoking callback function to avoid confusing TUSB stack. */ - TU_LOG1("Drop CONTROL_STAGE_ACK\n"); + TU_LOG1("Drop CONTROL_STAGE_ACK\r\n"); } return true; } @@ -431,16 +431,16 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ } else { USB0->CSRL0 = USB_CSRL0_TXRDY; /* Flush TX FIFO to return ACK. */ } - // TU_LOG1(" IN USB0->CSRL0 = %x\n", USB0->CSRL0); + // TU_LOG1(" IN USB0->CSRL0 = %x\r\n", USB0->CSRL0); } else { - // TU_LOG1(" OUT USB0->CSRL0 = %x\n", USB0->CSRL0); + // TU_LOG1(" OUT USB0->CSRL0 = %x\r\n", USB0->CSRL0); _dcd.pipe0.buf = buffer; _dcd.pipe0.length = len; _dcd.pipe0.remaining = len; USB0->CSRL0 = USB_CSRL0_RXRDYC; /* Clear RX FIFO to return ACK. */ } } else if (dir_in) { - // TU_LOG1(" STATUS IN USB0->CSRL0 = %x\n", USB0->CSRL0); + // TU_LOG1(" STATUS IN USB0->CSRL0 = %x\r\n", USB0->CSRL0); _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; @@ -454,7 +454,7 @@ static void process_ep0(uint8_t rhport) { uint_fast8_t csrl = USB0->CSRL0; - // TU_LOG1(" EP0 USB0->CSRL0 = %x\n", csrl); + // TU_LOG1(" EP0 USB0->CSRL0 = %x\r\n", csrl); if (csrl & USB_CSRL0_STALLED) { /* Returned STALL packet to HOST. */ @@ -464,7 +464,7 @@ static void process_ep0(uint8_t rhport) unsigned req = _dcd.setup_packet.bmRequestType; if (csrl & USB_CSRL0_SETEND) { - TU_LOG1(" ABORT by the next packets\n"); + TU_LOG1(" ABORT by the next packets\r\n"); USB0->CSRL0 = USB_CSRL0_SETENDC; if (req != REQUEST_TYPE_INVALID && _dcd.pipe0.buf) { /* DATA stage was aborted by receiving STATUS or SETUP packet. */ @@ -539,14 +539,14 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) volatile hw_endpoint_t *regs = edpt_regs(epn_minus1); if (dir_in) { - // TU_LOG1(" TXCSRL%d = %x\n", epn_minus1 + 1, regs->TXCSRL); + // TU_LOG1(" TXCSRL%d = %x\r\n", epn_minus1 + 1, regs->TXCSRL); if (regs->TXCSRL & USB_TXCSRL1_STALLED) { regs->TXCSRL &= ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_UNDRN); return; } completed = handle_xfer_in(ep_addr); } else { - // TU_LOG1(" RXCSRL%d = %x\n", epn_minus1 + 1, regs->RXCSRL); + // TU_LOG1(" RXCSRL%d = %x\r\n", epn_minus1 + 1, regs->RXCSRL); if (regs->RXCSRL & USB_RXCSRL1_STALLED) { regs->RXCSRL &= ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_OVER); return; @@ -789,7 +789,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t { (void)rhport; bool ret; - // TU_LOG1("X %x %d\n", ep_addr, total_bytes); + // TU_LOG1("X %x %d\r\n", ep_addr, total_bytes); unsigned const epnum = tu_edpt_number(ep_addr); unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); NVIC_DisableIRQ(USB0_IRQn); @@ -807,7 +807,7 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_ { (void)rhport; bool ret; - // TU_LOG1("X %x %d\n", ep_addr, total_bytes); + // TU_LOG1("X %x %d\r\n", ep_addr, total_bytes); unsigned const epnum = tu_edpt_number(ep_addr); TU_ASSERT(epnum); unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); @@ -869,7 +869,7 @@ void dcd_int_handler(uint8_t rhport) is = USB0->IS; /* read and clear interrupt status */ txis = USB0->TXIS; /* read and clear interrupt status */ rxis = USB0->RXIS; /* read and clear interrupt status */ - // TU_LOG1("D%2x T%2x R%2x\n", is, txis, rxis); + // TU_LOG1("D%2x T%2x R%2x\r\n", is, txis, rxis); is &= USB0->IE; /* Clear disabled interrupts */ if (is & USB_IS_DISCON) { diff --git a/src/portable/mentor/musb/hcd_musb.c b/src/portable/mentor/musb/hcd_musb.c index 9eb2e005e..02090df85 100644 --- a/src/portable/mentor/musb/hcd_musb.c +++ b/src/portable/mentor/musb/hcd_musb.c @@ -418,7 +418,7 @@ static void process_ep0(uint8_t rhport) (void)rhport; uint_fast8_t csrl = USB0->CSRL0; - // TU_LOG1(" EP0 CSRL = %x\n", csrl); + // TU_LOG1(" EP0 CSRL = %x\r\n", csrl); unsigned const dev_addr = USB0->TXFUNCADDR0; unsigned const req = _hcd.bmRequestType; @@ -508,7 +508,7 @@ static void process_pipe_tx(uint8_t rhport, uint_fast8_t pipenum) volatile hw_endpoint_t *regs = edpt_regs(pipenum - 1); unsigned const csrl = regs->TXCSRL; - // TU_LOG1(" TXCSRL%d = %x\n", pipenum, csrl); + // TU_LOG1(" TXCSRL%d = %x\r\n", pipenum, csrl); if (csrl & (USB_TXCSRL1_STALLED | USB_TXCSRL1_ERROR)) { if (csrl & USB_TXCSRL1_TXRDY) regs->TXCSRL = (csrl & ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_ERROR)) | USB_TXCSRL1_FLUSH; @@ -537,7 +537,7 @@ static void process_pipe_rx(uint8_t rhport, uint_fast8_t pipenum) volatile hw_endpoint_t *regs = edpt_regs(pipenum - 1); unsigned const csrl = regs->RXCSRL; - // TU_LOG1(" RXCSRL%d = %x\n", pipenum, csrl); + // TU_LOG1(" RXCSRL%d = %x\r\n", pipenum, csrl); if (csrl & (USB_RXCSRL1_STALLED | USB_RXCSRL1_ERROR)) { if (csrl & USB_RXCSRL1_RXRDY) regs->RXCSRL = (csrl & ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_ERROR)) | USB_RXCSRL1_FLUSH; @@ -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); @@ -846,7 +854,7 @@ void hcd_int_handler(uint8_t rhport) is = USB0->IS; /* read and clear interrupt status */ txis = USB0->TXIS; /* read and clear interrupt status */ rxis = USB0->RXIS; /* read and clear interrupt status */ - // TU_LOG1("D%2x T%2x R%2x\n", is, txis, rxis); + // TU_LOG1("D%2x T%2x R%2x\r\n", is, txis, rxis); is &= USB0->IE; /* Clear disabled interrupts */ if (is & USB_IS_RESUME) { diff --git a/src/portable/microchip/pic/dcd_pic.c b/src/portable/microchip/pic/dcd_pic.c index 6986c8317..ccc27c3c9 100644 --- a/src/portable/microchip/pic/dcd_pic.c +++ b/src/portable/microchip/pic/dcd_pic.c @@ -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" ); diff --git a/src/portable/microchip/samx7x/dcd_samx7x.c b/src/portable/microchip/samx7x/dcd_samx7x.c index 2bbb345d6..9586df84d 100644 --- a/src/portable/microchip/samx7x/dcd_samx7x.c +++ b/src/portable/microchip/samx7x/dcd_samx7x.c @@ -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]; diff --git a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c index 39b09db68..c3d0c7297 100644 --- a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c +++ b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c @@ -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" ); diff --git a/src/portable/nxp/khci/dcd_khci.c b/src/portable/nxp/khci/dcd_khci.c index 52f4145f2..5c65ea33d 100644 --- a/src/portable/nxp/khci/dcd_khci.c +++ b/src/portable/nxp/khci/dcd_khci.c @@ -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" ); diff --git a/src/portable/nxp/khci/hcd_khci.c b/src/portable/nxp/khci/hcd_khci.c index f6029ee0d..55327e02d 100644 --- a/src/portable/nxp/khci/hcd_khci.c +++ b/src/portable/nxp/khci/hcd_khci.c @@ -161,7 +161,7 @@ static int prepare_packets(int pipenum) buffer_descriptor_t *bd = _hcd.bdt[dir_tx]; TU_ASSERT(0 == bd[odd].own, -1); - // TU_LOG1(" %p dir %d odd %d data %d\n", &bd[odd], dir_tx, odd, pipe->data); + // TU_LOG1(" %p dir %d odd %d data %d\r\n", &bd[odd], dir_tx, odd, pipe->data); ep->pipenum = pipenum; @@ -251,7 +251,7 @@ static bool resume_transfer(int pipenum) flags |= USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPCTLDIS_MASK | USB_ENDPT_RETRYDIS_MASK; break; } - // TU_LOG1(" resume pipenum %d flags %x\n", pipenum, flags); + // TU_LOG1(" resume pipenum %d flags %x\r\n", pipenum, flags); KHCI->ENDPOINT[0].ENDPT = flags; KHCI->ADDR = (KHCI->ADDR & USB_ADDR_LSEN_MASK) | pipe->dev_addr; @@ -302,7 +302,7 @@ static void process_tokdne(uint8_t rhport) int pipenum = ep->pipenum; int next_pipenum; - // TU_LOG1("TOKDNE %x PID %x pipe %d\n", s, pid, pipenum); + // TU_LOG1("TOKDNE %x PID %x pipe %d\r\n", s, pid, pipenum); xfer_result_t result; switch (pid) { @@ -479,7 +479,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("SETUP %u\n", dev_addr); + // TU_LOG1("SETUP %u\r\n", dev_addr); TU_ASSERT(0 == (_hcd.in_progress & TU_BIT(0))); int pipenum = find_pipe(dev_addr, 0); @@ -510,7 +510,7 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const { (void)rhport; uint8_t const ep_addr = ep_desc->bEndpointAddress; - // TU_LOG1("O %u %x\n", dev_addr, ep_addr); + // TU_LOG1("O %u %x\r\n", dev_addr, ep_addr); /* Find a free pipe */ pipe_state_t *p = &_hcd.pipe[0]; pipe_state_t *end = &_hcd.pipe[CFG_TUH_ENDPOINT_MAX * 2]; @@ -543,7 +543,7 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) { (void)rhport; - // TU_LOG1("X %u %x %x %d\n", dev_addr, ep_addr, (uintptr_t)buffer, buflen); + // TU_LOG1("X %u %x %x %d\r\n", dev_addr, ep_addr, (uintptr_t)buffer, buflen); int pipenum = find_pipe(dev_addr, ep_addr); TU_ASSERT(0 <= pipenum); @@ -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; @@ -580,7 +588,7 @@ void hcd_int_handler(uint8_t rhport) uint32_t is = KHCI->ISTAT; uint32_t msk = KHCI->INTEN; - // TU_LOG1("S %lx\n", is); + // TU_LOG1("S %lx\r\n", is); /* clear disabled interrupts */ KHCI->ISTAT = (is & ~msk & ~USB_ISTAT_TOKDNE_MASK) | USB_ISTAT_SOFTOK_MASK; @@ -589,7 +597,7 @@ void hcd_int_handler(uint8_t rhport) if (is & USB_ISTAT_ERROR_MASK) { unsigned err = KHCI->ERRSTAT; if (err) { - TU_LOG1(" ERR %x\n", err); + TU_LOG1(" ERR %x\r\n", err); KHCI->ERRSTAT = err; } else { KHCI->INTEN &= ~USB_ISTAT_ERROR_MASK; diff --git a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c index 86149afd8..b880c2870 100644 --- a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c +++ b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c @@ -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; //--------------------------------------------------------------------+ diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c index 5368ef868..7ca698a93 100644 --- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c +++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c @@ -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 diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c index 3f702d22c..413e72037 100644 --- a/src/portable/ohci/ohci.c +++ b/src/portable/ohci/ohci.c @@ -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; + uint8_t *cbp = (uint8_t *) _phys_addr(data_ptr); - 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; + 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; diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c index 264af2e7a..adb83e97d 100644 --- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c @@ -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); @@ -150,16 +155,16 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet // // so if any transfer is active on epx, we are busy. Interrupt endpoints have their own // // EPX so ep->active will only be busy if there is a pending transfer on that interrupt endpoint // // on that device -// pico_trace("hcd_edpt_busy dev addr %d ep_addr 0x%x\n", dev_addr, ep_addr); +// pico_trace("hcd_edpt_busy dev addr %d ep_addr 0x%x\r\n", dev_addr, ep_addr); // struct hw_endpoint *ep = get_dev_ep(dev_addr, ep_addr); // assert(ep); // bool busy = ep->active; -// pico_trace("busy == %d\n", busy); +// pico_trace("busy == %d\r\n", busy); // 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; diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 479b17b67..e8cee73fd 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -189,7 +189,7 @@ static void hw_endpoint_xfer(uint8_t ep_addr, uint8_t *buffer, uint16_t total_by static void __tusb_irq_path_func(hw_handle_buff_status)(void) { uint32_t remaining_buffers = usb_hw->buf_status; - pico_trace("buf_status = 0x%08lx\n", remaining_buffers); + pico_trace("buf_status = 0x%08lx\r\n", remaining_buffers); uint bit = 1u; for (uint8_t i = 0; remaining_buffers && i < USB_MAX_ENDPOINTS * 2; i++) { @@ -331,7 +331,7 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) // SE0 for 2.5 us or more (will last at least 10ms) if ( status & USB_INTS_BUS_RESET_BITS ) { - pico_trace("BUS RESET\n"); + pico_trace("BUS RESET\r\n"); handled |= USB_INTS_BUS_RESET_BITS; @@ -565,7 +565,7 @@ void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) { (void) rhport; - pico_trace("dcd_edpt_close %02x\n", ep_addr); + pico_trace("dcd_edpt_close %02x\r\n", ep_addr); hw_endpoint_close(ep_addr); } diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 02f9968a7..21dc3f67d 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -219,7 +219,7 @@ static void __tusb_irq_path_func(hcd_rp2040_irq)(void) if ( status & USB_INTS_BUFF_STATUS_BITS ) { handled |= USB_INTS_BUFF_STATUS_BITS; - TU_LOG(2, "Buffer complete\n"); + TU_LOG(2, "Buffer complete\r\n"); hw_handle_buff_status(); } @@ -227,7 +227,7 @@ static void __tusb_irq_path_func(hcd_rp2040_irq)(void) { handled |= USB_INTS_TRANS_COMPLETE_BITS; usb_hw_clear->sie_status = USB_SIE_STATUS_TRANS_COMPLETE_BITS; - TU_LOG(2, "Transfer complete\n"); + TU_LOG(2, "Transfer complete\r\n"); hw_trans_complete(); } @@ -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; diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index 1f49665ff..a512dc34f 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -219,7 +219,7 @@ void hw_endpoint_xfer_start(struct hw_endpoint *ep, uint8_t *buffer, uint16_t to if ( ep->active ) { // TODO: Is this acceptable for interrupt packets? - TU_LOG(1, "WARN: starting new transfer on already active ep %d %s\n", tu_edpt_number(ep->ep_addr), + TU_LOG(1, "WARN: starting new transfer on already active ep %d %s\r\n", tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]); hw_endpoint_reset_transfer(ep); @@ -276,7 +276,7 @@ static uint16_t __tusb_irq_path_func(sync_ep_buffer)(struct hw_endpoint *ep, uin // Short packet if (xferred_bytes < ep->wMaxPacketSize) { - pico_trace(" Short packet on buffer %d with %u bytes\n", buf_id, xferred_bytes); + pico_trace(" Short packet on buffer %d with %u bytes\r\n", buf_id, xferred_bytes); // Reduce total length as this is last packet ep->remaining_len = 0; } @@ -352,7 +352,7 @@ bool __tusb_irq_path_func(hw_endpoint_xfer_continue)(struct hw_endpoint *ep) // If we are done then notify tinyusb if (ep->remaining_len == 0) { - pico_trace("Completed transfer of %d bytes on ep %d %s\n", + pico_trace("Completed transfer of %d bytes on ep %d %s\r\n", ep->xferred_len, tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]); // Notify caller we are done so it can notify the tinyusb stack hw_endpoint_lock_update(ep, -1); @@ -419,7 +419,7 @@ static bool __tusb_irq_path_func(e15_is_critical_frame_period) (struct hw_endpoi if (delta < 800 || delta > 998) { return false; } - TU_LOG(3, "Avoiding sof %lu now %lu last %lu\n", (usb_hw->sof_rd + 1) & USB_SOF_RD_BITS, time_us_32(), e15_last_sof); + TU_LOG(3, "Avoiding sof %lu now %lu last %lu\r\n", (usb_hw->sof_rd + 1) & USB_SOF_RD_BITS, time_us_32(), e15_last_sof); return true; } diff --git a/src/portable/renesas/rusb2/dcd_rusb2.c b/src/portable/renesas/rusb2/dcd_rusb2.c index 78584125f..3ec1b70b5 100644 --- a/src/portable/renesas/rusb2/dcd_rusb2.c +++ b/src/portable/renesas/rusb2/dcd_rusb2.c @@ -27,13 +27,12 @@ #include "tusb_option.h" +#if CFG_TUD_ENABLED && defined(TUP_USBIP_RUSB2) + // Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval) // We disable SOF for now until needed later on #define USE_SOF 0 -#if CFG_TUD_ENABLED && (TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N) || \ - TU_CHECK_MCU(OPT_MCU_RAXXX)) - #include "device/dcd.h" #include "rusb2_type.h" @@ -41,6 +40,16 @@ #include "rusb2_rx.h" #elif TU_CHECK_MCU(OPT_MCU_RAXXX) #include "rusb2_ra.h" + #if defined(RENESAS_CORTEX_M23) + #define D0FIFO CFIFO + #define D0FIFOSEL CFIFOSEL + #define D0FIFOSEL_b CFIFOSEL_b + #define D1FIFOSEL CFIFOSEL + #define D1FIFOSEL_b CFIFOSEL_b + #define D0FIFOCTR CFIFOCTR + #define D0FIFOCTR_b CFIFOCTR_b + #endif + #else #error "Unsupported MCU" #endif @@ -49,38 +58,10 @@ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ -/* LINK core registers */ -#if defined(__CCRX__) - #define RUSB2 ((RUSB2_REG_t __evenaccess*) RUSB2_REG_BASE) -#else - #define RUSB2 ((RUSB2_REG_t*) RUSB2_REG_BASE) -#endif - /* Start of definition of packed structs (used by the CCRX toolchain) */ TU_ATTR_PACKED_BEGIN TU_ATTR_BIT_FIELD_ORDER_BEGIN -typedef struct TU_ATTR_PACKED { - union { - struct { - uint16_t : 8; - uint16_t TRCLR: 1; - uint16_t TRENB: 1; - uint16_t : 0; - }; - uint16_t TRE; - }; - uint16_t TRN; -} reg_pipetre_t; - -typedef union TU_ATTR_PACKED { - struct { - volatile uint16_t u8: 8; - volatile uint16_t : 0; - }; - volatile uint16_t u16; -} hw_fifo_t; - typedef struct TU_ATTR_PACKED { void *buf; /* the start address of a transfer data buffer */ @@ -102,188 +83,257 @@ typedef struct uint8_t ep[2][16]; /* a lookup table for a pipe index from an endpoint address */ } dcd_data_t; +static dcd_data_t _dcd; + //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION //--------------------------------------------------------------------+ -static dcd_data_t _dcd; + +// Transfer conditions specifiable for each pipe: +// - Pipe 0: Control transfer with 64-byte single buffer +// - Pipes 1 and 2: Bulk isochronous transfer continuous transfer mode with programmable buffer size up +// to 2 KB and optional double buffer +// - Pipes 3 to 5: Bulk transfer continuous transfer mode with programmable buffer size up to 2 KB and +// optional double buffer +// - Pipes 6 to 9: Interrupt transfer with 64-byte single buffer +enum { + PIPE_1ST_BULK = 3, + PIPE_1ST_INTERRUPT = 6, + PIPE_COUNT = 10, +}; static unsigned find_pipe(unsigned xfer) { switch (xfer) { - case TUSB_XFER_ISOCHRONOUS: - for (int i = 1; i <= 2; ++i) { - if (0 == _dcd.pipe[i].ep) return i; - } - break; - case TUSB_XFER_BULK: - for (int i = 3; i <= 5; ++i) { - if (0 == _dcd.pipe[i].ep) return i; - } - for (int i = 1; i <= 1; ++i) { - if (0 == _dcd.pipe[i].ep) return i; - } - break; - case TUSB_XFER_INTERRUPT: - for (int i = 6; i <= 9; ++i) { - if (0 == _dcd.pipe[i].ep) return i; - } - break; - default: - /* No support for control transfer */ - break; + case TUSB_XFER_ISOCHRONOUS: + for (int i = 1; i < PIPE_1ST_BULK; ++i) { + if (0 == _dcd.pipe[i].ep) return i; + } + break; + + case TUSB_XFER_BULK: + for (int i = PIPE_1ST_BULK; i < PIPE_1ST_INTERRUPT; ++i) { + if (0 == _dcd.pipe[i].ep) return i; + } + for (int i = 1; i < PIPE_1ST_BULK; ++i) { + if (0 == _dcd.pipe[i].ep) return i; + } + break; + + case TUSB_XFER_INTERRUPT: + for (int i = PIPE_1ST_INTERRUPT; i < PIPE_COUNT; ++i) { + if (0 == _dcd.pipe[i].ep) return i; + } + break; + + default: + /* No support for control transfer */ + break; } return 0; } -static volatile uint16_t* get_pipectr(unsigned num) +static volatile uint16_t* get_pipectr(rusb2_reg_t *rusb, unsigned num) { if (num) { - return (volatile uint16_t*)&(RUSB2->PIPE_CTR[num - 1]); + return (volatile uint16_t*)&(rusb->PIPE_CTR[num - 1]); } else { - return (volatile uint16_t*)&(RUSB2->DCPCTR); + return (volatile uint16_t*)&(rusb->DCPCTR); } } -static volatile reg_pipetre_t* get_pipetre(unsigned num) +static volatile reg_pipetre_t* get_pipetre(rusb2_reg_t *rusb, unsigned num) { volatile reg_pipetre_t* tre = NULL; if ((1 <= num) && (num <= 5)) { - tre = (volatile reg_pipetre_t*)&(RUSB2->PIPE_TR[num - 1].E); + tre = (volatile reg_pipetre_t*)&(rusb->PIPE_TR[num - 1].E); } return tre; } static volatile uint16_t* ep_addr_to_pipectr(uint8_t rhport, unsigned ep_addr) { - (void)rhport; + rusb2_reg_t *rusb = RUSB2_REG(rhport); const unsigned epn = tu_edpt_number(ep_addr); + if (epn) { const unsigned dir = tu_edpt_dir(ep_addr); const unsigned num = _dcd.ep[dir][epn]; - return get_pipectr(num); + return get_pipectr(rusb, num); } else { - return get_pipectr(0); + return get_pipectr(rusb, 0); } } -static unsigned edpt0_max_packet_size(void) +static uint16_t edpt0_max_packet_size(rusb2_reg_t* rusb) { - return RUSB2->DCPMAXP_b.MXPS; + return rusb->DCPMAXP_b.MXPS; } -static unsigned edpt_max_packet_size(unsigned num) +static uint16_t edpt_max_packet_size(rusb2_reg_t *rusb, unsigned num) { - RUSB2->PIPESEL = num; - return RUSB2->PIPEMAXP; + rusb->PIPESEL = num; + return rusb->PIPEMAXP; } -static inline void pipe_wait_for_ready(unsigned num) +static inline void pipe_wait_for_ready(rusb2_reg_t * rusb, unsigned num) { - while (RUSB2->D0FIFOSEL_b.CURPIPE != num) ; - while (!RUSB2->D0FIFOCTR_b.FRDY) ; + while ( rusb->D0FIFOSEL_b.CURPIPE != num ) {} + while ( !rusb->D0FIFOCTR_b.FRDY ) {} } -static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) +//--------------------------------------------------------------------+ +// Pipe FIFO +//--------------------------------------------------------------------+ + +// Write data buffer --> hw fifo +static void pipe_write_packet(rusb2_reg_t * rusb, void *buf, volatile void *fifo, unsigned len) { - volatile hw_fifo_t *reg = (volatile hw_fifo_t*) fifo; - uintptr_t addr = (uintptr_t)buf; + (void) rusb; + + volatile uint16_t *ff16; + volatile uint8_t *ff8; + + // Highspeed FIFO is 32-bit + if ( rusb2_is_highspeed_reg(rusb) ) { + // TODO 32-bit access for better performance + ff16 = (volatile uint16_t*) ((uintptr_t) fifo+2); + ff8 = (volatile uint8_t *) ((uintptr_t) fifo+3); + }else { + ff16 = (volatile uint16_t*) fifo; + ff8 = ((volatile uint8_t*) fifo); + } + + uint8_t const* buf8 = (uint8_t const*) buf; + while (len >= 2) { - reg->u16 = *(const uint16_t *)addr; - addr += 2; + *ff16 = tu_unaligned_read16(buf8); + buf8 += 2; len -= 2; } - if (len) { - reg->u8 = *(const uint8_t *)addr; - ++addr; + + if (len > 0) { + *ff8 = *buf8; + ++buf8; } } -static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) +// Read data buffer <-- hw fifo +static void pipe_read_packet(rusb2_reg_t * rusb, void *buf, volatile void *fifo, unsigned len) { - uint8_t *p = (uint8_t*)buf; + (void) rusb; + + // TODO 16/32-bit access for better performance + + uint8_t *p = (uint8_t*)buf; volatile uint8_t *reg = (volatile uint8_t*)fifo; /* byte access is always at base register address */ while (len--) *p++ = *reg; } -static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigned len, unsigned dir) -{ - static const struct { - void (*tu_fifo_get_info)(tu_fifo_t *f, tu_fifo_buffer_info_t *info); - void (*tu_fifo_advance)(tu_fifo_t *f, uint16_t n); - void (*pipe_read_write)(void *buf, volatile void *fifo, unsigned len); - } ops[] = { - /* OUT */ {tu_fifo_get_write_info,tu_fifo_advance_write_pointer,pipe_read_packet}, - /* IN */ {tu_fifo_get_read_info, tu_fifo_advance_read_pointer, pipe_write_packet}, - }; +// Write data sw fifo --> hw fifo +static void pipe_write_packet_ff(rusb2_reg_t * rusb, tu_fifo_t *f, volatile void *fifo, uint16_t total_len) { tu_fifo_buffer_info_t info; - ops[dir].tu_fifo_get_info(f, &info); - unsigned total_len = len; - len = TU_MIN(total_len, info.len_lin); - ops[dir].pipe_read_write(info.ptr_lin, fifo, len); - unsigned rem = total_len - len; + tu_fifo_get_read_info(f, &info); + + uint16_t count = tu_min16(total_len, info.len_lin); + pipe_write_packet(rusb, info.ptr_lin, fifo, count); + + uint16_t rem = total_len - count; + if (rem) { + rem = tu_min16(rem, info.len_wrap); + pipe_write_packet(rusb, info.ptr_wrap, fifo, rem); + count += rem; + } + + tu_fifo_advance_read_pointer(f, count); +} + +// Read data sw fifo <-- hw fifo +static void pipe_read_packet_ff(rusb2_reg_t * rusb, tu_fifo_t *f, volatile void *fifo, uint16_t total_len) { + tu_fifo_buffer_info_t info; + tu_fifo_get_write_info(f, &info); + + uint16_t count = tu_min16(total_len, info.len_lin); + pipe_read_packet(rusb, info.ptr_lin, fifo, count); + + uint16_t rem = total_len - count; if (rem) { - len = TU_MIN(rem, info.len_wrap); - ops[dir].pipe_read_write(info.ptr_wrap, fifo, len); - rem -= len; + rem = tu_min16(rem, info.len_wrap); + pipe_read_packet(rusb, info.ptr_wrap, fifo, rem); + count += rem; } - ops[dir].tu_fifo_advance(f, total_len - rem); + + tu_fifo_advance_write_pointer(f, count); } -static bool pipe0_xfer_in(void) +//--------------------------------------------------------------------+ +// Pipe Transfer +//--------------------------------------------------------------------+ + +static bool pipe0_xfer_in(rusb2_reg_t* rusb) { pipe_state_t *pipe = &_dcd.pipe[0]; const unsigned rem = pipe->remaining; + if (!rem) { pipe->buf = NULL; return true; } - const unsigned mps = edpt0_max_packet_size(); - const unsigned len = TU_MIN(mps, rem); + + const uint16_t mps = edpt0_max_packet_size(rusb); + const uint16_t len = tu_min16(mps, rem); void *buf = pipe->buf; + if (len) { if (pipe->ff) { - pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&RUSB2->CFIFO, len, TUSB_DIR_IN); + pipe_write_packet_ff(rusb, (tu_fifo_t*)buf, (volatile void*)&rusb->CFIFO, len); } else { - pipe_write_packet(buf, (volatile void*)&RUSB2->CFIFO, len); + pipe_write_packet(rusb, buf, (volatile void*)&rusb->CFIFO, len); pipe->buf = (uint8_t*)buf + len; } } + if (len < mps) { - RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; + rusb->CFIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; } + pipe->remaining = rem - len; return false; } -static bool pipe0_xfer_out(void) +static bool pipe0_xfer_out(rusb2_reg_t* rusb) { pipe_state_t *pipe = &_dcd.pipe[0]; const unsigned rem = pipe->remaining; - const unsigned mps = edpt0_max_packet_size(); - const unsigned vld = RUSB2->CFIFOCTR_b.DTLN; - const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); + const uint16_t mps = edpt0_max_packet_size(rusb); + const uint16_t vld = rusb->CFIFOCTR_b.DTLN; + const uint16_t len = tu_min16(tu_min16(rem, mps), vld); void *buf = pipe->buf; + if (len) { if (pipe->ff) { - pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&RUSB2->CFIFO, len, TUSB_DIR_OUT); + pipe_read_packet_ff(rusb, (tu_fifo_t*)buf, (volatile void*)&rusb->CFIFO, len); } else { - pipe_read_packet(buf, (volatile void*)&RUSB2->CFIFO, len); + pipe_read_packet(rusb, buf, (volatile void*)&rusb->CFIFO, len); pipe->buf = (uint8_t*)buf + len; } } + if (len < mps) { - RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; + rusb->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; } + pipe->remaining = rem - len; if ((len < mps) || (rem == len)) { pipe->buf = NULL; return true; } + return false; } -static bool pipe_xfer_in(unsigned num) +static bool pipe_xfer_in(rusb2_reg_t* rusb, unsigned num) { pipe_state_t *pipe = &_dcd.pipe[num]; const unsigned rem = pipe->remaining; @@ -293,119 +343,141 @@ static bool pipe_xfer_in(unsigned num) return true; } - RUSB2->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_16BIT | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0); - const unsigned mps = edpt_max_packet_size(num); - pipe_wait_for_ready(num); - const unsigned len = TU_MIN(rem, mps); + rusb->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_16BIT | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0); + const uint16_t mps = edpt_max_packet_size(rusb, num); + pipe_wait_for_ready(rusb, num); + const uint16_t len = tu_min16(rem, mps); void *buf = pipe->buf; + if (len) { if (pipe->ff) { - pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&RUSB2->D0FIFO, len, TUSB_DIR_IN); + pipe_write_packet_ff(rusb, (tu_fifo_t*)buf, (volatile void*)&rusb->D0FIFO, len); } else { - pipe_write_packet(buf, (volatile void*)&RUSB2->D0FIFO, len); + pipe_write_packet(rusb, buf, (volatile void*)&rusb->D0FIFO, len); pipe->buf = (uint8_t*)buf + len; } } + if (len < mps) { - RUSB2->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; + rusb->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; } - RUSB2->D0FIFOSEL = 0; - while (RUSB2->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */ + + rusb->D0FIFOSEL = 0; + while (rusb->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */ + pipe->remaining = rem - len; + return false; } -static bool pipe_xfer_out(unsigned num) +static bool pipe_xfer_out(rusb2_reg_t* rusb, unsigned num) { pipe_state_t *pipe = &_dcd.pipe[num]; - const unsigned rem = pipe->remaining; + const uint16_t rem = pipe->remaining; + + rusb->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_8BIT; + const uint16_t mps = edpt_max_packet_size(rusb, num); + pipe_wait_for_ready(rusb, num); - RUSB2->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_8BIT; - const unsigned mps = edpt_max_packet_size(num); - pipe_wait_for_ready(num); - const unsigned vld = RUSB2->D0FIFOCTR_b.DTLN; - const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); + const uint16_t vld = rusb->D0FIFOCTR_b.DTLN; + const uint16_t len = tu_min16(tu_min16(rem, mps), vld); void *buf = pipe->buf; + if (len) { if (pipe->ff) { - pipe_read_write_packet_ff((tu_fifo_t*)buf, (volatile void*)&RUSB2->D0FIFO, len, TUSB_DIR_OUT); + pipe_read_packet_ff(rusb, (tu_fifo_t*)buf, (volatile void*)&rusb->D0FIFO, len); } else { - pipe_read_packet(buf, (volatile void*)&RUSB2->D0FIFO, len); + pipe_read_packet(rusb, buf, (volatile void*)&rusb->D0FIFO, len); pipe->buf = (uint8_t*)buf + len; } } + if (len < mps) { - RUSB2->D0FIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; + rusb->D0FIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; } - RUSB2->D0FIFOSEL = 0; - while (RUSB2->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */ + + rusb->D0FIFOSEL = 0; + while (rusb->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */ + pipe->remaining = rem - len; if ((len < mps) || (rem == len)) { pipe->buf = NULL; return NULL != buf; } + return false; } static void process_setup_packet(uint8_t rhport) { - uint16_t setup_packet[4]; - if (0 == (RUSB2->INTSTS0 & RUSB2_INTSTS0_VALID_Msk)) return; - RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; - setup_packet[0] = tu_le16toh(RUSB2->USBREQ); - setup_packet[1] = RUSB2->USBVAL; - setup_packet[2] = RUSB2->USBINDX; - setup_packet[3] = RUSB2->USBLENG; - RUSB2->INTSTS0 = ~((uint16_t)RUSB2_INTSTS0_VALID_Msk); + rusb2_reg_t* rusb = RUSB2_REG(rhport); + if (0 == (rusb->INTSTS0 & RUSB2_INTSTS0_VALID_Msk)) return; + + rusb->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; + uint16_t setup_packet[4] = { + tu_htole16(rusb->USBREQ), + tu_htole16(rusb->USBVAL), + tu_htole16(rusb->USBINDX), + tu_htole16(rusb->USBLENG) + }; + + rusb->INTSTS0 = ~((uint16_t) RUSB2_INTSTS0_VALID_Msk); dcd_event_setup_received(rhport, (const uint8_t*)&setup_packet[0], true); } static void process_status_completion(uint8_t rhport) { + rusb2_reg_t* rusb = RUSB2_REG(rhport); uint8_t ep_addr; /* Check the data stage direction */ - if (RUSB2->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) { + if (rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) { /* IN transfer. */ ep_addr = tu_edpt_addr(0, TUSB_DIR_IN); } else { /* OUT transfer. */ ep_addr = tu_edpt_addr(0, TUSB_DIR_OUT); } + dcd_event_xfer_complete(rhport, ep_addr, 0, XFER_RESULT_SUCCESS, true); } -static bool process_pipe0_xfer(int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes) +static bool process_pipe0_xfer(rusb2_reg_t* rusb, int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes) { /* configure fifo direction and access unit settings */ - if (ep_addr) { /* IN, 2 bytes */ - RUSB2->CFIFOSEL = RUSB2_CFIFOSEL_ISEL_WRITE | RUSB2_FIFOSEL_MBW_16BIT | - (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0); - while (!(RUSB2->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE)) ; - } else { /* OUT, a byte */ - RUSB2->CFIFOSEL = RUSB2_FIFOSEL_MBW_8BIT; - while (RUSB2->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) ; + if ( ep_addr ) { + /* IN, 2 bytes */ + rusb->CFIFOSEL = RUSB2_CFIFOSEL_ISEL_WRITE | RUSB2_FIFOSEL_MBW_16BIT | + (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0); + while ( !(rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) ) {} + } else { + /* OUT, a byte */ + rusb->CFIFOSEL = RUSB2_FIFOSEL_MBW_8BIT; + while ( rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE ) {} } pipe_state_t *pipe = &_dcd.pipe[0]; pipe->ff = buffer_type; pipe->length = total_bytes; pipe->remaining = total_bytes; - if (total_bytes) { - pipe->buf = buffer; - if (ep_addr) { /* IN */ - TU_ASSERT(RUSB2->DCPCTR_b.BSTS && (RUSB2->USBREQ & 0x80)); - pipe0_xfer_in(); + + if ( total_bytes ) { + pipe->buf = buffer; + if ( ep_addr ) { + /* IN */ + TU_ASSERT(rusb->DCPCTR_b.BSTS && (rusb->USBREQ & 0x80)); + pipe0_xfer_in(rusb); } - RUSB2->DCPCTR = RUSB2_PIPE_CTR_PID_BUF; + rusb->DCPCTR = RUSB2_PIPE_CTR_PID_BUF; } else { /* ZLP */ - pipe->buf = NULL; - RUSB2->DCPCTR = RUSB2_DCPCTR_CCPL_Msk | RUSB2_PIPE_CTR_PID_BUF; + pipe->buf = NULL; + rusb->DCPCTR = RUSB2_DCPCTR_CCPL_Msk | RUSB2_PIPE_CTR_PID_BUF; } + return true; } -static bool process_pipe_xfer(int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes) +static bool process_pipe_xfer(rusb2_reg_t* rusb, int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes) { const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir = tu_edpt_dir(ep_addr); @@ -418,49 +490,55 @@ static bool process_pipe_xfer(int buffer_type, uint8_t ep_addr, void* buffer, ui pipe->buf = buffer; pipe->length = total_bytes; pipe->remaining = total_bytes; - if (dir) { /* IN */ + + if (dir) { + /* IN */ if (total_bytes) { - pipe_xfer_in(num); - } else { /* ZLP */ - RUSB2->D0FIFOSEL = num; - pipe_wait_for_ready(num); - RUSB2->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; - RUSB2->D0FIFOSEL = 0; - while (RUSB2->D0FIFOSEL_b.CURPIPE) ; /* if CURPIPE bits changes, check written value */ + pipe_xfer_in(rusb, num); + } else { + /* ZLP */ + rusb->D0FIFOSEL = num; + pipe_wait_for_ready(rusb, num); + rusb->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; + rusb->D0FIFOSEL = 0; + /* if CURPIPE bits changes, check written value */ + while (rusb->D0FIFOSEL_b.CURPIPE) {} } } else { -#if defined(__CCRX__) - __evenaccess volatile reg_pipetre_t *pt = get_pipetre(num); -#else - volatile reg_pipetre_t *pt = get_pipetre(num); -#endif + // OUT + volatile reg_pipetre_t *pt = get_pipetre(rusb, num); + if (pt) { - const unsigned mps = edpt_max_packet_size(num); - volatile uint16_t *ctr = get_pipectr(num); + const uint16_t mps = edpt_max_packet_size(rusb, num); + volatile uint16_t *ctr = get_pipectr(rusb, num); + if (*ctr & 0x3) *ctr = RUSB2_PIPE_CTR_PID_NAK; + pt->TRE = TU_BIT(8); pt->TRN = (total_bytes + mps - 1) / mps; pt->TRENB = 1; *ctr = RUSB2_PIPE_CTR_PID_BUF; } } - // TU_LOG1("X %x %d %d\r\n", ep_addr, total_bytes, buffer_type); + + // TU_LOG2("X %x %d %d\r\n", ep_addr, total_bytes, buffer_type); return true; } -static bool process_edpt_xfer(int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes) +static bool process_edpt_xfer(rusb2_reg_t* rusb, int buffer_type, uint8_t ep_addr, void* buffer, uint16_t total_bytes) { const unsigned epn = tu_edpt_number(ep_addr); if (0 == epn) { - return process_pipe0_xfer(buffer_type, ep_addr, buffer, total_bytes); + return process_pipe0_xfer(rusb, buffer_type, ep_addr, buffer, total_bytes); } else { - return process_pipe_xfer(buffer_type, ep_addr, buffer, total_bytes); + return process_pipe_xfer(rusb, buffer_type, ep_addr, buffer, total_bytes); } } static void process_pipe0_bemp(uint8_t rhport) { - bool completed = pipe0_xfer_in(); + rusb2_reg_t* rusb = RUSB2_REG(rhport); + bool completed = pipe0_xfer_in(rusb); if (completed) { pipe_state_t *pipe = &_dcd.pipe[0]; dcd_event_xfer_complete(rhport, tu_edpt_addr(0, TUSB_DIR_IN), @@ -470,17 +548,20 @@ static void process_pipe0_bemp(uint8_t rhport) static void process_pipe_brdy(uint8_t rhport, unsigned num) { + rusb2_reg_t* rusb = RUSB2_REG(rhport); pipe_state_t *pipe = &_dcd.pipe[num]; const unsigned dir = tu_edpt_dir(pipe->ep); bool completed; - if (dir) { /* IN */ - completed = pipe_xfer_in(num); + if (dir) { + /* IN */ + completed = pipe_xfer_in(rusb, num); } else { + // OUT if (num) { - completed = pipe_xfer_out(num); + completed = pipe_xfer_out(rusb, num); } else { - completed = pipe0_xfer_out(); + completed = pipe0_xfer_out(rusb); } } if (completed) { @@ -493,39 +574,68 @@ static void process_pipe_brdy(uint8_t rhport, unsigned num) static void process_bus_reset(uint8_t rhport) { - RUSB2->BEMPENB = 1; - RUSB2->BRDYENB = 1; - RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; - RUSB2->D0FIFOSEL = 0; - while (RUSB2->D0FIFOSEL_b.CURPIPE) ; /* if CURPIPE bits changes, check written value */ - RUSB2->D1FIFOSEL = 0; - while (RUSB2->D1FIFOSEL_b.CURPIPE) ; /* if CURPIPE bits changes, check written value */ - volatile uint16_t *ctr = (volatile uint16_t*)((uintptr_t) (&RUSB2->PIPE_CTR[0])); - volatile uint16_t *tre = (volatile uint16_t*)((uintptr_t) (&RUSB2->PIPE_TR[0].E)); + rusb2_reg_t* rusb = RUSB2_REG(rhport); + + rusb->BEMPENB = 1; + rusb->BRDYENB = 1; + rusb->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; + + rusb->D0FIFOSEL = 0; + while (rusb->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */ + + rusb->D1FIFOSEL = 0; + while (rusb->D1FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */ + + volatile uint16_t *ctr = (volatile uint16_t*)((uintptr_t) (&rusb->PIPE_CTR[0])); + volatile uint16_t *tre = (volatile uint16_t*)((uintptr_t) (&rusb->PIPE_TR[0].E)); + for (int i = 1; i <= 5; ++i) { - RUSB2->PIPESEL = i; - RUSB2->PIPECFG = 0; + rusb->PIPESEL = i; + rusb->PIPECFG = 0; *ctr = RUSB2_PIPE_CTR_ACLRM_Msk; *ctr = 0; ++ctr; *tre = TU_BIT(8); tre += 2; } + for (int i = 6; i <= 9; ++i) { - RUSB2->PIPESEL = i; - RUSB2->PIPECFG = 0; + rusb->PIPESEL = i; + rusb->PIPECFG = 0; *ctr = RUSB2_PIPE_CTR_ACLRM_Msk; *ctr = 0; ++ctr; } tu_varclr(&_dcd); - dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); + + TU_LOG3("Bus reset, RHST = %u\r\n", rusb->DVSTCTR0_b.RHST); + tusb_speed_t speed; + switch(rusb->DVSTCTR0 & RUSB2_DVSTCTR0_RHST_Msk) { + case RUSB2_DVSTCTR0_RHST_LS: + speed = TUSB_SPEED_LOW; + break; + + case RUSB2_DVSTCTR0_RHST_FS: + speed = TUSB_SPEED_FULL; + break; + + case RUSB2_DVSTCTR0_RHST_HS: + speed = TUSB_SPEED_HIGH; + break; + + default: + TU_ASSERT(false, ); + } + + dcd_event_bus_reset(rhport, speed, true); } static void process_set_address(uint8_t rhport) { - const uint32_t addr = RUSB2->USBADDR_b.USBADDR; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + const uint16_t addr = rusb->USBADDR_b.USBADDR; if (!addr) return; + const tusb_control_request_t setup_packet = { #if defined(__CCRX__) .bmRequestType = { 0 }, /* Note: CCRX needs the braces over this struct member */ @@ -536,8 +646,9 @@ static void process_set_address(uint8_t rhport) .wValue = addr, .wIndex = 0, .wLength = 0, - }; - dcd_event_setup_received(rhport, (const uint8_t*)&setup_packet, true); + }; + + dcd_event_setup_received(rhport, (const uint8_t *) &setup_packet, true); } /*------------------------------------------------------------------*/ @@ -570,73 +681,97 @@ static void enable_interrupt(uint32_t pswi) void dcd_init(uint8_t rhport) { - (void)rhport; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + rusb2_module_start(rhport, true); -#if 0 // previously present in the rx driver before generalization - uint32_t pswi = disable_interrupt(); - SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | SYSTEM_PRCR_PRC1; - MSTP(USB0) = 0; - SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY; - enable_interrupt(pswi); -#endif +#ifdef RUSB2_SUPPORT_HIGHSPEED + if ( rusb2_is_highspeed_rhport(rhport) ) { + rusb->SYSCFG_b.HSE = 1; + + // leave CLKSEL as default (0x11) 24Mhz - RUSB2->SYSCFG_b.SCKE = 1; - while (!RUSB2->SYSCFG_b.SCKE) ; - RUSB2->SYSCFG_b.DRPD = 0; - RUSB2->SYSCFG_b.DCFM = 0; - RUSB2->SYSCFG_b.USBE = 1; + // Power and reset UTMI Phy + uint16_t physet = (rusb->PHYSET | RUSB2_PHYSET_PLLRESET_Msk) & ~RUSB2_PHYSET_DIRPD_Msk; + rusb->PHYSET = physet; + R_BSP_SoftwareDelay((uint32_t) 1, BSP_DELAY_UNITS_MILLISECONDS); + rusb->PHYSET_b.PLLRESET = 0; - // MCU specific PHY init - rusb2_phy_init(); + // set UTMI to operating mode and wait for PLL lock confirmation + rusb->LPSTS_b.SUSPENDM = 1; + while (!rusb->PLLSTA_b.PLLLOCK) {} - RUSB2->PHYSLEW = 0x5; - RUSB2->DPUSR0R_FS_b.FIXPHY0 = 0u; /* USB_BASE Transceiver Output fixed */ + rusb->SYSCFG_b.DRPD = 0; + rusb->SYSCFG_b.USBE = 1; + + // Set CPU bus wait time (fine tunne later) + // rusb2->BUSWAIT |= 0x0F00U; + + rusb->PHYSET_b.REPSEL = 1; + } else +#endif + { + rusb->SYSCFG_b.SCKE = 1; + while (!rusb->SYSCFG_b.SCKE) {} + rusb->SYSCFG_b.DRPD = 0; + rusb->SYSCFG_b.DCFM = 0; + rusb->SYSCFG_b.USBE = 1; + + // MCU specific PHY init + rusb2_phy_init(); + + rusb->PHYSLEW = 0x5; + rusb->DPUSR0R_FS_b.FIXPHY0 = 0u; /* USB_BASE Transceiver Output fixed */ + } /* Setup default control pipe */ - RUSB2->DCPMAXP_b.MXPS = 64; - RUSB2->INTENB0 = RUSB2_INTSTS0_VBINT_Msk | RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_BEMP_Msk | - RUSB2_INTSTS0_DVST_Msk | RUSB2_INTSTS0_CTRT_Msk | (USE_SOF ? RUSB2_INTSTS0_SOFR_Msk : 0) | - RUSB2_INTSTS0_RESM_Msk; - RUSB2->BEMPENB = 1; - RUSB2->BRDYENB = 1; + rusb->DCPMAXP_b.MXPS = 64; + + rusb->INTSTS0 = 0; + rusb->INTENB0 = RUSB2_INTSTS0_VBINT_Msk | RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_BEMP_Msk | + RUSB2_INTSTS0_DVST_Msk | RUSB2_INTSTS0_CTRT_Msk | (USE_SOF ? RUSB2_INTSTS0_SOFR_Msk : 0) | + RUSB2_INTSTS0_RESM_Msk; + rusb->BEMPENB = 1; + rusb->BRDYENB = 1; - if (RUSB2->INTSTS0_b.VBSTS) { + // If VBUS (detect) pin is not used, application need to call tud_connect() manually after tud_init() + if (rusb->INTSTS0_b.VBSTS) { dcd_connect(rhport); } } -void dcd_int_enable(uint8_t rhport) -{ +void dcd_int_enable(uint8_t rhport) { rusb2_int_enable(rhport); } -void dcd_int_disable(uint8_t rhport) -{ +void dcd_int_disable(uint8_t rhport) { rusb2_int_disable(rhport); } -void dcd_set_address(uint8_t rhport, uint8_t dev_addr) -{ - (void)rhport; - (void)dev_addr; +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { + (void) rhport; + (void) dev_addr; } void dcd_remote_wakeup(uint8_t rhport) { - (void)rhport; - RUSB2->DVSTCTR0_b.WKUP = 1; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + rusb->DVSTCTR0_b.WKUP = 1; } void dcd_connect(uint8_t rhport) { - (void)rhport; - RUSB2->SYSCFG_b.DPRPU = 1; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + + if ( rusb2_is_highspeed_rhport(rhport)) { + rusb->SYSCFG_b.CNEN = 1; + } + rusb->SYSCFG_b.DPRPU = 1; } void dcd_disconnect(uint8_t rhport) { - (void)rhport; - RUSB2->SYSCFG_b.DPRPU = 0; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + rusb->SYSCFG_b.DPRPU = 0; } void dcd_sof_enable(uint8_t rhport, bool en) @@ -654,30 +789,43 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { (void)rhport; + rusb2_reg_t * rusb = RUSB2_REG(rhport); const unsigned ep_addr = ep_desc->bEndpointAddress; const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir = tu_edpt_dir(ep_addr); const unsigned xfer = ep_desc->bmAttributes.xfer; const unsigned mps = tu_edpt_packet_size(ep_desc); - if (xfer == TUSB_XFER_ISOCHRONOUS && mps > 256) { - /* USBa supports up to 256 bytes */ - return false; + + if (xfer == TUSB_XFER_ISOCHRONOUS) { + // Fullspeed ISO is limit to 256 bytes + if ( !rusb2_is_highspeed_rhport(rhport) && mps > 256) { + return false; + } } const unsigned num = find_pipe(xfer); - if (!num) return false; + TU_ASSERT(num); + _dcd.pipe[num].ep = ep_addr; _dcd.ep[dir][epn] = num; /* setup pipe */ dcd_int_disable(rhport); - RUSB2->PIPESEL = num; - RUSB2->PIPEMAXP = mps; - volatile uint16_t *ctr = get_pipectr(num); + + if ( rusb2_is_highspeed_rhport(rhport) ) { + // FIXME shouldn't be after pipe selection and config, also the BUFNMB should be changed + // depending on the allocation scheme + rusb->PIPEBUF = 0x7C08; + } + + rusb->PIPESEL = num; + rusb->PIPEMAXP = mps; + volatile uint16_t *ctr = get_pipectr(rusb, num); *ctr = RUSB2_PIPE_CTR_ACLRM_Msk | RUSB2_PIPE_CTR_SQCLR_Msk; *ctr = 0; unsigned cfg = (dir << 4) | epn; + if (xfer == TUSB_XFER_BULK) { cfg |= (RUSB2_PIPECFG_TYPE_BULK | RUSB2_PIPECFG_SHTNAK_Msk | RUSB2_PIPECFG_DBLB_Msk); } else if (xfer == TUSB_XFER_INTERRUPT) { @@ -685,13 +833,16 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) } else { cfg |= (RUSB2_PIPECFG_TYPE_ISO | RUSB2_PIPECFG_DBLB_Msk); } - RUSB2->PIPECFG = cfg; - RUSB2->BRDYSTS = 0x1FFu ^ TU_BIT(num); - RUSB2->BRDYENB |= TU_BIT(num); + + rusb->PIPECFG = cfg; + rusb->BRDYSTS = 0x1FFu ^ TU_BIT(num); + rusb->BRDYENB |= TU_BIT(num); + 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_LOG1("O %d %x %x\r\n", rusb->PIPESEL, rusb->PIPECFG, rusb->PIPEMAXP); dcd_int_enable(rhport); return true; @@ -711,26 +862,28 @@ void dcd_edpt_close_all(uint8_t rhport) void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { - (void)rhport; + rusb2_reg_t * rusb = RUSB2_REG(rhport); const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir = tu_edpt_dir(ep_addr); const unsigned num = _dcd.ep[dir][epn]; - RUSB2->BRDYENB &= ~TU_BIT(num); - volatile uint16_t *ctr = get_pipectr(num); + rusb->BRDYENB &= ~TU_BIT(num); + volatile uint16_t *ctr = get_pipectr(rusb, num); *ctr = 0; - RUSB2->PIPESEL = num; - RUSB2->PIPECFG = 0; + rusb->PIPESEL = num; + rusb->PIPECFG = 0; _dcd.pipe[num].ep = 0; _dcd.ep[dir][epn] = 0; } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { - bool r; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + dcd_int_disable(rhport); - r = process_edpt_xfer(0, ep_addr, buffer, total_bytes); + bool r = process_edpt_xfer(rusb, 0, ep_addr, buffer, total_bytes); dcd_int_enable(rhport); + return r; } @@ -738,10 +891,12 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_ { // USB buffers always work in bytes so to avoid unnecessary divisions we demand item_size = 1 TU_ASSERT(ff->item_size == 1); - bool r; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + dcd_int_disable(rhport); - r = process_edpt_xfer(1, ep_addr, ff, total_bytes); + bool r = process_edpt_xfer(rusb, 1, ep_addr, ff, total_bytes); dcd_int_enable(rhport); + return r; } @@ -758,8 +913,10 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { + rusb2_reg_t * rusb = RUSB2_REG(rhport); volatile uint16_t *ctr = ep_addr_to_pipectr(rhport, ep_addr); if (!ctr) return; + dcd_int_disable(rhport); *ctr = RUSB2_PIPE_CTR_SQCLR_Msk; @@ -767,8 +924,8 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) *ctr = RUSB2_PIPE_CTR_PID_BUF; } else { const unsigned num = _dcd.ep[0][tu_edpt_number(ep_addr)]; - RUSB2->PIPESEL = num; - if (RUSB2->PIPECFG_b.TYPE != 1) { + rusb->PIPESEL = num; + if (rusb->PIPECFG_b.TYPE != 1) { *ctr = RUSB2_PIPE_CTR_PID_BUF; } } @@ -780,73 +937,94 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) //--------------------------------------------------------------------+ void dcd_int_handler(uint8_t rhport) { - (void)rhport; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + + uint16_t is0 = rusb->INTSTS0; - unsigned is0 = RUSB2->INTSTS0; /* clear active bits except VALID (don't write 0 to already cleared bits according to the HW manual) */ - RUSB2->INTSTS0 = ~((RUSB2_INTSTS0_CTRT_Msk | RUSB2_INTSTS0_DVST_Msk | RUSB2_INTSTS0_SOFR_Msk | - RUSB2_INTSTS0_RESM_Msk | RUSB2_INTSTS0_VBINT_Msk) & is0) | RUSB2_INTSTS0_VALID_Msk; - if (is0 & RUSB2_INTSTS0_VBINT_Msk) { - if (RUSB2->INTSTS0_b.VBSTS) { + rusb->INTSTS0 = ~((RUSB2_INTSTS0_CTRT_Msk | RUSB2_INTSTS0_DVST_Msk | RUSB2_INTSTS0_SOFR_Msk | + RUSB2_INTSTS0_RESM_Msk | RUSB2_INTSTS0_VBINT_Msk) & is0) | RUSB2_INTSTS0_VALID_Msk; + + // VBUS changes + if ( is0 & RUSB2_INTSTS0_VBINT_Msk ) { + if ( rusb->INTSTS0_b.VBSTS ) { dcd_connect(rhport); } else { dcd_disconnect(rhport); } } - if (is0 & RUSB2_INTSTS0_RESM_Msk) { + + // Resumed + if ( is0 & RUSB2_INTSTS0_RESM_Msk ) { dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); -#if (0==USE_SOF) - RUSB2->INTENB0_b.SOFE = 0; +#if (0 == USE_SOF) + rusb->INTENB0_b.SOFE = 0; #endif } - if ((is0 & RUSB2_INTSTS0_SOFR_Msk) && RUSB2->INTENB0_b.SOFE) { + + // SOF received + if ( (is0 & RUSB2_INTSTS0_SOFR_Msk) && rusb->INTENB0_b.SOFE ) { // USBD will exit suspended mode when SOF event is received dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); #if (0 == USE_SOF) - RUSB2->INTENB0_b.SOFE = 0; + rusb->INTENB0_b.SOFE = 0; #endif } - if (is0 & RUSB2_INTSTS0_DVST_Msk) { + + // Device state changes + if ( is0 & RUSB2_INTSTS0_DVST_Msk ) { switch (is0 & RUSB2_INTSTS0_DVSQ_Msk) { - case RUSB2_INTSTS0_DVSQ_STATE_DEF: - process_bus_reset(rhport); - break; - case RUSB2_INTSTS0_DVSQ_STATE_ADDR: - process_set_address(rhport); - break; - case RUSB2_INTSTS0_DVSQ_STATE_SUSP0: - case RUSB2_INTSTS0_DVSQ_STATE_SUSP1: - case RUSB2_INTSTS0_DVSQ_STATE_SUSP2: - case RUSB2_INTSTS0_DVSQ_STATE_SUSP3: - dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); -#if (0==USE_SOF) - RUSB2->INTENB0_b.SOFE = 1; + case RUSB2_INTSTS0_DVSQ_STATE_DEF: + process_bus_reset(rhport); + break; + + case RUSB2_INTSTS0_DVSQ_STATE_ADDR: + process_set_address(rhport); + break; + + case RUSB2_INTSTS0_DVSQ_STATE_SUSP0: + case RUSB2_INTSTS0_DVSQ_STATE_SUSP1: + case RUSB2_INTSTS0_DVSQ_STATE_SUSP2: + case RUSB2_INTSTS0_DVSQ_STATE_SUSP3: + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); +#if (0 == USE_SOF) + rusb->INTENB0_b.SOFE = 1; #endif - default: - break; + + default: break; } } - if (is0 & RUSB2_INTSTS0_CTRT_Msk) { - if (is0 & RUSB2_INTSTS0_CTSQ_CTRL_RDATA) { + +// if ( is0 & RUSB2_INTSTS0_NRDY_Msk ) { +// rusb->NRDYSTS = 0; +// } + + // Control transfer stage changes + if ( is0 & RUSB2_INTSTS0_CTRT_Msk ) { + if ( is0 & RUSB2_INTSTS0_CTSQ_CTRL_RDATA ) { /* A setup packet has been received. */ process_setup_packet(rhport); - } else if (0 == (is0 & RUSB2_INTSTS0_CTSQ_Msk)) { + } else if ( 0 == (is0 & RUSB2_INTSTS0_CTSQ_Msk) ) { /* A ZLP has been sent/received. */ process_status_completion(rhport); } } - if (is0 & RUSB2_INTSTS0_BEMP_Msk) { - const unsigned s = RUSB2->BEMPSTS; - RUSB2->BEMPSTS = 0; - if (s & 1) { + + // Buffer empty + if ( is0 & RUSB2_INTSTS0_BEMP_Msk ) { + const uint16_t s = rusb->BEMPSTS; + rusb->BEMPSTS = 0; + if ( s & 1 ) { process_pipe0_bemp(rhport); } } - if (is0 & RUSB2_INTSTS0_BRDY_Msk) { - const unsigned m = RUSB2->BRDYENB; - unsigned s = RUSB2->BRDYSTS & m; + + // Buffer ready + if ( is0 & RUSB2_INTSTS0_BRDY_Msk ) { + const unsigned m = rusb->BRDYENB; + unsigned s = rusb->BRDYSTS & m; /* clear active bits (don't write 0 to already cleared bits according to the HW manual) */ - RUSB2->BRDYSTS = ~s; + rusb->BRDYSTS = ~s; while (s) { #if defined(__CCRX__) static const int Mod37BitPosition[] = { diff --git a/src/portable/renesas/rusb2/hcd_rusb2.c b/src/portable/renesas/rusb2/hcd_rusb2.c index 0e6fa1618..55bf6de4d 100644 --- a/src/portable/renesas/rusb2/hcd_rusb2.c +++ b/src/portable/renesas/rusb2/hcd_rusb2.c @@ -27,8 +27,7 @@ #include "tusb_option.h" -#if CFG_TUH_ENABLED && (TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N) || \ - TU_CHECK_MCU(OPT_MCU_RAXXX)) +#if CFG_TUH_ENABLED && defined(TUP_USBIP_RUSB2) #include "host/hcd.h" #include "rusb2_type.h" @@ -41,33 +40,15 @@ #error "Unsupported MCU" #endif +#define TU_RUSB2_HCD_DBG 2 + //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION //--------------------------------------------------------------------+ -/* LINK core registers */ -#if defined(__CCRX__) - #define RUSB2 ((RUSB2_REG_t __evenaccess*) RUSB2_REG_BASE) -#else - #define RUSB2 ((RUSB2_REG_t*) RUSB2_REG_BASE) -#endif - TU_ATTR_PACKED_BEGIN TU_ATTR_BIT_FIELD_ORDER_BEGIN -typedef struct TU_ATTR_PACKED { - union { - struct { - uint16_t : 8; - uint16_t TRCLR: 1; - uint16_t TRENB: 1; - uint16_t : 0; - }; - uint16_t TRE; - }; - uint16_t TRN; -} reg_pipetre_t; - typedef union TU_ATTR_PACKED { struct { volatile uint16_t u8: 8; @@ -104,83 +85,102 @@ typedef struct //--------------------------------------------------------------------+ static hcd_data_t _hcd; -static unsigned find_pipe(unsigned xfer) -{ - switch (xfer) { - case TUSB_XFER_ISOCHRONOUS: - for (int i = 1; i <= 2; ++i) { - if (0 == _hcd.pipe[i].ep) return i; - } - break; - case TUSB_XFER_BULK: - for (int i = 3; i <= 5; ++i) { - if (0 == _hcd.pipe[i].ep) return i; - } - for (int i = 1; i <= 1; ++i) { - if (0 == _hcd.pipe[i].ep) return i; - } - break; - case TUSB_XFER_INTERRUPT: - for (int i = 6; i <= 9; ++i) { - if (0 == _hcd.pipe[i].ep) return i; - } - break; - default: - /* No support for control transfer */ - break; +// TODO merged with DCD +// Transfer conditions specifiable for each pipe: +// - Pipe 0: Control transfer with 64-byte single buffer +// - Pipes 1 and 2: Bulk isochronous transfer continuous transfer mode with programmable buffer size up +// to 2 KB and optional double buffer +// - Pipes 3 to 5: Bulk transfer continuous transfer mode with programmable buffer size up to 2 KB and +// optional double buffer +// - Pipes 6 to 9: Interrupt transfer with 64-byte single buffer +enum { + PIPE_1ST_BULK = 3, + PIPE_1ST_INTERRUPT = 6, + PIPE_COUNT = 10, +}; + +static unsigned find_pipe(unsigned xfer) { + switch ( xfer ) { + case TUSB_XFER_ISOCHRONOUS: + for (int i = 1; i < PIPE_1ST_BULK; ++i) { + if ( 0 == _hcd.pipe[i].ep ) return i; + } + break; + + case TUSB_XFER_BULK: + for (int i = PIPE_1ST_BULK; i < PIPE_1ST_INTERRUPT; ++i) { + if ( 0 == _hcd.pipe[i].ep ) return i; + } + for (int i = 1; i < PIPE_1ST_BULK; ++i) { + if ( 0 == _hcd.pipe[i].ep ) return i; + } + break; + + case TUSB_XFER_INTERRUPT: + for (int i = PIPE_1ST_INTERRUPT; i < PIPE_COUNT; ++i) { + if ( 0 == _hcd.pipe[i].ep ) return i; + } + break; + + default: + /* No support for control transfer */ + break; } return 0; } -static volatile uint16_t* get_pipectr(unsigned num) +static volatile uint16_t* get_pipectr(rusb2_reg_t *rusb, unsigned num) { if (num) { - return (volatile uint16_t*)&(RUSB2->PIPE_CTR[num - 1]); + return (volatile uint16_t*)&(rusb->PIPE_CTR[num - 1]); } else { - return (volatile uint16_t*)&(RUSB2->DCPCTR); + return (volatile uint16_t*)&(rusb->DCPCTR); } } -static volatile reg_pipetre_t* get_pipetre(unsigned num) +static volatile reg_pipetre_t* get_pipetre(rusb2_reg_t *rusb, unsigned num) { volatile reg_pipetre_t* tre = NULL; if ((1 <= num) && (num <= 5)) { - tre = (volatile reg_pipetre_t*)&(RUSB2->PIPE_TR[num - 1].E); + tre = (volatile reg_pipetre_t*)&(rusb->PIPE_TR[num - 1].E); } return tre; } -static volatile uint16_t* addr_to_pipectr(uint8_t dev_addr, unsigned ep_addr) +static volatile uint16_t* addr_to_pipectr(uint8_t rhport, uint8_t dev_addr, unsigned ep_addr) { + rusb2_reg_t* rusb = RUSB2_REG(rhport); const unsigned epn = tu_edpt_number(ep_addr); + if (epn) { const unsigned dir_in = tu_edpt_dir(ep_addr); const unsigned num = _hcd.ep[dev_addr][dir_in][epn - 1]; - return get_pipectr(num); + return get_pipectr(rusb, num); } else { - return get_pipectr(0); + return get_pipectr(rusb, 0); } } -static unsigned edpt0_max_packet_size(void) +static uint16_t edpt0_max_packet_size(rusb2_reg_t* rusb) { - return RUSB2->DCPMAXP_b.MXPS; + return rusb->DCPMAXP_b.MXPS; } -static unsigned edpt_max_packet_size(unsigned num) +static uint16_t edpt_max_packet_size(rusb2_reg_t *rusb, unsigned num) { - RUSB2->PIPESEL = num; - return RUSB2->PIPEMAXP_b.MXPS; + rusb->PIPESEL = num; + return rusb->PIPEMAXP_b.MXPS; } -static inline void pipe_wait_for_ready(unsigned num) +static inline void pipe_wait_for_ready(rusb2_reg_t* rusb, unsigned num) { - while (RUSB2->D0FIFOSEL_b.CURPIPE != num) ; - while (!RUSB2->D0FIFOCTR_b.FRDY) ; + while (rusb->D0FIFOSEL_b.CURPIPE != num) ; + while (!rusb->D0FIFOCTR_b.FRDY) {} } static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) { + // NOTE: unlike DCD, Highspeed 32-bit FIFO does not need to adjust the fifo address volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; uintptr_t addr = (uintptr_t)buf; while (len >= 2) { @@ -201,33 +201,33 @@ static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) while (len--) *p++ = *reg; } -static bool pipe0_xfer_in(void) +static bool pipe0_xfer_in(rusb2_reg_t* rusb) { pipe_state_t *pipe = &_hcd.pipe[0]; const unsigned rem = pipe->remaining; - const unsigned mps = edpt0_max_packet_size(); - const unsigned vld = RUSB2->CFIFOCTR_b.DTLN; + const unsigned mps = edpt0_max_packet_size(rusb); + const unsigned vld = rusb->CFIFOCTR_b.DTLN; const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); void *buf = pipe->buf; if (len) { - RUSB2->DCPCTR = RUSB2_PIPE_CTR_PID_NAK; - pipe_read_packet(buf, (volatile void*)&RUSB2->CFIFO, len); + rusb->DCPCTR = RUSB2_PIPE_CTR_PID_NAK; + pipe_read_packet(buf, (volatile void*)&rusb->CFIFO, len); pipe->buf = (uint8_t*)buf + len; } if (len < mps) { - RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; + rusb->CFIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; } pipe->remaining = rem - len; if ((len < mps) || (rem == len)) { pipe->buf = NULL; return true; } - RUSB2->DCPCTR = RUSB2_PIPE_CTR_PID_BUF; + rusb->DCPCTR = RUSB2_PIPE_CTR_PID_BUF; return false; } -static bool pipe0_xfer_out(void) +static bool pipe0_xfer_out(rusb2_reg_t* rusb) { pipe_state_t *pipe = &_hcd.pipe[0]; const unsigned rem = pipe->remaining; @@ -235,40 +235,40 @@ static bool pipe0_xfer_out(void) pipe->buf = NULL; return true; } - const unsigned mps = edpt0_max_packet_size(); + const unsigned mps = edpt0_max_packet_size(rusb); const unsigned len = TU_MIN(mps, rem); void *buf = pipe->buf; if (len) { - pipe_write_packet(buf, (volatile void*)&RUSB2->CFIFO, len); + pipe_write_packet(buf, (volatile void*)&rusb->CFIFO, len); pipe->buf = (uint8_t*)buf + len; } if (len < mps) { - RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; + rusb->CFIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; } pipe->remaining = rem - len; return false; } -static bool pipe_xfer_in(unsigned num) +static bool pipe_xfer_in(rusb2_reg_t* rusb, unsigned num) { pipe_state_t *pipe = &_hcd.pipe[num]; const unsigned rem = pipe->remaining; - RUSB2->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_8BIT; - const unsigned mps = edpt_max_packet_size(num); - pipe_wait_for_ready(num); - const unsigned vld = RUSB2->D0FIFOCTR_b.DTLN; + rusb->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_8BIT; + const unsigned mps = edpt_max_packet_size(rusb, num); + pipe_wait_for_ready(rusb, num); + const unsigned vld = rusb->D0FIFOCTR_b.DTLN; const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); void *buf = pipe->buf; if (len) { - pipe_read_packet(buf, (volatile void*)&RUSB2->D0FIFO, len); + pipe_read_packet(buf, (volatile void*)&rusb->D0FIFO, len); pipe->buf = (uint8_t*)buf + len; } if (len < mps) { - RUSB2->D0FIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; + rusb->D0FIFOCTR = RUSB2_CFIFOCTR_BCLR_Msk; } - RUSB2->D0FIFOSEL = 0; - while (RUSB2->D0FIFOSEL_b.CURPIPE) ; /* if CURPIPE bits changes, check written value */ + rusb->D0FIFOSEL = 0; + while (rusb->D0FIFOSEL_b.CURPIPE) ; /* if CURPIPE bits changes, check written value */ pipe->remaining = rem - len; if ((len < mps) || (rem == len)) { pipe->buf = NULL; @@ -277,7 +277,7 @@ static bool pipe_xfer_in(unsigned num) return false; } -static bool pipe_xfer_out(unsigned num) +static bool pipe_xfer_out(rusb2_reg_t* rusb, unsigned num) { pipe_state_t *pipe = &_hcd.pipe[num]; const unsigned rem = pipe->remaining; @@ -287,36 +287,39 @@ static bool pipe_xfer_out(unsigned num) return true; } - RUSB2->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_16BIT | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0); - const unsigned mps = edpt_max_packet_size(num); - pipe_wait_for_ready(num); + rusb->D0FIFOSEL = num | RUSB2_FIFOSEL_MBW_16BIT | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0); + const unsigned mps = edpt_max_packet_size(rusb, num); + pipe_wait_for_ready(rusb, num); const unsigned len = TU_MIN(rem, mps); void *buf = pipe->buf; if (len) { - pipe_write_packet(buf, (volatile void*)&RUSB2->D0FIFO, len); + pipe_write_packet(buf, (volatile void*)&rusb->D0FIFO, len); pipe->buf = (uint8_t*)buf + len; } - if (len < mps) - RUSB2->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; - RUSB2->D0FIFOSEL = 0; - while (RUSB2->D0FIFOSEL_b.CURPIPE) ; /* if CURPIPE bits changes, check written value */ + if (len < mps) { + rusb->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; + } + rusb->D0FIFOSEL = 0; + while (rusb->D0FIFOSEL_b.CURPIPE) ; /* if CURPIPE bits changes, check written value */ pipe->remaining = rem - len; return false; } -static bool process_pipe0_xfer(uint8_t dev_addr, uint8_t ep_addr, void* buffer, uint16_t buflen) +static bool process_pipe0_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, void* buffer, uint16_t buflen) { (void)dev_addr; + + rusb2_reg_t* rusb = RUSB2_REG(rhport); const unsigned dir_in = tu_edpt_dir(ep_addr); /* configure fifo direction and access unit settings */ if (dir_in) { /* IN, a byte */ - RUSB2->CFIFOSEL = RUSB2_FIFOSEL_MBW_8BIT; - while (RUSB2->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) ; + rusb->CFIFOSEL = RUSB2_FIFOSEL_MBW_8BIT; + while (rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE) ; } else { /* OUT, 2 bytes */ - RUSB2->CFIFOSEL = RUSB2_CFIFOSEL_ISEL_WRITE | RUSB2_FIFOSEL_MBW_16BIT | + rusb->CFIFOSEL = RUSB2_CFIFOSEL_ISEL_WRITE | RUSB2_FIFOSEL_MBW_16BIT | (TU_BYTE_ORDER == TU_BIG_ENDIAN ? RUSB2_FIFOSEL_BIGEND : 0); - while (!(RUSB2->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE)) ; + while (!(rusb->CFIFOSEL & RUSB2_CFIFOSEL_ISEL_WRITE)) ; } pipe_state_t *pipe = &_hcd.pipe[0]; @@ -326,26 +329,28 @@ static bool process_pipe0_xfer(uint8_t dev_addr, uint8_t ep_addr, void* buffer, if (buflen) { pipe->buf = buffer; if (!dir_in) { /* OUT */ - TU_ASSERT(RUSB2->DCPCTR_b.BSTS && (RUSB2->USBREQ & 0x80)); - pipe0_xfer_out(); + TU_ASSERT(rusb->DCPCTR_b.BSTS && (rusb->USBREQ & 0x80)); + pipe0_xfer_out(rusb); } } else { /* ZLP */ pipe->buf = NULL; if (!dir_in) { /* OUT */ - RUSB2->CFIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; + rusb->CFIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; } - if (dir_in == RUSB2->DCPCFG_b.DIR) { - TU_ASSERT(RUSB2_PIPE_CTR_PID_NAK == RUSB2->DCPCTR_b.PID); - RUSB2->DCPCTR_b.SQSET = 1; - RUSB2->DCPCFG_b.DIR = dir_in ^ 1; + if (dir_in == rusb->DCPCFG_b.DIR) { + TU_ASSERT(RUSB2_PIPE_CTR_PID_NAK == rusb->DCPCTR_b.PID); + rusb->DCPCTR_b.SQSET = 1; + rusb->DCPCFG_b.DIR = dir_in ^ 1; } } - RUSB2->DCPCTR = RUSB2_PIPE_CTR_PID_BUF; + rusb->DCPCTR = RUSB2_PIPE_CTR_PID_BUF; return true; } -static bool process_pipe_xfer(uint8_t dev_addr, uint8_t ep_addr, void *buffer, uint16_t buflen) +static bool process_pipe_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, void *buffer, uint16_t buflen) { + rusb2_reg_t* rusb = RUSB2_REG(rhport); + const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir_in = tu_edpt_dir(ep_addr); const unsigned num = _hcd.ep[dev_addr - 1][dir_in][epn - 1]; @@ -358,19 +363,19 @@ static bool process_pipe_xfer(uint8_t dev_addr, uint8_t ep_addr, void *buffer, u pipe->remaining = buflen; if (!dir_in) { /* OUT */ if (buflen) { - pipe_xfer_out(num); + pipe_xfer_out(rusb, num); } else { /* ZLP */ - RUSB2->D0FIFOSEL = num; - pipe_wait_for_ready(num); - RUSB2->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; - RUSB2->D0FIFOSEL = 0; - while (RUSB2->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */ + rusb->D0FIFOSEL = num; + pipe_wait_for_ready(rusb, num); + rusb->D0FIFOCTR = RUSB2_CFIFOCTR_BVAL_Msk; + rusb->D0FIFOSEL = 0; + while (rusb->D0FIFOSEL_b.CURPIPE) {} /* if CURPIPE bits changes, check written value */ } } else { - volatile uint16_t *ctr = get_pipectr(num); - volatile reg_pipetre_t *pt = get_pipetre(num); + volatile uint16_t *ctr = get_pipectr(rusb, num); + volatile reg_pipetre_t *pt = get_pipetre(rusb, num); if (pt) { - const unsigned mps = edpt_max_packet_size(num); + const unsigned mps = edpt_max_packet_size(rusb, num); if (*ctr & 0x3) *ctr = RUSB2_PIPE_CTR_PID_NAK; pt->TRE = TU_BIT(8); pt->TRN = (buflen + mps - 1) / mps; @@ -381,20 +386,20 @@ static bool process_pipe_xfer(uint8_t dev_addr, uint8_t ep_addr, void *buffer, u return true; } -static bool process_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, void* buffer, uint16_t buflen) +static bool process_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, void* buffer, uint16_t buflen) { const unsigned epn = tu_edpt_number(ep_addr); if (0 == epn) { - return process_pipe0_xfer(dev_addr, ep_addr, buffer, buflen); + return process_pipe0_xfer(rhport, dev_addr, ep_addr, buffer, buflen); } else { - return process_pipe_xfer(dev_addr, ep_addr, buffer, buflen); + return process_pipe_xfer(rhport, dev_addr, ep_addr, buffer, buflen); } } static void process_pipe0_bemp(uint8_t rhport) { - (void)rhport; - bool completed = pipe0_xfer_out(); + rusb2_reg_t* rusb = RUSB2_REG(rhport); + bool completed = pipe0_xfer_out(rusb); if (completed) { pipe_state_t *pipe = &_hcd.pipe[0]; hcd_event_xfer_complete(pipe->dev, @@ -406,13 +411,14 @@ static void process_pipe0_bemp(uint8_t rhport) static void process_pipe_nrdy(uint8_t rhport, unsigned num) { - (void)rhport; + rusb2_reg_t* rusb = RUSB2_REG(rhport); xfer_result_t result; - uint16_t volatile *ctr = get_pipectr(num); - // TU_LOG1("NRDY %d %x\n", num, *ctr); + uint16_t volatile *ctr = get_pipectr(rusb, num); + TU_LOG(TU_RUSB2_HCD_DBG, "NRDY %d %x\r\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]; @@ -423,25 +429,25 @@ static void process_pipe_nrdy(uint8_t rhport, unsigned num) static void process_pipe_brdy(uint8_t rhport, unsigned num) { - (void)rhport; + rusb2_reg_t* rusb = RUSB2_REG(rhport); pipe_state_t *pipe = &_hcd.pipe[num]; const unsigned dir_in = tu_edpt_dir(pipe->ep); bool completed; if (dir_in) { /* IN */ if (num) { - completed = pipe_xfer_in(num); + completed = pipe_xfer_in(rusb, num); } else { - completed = pipe0_xfer_in(); + completed = pipe0_xfer_in(rusb); } } else { - completed = pipe_xfer_out(num); + completed = pipe_xfer_out(rusb, num); } if (completed) { 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); } } @@ -475,126 +481,146 @@ static void enable_interrupt(uint32_t pswi) bool hcd_init(uint8_t rhport) { - (void)rhport; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + rusb2_module_start(rhport, true); -#if 0 // previously present in the rx driver before generalization - uint32_t pswi = disable_interrupt(); - SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY | SYSTEM_PRCR_PRC1; - MSTP(USB0) = 0; - SYSTEM.PRCR.WORD = SYSTEM_PRCR_PRKEY; - enable_interrupt(pswi); +#ifdef RUSB2_SUPPORT_HIGHSPEED + if (rusb2_is_highspeed_rhport(rhport) ) { + rusb->SYSCFG_b.HSE = 1; + rusb->PHYSET_b.HSEB = 0; + rusb->PHYSET_b.DIRPD = 0; + R_BSP_SoftwareDelay((uint32_t) 1, BSP_DELAY_UNITS_MILLISECONDS); + rusb->PHYSET_b.PLLRESET = 0; + rusb->LPSTS_b.SUSPENDM = 1; + while ( !rusb->PLLSTA_b.PLLLOCK ); + rusb->SYSCFG_b.DRPD = 1; + rusb->SYSCFG_b.DCFM = 1; + rusb->SYSCFG_b.DPRPU = 0; + rusb->SYSCFG_b.CNEN = 1; + rusb->BUSWAIT |= 0x0F00U; + rusb->SOFCFG_b.INTL = 1; + rusb->DVSTCTR0_b.VBUSEN = 1; + rusb->CFIFOSEL_b.MBW = 1; + rusb->D0FIFOSEL_b.MBW = 1; + rusb->D1FIFOSEL_b.MBW = 1; + rusb->INTSTS0 = 0; + for ( volatile int i = 0; i < 30000; ++i ); + rusb->SYSCFG_b.USBE = 1; + } else #endif + { + rusb->SYSCFG_b.SCKE = 1; + while ( !rusb->SYSCFG_b.SCKE ) {} + rusb->SYSCFG_b.DCFM = 1; // Host function + rusb->SYSCFG_b.DPRPU = 0; // Disable D+ pull up + rusb->SYSCFG_b.DRPD = 1; // Enable D+/D- pull down - RUSB2->SYSCFG_b.SCKE = 1; - while (!RUSB2->SYSCFG_b.SCKE) ; - RUSB2->SYSCFG_b.DPRPU = 0; - RUSB2->SYSCFG_b.DRPD = 0; - RUSB2->SYSCFG_b.DCFM = 1; - - RUSB2->DVSTCTR0_b.VBUSEN = 1; + rusb->DVSTCTR0_b.VBUSEN = 1; + for ( volatile int i = 0; i < 30000; ++i ) {} // FIXME do we need to wait here? how long ? + //R_BSP_SoftwareDelay(10, BSP_DELAY_UNITS_MILLISECONDS); + rusb->SYSCFG_b.USBE = 1; - RUSB2->SYSCFG_b.DRPD = 1; - for (volatile int i = 0; i < 30000; ++i) ; - RUSB2->SYSCFG_b.USBE = 1; + // MCU specific PHY init + rusb2_phy_init(); - // MCU specific PHY init - rusb2_phy_init(); - - RUSB2->PHYSLEW = 0x5; - RUSB2->DPUSR0R_FS_b.FIXPHY0 = 0u; /* Transceiver Output fixed */ + rusb->PHYSLEW = 0x5; + rusb->DPUSR0R_FS_b.FIXPHY0 = 0u; /* Transceiver Output fixed */ + } /* Setup default control pipe */ - RUSB2->DCPCFG = RUSB2_PIPECFG_SHTNAK_Msk; - RUSB2->DCPMAXP = 64; - RUSB2->INTENB0 = RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_NRDY_Msk | RUSB2_INTSTS0_BEMP_Msk; - RUSB2->INTENB1 = RUSB2_INTSTS1_SACK_Msk | RUSB2_INTSTS1_SIGN_Msk | RUSB2_INTSTS1_ATTCH_Msk | RUSB2_INTSTS1_DTCH_Msk; - RUSB2->BEMPENB = 1; - RUSB2->NRDYENB = 1; - RUSB2->BRDYENB = 1; + rusb->DCPCFG = RUSB2_PIPECFG_SHTNAK_Msk; + rusb->DCPMAXP = 64; + rusb->INTENB0 = RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_NRDY_Msk | RUSB2_INTSTS0_BEMP_Msk; + rusb->INTENB1 = RUSB2_INTSTS1_SACK_Msk | RUSB2_INTSTS1_SIGN_Msk | RUSB2_INTSTS1_ATTCH_Msk | RUSB2_INTSTS1_DTCH_Msk; + rusb->BEMPENB = 1; + rusb->NRDYENB = 1; + rusb->BRDYENB = 1; return true; } -void hcd_int_enable(uint8_t rhport) -{ +void hcd_int_enable(uint8_t rhport) { rusb2_int_enable(rhport); } -void hcd_int_disable(uint8_t rhport) -{ +void hcd_int_disable(uint8_t rhport) { rusb2_int_disable(rhport); } uint32_t hcd_frame_number(uint8_t rhport) { - (void)rhport; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + /* The device must be reset at least once after connection * in order to start the frame counter. */ if (_hcd.need_reset) hcd_port_reset(rhport); - return RUSB2->FRMNUM_b.FRNM; + return rusb->FRMNUM_b.FRNM; } /*--------------------------------------------------------------------+ * Port API *--------------------------------------------------------------------+*/ -bool hcd_port_connect_status(uint8_t rhport) -{ - (void)rhport; - return RUSB2->INTSTS1_b.ATTCH ? true : false; +bool hcd_port_connect_status(uint8_t rhport) { + rusb2_reg_t* rusb = RUSB2_REG(rhport); + return rusb->INTSTS1_b.ATTCH ? true : false; } -void hcd_port_reset(uint8_t rhport) -{ - RUSB2->DCPCTR = RUSB2_PIPE_CTR_PID_NAK; - while (RUSB2->DCPCTR_b.PBUSY) ; +void hcd_port_reset(uint8_t rhport) { + rusb2_reg_t* rusb = RUSB2_REG(rhport); + rusb->DCPCTR = RUSB2_PIPE_CTR_PID_NAK; + while (rusb->DCPCTR_b.PBUSY) {} + hcd_int_disable(rhport); - RUSB2->DVSTCTR0_b.UACT = 0; - if (RUSB2->DCPCTR_b.SUREQ) { - RUSB2->DCPCTR_b.SUREQCLR = 1; + rusb->DVSTCTR0_b.UACT = 0; + if (rusb->DCPCTR_b.SUREQ) { + rusb->DCPCTR_b.SUREQCLR = 1; } hcd_int_enable(rhport); + /* Reset should be asserted 10-20ms. */ - RUSB2->DVSTCTR0_b.USBRST = 1; - for (volatile int i = 0; i < 2400000; ++i) ; - RUSB2->DVSTCTR0_b.USBRST = 0; - RUSB2->DVSTCTR0_b.UACT = 1; + rusb->DVSTCTR0_b.USBRST = 1; + for (volatile int i = 0; i < 2400000; ++i) {} + rusb->DVSTCTR0_b.USBRST = 0; + + rusb->DVSTCTR0_b.UACT = 1; _hcd.need_reset = false; } -void hcd_port_reset_end(uint8_t rhport) -{ +void hcd_port_reset_end(uint8_t rhport) { (void) rhport; } -tusb_speed_t hcd_port_speed_get(uint8_t rhport) -{ - (void)rhport; - switch (RUSB2->DVSTCTR0_b.RHST) { - default: return TUSB_SPEED_INVALID; +tusb_speed_t hcd_port_speed_get(uint8_t rhport) { + rusb2_reg_t* rusb = RUSB2_REG(rhport); + switch (rusb->DVSTCTR0_b.RHST) { + case RUSB2_DVSTCTR0_RHST_HS: return TUSB_SPEED_HIGH; case RUSB2_DVSTCTR0_RHST_FS: return TUSB_SPEED_FULL; - case RUSB2_DVSTCTR0_RHST_LS: return TUSB_SPEED_LOW; + case RUSB2_DVSTCTR0_RHST_LS: return TUSB_SPEED_LOW; + default: return TUSB_SPEED_INVALID; } } -void hcd_device_close(uint8_t rhport, uint8_t dev_addr) -{ - (void)rhport; +void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { + rusb2_reg_t* rusb = RUSB2_REG(rhport); uint16_t volatile *ctr; + TU_ASSERT(dev_addr < 6,); /* USBa can only handle addresses from 0 to 5. */ if (!dev_addr) return; + _hcd.ctl_mps[dev_addr] = 0; 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 = (uint16_t volatile*)&rusb->PIPE_CTR[num - 1]; *ctr = 0; - RUSB2->NRDYENB &= ~TU_BIT(num); - RUSB2->BRDYENB &= ~TU_BIT(num); - RUSB2->PIPESEL = num; - RUSB2->PIPECFG = 0; - RUSB2->PIPEMAXP = 0; + rusb->NRDYENB &= ~TU_BIT(num); + rusb->BRDYENB &= ~TU_BIT(num); + rusb->PIPESEL = num; + rusb->PIPECFG = 0; + rusb->PIPEMAXP = 0; _hcd.pipe[num].ep = 0; _hcd.pipe[num].dev = 0; @@ -607,52 +633,54 @@ 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_ASSERT(dev_addr < 6); /* USBa can only handle addresses from 0 to 5. */ - TU_ASSERT(0 == RUSB2->DCPCTR_b.SUREQ); - RUSB2->DCPCTR = RUSB2_PIPE_CTR_PID_NAK; + rusb2_reg_t* rusb = RUSB2_REG(rhport); + TU_LOG(TU_RUSB2_HCD_DBG, "S %d %x\r\n", dev_addr, rusb->DCPCTR); + + TU_ASSERT(0 == rusb->DCPCTR_b.SUREQ); + + rusb->DCPCTR = RUSB2_PIPE_CTR_PID_NAK; _hcd.pipe[0].buf = NULL; _hcd.pipe[0].length = 8; _hcd.pipe[0].remaining = 0; _hcd.pipe[0].dev = dev_addr; - while (RUSB2->DCPCTR_b.PBUSY) ; - RUSB2->DCPMAXP = (dev_addr << 12) | _hcd.ctl_mps[dev_addr]; + while (rusb->DCPCTR_b.PBUSY) ; + rusb->DCPMAXP = (dev_addr << 12) | _hcd.ctl_mps[dev_addr]; /* Set direction in advance for DATA stage */ uint8_t const bmRequesttype = setup_packet[0]; - RUSB2->DCPCFG_b.DIR = tu_edpt_dir(bmRequesttype) ? 0: 1; + rusb->DCPCFG_b.DIR = tu_edpt_dir(bmRequesttype) ? 0: 1; uint16_t const* p = (uint16_t const*)(uintptr_t)&setup_packet[0]; - RUSB2->USBREQ = tu_htole16(p[0]); - RUSB2->USBVAL = p[1]; - RUSB2->USBINDX = p[2]; - RUSB2->USBLENG = p[3]; + rusb->USBREQ = tu_htole16(p[0]); + rusb->USBVAL = p[1]; + rusb->USBINDX = p[2]; + rusb->USBLENG = p[3]; - RUSB2->DCPCTR_b.SUREQ = 1; + rusb->DCPCTR_b.SUREQ = 1; return true; } bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const *ep_desc) { - (void)rhport; TU_ASSERT(dev_addr < 6); /* USBa can only handle addresses from 0 to 5. */ + rusb2_reg_t* rusb = RUSB2_REG(rhport); const unsigned ep_addr = ep_desc->bEndpointAddress; const unsigned epn = tu_edpt_number(ep_addr); const unsigned mps = tu_edpt_packet_size(ep_desc); + if (0 == epn) { - RUSB2->DCPCTR = RUSB2_PIPE_CTR_PID_NAK; + rusb->DCPCTR = RUSB2_PIPE_CTR_PID_NAK; hcd_devtree_info_t devtree; hcd_devtree_get_info(dev_addr, &devtree); - uint16_t volatile *devadd = (uint16_t volatile *)(uintptr_t) &RUSB2->DEVADD[0]; + uint16_t volatile *devadd = (uint16_t volatile *)(uintptr_t) &rusb->DEVADD[0]; devadd += dev_addr; - while (RUSB2->DCPCTR_b.PBUSY) ; - RUSB2->DCPMAXP = (dev_addr << 12) | mps; + while (rusb->DCPCTR_b.PBUSY) {} + rusb->DCPMAXP = (dev_addr << 12) | mps; *devadd = (TUSB_SPEED_FULL == devtree.speed) ? RUSB2_DEVADD_USBSPD_FS : RUSB2_DEVADD_USBSPD_LS; _hcd.ctl_mps[dev_addr] = mps; return true; @@ -666,17 +694,20 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const } const unsigned num = find_pipe(xfer); if (!num) return false; + _hcd.pipe[num].dev = dev_addr; _hcd.pipe[num].ep = ep_addr; _hcd.ep[dev_addr - 1][dir_in][epn - 1] = num; /* setup pipe */ hcd_int_disable(rhport); - RUSB2->PIPESEL = num; - RUSB2->PIPEMAXP = (dev_addr << 12) | mps; - volatile uint16_t *ctr = get_pipectr(num); + + rusb->PIPESEL = num; + rusb->PIPEMAXP = (dev_addr << 12) | mps; + volatile uint16_t *ctr = get_pipectr(rusb, num); *ctr = RUSB2_PIPE_CTR_ACLRM_Msk | RUSB2_PIPE_CTR_SQCLR_Msk; *ctr = 0; + unsigned cfg = ((1 ^ dir_in) << 4) | epn; if (xfer == TUSB_XFER_BULK) { cfg |= RUSB2_PIPECFG_TYPE_BULK | RUSB2_PIPECFG_SHTNAK_Msk | RUSB2_PIPECFG_DBLB_Msk; @@ -685,13 +716,16 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const } else { cfg |= RUSB2_PIPECFG_TYPE_ISO | RUSB2_PIPECFG_DBLB_Msk; } - RUSB2->PIPECFG = cfg; - RUSB2->BRDYSTS = 0x1FFu ^ TU_BIT(num); - RUSB2->NRDYENB |= TU_BIT(num); - RUSB2->BRDYENB |= TU_BIT(num); + + rusb->PIPECFG = cfg; + rusb->BRDYSTS = 0x1FFu ^ TU_BIT(num); + rusb->NRDYENB |= TU_BIT(num); + rusb->BRDYENB |= TU_BIT(num); + if (!dir_in) { *ctr = RUSB2_PIPE_CTR_PID_BUF; } + hcd_int_enable(rhport); return true; @@ -701,15 +735,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); - r = process_edpt_xfer(dev_addr, ep_addr, buffer, buflen); + TU_LOG(TU_RUSB2_HCD_DBG, "X %d %x %u\r\n", dev_addr, ep_addr, buflen); + r = process_edpt_xfer(rhport, 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) -{ - uint16_t volatile *ctr = addr_to_pipectr(dev_addr, 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) { + uint16_t volatile *ctr = addr_to_pipectr(rhport, dev_addr, ep_addr); TU_ASSERT(ctr); const uint32_t pid = *ctr & 0x3; @@ -732,57 +773,63 @@ bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) //--------------------------------------------------------------------+ void hcd_int_handler(uint8_t rhport) { - (void)rhport; -#if defined(__CCRX__) - static const int Mod37BitPosition[] = { - -1, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, - 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, - 20, 8, 19, 18}; -#endif + rusb2_reg_t* rusb = RUSB2_REG(rhport); + unsigned is0 = rusb->INTSTS0; + unsigned is1 = rusb->INTSTS1; - unsigned is1 = RUSB2->INTSTS1; - unsigned is0 = RUSB2->INTSTS0; /* 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); - is1 &= RUSB2->INTENB1; - is0 &= RUSB2->INTENB0; + rusb->INTSTS1 = ~((RUSB2_INTSTS1_SACK_Msk | RUSB2_INTSTS1_SIGN_Msk | RUSB2_INTSTS1_ATTCH_Msk | RUSB2_INTSTS1_DTCH_Msk) & is1); + rusb->INTSTS0 = ~((RUSB2_INTSTS0_BRDY_Msk | RUSB2_INTSTS0_NRDY_Msk | RUSB2_INTSTS0_BEMP_Msk) & is0); + + TU_LOG3("IS %04x %04x\r\n", is0, is1); + is1 &= rusb->INTENB1; + is0 &= rusb->INTENB0; if (is1 & RUSB2_INTSTS1_SACK_Msk) { /* Set DATA1 in advance for the next transfer. */ - RUSB2->DCPCTR_b.SQSET = 1; - hcd_event_xfer_complete(RUSB2->DCPMAXP_b.DEVSEL, tu_edpt_addr(0, TUSB_DIR_OUT), 8, XFER_RESULT_SUCCESS, true); + rusb->DCPCTR_b.SQSET = 1; + hcd_event_xfer_complete(rusb->DCPMAXP_b.DEVSEL, tu_edpt_addr(0, TUSB_DIR_OUT), 8, XFER_RESULT_SUCCESS, true); } + if (is1 & RUSB2_INTSTS1_SIGN_Msk) { - hcd_event_xfer_complete(RUSB2->DCPMAXP_b.DEVSEL, tu_edpt_addr(0, TUSB_DIR_OUT), 8, XFER_RESULT_FAILED, true); + hcd_event_xfer_complete(rusb->DCPMAXP_b.DEVSEL, tu_edpt_addr(0, TUSB_DIR_OUT), 8, XFER_RESULT_FAILED, true); } + if (is1 & RUSB2_INTSTS1_ATTCH_Msk) { - RUSB2->DVSTCTR0_b.UACT = 1; + rusb->DVSTCTR0_b.UACT = 1; _hcd.need_reset = true; - RUSB2->INTENB1 = (RUSB2->INTENB1 & ~RUSB2_INTSTS1_ATTCH_Msk) | RUSB2_INTSTS1_DTCH_Msk; + rusb->INTENB1 = (rusb->INTENB1 & ~RUSB2_INTSTS1_ATTCH_Msk) | RUSB2_INTSTS1_DTCH_Msk; hcd_event_device_attach(rhport, true); } + if (is1 & RUSB2_INTSTS1_DTCH_Msk) { - RUSB2->DVSTCTR0_b.UACT = 0; - if (RUSB2->DCPCTR_b.SUREQ) { - RUSB2->DCPCTR_b.SUREQCLR = 1; + rusb->DVSTCTR0_b.UACT = 0; + if (rusb->DCPCTR_b.SUREQ) { + rusb->DCPCTR_b.SUREQCLR = 1; } - RUSB2->INTENB1 = (RUSB2->INTENB1 & ~RUSB2_INTSTS1_DTCH_Msk) | RUSB2_INTSTS1_ATTCH_Msk; + rusb->INTENB1 = (rusb->INTENB1 & ~RUSB2_INTSTS1_DTCH_Msk) | RUSB2_INTSTS1_ATTCH_Msk; hcd_event_device_remove(rhport, true); } if (is0 & RUSB2_INTSTS0_BEMP_Msk) { - const unsigned s = RUSB2->BEMPSTS; - RUSB2->BEMPSTS = 0; + const unsigned s = rusb->BEMPSTS; + rusb->BEMPSTS = 0; if (s & 1) { process_pipe0_bemp(rhport); } } + +#if defined(__CCRX__) + static const int Mod37BitPosition[] = { + -1, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, + 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, + 20, 8, 19, 18}; +#endif + if (is0 & RUSB2_INTSTS0_NRDY_Msk) { - const unsigned m = RUSB2->NRDYENB; - unsigned s = RUSB2->NRDYSTS & m; - RUSB2->NRDYSTS = ~s; + const unsigned m = rusb->NRDYENB; + unsigned s = rusb->NRDYSTS & m; + rusb->NRDYSTS = ~s; while (s) { #if defined(__CCRX__) const unsigned num = Mod37BitPosition[(-s & s) % 37]; @@ -794,10 +841,10 @@ void hcd_int_handler(uint8_t rhport) } } if (is0 & RUSB2_INTSTS0_BRDY_Msk) { - const unsigned m = RUSB2->BRDYENB; - unsigned s = RUSB2->BRDYSTS & m; + const unsigned m = rusb->BRDYENB; + unsigned s = rusb->BRDYSTS & m; /* clear active bits (don't write 0 to already cleared bits according to the HW manual) */ - RUSB2->BRDYSTS = ~s; + rusb->BRDYSTS = ~s; while (s) { #if defined(__CCRX__) const unsigned num = Mod37BitPosition[(-s & s) % 37]; diff --git a/src/portable/renesas/rusb2/rusb2_common.c b/src/portable/renesas/rusb2/rusb2_common.c new file mode 100644 index 000000000..850060777 --- /dev/null +++ b/src/portable/renesas/rusb2/rusb2_common.c @@ -0,0 +1,61 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if defined(TUP_USBIP_RUSB2) && (CFG_TUH_ENABLED || CFG_TUD_ENABLED) + +#include "rusb2_type.h" + +#if TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N) +#include "rusb2_rx.h" + +#elif TU_CHECK_MCU(OPT_MCU_RAXXX) +#include "rusb2_ra.h" + +// USBFS_INT_IRQn and USBHS_USB_INT_RESUME_IRQn are generated by FSP +rusb2_controller_t rusb2_controller[] = { + { .reg_base = R_USB_FS0_BASE, .irqnum = USBFS_INT_IRQn }, + #ifdef RUSB2_SUPPORT_HIGHSPEED + { .reg_base = R_USB_HS0_BASE, .irqnum = USBHS_USB_INT_RESUME_IRQn }, + #endif +}; + +// Application API for setting IRQ number. May throw warnings for missing prototypes. +void tusb_rusb2_set_irqnum(uint8_t rhport, int32_t irqnum) { + rusb2_controller[rhport].irqnum = irqnum; +} + +// void osal_task_delay(uint32_t msec) { +// R_BSP_SoftwareDelay(msec, BSP_DELAY_UNITS_MILLISECONDS); +// } + +#else + #error "Unsupported MCU" +#endif + + +#endif diff --git a/src/portable/renesas/rusb2/rusb2_ra.h b/src/portable/renesas/rusb2/rusb2_ra.h index 5be9f11ce..4774d2e2c 100644 --- a/src/portable/renesas/rusb2/rusb2_ra.h +++ b/src/portable/renesas/rusb2/rusb2_ra.h @@ -31,30 +31,75 @@ 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" -#define RUSB2_REG_BASE (0x40090000) +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif +// IAR does not have __builtin_ctz #if defined(__ICCARM__) - #define __builtin_ctz(x) __iar_builtin_CLZ(__iar_builtin_RBIT(x)) + #define __builtin_ctz(x) __iar_builtin_CLZ(__iar_builtin_RBIT(x)) +#endif + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + +typedef struct { + uint32_t reg_base; + int32_t irqnum; +}rusb2_controller_t; + +#if defined(BSP_MCU_GROUP_RA6M5) || defined(BSP_MCU_GROUP_RA6M3) || (BSP_CFG_MCU_PART_SERIES == 8) + #define RUSB2_SUPPORT_HIGHSPEED + #define RUSB2_CONTROLLER_COUNT 2 + + #define rusb2_is_highspeed_rhport(_p) (_p == 1) + #define rusb2_is_highspeed_reg(_reg) (_reg == RUSB2_REG(1)) +#else + #define RUSB2_CONTROLLER_COUNT 1 + + #define rusb2_is_highspeed_rhport(_p) (false) + #define rusb2_is_highspeed_reg(_reg) (false) #endif -TU_ATTR_ALWAYS_INLINE static inline void rusb2_int_enable(uint8_t rhport) -{ - (void) rhport; - NVIC_EnableIRQ(TU_IRQn); +extern rusb2_controller_t rusb2_controller[]; +#define RUSB2_REG(_p) ((rusb2_reg_t*) rusb2_controller[_p].reg_base) + +//--------------------------------------------------------------------+ +// RUSB2 API +//--------------------------------------------------------------------+ + +TU_ATTR_ALWAYS_INLINE static inline void rusb2_module_start(uint8_t rhport, bool start) { + uint32_t const mask = 1U << (11+rhport); + if (start) { + R_MSTP->MSTPCRB &= ~mask; + }else { + R_MSTP->MSTPCRB |= mask; + } +} + +TU_ATTR_ALWAYS_INLINE static inline void rusb2_int_enable(uint8_t rhport) { + NVIC_EnableIRQ(rusb2_controller[rhport].irqnum); } -TU_ATTR_ALWAYS_INLINE static inline void rusb2_int_disable(uint8_t rhport) -{ - (void) rhport; - NVIC_DisableIRQ(TU_IRQn); +TU_ATTR_ALWAYS_INLINE static inline void rusb2_int_disable(uint8_t rhport) { + NVIC_DisableIRQ(rusb2_controller[rhport].irqnum); } // MCU specific PHY init -TU_ATTR_ALWAYS_INLINE static inline void rusb2_phy_init(void) -{ +TU_ATTR_ALWAYS_INLINE static inline void rusb2_phy_init(void) { } #ifdef __cplusplus diff --git a/src/portable/renesas/rusb2/rusb2_rx.h b/src/portable/renesas/rusb2/rusb2_rx.h index 397c0d56c..7bf4be47e 100644 --- a/src/portable/renesas/rusb2/rusb2_rx.h +++ b/src/portable/renesas/rusb2/rusb2_rx.h @@ -37,6 +37,26 @@ extern "C" { #define RUSB2_REG_BASE (0x000A0000) +TU_ATTR_ALWAYS_INLINE static inline rusb2_reg_t* RUSB2_REG(uint8_t rhport) { + (void) rhport; + return (rusb2_reg_t *) RUSB2_REG_BASE; +} + + +#define rusb2_is_highspeed_rhport(_p) (false) +#define rusb2_is_highspeed_reg(_reg) (false) + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + + +// Start/Stop MSTP TODO implement later +TU_ATTR_ALWAYS_INLINE static inline void rusb2_module_start(uint8_t rhport, bool start) { + (void) rhport; + (void) start; +} + TU_ATTR_ALWAYS_INLINE static inline void rusb2_int_enable(uint8_t rhport) { (void) rhport; diff --git a/src/portable/renesas/rusb2/rusb2_type.h b/src/portable/renesas/rusb2/rusb2_type.h index 90ba4f012..dd88f66a7 100644 --- a/src/portable/renesas/rusb2/rusb2_type.h +++ b/src/portable/renesas/rusb2/rusb2_type.h @@ -28,11 +28,19 @@ #define _TUSB_RUSB2_TYPE_H_ #include <stdint.h> +#include <stddef.h> #ifdef __cplusplus extern "C" { #endif +// CCRX specific attribute to generate a Code that Accesses Variables in the Declared Size +#ifdef __CCRX__ + #define _ccrx_evenaccess __evenaccess +#else + #define _ccrx_evenaccess +#endif + /*--------------------------------------------------------------------*/ /* Register Definitions */ /*--------------------------------------------------------------------*/ @@ -41,15 +49,29 @@ extern "C" { TU_ATTR_PACKED_BEGIN TU_ATTR_BIT_FIELD_ORDER_BEGIN +// TODO same as RUSB2_PIPE_TR_t +typedef struct TU_ATTR_PACKED _ccrx_evenaccess { + union { + struct { + uint16_t : 8; + uint16_t TRCLR: 1; + uint16_t TRENB: 1; + uint16_t : 0; + }; + uint16_t TRE; + }; + uint16_t TRN; +} reg_pipetre_t; + typedef struct { union { volatile uint16_t E; /* (@ 0x00000000) Pipe Transaction Counter Enable Register */ struct TU_ATTR_PACKED { - uint16_t : 8; + uint16_t : 8; volatile uint16_t TRCLR : 1; /* [8..8] Transaction Counter Clear */ volatile uint16_t TRENB : 1; /* [9..9] Transaction Counter Enable */ - uint16_t : 6; + uint16_t : 6; } E_b; }; @@ -62,8 +84,9 @@ typedef struct { }; } RUSB2_PIPE_TR_t; /* Size = 4 (0x4) */ -/* LINK_REG Structure */ -typedef struct { + +/* RUSB2 Registers Structure */ +typedef struct _ccrx_evenaccess { union { volatile uint16_t SYSCFG; /* (@ 0x00000000) System Configuration Control Register */ @@ -74,7 +97,7 @@ typedef struct { volatile uint16_t DPRPU : 1; /* [4..4] D+ Line Resistor Control */ volatile uint16_t DRPD : 1; /* [5..5] D+/D- Line Resistor Control */ volatile uint16_t DCFM : 1; /* [6..6] Controller Function Select */ - uint16_t : 1; + volatile uint16_t HSE : 1; // [7..7] High-Speed Operation Enable volatile uint16_t CNEN : 1; /* [8..8] CNEN Single End Receiver Enable */ uint16_t : 1; volatile uint16_t SCKE : 1; /* [10..10] USB Clock Enable */ @@ -87,7 +110,7 @@ typedef struct { struct TU_ATTR_PACKED { volatile uint16_t BWAIT : 4; /* [3..0] CPU Bus Access Wait Specification BWAIT waits (BWAIT+2 access cycles) */ - uint16_t : 12; + uint16_t : 12; } BUSWAIT_b; }; @@ -98,8 +121,7 @@ typedef struct { volatile const uint16_t LNST : 2; /* [1..0] USB Data Line Status Monitor */ volatile const uint16_t IDMON : 1; /* [2..2] External ID0 Input Pin Monitor */ uint16_t : 2; - volatile const uint16_t - SOFEA : 1; /* [5..5] SOF Active Monitor While Host Controller Function is Selected. */ + volatile const uint16_t SOFEA : 1; /* [5..5] SOF Active Monitor While Host Controller Function is Selected. */ volatile const uint16_t HTACT : 1; /* [6..6] USB Host Sequencer Status Monitor */ uint16_t : 7; volatile const uint16_t OVCMON : 2; /* [15..14] External USB0_OVRCURA/ USB0_OVRCURB Input Pin Monitor */ @@ -111,7 +133,7 @@ typedef struct { struct TU_ATTR_PACKED { volatile const uint16_t PLLLOCK : 1; /* [0..0] PLL Lock Flag */ - uint16_t : 15; + uint16_t : 15; } PLLSTA_b; }; @@ -139,7 +161,7 @@ typedef struct { struct TU_ATTR_PACKED { volatile uint16_t UTST : 4; /* [3..0] Test Mode */ - uint16_t : 12; + uint16_t : 12; } TESTMODE_b; }; volatile const uint16_t RESERVED1; @@ -295,7 +317,7 @@ typedef struct { volatile uint16_t INTENB0; /* (@ 0x00000030) Interrupt Enable Register 0 */ struct TU_ATTR_PACKED { - uint16_t : 8; + uint16_t : 8; volatile uint16_t BRDYE : 1; /* [8..8] Buffer Ready Interrupt Enable */ volatile uint16_t NRDYE : 1; /* [9..9] Buffer Not Ready Response Interrupt Enable */ volatile uint16_t BEMPE : 1; /* [10..10] Buffer Empty Interrupt Enable */ @@ -316,7 +338,10 @@ typedef struct { volatile uint16_t SACKE : 1; /* [4..4] Setup Transaction Normal Response Interrupt Enable */ volatile uint16_t SIGNE : 1; /* [5..5] Setup Transaction Error Interrupt Enable */ volatile uint16_t EOFERRE : 1; /* [6..6] EOF Error Detection Interrupt Enable */ - uint16_t : 4; + uint16_t : 1; + volatile uint16_t LPMENDE : 1; /*!< [8..8] LPM Transaction End Interrupt Enable */ + volatile uint16_t L1RSMENDE : 1; /*!< [9..9] L1 Resume End Interrupt Enable */ + uint16_t : 1; volatile uint16_t ATTCHE : 1; /* [11..11] Connection Detection Interrupt Enable */ volatile uint16_t DTCHE : 1; /* [12..12] Disconnection Detection Interrupt Enable */ uint16_t : 1; @@ -340,7 +365,7 @@ typedef struct { volatile uint16_t PIPE7BRDYE : 1; /* [7..7] BRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE8BRDYE : 1; /* [8..8] BRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE9BRDYE : 1; /* [9..9] BRDY Interrupt Enable for PIPE */ - uint16_t : 6; + uint16_t : 6; } BRDYENB_b; }; @@ -358,7 +383,7 @@ typedef struct { volatile uint16_t PIPE7NRDYE : 1; /* [7..7] NRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE8NRDYE : 1; /* [8..8] NRDY Interrupt Enable for PIPE */ volatile uint16_t PIPE9NRDYE : 1; /* [9..9] NRDY Interrupt Enable for PIPE */ - uint16_t : 6; + uint16_t : 6; } NRDYENB_b; }; @@ -376,7 +401,7 @@ typedef struct { volatile uint16_t PIPE7BEMPE : 1; /* [7..7] BEMP Interrupt Enable for PIPE */ volatile uint16_t PIPE8BEMPE : 1; /* [8..8] BEMP Interrupt Enable for PIPE */ volatile uint16_t PIPE9BEMPE : 1; /* [9..9] BEMP Interrupt Enable for PIPE */ - uint16_t : 6; + uint16_t : 6; } BEMPENB_b; }; @@ -390,7 +415,7 @@ typedef struct { volatile uint16_t BRDYM : 1; /* [6..6] BRDY Interrupt Status Clear Timing */ uint16_t : 1; volatile uint16_t TRNENSEL : 1; /* [8..8] Transaction-Enabled Time Select */ - uint16_t : 7; + uint16_t : 7; } SOFCFG_b; }; @@ -467,7 +492,7 @@ typedef struct { volatile uint16_t PIPE7BRDY : 1; /* [7..7] BRDY Interrupt Status for PIPE */ volatile uint16_t PIPE8BRDY : 1; /* [8..8] BRDY Interrupt Status for PIPE */ volatile uint16_t PIPE9BRDY : 1; /* [9..9] BRDY Interrupt Status for PIPE */ - uint16_t : 6; + uint16_t : 6; } BRDYSTS_b; }; @@ -485,7 +510,7 @@ typedef struct { volatile uint16_t PIPE7NRDY : 1; /* [7..7] NRDY Interrupt Status for PIPE */ volatile uint16_t PIPE8NRDY : 1; /* [8..8] NRDY Interrupt Status for PIPE */ volatile uint16_t PIPE9NRDY : 1; /* [9..9] NRDY Interrupt Status for PIPE */ - uint16_t : 6; + uint16_t : 6; } NRDYSTS_b; }; @@ -503,7 +528,7 @@ typedef struct { volatile uint16_t PIPE7BEMP : 1; /* [7..7] BEMP Interrupt Status for PIPE */ volatile uint16_t PIPE8BEMP : 1; /* [8..8] BEMP Interrupt Status for PIPE */ volatile uint16_t PIPE9BEMP : 1; /* [9..9] BEMP Interrupt Status for PIPE */ - uint16_t : 6; + uint16_t : 6; } BEMPSTS_b; }; @@ -609,7 +634,8 @@ typedef struct { volatile uint16_t SQCLR : 1; /* [8..8] Sequence Toggle Bit Clear */ uint16_t : 2; volatile uint16_t SUREQCLR : 1; /* [11..11] SUREQ Bit Clear */ - uint16_t : 2; + volatile uint16_t CSSTS : 1; /* [12..12] Split Transaction COMPLETE SPLIT(CSPLIT) Status */ + volatile uint16_t CSCLR : 1; /* [13..13] Split Transaction CSPLIT Status Clear */ volatile uint16_t SUREQ : 1; /* [14..14] Setup Token Transmission */ volatile const uint16_t BSTS : 1; /* [15..15] Buffer Status */ } DCPCTR_b; @@ -621,7 +647,7 @@ typedef struct { struct TU_ATTR_PACKED { volatile uint16_t PIPESEL : 4; /* [3..0] Pipe Window Select */ - uint16_t : 12; + uint16_t : 12; } PIPESEL_b; }; volatile const uint16_t RESERVED11; @@ -634,21 +660,31 @@ typedef struct { volatile uint16_t DIR : 1; /* [4..4] Transfer Direction */ uint16_t : 2; volatile uint16_t SHTNAK : 1; /* [7..7] Pipe Disabled at End of Transfer */ - uint16_t : 1; + volatile uint16_t CNTMD : 1; /* [8..8] Continuous Transfer Mode */ volatile uint16_t DBLB : 1; /* [9..9] Double Buffer Mode */ volatile uint16_t BFRE : 1; /* [10..10] BRDY Interrupt Operation Specification */ uint16_t : 3; volatile uint16_t TYPE : 2; /* [15..14] Transfer Type */ } PIPECFG_b; }; - volatile const uint16_t RESERVED12; + + union { + volatile uint16_t PIPEBUF; /*!< (@ 0x0000006A) Pipe Buffer Register */ + + struct { + volatile uint16_t BUFNMB : 8; // [7..0] Buffer NumberThese bits specify the FIFO buffer number of the selected pipe (04h to 87h) + uint16_t : 2; + volatile uint16_t BUFSIZE : 5; /*!< [14..10] Buffer Size 00h: 64 bytes 01h: 128 bytes : 1Fh: 2 Kbytes */ + uint16_t : 1; + } PIPEBUF_b; + }; union { volatile uint16_t PIPEMAXP; /* (@ 0x0000006C) Pipe Maximum Packet Size Register */ struct TU_ATTR_PACKED { - volatile uint16_t MXPS : 9; /* [8..0] Maximum Packet Size */ - uint16_t : 3; + volatile uint16_t MXPS : 11; /* [10..0] Maximum Packet Size */ + uint16_t : 1; volatile uint16_t DEVSEL : 4; /* [15..12] Device Select */ } PIPEMAXP_b; }; @@ -694,11 +730,9 @@ typedef struct { struct TU_ATTR_PACKED { volatile uint16_t RPDME0 : 1; /* [0..0] D- Pin Pull-Down Control */ volatile uint16_t IDPSRCE0 : 1; /* [1..1] D+ Pin IDPSRC Output Control */ - volatile uint16_t - IDMSINKE0 : 1; /* [2..2] D- Pin 0.6 V Input Detection (Comparator and Sink) Control */ + volatile uint16_t IDMSINKE0 : 1; /* [2..2] D- Pin 0.6 V Input Detection (Comparator and Sink) Control */ volatile uint16_t VDPSRCE0 : 1; /* [3..3] D+ Pin VDPSRC (0.6 V) Output Control */ - volatile uint16_t - IDPSINKE0 : 1; /* [4..4] D+ Pin 0.6 V Input Detection (Comparator and Sink) Control */ + volatile uint16_t IDPSINKE0 : 1; /* [4..4] D+ Pin 0.6 V Input Detection (Comparator and Sink) Control */ volatile uint16_t VDMSRCE0 : 1; /* [5..5] D- Pin VDMSRC (0.6 V) Output Control */ uint16_t : 1; volatile uint16_t BATCHGE0 : 1; /* [7..7] BC (Battery Charger) Function Ch0 General Enable Control */ @@ -715,7 +749,7 @@ typedef struct { struct TU_ATTR_PACKED { volatile uint16_t UCKSELC : 1; /* [0..0] USB Clock Selection */ - uint16_t : 15; + uint16_t : 15; } UCKSEL_b; }; volatile const uint16_t RESERVED18; @@ -737,11 +771,11 @@ typedef struct { volatile uint16_t DEVADD[10]; /* (@ 0x000000D0) Device Address Configuration Register */ struct TU_ATTR_PACKED { - uint16_t : 6; + uint16_t : 6; volatile uint16_t USBSPD : 2; /* [7..6] Transfer Speed of Communication Target Device */ volatile uint16_t HUBPORT : 3; /* [10..8] Communication Target Connecting Hub Port */ volatile uint16_t UPPHUB : 4; /* [14..11] Communication Target Connecting Hub Register */ - uint16_t : 1; + uint16_t : 1; } DEVADD_b[10]; }; volatile const uint32_t RESERVED21[3]; @@ -754,7 +788,7 @@ typedef struct { volatile uint32_t SLEWR01 : 1; /* [1..1] Receiver Cross Point Adjustment 01 */ volatile uint32_t SLEWF00 : 1; /* [2..2] Receiver Cross Point Adjustment 00 */ volatile uint32_t SLEWF01 : 1; /* [3..3] Receiver Cross Point Adjustment 01 */ - uint32_t : 28; + uint32_t : 28; } PHYSLEW_b; }; volatile const uint32_t RESERVED22[3]; @@ -763,9 +797,9 @@ typedef struct { volatile uint16_t LPCTRL; /* (@ 0x00000100) Low Power Control Register */ struct TU_ATTR_PACKED { - uint16_t : 7; + uint16_t : 7; volatile uint16_t HWUPM : 1; /* [7..7] Resume Return Mode Setting */ - uint16_t : 8; + uint16_t : 8; } LPCTRL_b; }; @@ -773,9 +807,9 @@ typedef struct { volatile uint16_t LPSTS; /* (@ 0x00000102) Low Power Status Register */ struct TU_ATTR_PACKED { - uint16_t : 14; + uint16_t : 14; volatile uint16_t SUSPENDM : 1; /* [14..14] UTMI SuspendM Control */ - uint16_t : 1; + uint16_t : 1; } LPSTS_b; }; volatile const uint32_t RESERVED23[15]; @@ -793,7 +827,7 @@ typedef struct { uint16_t : 2; volatile const uint16_t CHGDETSTS : 1; /* [8..8] CHGDET Status */ volatile const uint16_t PDDETSTS : 1; /* [9..9] PDDET Status */ - uint16_t : 6; + uint16_t : 6; } BCCTRL_b; }; volatile const uint16_t RESERVED24; @@ -809,7 +843,7 @@ typedef struct { volatile uint16_t HIRDTHR : 4; /* [11..8] L1 Response Negotiation Threshold Value */ uint16_t : 2; volatile uint16_t L1EXTMD : 1; /* [14..14] PHY Control Mode at L1 Return */ - uint16_t : 1; + uint16_t : 1; } PL1CTRL1_b; }; @@ -817,10 +851,10 @@ typedef struct { volatile uint16_t PL1CTRL2; /* (@ 0x00000146) Function L1 Control Register 2 */ struct TU_ATTR_PACKED { - uint16_t : 8; + uint16_t : 8; volatile uint16_t HIRDMON : 4; /* [11..8] HIRD Value Monitor */ volatile uint16_t RWEMON : 1; /* [12..12] RWE Value Monitor */ - uint16_t : 3; + uint16_t : 3; } PL1CTRL2_b; }; @@ -830,7 +864,7 @@ typedef struct { struct TU_ATTR_PACKED { volatile uint16_t L1REQ : 1; /* [0..0] L1 Transition Request */ volatile const uint16_t L1STATUS : 2; /* [2..1] L1 Request Completion Status */ - uint16_t : 13; + uint16_t : 13; } HL1CTRL1_b; }; @@ -846,18 +880,48 @@ typedef struct { volatile uint16_t BESL : 1; /* [15..15] BESL & Alternate HIRD */ } HL1CTRL2_b; }; - volatile const uint32_t RESERVED25[5]; + + volatile uint32_t RESERVED25_1; + + union { + volatile uint16_t PHYTRIM1; /*!< (@ 0x00000150) PHY Timing Register 1 */ + + struct { + volatile uint16_t DRISE : 2; /*!< [1..0] FS/LS Rising-Edge Output Waveform Adjustment Function */ + volatile uint16_t DFALL : 2; /*!< [3..2] FS/LS Falling-Edge Output Waveform Adjustment Function */ + uint16_t : 3; + volatile uint16_t PCOMPENB : 1; /*!< [7..7] PVDD Start-up Detection */ + volatile uint16_t HSIUP : 4; /*!< [11..8] HS Output Level Setting */ + volatile uint16_t IMPOFFSET : 3; /*!< [14..12] terminating resistance offset value setting.Offset value for adjusting the terminating resistance. */ + uint16_t : 1; + } PHYTRIM1_b; + }; + + union { + volatile uint16_t PHYTRIM2; /*!< (@ 0x00000152) PHY Timing Register 2 */ + + struct { + volatile uint16_t SQU : 4; /*!< [3..0] Squelch Detection Level */ + uint16_t : 3; + volatile uint16_t HSRXENMO : 1; /*!< [7..7] HS Receive Enable Control Mode */ + volatile uint16_t PDR : 2; /*!< [9..8] HS Output Adjustment Function */ + uint16_t : 2; + volatile uint16_t DIS : 3; /*!< [14..12] Disconnect Detection Level */ + uint16_t : 1; + } PHYTRIM2_b; + }; + volatile uint32_t RESERVED25_2[3]; union { volatile const uint32_t DPUSR0R; /* (@ 0x00000160) Deep Standby USB Transceiver Control/Pin Monitor Register */ struct TU_ATTR_PACKED { - uint32_t : 20; + uint32_t : 20; volatile const uint32_t DOVCAHM : 1; /* [20..20] OVRCURA InputIndicates OVRCURA input signal on the HS side of USB port. */ volatile const uint32_t DOVCBHM : 1; /* [21..21] OVRCURB InputIndicates OVRCURB input signal on the HS side of USB port. */ uint32_t : 1; volatile const uint32_t DVBSTSHM : 1; /* [23..23] VBUS InputIndicates VBUS input signal on the HS side of USB port. */ - uint32_t : 8; + uint32_t : 8; } DPUSR0R_b; }; @@ -865,7 +929,7 @@ typedef struct { volatile uint32_t DPUSR1R; /* (@ 0x00000164) Deep Standby USB Suspend/Resume Interrupt Register */ struct TU_ATTR_PACKED { - uint32_t : 4; + uint32_t : 4; volatile uint32_t DOVCAHE : 1; /* [4..4] OVRCURA Interrupt Enable Clear */ volatile uint32_t DOVCBHE : 1; /* [5..5] OVRCURB Interrupt Enable Clear */ uint32_t : 1; @@ -875,7 +939,7 @@ typedef struct { volatile const uint32_t DOVCBH : 1; /* [21..21] Indication of Return from OVRCURB Interrupt Source */ uint32_t : 1; volatile const uint32_t DVBSTSH : 1; /* [23..23] Indication of Return from VBUS Interrupt Source */ - uint32_t : 8; + uint32_t : 8; } DPUSR1R_b; }; @@ -891,7 +955,7 @@ typedef struct { uint16_t : 2; volatile uint16_t DPINTE : 1; /* [8..8] DP Interrupt Enable Clear */ volatile uint16_t DMINTE : 1; /* [9..9] DM Interrupt Enable Clear */ - uint16_t : 6; + uint16_t : 6; } DPUSR2R_b; }; @@ -901,7 +965,7 @@ typedef struct { struct TU_ATTR_PACKED { volatile uint16_t FIXPHY : 1; /* [0..0] USB Transceiver Control Fix */ volatile uint16_t FIXPHYPD : 1; /* [1..1] USB Transceiver Control Fix for PLL */ - uint16_t : 14; + uint16_t : 14; } DPUSRCR_b; }; volatile const uint32_t RESERVED26[165]; @@ -924,7 +988,7 @@ typedef struct { volatile const uint32_t DOVCB0 : 1; /* [21..21] USB OVRCURB InputIndicates the OVRCURB input signal of the USB. */ uint32_t : 1; volatile const uint32_t DVBSTS0 : 1; /* [23..23] USB VBUS InputIndicates the VBUS input signal of the USB. */ - uint32_t : 8; + uint32_t : 8; } DPUSR0R_FS_b; }; @@ -947,10 +1011,10 @@ typedef struct { volatile const uint32_t DOVRCRB0 : 1; /* [21..21] USB OVRCURB Interrupt Source Recovery */ uint32_t : 1; volatile const uint32_t DVBINT0 : 1; /* [23..23] USB VBUS Interrupt Source Recovery */ - uint32_t : 8; + uint32_t : 8; } DPUSR1R_FS_b; }; -} RUSB2_REG_t; /* Size = 1032 (0x408) */ +} rusb2_reg_t; /* Size = 1032 (0x408) */ TU_ATTR_PACKED_END /* End of definition of packed structs (used by the CCRX toolchain) */ TU_ATTR_BIT_FIELD_ORDER_END @@ -970,13 +1034,15 @@ TU_ATTR_BIT_FIELD_ORDER_END #define RUSB2_PIPE_TR_N_TRNCNT_Pos (0UL) /* TRNCNT (Bit 0) */ #define RUSB2_PIPE_TR_N_TRNCNT_Msk (0xffffUL) /* TRNCNT (Bitfield-Mask: 0xffff) */ -// LINK_REG +// Core Registers // SYSCFG #define RUSB2_SYSCFG_SCKE_Pos (10UL) /* SCKE (Bit 10) */ #define RUSB2_SYSCFG_SCKE_Msk (0x400UL) /* SCKE (Bitfield-Mask: 0x01) */ #define RUSB2_SYSCFG_CNEN_Pos (8UL) /* CNEN (Bit 8) */ #define RUSB2_SYSCFG_CNEN_Msk (0x100UL) /* CNEN (Bitfield-Mask: 0x01) */ +#define RUSB2_SYSCFG_HSE_Pos (7UL) /*!< HSE (Bit 7) */ +#define RUSB2_SYSCFG_HSE_Msk (0x80UL) /*!< HSE (Bitfield-Mask: 0x01) */ #define RUSB2_SYSCFG_DCFM_Pos (6UL) /* DCFM (Bit 6) */ #define RUSB2_SYSCFG_DCFM_Msk (0x40UL) /* DCFM (Bitfield-Mask: 0x01) */ #define RUSB2_SYSCFG_DRPD_Pos (5UL) /* DRPD (Bit 5) */ @@ -1135,6 +1201,10 @@ TU_ATTR_BIT_FIELD_ORDER_END #define RUSB2_INTENB1_DTCHE_Msk (0x1000UL) /* DTCHE (Bitfield-Mask: 0x01) */ #define RUSB2_INTENB1_ATTCHE_Pos (11UL) /* ATTCHE (Bit 11) */ #define RUSB2_INTENB1_ATTCHE_Msk (0x800UL) /* ATTCHE (Bitfield-Mask: 0x01) */ +#define RUSB2_INTENB1_L1RSMENDE_Pos (9UL) /*!< L1RSMENDE (Bit 9) */ +#define RUSB2_INTENB1_L1RSMENDE_Msk (0x200UL) /*!< L1RSMENDE (Bitfield-Mask: 0x01) */ +#define RUSB2_INTENB1_LPMENDE_Pos (8UL) /*!< LPMENDE (Bit 8) */ +#define RUSB2_INTENB1_LPMENDE_Msk (0x100UL) /*!< LPMENDE (Bitfield-Mask: 0x01) */ #define RUSB2_INTENB1_EOFERRE_Pos (6UL) /* EOFERRE (Bit 6) */ #define RUSB2_INTENB1_EOFERRE_Msk (0x40UL) /* EOFERRE (Bitfield-Mask: 0x01) */ #define RUSB2_INTENB1_SIGNE_Pos (5UL) /* SIGNE (Bit 5) */ @@ -1299,6 +1369,10 @@ TU_ATTR_BIT_FIELD_ORDER_END #define RUSB2_DCPCTR_BSTS_Msk (0x8000UL) /* BSTS (Bitfield-Mask: 0x01) */ #define RUSB2_DCPCTR_SUREQ_Pos (14UL) /* SUREQ (Bit 14) */ #define RUSB2_DCPCTR_SUREQ_Msk (0x4000UL) /* SUREQ (Bitfield-Mask: 0x01) */ +#define R_USB_HS0_DCPCTR_CSCLR_Pos (13UL) /*!< CSCLR (Bit 13) */ +#define RUSB2_DCPCTR_CSCLR_Msk (0x2000UL) /*!< CSCLR (Bitfield-Mask: 0x01) */ +#define RUSB2_DCPCTR_CSSTS_Pos (12UL) /*!< CSSTS (Bit 12) */ +#define RUSB2_DCPCTR_CSSTS_Msk (0x1000UL) /*!< CSSTS (Bitfield-Mask: 0x01) */ #define RUSB2_DCPCTR_SUREQCLR_Pos (11UL) /* SUREQCLR (Bit 11) */ #define RUSB2_DCPCTR_SUREQCLR_Msk (0x800UL) /* SUREQCLR (Bitfield-Mask: 0x01) */ #define RUSB2_DCPCTR_SQCLR_Pos (8UL) /* SQCLR (Bit 8) */ @@ -1325,6 +1399,8 @@ TU_ATTR_BIT_FIELD_ORDER_END #define RUSB2_PIPECFG_BFRE_Msk (0x400UL) /* BFRE (Bitfield-Mask: 0x01) */ #define RUSB2_PIPECFG_DBLB_Pos (9UL) /* DBLB (Bit 9) */ #define RUSB2_PIPECFG_DBLB_Msk (0x200UL) /* DBLB (Bitfield-Mask: 0x01) */ +#define RUSB2_PIPECFG_CNTMD_Pos (8UL) /*!< CNTMD (Bit 8) */ +#define RUSB2_PIPECFG_CNTMD_Msk (0x100UL) /*!< CNTMD (Bitfield-Mask: 0x01) */ #define RUSB2_PIPECFG_SHTNAK_Pos (7UL) /* SHTNAK (Bit 7) */ #define RUSB2_PIPECFG_SHTNAK_Msk (0x80UL) /* SHTNAK (Bitfield-Mask: 0x01) */ #define RUSB2_PIPECFG_DIR_Pos (4UL) /* DIR (Bit 4) */ @@ -1332,6 +1408,12 @@ TU_ATTR_BIT_FIELD_ORDER_END #define RUSB2_PIPECFG_EPNUM_Pos (0UL) /* EPNUM (Bit 0) */ #define RUSB2_PIPECFG_EPNUM_Msk (0xfUL) /* EPNUM (Bitfield-Mask: 0x0f) */ +// PIPEBUF +#define RUSB2_PIPEBUF_BUFSIZE_Pos (10UL) /*!< BUFSIZE (Bit 10) */ +#define RUSB2_PIPEBUF_BUFSIZE_Msk (0x7c00UL) /*!< BUFSIZE (Bitfield-Mask: 0x1f) */ +#define RUSB2_PIPEBUF_BUFNMB_Pos (0UL) /*!< BUFNMB (Bit 0) */ +#define RUSB2_PIPEBUF_BUFNMB_Msk (0xffUL) /*!< BUFNMB (Bitfield-Mask: 0xff) */ + // PIPEMAXP #define RUSB2_PIPEMAXP_DEVSEL_Pos (12UL) /* DEVSEL (Bit 12) */ #define RUSB2_PIPEMAXP_DEVSEL_Msk (0xf000UL) /* DEVSEL (Bitfield-Mask: 0x0f) */ @@ -1478,6 +1560,28 @@ TU_ATTR_BIT_FIELD_ORDER_END #define RUSB2_HL1CTRL2_L1ADDR_Pos (0UL) /* L1ADDR (Bit 0) */ #define RUSB2_HL1CTRL2_L1ADDR_Msk (0xfUL) /* L1ADDR (Bitfield-Mask: 0x0f) */ +// PHYTRIM1 +#define RUSB2_PHYTRIM1_IMPOFFSET_Pos (12UL) /*!< IMPOFFSET (Bit 12) */ +#define RUSB2_PHYTRIM1_IMPOFFSET_Msk (0x7000UL) /*!< IMPOFFSET (Bitfield-Mask: 0x07) */ +#define RUSB2_PHYTRIM1_HSIUP_Pos (8UL) /*!< HSIUP (Bit 8) */ +#define RUSB2_PHYTRIM1_HSIUP_Msk (0xf00UL) /*!< HSIUP (Bitfield-Mask: 0x0f) */ +#define RUSB2_PHYTRIM1_PCOMPENB_Pos (7UL) /*!< PCOMPENB (Bit 7) */ +#define RUSB2_PHYTRIM1_PCOMPENB_Msk (0x80UL) /*!< PCOMPENB (Bitfield-Mask: 0x01) */ +#define RUSB2_PHYTRIM1_DFALL_Pos (2UL) /*!< DFALL (Bit 2) */ +#define RUSB2_PHYTRIM1_DFALL_Msk (0xcUL) /*!< DFALL (Bitfield-Mask: 0x03) */ +#define RUSB2_PHYTRIM1_DRISE_Pos (0UL) /*!< DRISE (Bit 0) */ +#define RUSB2_PHYTRIM1_DRISE_Msk (0x3UL) /*!< DRISE (Bitfield-Mask: 0x03) */ + +// PHYTRIM2 +#define RUSB2_PHYTRIM2_DIS_Pos (12UL) /*!< DIS (Bit 12) */ +#define RUSB2_PHYTRIM2_DIS_Msk (0x7000UL) /*!< DIS (Bitfield-Mask: 0x07) */ +#define RUSB2_PHYTRIM2_PDR_Pos (8UL) /*!< PDR (Bit 8) */ +#define RUSB2_PHYTRIM2_PDR_Msk (0x300UL) /*!< PDR (Bitfield-Mask: 0x03) */ +#define RUSB2_PHYTRIM2_HSRXENMO_Pos (7UL) /*!< HSRXENMO (Bit 7) */ +#define RUSB2_PHYTRIM2_HSRXENMO_Msk (0x80UL) /*!< HSRXENMO (Bitfield-Mask: 0x01) */ +#define RUSB2_PHYTRIM2_SQU_Pos (0UL) /*!< SQU (Bit 0) */ +#define RUSB2_PHYTRIM2_SQU_Msk (0xfUL) /*!< SQU (Bitfield-Mask: 0x0f) */ + // DPUSR0R #define RUSB2_DPUSR0R_DVBSTSHM_Pos (23UL) /* DVBSTSHM (Bit 23) */ #define RUSB2_DPUSR0R_DVBSTSHM_Msk (0x800000UL) /* DVBSTSHM (Bitfield-Mask: 0x01) */ @@ -1568,9 +1672,11 @@ 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 */ +#define RUSB2_DVSTCTR0_RHST_HS (3U << RUSB2_DVSTCTR0_RHST_Pos) /* Full-speed connection */ #define RUSB2_DEVADD_USBSPD_LS (1U << RUSB2_DEVADD_USBSPD_Pos) /* Target Device Low-speed */ #define RUSB2_DEVADD_USBSPD_FS (2U << RUSB2_DEVADD_USBSPD_Pos) /* Target Device Full-speed */ @@ -1580,6 +1686,7 @@ TU_ATTR_BIT_FIELD_ORDER_END #define RUSB2_FIFOSEL_BIGEND (1U << RUSB2_CFIFOSEL_BIGEND_Pos) /* FIFO Big Endian */ #define RUSB2_FIFOSEL_MBW_8BIT (0U << RUSB2_CFIFOSEL_MBW_Pos) /* 8-bit width */ #define RUSB2_FIFOSEL_MBW_16BIT (1U << RUSB2_CFIFOSEL_MBW_Pos) /* 16-bit width */ +#define RUSB2_FIFOSEL_MBW_32BIT (2U << RUSB2_CFIFOSEL_MBW_Pos) /* 32-bit width */ #define RUSB2_INTSTS0_CTSQ_CTRL_RDATA (1U << RUSB2_INTSTS0_CTSQ_Pos) @@ -1599,69 +1706,72 @@ TU_ATTR_BIT_FIELD_ORDER_END //--------------------------------------------------------------------+ TU_VERIFY_STATIC(sizeof(RUSB2_PIPE_TR_t) == 4, "incorrect size"); -TU_VERIFY_STATIC(sizeof(RUSB2_REG_t) == 1032, "incorrect size"); +TU_VERIFY_STATIC(sizeof(rusb2_reg_t) == 1032, "incorrect size"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, SYSCFG ) == 0x00000000, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, BUSWAIT ) == 0x00000002, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, SYSSTS0 ) == 0x00000004, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, PLLSTA ) == 0x00000006, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, DVSTCTR0 ) == 0x00000008, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, TESTMODE ) == 0x0000000C, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, CFIFO ) == 0x00000014, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, D0FIFO ) == 0x00000018, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, D1FIFO ) == 0x0000001C, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, CFIFOSEL ) == 0x00000020, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, CFIFOCTR ) == 0x00000022, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, D0FIFOSEL ) == 0x00000028, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, D0FIFOCTR ) == 0x0000002A, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, D1FIFOSEL ) == 0x0000002C, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, D1FIFOCTR ) == 0x0000002E, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, INTENB0 ) == 0x00000030, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, INTENB1 ) == 0x00000032, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, BRDYENB ) == 0x00000036, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, NRDYENB ) == 0x00000038, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, BEMPENB ) == 0x0000003A, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, SOFCFG ) == 0x0000003C, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, PHYSET ) == 0x0000003E, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, INTSTS0 ) == 0x00000040, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, INTSTS1 ) == 0x00000042, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, BRDYSTS ) == 0x00000046, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, NRDYSTS ) == 0x00000048, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, BEMPSTS ) == 0x0000004A, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, FRMNUM ) == 0x0000004C, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, UFRMNUM ) == 0x0000004E, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, USBADDR ) == 0x00000050, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, USBREQ ) == 0x00000054, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, USBVAL ) == 0x00000056, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, USBINDX ) == 0x00000058, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, USBLENG ) == 0x0000005A, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, DCPCFG ) == 0x0000005C, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, DCPMAXP ) == 0x0000005E, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, DCPCTR ) == 0x00000060, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, PIPESEL ) == 0x00000064, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, PIPECFG ) == 0x00000068, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, PIPEMAXP ) == 0x0000006C, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, PIPEPERI ) == 0x0000006E, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, PIPE_CTR ) == 0x00000070, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, PIPE_TR ) == 0x00000090, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, USBBCCTRL0 ) == 0x000000B0, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, UCKSEL ) == 0x000000C4, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, USBMC ) == 0x000000CC, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, DEVADD ) == 0x000000D0, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, PHYSLEW ) == 0x000000F0, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, LPCTRL ) == 0x00000100, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, LPSTS ) == 0x00000102, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, BCCTRL ) == 0x00000140, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, PL1CTRL1 ) == 0x00000144, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, PL1CTRL2 ) == 0x00000146, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, HL1CTRL1 ) == 0x00000148, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, HL1CTRL2 ) == 0x0000014A, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, DPUSR0R ) == 0x00000160, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, DPUSR1R ) == 0x00000164, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, DPUSR2R ) == 0x00000168, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, DPUSRCR ) == 0x0000016A, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, DPUSR0R_FS ) == 0x00000400, "incorrect offset"); -TU_VERIFY_STATIC(offsetof(RUSB2_REG_t, DPUSR1R_FS ) == 0x00000404, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, SYSCFG ) == 0x0000, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, BUSWAIT ) == 0x0002, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, SYSSTS0 ) == 0x0004, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PLLSTA ) == 0x0006, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DVSTCTR0 ) == 0x0008, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, TESTMODE ) == 0x000C, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, CFIFO ) == 0x0014, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, D0FIFO ) == 0x0018, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, D1FIFO ) == 0x001C, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, CFIFOSEL ) == 0x0020, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, CFIFOCTR ) == 0x0022, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, D0FIFOSEL ) == 0x0028, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, D0FIFOCTR ) == 0x002A, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, D1FIFOSEL ) == 0x002C, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, D1FIFOCTR ) == 0x002E, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, INTENB0 ) == 0x0030, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, INTENB1 ) == 0x0032, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, BRDYENB ) == 0x0036, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, NRDYENB ) == 0x0038, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, BEMPENB ) == 0x003A, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, SOFCFG ) == 0x003C, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PHYSET ) == 0x003E, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, INTSTS0 ) == 0x0040, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, INTSTS1 ) == 0x0042, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, BRDYSTS ) == 0x0046, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, NRDYSTS ) == 0x0048, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, BEMPSTS ) == 0x004A, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, FRMNUM ) == 0x004C, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, UFRMNUM ) == 0x004E, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, USBADDR ) == 0x0050, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, USBREQ ) == 0x0054, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, USBVAL ) == 0x0056, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, USBINDX ) == 0x0058, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, USBLENG ) == 0x005A, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DCPCFG ) == 0x005C, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DCPMAXP ) == 0x005E, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DCPCTR ) == 0x0060, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PIPESEL ) == 0x0064, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PIPECFG ) == 0x0068, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PIPEBUF ) == 0x006A, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PIPEMAXP ) == 0x006C, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PIPEPERI ) == 0x006E, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PIPE_CTR ) == 0x0070, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PIPE_TR ) == 0x0090, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, USBBCCTRL0 ) == 0x00B0, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, UCKSEL ) == 0x00C4, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, USBMC ) == 0x00CC, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DEVADD ) == 0x00D0, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PHYSLEW ) == 0x00F0, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, LPCTRL ) == 0x0100, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, LPSTS ) == 0x0102, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, BCCTRL ) == 0x0140, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PL1CTRL1 ) == 0x0144, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PL1CTRL2 ) == 0x0146, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, HL1CTRL1 ) == 0x0148, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, HL1CTRL2 ) == 0x014A, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PHYTRIM1 ) == 0x0150, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, PHYTRIM2 ) == 0x0152, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DPUSR0R ) == 0x0160, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DPUSR1R ) == 0x0164, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DPUSR2R ) == 0x0168, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DPUSRCR ) == 0x016A, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DPUSR0R_FS ) == 0x0400, "incorrect offset"); +TU_VERIFY_STATIC(offsetof(rusb2_reg_t, DPUSR1R_FS ) == 0x0404, "incorrect offset"); #ifdef __cplusplus } diff --git a/src/portable/st/typec/typec_stm32.c b/src/portable/st/typec/typec_stm32.c index bf8b660f0..8da2e39ba 100644 --- a/src/portable/st/typec/typec_stm32.c +++ b/src/portable/st/typec/typec_stm32.c @@ -246,7 +246,7 @@ void tcd_int_handler(uint8_t rhport) { v_cc[0] = (UCPD1->SR >> UCPD_SR_TYPEC_VSTATE_CC1_Pos) & 0x03; v_cc[1] = (UCPD1->SR >> UCPD_SR_TYPEC_VSTATE_CC2_Pos) & 0x03; - TU_LOG3("VState CC1 = %lu, CC2 = %lu\n", v_cc[0], v_cc[1]); + TU_LOG3("VState CC1 = %lu, CC2 = %lu\r\n", v_cc[0], v_cc[1]); uint32_t cr = UCPD1->CR; @@ -255,15 +255,15 @@ void tcd_int_handler(uint8_t rhport) { // FIXME somehow CC2 is vstate is not correct, always 1 even not attached. // on DPOW1 board, it is connected to PA10 (USBPD_DBCC2), we probably miss something. if ((sr & UCPD_SR_TYPECEVT1) && (v_cc[0] == 3)) { - TU_LOG3("Attach CC1\n"); + TU_LOG3("Attach CC1\r\n"); cr &= ~(UCPD_CR_PHYCCSEL | UCPD_CR_CCENABLE); cr |= UCPD_CR_PHYRXEN | UCPD_CR_CCENABLE_0; } else if ((sr & UCPD_SR_TYPECEVT2) && (v_cc[1] == 3)) { - TU_LOG3("Attach CC2\n"); + TU_LOG3("Attach CC2\r\n"); cr &= ~UCPD_CR_CCENABLE; cr |= (UCPD_CR_PHYCCSEL | UCPD_CR_PHYRXEN | UCPD_CR_CCENABLE_1); } else { - TU_LOG3("Detach\n"); + TU_LOG3("Detach\r\n"); cr &= ~UCPD_CR_PHYRXEN; cr |= UCPD_CR_CCENABLE_0 | UCPD_CR_CCENABLE_1; } @@ -290,7 +290,7 @@ void tcd_int_handler(uint8_t rhport) { //------------- RX -------------// if (sr & UCPD_SR_RXORDDET) { // SOP: Start of Packet. - TU_LOG3("SOP\n"); + TU_LOG3("SOP\r\n"); // UCPD1->RX_ORDSET & UCPD_RX_ORDSET_RXORDSET_Msk; // ack @@ -299,7 +299,7 @@ void tcd_int_handler(uint8_t rhport) { // Received full message if (sr & UCPD_SR_RXMSGEND) { - TU_LOG3("RX MSG END\n"); + TU_LOG3("RX MSG END\r\n"); // stop TX dma_stop(rhport, true); @@ -328,7 +328,7 @@ void tcd_int_handler(uint8_t rhport) { } if (sr & UCPD_SR_RXOVR) { - TU_LOG3("RXOVR\n"); + TU_LOG3("RXOVR\r\n"); // ack UCPD1->ICR = UCPD_ICR_RXOVRCF; } @@ -343,12 +343,12 @@ void tcd_int_handler(uint8_t rhport) { uint8_t result; if ( sr & UCPD_SR_TXMSGSENT ) { - TU_LOG3("TX MSG SENT\n"); + TU_LOG3("TX MSG SENT\r\n"); result = XFER_RESULT_SUCCESS; // ack UCPD1->ICR = UCPD_ICR_TXMSGSENTCF; }else { - TU_LOG3("TX Error\n"); + TU_LOG3("TX Error\r\n"); result = XFER_RESULT_FAILED; // ack UCPD1->ICR = UCPD_SR_TXMSGDISC | UCPD_SR_TXMSGABT | UCPD_SR_TXUND; diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index e26be775d..6cc1975a8 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -408,9 +408,9 @@ static inline unsigned free_block_size(free_block_t const *blk) #if 0 static inline void print_block_list(free_block_t const *blk, unsigned num) { - TU_LOG1("*************\n"); + TU_LOG1("*************\r\n"); for (unsigned i = 0; i < num; ++i) { - TU_LOG1(" Blk%u %u %u\n", i, blk->beg, blk->end); + TU_LOG1(" Blk%u %u %u\r\n", i, blk->beg, blk->end); ++blk; } } @@ -590,7 +590,7 @@ static bool handle_xfer_in(uint_fast8_t ep_addr) const unsigned mps = USBC_Readw(USBC_REG_TXMAXP(USBC0_BASE)); const unsigned len = TU_MIN(mps, rem); uint8_t *buf = pipe->buf; - // TU_LOG1(" %p mps %d len %d rem %d\n", buf, mps, len, rem); + // TU_LOG1(" %p mps %d len %d rem %d\r\n", buf, mps, len, rem); if (len) { volatile void* addr = (volatile void*)(USBC_REG_EPFIFO1(USBC0_BASE) + (epnum_minus1 << 2)); if (_dcd.pipe_buf_is_fifo[TUSB_DIR_IN] & TU_BIT(epnum_minus1)) { @@ -602,7 +602,7 @@ static bool handle_xfer_in(uint_fast8_t ep_addr) pipe->remaining = rem - len; } __USBC_Dev_Tx_WriteDataComplete(); - // TU_LOG1(" TXCSRL%d = %x %d\n", epnum_minus1 + 1, regs->TXCSRL, rem - len); + // TU_LOG1(" TXCSRL%d = %x %d\r\n", epnum_minus1 + 1, regs->TXCSRL, rem - len); return false; } @@ -610,7 +610,7 @@ static bool handle_xfer_out(uint_fast8_t ep_addr) { unsigned epnum_minus1 = tu_edpt_number(ep_addr) - 1; pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; - // TU_LOG1(" RXCSRL%d = %x\n", epnum_minus1 + 1, regs->RXCSRL); + // TU_LOG1(" RXCSRL%d = %x\r\n", epnum_minus1 + 1, regs->RXCSRL); TU_ASSERT(__USBC_Dev_Rx_IsReadDataReady()); @@ -677,14 +677,14 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ * may have already finished and received the next setup packet * without calling this function, so we have no choice but to * invoke the callback function of status packet here. */ - // TU_LOG1(" STATUS OUT CSRL0 = %x\n", CSRL0); + // TU_LOG1(" STATUS OUT CSRL0 = %x\r\n", CSRL0); _dcd.status_out = 0; if (req == REQUEST_TYPE_INVALID) { dcd_event_xfer_complete(rhport, ep_addr, total_bytes, XFER_RESULT_SUCCESS, false); } else { /* The next setup packet has already been received, it aborts * invoking callback function to avoid confusing TUSB stack. */ - TU_LOG1("Drop CONTROL_STAGE_ACK\n"); + TU_LOG1("Drop CONTROL_STAGE_ACK\r\n"); } return true; } @@ -709,16 +709,16 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ } else { __USBC_Dev_ep0_WriteDataHalf(); } - // TU_LOG1(" IN CSRL0 = %x\n", CSRL0); + // TU_LOG1(" IN CSRL0 = %x\r\n", CSRL0); } else { - // TU_LOG1(" OUT CSRL0 = %x\n", CSRL0); + // TU_LOG1(" OUT CSRL0 = %x\r\n", CSRL0); _dcd.pipe0.buf = buffer; _dcd.pipe0.length = len; _dcd.pipe0.remaining = len; __USBC_Dev_ep0_ReadDataHalf(); } } else if (dir_in) { - // TU_LOG1(" STATUS IN CSRL0 = %x\n", CSRL0); + // TU_LOG1(" STATUS IN CSRL0 = %x\r\n", CSRL0); _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; @@ -733,7 +733,7 @@ static void process_ep0(uint8_t rhport) USBC_SelectActiveEp(0); uint_fast8_t csrl = USBC_Readw(USBC_REG_CSR0(USBC0_BASE)); - // TU_LOG1(" EP0 CSRL0 = %x\n", csrl); + // TU_LOG1(" EP0 CSRL0 = %x\r\n", csrl); if (csrl & USB_CSRL0_STALLED) { /* Returned STALL packet to HOST. */ @@ -743,7 +743,7 @@ static void process_ep0(uint8_t rhport) unsigned req = _dcd.setup_packet.bmRequestType; if (csrl & USB_CSRL0_SETEND) { - // TU_LOG1(" ABORT by the next packets\n"); + // TU_LOG1(" ABORT by the next packets\r\n"); USBC_Dev_Ctrl_ClearSetupEnd(); if (req != REQUEST_TYPE_INVALID && _dcd.pipe0.buf) { /* DATA stage was aborted by receiving STATUS or SETUP packet. */ @@ -819,14 +819,14 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) USBC_SelectActiveEp(epn); if (dir_in) { - // TU_LOG1(" TXCSRL%d = %x\n", epn_minus1 + 1, regs->TXCSRL); + // TU_LOG1(" TXCSRL%d = %x\r\n", epn_minus1 + 1, regs->TXCSRL); if (__USBC_Dev_Tx_IsEpStall()) { __USBC_Dev_Tx_ClearStall(); return; } completed = handle_xfer_in(ep_addr); } else { - // TU_LOG1(" RXCSRL%d = %x\n", epn_minus1 + 1, regs->RXCSRL); + // TU_LOG1(" RXCSRL%d = %x\r\n", epn_minus1 + 1, regs->RXCSRL); if (__USBC_Dev_Rx_IsEpStall()) { __USBC_Dev_Rx_ClearStall(); return; @@ -1092,7 +1092,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t { (void)rhport; bool ret; - // TU_LOG1("X %x %d\n", ep_addr, total_bytes); + // TU_LOG1("X %x %d\r\n", ep_addr, total_bytes); unsigned const epnum = tu_edpt_number(ep_addr); musb_int_mask(); @@ -1111,7 +1111,7 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_ { (void)rhport; bool ret; - // TU_LOG1("X %x %d\n", ep_addr, total_bytes); + // TU_LOG1("X %x %d\r\n", ep_addr, total_bytes); unsigned const epnum = tu_edpt_number(ep_addr); TU_ASSERT(epnum); diff --git a/src/tusb_option.h b/src/tusb_option.h index f16d8a5d0..7a4cfe51c 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -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 -------------// |
