From d0bff6fd3ec9fc133032dea84732451d93d202b4 Mon Sep 17 00:00:00 2001 From: Xelus22 Date: Tue, 25 Jul 2023 23:53:55 +1000 Subject: initial add SOF supporpt to CH32V307 USB HS --- src/portable/wch/ch32v307/dcd_usbhs.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'src/portable') diff --git a/src/portable/wch/ch32v307/dcd_usbhs.c b/src/portable/wch/ch32v307/dcd_usbhs.c index 3ad011cff..843643ef7 100644 --- a/src/portable/wch/ch32v307/dcd_usbhs.c +++ b/src/portable/wch/ch32v307/dcd_usbhs.c @@ -135,6 +135,19 @@ void dcd_remote_wakeup(uint8_t rhport) (void) rhport; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + if (en) + { + USBHSD->INT_EN |= USBHS_SOF_ACT_EN; + } + else + { + USBHSD->INT_EN &= ~(USBHS_SOF_ACT_EN); + } +} + void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) { (void)rhport; @@ -332,7 +345,9 @@ void dcd_int_handler(uint8_t rhport) { xfer_ctl_t *xfer = XFER_CTL_BASE(end_num, tu_edpt_dir(endp)); - if (rx_token == PID_OUT) { + if (rx_token == PID_SOF) { + dcd_event_sof(rhport, USBHSD->FRAME_NO, true); + } else if (rx_token == PID_OUT) { uint16_t rx_len = USBHSD->RX_LEN; receive_packet(xfer, rx_len); -- cgit v1.3.1 From 1755bba509edf2d5bc49cadecb6e956497732b37 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Mon, 15 Jan 2024 12:47:13 +0000 Subject: Add DWC2 Test Mode SUpport --- src/common/tusb_mcu.h | 2 ++ src/device/dcd.h | 28 ++++++++++++++++++ src/device/usbd.c | 53 +++++++++++++++++++++++++++++++---- src/portable/synopsys/dwc2/dcd_dwc2.c | 30 ++++++++++++++++++++ 4 files changed, 107 insertions(+), 6 deletions(-) (limited to 'src/portable') diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 35f94efbc..146accabf 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -195,6 +195,7 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32F7) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 + #define TUP_USBIP_DWC2_TEST_MODE_SUPPORT // FS has 6, HS has 9 #define TUP_DCD_ENDPOINT_MAX 9 @@ -262,6 +263,7 @@ #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_USBIP_DWC2_TEST_MODE_SUPPORT #elif TU_CHECK_MCU(OPT_MCU_STM32L5) #define TUP_USBIP_FSDEV diff --git a/src/device/dcd.h b/src/device/dcd.h index 18a708347..7755ef107 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -58,6 +58,7 @@ typedef enum DCD_EVENT_SETUP_RECEIVED, DCD_EVENT_XFER_COMPLETE, + DCD_EVENT_TEST_MODE, // Not an DCD event, just a convenient way to defer ISR function USBD_EVENT_FUNC_CALL, @@ -97,9 +98,23 @@ typedef struct TU_ATTR_ALIGNED(4) void (*func) (void*); void* param; }func_call; + + // TEST MODE + struct { + uint8_t selector; + }test_mode; }; } dcd_event_t; +typedef enum _test_mode_selector +{ + TEST_J = 1, + TEST_K, + TEST_SE0_NAK, + TEST_PACKET, + TEST_FORCE_ENABLE, +} test_mode_t; + //TU_VERIFY_STATIC(sizeof(dcd_event_t) <= 12, "size is not correct"); //--------------------------------------------------------------------+ @@ -149,6 +164,12 @@ void dcd_disconnect(uint8_t rhport) TU_ATTR_WEAK; // Enable/Disable Start-of-frame interrupt. Default is disabled void dcd_sof_enable(uint8_t rhport, bool en); +// Check if the test mode is supported +bool dcd_test_mode_supported(test_mode_t test_selector) TU_ATTR_WEAK; + +// Put device into a test mode (needs power cycle to quit) +void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) TU_ATTR_WEAK; + //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ @@ -240,6 +261,13 @@ static inline void dcd_event_sof(uint8_t rhport, uint32_t frame_count, bool in_i dcd_event_handler(&event, in_isr); } +TU_ATTR_ALWAYS_INLINE static inline void dcd_event_enter_test_mode(uint8_t rhport, uint8_t test_selector, bool in_isr) +{ + dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_TEST_MODE }; + event.test_mode.selector = test_selector; + dcd_event_handler(&event, in_isr); +} + #ifdef __cplusplus } #endif diff --git a/src/device/usbd.c b/src/device/usbd.c index f0d9fba52..90fde92b5 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -587,6 +587,11 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) if ( event.func_call.func ) event.func_call.func(event.func_call.param); break; + case DCD_EVENT_TEST_MODE: + TU_LOG_USBD(": Enter Test Mode with selector index = %d)\r\n", event.test_mode.selector); + if (dcd_enter_test_mode) dcd_enter_test_mode(event.rhport, event.test_mode.selector); + break; + case DCD_EVENT_SOF: default: TU_BREAKPOINT(); @@ -725,14 +730,50 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const break; case TUSB_REQ_SET_FEATURE: - // Only support remote wakeup for device feature - TU_VERIFY(TUSB_REQ_FEATURE_REMOTE_WAKEUP == p_request->wValue); + // Handle the feature selector + switch(p_request->wValue) + { + // Support for remote wakeup + case TUSB_REQ_FEATURE_REMOTE_WAKEUP: + TU_LOG_USBD(" Enable Remote Wakeup\r\n"); - TU_LOG_USBD(" Enable Remote Wakeup\r\n"); + // Host may enable remote wake up before suspending especially HID device + _usbd_dev.remote_wakeup_en = true; + tud_control_status(rhport, p_request); - // Host may enable remote wake up before suspending especially HID device - _usbd_dev.remote_wakeup_en = true; - tud_control_status(rhport, p_request); + break; + + // Support for TEST_MODE + case TUSB_REQ_FEATURE_TEST_MODE: + // Only handle the test mode is supported and valid + if (!dcd_enter_test_mode || !dcd_test_mode_supported || 0 != tu_u16_low(p_request->wIndex)) + { + return false; + } + + uint8_t selector = tu_u16_high(p_request->wIndex); + + // Stall request if the selected test mode isn't supported + if (!dcd_test_mode_supported(selector)) + { + TU_LOG_USBD(" Unsupported Test Mode (test selector index: %d)\r\n", selector); + + return false; + } + + TU_LOG_USBD(" Schedule Test Mode (test selector index: %d)\r\n", selector); + + // Acknowledge request + tud_control_status(rhport, p_request); + + // Schedule the execution of the test mode so that the request can be answered + dcd_event_enter_test_mode(rhport, selector, false); + + break; + + // Stall unsupported feature selector + default: return false; + } break; case TUSB_REQ_CLEAR_FEATURE: diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index c6132a1f5..ee4b2b28d 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1351,4 +1351,34 @@ void dcd_int_handler(uint8_t rhport) // } } +#if defined(TUP_USBIP_DWC2_TEST_MODE_SUPPORT) + +bool dcd_test_mode_supported(test_mode_t test_selector) { + // Check if test mode selector is unsupported + if (TEST_FORCE_ENABLE < test_selector || TEST_J > test_selector) { + return false; + } + + return true; +} + +void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) { + // Disable test mode if not supported + if (!dcd_test_mode_supported(test_selector)) { + test_selector = 0; + } + + // Delay the entering a bit so there is enough time to acknowledge request + uint32_t count = SystemCoreClock / 20000; + while (count--) __NOP(); + + // Get port address... + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + + // Enable the test mode + dwc2->dctl = (dwc2->dctl & ~DCTL_TCTL_Msk) | (test_selector << DCTL_TCTL_Pos); +} + +#endif /* TUP_USBIP_DWC2_TEST_MODE_SUPPORT */ + #endif -- cgit v1.3.1 From c3e96e667f45e695bc855db4011f1a7f46d24b29 Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Mon, 15 Jan 2024 15:10:46 +0000 Subject: Change to control complete cb --- src/device/dcd.h | 19 +++---------------- src/device/usbd.c | 34 ++++++++++++++++++---------------- src/portable/synopsys/dwc2/dcd_dwc2.c | 11 +++-------- 3 files changed, 24 insertions(+), 40 deletions(-) (limited to 'src/portable') diff --git a/src/device/dcd.h b/src/device/dcd.h index 7755ef107..2248cd392 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -58,7 +58,6 @@ typedef enum DCD_EVENT_SETUP_RECEIVED, DCD_EVENT_XFER_COMPLETE, - DCD_EVENT_TEST_MODE, // Not an DCD event, just a convenient way to defer ISR function USBD_EVENT_FUNC_CALL, @@ -71,7 +70,7 @@ typedef struct TU_ATTR_ALIGNED(4) uint8_t rhport; uint8_t event_id; - union + union { // BUS RESET struct { @@ -98,11 +97,6 @@ typedef struct TU_ATTR_ALIGNED(4) void (*func) (void*); void* param; }func_call; - - // TEST MODE - struct { - uint8_t selector; - }test_mode; }; } dcd_event_t; @@ -164,8 +158,8 @@ void dcd_disconnect(uint8_t rhport) TU_ATTR_WEAK; // Enable/Disable Start-of-frame interrupt. Default is disabled void dcd_sof_enable(uint8_t rhport, bool en); -// Check if the test mode is supported -bool dcd_test_mode_supported(test_mode_t test_selector) TU_ATTR_WEAK; +// Check if the test mode is supported, returns true is test mode selector is supported +bool dcd_check_test_mode_support(test_mode_t test_selector) TU_ATTR_WEAK; // Put device into a test mode (needs power cycle to quit) void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) TU_ATTR_WEAK; @@ -261,13 +255,6 @@ static inline void dcd_event_sof(uint8_t rhport, uint32_t frame_count, bool in_i dcd_event_handler(&event, in_isr); } -TU_ATTR_ALWAYS_INLINE static inline void dcd_event_enter_test_mode(uint8_t rhport, uint8_t test_selector, bool in_isr) -{ - dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_TEST_MODE }; - event.test_mode.selector = test_selector; - dcd_event_handler(&event, in_isr); -} - #ifdef __cplusplus } #endif diff --git a/src/device/usbd.c b/src/device/usbd.c index 90fde92b5..fbdba4d2f 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -285,6 +285,7 @@ tu_static osal_queue_t _usbd_q; static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request); static bool process_set_config(uint8_t rhport, uint8_t cfg_num); static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const * p_request); +static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); // from usbd_control.c void usbd_control_reset(void); @@ -587,11 +588,6 @@ void tud_task_ext(uint32_t timeout_ms, bool in_isr) if ( event.func_call.func ) event.func_call.func(event.func_call.param); break; - case DCD_EVENT_TEST_MODE: - TU_LOG_USBD(": Enter Test Mode with selector index = %d)\r\n", event.test_mode.selector); - if (dcd_enter_test_mode) dcd_enter_test_mode(event.rhport, event.test_mode.selector); - break; - case DCD_EVENT_SOF: default: TU_BREAKPOINT(); @@ -740,35 +736,29 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const // Host may enable remote wake up before suspending especially HID device _usbd_dev.remote_wakeup_en = true; tud_control_status(rhport, p_request); - break; // Support for TEST_MODE case TUSB_REQ_FEATURE_TEST_MODE: - // Only handle the test mode is supported and valid - if (!dcd_enter_test_mode || !dcd_test_mode_supported || 0 != tu_u16_low(p_request->wIndex)) - { - return false; - } + // Only handle the test mode if supported and valid + TU_VERIFY(dcd_enter_test_mode && dcd_check_test_mode_support && 0 == tu_u16_low(p_request->wIndex)); uint8_t selector = tu_u16_high(p_request->wIndex); // Stall request if the selected test mode isn't supported - if (!dcd_test_mode_supported(selector)) + if (!dcd_check_test_mode_support(selector)) { TU_LOG_USBD(" Unsupported Test Mode (test selector index: %d)\r\n", selector); return false; } - TU_LOG_USBD(" Schedule Test Mode (test selector index: %d)\r\n", selector); - // Acknowledge request tud_control_status(rhport, p_request); - // Schedule the execution of the test mode so that the request can be answered - dcd_event_enter_test_mode(rhport, selector, false); + TU_LOG_USBD(" Enter Test Mode (test selector index: %d)\r\n", selector); + usbd_control_set_complete_callback(process_test_mode_cb); break; // Stall unsupported feature selector @@ -1115,6 +1105,18 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const } } +bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +{ + // At this point it should already be ensured that dcd_enter_test_mode() is defined + + // Only enter the test mode after the request for it has completed + TU_VERIFY(CONTROL_STAGE_ACK == stage); + + dcd_enter_test_mode(rhport, tu_u16_high(request->wIndex)); + + return true; +} + //--------------------------------------------------------------------+ // DCD Event Handler //--------------------------------------------------------------------+ diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index ee4b2b28d..aa4a8bfb2 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1353,7 +1353,7 @@ void dcd_int_handler(uint8_t rhport) #if defined(TUP_USBIP_DWC2_TEST_MODE_SUPPORT) -bool dcd_test_mode_supported(test_mode_t test_selector) { +bool dcd_check_test_mode_support(test_mode_t test_selector) { // Check if test mode selector is unsupported if (TEST_FORCE_ENABLE < test_selector || TEST_J > test_selector) { return false; @@ -1363,15 +1363,10 @@ bool dcd_test_mode_supported(test_mode_t test_selector) { } void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) { - // Disable test mode if not supported - if (!dcd_test_mode_supported(test_selector)) { + // Disable test mode if not supported as a fall back + if (!dcd_check_test_mode_support(test_selector)) { test_selector = 0; } - - // Delay the entering a bit so there is enough time to acknowledge request - uint32_t count = SystemCoreClock / 20000; - while (count--) __NOP(); - // Get port address... dwc2_regs_t* dwc2 = DWC2_REG(rhport); -- cgit v1.3.1 From d0373f4749e320c7cb3fac9cce068b4398e60f2f Mon Sep 17 00:00:00 2001 From: Rocky04 Date: Mon, 19 Feb 2024 17:44:18 +0000 Subject: Opt-out for USB Test-Mode --- src/device/usbd.c | 4 ++++ src/portable/synopsys/dwc2/dcd_dwc2.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'src/portable') diff --git a/src/device/usbd.c b/src/device/usbd.c index 83217a869..1da6f0b53 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -731,6 +731,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const tud_control_status(rhport, p_request); break; + #if !defined(TUSB_NO_TEST_MODE_SUPPORT) // Support for TEST_MODE case TUSB_REQ_FEATURE_TEST_MODE: // Only handle the test mode if supported and valid @@ -753,6 +754,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const usbd_control_set_complete_callback(process_test_mode_cb); break; + #endif /* !TUSB_NO_TEST_MODE_SUPPORT */ // Stall unsupported feature selector default: return false; @@ -1098,6 +1100,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const } } +#if !defined(TUSB_NO_TEST_MODE_SUPPORT) static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) { // At this point it should already be ensured that dcd_enter_test_mode() is defined @@ -1109,6 +1112,7 @@ static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_req return true; } +#endif /* !TUSB_NO_TEST_MODE_SUPPORT */ //--------------------------------------------------------------------+ // DCD Event Handler diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 381aeca71..8163ba8e1 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1186,7 +1186,7 @@ void dcd_int_handler(uint8_t rhport) { // } } -#if defined(TUP_USBIP_DWC2_TEST_MODE_SUPPORT) +#if defined(TUP_USBIP_DWC2_TEST_MODE_SUPPORT) && !defined(TUSB_NO_TEST_MODE_SUPPORT) bool dcd_check_test_mode_support(test_mode_t test_selector) { // Check if test mode selector is unsupported @@ -1209,6 +1209,6 @@ void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) { dwc2->dctl = (dwc2->dctl & ~DCTL_TCTL_Msk) | (test_selector << DCTL_TCTL_Pos); } -#endif /* TUP_USBIP_DWC2_TEST_MODE_SUPPORT */ +#endif /* TUP_USBIP_DWC2_TEST_MODE_SUPPORT && !TUSB_NO_TEST_MODE_SUPPORT */ #endif -- cgit v1.3.1 From 2e995d7cf4b2971e3ca7167a097b99832c8d61ce Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 25 Apr 2024 20:23:40 +0700 Subject: adding support for esp32 for use with max3421e host --- examples/device/board_test/src/tusb_config.h | 2 +- examples/device/cdc_msc_freertos/src/main.c | 6 +-- examples/device/cdc_msc_freertos/src/tusb_config.h | 2 +- examples/device/hid_composite_freertos/src/main.c | 6 +-- .../hid_composite_freertos/src/tusb_config.h | 2 +- examples/device/video_capture/src/main.c | 4 +- examples/device/video_capture/src/tusb_config.h | 2 +- examples/device/video_capture_2ch/src/main.c | 4 +- .../device/video_capture_2ch/src/tusb_config.h | 2 +- examples/host/cdc_msc_hid_freertos/src/cdc_app.c | 2 +- examples/host/cdc_msc_hid_freertos/src/main.c | 6 +-- .../host/cdc_msc_hid_freertos/src/tusb_config.h | 2 +- hw/bsp/board_api.h | 2 +- .../boards/adafruit_feather_esp32_v2/board.cmake | 2 + .../boards/adafruit_feather_esp32_v2/board.h | 53 ++++++++++++++++++++++ hw/bsp/espressif/boards/family.c | 19 ++++---- .../components/tinyusb_src/CMakeLists.txt | 12 +---- hw/bsp/espressif/family.cmake | 6 +-- src/common/tusb_mcu.h | 5 +- src/portable/analog/max3421/hcd_max3421.c | 2 +- src/tusb_option.h | 2 + 21 files changed, 94 insertions(+), 49 deletions(-) create mode 100644 hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.cmake create mode 100644 hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.h (limited to 'src/portable') diff --git a/examples/device/board_test/src/tusb_config.h b/examples/device/board_test/src/tusb_config.h index 1a27cc87f..36eafe807 100644 --- a/examples/device/board_test/src/tusb_config.h +++ b/examples/device/board_test/src/tusb_config.h @@ -49,7 +49,7 @@ #endif // Espressif IDF requires "freertos/" prefix in include path -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF #define CFG_TUSB_OS_INC_PATH freertos/ #endif diff --git a/examples/device/cdc_msc_freertos/src/main.c b/examples/device/cdc_msc_freertos/src/main.c index e94e8eaec..607d40270 100644 --- a/examples/device/cdc_msc_freertos/src/main.c +++ b/examples/device/cdc_msc_freertos/src/main.c @@ -30,7 +30,7 @@ #include "bsp/board_api.h" #include "tusb.h" -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF // ESP-IDF need "freertos/" prefix in include path. // CFG_TUSB_OS_INC_PATH should be defined accordingly. #include "freertos/FreeRTOS.h" @@ -111,14 +111,14 @@ int main(void) { #endif // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 -#if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if !TUP_MCU_ESPRESSIF vTaskStartScheduler(); #endif return 0; } -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF void app_main(void) { main(); } diff --git a/examples/device/cdc_msc_freertos/src/tusb_config.h b/examples/device/cdc_msc_freertos/src/tusb_config.h index 91efe7d40..e743c9148 100644 --- a/examples/device/cdc_msc_freertos/src/tusb_config.h +++ b/examples/device/cdc_msc_freertos/src/tusb_config.h @@ -59,7 +59,7 @@ #endif // Espressif IDF requires "freertos/" prefix in include path -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF #define CFG_TUSB_OS_INC_PATH freertos/ #endif diff --git a/examples/device/hid_composite_freertos/src/main.c b/examples/device/hid_composite_freertos/src/main.c index ff2cb635e..2bd545bc2 100644 --- a/examples/device/hid_composite_freertos/src/main.c +++ b/examples/device/hid_composite_freertos/src/main.c @@ -31,7 +31,7 @@ #include "tusb.h" #include "usb_descriptors.h" -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF // ESP-IDF need "freertos/" prefix in include path. // CFG_TUSB_OS_INC_PATH should be defined accordingly. #include "freertos/FreeRTOS.h" @@ -113,14 +113,14 @@ int main(void) xTimerStart(blinky_tm, 0); // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 -#if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if !TUP_MCU_ESPRESSIF vTaskStartScheduler(); #endif return 0; } -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF void app_main(void) { main(); diff --git a/examples/device/hid_composite_freertos/src/tusb_config.h b/examples/device/hid_composite_freertos/src/tusb_config.h index 3ba9bf311..0689e0f23 100644 --- a/examples/device/hid_composite_freertos/src/tusb_config.h +++ b/examples/device/hid_composite_freertos/src/tusb_config.h @@ -59,7 +59,7 @@ #endif // Espressif IDF requires "freertos/" prefix in include path -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF #define CFG_TUSB_OS_INC_PATH freertos/ #endif diff --git a/examples/device/video_capture/src/main.c b/examples/device/video_capture/src/main.c index 2a2b0961f..ddb51e03a 100644 --- a/examples/device/video_capture/src/main.c +++ b/examples/device/video_capture/src/main.c @@ -288,7 +288,7 @@ void led_blinking_task(void* param) { #define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE #define VIDEO_STACK_SIZE (configMINIMAL_STACK_SIZE*4) -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF #define USBD_STACK_SIZE 4096 int main(void); void app_main(void) { @@ -344,7 +344,7 @@ void freertos_init_task(void) { #endif // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 - #if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + #if !TUP_MCU_ESPRESSIF vTaskStartScheduler(); #endif } diff --git a/examples/device/video_capture/src/tusb_config.h b/examples/device/video_capture/src/tusb_config.h index bdfc37d87..21483a2da 100644 --- a/examples/device/video_capture/src/tusb_config.h +++ b/examples/device/video_capture/src/tusb_config.h @@ -58,7 +58,7 @@ #endif // Espressif IDF requires "freertos/" prefix in include path -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF #define CFG_TUSB_OS_INC_PATH freertos/ #endif diff --git a/examples/device/video_capture_2ch/src/main.c b/examples/device/video_capture_2ch/src/main.c index eb1cf2580..e8c2ec6b0 100644 --- a/examples/device/video_capture_2ch/src/main.c +++ b/examples/device/video_capture_2ch/src/main.c @@ -296,7 +296,7 @@ void led_blinking_task(void* param) { #define BLINKY_STACK_SIZE configMINIMAL_STACK_SIZE #define VIDEO_STACK_SIZE (configMINIMAL_STACK_SIZE*4) -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF #define USBD_STACK_SIZE 4096 int main(void); void app_main(void) { @@ -352,7 +352,7 @@ void freertos_init_task(void) { #endif // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 - #if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) + #if !TUP_MCU_ESPRESSIF vTaskStartScheduler(); #endif } diff --git a/examples/device/video_capture_2ch/src/tusb_config.h b/examples/device/video_capture_2ch/src/tusb_config.h index fe66d63b5..43c7dfc90 100644 --- a/examples/device/video_capture_2ch/src/tusb_config.h +++ b/examples/device/video_capture_2ch/src/tusb_config.h @@ -58,7 +58,7 @@ #endif // Espressif IDF requires "freertos/" prefix in include path -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF #define CFG_TUSB_OS_INC_PATH freertos/ #endif diff --git a/examples/host/cdc_msc_hid_freertos/src/cdc_app.c b/examples/host/cdc_msc_hid_freertos/src/cdc_app.c index 7d246af67..f3495ab28 100644 --- a/examples/host/cdc_msc_hid_freertos/src/cdc_app.c +++ b/examples/host/cdc_msc_hid_freertos/src/cdc_app.c @@ -27,7 +27,7 @@ #include "tusb.h" #include "bsp/board_api.h" -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF // ESP-IDF need "freertos/" prefix in include path. // CFG_TUSB_OS_INC_PATH should be defined accordingly. #include "freertos/FreeRTOS.h" diff --git a/examples/host/cdc_msc_hid_freertos/src/main.c b/examples/host/cdc_msc_hid_freertos/src/main.c index 069cbdc90..a6cb4d460 100644 --- a/examples/host/cdc_msc_hid_freertos/src/main.c +++ b/examples/host/cdc_msc_hid_freertos/src/main.c @@ -30,7 +30,7 @@ #include "bsp/board_api.h" #include "tusb.h" -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF // ESP-IDF need "freertos/" prefix in include path. // CFG_TUSB_OS_INC_PATH should be defined accordingly. #include "freertos/FreeRTOS.h" @@ -107,14 +107,14 @@ int main(void) { xTimerStart(blinky_tm, 0); // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 -#if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if !TUP_MCU_ESPRESSIF vTaskStartScheduler(); #endif return 0; } -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF void app_main(void) { main(); } diff --git a/examples/host/cdc_msc_hid_freertos/src/tusb_config.h b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h index 35de5ee50..0aab2cd2f 100644 --- a/examples/host/cdc_msc_hid_freertos/src/tusb_config.h +++ b/examples/host/cdc_msc_hid_freertos/src/tusb_config.h @@ -44,7 +44,7 @@ #endif // Espressif IDF requires "freertos/" prefix in include path -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF #define CFG_TUSB_OS_INC_PATH freertos/ #endif diff --git a/hw/bsp/board_api.h b/hw/bsp/board_api.h index f21a32371..eee9ed9c5 100644 --- a/hw/bsp/board_api.h +++ b/hw/bsp/board_api.h @@ -39,7 +39,7 @@ extern "C" { #include "tusb.h" #if CFG_TUSB_OS == OPT_OS_FREERTOS -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TUP_MCU_ESPRESSIF // ESP-IDF need "freertos/" prefix in include path. // CFG_TUSB_OS_INC_PATH should be defined accordingly. #include "freertos/FreeRTOS.h" diff --git a/hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.cmake b/hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.cmake new file mode 100644 index 000000000..18c956714 --- /dev/null +++ b/hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.cmake @@ -0,0 +1,2 @@ +# Apply board specific content here +set(IDF_TARGET "esp32") diff --git a/hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.h b/hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.h new file mode 100644 index 000000000..0c53df06b --- /dev/null +++ b/hw/bsp/espressif/boards/adafruit_feather_esp32_v2/board.h @@ -0,0 +1,53 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, 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. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define NEOPIXEL_PIN 0 +#define NEOPIXEL_POWER_PIN 2 +#define NEOPIXEL_POWER_STATE 1 + +#define BUTTON_PIN 38 +#define BUTTON_STATE_ACTIVE 0 + +// SPI for USB host shield +#define MAX3421_SPI_HOST SPI3_HOST +#define MAX3421_SCK_PIN 5 +#define MAX3421_MOSI_PIN 19 +#define MAX3421_MISO_PIN 21 +#define MAX3421_CS_PIN 33 +#define MAX3421_INTR_PIN 15 + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/espressif/boards/family.c b/hw/bsp/espressif/boards/family.c index 5599d1504..02e478a0c 100644 --- a/hw/bsp/espressif/boards/family.c +++ b/hw/bsp/espressif/boards/family.c @@ -30,8 +30,12 @@ #include "esp_rom_gpio.h" #include "esp_mac.h" #include "hal/gpio_ll.h" + +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) #include "hal/usb_hal.h" #include "soc/usb_periph.h" +static void configure_pins(usb_hal_context_t* usb); +#endif #include "driver/gpio.h" #include "driver/uart.h" @@ -56,7 +60,6 @@ static led_strip_handle_t led_strip; static void max3421_init(void); #endif -static void configure_pins(usb_hal_context_t* usb); //--------------------------------------------------------------------+ // Implementation @@ -100,7 +103,6 @@ void board_init(void) { }; ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip)); - led_strip_clear(led_strip); // off #endif @@ -109,6 +111,7 @@ void board_init(void) { gpio_set_direction(BUTTON_PIN, GPIO_MODE_INPUT); gpio_set_pull_mode(BUTTON_PIN, BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN_ONLY : GPIO_PULLUP_ONLY); +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) // USB Controller Hal init periph_module_reset(PERIPH_USB_MODULE); periph_module_enable(PERIPH_USB_MODULE); @@ -118,12 +121,14 @@ void board_init(void) { }; usb_hal_init(&hal); configure_pins(&hal); +#endif #if CFG_TUH_ENABLED && CFG_TUH_MAX3421 max3421_init(); #endif } +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) static void configure_pins(usb_hal_context_t* usb) { /* usb_periph_iopins currently configures USB_OTG as USB Device. * Introduce additional parameters in usb_hal_context_t when adding support @@ -153,6 +158,7 @@ static void configure_pins(usb_hal_context_t* usb) { gpio_set_drive_capability(USBPHY_DP_NUM, GPIO_DRIVE_CAP_3); } } +#endif //--------------------------------------------------------------------+ // Board porting API @@ -208,15 +214,12 @@ SemaphoreHandle_t max3421_intr_sem; static void IRAM_ATTR max3421_isr_handler(void* arg) { (void) arg; // arg is gpio num - gpio_set_level(13, 1); BaseType_t xHigherPriorityTaskWoken = pdFALSE; xSemaphoreGiveFromISR(max3421_intr_sem, &xHigherPriorityTaskWoken); if (xHigherPriorityTaskWoken) { portYIELD_FROM_ISR(); } - - gpio_set_level(13, 0); } static void max3421_intr_task(void* param) { @@ -250,16 +253,12 @@ static void max3421_init(void) { spi_device_interface_config_t max3421_cfg = { .mode = 0, - .clock_speed_hz = 26000000, + .clock_speed_hz = 20000000, // S2/S3 can work with 26 Mhz, but esp32 seems only work up to 20 Mhz .spics_io_num = -1, // manual control CS .queue_size = 1 }; ESP_ERROR_CHECK(spi_bus_add_device(MAX3421_SPI_HOST, &max3421_cfg, &max3421_spi)); - // debug - gpio_set_direction(13, GPIO_MODE_OUTPUT); - gpio_set_level(13, 0); - // Interrupt pin max3421_intr_sem = xSemaphoreCreateBinary(); xTaskCreate(max3421_intr_task, "max3421 intr", 2048, NULL, configMAX_PRIORITIES - 2, NULL); diff --git a/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt b/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt index abe276910..8bdb3802e 100644 --- a/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt +++ b/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt @@ -5,17 +5,7 @@ set(includes_public) set(compile_options) set(tusb_src "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src") -if(target STREQUAL "esp32s3") - set(tusb_mcu "OPT_MCU_ESP32S3") -elseif(target STREQUAL "esp32s2") - set(tusb_mcu "OPT_MCU_ESP32S2") -else() - # CONFIG_TINYUSB dependency has been guaranteed by Kconfig logic, - # So it's not possible that cmake goes here - message(FATAL_ERROR "TinyUSB is not support on ${target}.") - return() -endif() - +string(TOUPPER OPT_MCU_${target} tusb_mcu) list(APPEND compile_definitions CFG_TUSB_MCU=${tusb_mcu} CFG_TUSB_OS=OPT_OS_FREERTOS diff --git a/hw/bsp/espressif/family.cmake b/hw/bsp/espressif/family.cmake index 92a9bcb04..eb97401c3 100644 --- a/hw/bsp/espressif/family.cmake +++ b/hw/bsp/espressif/family.cmake @@ -3,11 +3,7 @@ cmake_minimum_required(VERSION 3.5) # Apply board specific content i.e IDF_TARGET must be set before project.cmake is included include("${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake") -if(IDF_TARGET STREQUAL "esp32s2") - set(FAMILY_MCUS ESP32S2) -elseif(IDF_TARGET STREQUAL "esp32s3") - set(FAMILY_MCUS ESP32S3) -endif() +string(TOUPPER ${IDF_TARGET} FAMILY_MCUS) # Add example src and bsp directories set(EXTRA_COMPONENT_DIRS "src" "${CMAKE_CURRENT_LIST_DIR}/boards" "${CMAKE_CURRENT_LIST_DIR}/components") diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 0ae2573cd..2c4d7461d 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -329,6 +329,9 @@ #define TUP_USBIP_DWC2 #define TUP_DCD_ENDPOINT_MAX 6 +#elif TU_CHECK_MCU(OPT_MCU_ESP32) && (CFG_TUD_ENABLED || !(defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421)) + #error "MCUs are only supported with CFG_TUH_MAX3421 enabled" + //--------------------------------------------------------------------+ // Dialog //--------------------------------------------------------------------+ @@ -426,7 +429,7 @@ #define TUP_MCU_MULTIPLE_CORE 0 #endif -#ifndef TUP_DCD_ENDPOINT_MAX +#if CFG_TUD_ENABLED && !defined(TUP_DCD_ENDPOINT_MAX) #warning "TUP_DCD_ENDPOINT_MAX is not defined for this MCU, default to 8" #define TUP_DCD_ENDPOINT_MAX 8 #endif diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 39afb7505..053169bf2 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -484,8 +484,8 @@ bool hcd_init(uint8_t rhport) { // v1 is 0x01, v2 is 0x12, v3 is 0x13 uint8_t const revision = reg_read(rhport, REVISION_ADDR, false); - TU_ASSERT(revision == 0x01 || revision == 0x12 || revision == 0x13, false); TU_LOG2_HEX(revision); + TU_ASSERT(revision == 0x01 || revision == 0x12 || revision == 0x13, false); // reset reg_write(rhport, USBCTL_ADDR, USBCTL_CHIPRES, false); diff --git a/src/tusb_option.h b/src/tusb_option.h index cbcb69edd..25412d432 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -119,6 +119,8 @@ // Espressif #define OPT_MCU_ESP32S2 900 ///< Espressif ESP32-S2 #define OPT_MCU_ESP32S3 901 ///< Espressif ESP32-S3 +#define OPT_MCU_ESP32 902 ///< Espressif ESP32 (for host max3421e) +#define TUP_MCU_ESPRESSIF (CFG_TUSB_MCU >= 900 && CFG_TUSB_MCU < 1000) // check if Espressif MCU // Dialog #define OPT_MCU_DA1469X 1000 ///< Dialog Semiconductor DA1469x -- cgit v1.3.1 From 223ce56625474764dc00229c44731858abcf4f29 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 26 Apr 2024 00:10:57 +0700 Subject: - add esp32 c3, c6 mcu option - skip breakpoint for espressif riscv --- examples/host/cdc_msc_hid_freertos/src/main.c | 5 ++++- src/common/tusb_mcu.h | 4 ++-- src/common/tusb_verify.h | 2 +- src/portable/analog/max3421/hcd_max3421.c | 2 ++ src/tusb_option.h | 2 ++ 5 files changed, 11 insertions(+), 4 deletions(-) (limited to 'src/portable') diff --git a/examples/host/cdc_msc_hid_freertos/src/main.c b/examples/host/cdc_msc_hid_freertos/src/main.c index a6cb4d460..fa799aede 100644 --- a/examples/host/cdc_msc_hid_freertos/src/main.c +++ b/examples/host/cdc_msc_hid_freertos/src/main.c @@ -126,7 +126,10 @@ static void usb_host_task(void *param) { (void) param; // init host stack on configured roothub port - tuh_init(BOARD_TUH_RHPORT); + if (!tuh_init(BOARD_TUH_RHPORT)) { + printf("Failed to init USB Host Stack\r\n"); + vTaskSuspend(NULL); + } if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 00526bdba..5a567f2d5 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -429,8 +429,8 @@ #define TUP_MCU_MULTIPLE_CORE 0 #endif -#if !defined(TUP_DCD_ENDPOINT_MAX) - #warning "TUP_DCD_ENDPOINT_MAX is not defined for this MCU, default to 8" +#if !defined(TUP_DCD_ENDPOINT_MAX) && defined(CFG_TUD_ENABLED) && CFG_TUD_ENABLED +#warning "TUP_DCD_ENDPOINT_MAX is not defined for this MCU, default to 8" #define TUP_DCD_ENDPOINT_MAX 8 #endif diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h index 71406dacf..0a9549c99 100644 --- a/src/common/tusb_verify.h +++ b/src/common/tusb_verify.h @@ -84,7 +84,7 @@ if ( (*ARM_CM_DHCSR) & 1UL ) __asm("BKPT #0\n"); /* Only halt mcu if debugger is attached */ \ } while(0) -#elif defined(__riscv) +#elif defined(__riscv) && !TUP_MCU_ESPRESSIF #define TU_BREAKPOINT() do { __asm("ebreak\n"); } while(0) #elif defined(_mips) diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 053169bf2..4dc93d2d8 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -479,6 +479,8 @@ bool hcd_init(uint8_t rhport) { _hcd_data.spi_mutex = osal_mutex_create(&_hcd_data.spi_mutexdef); #endif + // NOTE: driver does not seem to work without nRST pin signal + // full duplex, interrupt negative edge reg_write(rhport, PINCTL_ADDR, _tuh_cfg.pinctl | PINCTL_FDUPSPI, false); diff --git a/src/tusb_option.h b/src/tusb_option.h index 25412d432..3ead20ee7 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -120,6 +120,8 @@ #define OPT_MCU_ESP32S2 900 ///< Espressif ESP32-S2 #define OPT_MCU_ESP32S3 901 ///< Espressif ESP32-S3 #define OPT_MCU_ESP32 902 ///< Espressif ESP32 (for host max3421e) +#define OPT_MCU_ESP32C3 903 ///< Espressif ESP32-C3 +#define OPT_MCU_ESP32C6 904 ///< Espressif ESP32-C6 #define TUP_MCU_ESPRESSIF (CFG_TUSB_MCU >= 900 && CFG_TUSB_MCU < 1000) // check if Espressif MCU // Dialog -- cgit v1.3.1 From cde722385c579fc388fcf78ddb57fad22a643ba5 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 5 Apr 2024 22:19:45 +0200 Subject: dwc2: add dma support. --- src/portable/synopsys/dwc2/dcd_dwc2.c | 154 +++++++++++++++++++++++++++------- 1 file changed, 124 insertions(+), 30 deletions(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 692096fc8..2e679d1f3 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -67,6 +67,11 @@ // Debug level for DWC2 #define DWC2_DEBUG 2 +// DMA switch +#ifndef DWC2_ENABLE_DMA +#define DWC2_ENABLE_DMA 1 +#endif + #ifndef dcache_clean #define dcache_clean(_addr, _size) #endif @@ -186,6 +191,32 @@ static bool fifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) { return true; } +static bool dma_supported(uint8_t rhport) +{ + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + // Internal DMA only + return (dwc2->ghwcfg2_bm.arch == 2) && DWC2_ENABLE_DMA; +} + +static void dma_stpkt_rx(uint8_t rhport) +{ + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + + if (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a) { + if(dwc2->epout[0].doepctl & DOEPCTL_EPENA) + return; + } + + // Receive only 1 packet + dwc2->epout[0].doeptsiz = 0; + dwc2->epout[0].doeptsiz |= (1 << DOEPTSIZ_STUPCNT_Pos); + dwc2->epout[0].doeptsiz |= 8; + dwc2->epout[0].doeptsiz |= (1 << DOEPTSIZ_PKTCNT_Pos); + dwc2->epout[0].doepdma = (uintptr_t)_setup_packet; + + dwc2->epout[0].doepctl |= DOEPCTL_EPENA | DOEPCTL_USBAEP; +} + static void edpt_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); @@ -351,6 +382,11 @@ static void bus_reset(uint8_t rhport) { // Setup the control endpoint 0 _allocated_fifo_words_tx = 16; + // DMA needs extra space for processing, needs size confirmation + if(dma_supported(rhport)) { + _allocated_fifo_words_tx += 72; + } + // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word ) dwc2->dieptxf0 = (16 << DIEPTXF0_TX0FD_Pos) | (_dwc2_controller[rhport].ep_fifo_size / 4 - _allocated_fifo_words_tx); @@ -361,6 +397,10 @@ static void bus_reset(uint8_t rhport) { dwc2->epout[0].doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos); + if(dma_supported(rhport)) { + dma_stpkt_rx(rhport); + } + dwc2->gintmsk |= GINTMSK_OEPINT | GINTMSK_IEPINT; } @@ -369,11 +409,11 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c (void) rhport; dwc2_regs_t* dwc2 = DWC2_REG(rhport); + xfer_ctl_t* const xfer = XFER_CTL_BASE(epnum, dir); // EP0 is limited to one packet each xfer // We use multiple transaction of xfer->max_size length to get a whole transfer done if (epnum == 0) { - xfer_ctl_t* const xfer = XFER_CTL_BASE(epnum, dir); total_bytes = tu_min16(ep0_pending[dir], xfer->max_size); ep0_pending[dir] -= total_bytes; } @@ -386,17 +426,31 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c epin[epnum].dieptsiz = (num_packets << DIEPTSIZ_PKTCNT_Pos) | ((total_bytes << DIEPTSIZ_XFRSIZ_Pos) & DIEPTSIZ_XFRSIZ_Msk); - epin[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK; + if(dma_supported(rhport)) { + epin[epnum].diepdma = (uintptr_t)xfer->buffer; - // For ISO endpoint set correct odd/even bit for next frame. - if ((epin[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) { - // Take odd/even bit from frame counter. - uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); - epin[epnum].diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk); - } - // Enable fifo empty interrupt only if there are something to put in the fifo. - if (total_bytes != 0) { - dwc2->diepempmsk |= (1 << epnum); + // For ISO endpoint set correct odd/even bit for next frame. + if ((epin[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) { + // Take odd/even bit from frame counter. + uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); + epin[epnum].diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk); + } + + epin[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK; + } else { + + epin[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK; + + // For ISO endpoint set correct odd/even bit for next frame. + if ((epin[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) { + // Take odd/even bit from frame counter. + uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); + epin[epnum].diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk); + } + // Enable fifo empty interrupt only if there are something to put in the fifo. + if (total_bytes != 0) { + dwc2->diepempmsk |= (1 << epnum); + } } } else { dwc2_epout_t* epout = dwc2->epout; @@ -406,13 +460,18 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c epout[epnum].doeptsiz |= (num_packets << DOEPTSIZ_PKTCNT_Pos) | ((total_bytes << DOEPTSIZ_XFRSIZ_Pos) & DOEPTSIZ_XFRSIZ_Msk); - epout[epnum].doepctl |= DOEPCTL_EPENA | DOEPCTL_CNAK; if ((epout[epnum].doepctl & DOEPCTL_EPTYP) == DOEPCTL_EPTYP_0 && XFER_CTL_BASE(epnum, dir)->interval == 1) { // Take odd/even bit from frame counter. uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); epout[epnum].doepctl |= (odd_frame_now ? DOEPCTL_SD0PID_SEVNFRM_Msk : DOEPCTL_SODDFRM_Msk); } + + if(dma_supported(rhport)) { + epout[epnum].doepdma = (uintptr_t)xfer->buffer; + } + + epout[epnum].doepctl |= DOEPCTL_EPENA | DOEPCTL_CNAK; } } @@ -619,6 +678,11 @@ void dcd_init(uint8_t rhport) { // Enable global interrupt dwc2->gahbcfg |= GAHBCFG_GINT; + if (dma_supported(rhport)) { + dwc2->gahbcfg |= GAHBCFG_DMAEN | GAHBCFG_HBSTLEN_2; + dwc2->gintmsk &=~GINTMSK_RXFLVLM; + } + // make sure we are in device mode // TU_ASSERT(!(dwc2->gintsts & GINTSTS_CMOD), ); @@ -728,6 +792,11 @@ void dcd_edpt_close_all(uint8_t rhport) { // reset allocated fifo IN _allocated_fifo_words_tx = 16; + // DMA needs extra space for processing, needs size confirmation + if(dma_supported(rhport)) { + _allocated_fifo_words_tx += 72; + } + fifo_flush_tx(dwc2, 0x10); // all tx fifo fifo_flush_rx(dwc2); } @@ -809,6 +878,9 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { edpt_disable(rhport, ep_addr, true); + if((tu_edpt_number(ep_addr) == 0) && dma_supported(rhport)) { + dma_stpkt_rx(rhport); + } } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { @@ -991,32 +1063,51 @@ static void handle_epout_irq(uint8_t rhport) { uint32_t const doepint = epout->doepint; - // SETUP packet Setup Phase done. - if (doepint & DOEPINT_STUP) { - uint32_t clear_flag = DOEPINT_STUP; - - // STPKTRX is only available for version from 3_00a - if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { - clear_flag |= DOEPINT_STPKTRX; - } - - epout->doepint = clear_flag; - dcd_event_setup_received(rhport, (uint8_t*) _setup_packet, true); - } - // OUT XFER complete if (epout->doepint & DOEPINT_XFRC) { epout->doepint = DOEPINT_XFRC; xfer_ctl_t* xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT); - // EP0 can only handle one packet - if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { - // Schedule another packet to be received. - edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + if (doepint & DOEPINT_STUP) { + // STPKTRX is only available for version from 3_00a + if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { + epout->doepint = DOEPINT_STPKTRX; + } + } else if (doepint & DOEPINT_OTEPSPR) { + epout->doepint = DOEPINT_OTEPSPR; } else { - dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); + // EP0 can only handle one packet + if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { + // Schedule another packet to be received. + edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + } else { + if(dma_supported(rhport)) { + // Fix packet length + uint16_t remain = (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos; + xfer->total_len -= remain; + // this is ZLP, so prepare EP0 for next setup + if(n == 0 && xfer->total_len == 0) { + dma_stpkt_rx(rhport); + } + } + + dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); + } + } + } + + // SETUP packet Setup Phase done. + if (doepint & DOEPINT_STUP) { + epout->doepint = DOEPINT_STUP; + if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { + epout->doepint = DOEPINT_STPKTRX; + } + if(dma_supported(rhport) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { + dma_stpkt_rx(rhport); } + + dcd_event_setup_received(rhport, (uint8_t*) _setup_packet, true); } } } @@ -1042,6 +1133,9 @@ static void handle_epin_irq(uint8_t rhport) { // Schedule another packet to be transmitted. edpt_schedule_packets(rhport, n, TUSB_DIR_IN, 1, ep0_pending[TUSB_DIR_IN]); } else { + if((n == 0) && dma_supported(rhport)) { + dma_stpkt_rx(rhport); + } dcd_event_xfer_complete(rhport, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); } } -- cgit v1.3.1 From 394dc0686a5c26bd3375ce9aba12b82fa18ba42f Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 25 Apr 2024 22:09:59 +0200 Subject: Check IN ep count limit. --- src/portable/synopsys/dwc2/dcd_dwc2.c | 13 +++++++++++++ src/portable/synopsys/dwc2/dwc2_esp32.h | 5 +++-- src/portable/synopsys/dwc2/dwc2_type.h | 1 + 3 files changed, 17 insertions(+), 2 deletions(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 2e679d1f3..cdf6c2a68 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -103,6 +103,9 @@ static uint16_t ep0_pending[2]; // Index determines direction as t // TX FIFO RAM allocation so far in words - RX FIFO size is readily available from dwc2->grxfsiz static uint16_t _allocated_fifo_words_tx; // TX FIFO size in words (IN EPs) +// Number of IN endpoints active +static uint8_t _allocated_ep_in_count; + // SOF enabling flag - required for SOF to not get disabled in ISR when SOF was enabled by static bool _sof_en; @@ -170,6 +173,12 @@ static bool fifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) { dwc2->grxfsiz = sz; } } else { + // Check IN endpoints concurrently active limit + if(_dwc2_controller->ep_in_count) { + TU_ASSERT(_allocated_ep_in_count < _dwc2_controller->ep_in_count); + _allocated_ep_in_count++; + } + // Note if The TXFELVL is configured as half empty. In order // to be able to write a packet at that point, the fifo must be twice the max_size. if ((dwc2->gahbcfg & GAHBCFG_TXFELVL) == 0) { @@ -303,6 +312,8 @@ static void bus_reset(uint8_t rhport) { _sof_en = false; + _allocated_ep_in_count = 1; + // clear device address dwc2->dcfg &= ~DCFG_DAD_Msk; @@ -770,6 +781,8 @@ void dcd_edpt_close_all(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); uint8_t const ep_count = _dwc2_controller[rhport].ep_count; + _allocated_ep_in_count = 1; + // Disable non-control interrupt dwc2->daintmsk = (1 << DAINTMSK_OEPM_Pos) | (1 << DAINTMSK_IEPM_Pos); diff --git a/src/portable/synopsys/dwc2/dwc2_esp32.h b/src/portable/synopsys/dwc2/dwc2_esp32.h index c50dd66b8..fc12d7551 100644 --- a/src/portable/synopsys/dwc2/dwc2_esp32.h +++ b/src/portable/synopsys/dwc2/dwc2_esp32.h @@ -37,11 +37,12 @@ //#include "soc/usb_periph.h" #define DWC2_REG_BASE 0x60080000UL -#define DWC2_EP_MAX 6 // USB_OUT_EP_NUM. TODO ESP32Sx only has 5 tx fifo (5 endpoint IN) +#define DWC2_EP_MAX 7 +#define DWC2_EP_IN_MAX 5 static const dwc2_controller_t _dwc2_controller[] = { - { .reg_base = DWC2_REG_BASE, .irqnum = 0, .ep_count = DWC2_EP_MAX, .ep_fifo_size = 1024 } + { .reg_base = DWC2_REG_BASE, .irqnum = 0, .ep_count = DWC2_EP_MAX, .ep_in_count = DWC2_EP_IN_MAX, .ep_fifo_size = 1024 } }; static intr_handle_t usb_ih; diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index c15771237..5db453561 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -29,6 +29,7 @@ typedef struct uintptr_t reg_base; uint32_t irqnum; uint8_t ep_count; + uint8_t ep_in_count; uint32_t ep_fifo_size; }dwc2_controller_t; -- cgit v1.3.1 From 298f7f2d818d117785af9f79da79fbdb85120cd2 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 25 Apr 2024 22:11:49 +0200 Subject: Fix DMA FIFO reservation. --- src/portable/synopsys/dwc2/dcd_dwc2.c | 16 +++++++++------- src/portable/synopsys/dwc2/dwc2_bcm.h | 2 +- src/portable/synopsys/dwc2/dwc2_type.h | 6 +++--- 3 files changed, 13 insertions(+), 11 deletions(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index cdf6c2a68..1057ee925 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -393,9 +393,10 @@ static void bus_reset(uint8_t rhport) { // Setup the control endpoint 0 _allocated_fifo_words_tx = 16; - // DMA needs extra space for processing, needs size confirmation + // DMA needs extra space for processing if(dma_supported(rhport)) { - _allocated_fifo_words_tx += 72; + uint16_t reserved = _dwc2_controller[rhport].ep_fifo_size / 4- dwc2->ghwcfg3_bm.total_fifo_size; + _allocated_fifo_words_tx += reserved; } // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word ) @@ -805,13 +806,14 @@ void dcd_edpt_close_all(uint8_t rhport) { // reset allocated fifo IN _allocated_fifo_words_tx = 16; - // DMA needs extra space for processing, needs size confirmation - if(dma_supported(rhport)) { - _allocated_fifo_words_tx += 72; - } - fifo_flush_tx(dwc2, 0x10); // all tx fifo fifo_flush_rx(dwc2); + + // DMA needs extra space for processing + if(dma_supported(rhport)) { + uint16_t reserved = _dwc2_controller[rhport].ep_fifo_size / 4- dwc2->ghwcfg3_bm.total_fifo_size; + _allocated_fifo_words_tx += reserved; + } } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { diff --git a/src/portable/synopsys/dwc2/dwc2_bcm.h b/src/portable/synopsys/dwc2/dwc2_bcm.h index 732d96ae0..e5824606a 100644 --- a/src/portable/synopsys/dwc2/dwc2_bcm.h +++ b/src/portable/synopsys/dwc2/dwc2_bcm.h @@ -39,7 +39,7 @@ static const dwc2_controller_t _dwc2_controller[] = { - { .reg_base = USB_OTG_GLOBAL_BASE, .irqnum = USB_IRQn, .ep_count = DWC2_EP_MAX, .ep_fifo_size = 4096 } + { .reg_base = USB_OTG_GLOBAL_BASE, .irqnum = USB_IRQn, .ep_count = DWC2_EP_MAX, .ep_fifo_size = 16384 } }; #define dcache_clean(_addr, _size) data_clean(_addr, _size) diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index 5db453561..08c9b8b1b 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -214,15 +214,15 @@ union { volatile uint32_t ghwcfg1; // 044 User Hardware Configuration1: endpoint dir (2 bit per ep) union { volatile uint32_t ghwcfg2; // 048 User Hardware Configuration2 - dwc2_ghwcfg2_t ghwcfg2_bm; + volatile dwc2_ghwcfg2_t ghwcfg2_bm; }; union { volatile uint32_t ghwcfg3; // 04C User Hardware Configuration3 - dwc2_ghwcfg3_t ghwcfg3_bm; + volatile dwc2_ghwcfg3_t ghwcfg3_bm; }; union { volatile uint32_t ghwcfg4; // 050 User Hardware Configuration4 - dwc2_ghwcfg4_t ghwcfg4_bm; + volatile dwc2_ghwcfg4_t ghwcfg4_bm; }; volatile uint32_t glpmcfg; // 054 Core LPM Configuration volatile uint32_t gpwrdn; // 058 Power Down -- cgit v1.3.1 From 87655682822690de87ade34ceca7c21ca65dd000 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 25 Apr 2024 22:39:19 +0200 Subject: Change DMA condition. --- src/class/audio/audio_device.c | 4 ++- src/portable/synopsys/dwc2/dcd_dwc2.c | 47 ++++++++++++++--------------------- 2 files changed, 21 insertions(+), 30 deletions(-) (limited to 'src/portable') diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 9ba38a20c..b7af0259a 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -65,8 +65,10 @@ //--------------------------------------------------------------------+ // Use ring buffer if it's available, some MCUs need extra RAM requirements +// For DWC2 enable ring buffer will disable DMA (if available) #ifndef TUD_AUDIO_PREFER_RING_BUFFER - #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT1XXX + #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT1XXX || \ + defined(TUP_USBIP_DWC2) #define TUD_AUDIO_PREFER_RING_BUFFER 0 #else #define TUD_AUDIO_PREFER_RING_BUFFER 1 diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 1057ee925..c4b1956ce 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -67,23 +67,6 @@ // Debug level for DWC2 #define DWC2_DEBUG 2 -// DMA switch -#ifndef DWC2_ENABLE_DMA -#define DWC2_ENABLE_DMA 1 -#endif - -#ifndef dcache_clean -#define dcache_clean(_addr, _size) -#endif - -#ifndef dcache_invalidate -#define dcache_invalidate(_addr, _size) -#endif - -#ifndef dcache_clean_invalidate -#define dcache_clean_invalidate(_addr, _size) -#endif - static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2]; typedef struct { @@ -200,11 +183,17 @@ static bool fifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) { return true; } -static bool dma_supported(uint8_t rhport) +static inline bool dma_enabled(uint8_t rhport) { + // DMA doesn't support fifo transfer +#ifdef TUD_AUDIO_PREFER_RING_BUFFER +#if TUD_AUDIO_PREFER_RING_BUFFER + return false; +#endif +#endif dwc2_regs_t* dwc2 = DWC2_REG(rhport); // Internal DMA only - return (dwc2->ghwcfg2_bm.arch == 2) && DWC2_ENABLE_DMA; + return (dwc2->ghwcfg2_bm.arch == 2); } static void dma_stpkt_rx(uint8_t rhport) @@ -394,7 +383,7 @@ static void bus_reset(uint8_t rhport) { _allocated_fifo_words_tx = 16; // DMA needs extra space for processing - if(dma_supported(rhport)) { + if(dma_enabled(rhport)) { uint16_t reserved = _dwc2_controller[rhport].ep_fifo_size / 4- dwc2->ghwcfg3_bm.total_fifo_size; _allocated_fifo_words_tx += reserved; } @@ -409,7 +398,7 @@ static void bus_reset(uint8_t rhport) { dwc2->epout[0].doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos); - if(dma_supported(rhport)) { + if(dma_enabled(rhport)) { dma_stpkt_rx(rhport); } @@ -438,7 +427,7 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c epin[epnum].dieptsiz = (num_packets << DIEPTSIZ_PKTCNT_Pos) | ((total_bytes << DIEPTSIZ_XFRSIZ_Pos) & DIEPTSIZ_XFRSIZ_Msk); - if(dma_supported(rhport)) { + if(dma_enabled(rhport)) { epin[epnum].diepdma = (uintptr_t)xfer->buffer; // For ISO endpoint set correct odd/even bit for next frame. @@ -479,7 +468,7 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c epout[epnum].doepctl |= (odd_frame_now ? DOEPCTL_SD0PID_SEVNFRM_Msk : DOEPCTL_SODDFRM_Msk); } - if(dma_supported(rhport)) { + if(dma_enabled(rhport)) { epout[epnum].doepdma = (uintptr_t)xfer->buffer; } @@ -690,7 +679,7 @@ void dcd_init(uint8_t rhport) { // Enable global interrupt dwc2->gahbcfg |= GAHBCFG_GINT; - if (dma_supported(rhport)) { + if (dma_enabled(rhport)) { dwc2->gahbcfg |= GAHBCFG_DMAEN | GAHBCFG_HBSTLEN_2; dwc2->gintmsk &=~GINTMSK_RXFLVLM; } @@ -810,7 +799,7 @@ void dcd_edpt_close_all(uint8_t rhport) { fifo_flush_rx(dwc2); // DMA needs extra space for processing - if(dma_supported(rhport)) { + if(dma_enabled(rhport)) { uint16_t reserved = _dwc2_controller[rhport].ep_fifo_size / 4- dwc2->ghwcfg3_bm.total_fifo_size; _allocated_fifo_words_tx += reserved; } @@ -893,7 +882,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { edpt_disable(rhport, ep_addr, true); - if((tu_edpt_number(ep_addr) == 0) && dma_supported(rhport)) { + if((tu_edpt_number(ep_addr) == 0) && dma_enabled(rhport)) { dma_stpkt_rx(rhport); } } @@ -1097,7 +1086,7 @@ static void handle_epout_irq(uint8_t rhport) { // Schedule another packet to be received. edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); } else { - if(dma_supported(rhport)) { + if(dma_enabled(rhport)) { // Fix packet length uint16_t remain = (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos; xfer->total_len -= remain; @@ -1118,7 +1107,7 @@ static void handle_epout_irq(uint8_t rhport) { if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { epout->doepint = DOEPINT_STPKTRX; } - if(dma_supported(rhport) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { + if(dma_enabled(rhport) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { dma_stpkt_rx(rhport); } @@ -1148,7 +1137,7 @@ static void handle_epin_irq(uint8_t rhport) { // Schedule another packet to be transmitted. edpt_schedule_packets(rhport, n, TUSB_DIR_IN, 1, ep0_pending[TUSB_DIR_IN]); } else { - if((n == 0) && dma_supported(rhport)) { + if((n == 0) && dma_enabled(rhport)) { dma_stpkt_rx(rhport); } dcd_event_xfer_complete(rhport, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); -- cgit v1.3.1 From c717e52ab2453f7672b16f2d63cd70558950ef33 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 May 2024 17:54:44 +0700 Subject: add cmake for lpc11 --- .../device/audio_4_channel_mic_freertos/skip.txt | 1 + .../kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h | 2 +- hw/bsp/lpc11/FreeRTOSConfig/FreeRTOSConfig.h | 178 ++++++++++++++++++ hw/bsp/lpc11/boards/lpcxpresso11u37/board.cmake | 19 ++ hw/bsp/lpc11/boards/lpcxpresso11u37/board.h | 98 ++++++++++ .../lpc11/boards/lpcxpresso11u37/lpcxpresso11u37.c | 208 --------------------- hw/bsp/lpc11/boards/lpcxpresso11u68/board.cmake | 12 ++ hw/bsp/lpc11/boards/lpcxpresso11u68/board.h | 27 +++ hw/bsp/lpc11/boards/lpcxpresso11u68/board.mk | 1 - .../lpc11/boards/lpcxpresso11u68/lpcxpresso11u68.c | 135 ------------- hw/bsp/lpc11/family.c | 120 ++++++++++++ hw/bsp/lpc11/family.cmake | 104 +++++++++++ hw/bsp/lpc11/family.mk | 5 +- src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 10 + 14 files changed, 572 insertions(+), 348 deletions(-) create mode 100644 hw/bsp/lpc11/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/lpc11/boards/lpcxpresso11u37/board.cmake create mode 100644 hw/bsp/lpc11/boards/lpcxpresso11u37/board.h delete mode 100644 hw/bsp/lpc11/boards/lpcxpresso11u37/lpcxpresso11u37.c create mode 100644 hw/bsp/lpc11/boards/lpcxpresso11u68/board.cmake create mode 100644 hw/bsp/lpc11/boards/lpcxpresso11u68/board.h delete mode 100644 hw/bsp/lpc11/boards/lpcxpresso11u68/lpcxpresso11u68.c create mode 100644 hw/bsp/lpc11/family.c create mode 100644 hw/bsp/lpc11/family.cmake (limited to 'src/portable') diff --git a/examples/device/audio_4_channel_mic_freertos/skip.txt b/examples/device/audio_4_channel_mic_freertos/skip.txt index eb434c23b..21683518c 100644 --- a/examples/device/audio_4_channel_mic_freertos/skip.txt +++ b/examples/device/audio_4_channel_mic_freertos/skip.txt @@ -10,5 +10,6 @@ mcu:SAMX7X mcu:VALENTYUSB_EPTRI mcu:RAXXX mcu:STM32L0 +board:lpcxpresso11u37 family:broadcom_32bit family:broadcom_64bit diff --git a/hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h index 133728596..e6604d360 100644 --- a/hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h @@ -147,7 +147,7 @@ //--------------------------------------------------------------------+ // For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header -#define configPRIO_BITS 4 +#define configPRIO_BITS 2 /* The lowest interrupt priority that can be used in a call to a "set priority" function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 2 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* Define to trap errors during development. */ +// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 +#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) + #define configASSERT(_exp) \ + do {\ + if ( !(_exp) ) { \ + volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ + if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ + taskDISABLE_INTERRUPTS(); \ + __asm("BKPT #0\n"); \ + }\ + }\ + } while(0) +#else + #define configASSERT( x ) +#endif + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 2 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< Date: Thu, 2 May 2024 18:24:47 +0700 Subject: add cmake for lpc15 --- hw/bsp/lpc15/FreeRTOSConfig/FreeRTOSConfig.h | 179 +++++++++++++++++++++++++ hw/bsp/lpc15/boards/lpcxpresso1549/board.cmake | 11 ++ hw/bsp/lpc15/family.c | 11 ++ hw/bsp/lpc15/family.cmake | 104 ++++++++++++++ hw/bsp/lpc15/family.mk | 2 +- src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 1 + 6 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 hw/bsp/lpc15/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/lpc15/boards/lpcxpresso1549/board.cmake create mode 100644 hw/bsp/lpc15/family.cmake (limited to 'src/portable') diff --git a/hw/bsp/lpc15/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/lpc15/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..33bc22b37 --- /dev/null +++ b/hw/bsp/lpc15/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,179 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wunused-parameter" + #pragma GCC diagnostic ignored "-Wstrict-prototypes" + #endif + + #include "chip.h" + + #ifdef __GNUC__ + #pragma GCC diagnostic pop + #endif +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#if defined(__ARM_FP) && __ARM_FP >= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 2 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* Define to trap errors during development. */ +// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 +#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) + #define configASSERT(_exp) \ + do {\ + if ( !(_exp) ) { \ + volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ + if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ + taskDISABLE_INTERRUPTS(); \ + __asm("BKPT #0\n"); \ + }\ + }\ + } while(0) +#else + #define configASSERT( x ) +#endif + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 3 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< Date: Sat, 4 May 2024 12:36:40 +0700 Subject: add cmake for f1c100s --- examples/build_system/cmake/cpu/arm1176jzf-s.cmake | 2 + examples/build_system/cmake/cpu/arm926ej-s.cmake | 21 ++++ examples/build_system/make/cpu/arm926ej-s.mk | 9 ++ hw/bsp/f1c100s/board.h | 1 - hw/bsp/f1c100s/board.mk | 52 --------- hw/bsp/f1c100s/boards/f1c100s/board.cmake | 3 + hw/bsp/f1c100s/boards/f1c100s/board.h | 6 + hw/bsp/f1c100s/boards/f1c100s/board.mk | 1 + hw/bsp/f1c100s/f1c100s.c | 130 --------------------- hw/bsp/f1c100s/family.c | 126 ++++++++++++++++++++ hw/bsp/f1c100s/family.cmake | 114 ++++++++++++++++++ hw/bsp/f1c100s/family.mk | 58 +++++++++ src/portable/sunxi/dcd_sunxi_musb.c | 14 ++- 13 files changed, 348 insertions(+), 189 deletions(-) create mode 100644 examples/build_system/cmake/cpu/arm926ej-s.cmake create mode 100644 examples/build_system/make/cpu/arm926ej-s.mk delete mode 100644 hw/bsp/f1c100s/board.h delete mode 100644 hw/bsp/f1c100s/board.mk create mode 100644 hw/bsp/f1c100s/boards/f1c100s/board.cmake create mode 100644 hw/bsp/f1c100s/boards/f1c100s/board.h create mode 100644 hw/bsp/f1c100s/boards/f1c100s/board.mk delete mode 100644 hw/bsp/f1c100s/f1c100s.c create mode 100644 hw/bsp/f1c100s/family.c create mode 100644 hw/bsp/f1c100s/family.cmake create mode 100644 hw/bsp/f1c100s/family.mk (limited to 'src/portable') diff --git a/examples/build_system/cmake/cpu/arm1176jzf-s.cmake b/examples/build_system/cmake/cpu/arm1176jzf-s.cmake index 11bb52f30..8029e3987 100644 --- a/examples/build_system/cmake/cpu/arm1176jzf-s.cmake +++ b/examples/build_system/cmake/cpu/arm1176jzf-s.cmake @@ -1,6 +1,7 @@ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS -mcpu=arm1176jzf-s + -ffreestanding ) # set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") @@ -10,6 +11,7 @@ elseif (TOOLCHAIN STREQUAL "clang") -mcpu=arm1176jzf-s -mfpu=none -mfloat-abi=soft + -ffreestanding ) #set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") diff --git a/examples/build_system/cmake/cpu/arm926ej-s.cmake b/examples/build_system/cmake/cpu/arm926ej-s.cmake new file mode 100644 index 000000000..c19b9f8a8 --- /dev/null +++ b/examples/build_system/cmake/cpu/arm926ej-s.cmake @@ -0,0 +1,21 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(TOOLCHAIN_COMMON_FLAGS + -mcpu=arm926ej-s + -ffreestanding + ) + # set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "clang") + set(TOOLCHAIN_COMMON_FLAGS + --target=arm-none-eabi + -mcpu=arm926ej-s + -mfpu=none + -mfloat-abi=soft + -ffreestanding + ) + #set(FREERTOS_PORT GCC_ARM_CM0 CACHE INTERNAL "") + +elseif (TOOLCHAIN STREQUAL "iar") + message(FATAL_ERROR "IAR not supported") + +endif () diff --git a/examples/build_system/make/cpu/arm926ej-s.mk b/examples/build_system/make/cpu/arm926ej-s.mk new file mode 100644 index 000000000..5b84f514f --- /dev/null +++ b/examples/build_system/make/cpu/arm926ej-s.mk @@ -0,0 +1,9 @@ +ifeq ($(TOOLCHAIN),gcc) + CFLAGS += \ + -mcpu=arm926ej-s \ + +else ifeq ($(TOOLCHAIN),iar) + #CFLAGS += --cpu cortex-a53 + #ASFLAGS += --cpu cortex-a53 + +endif diff --git a/hw/bsp/f1c100s/board.h b/hw/bsp/f1c100s/board.h deleted file mode 100644 index 0ef9a1700..000000000 --- a/hw/bsp/f1c100s/board.h +++ /dev/null @@ -1 +0,0 @@ -// Nothing valuable here diff --git a/hw/bsp/f1c100s/board.mk b/hw/bsp/f1c100s/board.mk deleted file mode 100644 index 3596e5414..000000000 --- a/hw/bsp/f1c100s/board.mk +++ /dev/null @@ -1,52 +0,0 @@ -MCU_DIR = hw/mcu/allwinner/f1c100s -DEPS_SUBMODULES += hw/mcu/allwinner -DEFINES += -D__ARM32_ARCH__=5 -D__ARM926EJS__ - -CFLAGS += \ - -ffreestanding \ - -std=gnu99 \ - -march=armv5te \ - -mtune=arm926ej-s \ - -mfloat-abi=soft \ - -marm \ - -mno-thumb-interwork \ - -Wno-unused-parameter \ - -Wno-float-equal \ - -DCFG_TUSB_MCU=OPT_MCU_F1C100S \ - -Wno-error=cast-align \ - -Wno-error=address-of-packed-member \ - $(DEFINES) - -LD_FILE = hw/mcu/allwinner/f1c100s/f1c100s.ld -# TODO may skip nanolib -LDFLAGS += -nostdlib -lgcc -specs=nosys.specs -specs=nano.specs - -SRC_C += \ - src/portable/sunxi/dcd_sunxi_musb.c \ - $(MCU_DIR)/machine/sys-uart.c \ - $(MCU_DIR)/machine/exception.c \ - $(MCU_DIR)/machine/sys-clock.c \ - $(MCU_DIR)/machine/sys-copyself.c \ - $(MCU_DIR)/machine/sys-dram.c \ - $(MCU_DIR)/machine/sys-mmu.c \ - $(MCU_DIR)/machine/sys-spi-flash.c \ - $(MCU_DIR)/machine/f1c100s-intc.c \ - $(MCU_DIR)/lib/malloc.c \ - $(MCU_DIR)/lib/printf.c - -SRC_S += \ - $(MCU_DIR)/machine/start.S \ - $(MCU_DIR)/lib/memcpy.S \ - $(MCU_DIR)/lib/memset.S - -INC += \ - $(TOP)/$(MCU_DIR)/include \ - $(TOP)/$(BOARD_PATH) - -# flash target using xfel -flash: flash-xfel - -exec: $(BUILD)/$(PROJECT).bin - xfel ddr - xfel write 0x80000000 $< - xfel exec 0x80000000 diff --git a/hw/bsp/f1c100s/boards/f1c100s/board.cmake b/hw/bsp/f1c100s/boards/f1c100s/board.cmake new file mode 100644 index 000000000..98ed56c57 --- /dev/null +++ b/hw/bsp/f1c100s/boards/f1c100s/board.cmake @@ -0,0 +1,3 @@ +function(update_board TARGET) + # nothing to do +endfunction() diff --git a/hw/bsp/f1c100s/boards/f1c100s/board.h b/hw/bsp/f1c100s/boards/f1c100s/board.h new file mode 100644 index 000000000..3b56a3a57 --- /dev/null +++ b/hw/bsp/f1c100s/boards/f1c100s/board.h @@ -0,0 +1,6 @@ +#ifndef BOARD_H +#define BOARD_H + +// Nothing valuable here + +#endif diff --git a/hw/bsp/f1c100s/boards/f1c100s/board.mk b/hw/bsp/f1c100s/boards/f1c100s/board.mk new file mode 100644 index 000000000..be830bd8c --- /dev/null +++ b/hw/bsp/f1c100s/boards/f1c100s/board.mk @@ -0,0 +1 @@ +# nothing to do diff --git a/hw/bsp/f1c100s/f1c100s.c b/hw/bsp/f1c100s/f1c100s.c deleted file mode 100644 index 272b756f2..000000000 --- a/hw/bsp/f1c100s/f1c100s.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 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 -#include -#include -#include -#include "bsp/board_api.h" -#include "board.h" - -extern void sys_uart_putc(char c); - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -static void timer_init(void); - -void board_init(void) -{ - arch_local_irq_disable(); - do_init_mem_pool(); - f1c100s_intc_init(); - timer_init(); - printf("Timer INIT done\n"); - arch_local_irq_enable(); -} - -// No LED, no button -void board_led_write(bool state) -{ - -} - -uint32_t board_button_read(void) -{ - return 0; -} - -int board_uart_read(uint8_t* buf, int len) -{ - return 0; -} - -int board_uart_write(void const * buf, int len) -{ - int txsize = len; - while (txsize--) { - sys_uart_putc(*(uint8_t const*)buf); - buf++; - } - return len; -} - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; - -uint32_t board_millis(void) -{ - return system_ticks; -} - -static void timer_handler(void) -{ - volatile uint32_t *temp_addr = (uint32_t *)(0x01C20C00 + 0x04); - - /* clear timer */ - *temp_addr |= 0x01; - - system_ticks++; -} - -static void timer_init(void) { - uint32_t temp; - volatile uint32_t *temp_addr; - - /* reload value */ - temp = 12000000 / 1000; - temp_addr = (uint32_t *)(0x01C20C00 + 0x14); - *temp_addr = temp; - - /* continuous | /2 | 24Mhz | reload*/ - temp = (0x00 << 7) | (0x01 << 4) | (0x01 << 2) | (0x00 << 1); - temp_addr = (uint32_t *)(0x01C20C00 + 0x10); - *temp_addr &= 0xffffff00; - *temp_addr |= temp; - - /* open timer irq */ - temp = 0x01 << 0; - temp_addr = (uint32_t *)(0x01C20C00); - *temp_addr |= temp; - - /* set init value */ - temp_addr = (uint32_t *)(0x01C20C00 + 0x18); - *temp_addr = 0; - - /* begin run timer */ - temp = 0x01 << 0; - temp_addr = (uint32_t *)(0x01C20C00 + 0x10); - *temp_addr |= temp; - - f1c100s_intc_set_isr(F1C100S_IRQ_TIMER0, timer_handler); - f1c100s_intc_enable_irq(F1C100S_IRQ_TIMER0); -} -#else -static void timer_init(void) { } -#endif diff --git a/hw/bsp/f1c100s/family.c b/hw/bsp/f1c100s/family.c new file mode 100644 index 000000000..6df4a0ed8 --- /dev/null +++ b/hw/bsp/f1c100s/family.c @@ -0,0 +1,126 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 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 +#include +#include +#include +#include "bsp/board_api.h" +#include "board.h" + +extern void sys_uart_putc(char c); + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +static void timer_init(void); + +void board_init(void) { + arch_local_irq_disable(); + do_init_mem_pool(); + f1c100s_intc_init(); + timer_init(); + printf("Timer INIT done\n"); + arch_local_irq_enable(); +} + +// No LED, no button +void board_led_write(bool state) { + (void) state; +} + +uint32_t board_button_read(void) { + return 0; +} + +int board_uart_read(uint8_t* buf, int len) { + (void) buf; + (void) len; + return 0; +} + +int board_uart_write(void const* buf, int len) { + int txsize = len; + while (txsize--) { + sys_uart_putc(*(uint8_t const*) buf); + buf++; + } + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +uint32_t board_millis(void) { + return system_ticks; +} + +static void timer_handler(void) { + volatile uint32_t* temp_addr = (uint32_t*) (0x01C20C00 + 0x04); + + /* clear timer */ + *temp_addr |= 0x01; + + system_ticks++; +} + +static void timer_init(void) { + uint32_t temp; + volatile uint32_t* temp_addr; + + /* reload value */ + temp = 12000000 / 1000; + temp_addr = (uint32_t*) (0x01C20C00 + 0x14); + *temp_addr = temp; + + /* continuous | /2 | 24Mhz | reload*/ + temp = (0x00 << 7) | (0x01 << 4) | (0x01 << 2) | (0x00 << 1); + temp_addr = (uint32_t*) (0x01C20C00 + 0x10); + *temp_addr &= 0xffffff00; + *temp_addr |= temp; + + /* open timer irq */ + temp = 0x01 << 0; + temp_addr = (uint32_t*) (0x01C20C00); + *temp_addr |= temp; + + /* set init value */ + temp_addr = (uint32_t*) (0x01C20C00 + 0x18); + *temp_addr = 0; + + /* begin run timer */ + temp = 0x01 << 0; + temp_addr = (uint32_t*) (0x01C20C00 + 0x10); + *temp_addr |= temp; + + f1c100s_intc_set_isr(F1C100S_IRQ_TIMER0, timer_handler); + f1c100s_intc_enable_irq(F1C100S_IRQ_TIMER0); +} + +#else +static void timer_init(void) { } +#endif diff --git a/hw/bsp/f1c100s/family.cmake b/hw/bsp/f1c100s/family.cmake new file mode 100644 index 000000000..0903a0143 --- /dev/null +++ b/hw/bsp/f1c100s/family.cmake @@ -0,0 +1,114 @@ +include_guard() + +set(SDK_DIR ${TOP}/hw/mcu/allwinner/f1c100s) + +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR arm926ej-s CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS F1C100S CACHE INTERNAL "") + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif () + + # LD_FILE and STARTUP_FILE can be defined in board.cmake + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${SDK_DIR}/f1c100s.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${SDK_DIR}/machine/start.S) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/lib/malloc.c + ${SDK_DIR}/lib/printf.c + ${SDK_DIR}/lib/memcpy.S + ${SDK_DIR}/lib/memset.S + ${SDK_DIR}/machine/sys-uart.c + ${SDK_DIR}/machine/exception.c + ${SDK_DIR}/machine/sys-clock.c + ${SDK_DIR}/machine/sys-copyself.c + ${SDK_DIR}/machine/sys-dram.c + ${SDK_DIR}/machine/sys-mmu.c + ${SDK_DIR}/machine/sys-spi-flash.c + ${SDK_DIR}/machine/f1c100s-intc.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + + target_compile_definitions(${BOARD_TARGET} PUBLIC + __ARM32_ARCH__=5 + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR}/include + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -lgcc + --specs=nosys.specs --specs=nano.specs + "LINKER:--defsym=__bss_end__=__bss_end" + "LINKER:--defsym=__bss_start__=__bss_start" + "LINKER:--defsym=end=__bss_end" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_F1C100S ${RTOS}) + target_sources(${TARGET}-tinyusb PRIVATE + ${TOP}/src/portable/sunxi/dcd_sunxi_musb.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_flash_jlink(${TARGET}) +endfunction() diff --git a/hw/bsp/f1c100s/family.mk b/hw/bsp/f1c100s/family.mk new file mode 100644 index 000000000..be416e72e --- /dev/null +++ b/hw/bsp/f1c100s/family.mk @@ -0,0 +1,58 @@ +SDK_DIR = hw/mcu/allwinner/f1c100s + +include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= arm926ej-s + +#CFLAGS += \ +# -march=armv5te \ +# -mtune=arm926ej-s \ +# -mfloat-abi=soft \ +# -marm \ + +CFLAGS += \ + -ffreestanding \ + -std=gnu99 \ + -mno-thumb-interwork \ + -D__ARM32_ARCH__=5 \ + -D__ARM926EJS__ \ + -Wno-float-equal \ + -Wno-unused-parameter \ + -DCFG_TUSB_MCU=OPT_MCU_F1C100S \ + -Wno-error=array-bounds \ + +LD_FILE = ${SDK_DIR}/f1c100s.ld + +# TODO may skip nanolib +LDFLAGS += \ + -nostdlib -lgcc \ + --specs=nosys.specs --specs=nano.specs \ + +SRC_C += \ + src/portable/sunxi/dcd_sunxi_musb.c \ + ${SDK_DIR}/machine/sys-uart.c \ + ${SDK_DIR}/machine/exception.c \ + ${SDK_DIR}/machine/sys-clock.c \ + ${SDK_DIR}/machine/sys-copyself.c \ + ${SDK_DIR}/machine/sys-dram.c \ + ${SDK_DIR}/machine/sys-mmu.c \ + ${SDK_DIR}/machine/sys-spi-flash.c \ + ${SDK_DIR}/machine/f1c100s-intc.c \ + ${SDK_DIR}/lib/malloc.c \ + ${SDK_DIR}/lib/printf.c + +SRC_S += \ + ${SDK_DIR}/machine/start.S \ + ${SDK_DIR}/lib/memcpy.S \ + ${SDK_DIR}/lib/memset.S + +INC += \ + $(TOP)/${SDK_DIR}/include \ + $(TOP)/$(BOARD_PATH) + +# flash target using xfel +flash: flash-xfel + +exec: $(BUILD)/$(PROJECT).bin + xfel ddr + xfel write 0x80000000 $< + xfel exec 0x80000000 diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index 6cc1975a8..6f36ad441 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -35,7 +35,9 @@ #include #include #include "musb_def.h" -#include "bsp/board.h" + +//#include "bsp/board_api.h" +extern uint32_t board_millis(void); // TODO remove typedef uint32_t u32; typedef uint16_t u16; @@ -58,7 +60,7 @@ typedef struct TU_ATTR_PACKED typedef struct { - tusb_control_request_t setup_packet; + CFG_TUD_MEM_ALIGN tusb_control_request_t setup_packet; uint16_t remaining_ctrl; /* The number of bytes remaining in data stage of control transfer. */ int8_t status_out; pipe_state_t pipe0; @@ -350,7 +352,7 @@ static void USBC_INT_DisableRxEp(u8 ep_index) * INTERNAL FUNCTION DECLARATION *------------------------------------------------------------------*/ -static dcd_data_t _dcd; +CFG_TUD_MEM_ALIGN static dcd_data_t _dcd; static inline free_block_t *find_containing_block(free_block_t *beg, free_block_t *end, uint_fast16_t addr) { @@ -560,7 +562,7 @@ static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigne static void process_setup_packet(uint8_t rhport) { - uint32_t *p = (uint32_t*)&_dcd.setup_packet; + uint32_t *p = (uint32_t*)(uintptr_t) &_dcd.setup_packet; p[0] = USBC_Readl(USBC_REG_EPFIFO0(USBC0_BASE)); p[1] = USBC_Readl(USBC_REG_EPFIFO0(USBC0_BASE)); @@ -594,7 +596,7 @@ static bool handle_xfer_in(uint_fast8_t ep_addr) 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)) { - pipe_read_write_packet_ff((tu_fifo_t *)buf, addr, len, TUSB_DIR_IN); + pipe_read_write_packet_ff((tu_fifo_t *)(uintptr_t) buf, addr, len, TUSB_DIR_IN); } else { pipe_write_packet(buf, addr, len); pipe->buf = buf + len; @@ -622,7 +624,7 @@ static bool handle_xfer_out(uint_fast8_t ep_addr) if (len) { volatile void* addr = (volatile void*)(USBC_REG_EPFIFO1(USBC0_BASE) + (epnum_minus1 << 2)); if (_dcd.pipe_buf_is_fifo[TUSB_DIR_OUT] & TU_BIT(epnum_minus1)) { - pipe_read_write_packet_ff((tu_fifo_t *)buf, addr, len, TUSB_DIR_OUT); + pipe_read_write_packet_ff((tu_fifo_t *)(uintptr_t )buf, addr, len, TUSB_DIR_OUT); } else { pipe_read_packet(buf, addr, len); pipe->buf = buf + len; -- cgit v1.3.1 From 02ec4866105eca3f95e7392e538caf97ebb902b4 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sun, 5 May 2024 22:01:09 +0200 Subject: Fix spurious EP0 completion. --- src/portable/synopsys/dwc2/dcd_dwc2.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index c4b1956ce..8c3a6ec61 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1081,22 +1081,26 @@ static void handle_epout_irq(uint8_t rhport) { } else if (doepint & DOEPINT_OTEPSPR) { epout->doepint = DOEPINT_OTEPSPR; } else { - // EP0 can only handle one packet - if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { - // Schedule another packet to be received. - edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { + epout->doepint = DOEPINT_STPKTRX; } else { - if(dma_enabled(rhport)) { - // Fix packet length - uint16_t remain = (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos; - xfer->total_len -= remain; - // this is ZLP, so prepare EP0 for next setup - if(n == 0 && xfer->total_len == 0) { - dma_stpkt_rx(rhport); + // EP0 can only handle one packet + if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { + // Schedule another packet to be received. + edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + } else { + if(dma_enabled(rhport)) { + // Fix packet length + uint16_t remain = (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos; + xfer->total_len -= remain; + // this is ZLP, so prepare EP0 for next setup + if(n == 0 && xfer->total_len == 0) { + dma_stpkt_rx(rhport); + } } - } - dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); + dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); + } } } } -- cgit v1.3.1 From 82547372d1a83f03d137a20f71b2d60a5702a75a Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Mon, 6 May 2024 08:42:08 +0200 Subject: edpt_dma_start() is called during interrupt time as well, dcd_edpt_xfer() needs DI/EI at one point --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src/portable') diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 2fe721d6b..805eb1dda 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -77,6 +77,18 @@ #endif #endif +/** disable interrupts */ +#define DISABLE_IRQ() \ + uint32_t prim = __get_PRIMASK(); \ + __disable_irq(); + +/** (re)enable interrupts */ +#define ENABLE_IRQ() \ + if (!prim) \ + { \ + __enable_irq(); \ + } + /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ @@ -147,7 +159,7 @@ static void start_dma(volatile uint32_t* reg_startep) { static void edpt_dma_start(volatile uint32_t* reg_startep) { if (atomic_flag_test_and_set(&_dcd.dma_running)) { - usbd_defer_func((osal_task_func_t)(uintptr_t ) edpt_dma_start, (void*) (uintptr_t) reg_startep, true); + usbd_defer_func((osal_task_func_t)(uintptr_t ) edpt_dma_start, (void*) (uintptr_t) reg_startep, is_in_isr()); } else { start_dma(reg_startep); } @@ -434,11 +446,15 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to bool const control_status = (epnum == 0 && total_bytes == 0 && dir != tu_edpt_dir(NRF_USBD->BMREQUESTTYPE)); if (control_status) { + DISABLE_IRQ(); + // Status Phase also requires EasyDMA has to be available as well !!!! edpt_dma_start(&NRF_USBD->TASKS_EP0STATUS); // The nRF doesn't interrupt on status transmit so we queue up a success response. dcd_event_xfer_complete(0, ep_addr, 0, XFER_RESULT_SUCCESS, is_in_isr()); + + ENABLE_IRQ(); } else if (dir == TUSB_DIR_OUT) { xfer->started = true; if (epnum == 0) { -- cgit v1.3.1 From a9f1c62dffc2cb0229767959173f78eec9931db0 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 6 May 2024 17:28:48 +0700 Subject: temp fix for mm32 redundant-decls of SystemCoreClock --- hw/bsp/mm32/family.c | 24 ++++++++++++++++-------- src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c | 11 +++++++++++ 2 files changed, 27 insertions(+), 8 deletions(-) (limited to 'src/portable') diff --git a/hw/bsp/mm32/family.c b/hw/bsp/mm32/family.c index f22fd90a1..f0fd6d334 100644 --- a/hw/bsp/mm32/family.c +++ b/hw/bsp/mm32/family.c @@ -30,6 +30,21 @@ #include "bsp/board_api.h" #include "board.h" +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM DECLARATION +//--------------------------------------------------------------------+ + +#ifdef __GNUC__ // caused by extra declaration of SystemCoreClock in freeRTOSConfig.h +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wredundant-decls" +#endif + +extern u32 SystemCoreClock; + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ @@ -46,19 +61,12 @@ void USB_DeviceClockInit(void) { /* Enable USB clock */ RCC->AHB2ENR |= 0x1 << 7; } -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM DECLARATION -//--------------------------------------------------------------------+ - -extern u32 SystemCoreClock; void board_init(void) { // usb clock USB_DeviceClockInit(); - if (SysTick_Config(SystemCoreClock / 1000)) { - while (1); - } + SysTick_Config(SystemCoreClock / 1000); NVIC_SetPriority(SysTick_IRQn, 0x0); RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOA, ENABLE); diff --git a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c index c3d0c7297..d5c0daaeb 100644 --- a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c +++ b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c @@ -283,7 +283,18 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) /* Response with status first before changing device address */ dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); } + +#ifdef __GNUC__ // caused by extra declaration of SystemCoreClock in freeRTOSConfig.h +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wredundant-decls" +#endif + extern u32 SystemCoreClock; + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + void dcd_remote_wakeup(uint8_t rhport) { (void) rhport; -- cgit v1.3.1 From 1cab553f4bcb6633face4f50f03192928a68f751 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 9 May 2024 13:55:18 +0200 Subject: Format. --- src/portable/wch/dcd_ch32_usbhs.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src/portable') diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c index 41c1d8c7c..68e2179e9 100644 --- a/src/portable/wch/dcd_ch32_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -135,15 +135,12 @@ void dcd_remote_wakeup(uint8_t rhport) (void) rhport; } -void dcd_sof_enable(uint8_t rhport, bool en) +void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; - if (en) - { + if (en) { USBHSD->INT_EN |= USBHS_SOF_ACT_EN; - } - else - { + } else { USBHSD->INT_EN &= ~(USBHS_SOF_ACT_EN); } } @@ -347,6 +344,7 @@ void dcd_int_handler(uint8_t rhport) { if (rx_token == PID_SOF) { dcd_event_sof(rhport, USBHSD->FRAME_NO, true); + } else if (rx_token == PID_OUT) { uint16_t rx_len = USBHSD->RX_LEN; -- cgit v1.3.1 From 9d561410e58ba9efb6ef2bff7b03a2f47dee8d64 Mon Sep 17 00:00:00 2001 From: Hardy Griech Date: Mon, 13 May 2024 18:57:03 +0200 Subject: revert (unverified) second race condition --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'src/portable') diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 805eb1dda..bb07063d2 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -77,18 +77,6 @@ #endif #endif -/** disable interrupts */ -#define DISABLE_IRQ() \ - uint32_t prim = __get_PRIMASK(); \ - __disable_irq(); - -/** (re)enable interrupts */ -#define ENABLE_IRQ() \ - if (!prim) \ - { \ - __enable_irq(); \ - } - /*------------------------------------------------------------------*/ /* MACRO TYPEDEF CONSTANT ENUM *------------------------------------------------------------------*/ @@ -446,15 +434,11 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to bool const control_status = (epnum == 0 && total_bytes == 0 && dir != tu_edpt_dir(NRF_USBD->BMREQUESTTYPE)); if (control_status) { - DISABLE_IRQ(); - // Status Phase also requires EasyDMA has to be available as well !!!! edpt_dma_start(&NRF_USBD->TASKS_EP0STATUS); // The nRF doesn't interrupt on status transmit so we queue up a success response. dcd_event_xfer_complete(0, ep_addr, 0, XFER_RESULT_SUCCESS, is_in_isr()); - - ENABLE_IRQ(); } else if (dir == TUSB_DIR_OUT) { xfer->started = true; if (epnum == 0) { -- cgit v1.3.1 From e250b82377aa9c1433c6235501c72dd079544c75 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 13 May 2024 22:26:19 +0200 Subject: Adjust logic. --- src/common/tusb_mcu.h | 5 +++-- src/device/dcd.h | 6 +++--- src/device/usbd.c | 20 +++++++++++--------- src/portable/synopsys/dwc2/dcd_dwc2.c | 4 ++-- src/tusb_option.h | 5 +++++ 5 files changed, 24 insertions(+), 16 deletions(-) (limited to 'src/portable') diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index e489e93e7..3a7d6ad33 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -195,6 +195,7 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32F4) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 + #define TUP_USBIP_DWC2_TEST_MODE // For most mcu, FS has 4, HS has 6. TODO 446/469/479 HS has 9 #define TUP_DCD_ENDPOINT_MAX 6 @@ -209,7 +210,7 @@ // MCU with on-chip HS Phy #if defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F733xx) #define TUP_RHPORT_HIGHSPEED 1 // Port0: FS, Port1: HS - #define TUP_USBIP_DWC2_TEST_MODE_SUPPORT + #define TUP_USBIP_DWC2_TEST_MODE #endif #elif TU_CHECK_MCU(OPT_MCU_STM32H7) @@ -278,7 +279,7 @@ defined(STM32U5F7xx) || defined(STM32U5F9xx) || defined(STM32U5G7xx) || defined(STM32U5G9xx) #define TUP_DCD_ENDPOINT_MAX 9 #define TUP_RHPORT_HIGHSPEED 1 - #define TUP_USBIP_DWC2_TEST_MODE_SUPPORT + #define TUP_USBIP_DWC2_TEST_MODE #else #define TUP_DCD_ENDPOINT_MAX 6 #endif diff --git a/src/device/dcd.h b/src/device/dcd.h index b71b99869..9447d6d9d 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -97,8 +97,7 @@ typedef struct TU_ATTR_ALIGNED(4) { }; } dcd_event_t; -typedef enum _test_mode_selector -{ +typedef enum { TEST_J = 1, TEST_K, TEST_SE0_NAK, @@ -158,12 +157,13 @@ void dcd_disconnect(uint8_t rhport) TU_ATTR_WEAK; // Enable/Disable Start-of-frame interrupt. Default is disabled void dcd_sof_enable(uint8_t rhport, bool en); +#if CFG_TUD_TEST_MODE // Check if the test mode is supported, returns true is test mode selector is supported bool dcd_check_test_mode_support(test_mode_t test_selector) TU_ATTR_WEAK; // Put device into a test mode (needs power cycle to quit) void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) TU_ATTR_WEAK; - +#endif //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ diff --git a/src/device/usbd.c b/src/device/usbd.c index 7dfdc8476..25d890dc7 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -313,8 +313,9 @@ TU_ATTR_ALWAYS_INLINE static inline bool queue_event(dcd_event_t const * event, static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request); static bool process_set_config(uint8_t rhport, uint8_t cfg_num); static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const * p_request); +#if CFG_TUD_TEST_MODE static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); - +#endif // from usbd_control.c void usbd_control_reset(void); void usbd_control_set_request(tusb_control_request_t const *request); @@ -766,16 +767,16 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const tud_control_status(rhport, p_request); break; - #if !defined(TUSB_NO_TEST_MODE_SUPPORT) +#if CFG_TUD_TEST_MODE // Support for TEST_MODE - case TUSB_REQ_FEATURE_TEST_MODE: + case TUSB_REQ_FEATURE_TEST_MODE: { // Only handle the test mode if supported and valid TU_VERIFY(dcd_enter_test_mode && dcd_check_test_mode_support && 0 == tu_u16_low(p_request->wIndex)); uint8_t selector = tu_u16_high(p_request->wIndex); // Stall request if the selected test mode isn't supported - if (!dcd_check_test_mode_support(selector)) + if (!dcd_check_test_mode_support((test_mode_t)selector)) { TU_LOG_USBD(" Unsupported Test Mode (test selector index: %d)\r\n", selector); @@ -788,8 +789,9 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const TU_LOG_USBD(" Enter Test Mode (test selector index: %d)\r\n", selector); usbd_control_set_complete_callback(process_test_mode_cb); - break; - #endif /* !TUSB_NO_TEST_MODE_SUPPORT */ + break; + } +#endif /* CFG_TUD_TEST_MODE */ // Stall unsupported feature selector default: return false; @@ -1121,7 +1123,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const } } -#if !defined(TUSB_NO_TEST_MODE_SUPPORT) +#if CFG_TUD_TEST_MODE static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) { // At this point it should already be ensured that dcd_enter_test_mode() is defined @@ -1129,11 +1131,11 @@ static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_req // Only enter the test mode after the request for it has completed TU_VERIFY(CONTROL_STAGE_ACK == stage); - dcd_enter_test_mode(rhport, tu_u16_high(request->wIndex)); + dcd_enter_test_mode(rhport, (test_mode_t)tu_u16_high(request->wIndex)); return true; } -#endif /* !TUSB_NO_TEST_MODE_SUPPORT */ +#endif /* CFG_TUD_TEST_MODE */ //--------------------------------------------------------------------+ // DCD Event Handler diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index c9580655f..fd2f08453 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1195,7 +1195,7 @@ void dcd_int_handler(uint8_t rhport) { // } } -#if defined(TUP_USBIP_DWC2_TEST_MODE_SUPPORT) && !defined(TUSB_NO_TEST_MODE_SUPPORT) +#if defined(TUP_USBIP_DWC2_TEST_MODE) && CFG_TUD_TEST_MODE bool dcd_check_test_mode_support(test_mode_t test_selector) { // Check if test mode selector is unsupported @@ -1218,6 +1218,6 @@ void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) { dwc2->dctl = (dwc2->dctl & ~DCTL_TCTL_Msk) | (test_selector << DCTL_TCTL_Pos); } -#endif /* TUP_USBIP_DWC2_TEST_MODE_SUPPORT && !TUSB_NO_TEST_MODE_SUPPORT */ +#endif /* TUP_USBIP_DWC2_TEST_MODE && CFG_TUD_TEST_MODE */ #endif diff --git a/src/tusb_option.h b/src/tusb_option.h index 8d5527936..058427e0e 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -364,6 +364,11 @@ #define CFG_TUD_INTERFACE_MAX 16 #endif +// USB 2.0 compliance test mode support +#ifndef CFG_TUD_TEST_MODE + #define CFG_TUD_TEST_MODE 0 +#endif + //------------- Device Class Driver -------------// #ifndef CFG_TUD_BTH #define CFG_TUD_BTH 0 -- cgit v1.3.1 From ad734e658cc9e39021a93fc21e077f1b1709c0ff Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 13 May 2024 22:27:33 +0200 Subject: Remove dead code. --- src/portable/synopsys/dwc2/dcd_dwc2.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index fd2f08453..dbcd586c5 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1207,10 +1207,6 @@ bool dcd_check_test_mode_support(test_mode_t test_selector) { } void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) { - // Disable test mode if not supported as a fall back - if (!dcd_check_test_mode_support(test_selector)) { - test_selector = 0; - } // Get port address... dwc2_regs_t* dwc2 = DWC2_REG(rhport); -- cgit v1.3.1 From aa2685536ba9e2fbbe3f350a5bb3c6709e586722 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 15 May 2024 16:00:15 +0700 Subject: implement max3421e hcd_edpt_abort_xfer() --- hw/bsp/nrf/family.cmake | 10 ++++ src/portable/analog/max3421/hcd_max3421.c | 80 +++++++++++++++++-------------- 2 files changed, 54 insertions(+), 36 deletions(-) (limited to 'src/portable') diff --git a/hw/bsp/nrf/family.cmake b/hw/bsp/nrf/family.cmake index 5de69a8a3..9e86374dc 100644 --- a/hw/bsp/nrf/family.cmake +++ b/hw/bsp/nrf/family.cmake @@ -101,6 +101,15 @@ endfunction() #------------------------------------ # Functions #------------------------------------ + +#function(family_flash_adafruit_nrfutil TARGET) +# add_custom_target(${TARGET}-adafruit-nrfutil +# DEPENDS ${TARGET} +# COMMAND adafruit-nrfutil --verbose dfu serial --package $^ -p /dev/ttyACM0 -b 115200 --singlebank --touch 1200 +# ) +#endfunction() + + function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) @@ -133,4 +142,5 @@ function(family_configure_example TARGET RTOS) # Flashing family_flash_jlink(${TARGET}) +# family_flash_adafruit_nrfutil(${TARGET}) endfunction() diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 4dc93d2d8..d9b8e1fc3 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -174,7 +174,8 @@ enum { enum { EP_STATE_IDLE = 0, EP_STATE_COMPLETE = 1, - EP_STATE_ATTEMPT_1 = 2, // pending 1st attempt + EP_STATE_ABORTING = 2, + EP_STATE_ATTEMPT_1 = 3, // pending 1st attempt EP_STATE_ATTEMPT_MAX = 15 }; @@ -459,6 +460,7 @@ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { tuh_configure_param_t const* cfg = (tuh_configure_param_t const*) cfg_param; _tuh_cfg = cfg->max3421; + _tuh_cfg.max_nak = tu_min8(_tuh_cfg.max_nak, EP_STATE_ATTEMPT_MAX-EP_STATE_ATTEMPT_1); return true; } @@ -678,7 +680,6 @@ static void xact_generic(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen) { uint8_t const ep_num = tu_edpt_number(ep_addr); uint8_t const ep_dir = (uint8_t) tu_edpt_dir(ep_addr); - max3421_ep_t* ep = find_opened_ep(daddr, ep_num, ep_dir); TU_VERIFY(ep); @@ -702,14 +703,19 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr, uint8_t * buf return true; } -// 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) { - (void) rhport; - (void) dev_addr; - (void) ep_addr; +bool hcd_edpt_abort_xfer(uint8_t rhport, uint8_t daddr, uint8_t ep_addr) { + uint8_t const ep_num = tu_edpt_number(ep_addr); + uint8_t const ep_dir = (uint8_t) tu_edpt_dir(ep_addr); + max3421_ep_t* ep = find_opened_ep(daddr, ep_num, ep_dir); + TU_VERIFY(ep); - return false; + if (EP_STATE_ATTEMPT_1 <= ep->state && ep->state < EP_STATE_ATTEMPT_MAX) { + hcd_int_disable(rhport); + ep->state = EP_STATE_ABORTING; + hcd_int_enable(rhport); + } + + return true; } // Submit a special transfer to send 8-byte Setup Packet, when complete hcd_event_xfer_complete() must be invoked @@ -819,7 +825,6 @@ static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t re static void handle_xfer_done(uint8_t rhport, bool in_isr) { uint8_t const hrsl = reg_read(rhport, HRSL_ADDR, in_isr); uint8_t const hresult = hrsl & HRSL_RESULT_MASK; - uint8_t const ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK; uint8_t const hxfr_type = _hcd_data.hxfr & 0xf0; uint8_t const ep_dir = ((hxfr_type & HXFR_SETUP) || (hxfr_type & HXFR_OUT_NIN)) ? 0 : 1; @@ -829,34 +834,30 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { xfer_result_t xfer_result; switch(hresult) { - case HRSL_SUCCESS: - xfer_result = XFER_RESULT_SUCCESS; - break; - - case HRSL_STALL: - xfer_result = XFER_RESULT_STALLED; - break; - case HRSL_NAK: - if (ep_num == 0) { - // control endpoint -> retry immediately - hxfr_write(rhport, _hcd_data.hxfr, in_isr); + if (ep->state == EP_STATE_ABORTING) { + ep->state = EP_STATE_IDLE; } else { - if (ep->state < EP_STATE_ATTEMPT_MAX) { + if (ep_num == 0) { + // control endpoint -> retry immediately and return + hxfr_write(rhport, _hcd_data.hxfr, in_isr); + return; + } else if (EP_STATE_ATTEMPT_1 <= ep->state && ep->state < EP_STATE_ATTEMPT_MAX) { ep->state++; } + } - max3421_ep_t * next_ep = find_next_pending_ep(ep); - if (ep == next_ep) { - // this endpoint is only one pending -> retry immediately - hxfr_write(rhport, _hcd_data.hxfr, in_isr); - } else if (next_ep) { - // switch to next pending endpoint TODO could have issue with double buffered if not clear previously out data - xact_generic(rhport, next_ep, true, in_isr); - } else { - // no more pending in this frame -> clear busy - atomic_flag_clear(&_hcd_data.busy); - } + max3421_ep_t * next_ep = find_next_pending_ep(ep); + if (ep == next_ep) { + // this endpoint is only one pending -> retry immediately + hxfr_write(rhport, _hcd_data.hxfr, in_isr); + } else if (next_ep) { + // switch to next pending endpoint + // TODO could have issue with double buffered if not clear previously out data + xact_generic(rhport, next_ep, true, in_isr); + } else { + // no more pending in this frame -> clear busy + atomic_flag_clear(&_hcd_data.busy); } return; @@ -864,6 +865,14 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { // occurred when initialized without any pending transfer. Skip for now return; + case HRSL_SUCCESS: + xfer_result = XFER_RESULT_SUCCESS; + break; + + case HRSL_STALL: + xfer_result = XFER_RESULT_STALLED; + break; + default: TU_LOG3("HRSL: %02X\r\n", hrsl); xfer_result = XFER_RESULT_FAILED; @@ -942,9 +951,8 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { if (hirq & HIRQ_FRAME_IRQ) { _hcd_data.frame_count++; + // reset all endpoints nak counter, retry with 1st pending ep. max3421_ep_t* ep_retry = NULL; - - // reset all endpoints attempt counter for (size_t i = 0; i < CFG_TUH_MAX3421_ENDPOINT_TOTAL; i++) { max3421_ep_t* ep = &_hcd_data.ep[i]; if (ep->packet_size && ep->state > EP_STATE_ATTEMPT_1) { @@ -1004,7 +1012,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { // clear all interrupt except SNDBAV_IRQ (never clear by us). Note RCVDAV_IRQ, HXFRDN_IRQ already clear while processing hirq &= (uint8_t) ~HIRQ_SNDBAV_IRQ; - if ( hirq ) { + if (hirq) { hirq_write(rhport, hirq, in_isr); } } -- cgit v1.3.1 From db60fa1c63ae58c205e43e144253dab6815bb2d1 Mon Sep 17 00:00:00 2001 From: Matthew Tran Date: Sun, 19 Nov 2023 18:26:40 -0800 Subject: add CH32V20x USB OTG/FS driver --- .gitignore | 1 + README.rst | 2 +- docs/reference/dependencies.rst | 1 + docs/reference/supported.rst | 6 +- examples/device/cdc_msc_freertos/skip.txt | 1 + examples/device/hid_composite_freertos/skip.txt | 1 + examples/device/msc_dual_lun/skip.txt | 1 + examples/device/video_capture/skip.txt | 1 + hw/bsp/ch32v20x/boards/nanoch32v203/board.h | 17 + hw/bsp/ch32v20x/boards/nanoch32v203/board.mk | 5 + hw/bsp/ch32v20x/ch32v20x_conf.h | 36 + hw/bsp/ch32v20x/ch32v20x_it.h | 15 + hw/bsp/ch32v20x/core_riscv.h | 572 ++++++++++++++ hw/bsp/ch32v20x/family.c | 82 ++ hw/bsp/ch32v20x/family.mk | 50 ++ hw/bsp/ch32v20x/system_ch32v20x.c | 976 ++++++++++++++++++++++++ hw/bsp/ch32v20x/system_ch32v20x.h | 29 + hw/bsp/ch32v20x/wch-riscv.cfg | 18 + hw/bsp/ch32v307/family.mk | 5 + hw/bsp/fomu/family.mk | 4 + hw/bsp/gd32vf103/family.mk | 5 + src/class/video/video_device.c | 2 +- src/common/tusb_mcu.h | 4 + src/portable/wch/ch32_usbfs_reg.h | 77 ++ src/portable/wch/dcd_ch32_usbfs.c | 304 ++++++++ src/tusb_option.h | 1 + tools/get_deps.py | 3 + tools/iar_template.ipcf | 1 + 28 files changed, 2215 insertions(+), 5 deletions(-) create mode 100644 hw/bsp/ch32v20x/boards/nanoch32v203/board.h create mode 100644 hw/bsp/ch32v20x/boards/nanoch32v203/board.mk create mode 100644 hw/bsp/ch32v20x/ch32v20x_conf.h create mode 100644 hw/bsp/ch32v20x/ch32v20x_it.h create mode 100644 hw/bsp/ch32v20x/core_riscv.h create mode 100644 hw/bsp/ch32v20x/family.c create mode 100644 hw/bsp/ch32v20x/family.mk create mode 100644 hw/bsp/ch32v20x/system_ch32v20x.c create mode 100644 hw/bsp/ch32v20x/system_ch32v20x.h create mode 100644 hw/bsp/ch32v20x/wch-riscv.cfg create mode 100644 src/portable/wch/ch32_usbfs_reg.h create mode 100644 src/portable/wch/dcd_ch32_usbfs.c (limited to 'src/portable') diff --git a/.gitignore b/.gitignore index 56ae7600f..7a37d65dc 100644 --- a/.gitignore +++ b/.gitignore @@ -82,6 +82,7 @@ hw/mcu/st/stm32l5xx_hal_driver hw/mcu/st/stm32u5xx_hal_driver hw/mcu/st/stm32wbxx_hal_driver hw/mcu/ti +hw/mcu/wch/ch32v20x hw/mcu/wch/ch32v307 hw/mcu/wch/ch32f20x lib/CMSIS_5 diff --git a/README.rst b/README.rst index 8c3145d33..dbe75adc8 100644 --- a/README.rst +++ b/README.rst @@ -157,7 +157,7 @@ Following CPUs are supported, check out `Supported Devices`_ for comprehensive l +--------------+------------------------------------------------------------+ | ValentyUSB | eptri | +--------------+------------------------------------------------------------+ -| WCH | CH32F20x, CH32V307, | +| WCH | CH32F20x, CH32V20x, CH32V307 | +--------------+------------------------------------------------------------+ License diff --git a/docs/reference/dependencies.rst b/docs/reference/dependencies.rst index 6ba6692e9..3a98594ff 100644 --- a/docs/reference/dependencies.rst +++ b/docs/reference/dependencies.rst @@ -55,6 +55,7 @@ hw/mcu/st/stm32u5xx_hal_driver https://github.com/STMicroelectronics/ hw/mcu/st/stm32wbxx_hal_driver https://github.com/STMicroelectronics/stm32wbxx_hal_driver.git 2c5f06638be516c1b772f768456ba637f077bac8 stm32wb hw/mcu/ti https://github.com/hathach/ti_driver.git 143ed6cc20a7615d042b03b21e070197d473e6e5 msp430 msp432e4 tm4c123 hw/mcu/wch/ch32f20x https://github.com/openwch/ch32f20x.git 77c4095087e5ed2c548ec9058e655d0b8757663b ch32f20x +hw/mcu/wch/ch32v20x https://github.com/openwch/ch32v20x.git de6d68c654340d7f27b00cebbfc9aa2740a1abc2 ch32v20x hw/mcu/wch/ch32v307 https://github.com/openwch/ch32v307.git 17761f5cf9dbbf2dcf665b7c04934188add20082 ch32v307 lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 20285262657d1b482d132d20d755c8c330d55c1f imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf ra saml2xstm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h7 stm32l0 stm32l1 stm32l4 stm32l5 stm32u5 stm32wb lib/FreeRTOS-Kernel https://github.com/FreeRTOS/FreeRTOS-Kernel.git 4ff01a7a4a51f53b44496aefee1e3c0071b7b173 all diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index 7e7be25a4..3ca203e88 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -128,9 +128,9 @@ Supported MCUs +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ | ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ -| WCH | CH32V307 | ✔ | | ✔ | ch32v307 | | -| +-----------------------+--------+------+-----------+-------------------+--------------+ -| | CH32F20x | ✔ | | ✔ | ch32f205 | | +| WCH | CH32F20x | ✔ | | ✔ | ch32f205 | | +| | CH32V20x | ✔ | | ✖ | ch32v20x | | +| | CH32V307 | ✔ | | ✔ | ch32v307 | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ diff --git a/examples/device/cdc_msc_freertos/skip.txt b/examples/device/cdc_msc_freertos/skip.txt index eb434c23b..457ddb760 100644 --- a/examples/device/cdc_msc_freertos/skip.txt +++ b/examples/device/cdc_msc_freertos/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V20X mcu:CH32V307 mcu:CXD56 mcu:F1C100S diff --git a/examples/device/hid_composite_freertos/skip.txt b/examples/device/hid_composite_freertos/skip.txt index a6f96b288..6aaa27661 100644 --- a/examples/device/hid_composite_freertos/skip.txt +++ b/examples/device/hid_composite_freertos/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V20X mcu:CH32V307 mcu:CXD56 mcu:F1C100S diff --git a/examples/device/msc_dual_lun/skip.txt b/examples/device/msc_dual_lun/skip.txt index a9e3a99b1..4d607dc05 100644 --- a/examples/device/msc_dual_lun/skip.txt +++ b/examples/device/msc_dual_lun/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V20X mcu:SAMD11 mcu:MKL25ZXX family:espressif diff --git a/examples/device/video_capture/skip.txt b/examples/device/video_capture/skip.txt index 5898664a2..714cabeec 100644 --- a/examples/device/video_capture/skip.txt +++ b/examples/device/video_capture/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V20X mcu:MSP430x5xx mcu:NUC121 mcu:SAMD11 diff --git a/hw/bsp/ch32v20x/boards/nanoch32v203/board.h b/hw/bsp/ch32v20x/boards/nanoch32v203/board.h new file mode 100644 index 000000000..c8d28d90f --- /dev/null +++ b/hw/bsp/ch32v20x/boards/nanoch32v203/board.h @@ -0,0 +1,17 @@ +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define LED_PORT GPIOA +#define LED_PIN GPIO_Pin_15 +#define LED_STATE_ON 0 +#define LED_CLOCK_EN() RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hw/bsp/ch32v20x/boards/nanoch32v203/board.mk b/hw/bsp/ch32v20x/boards/nanoch32v203/board.mk new file mode 100644 index 000000000..75dc05457 --- /dev/null +++ b/hw/bsp/ch32v20x/boards/nanoch32v203/board.mk @@ -0,0 +1,5 @@ +CFLAGS += \ + -DCH32V20x_D6 + +SRC_S += \ + $(CH32V20X_SDK_SRC)/Startup/startup_ch32v20x_D6.S diff --git a/hw/bsp/ch32v20x/ch32v20x_conf.h b/hw/bsp/ch32v20x/ch32v20x_conf.h new file mode 100644 index 000000000..949297fe6 --- /dev/null +++ b/hw/bsp/ch32v20x/ch32v20x_conf.h @@ -0,0 +1,36 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : ch32v20x_conf.h + * Author : WCH + * Version : V1.0.0 + * Date : 2021/06/06 + * Description : Library configuration file. +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef __CH32V20x_CONF_H +#define __CH32V20x_CONF_H + +#include "ch32v20x_adc.h" +#include "ch32v20x_bkp.h" +#include "ch32v20x_can.h" +#include "ch32v20x_crc.h" +#include "ch32v20x_dbgmcu.h" +#include "ch32v20x_dma.h" +#include "ch32v20x_exti.h" +#include "ch32v20x_flash.h" +#include "ch32v20x_gpio.h" +#include "ch32v20x_i2c.h" +#include "ch32v20x_iwdg.h" +#include "ch32v20x_pwr.h" +#include "ch32v20x_rcc.h" +#include "ch32v20x_rtc.h" +#include "ch32v20x_spi.h" +#include "ch32v20x_tim.h" +#include "ch32v20x_usart.h" +#include "ch32v20x_wwdg.h" +#include "ch32v20x_it.h" +#include "ch32v20x_misc.h" + +#endif /* __CH32V20x_CONF_H */ diff --git a/hw/bsp/ch32v20x/ch32v20x_it.h b/hw/bsp/ch32v20x/ch32v20x_it.h new file mode 100644 index 000000000..e49c61ae2 --- /dev/null +++ b/hw/bsp/ch32v20x/ch32v20x_it.h @@ -0,0 +1,15 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : ch32v20x_it.h + * Author : WCH + * Version : V1.0.0 + * Date : 2021/06/06 + * Description : This file contains the headers of the interrupt handlers. +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef __CH32V20x_IT_H +#define __CH32V20x_IT_H + +#endif /* __CH32V20x_IT_H */ diff --git a/hw/bsp/ch32v20x/core_riscv.h b/hw/bsp/ch32v20x/core_riscv.h new file mode 100644 index 000000000..be1b52a6c --- /dev/null +++ b/hw/bsp/ch32v20x/core_riscv.h @@ -0,0 +1,572 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : core_riscv.h + * Author : WCH + * Version : V1.0.0 + * Date : 2021/06/06 + * Description : RISC-V Core Peripheral Access Layer Header File for CH32V20x +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef __CORE_RISCV_H__ +#define __CORE_RISCV_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* IO definitions */ +#ifdef __cplusplus + #define __I volatile /* defines 'read only' permissions */ +#else + #define __I volatile const /* defines 'read only' permissions */ +#endif +#define __O volatile /* defines 'write only' permissions */ +#define __IO volatile /* defines 'read / write' permissions */ + +/* Standard Peripheral Library old types (maintained for legacy purpose) */ +typedef __I uint64_t vuc64; /* Read Only */ +typedef __I uint32_t vuc32; /* Read Only */ +typedef __I uint16_t vuc16; /* Read Only */ +typedef __I uint8_t vuc8; /* Read Only */ + +typedef const uint64_t uc64; /* Read Only */ +typedef const uint32_t uc32; /* Read Only */ +typedef const uint16_t uc16; /* Read Only */ +typedef const uint8_t uc8; /* Read Only */ + +typedef __I int64_t vsc64; /* Read Only */ +typedef __I int32_t vsc32; /* Read Only */ +typedef __I int16_t vsc16; /* Read Only */ +typedef __I int8_t vsc8; /* Read Only */ + +typedef const int64_t sc64; /* Read Only */ +typedef const int32_t sc32; /* Read Only */ +typedef const int16_t sc16; /* Read Only */ +typedef const int8_t sc8; /* Read Only */ + +typedef __IO uint64_t vu64; +typedef __IO uint32_t vu32; +typedef __IO uint16_t vu16; +typedef __IO uint8_t vu8; + +typedef uint64_t u64; +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; + +typedef __IO int64_t vs64; +typedef __IO int32_t vs32; +typedef __IO int16_t vs16; +typedef __IO int8_t vs8; + +typedef int64_t s64; +typedef int32_t s32; +typedef int16_t s16; +typedef int8_t s8; + +typedef enum {NoREADY = 0, READY = !NoREADY} ErrorStatus; + +typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; + +typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; + +#define RV_STATIC_INLINE static inline + +/* memory mapped structure for Program Fast Interrupt Controller (PFIC) */ +typedef struct{ + __I uint32_t ISR[8]; + __I uint32_t IPR[8]; + __IO uint32_t ITHRESDR; + __IO uint32_t RESERVED; + __IO uint32_t CFGR; + __I uint32_t GISR; + __IO uint8_t VTFIDR[4]; + uint8_t RESERVED0[12]; + __IO uint32_t VTFADDR[4]; + uint8_t RESERVED1[0x90]; + __O uint32_t IENR[8]; + uint8_t RESERVED2[0x60]; + __O uint32_t IRER[8]; + uint8_t RESERVED3[0x60]; + __O uint32_t IPSR[8]; + uint8_t RESERVED4[0x60]; + __O uint32_t IPRR[8]; + uint8_t RESERVED5[0x60]; + __IO uint32_t IACTR[8]; + uint8_t RESERVED6[0xE0]; + __IO uint8_t IPRIOR[256]; + uint8_t RESERVED7[0x810]; + __IO uint32_t SCTLR; +}PFIC_Type; + +/* memory mapped structure for SysTick */ +typedef struct +{ + __IO uint32_t CTLR; + __IO uint32_t SR; + __IO uint64_t CNT; + __IO uint64_t CMP; +}SysTick_Type; + +#define PFIC ((PFIC_Type *) 0xE000E000 ) +#define NVIC PFIC +#define NVIC_KEY1 ((uint32_t)0xFA050000) +#define NVIC_KEY2 ((uint32_t)0xBCAF0000) +#define NVIC_KEY3 ((uint32_t)0xBEEF0000) + +#define SysTick ((SysTick_Type *) 0xE000F000) + +/********************************************************************* + * @fn __enable_irq + * + * @brief Enable Global Interrupt + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __enable_irq(void) +{ + __asm volatile ("csrw 0x800, %0" : : "r" (0x6088) ); +} + +/********************************************************************* + * @fn __disable_irq + * + * @brief Disable Global Interrupt + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __disable_irq(void) +{ + __asm volatile ("csrw 0x800, %0" : : "r" (0x6000) ); +} + +/********************************************************************* + * @fn __NOP + * + * @brief nop + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __NOP(void) +{ + __asm volatile ("nop"); +} + +/********************************************************************* + * @fn NVIC_EnableIRQ + * + * @brief Disable Interrupt + * + * @param IRQn - Interrupt Numbers + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->IENR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + +/********************************************************************* + * @fn NVIC_DisableIRQ + * + * @brief Disable Interrupt + * + * @param IRQn - Interrupt Numbers + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->IRER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + +/********************************************************************* + * @fn NVIC_GetStatusIRQ + * + * @brief Get Interrupt Enable State + * + * @param IRQn - Interrupt Numbers + * + * @return 1 - Interrupt Pending Enable + * 0 - Interrupt Pending Disable + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetStatusIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->ISR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); +} + +/********************************************************************* + * @fn NVIC_GetPendingIRQ + * + * @brief Get Interrupt Pending State + * + * @param IRQn - Interrupt Numbers + * + * @return 1 - Interrupt Pending Enable + * 0 - Interrupt Pending Disable + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->IPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); +} + +/********************************************************************* + * @fn NVIC_SetPendingIRQ + * + * @brief Set Interrupt Pending + * + * @param IRQn - Interrupt Numbers + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->IPSR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + +/********************************************************************* + * @fn NVIC_ClearPendingIRQ + * + * @brief Clear Interrupt Pending + * + * @param IRQn - Interrupt Numbers + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->IPRR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + +/********************************************************************* + * @fn NVIC_GetActive + * + * @brief Get Interrupt Active State + * + * @param IRQn - Interrupt Numbers + * + * @return 1 - Interrupt Active + * 0 - Interrupt No Active + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)((NVIC->IACTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); +} + +/********************************************************************* + * @fn NVIC_SetPriority + * + * @brief Set Interrupt Priority + * + * @param IRQn - Interrupt Numbers + * priority - bit7 - Pre-emption Priority + * bit[6:5] - Subpriority + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint8_t priority) +{ + NVIC->IPRIOR[(uint32_t)(IRQn)] = priority; +} + +/********************************************************************* + * @fn __WFI + * + * @brief Wait for Interrupt + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFI(void) +{ + NVIC->SCTLR &= ~(1<<3); // wfi + asm volatile ("wfi"); +} + +/********************************************************************* + * @fn _SEV + * + * @brief Set Event + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void _SEV(void) +{ + uint32_t t; + + t = NVIC->SCTLR; + NVIC->SCTLR |= (1<<3)|(1<<5); + NVIC->SCTLR = (NVIC->SCTLR & ~(1<<5)) | ( t & (1<<5)); +} + +/********************************************************************* + * @fn _WFE + * + * @brief Wait for Events + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void _WFE(void) +{ + NVIC->SCTLR |= (1<<3); + asm volatile ("wfi"); +} + +/********************************************************************* + * @fn __WFE + * + * @brief Wait for Events + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFE(void) +{ + _SEV(); + _WFE(); + _WFE(); +} + +/********************************************************************* + * @fn SetVTFIRQ + * + * @brief Set VTF Interrupt + * + * @param addr - VTF interrupt service function base address. + * IRQn - Interrupt Numbers + * num - VTF Interrupt Numbers + * NewState - DISABLE or ENABLE + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void SetVTFIRQ(uint32_t addr, IRQn_Type IRQn, uint8_t num, FunctionalState NewState){ + if(num > 3) return ; + + if (NewState != DISABLE) + { + NVIC->VTFIDR[num] = IRQn; + NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)|0x1); + } + else{ + NVIC->VTFIDR[num] = IRQn; + NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)&(~0x1)); + } +} + +/********************************************************************* + * @fn NVIC_SystemReset + * + * @brief Initiate a system reset request + * + * @return none + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SystemReset(void) +{ + NVIC->CFGR = NVIC_KEY3|(1<<7); +} + +/********************************************************************* + * @fn __AMOADD_W + * + * @brief Atomic Add with 32bit value + * Atomically ADD 32bit value with value in memory using amoadd.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be ADDed + * + * @return return memory value + add value + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOADD_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __asm volatile ("amoadd.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/********************************************************************* + * @fn __AMOAND_W + * + * @brief Atomic And with 32bit value + * Atomically AND 32bit value with value in memory using amoand.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be ANDed + * + * @return return memory value & and value + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOAND_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __asm volatile ("amoand.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/********************************************************************* + * @fn __AMOMAX_W + * + * @brief Atomic signed MAX with 32bit value + * Atomically signed max compare 32bit value with value in memory using amomax.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be compared + * + * @return the bigger value + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOMAX_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __asm volatile ("amomax.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/********************************************************************* + * @fn __AMOMAXU_W + * + * @brief Atomic unsigned MAX with 32bit value + * Atomically unsigned max compare 32bit value with value in memory using amomaxu.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be compared + * + * @return return the bigger value + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOMAXU_W(volatile uint32_t *addr, uint32_t value) +{ + uint32_t result; + + __asm volatile ("amomaxu.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/********************************************************************* + * @fn __AMOMIN_W + * + * @brief Atomic signed MIN with 32bit value + * Atomically signed min compare 32bit value with value in memory using amomin.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be compared + * + * @return the smaller value + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOMIN_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __asm volatile ("amomin.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/********************************************************************* + * @fn __AMOMINU_W + * + * @brief Atomic unsigned MIN with 32bit value + * Atomically unsigned min compare 32bit value with value in memory using amominu.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be compared + * + * @return the smaller value + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOMINU_W(volatile uint32_t *addr, uint32_t value) +{ + uint32_t result; + + __asm volatile ("amominu.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/********************************************************************* + * @fn __AMOOR_W + * + * @brief Atomic OR with 32bit value + * Atomically OR 32bit value with value in memory using amoor.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be ORed + * + * @return return memory value | and value + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOOR_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __asm volatile ("amoor.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/********************************************************************* + * @fn __AMOSWAP_W + * + * @brief Atomically swap new 32bit value into memory using amoswap.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * newval - New value to be stored into the address + * + * @return return the original value in memory + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOSWAP_W(volatile uint32_t *addr, uint32_t newval) +{ + uint32_t result; + + __asm volatile ("amoswap.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(newval) : "memory"); + return result; +} + +/********************************************************************* + * @fn __AMOXOR_W + * + * @brief Atomic XOR with 32bit value + * Atomically XOR 32bit value with value in memory using amoxor.d. + * + * @param addr - Address pointer to data, address need to be 4byte aligned + * value - value to be XORed + * + * @return return memory value ^ and value + */ +__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOXOR_W(volatile int32_t *addr, int32_t value) +{ + int32_t result; + + __asm volatile ("amoxor.w %0, %2, %1" : \ + "=r"(result), "+A"(*addr) : "r"(value) : "memory"); + return *addr; +} + +/* Core_Exported_Functions */ +extern uint32_t __get_MSTATUS(void); +extern void __set_MSTATUS(uint32_t value); +extern uint32_t __get_MISA(void); +extern void __set_MISA(uint32_t value); +extern uint32_t __get_MTVEC(void); +extern void __set_MTVEC(uint32_t value); +extern uint32_t __get_MSCRATCH(void); +extern void __set_MSCRATCH(uint32_t value); +extern uint32_t __get_MEPC(void); +extern void __set_MEPC(uint32_t value); +extern uint32_t __get_MCAUSE(void); +extern void __set_MCAUSE(uint32_t value); +extern uint32_t __get_MTVAL(void); +extern void __set_MTVAL(uint32_t value); +extern uint32_t __get_MVENDORID(void); +extern uint32_t __get_MARCHID(void); +extern uint32_t __get_MIMPID(void); +extern uint32_t __get_MHARTID(void); +extern uint32_t __get_SP(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hw/bsp/ch32v20x/family.c b/hw/bsp/ch32v20x/family.c new file mode 100644 index 000000000..247dacde6 --- /dev/null +++ b/hw/bsp/ch32v20x/family.c @@ -0,0 +1,82 @@ +#include +#include "ch32v20x.h" +#include "bsp/board_api.h" +#include "board.h" + +__attribute__((interrupt)) +void USBHD_IRQHandler(void) { + tud_int_handler(0); +} + +#if CFG_TUSB_OS == OPT_OS_NONE + +volatile uint32_t system_ticks = 0; + +__attribute__((interrupt)) +void SysTick_Handler(void) { + SysTick->SR = 0; + system_ticks++; +} + +uint32_t SysTick_Config(uint32_t ticks) { + NVIC_EnableIRQ(SysTicK_IRQn); + SysTick->CTLR = 0; + SysTick->SR = 0; + SysTick->CNT = 0; + SysTick->CMP = ticks-1; + SysTick->CTLR = 0xF; + return 0; +} + +uint32_t board_millis(void) { + return system_ticks; +} + +#endif + +void board_init(void) { + __disable_irq(); + +#if CFG_TUSB_OS == OPT_OS_NONE + SysTick_Config(SystemCoreClock / 1000); +#endif + + switch (SystemCoreClock) { + case 48000000: RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div1); break; + case 96000000: RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div2); break; + case 144000000: RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div3); break; + default: TU_ASSERT(0,); break; + } + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE); + + LED_CLOCK_EN(); + GPIO_InitTypeDef GPIO_InitStructure = { + .GPIO_Pin = LED_PIN, + .GPIO_Mode = GPIO_Mode_Out_OD, + .GPIO_Speed = GPIO_Speed_50MHz, + }; + GPIO_Init(LED_PORT, &GPIO_InitStructure); + + __enable_irq(); + board_delay(2); +} + +void board_led_write(bool state) { + GPIO_WriteBit(LED_PORT, LED_PIN, state); +} + +uint32_t board_button_read(void) { + return false; +} + +int board_uart_read(uint8_t *buf, int len) { + (void) buf; + (void) len; + return 0; +} + +int board_uart_write(void const *buf, int len) { + (void) buf; + (void) len; + return len; +} diff --git a/hw/bsp/ch32v20x/family.mk b/hw/bsp/ch32v20x/family.mk new file mode 100644 index 000000000..2d94f19fb --- /dev/null +++ b/hw/bsp/ch32v20x/family.mk @@ -0,0 +1,50 @@ +# Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack +CROSS_COMPILE ?= riscv-none-elf- + +# Submodules +CH32V20X_SDK = hw/mcu/wch/ch32v20x +DEPS_SUBMODULES += $(CH32V20X_SDK) + +# WCH-SDK paths +CH32V20X_SDK_SRC = $(CH32V20X_SDK)/EVT/EXAM/SRC + +include $(TOP)/$(BOARD_PATH)/board.mk + +CFLAGS += \ + -march=rv32imac_zicsr \ + -mabi=ilp32 \ + -mcmodel=medany \ + -ffunction-sections \ + -fdata-sections \ + -ffat-lto-objects \ + -flto \ + -nostdlib -nostartfiles \ + -DCFG_TUSB_MCU=OPT_MCU_CH32V20X \ + -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED \ + +LDFLAGS_GCC += \ + -Wl,--gc-sections \ + -specs=nosys.specs \ + -specs=nano.specs \ + +LD_FILE = $(CH32V20X_SDK_SRC)/Ld/Link.ld + +SRC_C += \ + src/portable/wch/dcd_ch32_usbfs.c \ + $(CH32V20X_SDK_SRC)/Core/core_riscv.c \ + $(CH32V20X_SDK_SRC)/Peripheral/src/ch32v20x_gpio.c \ + $(CH32V20X_SDK_SRC)/Peripheral/src/ch32v20x_misc.c \ + $(CH32V20X_SDK_SRC)/Peripheral/src/ch32v20x_rcc.c \ + $(CH32V20X_SDK_SRC)/Peripheral/src/ch32v20x_usart.c \ + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/$(CH32V20X_SDK_SRC)/Peripheral/inc \ + +FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V + +# wch-link is not supported yet in official openOCD yet. We need to either use +# 1. download openocd as part of mounriver studio http://www.mounriver.com/download or +# 2. compiled from modified source https://github.com/dragonlock2/miscboards/blob/main/wch/SDK/riscv-openocd.tar.xz +flash: $(BUILD)/$(PROJECT).elf + openocd -f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg -c init -c halt -c "flash write_image $<" -c reset -c exit diff --git a/hw/bsp/ch32v20x/system_ch32v20x.c b/hw/bsp/ch32v20x/system_ch32v20x.c new file mode 100644 index 000000000..588f3165a --- /dev/null +++ b/hw/bsp/ch32v20x/system_ch32v20x.c @@ -0,0 +1,976 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : system_ch32v20x.c + * Author : WCH + * Version : V1.0.0 + * Date : 2021/06/06 + * Description : CH32V20x Device Peripheral Access Layer System Source File. + * For HSE = 32Mhz (CH32V208x/CH32V203RBT6) + * For HSE = 8Mhz (other CH32V203x) +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#include "ch32v20x.h" + +/* +* Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after +* reset the HSI is used as SYSCLK source). +* If none of the define below is enabled, the HSI is used as System clock source. +*/ +//#define SYSCLK_FREQ_HSE HSE_VALUE +//#define SYSCLK_FREQ_48MHz_HSE 48000000 +//#define SYSCLK_FREQ_56MHz_HSE 56000000 +//#define SYSCLK_FREQ_72MHz_HSE 72000000 +#define SYSCLK_FREQ_96MHz_HSE 96000000 +//#define SYSCLK_FREQ_120MHz_HSE 120000000 +//#define SYSCLK_FREQ_144MHz_HSE 144000000 +//#define SYSCLK_FREQ_HSI HSI_VALUE +//#define SYSCLK_FREQ_48MHz_HSI 48000000 +//#define SYSCLK_FREQ_56MHz_HSI 56000000 +//#define SYSCLK_FREQ_72MHz_HSI 72000000 +//#define SYSCLK_FREQ_96MHz_HSI 96000000 +//#define SYSCLK_FREQ_120MHz_HSI 120000000 +//#define SYSCLK_FREQ_144MHz_HSI 144000000 + +/* Clock Definitions */ +#ifdef SYSCLK_FREQ_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_48MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_56MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_72MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_96MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_120MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_144MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_48MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSI; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_56MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSI; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_72MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSI; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_96MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_96MHz_HSI; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_120MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_120MHz_HSI; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_144MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_144MHz_HSI; /* System Clock Frequency (Core Clock) */ +#else +uint32_t SystemCoreClock = HSI_VALUE; /* System Clock Frequency (Core Clock) */ + +#endif + +__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + +/* system_private_function_proto_types */ +static void SetSysClock(void); + +#ifdef SYSCLK_FREQ_HSE +static void SetSysClockToHSE( void ); +#elif defined SYSCLK_FREQ_48MHz_HSE +static void SetSysClockTo48_HSE( void ); +#elif defined SYSCLK_FREQ_56MHz_HSE +static void SetSysClockTo56_HSE( void ); +#elif defined SYSCLK_FREQ_72MHz_HSE +static void SetSysClockTo72_HSE( void ); +#elif defined SYSCLK_FREQ_96MHz_HSE +static void SetSysClockTo96_HSE( void ); +#elif defined SYSCLK_FREQ_120MHz_HSE +static void SetSysClockTo120_HSE( void ); +#elif defined SYSCLK_FREQ_144MHz_HSE +static void SetSysClockTo144_HSE( void ); +#elif defined SYSCLK_FREQ_48MHz_HSI +static void SetSysClockTo48_HSI( void ); +#elif defined SYSCLK_FREQ_56MHz_HSI +static void SetSysClockTo56_HSI( void ); +#elif defined SYSCLK_FREQ_72MHz_HSI +static void SetSysClockTo72_HSI( void ); +#elif defined SYSCLK_FREQ_96MHz_HSI +static void SetSysClockTo96_HSI( void ); +#elif defined SYSCLK_FREQ_120MHz_HSI +static void SetSysClockTo120_HSI( void ); +#elif defined SYSCLK_FREQ_144MHz_HSI +static void SetSysClockTo144_HSI( void ); + +#endif + +/********************************************************************* + * @fn SystemInit + * + * @brief Setup the microcontroller system Initialize the Embedded Flash Interface, + * the PLL and update the SystemCoreClock variable. + * + * @return none + */ +void SystemInit (void) +{ + RCC->CTLR |= (uint32_t)0x00000001; + RCC->CFGR0 &= (uint32_t)0xF8FF0000; + RCC->CTLR &= (uint32_t)0xFEF6FFFF; + RCC->CTLR &= (uint32_t)0xFFFBFFFF; + RCC->CFGR0 &= (uint32_t)0xFF80FFFF; + RCC->INTR = 0x009F0000; + SetSysClock(); +} + +/********************************************************************* + * @fn SystemCoreClockUpdate + * + * @brief Update SystemCoreClock variable according to Clock Register Values. + * + * @return none + */ +void SystemCoreClockUpdate (void) +{ + uint32_t tmp = 0, pllmull = 0, pllsource = 0, Pll_6_5 = 0; + + tmp = RCC->CFGR0 & RCC_SWS; + + switch (tmp) + { + case 0x00: + SystemCoreClock = HSI_VALUE; + break; + case 0x04: + SystemCoreClock = HSE_VALUE; + break; + case 0x08: + pllmull = RCC->CFGR0 & RCC_PLLMULL; + pllsource = RCC->CFGR0 & RCC_PLLSRC; + pllmull = ( pllmull >> 18) + 2; + + if(pllmull == 17) pllmull = 18; + + if (pllsource == 0x00) + { + if(EXTEN->EXTEN_CTR & EXTEN_PLL_HSI_PRE){ + SystemCoreClock = HSI_VALUE * pllmull; + } + else{ + SystemCoreClock = (HSI_VALUE >> 1) * pllmull; + } + } + else + { +#if defined (CH32V20x_D8W) + if((RCC->CFGR0 & (3<<22)) == (3<<22)) + { + SystemCoreClock = ((HSE_VALUE>>1)) * pllmull; + } + else +#endif + if ((RCC->CFGR0 & RCC_PLLXTPRE) != (uint32_t)RESET) + { +#if defined (CH32V20x_D8) || defined (CH32V20x_D8W) + SystemCoreClock = ((HSE_VALUE>>2) >> 1) * pllmull; +#else + SystemCoreClock = (HSE_VALUE >> 1) * pllmull; +#endif + } + else + { +#if defined (CH32V20x_D8) || defined (CH32V20x_D8W) + SystemCoreClock = (HSE_VALUE>>2) * pllmull; +#else + SystemCoreClock = HSE_VALUE * pllmull; +#endif + } + } + + if(Pll_6_5 == 1) SystemCoreClock = (SystemCoreClock / 2); + + break; + default: + SystemCoreClock = HSI_VALUE; + break; + } + + tmp = AHBPrescTable[((RCC->CFGR0 & RCC_HPRE) >> 4)]; + SystemCoreClock >>= tmp; +} + +/********************************************************************* + * @fn SetSysClock + * + * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClock(void) +{ +#ifdef SYSCLK_FREQ_HSE + SetSysClockToHSE(); +#elif defined SYSCLK_FREQ_48MHz_HSE + SetSysClockTo48_HSE(); +#elif defined SYSCLK_FREQ_56MHz_HSE + SetSysClockTo56_HSE(); +#elif defined SYSCLK_FREQ_72MHz_HSE + SetSysClockTo72_HSE(); +#elif defined SYSCLK_FREQ_96MHz_HSE + SetSysClockTo96_HSE(); +#elif defined SYSCLK_FREQ_120MHz_HSE + SetSysClockTo120_HSE(); +#elif defined SYSCLK_FREQ_144MHz_HSE + SetSysClockTo144_HSE(); +#elif defined SYSCLK_FREQ_48MHz_HSI + SetSysClockTo48_HSI(); +#elif defined SYSCLK_FREQ_56MHz_HSI + SetSysClockTo56_HSI(); +#elif defined SYSCLK_FREQ_72MHz_HSI + SetSysClockTo72_HSI(); +#elif defined SYSCLK_FREQ_96MHz_HSI + SetSysClockTo96_HSI(); +#elif defined SYSCLK_FREQ_120MHz_HSI + SetSysClockTo120_HSI(); +#elif defined SYSCLK_FREQ_144MHz_HSI + SetSysClockTo144_HSI(); + +#endif + + /* If none of the define above is enabled, the HSI is used as System clock + * source (default after reset) + */ +} + +#ifdef SYSCLK_FREQ_HSE + +/********************************************************************* + * @fn SetSysClockToHSE + * + * @brief Sets HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockToHSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if ((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1; + + /* Select HSE as system clock source + * CH32V20x_D6 (HSE=8MHZ) + * CH32V20x_D8 (HSE=32MHZ) + * CH32V20x_D8W (HSE=32MHZ) + */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_HSE; + + /* Wait till HSE is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x04) + { + } + } + else + { + /* If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_48MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo48_HSE + * + * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo48_HSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if ((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 6 = 48 MHz (HSE=8MHZ) + * CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 6 = 48 MHz (HSE=32MHZ) + * CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 6 = 48 MHz (HSE=32MHZ) + */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL6); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_56MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo56_HSE + * + * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo56_HSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if ((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 7 = 56 MHz (HSE=8MHZ) + * CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 7 = 56 MHz (HSE=32MHZ) + * CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 7 = 56 MHz (HSE=32MHZ) + */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL7); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_72MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo72_HSE + * + * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo72_HSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if ((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 9 = 72 MHz (HSE=8MHZ) + * CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 9 = 72 MHz (HSE=32MHZ) + * CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 9 = 72 MHz (HSE=32MHZ) + */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | + RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL9); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_96MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo96_HSE + * + * @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo96_HSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if ((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 12 = 96 MHz (HSE=8MHZ) + * CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz (HSE=32MHZ) + * CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz (HSE=32MHZ) + */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | + RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL12); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_120MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo120_HSE + * + * @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo120_HSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if(HSEStatus == (uint32_t)0x01) + { +#if defined (CH32V20x_D8W) + RCC->CFGR0 |= (uint32_t)(3<<22); + /* HCLK = SYSCLK/2 */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV2; +#else + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; +#endif + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 15 = 120 MHz (HSE=8MHZ) + * CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 15 = 120 MHz (HSE=32MHZ) + * CH32V20x_D8W-PLL configuration: PLLCLK = HSE/2 * 15 = 240 MHz (HSE=32MHZ) + */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | + RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL15); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} +#elif defined SYSCLK_FREQ_144MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo144_HSE + * + * @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo144_HSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if ((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if (HSEStatus == (uint32_t)0x01) + { + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 18 = 144 MHz (HSE=8MHZ) + * CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 18 = 144 MHz (HSE=32MHZ) + * CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 18 = 144 MHz (HSE=32MHZ) + */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | + RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLXTPRE_HSE | RCC_PLLMULL18); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_48MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo48_HSI + * + * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo48_HSI(void) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 6 = 48 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL6); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } +} + +#elif defined SYSCLK_FREQ_56MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo56_HSI + * + * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo56_HSI(void) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 7 = 48 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL7); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } +} + +#elif defined SYSCLK_FREQ_72MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo72_HSI + * + * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo72_HSI(void) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 9 = 72 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL9); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } +} + +#elif defined SYSCLK_FREQ_96MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo96_HSI + * + * @brief Sets System clock frequency to 96MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo96_HSI(void) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 12 = 96 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL12); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } +} + +#elif defined SYSCLK_FREQ_120MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo120_HSI + * + * @brief Sets System clock frequency to 120MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo120_HSI(void) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 15 = 120 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | + RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL15); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } +} +#elif defined SYSCLK_FREQ_144MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo144_HSI + * + * @brief Sets System clock frequency to 144MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo144_HSI(void) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 18 = 144 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL18); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t)~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while ((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } +} + +#endif diff --git a/hw/bsp/ch32v20x/system_ch32v20x.h b/hw/bsp/ch32v20x/system_ch32v20x.h new file mode 100644 index 000000000..eec7ccb15 --- /dev/null +++ b/hw/bsp/ch32v20x/system_ch32v20x.h @@ -0,0 +1,29 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : system_ch32v20x.h + * Author : WCH + * Version : V1.0.0 + * Date : 2021/06/06 + * Description : CH32V20x Device Peripheral Access Layer System Header File. +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef __SYSTEM_ch32v20x_H +#define __SYSTEM_ch32v20x_H + +#ifdef __cplusplus + extern "C" { +#endif + +extern uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock) */ + +/* System_Exported_Functions */ +extern void SystemInit(void); +extern void SystemCoreClockUpdate(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__CH32V20x_SYSTEM_H */ diff --git a/hw/bsp/ch32v20x/wch-riscv.cfg b/hw/bsp/ch32v20x/wch-riscv.cfg new file mode 100644 index 000000000..56a18d77e --- /dev/null +++ b/hw/bsp/ch32v20x/wch-riscv.cfg @@ -0,0 +1,18 @@ +#interface wlink +adapter driver wlinke +adapter speed 6000 +transport select sdi + +wlink_set_address 0x00000000 +set _CHIPNAME wch_riscv +sdi newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001 + +set _TARGETNAME $_CHIPNAME.cpu + +target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME +$_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 10000 -work-area-backup 1 +set _FLASHNAME $_CHIPNAME.flash + +flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0 + +echo "Ready for Remote Connections" diff --git a/hw/bsp/ch32v307/family.mk b/hw/bsp/ch32v307/family.mk index 003b90539..7232bfa08 100644 --- a/hw/bsp/ch32v307/family.mk +++ b/hw/bsp/ch32v307/family.mk @@ -4,6 +4,9 @@ # Toolchain from https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack CROSS_COMPILE ?= riscv-none-embed- +# Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack +#CROSS_COMPILE ?= riscv-none-elf- + # Submodules CH32V307_SDK = hw/mcu/wch/ch32v307 @@ -13,6 +16,8 @@ CH32V307_SDK_SRC = $(CH32V307_SDK)/EVT/EXAM/SRC include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= rv32imac-ilp32 +# -march=rv32imac_zicsr + CFLAGS += \ -flto \ -msmall-data-limit=8 \ diff --git a/hw/bsp/fomu/family.mk b/hw/bsp/fomu/family.mk index d4b6eaea6..78f20d7db 100644 --- a/hw/bsp/fomu/family.mk +++ b/hw/bsp/fomu/family.mk @@ -1,6 +1,10 @@ # Toolchain from https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack CROSS_COMPILE = riscv-none-embed- +# Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack +# CROSS_COMPILE = riscv-none-elf- +# -march=rv32i_zicsr + CPU_CORE ?= rv32i-ilp32 CFLAGS += \ diff --git a/hw/bsp/gd32vf103/family.mk b/hw/bsp/gd32vf103/family.mk index 28e48a6b5..646564eae 100644 --- a/hw/bsp/gd32vf103/family.mk +++ b/hw/bsp/gd32vf103/family.mk @@ -7,6 +7,9 @@ # Toolchain from https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack CROSS_COMPILE ?= riscv-none-embed- +# Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack +# CROSS_COMPILE ?= riscv-none-elf- + # Submodules NUCLEI_SDK = hw/mcu/gd/nuclei-sdk @@ -19,6 +22,8 @@ STARTUP_ASM = $(GD32VF103_SDK_SOC)/Common/Source/GCC include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= rv32imac-ilp32 +# -march=rv32imac_zicsr + CFLAGS += \ -mcmodel=medlow \ -mstrict-align \ diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index 4218835aa..974289b69 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -609,7 +609,7 @@ static bool _negotiate_streaming_parameters(videod_streaming_interface_t const * tusb_desc_cs_video_fmt_t const *fmt = _find_desc_format(tu_desc_next(vs), end, fmtnum); tusb_desc_cs_video_frm_t const *frm = _find_desc_frame(tu_desc_next(fmt), end, frmnum); - uint_fast32_t interval, interval_ms; + uint_fast32_t interval, interval_ms = 0; switch (request) { case VIDEO_REQUEST_GET_MAX: { uint_fast32_t min_interval, max_interval; diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 3a7d6ad33..eab112015 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -410,6 +410,10 @@ #elif TU_CHECK_MCU(OPT_MCU_CH32F20X) #define TUP_DCD_ENDPOINT_MAX 16 #define TUP_RHPORT_HIGHSPEED 1 + +#elif TU_CHECK_MCU(OPT_MCU_CH32V20X) + #define TUP_DCD_ENDPOINT_MAX 8 + #endif diff --git a/src/portable/wch/ch32_usbfs_reg.h b/src/portable/wch/ch32_usbfs_reg.h new file mode 100644 index 000000000..3b8e49ae2 --- /dev/null +++ b/src/portable/wch/ch32_usbfs_reg.h @@ -0,0 +1,77 @@ +#ifndef USB_CH32_USBFS_REG_H +#define USB_CH32_USBFS_REG_H + +#if (CFG_TUSB_MCU == OPT_MCU_CH32V20X) +#include +#endif + +// CTRL +#define USBFS_CTRL_DMA_EN (1 << 0) +#define USBFS_CTRL_CLR_ALL (1 << 1) +#define USBFS_CTRL_RESET_SIE (1 << 2) +#define USBFS_CTRL_INT_BUSY (1 << 3) +#define USBFS_CTRL_SYS_CTRL (1 << 4) +#define USBFS_CTRL_DEV_PUEN (1 << 5) +#define USBFS_CTRL_LOW_SPEED (1 << 6) +#define USBFS_CTRL_HOST_MODE (1 << 7) + +// INT_EN +#define USBFS_INT_EN_BUS_RST (1 << 0) +#define USBFS_INT_EN_DETECT (1 << 0) +#define USBFS_INT_EN_TRANSFER (1 << 1) +#define USBFS_INT_EN_SUSPEND (1 << 2) +#define USBFS_INT_EN_HST_SOF (1 << 3) +#define USBFS_INT_EN_FIFO_OV (1 << 4) +#define USBFS_INT_EN_DEV_NAK (1 << 6) +#define USBFS_INT_EN_DEV_SOF (1 << 7) + +// INT_FG +#define USBFS_INT_FG_BUS_RST (1 << 0) +#define USBFS_INT_FG_DETECT (1 << 0) +#define USBFS_INT_FG_TRANSFER (1 << 1) +#define USBFS_INT_FG_SUSPEND (1 << 2) +#define USBFS_INT_FG_HST_SOF (1 << 3) +#define USBFS_INT_FG_FIFO_OV (1 << 4) +#define USBFS_INT_FG_SIE_FREE (1 << 5) +#define USBFS_INT_FG_TOG_OK (1 << 6) +#define USBFS_INT_FG_IS_NAK (1 << 7) + +// INT_ST +#define USBFS_INT_ST_MASK_UIS_ENDP(x) (((x) >> 0) & 0x0F) +#define USBFS_INT_ST_MASK_UIS_TOKEN(x) (((x) >> 4) & 0x03) + +// UDEV_CTRL +#define USBFS_UDEV_CTRL_PORT_EN (1 << 0) +#define USBFS_UDEV_CTRL_GP_BIT (1 << 1) +#define USBFS_UDEV_CTRL_LOW_SPEED (1 << 2) +#define USBFS_UDEV_CTRL_DM_PIN (1 << 4) +#define USBFS_UDEV_CTRL_DP_PIN (1 << 5) +#define USBFS_UDEV_CTRL_PD_DIS (1 << 7) + +// TX_CTRL +#define USBFS_EP_T_RES_MASK (3 << 0) +#define USBFS_EP_T_TOG (1 << 2) +#define USBFS_EP_T_AUTO_TOG (1 << 3) + +#define USBFS_EP_T_RES_ACK (0 << 0) +#define USBFS_EP_T_RES_NYET (1 << 0) +#define USBFS_EP_T_RES_NAK (2 << 0) +#define USBFS_EP_T_RES_STALL (3 << 0) + +// RX_CTRL +#define USBFS_EP_R_RES_MASK (3 << 0) +#define USBFS_EP_R_TOG (1 << 2) +#define USBFS_EP_R_AUTO_TOG (1 << 3) + +#define USBFS_EP_R_RES_ACK (0 << 0) +#define USBFS_EP_R_RES_NYET (1 << 0) +#define USBFS_EP_R_RES_NAK (2 << 0) +#define USBFS_EP_R_RES_STALL (3 << 0) + +// token PID +#define PID_OUT 0 +#define PID_SOF 1 +#define PID_IN 2 +#define PID_SETUP 3 + +#endif // USB_CH32_USBFS_REG_H diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c new file mode 100644 index 000000000..256c46696 --- /dev/null +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -0,0 +1,304 @@ +#include "tusb_option.h" + +#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32V20X) + +#include +#include "device/dcd.h" +#include "ch32_usbfs_reg.h" + +/* private defines */ +#define EP_MAX (8) + +#define EP_DMA(ep) ((&USBOTG_FS->UEP0_DMA)[ep]) +#define EP_TX_LEN(ep) ((&USBOTG_FS->UEP0_TX_LEN)[2 * ep]) +#define EP_TX_CTRL(ep) ((&USBOTG_FS->UEP0_TX_CTRL)[4 * ep]) +#define EP_RX_CTRL(ep) ((&USBOTG_FS->UEP0_RX_CTRL)[4 * ep]) + +/* private data */ +struct usb_xfer { + bool valid; + uint8_t *buffer; + size_t len; + size_t processed_len; + size_t max_size; +}; + +static struct { + bool ep0_tog; + bool isochronous[EP_MAX]; + struct usb_xfer xfer[EP_MAX][2]; + TU_ATTR_ALIGNED(4) uint8_t buffer[EP_MAX][2][64]; + TU_ATTR_ALIGNED(4) struct { + // OUT transfers >64 bytes will overwrite queued IN data! + uint8_t out[64]; + uint8_t in[1023]; + uint8_t pad; + } ep3_buffer; +} data; + +/* private helpers */ +static void update_in(uint8_t rhport, uint8_t ep, bool force) { + struct usb_xfer *xfer = &data.xfer[ep][TUSB_DIR_IN]; + if (xfer->valid) { + if (force || xfer->len) { + size_t len = TU_MIN(xfer->max_size, xfer->len); + if (ep == 0) { + memcpy(data.buffer[ep][TUSB_DIR_OUT], xfer->buffer, len); // ep0 uses same chunk + } else if (ep == 3) { + memcpy(data.ep3_buffer.in, xfer->buffer, len); + } else { + memcpy(data.buffer[ep][TUSB_DIR_IN], xfer->buffer, len); + } + xfer->buffer += len; + xfer->len -= len; + xfer->processed_len += len; + + EP_TX_LEN(ep) = len; + if (ep == 0) { + EP_TX_CTRL(0) = USBFS_EP_T_RES_ACK | (data.ep0_tog ? USBFS_EP_T_TOG : 0); + data.ep0_tog = !data.ep0_tog; + } else if (data.isochronous[ep]) { + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_NYET; + } else { + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_ACK; + } + } else { + xfer->valid = false; + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_NAK; + dcd_event_xfer_complete(rhport, ep | TUSB_DIR_IN_MASK, xfer->processed_len, + XFER_RESULT_SUCCESS, true); + } + } +} + +static void update_out(uint8_t rhport, uint8_t ep, size_t rx_len) { + struct usb_xfer *xfer = &data.xfer[ep][TUSB_DIR_OUT]; + if (xfer->valid) { + size_t len = TU_MIN(xfer->max_size, TU_MIN(xfer->len, rx_len)); + if (ep == 3) { + memcpy(xfer->buffer, data.ep3_buffer.out, len); + } else { + memcpy(xfer->buffer, data.buffer[ep][TUSB_DIR_OUT], len); + } + xfer->buffer += len; + xfer->len -= len; + xfer->processed_len += len; + + if (xfer->len == 0 || len < xfer->max_size) { + xfer->valid = false; + dcd_event_xfer_complete(rhport, ep, xfer->processed_len, XFER_RESULT_SUCCESS, true); + } + + if (ep == 0) { + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + } + } +} + +/* public functions */ +void dcd_init(uint8_t rhport) { + // init registers + USBOTG_FS->BASE_CTRL = USBFS_CTRL_SYS_CTRL | USBFS_CTRL_INT_BUSY | USBFS_CTRL_DMA_EN; + USBOTG_FS->UDEV_CTRL = USBFS_UDEV_CTRL_PD_DIS | USBFS_UDEV_CTRL_PORT_EN; + USBOTG_FS->DEV_ADDR = 0x00; + + USBOTG_FS->INT_FG = 0xFF; + USBOTG_FS->INT_EN = USBFS_INT_EN_BUS_RST | USBFS_INT_EN_TRANSFER | USBFS_INT_EN_SUSPEND; + + // setup endpoint 0 + EP_DMA(0) = (uint32_t) &data.buffer[0][0]; + EP_TX_LEN(0) = 0; + EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + + // enable other endpoints but NAK everything + USBOTG_FS->UEP4_1_MOD = 0xCC; + USBOTG_FS->UEP2_3_MOD = 0xCC; + USBOTG_FS->UEP5_6_MOD = 0xCC; + USBOTG_FS->UEP7_MOD = 0x0C; + + for (uint8_t ep = 1; ep < EP_MAX; ep++) { + EP_DMA(ep) = (uint32_t) &data.buffer[ep][0]; + EP_TX_LEN(ep) = 0; + EP_TX_CTRL(ep) = USBFS_EP_T_AUTO_TOG | USBFS_EP_T_RES_NAK; + EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_NAK; + } + EP_DMA(3) = (uint32_t) &data.ep3_buffer.out[0]; + + dcd_connect(rhport); +} + +void dcd_int_handler(uint8_t rhport) { + (void) rhport; + uint8_t status = USBOTG_FS->INT_FG; + if (status & USBFS_INT_FG_TRANSFER) { + uint8_t ep = USBFS_INT_ST_MASK_UIS_ENDP(USBOTG_FS->INT_ST); + uint8_t token = USBFS_INT_ST_MASK_UIS_TOKEN(USBOTG_FS->INT_ST); + + switch (token) { + case PID_OUT: { + uint16_t rx_len = USBOTG_FS->RX_LEN; + update_out(rhport, ep, rx_len); + break; + } + + case PID_IN: + update_in(rhport, ep, false); + break; + + case PID_SETUP: + data.ep0_tog = true; + dcd_event_setup_received(rhport, &data.buffer[0][TUSB_DIR_OUT][0], true); + break; + } + + USBOTG_FS->INT_FG = USBFS_INT_FG_TRANSFER; + } else if (status & USBFS_INT_FG_BUS_RST) { + data.ep0_tog = true; + data.xfer[0][TUSB_DIR_OUT].max_size = 64; + data.xfer[0][TUSB_DIR_IN].max_size = 64; + + dcd_event_bus_signal(rhport, DCD_EVENT_BUS_RESET, true); + + USBOTG_FS->DEV_ADDR = 0x00; + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + + USBOTG_FS->INT_FG = USBFS_INT_FG_BUS_RST; + } else if (status & USBFS_INT_FG_SUSPEND) { + dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SUSPEND }; + dcd_event_handler(&event, true); + USBOTG_FS->INT_FG = USBFS_INT_FG_SUSPEND; + } +} + +void dcd_int_enable(uint8_t rhport) { + (void) rhport; + NVIC_EnableIRQ(USBHD_IRQn); +} + +void dcd_int_disable(uint8_t rhport) { + (void) rhport; + NVIC_DisableIRQ(USBHD_IRQn); +} + +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { + (void) dev_addr; + dcd_edpt_xfer(rhport, 0x80, NULL, 0); // zlp status response +} + +void dcd_remote_wakeup(uint8_t rhport) { + (void) rhport; + // TODO optional +} + +void dcd_connect(uint8_t rhport) { + (void) rhport; + USBOTG_FS->BASE_CTRL |= USBFS_CTRL_DEV_PUEN; +} + +void dcd_disconnect(uint8_t rhport) { + (void) rhport; + USBOTG_FS->BASE_CTRL &= ~USBFS_CTRL_DEV_PUEN; +} + +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) { + (void) rhport; + if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && + request->bRequest == TUSB_REQ_SET_ADDRESS) { + USBOTG_FS->DEV_ADDR = (uint8_t) request->wValue; + } + EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; +} + +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { + (void) rhport; + uint8_t ep = tu_edpt_number(desc_ep->bEndpointAddress); + uint8_t dir = tu_edpt_dir(desc_ep->bEndpointAddress); + TU_ASSERT(ep < EP_MAX); + + data.isochronous[ep] = desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS; + data.xfer[ep][dir].max_size = tu_edpt_packet_size(desc_ep); + + if (ep != 0) { + if (dir == TUSB_DIR_OUT) { + if (data.isochronous[ep]) { + EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_NYET; + } else { + EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_ACK; + } + } else { + EP_TX_LEN(ep) = 0; + EP_TX_CTRL(ep) = USBFS_EP_T_AUTO_TOG | USBFS_EP_T_RES_NAK; + } + } + return true; +} + +void dcd_edpt_close_all(uint8_t rhport) { + (void) rhport; + // TODO optional +} + +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; + (void) ep_addr; + // TODO optional +} + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { + (void) rhport; + uint8_t ep = tu_edpt_number(ep_addr); + uint8_t dir = tu_edpt_dir(ep_addr); + + struct usb_xfer *xfer = &data.xfer[ep][dir]; + xfer->valid = true; + xfer->buffer = buffer; + xfer->len = total_bytes; + xfer->processed_len = 0; + + if (dir == TUSB_DIR_IN) { + update_in(rhport, ep, true); + } + return true; +} + +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; + uint8_t ep = tu_edpt_number(ep_addr); + uint8_t dir = tu_edpt_dir(ep_addr); + if (ep == 0) { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(0) = USBFS_EP_R_RES_STALL; + } else { + EP_TX_LEN(0) = 0; + EP_TX_CTRL(0) = USBFS_EP_T_RES_STALL; + } + } else { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep) = (EP_RX_CTRL(ep) & ~USBFS_EP_R_RES_MASK) | USBFS_EP_R_RES_STALL; + } else { + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~USBFS_EP_T_RES_MASK) | USBFS_EP_T_RES_STALL; + } + } +} + +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; + uint8_t ep = tu_edpt_number(ep_addr); + uint8_t dir = tu_edpt_dir(ep_addr); + if (ep == 0) { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + } + } else { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep) = (EP_RX_CTRL(ep) & ~(USBFS_EP_R_RES_MASK | USBFS_EP_R_TOG)) | USBFS_EP_R_RES_ACK; + } else { + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK | USBFS_EP_T_TOG)) | USBFS_EP_T_RES_NAK; + } + } +} + +#endif // CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32V20X) diff --git a/src/tusb_option.h b/src/tusb_option.h index 058427e0e..3d04825a4 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -181,6 +181,7 @@ // WCH #define OPT_MCU_CH32V307 2200 ///< WCH CH32V307 #define OPT_MCU_CH32F20X 2210 ///< WCH CH32F20x +#define OPT_MCU_CH32V20X 2220 ///< WCH CH32V20X // NXP LPC MCX diff --git a/tools/get_deps.py b/tools/get_deps.py index 87c1c5ccd..cf15126b3 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -168,6 +168,9 @@ deps_optional = { 'hw/mcu/ti': ['https://github.com/hathach/ti_driver.git', '143ed6cc20a7615d042b03b21e070197d473e6e5', 'msp430 msp432e4 tm4c'], + 'hw/mcu/wch/ch32v20x': ['https://github.com/openwch/ch32v20x.git', + 'de6d68c654340d7f27b00cebbfc9aa2740a1abc2', + 'ch32v20x'], 'hw/mcu/wch/ch32v307': ['https://github.com/openwch/ch32v307.git', '17761f5cf9dbbf2dcf665b7c04934188add20082', 'ch32v307'], diff --git a/tools/iar_template.ipcf b/tools/iar_template.ipcf index e72ec0ce2..33a6ef045 100644 --- a/tools/iar_template.ipcf +++ b/tools/iar_template.ipcf @@ -239,6 +239,7 @@ $TUSB_DIR$/src/portable/valentyusb/eptri/dcd_eptri.h + $TUSB_DIR$/src/portable/wch/dcd_ch32_usbfs.c $TUSB_DIR$/src/portable/wch/dcd_ch32_usbhs.c $TUSB_DIR$/src/portable/wch/ch32_usbhs_reg.h -- cgit v1.3.1 From 2a67ce773dcd68f7f8c4c07fce2e6e4f7947e03d Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 15 May 2024 20:13:00 +0700 Subject: change default risv-gcc to riscv-none-elf- and add _zicsr extension add cmake for ch32v20x, skip freertos examples for CH32V20X, also skip net webserver due to lack of RAM update to use openocd with wlinke adapter --- .github/workflows/ci_set_matrix.py | 4 +- .idea/cmake.xml | 4 +- examples/build_system/cmake/cpu/rv32i-ilp32.cmake | 4 +- .../build_system/cmake/cpu/rv32imac-ilp32.cmake | 4 +- .../build_system/cmake/toolchain/riscv_gcc.cmake | 19 +++- examples/build_system/make/cpu/rv32i-ilp32.mk | 11 ++- examples/build_system/make/cpu/rv32imac-ilp32.mk | 10 +- .../device/audio_4_channel_mic_freertos/skip.txt | 1 + examples/device/audio_test_freertos/skip.txt | 1 + examples/device/net_lwip_webserver/skip.txt | 1 + examples/device/video_capture_2ch/skip.txt | 1 + hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake | 7 ++ hw/bsp/ch32v20x/family.cmake | 109 +++++++++++++++++++++ hw/bsp/ch32v20x/family.mk | 17 ++-- hw/bsp/ch32v20x/wch-riscv.cfg | 1 - hw/bsp/ch32v307/family.cmake | 1 - hw/bsp/ch32v307/family.mk | 8 +- hw/bsp/ch32v307/wch-riscv.cfg | 16 +-- hw/bsp/family_support.cmake | 1 + hw/bsp/fomu/family.mk | 6 +- hw/bsp/gd32vf103/family.mk | 7 +- src/portable/wch/dcd_ch32_usbfs.c | 8 ++ 22 files changed, 191 insertions(+), 50 deletions(-) create mode 100644 hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake create mode 100644 hw/bsp/ch32v20x/family.cmake (limited to 'src/portable') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 62239c9ad..c6f4e8fe2 100644 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -7,14 +7,14 @@ toolchain_list = { "arm-iar": "", "arm-gcc": "", "msp430-gcc": "http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2", - "riscv-gcc": "https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack/releases/download/v10.1.0-1.1/xpack-riscv-none-embed-gcc-10.1.0-1.1-linux-x64.tar.gz", + "riscv-gcc": "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz" } # family: [supported toolchain] family_list = { "broadcom_32bit": ["arm-gcc"], "broadcom_64bit": ["aarch64-gcc"], - "ch32v307 fomu gd32vf103": ["riscv-gcc"], + "ch32v20x ch32v307 fomu gd32vf103": ["riscv-gcc"], "imxrt": ["arm-gcc", "arm-clang"], "kinetis_k kinetis_kl kinetis_k32l2": ["arm-gcc", "arm-clang"], "lpc11 lpc13 lpc15": ["arm-gcc", "arm-clang"], diff --git a/.idea/cmake.xml b/.idea/cmake.xml index bb13a0466..a34f19e1f 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -66,6 +66,7 @@ + @@ -103,6 +104,7 @@ + @@ -120,7 +122,6 @@ - @@ -130,6 +131,7 @@ + \ No newline at end of file diff --git a/examples/build_system/cmake/cpu/rv32i-ilp32.cmake b/examples/build_system/cmake/cpu/rv32i-ilp32.cmake index b4889e6ff..605c40ba1 100644 --- a/examples/build_system/cmake/cpu/rv32i-ilp32.cmake +++ b/examples/build_system/cmake/cpu/rv32i-ilp32.cmake @@ -1,13 +1,13 @@ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS - -march=rv32i + -march=rv32i_zicsr -mabi=ilp32 ) set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS - -march=rv32i + -march=rv32i_zicsr -mabi=ilp32 ) set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") diff --git a/examples/build_system/cmake/cpu/rv32imac-ilp32.cmake b/examples/build_system/cmake/cpu/rv32imac-ilp32.cmake index dd1bc0af7..584d90519 100644 --- a/examples/build_system/cmake/cpu/rv32imac-ilp32.cmake +++ b/examples/build_system/cmake/cpu/rv32imac-ilp32.cmake @@ -1,13 +1,13 @@ if (TOOLCHAIN STREQUAL "gcc") set(TOOLCHAIN_COMMON_FLAGS - -march=rv32imac + -march=rv32imac_zicsr -mabi=ilp32 ) set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") elseif (TOOLCHAIN STREQUAL "clang") set(TOOLCHAIN_COMMON_FLAGS - -march=rv32imac + -march=rv32imac_zicsr -mabi=ilp32 ) set(FREERTOS_PORT GCC_RISC_V CACHE INTERNAL "") diff --git a/examples/build_system/cmake/toolchain/riscv_gcc.cmake b/examples/build_system/cmake/toolchain/riscv_gcc.cmake index 904b27294..d788df023 100644 --- a/examples/build_system/cmake/toolchain/riscv_gcc.cmake +++ b/examples/build_system/cmake/toolchain/riscv_gcc.cmake @@ -1,15 +1,24 @@ +# default Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack +if (NOT DEFINED CROSS_COMPILE) + set(CROSS_COMPILE "riscv-none-elf-") +endif () + +if (NOT DEFINED CMAKE_C_COMPILER) + set(CMAKE_C_COMPILER ${CROSS_COMPILE}gcc) +endif () + if (NOT DEFINED CMAKE_C_COMPILER) - set(CMAKE_C_COMPILER "riscv-none-embed-gcc") + set(CMAKE_C_COMPILER ${CROSS_COMPILE}gcc) endif () if (NOT DEFINED CMAKE_CXX_COMPILER) - set(CMAKE_CXX_COMPILER "riscv-none-embed-g++") + set(CMAKE_CXX_COMPILER ${CROSS_COMPILE}g++) endif () set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) -set(CMAKE_SIZE "riscv-none-embed-size" CACHE FILEPATH "") -set(CMAKE_OBJCOPY "riscv-none-embed-objcopy" CACHE FILEPATH "") -set(CMAKE_OBJDUMP "riscv-none-embed-objdump" CACHE FILEPATH "") +set(CMAKE_SIZE ${CROSS_COMPILE}size CACHE FILEPATH "") +set(CMAKE_OBJCOPY ${CROSS_COMPILE}objcopy CACHE FILEPATH "") +set(CMAKE_OBJDUMP ${CROSS_COMPILE}objdump CACHE FILEPATH "") include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) diff --git a/examples/build_system/make/cpu/rv32i-ilp32.mk b/examples/build_system/make/cpu/rv32i-ilp32.mk index a465baf4c..af764afc5 100644 --- a/examples/build_system/make/cpu/rv32i-ilp32.mk +++ b/examples/build_system/make/cpu/rv32i-ilp32.mk @@ -1,12 +1,15 @@ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ - -march=rv32i \ + -march=rv32i_zicsr \ -mabi=ilp32 \ -else ifeq ($(TOOLCHAIN),iar) - #CFLAGS += --cpu cortex-a53 - #ASFLAGS += --cpu cortex-a53 +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + -march=rv32i_zicsr \ + -mabi=ilp32 \ +else ifeq ($(TOOLCHAIN),iar) + $(error not support) endif # For freeRTOS port source diff --git a/examples/build_system/make/cpu/rv32imac-ilp32.mk b/examples/build_system/make/cpu/rv32imac-ilp32.mk index 2b6493e48..19c322ebc 100644 --- a/examples/build_system/make/cpu/rv32imac-ilp32.mk +++ b/examples/build_system/make/cpu/rv32imac-ilp32.mk @@ -1,11 +1,15 @@ ifeq ($(TOOLCHAIN),gcc) CFLAGS += \ - -march=rv32imac \ + -march=rv32imac_zicsr \ + -mabi=ilp32 \ + +else ifeq ($(TOOLCHAIN),clang) + CFLAGS += \ + -march=rv32imac_zicsr \ -mabi=ilp32 \ else ifeq ($(TOOLCHAIN),iar) - #CFLAGS += --cpu cortex-a53 - #ASFLAGS += --cpu cortex-a53 + $(error not support) endif diff --git a/examples/device/audio_4_channel_mic_freertos/skip.txt b/examples/device/audio_4_channel_mic_freertos/skip.txt index 0b689192d..4769af009 100644 --- a/examples/device/audio_4_channel_mic_freertos/skip.txt +++ b/examples/device/audio_4_channel_mic_freertos/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V20X mcu:CH32V307 mcu:CXD56 mcu:F1C100S diff --git a/examples/device/audio_test_freertos/skip.txt b/examples/device/audio_test_freertos/skip.txt index a6f96b288..6aaa27661 100644 --- a/examples/device/audio_test_freertos/skip.txt +++ b/examples/device/audio_test_freertos/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V20X mcu:CH32V307 mcu:CXD56 mcu:F1C100S diff --git a/examples/device/net_lwip_webserver/skip.txt b/examples/device/net_lwip_webserver/skip.txt index 43cdab71a..51af58667 100644 --- a/examples/device/net_lwip_webserver/skip.txt +++ b/examples/device/net_lwip_webserver/skip.txt @@ -1,3 +1,4 @@ +mcu:CH32V20X mcu:LPC11UXX mcu:LPC13XX mcu:LPC15XX diff --git a/examples/device/video_capture_2ch/skip.txt b/examples/device/video_capture_2ch/skip.txt index 86697899b..1786297f9 100644 --- a/examples/device/video_capture_2ch/skip.txt +++ b/examples/device/video_capture_2ch/skip.txt @@ -2,6 +2,7 @@ mcu:MSP430x5xx mcu:NUC121 mcu:SAMD11 mcu:GD32VF103 +mcu:CH32V20X mcu:CH32V307 mcu:STM32L0 family:espressif diff --git a/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake b/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake new file mode 100644 index 000000000..2699f3e15 --- /dev/null +++ b/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake @@ -0,0 +1,7 @@ +set(MCU_VARIANT D6) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + CH32V20x_D6 + ) +endfunction() diff --git a/hw/bsp/ch32v20x/family.cmake b/hw/bsp/ch32v20x/family.cmake new file mode 100644 index 000000000..fb39e3630 --- /dev/null +++ b/hw/bsp/ch32v20x/family.cmake @@ -0,0 +1,109 @@ +include_guard() + +set(CH32_FAMILY ch32v20x) +set(SDK_DIR ${TOP}/hw/mcu/wch/${CH32_FAMILY}/EVT/EXAM/SRC) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR rv32imac-ilp32 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS CH32V20X CACHE INTERNAL "") +set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif() + + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${SDK_DIR}/Ld/Link.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${SDK_DIR}/Startup/startup_${CH32_FAMILY}_${MCU_VARIANT}.S) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_DIR}/Core/core_riscv.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_usart.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_${CH32_FAMILY}.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_DIR}/Peripheral/inc + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(${BOARD_TARGET} PUBLIC + -mcmodel=medany + ) + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + message(FATAL_ERROR "Clang is not supported for MSP432E4") + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_CH32V20X ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/wch/dcd_ch32_usbfs.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_openocd_wch(${TARGET}) +endfunction() diff --git a/hw/bsp/ch32v20x/family.mk b/hw/bsp/ch32v20x/family.mk index 2d94f19fb..7e290bb18 100644 --- a/hw/bsp/ch32v20x/family.mk +++ b/hw/bsp/ch32v20x/family.mk @@ -1,3 +1,9 @@ +# https://www.embecosm.com/resources/tool-chain-downloads/#riscv-stable +#CROSS_COMPILE ?= riscv32-unknown-elf- + +# Toolchain from https://nucleisys.com/download.php +#CROSS_COMPILE ?= riscv-nuclei-elf- + # Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack CROSS_COMPILE ?= riscv-none-elf- @@ -9,23 +15,21 @@ DEPS_SUBMODULES += $(CH32V20X_SDK) CH32V20X_SDK_SRC = $(CH32V20X_SDK)/EVT/EXAM/SRC include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= rv32imac-ilp32 CFLAGS += \ - -march=rv32imac_zicsr \ - -mabi=ilp32 \ -mcmodel=medany \ -ffunction-sections \ -fdata-sections \ -ffat-lto-objects \ -flto \ - -nostdlib -nostartfiles \ -DCFG_TUSB_MCU=OPT_MCU_CH32V20X \ -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED \ LDFLAGS_GCC += \ -Wl,--gc-sections \ - -specs=nosys.specs \ - -specs=nano.specs \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs \ LD_FILE = $(CH32V20X_SDK_SRC)/Ld/Link.ld @@ -46,5 +50,6 @@ FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V # wch-link is not supported yet in official openOCD yet. We need to either use # 1. download openocd as part of mounriver studio http://www.mounriver.com/download or # 2. compiled from modified source https://github.com/dragonlock2/miscboards/blob/main/wch/SDK/riscv-openocd.tar.xz +OPENOCD ?= $(HOME)/app/riscv-openocd-wch/src/openocd flash: $(BUILD)/$(PROJECT).elf - openocd -f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg -c init -c halt -c "flash write_image $<" -c reset -c exit + $(OPENOCD) -f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg -c init -c halt -c "flash write_image $<" -c reset -c exit diff --git a/hw/bsp/ch32v20x/wch-riscv.cfg b/hw/bsp/ch32v20x/wch-riscv.cfg index 56a18d77e..aa35aa9c5 100644 --- a/hw/bsp/ch32v20x/wch-riscv.cfg +++ b/hw/bsp/ch32v20x/wch-riscv.cfg @@ -1,4 +1,3 @@ -#interface wlink adapter driver wlinke adapter speed 6000 transport select sdi diff --git a/hw/bsp/ch32v307/family.cmake b/hw/bsp/ch32v307/family.cmake index 87a0f2eba..fb478d387 100644 --- a/hw/bsp/ch32v307/family.cmake +++ b/hw/bsp/ch32v307/family.cmake @@ -11,7 +11,6 @@ set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TO set(FAMILY_MCUS CH32V307 CACHE INTERNAL "") set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") -set(OPENOCD_OPTION2 "-c wlink_reset_resume") #------------------------------------ # BOARD_TARGET diff --git a/hw/bsp/ch32v307/family.mk b/hw/bsp/ch32v307/family.mk index 7232bfa08..df9ded4a0 100644 --- a/hw/bsp/ch32v307/family.mk +++ b/hw/bsp/ch32v307/family.mk @@ -1,11 +1,11 @@ # https://www.embecosm.com/resources/tool-chain-downloads/#riscv-stable #CROSS_COMPILE ?= riscv32-unknown-elf- -# Toolchain from https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack -CROSS_COMPILE ?= riscv-none-embed- +# Toolchain from https://nucleisys.com/download.php +#CROSS_COMPILE ?= riscv-nuclei-elf- # Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack -#CROSS_COMPILE ?= riscv-none-elf- +CROSS_COMPILE ?= riscv-none-elf- # Submodules CH32V307_SDK = hw/mcu/wch/ch32v307 @@ -16,8 +16,6 @@ CH32V307_SDK_SRC = $(CH32V307_SDK)/EVT/EXAM/SRC include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= rv32imac-ilp32 -# -march=rv32imac_zicsr - CFLAGS += \ -flto \ -msmall-data-limit=8 \ diff --git a/hw/bsp/ch32v307/wch-riscv.cfg b/hw/bsp/ch32v307/wch-riscv.cfg index 0d24d16ca..aa35aa9c5 100644 --- a/hw/bsp/ch32v307/wch-riscv.cfg +++ b/hw/bsp/ch32v307/wch-riscv.cfg @@ -1,13 +1,15 @@ -#interface wlink -adapter driver wlink -wlink_set -set _CHIPNAME riscv -jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001 +adapter driver wlinke +adapter speed 6000 +transport select sdi + +wlink_set_address 0x00000000 +set _CHIPNAME wch_riscv +sdi newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001 set _TARGETNAME $_CHIPNAME.cpu -target create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME -$_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1 +target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME +$_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 10000 -work-area-backup 1 set _FLASHNAME $_CHIPNAME.flash flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0 diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index df4f616ef..6eef5b88b 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -440,6 +440,7 @@ function(family_flash_openocd TARGET) endfunction() # Add flash openocd-wch target +# compiled from https://github.com/hathach/riscv-openocd-wch or https://github.com/dragonlock2/miscboards/blob/main/wch/SDK/riscv-openocd.tar.xz function(family_flash_openocd_wch TARGET) if (NOT DEFINED OPENOCD) set(OPENOCD $ENV{HOME}/app/riscv-openocd-wch/src/openocd) diff --git a/hw/bsp/fomu/family.mk b/hw/bsp/fomu/family.mk index 78f20d7db..69a546964 100644 --- a/hw/bsp/fomu/family.mk +++ b/hw/bsp/fomu/family.mk @@ -1,9 +1,5 @@ -# Toolchain from https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack -CROSS_COMPILE = riscv-none-embed- - # Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack -# CROSS_COMPILE = riscv-none-elf- -# -march=rv32i_zicsr +CROSS_COMPILE = riscv-none-elf- CPU_CORE ?= rv32i-ilp32 diff --git a/hw/bsp/gd32vf103/family.mk b/hw/bsp/gd32vf103/family.mk index 646564eae..48588886c 100644 --- a/hw/bsp/gd32vf103/family.mk +++ b/hw/bsp/gd32vf103/family.mk @@ -4,11 +4,8 @@ # Toolchain from https://nucleisys.com/download.php #CROSS_COMPILE ?= riscv-nuclei-elf- -# Toolchain from https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack -CROSS_COMPILE ?= riscv-none-embed- - # Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack -# CROSS_COMPILE ?= riscv-none-elf- +CROSS_COMPILE ?= riscv-none-elf- # Submodules NUCLEI_SDK = hw/mcu/gd/nuclei-sdk @@ -22,8 +19,6 @@ STARTUP_ASM = $(GD32VF103_SDK_SOC)/Common/Source/GCC include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= rv32imac-ilp32 -# -march=rv32imac_zicsr - CFLAGS += \ -mcmodel=medlow \ -mstrict-align \ diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index 256c46696..83f625e21 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -201,6 +201,14 @@ void dcd_disconnect(uint8_t rhport) { USBOTG_FS->BASE_CTRL &= ~USBFS_CTRL_DEV_PUEN; } +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) { (void) rhport; if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && -- cgit v1.3.1 From ab5f2768773634efe8c79add7e009e2e2ca63279 Mon Sep 17 00:00:00 2001 From: Matthew Tran Date: Fri, 17 May 2024 09:52:06 -0700 Subject: fix ep0 stall not clearing --- src/portable/wch/dcd_ch32_usbfs.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/portable') diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index 83f625e21..3af3ff6d7 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -148,6 +148,8 @@ void dcd_int_handler(uint8_t rhport) { case PID_SETUP: data.ep0_tog = true; + dcd_edpt_clear_stall(rhport, tu_edpt_addr(0, TUSB_DIR_IN)); // setup clears stall + dcd_edpt_clear_stall(rhport, tu_edpt_addr(0, TUSB_DIR_OUT)); dcd_event_setup_received(rhport, &data.buffer[0][TUSB_DIR_OUT][0], true); break; } @@ -261,10 +263,12 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to uint8_t dir = tu_edpt_dir(ep_addr); struct usb_xfer *xfer = &data.xfer[ep][dir]; + dcd_int_disable(rhport); xfer->valid = true; xfer->buffer = buffer; xfer->len = total_bytes; xfer->processed_len = 0; + dcd_int_enable(rhport); if (dir == TUSB_DIR_IN) { update_in(rhport, ep, true); -- cgit v1.3.1 From 5fee292606e4c5502b2172328c02d5df24eb0c7c Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 17 May 2024 16:13:59 +0700 Subject: temp code --- hw/bsp/ch32v307/family.c | 25 +++++++++++++++++++++++++ hw/bsp/ch32v307/family.cmake | 23 ++++++++++++++--------- src/common/tusb_mcu.h | 4 ++-- src/portable/wch/ch32_usbfs_reg.h | 9 ++++++++- src/portable/wch/dcd_ch32_usbfs.c | 2 +- 5 files changed, 50 insertions(+), 13 deletions(-) (limited to 'src/portable') diff --git a/hw/bsp/ch32v307/family.c b/hw/bsp/ch32v307/family.c index 245fa5674..50e48e7df 100644 --- a/hw/bsp/ch32v307/family.c +++ b/hw/bsp/ch32v307/family.c @@ -46,6 +46,18 @@ __attribute__ ((used)) void USBHS_IRQHandler_impl (void) tud_int_handler(0); } + +void OTG_FS_IRQHandler (void) __attribute__((naked)); +void OTG_FS_IRQHandler (void) +{ + __asm volatile ("call OTG_FS_IRQHandler_impl; mret"); +} + +__attribute__ ((used)) void OTG_FS_IRQHandler_impl (void) +{ + tud_int_handler(0); +} + //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ @@ -72,6 +84,7 @@ void board_init(void) { usart_printf_init(115200); + #if 0 RCC_USBCLK48MConfig(RCC_USBCLK48MCLKSource_USBPHY); RCC_USBHSPLLCLKConfig(RCC_HSBHSPLLCLKSource_HSE); RCC_USBHSConfig(RCC_USBPLL_Div2); @@ -79,6 +92,18 @@ void board_init(void) { RCC_USBHSPHYPLLALIVEcmd(ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_USBHS, ENABLE); + #else + uint8_t otg_div; + switch (SystemCoreClock) { + case 48000000: otg_div = RCC_OTGFSCLKSource_PLLCLK_Div1; break; + case 96000000: otg_div = RCC_OTGFSCLKSource_PLLCLK_Div2; break; + case 144000000: otg_div = RCC_OTGFSCLKSource_PLLCLK_Div3; break; + default: TU_ASSERT(0,); break; + } + RCC_OTGFSCLKConfig(otg_div); + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE); + #endif + GPIO_InitTypeDef GPIO_InitStructure = {0}; // LED diff --git a/hw/bsp/ch32v307/family.cmake b/hw/bsp/ch32v307/family.cmake index fb478d387..8a4bd7730 100644 --- a/hw/bsp/ch32v307/family.cmake +++ b/hw/bsp/ch32v307/family.cmake @@ -1,5 +1,6 @@ include_guard() +set(CH32_FAMILY ch32v30x) set(SDK_DIR ${TOP}/hw/mcu/wch/ch32v307/EVT/EXAM/SRC) # include board specific @@ -12,6 +13,8 @@ set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TO set(FAMILY_MCUS CH32V307 CACHE INTERNAL "") set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") +# Port0 Fullspeed, Port1 Highspeed + #------------------------------------ # BOARD_TARGET #------------------------------------ @@ -27,18 +30,18 @@ function(add_board_target BOARD_TARGET) set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED STARTUP_FILE_GNU) - set(STARTUP_FILE_GNU ${SDK_DIR}/Startup/startup_ch32v30x_D8C.S) + set(STARTUP_FILE_GNU ${SDK_DIR}/Startup/startup_${CH32_FAMILY}_D8C.S) endif () set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) add_library(${BOARD_TARGET} STATIC ${SDK_DIR}/Core/core_riscv.c - ${SDK_DIR}/Peripheral/src/ch32v30x_gpio.c - ${SDK_DIR}/Peripheral/src/ch32v30x_misc.c - ${SDK_DIR}/Peripheral/src/ch32v30x_rcc.c - ${SDK_DIR}/Peripheral/src/ch32v30x_usart.c - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ch32v30x_it.c - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_ch32v30x.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c + ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_usart.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${CH32_FAMILY}_it.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_${CH32_FAMILY}.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${BOARD_TARGET} PUBLIC @@ -46,7 +49,8 @@ function(add_board_target BOARD_TARGET) ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ) target_compile_definitions(${BOARD_TARGET} PUBLIC - BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + #BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED ) update_board(${BOARD_TARGET}) @@ -100,7 +104,8 @@ function(family_configure_example TARGET RTOS) # Add TinyUSB target and port source family_add_tinyusb(${TARGET} OPT_MCU_CH32V307 ${RTOS}) target_sources(${TARGET}-tinyusb PUBLIC - ${TOP}/src/portable/wch/dcd_ch32_usbhs.c + #${TOP}/src/portable/wch/dcd_ch32_usbhs.c + ${TOP}/src/portable/wch/dcd_ch32_usbfs.c ) target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index eab112015..e313fea05 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -404,8 +404,8 @@ //------------- WCH -------------// #elif TU_CHECK_MCU(OPT_MCU_CH32V307) - #define TUP_DCD_ENDPOINT_MAX 16 - #define TUP_RHPORT_HIGHSPEED 1 + #define TUP_DCD_ENDPOINT_MAX 8 +// #define TUP_RHPORT_HIGHSPEED 1 #elif TU_CHECK_MCU(OPT_MCU_CH32F20X) #define TUP_DCD_ENDPOINT_MAX 16 diff --git a/src/portable/wch/ch32_usbfs_reg.h b/src/portable/wch/ch32_usbfs_reg.h index 3b8e49ae2..d5341f3a8 100644 --- a/src/portable/wch/ch32_usbfs_reg.h +++ b/src/portable/wch/ch32_usbfs_reg.h @@ -1,8 +1,15 @@ #ifndef USB_CH32_USBFS_REG_H #define USB_CH32_USBFS_REG_H -#if (CFG_TUSB_MCU == OPT_MCU_CH32V20X) +#if (CFG_TUSB_MCU == OPT_MCU_CH32V307) +#include +#define USBHD_IRQn OTG_FS_IRQn + +#elif (CFG_TUSB_MCU == OPT_MCU_CH32V20X) #include + +#elif (CFG_TUSB_MCU == OPT_MCU_CH32F20X) +#include #endif // CTRL diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index 3af3ff6d7..3e4b6cae5 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -1,6 +1,6 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32V20X) +#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32V20X || CFG_TUSB_MCU == OPT_MCU_CH32V307) #include #include "device/dcd.h" -- cgit v1.3.1 From b19295c1c15de676e7cebd5bd5b6aa53887c6a56 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 20 May 2024 17:26:04 +0700 Subject: use correct wch usbhs, usbfs for ch32v307 using CFG_TUD_MAX_SPEED --- examples/build_system/make/rules.mk | 11 ++++++ hw/bsp/ch32v20x/family.mk | 10 +---- hw/bsp/ch32v307/family.c | 77 ++++++++++++------------------------- hw/bsp/ch32v307/family.cmake | 27 +++++++------ hw/bsp/ch32v307/family.mk | 61 +++++++++++++---------------- src/common/tusb_mcu.h | 16 ++++++-- src/portable/wch/ch32_usbhs_reg.h | 4 +- src/portable/wch/dcd_ch32_usbfs.c | 3 +- src/portable/wch/dcd_ch32_usbhs.c | 6 +-- 9 files changed, 98 insertions(+), 117 deletions(-) (limited to 'src/portable') diff --git a/examples/build_system/make/rules.mk b/examples/build_system/make/rules.mk index 7b6b339ed..102c6db0c 100644 --- a/examples/build_system/make/rules.mk +++ b/examples/build_system/make/rules.mk @@ -134,6 +134,17 @@ OPENOCD_OPTION ?= flash-openocd: $(BUILD)/$(PROJECT).elf openocd $(OPENOCD_OPTION) -c "program $< verify reset exit" +# --------------- openocd-wch ----------------- +# wch-linke is not supported yet in official openOCD yet. We need to either use +# 1. download openocd as part of mounriver studio http://www.mounriver.com/download or +# 2. compiled from https://github.com/hathach/riscv-openocd-wch or +# https://github.com/dragonlock2/miscboards/blob/main/wch/SDK/riscv-openocd.tar.xz +# with ./configure --disable-werror --enable-wlinke --enable-ch347=no +OPENOCD_WCH ?= /home/${USER}/app/riscv-openocd-wch/src/openocd +OPENOCD_WCH_OPTION ?= +flash-openocd-wch: $(BUILD)/$(PROJECT).elf + $(OPENOCD_WCH) $(OPENOCD_WCH_OPTION) -c init -c halt -c "flash write_image $<" -c reset -c exit + # --------------- dfu-util ----------------- DFU_UTIL_OPTION ?= -a 0 flash-dfu-util: $(BUILD)/$(PROJECT).bin diff --git a/hw/bsp/ch32v20x/family.mk b/hw/bsp/ch32v20x/family.mk index 6b09fdac7..5c8b31a1c 100644 --- a/hw/bsp/ch32v20x/family.mk +++ b/hw/bsp/ch32v20x/family.mk @@ -16,8 +16,6 @@ CPU_CORE ?= rv32imac-ilp32 CFLAGS += \ -mcmodel=medany \ - -ffunction-sections \ - -fdata-sections \ -ffat-lto-objects \ -flto \ -DCH32V20x_${MCU_VARIANT} \ @@ -46,9 +44,5 @@ INC += \ FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V -# wch-link is not supported yet in official openOCD yet. We need to either use -# 1. download openocd as part of mounriver studio http://www.mounriver.com/download or -# 2. compiled from modified source https://github.com/dragonlock2/miscboards/blob/main/wch/SDK/riscv-openocd.tar.xz -OPENOCD ?= $(HOME)/app/riscv-openocd-wch/src/openocd -flash: $(BUILD)/$(PROJECT).elf - $(OPENOCD) -f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg -c init -c halt -c "flash write_image $<" -c reset -c exit +OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg +flash: flash-openocd-wch diff --git a/hw/bsp/ch32v307/family.c b/hw/bsp/ch32v307/family.c index 50e48e7df..fe37ea8e3 100644 --- a/hw/bsp/ch32v307/family.c +++ b/hw/bsp/ch32v307/family.c @@ -35,41 +35,31 @@ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ -void USBHS_IRQHandler (void) __attribute__((naked)); -void USBHS_IRQHandler (void) -{ - __asm volatile ("call USBHS_IRQHandler_impl; mret"); -} +// TODO maybe having FS as port0, HS as port1 -__attribute__ ((used)) void USBHS_IRQHandler_impl (void) -{ +__attribute__((interrupt)) void USBHS_IRQHandler(void) { + #if CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED tud_int_handler(0); + #endif } - -void OTG_FS_IRQHandler (void) __attribute__((naked)); -void OTG_FS_IRQHandler (void) -{ - __asm volatile ("call OTG_FS_IRQHandler_impl; mret"); -} - -__attribute__ ((used)) void OTG_FS_IRQHandler_impl (void) -{ +__attribute__((interrupt)) void OTG_FS_IRQHandler(void) { + #if CFG_TUD_MAX_SPEED == OPT_MODE_FULL_SPEED tud_int_handler(0); + #endif } //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM //--------------------------------------------------------------------+ -uint32_t SysTick_Config(uint32_t ticks) -{ +uint32_t SysTick_Config(uint32_t ticks) { NVIC_EnableIRQ(SysTicK_IRQn); - SysTick->CTLR=0; - SysTick->SR=0; - SysTick->CNT=0; - SysTick->CMP=ticks-1; - SysTick->CTLR=0xF; + SysTick->CTLR = 0; + SysTick->SR = 0; + SysTick->CNT = 0; + SysTick->CMP = ticks - 1; + SysTick->CTLR = 0xF; return 0; } @@ -82,17 +72,17 @@ void board_init(void) { SysTick_Config(SystemCoreClock / 1000); #endif - usart_printf_init(115200); + usart_printf_init(115200); - #if 0 +#if CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED + // Use Highspeed USB RCC_USBCLK48MConfig(RCC_USBCLK48MCLKSource_USBPHY); RCC_USBHSPLLCLKConfig(RCC_HSBHSPLLCLKSource_HSE); RCC_USBHSConfig(RCC_USBPLL_Div2); RCC_USBHSPLLCKREFCLKConfig(RCC_USBHSPLLCKREFCLK_4M); RCC_USBHSPHYPLLALIVEcmd(ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_USBHS, ENABLE); - - #else +#else uint8_t otg_div; switch (SystemCoreClock) { case 48000000: otg_div = RCC_OTGFSCLKSource_PLLCLK_Div1; break; @@ -102,7 +92,7 @@ void board_init(void) { } RCC_OTGFSCLKConfig(otg_div); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE); - #endif +#endif GPIO_InitTypeDef GPIO_InitStructure = {0}; @@ -127,24 +117,14 @@ void board_init(void) { } #if CFG_TUSB_OS == OPT_OS_NONE - volatile uint32_t system_ticks = 0; -/* Small workaround to support HW stack save/restore */ -void SysTick_Handler (void) __attribute__((naked)); -void SysTick_Handler (void) -{ - __asm volatile ("call SysTick_Handler_impl; mret"); -} - -__attribute__((used)) void SysTick_Handler_impl (void) -{ +__attribute__((interrupt)) void SysTick_Handler(void) { SysTick->SR = 0; system_ticks++; } -uint32_t board_millis (void) -{ +uint32_t board_millis(void) { return system_ticks; } @@ -154,36 +134,29 @@ uint32_t board_millis (void) // Board porting API //--------------------------------------------------------------------+ -void board_led_write (bool state) -{ +void board_led_write(bool state) { GPIO_WriteBit(LED_PORT, LED_PIN, state); } -uint32_t board_button_read (void) -{ +uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == GPIO_ReadInputDataBit(BUTTON_PORT, BUTTON_PIN); } -int board_uart_read (uint8_t *buf, int len) -{ +int board_uart_read(uint8_t* buf, int len) { (void) buf; (void) len; return 0; } -int board_uart_write (void const *buf, int len) -{ +int board_uart_write(void const* buf, int len) { int txsize = len; - while ( txsize-- ) - { + while (txsize--) { uart_write(*(uint8_t const*) buf); buf++; } return len; } - - #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number diff --git a/hw/bsp/ch32v307/family.cmake b/hw/bsp/ch32v307/family.cmake index 8a4bd7730..fd475c987 100644 --- a/hw/bsp/ch32v307/family.cmake +++ b/hw/bsp/ch32v307/family.cmake @@ -1,7 +1,8 @@ include_guard() set(CH32_FAMILY ch32v30x) -set(SDK_DIR ${TOP}/hw/mcu/wch/ch32v307/EVT/EXAM/SRC) +set(SDK_DIR ${TOP}/hw/mcu/wch/ch32v307) +set(SDK_SRC_DIR ${SDK_DIR}/EVT/EXAM/SRC) # include board specific include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) @@ -13,7 +14,10 @@ set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TO set(FAMILY_MCUS CH32V307 CACHE INTERNAL "") set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") -# Port0 Fullspeed, Port1 Highspeed +# default to highspeed +if (NOT DEFINED SPEED) + set(SPEED high) +endif() #------------------------------------ # BOARD_TARGET @@ -30,27 +34,26 @@ function(add_board_target BOARD_TARGET) set(LD_FILE_Clang ${LD_FILE_GNU}) if (NOT DEFINED STARTUP_FILE_GNU) - set(STARTUP_FILE_GNU ${SDK_DIR}/Startup/startup_${CH32_FAMILY}_D8C.S) + set(STARTUP_FILE_GNU ${SDK_SRC_DIR}/Startup/startup_${CH32_FAMILY}_D8C.S) endif () set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) add_library(${BOARD_TARGET} STATIC - ${SDK_DIR}/Core/core_riscv.c - ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c - ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c - ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c - ${SDK_DIR}/Peripheral/src/${CH32_FAMILY}_usart.c + ${SDK_SRC_DIR}/Core/core_riscv.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_usart.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${CH32_FAMILY}_it.c ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_${CH32_FAMILY}.c ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${BOARD_TARGET} PUBLIC - ${SDK_DIR}/Peripheral/inc + ${SDK_SRC_DIR}/Peripheral/inc ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ) target_compile_definitions(${BOARD_TARGET} PUBLIC - #BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED - BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED + BOARD_TUD_MAX_SPEED=$,OPT_MODE_HIGH_SPEED,OPT_MODE_FULL_SPEED> ) update_board(${BOARD_TARGET}) @@ -104,7 +107,7 @@ function(family_configure_example TARGET RTOS) # Add TinyUSB target and port source family_add_tinyusb(${TARGET} OPT_MCU_CH32V307 ${RTOS}) target_sources(${TARGET}-tinyusb PUBLIC - #${TOP}/src/portable/wch/dcd_ch32_usbhs.c + ${TOP}/src/portable/wch/dcd_ch32_usbhs.c ${TOP}/src/portable/wch/dcd_ch32_usbfs.c ) target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) diff --git a/hw/bsp/ch32v307/family.mk b/hw/bsp/ch32v307/family.mk index df9ded4a0..2dbe0c46a 100644 --- a/hw/bsp/ch32v307/family.mk +++ b/hw/bsp/ch32v307/family.mk @@ -7,63 +7,54 @@ # Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack CROSS_COMPILE ?= riscv-none-elf- -# Submodules -CH32V307_SDK = hw/mcu/wch/ch32v307 - -# WCH-SDK paths -CH32V307_SDK_SRC = $(CH32V307_SDK)/EVT/EXAM/SRC +CH32_FAMILY = ch32v30x +SDK_DIR = hw/mcu/wch/ch32v307 +SDK_SRC_DIR = $(SDK_DIR)/EVT/EXAM/SRC include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= rv32imac-ilp32 +# default to use high speed port, unless specified in board.mk or command line +SPEED ?= high + CFLAGS += \ -flto \ -msmall-data-limit=8 \ - -mno-save-restore -Os \ + -mno-save-restore \ -fmessage-length=0 \ -fsigned-char \ - -ffunction-sections \ - -fdata-sections \ -DCFG_TUSB_MCU=OPT_MCU_CH32V307 \ - -Xlinker --gc-sections \ - -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + +ifeq ($(SPEED),high) + CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + $(info "Using USBHS driver for HighSpeed mode") +else + CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED + $(info "Using USBFS driver for FullSpeed mode") +endif LDFLAGS_GCC += \ -nostdlib -nostartfiles \ - --specs=nosys.specs --specs=nano.specs + --specs=nosys.specs --specs=nano.specs \ SRC_C += \ src/portable/wch/dcd_ch32_usbhs.c \ - $(CH32V307_SDK_SRC)/Core/core_riscv.c \ - $(CH32V307_SDK_SRC)/Peripheral/src/ch32v30x_gpio.c \ - $(CH32V307_SDK_SRC)/Peripheral/src/ch32v30x_misc.c \ - $(CH32V307_SDK_SRC)/Peripheral/src/ch32v30x_rcc.c \ - $(CH32V307_SDK_SRC)/Peripheral/src/ch32v30x_usart.c + src/portable/wch/dcd_ch32_usbfs.c \ + $(SDK_SRC_DIR)/Core/core_riscv.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_gpio.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_misc.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_rcc.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_usart.c SRC_S += \ - $(CH32V307_SDK_SRC)/Startup/startup_ch32v30x_D8C.S + $(SDK_SRC_DIR)/Startup/startup_${CH32_FAMILY}_D8C.S INC += \ $(TOP)/$(BOARD_PATH) \ - $(TOP)/$(CH32V307_SDK_SRC)/Peripheral/inc + $(TOP)/$(SDK_SRC_DIR)/Peripheral/inc # For freeRTOS port source FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V -# wch-link is not supported yet in official openOCD yet. We need to either use -# 1. download openocd as part of mounriver studio http://www.mounriver.com/download or -# 2. compiled from modified source https://github.com/kprasadvnsi/riscv-openocd-wch -# -# Note: For Linux, somehow openocd in mounriver studio does not seem to have wch-link enable, -# therefore we need to compile it from source as follows: -# git clone https://github.com/kprasadvnsi/riscv-openocd-wch -# cd riscv-openocd-wch -# ./bootstrap -# ./configure CFLAGS="-Wno-error" --enable-wlink -# make -# openocd binaries will be generated in riscv-openocd-wch/src - -# flash target ROM bootloader -OPENOCD_WCH = /home/${USER}/app/riscv-openocd-wch/src/openocd -flash: $(BUILD)/$(PROJECT).elf - $(OPENOCD_WCH) -f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg -c init -c halt -c "program $<" -c wlink_reset_resume -c exit +OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg +flash: flash-openocd-wch diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index e313fea05..d928e44e8 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -404,14 +404,22 @@ //------------- WCH -------------// #elif TU_CHECK_MCU(OPT_MCU_CH32V307) - #define TUP_DCD_ENDPOINT_MAX 8 -// #define TUP_RHPORT_HIGHSPEED 1 + // v307 support both FS and HS + #define TUP_USBIP_WCH_USBHS + #define TUP_USBIP_WCH_USBFS + + #define TUP_RHPORT_HIGHSPEED 1 // default to highspeed + #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED ? 16 : 8) #elif TU_CHECK_MCU(OPT_MCU_CH32F20X) - #define TUP_DCD_ENDPOINT_MAX 16 - #define TUP_RHPORT_HIGHSPEED 1 + #define TUP_USBIP_WCH_USBHS + #define TUP_USBIP_WCH_USBFS + + #define TUP_RHPORT_HIGHSPEED 1 // default to highspeed + #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED ? 16 : 8) #elif TU_CHECK_MCU(OPT_MCU_CH32V20X) + #define TUP_USBIP_WCH_USBFS #define TUP_DCD_ENDPOINT_MAX 8 #endif diff --git a/src/portable/wch/ch32_usbhs_reg.h b/src/portable/wch/ch32_usbhs_reg.h index 9b956231f..6ae91ec71 100644 --- a/src/portable/wch/ch32_usbhs_reg.h +++ b/src/portable/wch/ch32_usbhs_reg.h @@ -2,9 +2,9 @@ #define _USB_CH32_USBHS_REG_H #if (CFG_TUSB_MCU == OPT_MCU_CH32V307) -#include + #include #elif (CFG_TUSB_MCU == OPT_MCU_CH32F20X) -#include + #include #endif /******************* GLOBAL ******************/ diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index 3e4b6cae5..413fe92c9 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -1,6 +1,7 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32V20X || CFG_TUSB_MCU == OPT_MCU_CH32V307) +// Note: CH32 can have both USB FS and HS, only use this driver if CFG_TUD_MAX_SPEED is full speed +#if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBFS) && (CFG_TUD_MAX_SPEED == OPT_MODE_FULL_SPEED) #include #include "device/dcd.h" diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c index 68e2179e9..9a12fc97f 100644 --- a/src/portable/wch/dcd_ch32_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -26,11 +26,11 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && ((CFG_TUSB_MCU == OPT_MCU_CH32V307) || (CFG_TUSB_MCU == OPT_MCU_CH32F20X)) -#include "device/dcd.h" - +// Note: CH32 can have both USB FS and HS, only use this driver if CFG_TUD_MAX_SPEED is high speed +#if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBHS) && (CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED) #include "ch32_usbhs_reg.h" +#include "device/dcd.h" // Max number of bi-directional endpoints including EP0 #define EP_MAX 16 -- cgit v1.3.1 From 07d879378f052386699aba1eb41f04d4d32fb865 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 20 May 2024 17:32:40 +0700 Subject: code format add missing MIT license --- .idea/cmake.xml | 2 + src/portable/wch/ch32_usbfs_reg.h | 41 +++- src/portable/wch/ch32_usbhs_reg.h | 37 ++- src/portable/wch/dcd_ch32_usbfs.c | 482 ++++++++++++++++++++------------------ 4 files changed, 323 insertions(+), 239 deletions(-) (limited to 'src/portable') diff --git a/.idea/cmake.xml b/.idea/cmake.xml index a34f19e1f..d96b46853 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -132,6 +132,8 @@ + + \ No newline at end of file diff --git a/src/portable/wch/ch32_usbfs_reg.h b/src/portable/wch/ch32_usbfs_reg.h index d5341f3a8..0a50a6169 100644 --- a/src/portable/wch/ch32_usbfs_reg.h +++ b/src/portable/wch/ch32_usbfs_reg.h @@ -1,15 +1,42 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 Matthew Tran + * Copyright (c) 2024 hathach + * + * 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. + */ + #ifndef USB_CH32_USBFS_REG_H #define USB_CH32_USBFS_REG_H -#if (CFG_TUSB_MCU == OPT_MCU_CH32V307) -#include -#define USBHD_IRQn OTG_FS_IRQn +#if CFG_TUSB_MCU == OPT_MCU_CH32V307 + #include + #define USBHD_IRQn OTG_FS_IRQn -#elif (CFG_TUSB_MCU == OPT_MCU_CH32V20X) -#include +#elif CFG_TUSB_MCU == OPT_MCU_CH32V20X + #include -#elif (CFG_TUSB_MCU == OPT_MCU_CH32F20X) -#include +#elif CFG_TUSB_MCU == OPT_MCU_CH32F20X + #include #endif // CTRL diff --git a/src/portable/wch/ch32_usbhs_reg.h b/src/portable/wch/ch32_usbhs_reg.h index 6ae91ec71..a3a41bb6a 100644 --- a/src/portable/wch/ch32_usbhs_reg.h +++ b/src/portable/wch/ch32_usbhs_reg.h @@ -1,9 +1,36 @@ -#ifndef _USB_CH32_USBHS_REG_H -#define _USB_CH32_USBHS_REG_H - -#if (CFG_TUSB_MCU == OPT_MCU_CH32V307) +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 Matthew Tran + * Copyright (c) 2024 hathach + * + * 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. + */ + +#ifndef USB_CH32_USBHS_REG_H +#define USB_CH32_USBHS_REG_H + +#if CFG_TUSB_MCU == OPT_MCU_CH32V307 #include -#elif (CFG_TUSB_MCU == OPT_MCU_CH32F20X) +#elif CFG_TUSB_MCU == OPT_MCU_CH32F20X #include #endif diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index 413fe92c9..dafe4414e 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -1,9 +1,35 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 Matthew Tran + * Copyright (c) 2024 hathach + * + * 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" // Note: CH32 can have both USB FS and HS, only use this driver if CFG_TUD_MAX_SPEED is full speed #if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBFS) && (CFG_TUD_MAX_SPEED == OPT_MODE_FULL_SPEED) -#include #include "device/dcd.h" #include "ch32_usbfs_reg.h" @@ -17,301 +43,303 @@ /* private data */ struct usb_xfer { - bool valid; - uint8_t *buffer; - size_t len; - size_t processed_len; - size_t max_size; + bool valid; + uint8_t* buffer; + size_t len; + size_t processed_len; + size_t max_size; }; static struct { - bool ep0_tog; - bool isochronous[EP_MAX]; - struct usb_xfer xfer[EP_MAX][2]; - TU_ATTR_ALIGNED(4) uint8_t buffer[EP_MAX][2][64]; - TU_ATTR_ALIGNED(4) struct { - // OUT transfers >64 bytes will overwrite queued IN data! - uint8_t out[64]; - uint8_t in[1023]; - uint8_t pad; - } ep3_buffer; + bool ep0_tog; + bool isochronous[EP_MAX]; + struct usb_xfer xfer[EP_MAX][2]; + TU_ATTR_ALIGNED(4) uint8_t buffer[EP_MAX][2][64]; + TU_ATTR_ALIGNED(4) struct { + // OUT transfers >64 bytes will overwrite queued IN data! + uint8_t out[64]; + uint8_t in[1023]; + uint8_t pad; + } ep3_buffer; } data; /* private helpers */ static void update_in(uint8_t rhport, uint8_t ep, bool force) { - struct usb_xfer *xfer = &data.xfer[ep][TUSB_DIR_IN]; - if (xfer->valid) { - if (force || xfer->len) { - size_t len = TU_MIN(xfer->max_size, xfer->len); - if (ep == 0) { - memcpy(data.buffer[ep][TUSB_DIR_OUT], xfer->buffer, len); // ep0 uses same chunk - } else if (ep == 3) { - memcpy(data.ep3_buffer.in, xfer->buffer, len); - } else { - memcpy(data.buffer[ep][TUSB_DIR_IN], xfer->buffer, len); - } - xfer->buffer += len; - xfer->len -= len; - xfer->processed_len += len; - - EP_TX_LEN(ep) = len; - if (ep == 0) { - EP_TX_CTRL(0) = USBFS_EP_T_RES_ACK | (data.ep0_tog ? USBFS_EP_T_TOG : 0); - data.ep0_tog = !data.ep0_tog; - } else if (data.isochronous[ep]) { - EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_NYET; - } else { - EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_ACK; - } - } else { - xfer->valid = false; - EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_NAK; - dcd_event_xfer_complete(rhport, ep | TUSB_DIR_IN_MASK, xfer->processed_len, - XFER_RESULT_SUCCESS, true); - } + struct usb_xfer* xfer = &data.xfer[ep][TUSB_DIR_IN]; + if (xfer->valid) { + if (force || xfer->len) { + size_t len = TU_MIN(xfer->max_size, xfer->len); + if (ep == 0) { + memcpy(data.buffer[ep][TUSB_DIR_OUT], xfer->buffer, len); // ep0 uses same chunk + } else if (ep == 3) { + memcpy(data.ep3_buffer.in, xfer->buffer, len); + } else { + memcpy(data.buffer[ep][TUSB_DIR_IN], xfer->buffer, len); + } + xfer->buffer += len; + xfer->len -= len; + xfer->processed_len += len; + + EP_TX_LEN(ep) = len; + if (ep == 0) { + EP_TX_CTRL(0) = USBFS_EP_T_RES_ACK | (data.ep0_tog ? USBFS_EP_T_TOG : 0); + data.ep0_tog = !data.ep0_tog; + } else if (data.isochronous[ep]) { + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_NYET; + } else { + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_ACK; + } + } else { + xfer->valid = false; + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK)) | USBFS_EP_T_RES_NAK; + dcd_event_xfer_complete( + rhport, ep | TUSB_DIR_IN_MASK, xfer->processed_len, + XFER_RESULT_SUCCESS, true); } + } } static void update_out(uint8_t rhport, uint8_t ep, size_t rx_len) { - struct usb_xfer *xfer = &data.xfer[ep][TUSB_DIR_OUT]; - if (xfer->valid) { - size_t len = TU_MIN(xfer->max_size, TU_MIN(xfer->len, rx_len)); - if (ep == 3) { - memcpy(xfer->buffer, data.ep3_buffer.out, len); - } else { - memcpy(xfer->buffer, data.buffer[ep][TUSB_DIR_OUT], len); - } - xfer->buffer += len; - xfer->len -= len; - xfer->processed_len += len; - - if (xfer->len == 0 || len < xfer->max_size) { - xfer->valid = false; - dcd_event_xfer_complete(rhport, ep, xfer->processed_len, XFER_RESULT_SUCCESS, true); - } - - if (ep == 0) { - EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; - } + struct usb_xfer* xfer = &data.xfer[ep][TUSB_DIR_OUT]; + if (xfer->valid) { + size_t len = TU_MIN(xfer->max_size, TU_MIN(xfer->len, rx_len)); + if (ep == 3) { + memcpy(xfer->buffer, data.ep3_buffer.out, len); + } else { + memcpy(xfer->buffer, data.buffer[ep][TUSB_DIR_OUT], len); } -} + xfer->buffer += len; + xfer->len -= len; + xfer->processed_len += len; -/* public functions */ -void dcd_init(uint8_t rhport) { - // init registers - USBOTG_FS->BASE_CTRL = USBFS_CTRL_SYS_CTRL | USBFS_CTRL_INT_BUSY | USBFS_CTRL_DMA_EN; - USBOTG_FS->UDEV_CTRL = USBFS_UDEV_CTRL_PD_DIS | USBFS_UDEV_CTRL_PORT_EN; - USBOTG_FS->DEV_ADDR = 0x00; - - USBOTG_FS->INT_FG = 0xFF; - USBOTG_FS->INT_EN = USBFS_INT_EN_BUS_RST | USBFS_INT_EN_TRANSFER | USBFS_INT_EN_SUSPEND; - - // setup endpoint 0 - EP_DMA(0) = (uint32_t) &data.buffer[0][0]; - EP_TX_LEN(0) = 0; - EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; - EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + if (xfer->len == 0 || len < xfer->max_size) { + xfer->valid = false; + dcd_event_xfer_complete(rhport, ep, xfer->processed_len, XFER_RESULT_SUCCESS, true); + } - // enable other endpoints but NAK everything - USBOTG_FS->UEP4_1_MOD = 0xCC; - USBOTG_FS->UEP2_3_MOD = 0xCC; - USBOTG_FS->UEP5_6_MOD = 0xCC; - USBOTG_FS->UEP7_MOD = 0x0C; - - for (uint8_t ep = 1; ep < EP_MAX; ep++) { - EP_DMA(ep) = (uint32_t) &data.buffer[ep][0]; - EP_TX_LEN(ep) = 0; - EP_TX_CTRL(ep) = USBFS_EP_T_AUTO_TOG | USBFS_EP_T_RES_NAK; - EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_NAK; + if (ep == 0) { + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; } - EP_DMA(3) = (uint32_t) &data.ep3_buffer.out[0]; + } +} - dcd_connect(rhport); +/* public functions */ +void dcd_init(uint8_t rhport) { + // init registers + USBOTG_FS->BASE_CTRL = USBFS_CTRL_SYS_CTRL | USBFS_CTRL_INT_BUSY | USBFS_CTRL_DMA_EN; + USBOTG_FS->UDEV_CTRL = USBFS_UDEV_CTRL_PD_DIS | USBFS_UDEV_CTRL_PORT_EN; + USBOTG_FS->DEV_ADDR = 0x00; + + USBOTG_FS->INT_FG = 0xFF; + USBOTG_FS->INT_EN = USBFS_INT_EN_BUS_RST | USBFS_INT_EN_TRANSFER | USBFS_INT_EN_SUSPEND; + + // setup endpoint 0 + EP_DMA(0) = (uint32_t) &data.buffer[0][0]; + EP_TX_LEN(0) = 0; + EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + + // enable other endpoints but NAK everything + USBOTG_FS->UEP4_1_MOD = 0xCC; + USBOTG_FS->UEP2_3_MOD = 0xCC; + USBOTG_FS->UEP5_6_MOD = 0xCC; + USBOTG_FS->UEP7_MOD = 0x0C; + + for (uint8_t ep = 1; ep < EP_MAX; ep++) { + EP_DMA(ep) = (uint32_t) &data.buffer[ep][0]; + EP_TX_LEN(ep) = 0; + EP_TX_CTRL(ep) = USBFS_EP_T_AUTO_TOG | USBFS_EP_T_RES_NAK; + EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_NAK; + } + EP_DMA(3) = (uint32_t) &data.ep3_buffer.out[0]; + + dcd_connect(rhport); } void dcd_int_handler(uint8_t rhport) { - (void) rhport; - uint8_t status = USBOTG_FS->INT_FG; - if (status & USBFS_INT_FG_TRANSFER) { - uint8_t ep = USBFS_INT_ST_MASK_UIS_ENDP(USBOTG_FS->INT_ST); - uint8_t token = USBFS_INT_ST_MASK_UIS_TOKEN(USBOTG_FS->INT_ST); - - switch (token) { - case PID_OUT: { - uint16_t rx_len = USBOTG_FS->RX_LEN; - update_out(rhport, ep, rx_len); - break; - } - - case PID_IN: - update_in(rhport, ep, false); - break; - - case PID_SETUP: - data.ep0_tog = true; - dcd_edpt_clear_stall(rhport, tu_edpt_addr(0, TUSB_DIR_IN)); // setup clears stall - dcd_edpt_clear_stall(rhport, tu_edpt_addr(0, TUSB_DIR_OUT)); - dcd_event_setup_received(rhport, &data.buffer[0][TUSB_DIR_OUT][0], true); - break; - } - - USBOTG_FS->INT_FG = USBFS_INT_FG_TRANSFER; - } else if (status & USBFS_INT_FG_BUS_RST) { + (void) rhport; + uint8_t status = USBOTG_FS->INT_FG; + if (status & USBFS_INT_FG_TRANSFER) { + uint8_t ep = USBFS_INT_ST_MASK_UIS_ENDP(USBOTG_FS->INT_ST); + uint8_t token = USBFS_INT_ST_MASK_UIS_TOKEN(USBOTG_FS->INT_ST); + + switch (token) { + case PID_OUT: { + uint16_t rx_len = USBOTG_FS->RX_LEN; + update_out(rhport, ep, rx_len); + break; + } + + case PID_IN: + update_in(rhport, ep, false); + break; + + case PID_SETUP: + // setup clears stall + EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + data.ep0_tog = true; - data.xfer[0][TUSB_DIR_OUT].max_size = 64; - data.xfer[0][TUSB_DIR_IN].max_size = 64; + dcd_event_setup_received(rhport, &data.buffer[0][TUSB_DIR_OUT][0], true); + break; + } - dcd_event_bus_signal(rhport, DCD_EVENT_BUS_RESET, true); + USBOTG_FS->INT_FG = USBFS_INT_FG_TRANSFER; + } else if (status & USBFS_INT_FG_BUS_RST) { + data.ep0_tog = true; + data.xfer[0][TUSB_DIR_OUT].max_size = 64; + data.xfer[0][TUSB_DIR_IN].max_size = 64; - USBOTG_FS->DEV_ADDR = 0x00; - EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + dcd_event_bus_signal(rhport, DCD_EVENT_BUS_RESET, true); - USBOTG_FS->INT_FG = USBFS_INT_FG_BUS_RST; - } else if (status & USBFS_INT_FG_SUSPEND) { - dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SUSPEND }; - dcd_event_handler(&event, true); - USBOTG_FS->INT_FG = USBFS_INT_FG_SUSPEND; - } + USBOTG_FS->DEV_ADDR = 0x00; + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + + USBOTG_FS->INT_FG = USBFS_INT_FG_BUS_RST; + } else if (status & USBFS_INT_FG_SUSPEND) { + dcd_event_t event = {.rhport = rhport, .event_id = DCD_EVENT_SUSPEND}; + dcd_event_handler(&event, true); + USBOTG_FS->INT_FG = USBFS_INT_FG_SUSPEND; + } } void dcd_int_enable(uint8_t rhport) { - (void) rhport; - NVIC_EnableIRQ(USBHD_IRQn); + (void) rhport; + NVIC_EnableIRQ(USBHD_IRQn); } void dcd_int_disable(uint8_t rhport) { - (void) rhport; - NVIC_DisableIRQ(USBHD_IRQn); + (void) rhport; + NVIC_DisableIRQ(USBHD_IRQn); } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { - (void) dev_addr; - dcd_edpt_xfer(rhport, 0x80, NULL, 0); // zlp status response + (void) dev_addr; + dcd_edpt_xfer(rhport, 0x80, NULL, 0); // zlp status response } void dcd_remote_wakeup(uint8_t rhport) { - (void) rhport; - // TODO optional + (void) rhport; + // TODO optional } void dcd_connect(uint8_t rhport) { - (void) rhport; - USBOTG_FS->BASE_CTRL |= USBFS_CTRL_DEV_PUEN; + (void) rhport; + USBOTG_FS->BASE_CTRL |= USBFS_CTRL_DEV_PUEN; } void dcd_disconnect(uint8_t rhport) { - (void) rhport; - USBOTG_FS->BASE_CTRL &= ~USBFS_CTRL_DEV_PUEN; + (void) rhport; + USBOTG_FS->BASE_CTRL &= ~USBFS_CTRL_DEV_PUEN; } -void dcd_sof_enable(uint8_t rhport, bool en) -{ +void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; // TODO implement later } -void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) { - (void) rhport; - if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && - request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && - request->bRequest == TUSB_REQ_SET_ADDRESS) { - USBOTG_FS->DEV_ADDR = (uint8_t) request->wValue; - } - EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; - EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const* request) { + (void) rhport; + if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && + request->bRequest == TUSB_REQ_SET_ADDRESS) { + USBOTG_FS->DEV_ADDR = (uint8_t) request->wValue; + } + EP_TX_CTRL(0) = USBFS_EP_T_RES_NAK; + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; } -bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { - (void) rhport; - uint8_t ep = tu_edpt_number(desc_ep->bEndpointAddress); - uint8_t dir = tu_edpt_dir(desc_ep->bEndpointAddress); - TU_ASSERT(ep < EP_MAX); - - data.isochronous[ep] = desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS; - data.xfer[ep][dir].max_size = tu_edpt_packet_size(desc_ep); - - if (ep != 0) { - if (dir == TUSB_DIR_OUT) { - if (data.isochronous[ep]) { - EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_NYET; - } else { - EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_ACK; - } - } else { - EP_TX_LEN(ep) = 0; - EP_TX_CTRL(ep) = USBFS_EP_T_AUTO_TOG | USBFS_EP_T_RES_NAK; - } +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_ep) { + (void) rhport; + uint8_t ep = tu_edpt_number(desc_ep->bEndpointAddress); + uint8_t dir = tu_edpt_dir(desc_ep->bEndpointAddress); + TU_ASSERT(ep < EP_MAX); + + data.isochronous[ep] = desc_ep->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS; + data.xfer[ep][dir].max_size = tu_edpt_packet_size(desc_ep); + + if (ep != 0) { + if (dir == TUSB_DIR_OUT) { + if (data.isochronous[ep]) { + EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_NYET; + } else { + EP_RX_CTRL(ep) = USBFS_EP_R_AUTO_TOG | USBFS_EP_R_RES_ACK; + } + } else { + EP_TX_LEN(ep) = 0; + EP_TX_CTRL(ep) = USBFS_EP_T_AUTO_TOG | USBFS_EP_T_RES_NAK; } - return true; + } + return true; } void dcd_edpt_close_all(uint8_t rhport) { - (void) rhport; - // TODO optional + (void) rhport; + // TODO optional } void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; - (void) ep_addr; - // TODO optional + (void) rhport; + (void) ep_addr; + // TODO optional } -bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { - (void) rhport; - uint8_t ep = tu_edpt_number(ep_addr); - uint8_t dir = tu_edpt_dir(ep_addr); - - struct usb_xfer *xfer = &data.xfer[ep][dir]; - dcd_int_disable(rhport); - xfer->valid = true; - xfer->buffer = buffer; - xfer->len = total_bytes; - xfer->processed_len = 0; - dcd_int_enable(rhport); - - if (dir == TUSB_DIR_IN) { - update_in(rhport, ep, true); - } - return true; +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { + (void) rhport; + uint8_t ep = tu_edpt_number(ep_addr); + uint8_t dir = tu_edpt_dir(ep_addr); + + struct usb_xfer* xfer = &data.xfer[ep][dir]; + dcd_int_disable(rhport); + xfer->valid = true; + xfer->buffer = buffer; + xfer->len = total_bytes; + xfer->processed_len = 0; + dcd_int_enable(rhport); + + if (dir == TUSB_DIR_IN) { + update_in(rhport, ep, true); + } + return true; } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; - uint8_t ep = tu_edpt_number(ep_addr); - uint8_t dir = tu_edpt_dir(ep_addr); - if (ep == 0) { - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(0) = USBFS_EP_R_RES_STALL; - } else { - EP_TX_LEN(0) = 0; - EP_TX_CTRL(0) = USBFS_EP_T_RES_STALL; - } + (void) rhport; + uint8_t ep = tu_edpt_number(ep_addr); + uint8_t dir = tu_edpt_dir(ep_addr); + if (ep == 0) { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(0) = USBFS_EP_R_RES_STALL; } else { - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(ep) = (EP_RX_CTRL(ep) & ~USBFS_EP_R_RES_MASK) | USBFS_EP_R_RES_STALL; - } else { - EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~USBFS_EP_T_RES_MASK) | USBFS_EP_T_RES_STALL; - } + EP_TX_LEN(0) = 0; + EP_TX_CTRL(0) = USBFS_EP_T_RES_STALL; } + } else { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep) = (EP_RX_CTRL(ep) & ~USBFS_EP_R_RES_MASK) | USBFS_EP_R_RES_STALL; + } else { + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~USBFS_EP_T_RES_MASK) | USBFS_EP_T_RES_STALL; + } + } } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; - uint8_t ep = tu_edpt_number(ep_addr); - uint8_t dir = tu_edpt_dir(ep_addr); - if (ep == 0) { - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; - } + (void) rhport; + uint8_t ep = tu_edpt_number(ep_addr); + uint8_t dir = tu_edpt_dir(ep_addr); + if (ep == 0) { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(0) = USBFS_EP_R_RES_ACK; + } + } else { + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep) = (EP_RX_CTRL(ep) & ~(USBFS_EP_R_RES_MASK | USBFS_EP_R_TOG)) | USBFS_EP_R_RES_ACK; } else { - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(ep) = (EP_RX_CTRL(ep) & ~(USBFS_EP_R_RES_MASK | USBFS_EP_R_TOG)) | USBFS_EP_R_RES_ACK; - } else { - EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK | USBFS_EP_T_TOG)) | USBFS_EP_T_RES_NAK; - } + EP_TX_CTRL(ep) = (EP_TX_CTRL(ep) & ~(USBFS_EP_T_RES_MASK | USBFS_EP_T_TOG)) | USBFS_EP_T_RES_NAK; } + } } -#endif // CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_CH32V20X) +#endif -- cgit v1.3.1 From 869e5e950c545459788cb67d9063f3489f5c5e54 Mon Sep 17 00:00:00 2001 From: dkrasutski Date: Sat, 30 Dec 2023 03:04:43 +0200 Subject: bugfix(ch32-hs-dcd): fix ch32 DATAx managment and long packet transmission --- src/portable/wch/ch32_usbhs_reg.h | 21 +-- src/portable/wch/dcd_ch32_usbhs.c | 379 ++++++++++++++++++-------------------- 2 files changed, 194 insertions(+), 206 deletions(-) (limited to 'src/portable') diff --git a/src/portable/wch/ch32_usbhs_reg.h b/src/portable/wch/ch32_usbhs_reg.h index a3a41bb6a..7428285a5 100644 --- a/src/portable/wch/ch32_usbhs_reg.h +++ b/src/portable/wch/ch32_usbhs_reg.h @@ -99,12 +99,16 @@ #define USBHS_ISO_ACT_FLAG (1 << 6) // INT_ST -#define USBHS_INT_ST_OFFSET 0x0B -#define USBHS_DEV_UIS_IS_NAK (1 << 7) -#define USBHS_DEV_UIS_TOG_OK (1 << 6) -#define MASK_UIS_TOKEN (3 << 4) -#define MASK_UIS_ENDP (0x0F) -#define MASK_UIS_H_RES (0x0F) +#define USBHS_INT_ST_OFFSET 0x0B +#define USBHS_DEV_UIS_IS_NAK (1 << 7) +#define USBHS_DEV_UIS_TOG_OK (1 << 6) +#define MASK_UIS_TOKEN (3 << 4) +#define USBHS_TOKEN_PID_OUT (0 << 4) +#define USBHS_TOKEN_PID_SOF (1 << 4) +#define USBHS_TOKEN_PID_IN (2 << 4) +#define USBHS_TOKEN_PID_SETUP (3 << 4) +#define MASK_UIS_ENDP (0x0F) +#define MASK_UIS_H_RES (0x0F) #define USBHS_TOGGLE_OK (0x40) #define USBHS_HOST_RES (0x0f) @@ -367,10 +371,5 @@ #define USBHS_UH_T_TOG_AUTO (1 << 5) #define USBHS_UH_T_DATA_NO (1 << 6) -// 00: OUT, 01:SOF, 10:IN, 11:SETUP -#define PID_OUT 0 -#define PID_SOF 1 -#define PID_IN 2 -#define PID_SETUP 3 #endif diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c index 9a12fc97f..0313c0a69 100644 --- a/src/portable/wch/dcd_ch32_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -2,6 +2,7 @@ * The MIT License (MIT) * * Copyright (c) 2022 Greg Davill + * Copyright (c) 2023 Denis Krasutski * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -33,32 +34,99 @@ #include "device/dcd.h" // Max number of bi-directional endpoints including EP0 -#define EP_MAX 16 +#define EP_MAX 16 +#define CH32_USBHS_EP0_MAX_SIZE (64) typedef struct { uint8_t *buffer; - // tu_fifo_t * ff; // TODO support dcd_edpt_xfer_fifo API uint16_t total_len; uint16_t queued_len; uint16_t max_size; - bool short_packet; + bool is_last_packet; } xfer_ctl_t; +typedef enum { + EP_RESPONSE_ACK, + EP_RESPONSE_NAK, +} ep_response_list_t; + #define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] static xfer_ctl_t xfer_status[EP_MAX][2]; -#define EP_TX_LEN(ep) *(volatile uint16_t *)((volatile uint16_t *)&(USBHSD->UEP0_TX_LEN) + (ep)*2) -#define EP_TX_CTRL(ep) *(volatile uint8_t *)((volatile uint8_t *)&(USBHSD->UEP0_TX_CTRL) + (ep)*4) -#define EP_RX_CTRL(ep) *(volatile uint8_t *)((volatile uint8_t *)&(USBHSD->UEP0_RX_CTRL) + (ep)*4) -#define EP_RX_MAX_LEN(ep) *(volatile uint16_t *)((volatile uint16_t *)&(USBHSD->UEP0_MAX_LEN) + (ep)*2) +#define EP_TX_LEN(ep) *(volatile uint16_t *)((volatile uint16_t *)&(USBHSD->UEP0_TX_LEN) + (ep) * 2) +#define EP_TX_CTRL(ep) *(volatile uint8_t *)((volatile uint8_t *)&(USBHSD->UEP0_TX_CTRL) + (ep) * 4) +#define EP_RX_CTRL(ep) *(volatile uint8_t *)((volatile uint8_t *)&(USBHSD->UEP0_RX_CTRL) + (ep) * 4) +#define EP_RX_MAX_LEN(ep) *(volatile uint16_t *)((volatile uint16_t *)&(USBHSD->UEP0_MAX_LEN) + (ep) * 2) #define EP_TX_DMA_ADDR(ep) *(volatile uint32_t *)((volatile uint32_t *)&(USBHSD->UEP1_TX_DMA) + (ep - 1)) #define EP_RX_DMA_ADDR(ep) *(volatile uint32_t *)((volatile uint32_t *)&(USBHSD->UEP1_RX_DMA) + (ep - 1)) /* Endpoint Buffer */ -TU_ATTR_ALIGNED(4) uint8_t EP0_DatabufHD[64]; // ep0(64) +TU_ATTR_ALIGNED(4) static uint8_t ep0_data_in_out_buffer[CH32_USBHS_EP0_MAX_SIZE]; + +static void ep_set_response_and_toggle(uint8_t ep_addr, ep_response_list_t response_type) { + uint8_t const ep_num = tu_edpt_number(ep_addr); + if (ep_addr & TUSB_DIR_IN_MASK) { + uint8_t response = (response_type == EP_RESPONSE_ACK) ? USBHS_EP_T_RES_ACK : USBHS_EP_T_RES_NAK; + if (ep_num == 0) { + if (response_type == EP_RESPONSE_ACK) { + if (EP_TX_LEN(ep_num) == 0) { + EP_TX_CTRL(ep_num) |= USBHS_EP_T_TOG_1; + } else { + EP_TX_CTRL(ep_num) ^= USBHS_EP_T_TOG_1; + } + } + } + EP_TX_CTRL(ep_num) = (EP_TX_CTRL(ep_num) & ~(USBHS_EP_T_RES_MASK)) | response; + } else { + uint8_t response = (response_type == EP_RESPONSE_ACK) ? USBHS_EP_R_RES_ACK : USBHS_EP_R_RES_NAK; + if (ep_num == 0) { + if (response_type == EP_RESPONSE_ACK) { + if (xfer_status[ep_num][TUSB_DIR_OUT].queued_len == 0) { + EP_RX_CTRL(ep_num) |= USBHS_EP_R_TOG_1; + } + } else { + EP_RX_CTRL(ep_num) ^= USBHS_EP_R_TOG_1; + } + } + EP_RX_CTRL(ep_num) = (EP_RX_CTRL(ep_num) & ~(USBHS_EP_R_RES_MASK)) | response; + } +} + +static void xfer_data_packet(uint8_t ep_addr, xfer_ctl_t *xfer) { + uint8_t const ep_num = tu_edpt_number(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); -volatile uint8_t USBHS_Dev_Endp0_Tog = 0x01; + if (dir == TUSB_DIR_IN) { + uint16_t remaining = xfer->total_len - xfer->queued_len; + uint16_t next_tx_size = TU_MIN(remaining, xfer->max_size); + + if (ep_num == 0) { + memcpy(ep0_data_in_out_buffer, &xfer->buffer[xfer->queued_len], next_tx_size); + } else { + EP_TX_DMA_ADDR(ep_num) = (uint32_t)&xfer->buffer[xfer->queued_len]; + } + + EP_TX_LEN(ep_num) = next_tx_size; + xfer->queued_len += next_tx_size; + if (xfer->queued_len == xfer->total_len) { + xfer->is_last_packet = true; + } + } else { /* TUSB_DIR_OUT */ + uint16_t left_to_receive = xfer->total_len - xfer->queued_len; + uint16_t max_possible_rx_size = TU_MIN(xfer->max_size, left_to_receive); + + if (max_possible_rx_size == left_to_receive) { + xfer->is_last_packet = true; + } + + if (ep_num > 0) { + EP_RX_DMA_ADDR(ep_num) = (uint32_t)&xfer->buffer[xfer->queued_len]; + EP_RX_MAX_LEN(ep_num) = max_possible_rx_size; + } + } + ep_set_response_and_toggle(ep_addr, USBHS_EP_R_RES_ACK); +} void dcd_init(uint8_t rhport) { (void)rhport; @@ -80,29 +148,23 @@ void dcd_init(uint8_t rhport) { USBHSD->INT_EN = 0; USBHSD->INT_EN = USBHS_SETUP_ACT_EN | USBHS_TRANSFER_EN | USBHS_DETECT_EN | USBHS_SUSPEND_EN; - /* ALL endpoint enable */ - USBHSD->ENDP_CONFIG = 0xffffffff; - USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN; USBHSD->ENDP_TYPE = 0x00; USBHSD->BUF_MODE = 0x00; - USBHSD->UEP0_MAX_LEN = 64; - - USBHSD->UEP0_DMA = (uint32_t)EP0_DatabufHD; - - USBHSD->UEP0_TX_LEN = 0; - USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_NAK; - USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK; - - for (int ep = 1; ep < EP_MAX; ep++) { + for (int ep = 0; ep < EP_MAX; ep++) { EP_TX_LEN(ep) = 0; EP_TX_CTRL(ep) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK; EP_RX_CTRL(ep) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; - EP_RX_MAX_LEN(ep) = 512; + EP_RX_MAX_LEN(ep) = 0; } + USBHSD->UEP0_DMA = (uint32_t)ep0_data_in_out_buffer; + USBHSD->UEP0_MAX_LEN = CH32_USBHS_EP0_MAX_SIZE; + xfer_status[0][TUSB_DIR_OUT].max_size = CH32_USBHS_EP0_MAX_SIZE; + xfer_status[0][TUSB_DIR_IN].max_size = CH32_USBHS_EP0_MAX_SIZE; + USBHSD->DEV_AD = 0; USBHSD->CONTROL |= USBHS_DEV_PU_EN; } @@ -121,6 +183,16 @@ void dcd_int_disable(uint8_t rhport) { void dcd_edpt_close_all(uint8_t rhport) { (void)rhport; + + for (size_t ep = 1; ep < EP_MAX; ep++) { + EP_TX_LEN(ep) = 0; + EP_TX_CTRL(ep) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK; + EP_RX_CTRL(ep) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; + + EP_RX_MAX_LEN(ep) = 0; + } + + USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN; } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { @@ -130,9 +202,8 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { dcd_edpt_xfer(rhport, 0x80, NULL, 0); } -void dcd_remote_wakeup(uint8_t rhport) -{ - (void) rhport; +void dcd_remote_wakeup(uint8_t rhport) { + (void)rhport; } void dcd_sof_enable(uint8_t rhport, bool en) @@ -154,246 +225,164 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *req USBHSD->DEV_AD = (uint8_t)request->wValue; } - EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK; - EP_RX_CTRL(0) = USBHS_EP_R_RES_ACK; + EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; + EP_RX_CTRL(0) = USBHS_EP_R_RES_NAK | USBHS_EP_R_TOG_0; } bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt) { (void)rhport; - uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress); - uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); + uint8_t const ep_num = tu_edpt_number(desc_edpt->bEndpointAddress); + tusb_dir_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); + + TU_ASSERT(ep_num < EP_MAX); - TU_ASSERT(epnum < EP_MAX); + if (ep_num == 0) { + return true; + } - xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, dir); + xfer_ctl_t *xfer = XFER_CTL_BASE(ep_num, dir); xfer->max_size = tu_edpt_packet_size(desc_edpt); - if (epnum != 0) { - if (tu_edpt_dir(desc_edpt->bEndpointAddress) == TUSB_DIR_OUT) { - EP_RX_CTRL(epnum) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_ACK; - } else { - EP_TX_LEN(epnum) = 0; - EP_TX_CTRL(epnum) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; + bool is_iso = (desc_edpt->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS); + if (dir == TUSB_DIR_OUT) { + USBHSD->ENDP_CONFIG |= (USBHS_EP0_R_EN << ep_num); + EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; + if (is_iso == true) { + USBHSD->ENDP_TYPE |= (USBHS_EP0_R_TYP << ep_num); + } + EP_RX_MAX_LEN(ep_num) = xfer->max_size; + } else { + USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << ep_num); + if (is_iso == true) { + USBHSD->ENDP_TYPE |= (USBHS_EP0_T_TYP << ep_num); } + EP_TX_LEN(ep_num) = 0; + EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; } return true; } -int usbd_ep_close(const uint8_t ep) { - (void)ep; +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + (void)rhport; - return 0; + uint8_t const ep_num = tu_edpt_number(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); + + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; + EP_RX_MAX_LEN(ep_num) = 0; + USBHSD->ENDP_TYPE &= ~(USBHS_EP0_R_TYP << ep_num); + USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_R_EN << ep_num); + } else { // TUSB_DIR_IN + EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; + EP_TX_LEN(ep_num) = 0; + USBHSD->ENDP_TYPE &= ~(USBHS_EP0_T_TYP << ep_num); + USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_T_EN << ep_num); + } } + void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const ep_num = tu_edpt_number(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); - if (epnum == 0) { - if (dir == TUSB_DIR_OUT) { - USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_STALL; - } else { - USBHSD->UEP0_TX_LEN = 0; - USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_STALL; - } + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep_num) = USBHS_EP_R_RES_STALL; } else { - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(epnum) = (EP_RX_CTRL(epnum) & ~USBHS_EP_R_RES_MASK) | USBHS_EP_R_RES_STALL; - - } else { - EP_TX_CTRL(epnum) = (EP_TX_CTRL(epnum) & ~USBHS_EP_T_RES_MASK) | USBHS_EP_T_RES_STALL; - } + EP_TX_LEN(0) = 0; + EP_TX_CTRL(ep_num) = USBHS_EP_T_RES_STALL; } } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const ep_num = tu_edpt_number(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); - if (epnum == 0) { - if (dir == TUSB_DIR_OUT) { - USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK; - } else { - } + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; } else { - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(epnum) = (EP_RX_CTRL(epnum) & ~(USBHS_EP_R_RES_MASK | USBHS_EP_T_TOG_MASK)) | USBHS_EP_T_RES_ACK; - - } else { - EP_TX_CTRL(epnum) = (EP_TX_CTRL(epnum) & ~(USBHS_EP_T_RES_MASK | USBHS_EP_T_TOG_MASK)) | USBHS_EP_T_RES_NAK; - } + EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_R_RES_NAK; } } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { (void)rhport; - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + uint8_t const ep_num = tu_edpt_number(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); - xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, dir); + xfer_ctl_t *xfer = XFER_CTL_BASE(ep_num, dir); xfer->buffer = buffer; - // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API xfer->total_len = total_bytes; xfer->queued_len = 0; - xfer->short_packet = false; - - // uint16_t num_packets = (total_bytes / xfer->max_size); - uint16_t short_packet_size = total_bytes % (xfer->max_size + 1); - - // Zero-size packet is special case. - if (short_packet_size == 0 || (total_bytes == 0)) { - xfer->short_packet = true; - } - - if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { - if (!total_bytes) { - xfer->short_packet = true; - if (epnum == 0) { - USBHSD->UEP0_TX_LEN = 0; - USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_ACK | (USBHS_Dev_Endp0_Tog ? USBHS_EP_T_TOG_1 : USBHS_EP_T_TOG_0); - USBHS_Dev_Endp0_Tog ^= 1; - } else { - EP_TX_LEN(epnum) = 0; - EP_TX_CTRL(epnum) = (EP_TX_CTRL(epnum) & ~(USBHS_EP_T_RES_MASK)) | USBHS_EP_T_RES_ACK; - } - } else { - if (epnum == 0) { - xfer->queued_len += short_packet_size; - memcpy(&EP0_DatabufHD[0], buffer, short_packet_size); - - USBHSD->UEP0_TX_LEN = short_packet_size; - USBHSD->UEP0_TX_CTRL = USBHS_EP_T_RES_ACK | (USBHS_Dev_Endp0_Tog ? USBHS_EP_T_TOG_1 : USBHS_EP_T_TOG_0); - USBHS_Dev_Endp0_Tog ^= 1; - } else { - xfer->queued_len += short_packet_size; - - EP_TX_DMA_ADDR(epnum) = (uint32_t)buffer; - USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << epnum); - EP_TX_LEN(epnum) = short_packet_size; - EP_TX_CTRL(epnum) = (EP_TX_CTRL(epnum) & ~(USBHS_EP_T_RES_MASK)) | USBHS_EP_T_RES_ACK; - } - } - } else { /* TUSB_DIR_OUT */ - if (epnum == 0) { - uint32_t read_count = USBHSD->RX_LEN; - read_count = TU_MIN(read_count, total_bytes); + xfer->is_last_packet = false; - if ((total_bytes == 8)) { - read_count = 8; - memcpy(buffer, &EP0_DatabufHD[0], 8); - } else { - memcpy(buffer, &EP0_DatabufHD[0], read_count); - } - } else { - EP_RX_DMA_ADDR(epnum) = (uint32_t)xfer->buffer; - USBHSD->ENDP_CONFIG |= (USBHS_EP0_R_EN << epnum); - } + xfer_data_packet(ep_addr, xfer); - // usbd_ep_read(ep_addr, buffer, total_bytes, &ret_bytes); - } return true; } - -static void receive_packet(xfer_ctl_t *xfer, uint16_t xfer_size) { - // xfer->queued_len = xfer->total_len - remaining; - - uint16_t remaining = xfer->total_len - xfer->queued_len; - uint16_t to_recv_size; - - if (remaining <= xfer->max_size) { - // Avoid buffer overflow. - to_recv_size = (xfer_size > remaining) ? remaining : xfer_size; - } else { - // Room for full packet, choose recv_size based on what the microcontroller - // claims. - to_recv_size = (xfer_size > xfer->max_size) ? xfer->max_size : xfer_size; - } - - if (to_recv_size) { - } - - xfer->queued_len += xfer_size; - - // Per USB spec, a short OUT packet (including length 0) is always - // indicative of the end of a transfer (at least for ctl, bulk, int). - xfer->short_packet = (xfer_size < xfer->max_size); -} - void dcd_int_handler(uint8_t rhport) { (void)rhport; - uint32_t end_num, rx_token; - uint8_t intflag = 0; - - intflag = USBHSD->INT_FG; - - if (intflag & USBHS_TRANSFER_FLAG) { + uint8_t int_flag = USBHSD->INT_FG; + uint8_t int_status = USBHSD->INT_ST; - end_num = (USBHSD->INT_ST) & MASK_UIS_ENDP; - rx_token = (((USBHSD->INT_ST) & MASK_UIS_TOKEN) >> 4) & 0x03; + if (int_flag & USBHS_TRANSFER_FLAG) { - uint8_t endp = end_num | (rx_token == PID_IN ? TUSB_DIR_IN_MASK : 0); + uint8_t ep_num = int_status & MASK_UIS_ENDP; + uint8_t rx_token = int_status & MASK_UIS_TOKEN; - xfer_ctl_t *xfer = XFER_CTL_BASE(end_num, tu_edpt_dir(endp)); + uint8_t ep_addr = (rx_token == USBHS_TOKEN_PID_IN) ? (TUSB_DIR_IN_MASK | ep_num) : ep_num; - if (rx_token == PID_SOF) { - dcd_event_sof(rhport, USBHSD->FRAME_NO, true); + xfer_ctl_t *xfer = XFER_CTL_BASE(ep_num, tu_edpt_dir(ep_addr)); - } else if (rx_token == PID_OUT) { + if (rx_token == USBHS_TOKEN_PID_OUT) { uint16_t rx_len = USBHSD->RX_LEN; - receive_packet(xfer, rx_len); - - if (xfer->short_packet || (xfer->queued_len == xfer->total_len)) { - xfer->short_packet = false; - - dcd_event_xfer_complete(0, endp, xfer->queued_len, XFER_RESULT_SUCCESS, true); + if (ep_num == 0) { + memcpy(&xfer->buffer[xfer->queued_len], ep0_data_in_out_buffer, rx_len); } - if (end_num == 0) { - USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0; + xfer->queued_len += rx_len; + if (rx_len < xfer->max_size) { + xfer->is_last_packet = true; } - } else if (rx_token == PID_IN) { - if (xfer->short_packet || (xfer->queued_len == xfer->total_len)) { - xfer->short_packet = false; - xfer->total_len = 0; - dcd_event_xfer_complete(0, endp, xfer->queued_len, XFER_RESULT_SUCCESS, true); - - EP_TX_CTRL(end_num) = (EP_TX_CTRL(end_num) & ~(USBHS_EP_T_RES_MASK)) | USBHS_EP_T_RES_NAK; + } else if (rx_token == USBHS_TOKEN_PID_IN) { + // Do nothing, no need to update xfer->is_last_packet, it is already updated in xfer_data_packet + // Common processing below + } - if (end_num == 0) { - } - } else { - dcd_edpt_xfer(0, endp, xfer->buffer + xfer->queued_len, xfer->total_len - xfer->queued_len); - } + if (xfer->is_last_packet == true) { + ep_set_response_and_toggle(ep_addr, EP_RESPONSE_NAK); + dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); + } else { + /* prepare next part of packet to xref */ + xfer_data_packet(ep_addr, xfer); } USBHSD->INT_FG = USBHS_TRANSFER_FLAG; /* Clear flag */ - } else if (intflag & USBHS_SETUP_FLAG) { - USBHS_Dev_Endp0_Tog = 1; - dcd_event_setup_received(0, EP0_DatabufHD, true); + } else if (int_flag & USBHS_SETUP_FLAG) { + ep_set_response_and_toggle(0x80, EP_RESPONSE_NAK); + ep_set_response_and_toggle(0x00, EP_RESPONSE_NAK); + dcd_event_setup_received(0, ep0_data_in_out_buffer, true); USBHSD->INT_FG = USBHS_SETUP_FLAG; /* Clear flag */ - } else if (intflag & USBHS_DETECT_FLAG) { - USBHS_Dev_Endp0_Tog = 1; - - xfer_status[0][TUSB_DIR_OUT].max_size = 64; - xfer_status[0][TUSB_DIR_IN].max_size = 64; + } else if (int_flag & USBHS_DETECT_FLAG) { dcd_event_bus_reset(0, TUSB_SPEED_HIGH, true); USBHSD->DEV_AD = 0; - USBHSD->UEP0_RX_CTRL = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0; + EP_RX_CTRL(0) = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0; + EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; USBHSD->INT_FG = USBHS_DETECT_FLAG; /* Clear flag */ - } else if (intflag & USBHS_SUSPEND_FLAG) { + } else if (int_flag & USBHS_SUSPEND_FLAG) { dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SUSPEND }; dcd_event_handler(&event, true); -- cgit v1.3.1 From 3e604d1d5498cace44179026fe3ca017920704fe Mon Sep 17 00:00:00 2001 From: Denis Krasutski Date: Thu, 4 Jan 2024 12:22:11 +0200 Subject: fix(ch32, iso): fix iso IN transfers for CH32 --- src/portable/wch/dcd_ch32_usbhs.c | 76 +++++++++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 18 deletions(-) (limited to 'src/portable') diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c index 0313c0a69..42b15bf06 100644 --- a/src/portable/wch/dcd_ch32_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -43,6 +43,7 @@ typedef struct { uint16_t queued_len; uint16_t max_size; bool is_last_packet; + bool is_iso; } xfer_ctl_t; typedef enum { @@ -77,7 +78,11 @@ static void ep_set_response_and_toggle(uint8_t ep_addr, ep_response_list_t respo } } } - EP_TX_CTRL(ep_num) = (EP_TX_CTRL(ep_num) & ~(USBHS_EP_T_RES_MASK)) | response; + if (xfer_status[ep_num][TUSB_DIR_IN].is_iso == true) { + EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG; + } else { + EP_TX_CTRL(ep_num) = (EP_TX_CTRL(ep_num) & ~(USBHS_EP_T_RES_MASK)) | response; + } } else { uint8_t response = (response_type == EP_RESPONSE_ACK) ? USBHS_EP_R_RES_ACK : USBHS_EP_R_RES_NAK; if (ep_num == 0) { @@ -112,6 +117,10 @@ static void xfer_data_packet(uint8_t ep_addr, xfer_ctl_t *xfer) { if (xfer->queued_len == xfer->total_len) { xfer->is_last_packet = true; } + if (xfer->is_iso == true) { + /* Enable EP to generate ISA_ACT interrupt */ + USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << ep_num); + } } else { /* TUSB_DIR_OUT */ uint16_t left_to_receive = xfer->total_len - xfer->queued_len; uint16_t max_possible_rx_size = TU_MIN(xfer->max_size, left_to_receive); @@ -146,7 +155,7 @@ void dcd_init(uint8_t rhport) { #endif USBHSD->INT_EN = 0; - USBHSD->INT_EN = USBHS_SETUP_ACT_EN | USBHS_TRANSFER_EN | USBHS_DETECT_EN | USBHS_SUSPEND_EN; + USBHSD->INT_EN = USBHS_SETUP_ACT_EN | USBHS_TRANSFER_EN | USBHS_DETECT_EN | USBHS_SUSPEND_EN | USBHS_ISO_ACT_EN; USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN; USBHSD->ENDP_TYPE = 0x00; @@ -244,18 +253,20 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt) { xfer_ctl_t *xfer = XFER_CTL_BASE(ep_num, dir); xfer->max_size = tu_edpt_packet_size(desc_edpt); - bool is_iso = (desc_edpt->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS); + xfer->is_iso = (desc_edpt->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS); if (dir == TUSB_DIR_OUT) { USBHSD->ENDP_CONFIG |= (USBHS_EP0_R_EN << ep_num); EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; - if (is_iso == true) { + if (xfer->is_iso == true) { USBHSD->ENDP_TYPE |= (USBHS_EP0_R_TYP << ep_num); } EP_RX_MAX_LEN(ep_num) = xfer->max_size; } else { - USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << ep_num); - if (is_iso == true) { + if (xfer->is_iso == true) { USBHSD->ENDP_TYPE |= (USBHS_EP0_T_TYP << ep_num); + } else { + /* Enable all types except Isochronous to avoid ISO_ACT interrupt generation */ + USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << ep_num); } EP_TX_LEN(ep_num) = 0; EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; @@ -275,7 +286,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { EP_RX_MAX_LEN(ep_num) = 0; USBHSD->ENDP_TYPE &= ~(USBHS_EP0_R_TYP << ep_num); USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_R_EN << ep_num); - } else { // TUSB_DIR_IN + } else { // TUSB_DIR_IN EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; EP_TX_LEN(ep_num) = 0; USBHSD->ENDP_TYPE &= ~(USBHS_EP0_T_TYP << ep_num); @@ -332,30 +343,24 @@ void dcd_int_handler(uint8_t rhport) { uint8_t int_flag = USBHSD->INT_FG; uint8_t int_status = USBHSD->INT_ST; - if (int_flag & USBHS_TRANSFER_FLAG) { - + if (int_flag & USBHS_ISO_ACT_FLAG) { uint8_t ep_num = int_status & MASK_UIS_ENDP; uint8_t rx_token = int_status & MASK_UIS_TOKEN; - uint8_t ep_addr = (rx_token == USBHS_TOKEN_PID_IN) ? (TUSB_DIR_IN_MASK | ep_num) : ep_num; - xfer_ctl_t *xfer = XFER_CTL_BASE(ep_num, tu_edpt_dir(ep_addr)); if (rx_token == USBHS_TOKEN_PID_OUT) { uint16_t rx_len = USBHSD->RX_LEN; - if (ep_num == 0) { - memcpy(&xfer->buffer[xfer->queued_len], ep0_data_in_out_buffer, rx_len); - } - xfer->queued_len += rx_len; if (rx_len < xfer->max_size) { xfer->is_last_packet = true; } - } else if (rx_token == USBHS_TOKEN_PID_IN) { - // Do nothing, no need to update xfer->is_last_packet, it is already updated in xfer_data_packet - // Common processing below + if (xfer->is_last_packet == true) { + /* Disable EP to avoid ISO_ACT interrupt generation */ + USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_T_EN << ep_num); + } } if (xfer->is_last_packet == true) { @@ -366,6 +371,41 @@ void dcd_int_handler(uint8_t rhport) { xfer_data_packet(ep_addr, xfer); } + USBHSD->INT_FG = USBHS_ISO_ACT_FLAG; /* Clear flag */ + } else if (int_flag & USBHS_TRANSFER_FLAG) { + + uint8_t ep_num = int_status & MASK_UIS_ENDP; + uint8_t rx_token = int_status & MASK_UIS_TOKEN; + uint8_t ep_addr = (rx_token == USBHS_TOKEN_PID_IN) ? (TUSB_DIR_IN_MASK | ep_num) : ep_num; + xfer_ctl_t *xfer = XFER_CTL_BASE(ep_num, tu_edpt_dir(ep_addr)); + + if (xfer->is_iso == false) { + if (rx_token == USBHS_TOKEN_PID_OUT) { + uint16_t rx_len = USBHSD->RX_LEN; + + if (ep_num == 0) { + memcpy(&xfer->buffer[xfer->queued_len], ep0_data_in_out_buffer, rx_len); + } + + xfer->queued_len += rx_len; + if (rx_len < xfer->max_size) { + xfer->is_last_packet = true; + } + + } else if (rx_token == USBHS_TOKEN_PID_IN) { + // Do nothing, no need to update xfer->is_last_packet, it is already updated in xfer_data_packet + // Common processing below + } + + if (xfer->is_last_packet == true) { + ep_set_response_and_toggle(ep_addr, EP_RESPONSE_NAK); + dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); + } else { + /* prepare next part of packet to xref */ + xfer_data_packet(ep_addr, xfer); + } + } + USBHSD->INT_FG = USBHS_TRANSFER_FLAG; /* Clear flag */ } else if (int_flag & USBHS_SETUP_FLAG) { ep_set_response_and_toggle(0x80, EP_RESPONSE_NAK); -- cgit v1.3.1 From 4bd72da5cdce4b3ab8f5a9960234a97934672f1c Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 21 May 2024 15:41:59 +0700 Subject: use CFG_TUD_ENDPOINT0_SIZE, rename ep0_data_in_out_buffer to simply ep0_buffer reformat indent to 2 spaces --- src/portable/wch/dcd_ch32_usbhs.c | 552 +++++++++++++++++++------------------- 1 file changed, 274 insertions(+), 278 deletions(-) (limited to 'src/portable') diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c index 42b15bf06..dbcf19a7b 100644 --- a/src/portable/wch/dcd_ch32_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -34,21 +34,20 @@ #include "device/dcd.h" // Max number of bi-directional endpoints including EP0 -#define EP_MAX 16 -#define CH32_USBHS_EP0_MAX_SIZE (64) +#define EP_MAX 16 typedef struct { - uint8_t *buffer; - uint16_t total_len; - uint16_t queued_len; - uint16_t max_size; - bool is_last_packet; - bool is_iso; + uint8_t* buffer; + uint16_t total_len; + uint16_t queued_len; + uint16_t max_size; + bool is_last_packet; + bool is_iso; } xfer_ctl_t; typedef enum { - EP_RESPONSE_ACK, - EP_RESPONSE_NAK, + EP_RESPONSE_ACK, + EP_RESPONSE_NAK, } ep_response_list_t; #define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] @@ -63,371 +62,368 @@ static xfer_ctl_t xfer_status[EP_MAX][2]; #define EP_RX_DMA_ADDR(ep) *(volatile uint32_t *)((volatile uint32_t *)&(USBHSD->UEP1_RX_DMA) + (ep - 1)) /* Endpoint Buffer */ -TU_ATTR_ALIGNED(4) static uint8_t ep0_data_in_out_buffer[CH32_USBHS_EP0_MAX_SIZE]; +TU_ATTR_ALIGNED(4) static uint8_t ep0_buffer[CFG_TUD_ENDPOINT0_SIZE]; static void ep_set_response_and_toggle(uint8_t ep_addr, ep_response_list_t response_type) { - uint8_t const ep_num = tu_edpt_number(ep_addr); - if (ep_addr & TUSB_DIR_IN_MASK) { - uint8_t response = (response_type == EP_RESPONSE_ACK) ? USBHS_EP_T_RES_ACK : USBHS_EP_T_RES_NAK; - if (ep_num == 0) { - if (response_type == EP_RESPONSE_ACK) { - if (EP_TX_LEN(ep_num) == 0) { - EP_TX_CTRL(ep_num) |= USBHS_EP_T_TOG_1; - } else { - EP_TX_CTRL(ep_num) ^= USBHS_EP_T_TOG_1; - } - } - } - if (xfer_status[ep_num][TUSB_DIR_IN].is_iso == true) { - EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG; + uint8_t const ep_num = tu_edpt_number(ep_addr); + if (ep_addr & TUSB_DIR_IN_MASK) { + uint8_t response = (response_type == EP_RESPONSE_ACK) ? USBHS_EP_T_RES_ACK : USBHS_EP_T_RES_NAK; + if (ep_num == 0) { + if (response_type == EP_RESPONSE_ACK) { + if (EP_TX_LEN(ep_num) == 0) { + EP_TX_CTRL(ep_num) |= USBHS_EP_T_TOG_1; } else { - EP_TX_CTRL(ep_num) = (EP_TX_CTRL(ep_num) & ~(USBHS_EP_T_RES_MASK)) | response; + EP_TX_CTRL(ep_num) ^= USBHS_EP_T_TOG_1; } + } + } + if (xfer_status[ep_num][TUSB_DIR_IN].is_iso == true) { + EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG; } else { - uint8_t response = (response_type == EP_RESPONSE_ACK) ? USBHS_EP_R_RES_ACK : USBHS_EP_R_RES_NAK; - if (ep_num == 0) { - if (response_type == EP_RESPONSE_ACK) { - if (xfer_status[ep_num][TUSB_DIR_OUT].queued_len == 0) { - EP_RX_CTRL(ep_num) |= USBHS_EP_R_TOG_1; - } - } else { - EP_RX_CTRL(ep_num) ^= USBHS_EP_R_TOG_1; - } + EP_TX_CTRL(ep_num) = (EP_TX_CTRL(ep_num) & ~(USBHS_EP_T_RES_MASK)) | response; + } + } else { + uint8_t response = (response_type == EP_RESPONSE_ACK) ? USBHS_EP_R_RES_ACK : USBHS_EP_R_RES_NAK; + if (ep_num == 0) { + if (response_type == EP_RESPONSE_ACK) { + if (xfer_status[ep_num][TUSB_DIR_OUT].queued_len == 0) { + EP_RX_CTRL(ep_num) |= USBHS_EP_R_TOG_1; } - EP_RX_CTRL(ep_num) = (EP_RX_CTRL(ep_num) & ~(USBHS_EP_R_RES_MASK)) | response; + } else { + EP_RX_CTRL(ep_num) ^= USBHS_EP_R_TOG_1; + } } + EP_RX_CTRL(ep_num) = (EP_RX_CTRL(ep_num) & ~(USBHS_EP_R_RES_MASK)) | response; + } } -static void xfer_data_packet(uint8_t ep_addr, xfer_ctl_t *xfer) { - uint8_t const ep_num = tu_edpt_number(ep_addr); - tusb_dir_t const dir = tu_edpt_dir(ep_addr); +static void xfer_data_packet(uint8_t ep_addr, xfer_ctl_t* xfer) { + uint8_t const ep_num = tu_edpt_number(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); - if (dir == TUSB_DIR_IN) { - uint16_t remaining = xfer->total_len - xfer->queued_len; - uint16_t next_tx_size = TU_MIN(remaining, xfer->max_size); + if (dir == TUSB_DIR_IN) { + uint16_t remaining = xfer->total_len - xfer->queued_len; + uint16_t next_tx_size = TU_MIN(remaining, xfer->max_size); - if (ep_num == 0) { - memcpy(ep0_data_in_out_buffer, &xfer->buffer[xfer->queued_len], next_tx_size); - } else { - EP_TX_DMA_ADDR(ep_num) = (uint32_t)&xfer->buffer[xfer->queued_len]; - } + if (ep_num == 0) { + memcpy(ep0_buffer, &xfer->buffer[xfer->queued_len], next_tx_size); + } else { + EP_TX_DMA_ADDR(ep_num) = (uint32_t) &xfer->buffer[xfer->queued_len]; + } - EP_TX_LEN(ep_num) = next_tx_size; - xfer->queued_len += next_tx_size; - if (xfer->queued_len == xfer->total_len) { - xfer->is_last_packet = true; - } - if (xfer->is_iso == true) { - /* Enable EP to generate ISA_ACT interrupt */ - USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << ep_num); - } - } else { /* TUSB_DIR_OUT */ - uint16_t left_to_receive = xfer->total_len - xfer->queued_len; - uint16_t max_possible_rx_size = TU_MIN(xfer->max_size, left_to_receive); + EP_TX_LEN(ep_num) = next_tx_size; + xfer->queued_len += next_tx_size; + if (xfer->queued_len == xfer->total_len) { + xfer->is_last_packet = true; + } + if (xfer->is_iso == true) { + /* Enable EP to generate ISA_ACT interrupt */ + USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << ep_num); + } + } else { /* TUSB_DIR_OUT */ + uint16_t left_to_receive = xfer->total_len - xfer->queued_len; + uint16_t max_possible_rx_size = TU_MIN(xfer->max_size, left_to_receive); - if (max_possible_rx_size == left_to_receive) { - xfer->is_last_packet = true; - } + if (max_possible_rx_size == left_to_receive) { + xfer->is_last_packet = true; + } - if (ep_num > 0) { - EP_RX_DMA_ADDR(ep_num) = (uint32_t)&xfer->buffer[xfer->queued_len]; - EP_RX_MAX_LEN(ep_num) = max_possible_rx_size; - } + if (ep_num > 0) { + EP_RX_DMA_ADDR(ep_num) = (uint32_t) &xfer->buffer[xfer->queued_len]; + EP_RX_MAX_LEN(ep_num) = max_possible_rx_size; } - ep_set_response_and_toggle(ep_addr, USBHS_EP_R_RES_ACK); + } + ep_set_response_and_toggle(ep_addr, USBHS_EP_R_RES_ACK); } void dcd_init(uint8_t rhport) { - (void)rhport; + (void) rhport; - memset(&xfer_status, 0, sizeof(xfer_status)); + memset(&xfer_status, 0, sizeof(xfer_status)); - USBHSD->HOST_CTRL = 0x00; - USBHSD->HOST_CTRL = USBHS_PHY_SUSPENDM; + USBHSD->HOST_CTRL = 0x00; + USBHSD->HOST_CTRL = USBHS_PHY_SUSPENDM; - USBHSD->CONTROL = 0; + USBHSD->CONTROL = 0; #if TUD_OPT_HIGH_SPEED - USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_HIGH_SPEED; + USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_HIGH_SPEED; #else - #error OPT_MODE_FULL_SPEED not currently supported on CH32 - USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_FULL_SPEED; + #error OPT_MODE_FULL_SPEED not currently supported on CH32 + USBHSD->CONTROL = USBHS_DMA_EN | USBHS_INT_BUSY_EN | USBHS_FULL_SPEED; #endif - USBHSD->INT_EN = 0; - USBHSD->INT_EN = USBHS_SETUP_ACT_EN | USBHS_TRANSFER_EN | USBHS_DETECT_EN | USBHS_SUSPEND_EN | USBHS_ISO_ACT_EN; + USBHSD->INT_EN = 0; + USBHSD->INT_EN = USBHS_SETUP_ACT_EN | USBHS_TRANSFER_EN | USBHS_DETECT_EN | USBHS_SUSPEND_EN | USBHS_ISO_ACT_EN; - USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN; - USBHSD->ENDP_TYPE = 0x00; - USBHSD->BUF_MODE = 0x00; + USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN; + USBHSD->ENDP_TYPE = 0x00; + USBHSD->BUF_MODE = 0x00; - for (int ep = 0; ep < EP_MAX; ep++) { - EP_TX_LEN(ep) = 0; - EP_TX_CTRL(ep) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK; - EP_RX_CTRL(ep) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; + for (int ep = 0; ep < EP_MAX; ep++) { + EP_TX_LEN(ep) = 0; + EP_TX_CTRL(ep) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK; + EP_RX_CTRL(ep) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; - EP_RX_MAX_LEN(ep) = 0; - } + EP_RX_MAX_LEN(ep) = 0; + } - USBHSD->UEP0_DMA = (uint32_t)ep0_data_in_out_buffer; - USBHSD->UEP0_MAX_LEN = CH32_USBHS_EP0_MAX_SIZE; - xfer_status[0][TUSB_DIR_OUT].max_size = CH32_USBHS_EP0_MAX_SIZE; - xfer_status[0][TUSB_DIR_IN].max_size = CH32_USBHS_EP0_MAX_SIZE; + USBHSD->UEP0_DMA = (uint32_t) ep0_buffer; + USBHSD->UEP0_MAX_LEN = CFG_TUD_ENDPOINT0_SIZE; + xfer_status[0][TUSB_DIR_OUT].max_size = CFG_TUD_ENDPOINT0_SIZE; + xfer_status[0][TUSB_DIR_IN].max_size = CFG_TUD_ENDPOINT0_SIZE; - USBHSD->DEV_AD = 0; - USBHSD->CONTROL |= USBHS_DEV_PU_EN; + USBHSD->DEV_AD = 0; + USBHSD->CONTROL |= USBHS_DEV_PU_EN; } void dcd_int_enable(uint8_t rhport) { - (void)rhport; - - NVIC_EnableIRQ(USBHS_IRQn); + (void) rhport; + NVIC_EnableIRQ(USBHS_IRQn); } void dcd_int_disable(uint8_t rhport) { - (void)rhport; - - NVIC_DisableIRQ(USBHS_IRQn); + (void) rhport; + NVIC_DisableIRQ(USBHS_IRQn); } void dcd_edpt_close_all(uint8_t rhport) { - (void)rhport; + (void) rhport; - for (size_t ep = 1; ep < EP_MAX; ep++) { - EP_TX_LEN(ep) = 0; - EP_TX_CTRL(ep) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK; - EP_RX_CTRL(ep) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; + for (size_t ep = 1; ep < EP_MAX; ep++) { + EP_TX_LEN(ep) = 0; + EP_TX_CTRL(ep) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK; + EP_RX_CTRL(ep) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; - EP_RX_MAX_LEN(ep) = 0; - } + EP_RX_MAX_LEN(ep) = 0; + } - USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN; + USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN; } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { - (void)dev_addr; + (void) dev_addr; - // Response with zlp status - dcd_edpt_xfer(rhport, 0x80, NULL, 0); + // Response with zlp status + dcd_edpt_xfer(rhport, 0x80, NULL, 0); } void dcd_remote_wakeup(uint8_t rhport) { - (void)rhport; + (void) rhport; } -void dcd_sof_enable(uint8_t rhport, bool en) -{ - (void) rhport; - if (en) { - USBHSD->INT_EN |= USBHS_SOF_ACT_EN; - } else { - USBHSD->INT_EN &= ~(USBHS_SOF_ACT_EN); - } +void dcd_sof_enable(uint8_t rhport, bool en) { + (void) rhport; + if (en) { + USBHSD->INT_EN |= USBHS_SOF_ACT_EN; + } else { + USBHSD->INT_EN &= ~(USBHS_SOF_ACT_EN); + } } -void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) { - (void)rhport; +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const* request) { + (void) rhport; - if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && - request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && - request->bRequest == TUSB_REQ_SET_ADDRESS) { - USBHSD->DEV_AD = (uint8_t)request->wValue; - } + if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && + request->bRequest == TUSB_REQ_SET_ADDRESS) { + USBHSD->DEV_AD = (uint8_t) request->wValue; + } - EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; - EP_RX_CTRL(0) = USBHS_EP_R_RES_NAK | USBHS_EP_R_TOG_0; + EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; + EP_RX_CTRL(0) = USBHS_EP_R_RES_NAK | USBHS_EP_R_TOG_0; } -bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt) { - (void)rhport; +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_edpt) { + (void) rhport; - uint8_t const ep_num = tu_edpt_number(desc_edpt->bEndpointAddress); - tusb_dir_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); + uint8_t const ep_num = tu_edpt_number(desc_edpt->bEndpointAddress); + tusb_dir_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress); - TU_ASSERT(ep_num < EP_MAX); + TU_ASSERT(ep_num < EP_MAX); - if (ep_num == 0) { - return true; - } + if (ep_num == 0) { + return true; + } - xfer_ctl_t *xfer = XFER_CTL_BASE(ep_num, dir); - xfer->max_size = tu_edpt_packet_size(desc_edpt); + xfer_ctl_t* xfer = XFER_CTL_BASE(ep_num, dir); + xfer->max_size = tu_edpt_packet_size(desc_edpt); - xfer->is_iso = (desc_edpt->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS); - if (dir == TUSB_DIR_OUT) { - USBHSD->ENDP_CONFIG |= (USBHS_EP0_R_EN << ep_num); - EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; - if (xfer->is_iso == true) { - USBHSD->ENDP_TYPE |= (USBHS_EP0_R_TYP << ep_num); - } - EP_RX_MAX_LEN(ep_num) = xfer->max_size; + xfer->is_iso = (desc_edpt->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS); + if (dir == TUSB_DIR_OUT) { + USBHSD->ENDP_CONFIG |= (USBHS_EP0_R_EN << ep_num); + EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; + if (xfer->is_iso == true) { + USBHSD->ENDP_TYPE |= (USBHS_EP0_R_TYP << ep_num); + } + EP_RX_MAX_LEN(ep_num) = xfer->max_size; + } else { + if (xfer->is_iso == true) { + USBHSD->ENDP_TYPE |= (USBHS_EP0_T_TYP << ep_num); } else { - if (xfer->is_iso == true) { - USBHSD->ENDP_TYPE |= (USBHS_EP0_T_TYP << ep_num); - } else { - /* Enable all types except Isochronous to avoid ISO_ACT interrupt generation */ - USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << ep_num); - } - EP_TX_LEN(ep_num) = 0; - EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; + /* Enable all types except Isochronous to avoid ISO_ACT interrupt generation */ + USBHSD->ENDP_CONFIG |= (USBHS_EP0_T_EN << ep_num); } + EP_TX_LEN(ep_num) = 0; + EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; + } - return true; + return true; } void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { - (void)rhport; - - uint8_t const ep_num = tu_edpt_number(ep_addr); - tusb_dir_t const dir = tu_edpt_dir(ep_addr); - - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; - EP_RX_MAX_LEN(ep_num) = 0; - USBHSD->ENDP_TYPE &= ~(USBHS_EP0_R_TYP << ep_num); - USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_R_EN << ep_num); - } else { // TUSB_DIR_IN - EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; - EP_TX_LEN(ep_num) = 0; - USBHSD->ENDP_TYPE &= ~(USBHS_EP0_T_TYP << ep_num); - USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_T_EN << ep_num); - } + (void) rhport; + + uint8_t const ep_num = tu_edpt_number(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); + + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; + EP_RX_MAX_LEN(ep_num) = 0; + USBHSD->ENDP_TYPE &= ~(USBHS_EP0_R_TYP << ep_num); + USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_R_EN << ep_num); + } else { // TUSB_DIR_IN + EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; + EP_TX_LEN(ep_num) = 0; + USBHSD->ENDP_TYPE &= ~(USBHS_EP0_T_TYP << ep_num); + USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_T_EN << ep_num); + } } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { - (void)rhport; + (void) rhport; - uint8_t const ep_num = tu_edpt_number(ep_addr); - tusb_dir_t const dir = tu_edpt_dir(ep_addr); + uint8_t const ep_num = tu_edpt_number(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(ep_num) = USBHS_EP_R_RES_STALL; - } else { - EP_TX_LEN(0) = 0; - EP_TX_CTRL(ep_num) = USBHS_EP_T_RES_STALL; - } + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep_num) = USBHS_EP_R_RES_STALL; + } else { + EP_TX_LEN(0) = 0; + EP_TX_CTRL(ep_num) = USBHS_EP_T_RES_STALL; + } } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { - (void)rhport; + (void) rhport; - uint8_t const ep_num = tu_edpt_number(ep_addr); - tusb_dir_t const dir = tu_edpt_dir(ep_addr); + uint8_t const ep_num = tu_edpt_number(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); - if (dir == TUSB_DIR_OUT) { - EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; - } else { - EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_R_RES_NAK; - } + if (dir == TUSB_DIR_OUT) { + EP_RX_CTRL(ep_num) = USBHS_EP_R_AUTOTOG | USBHS_EP_R_RES_NAK; + } else { + EP_TX_CTRL(ep_num) = USBHS_EP_T_AUTOTOG | USBHS_EP_R_RES_NAK; + } } -bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { - (void)rhport; - uint8_t const ep_num = tu_edpt_number(ep_addr); - tusb_dir_t const dir = tu_edpt_dir(ep_addr); +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { + (void) rhport; + uint8_t const ep_num = tu_edpt_number(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); - xfer_ctl_t *xfer = XFER_CTL_BASE(ep_num, dir); - xfer->buffer = buffer; - xfer->total_len = total_bytes; - xfer->queued_len = 0; - xfer->is_last_packet = false; + xfer_ctl_t* xfer = XFER_CTL_BASE(ep_num, dir); + xfer->buffer = buffer; + xfer->total_len = total_bytes; + xfer->queued_len = 0; + xfer->is_last_packet = false; - xfer_data_packet(ep_addr, xfer); + xfer_data_packet(ep_addr, xfer); - return true; + return true; } void dcd_int_handler(uint8_t rhport) { - (void)rhport; - - uint8_t int_flag = USBHSD->INT_FG; - uint8_t int_status = USBHSD->INT_ST; - - if (int_flag & USBHS_ISO_ACT_FLAG) { - uint8_t ep_num = int_status & MASK_UIS_ENDP; - uint8_t rx_token = int_status & MASK_UIS_TOKEN; - uint8_t ep_addr = (rx_token == USBHS_TOKEN_PID_IN) ? (TUSB_DIR_IN_MASK | ep_num) : ep_num; - xfer_ctl_t *xfer = XFER_CTL_BASE(ep_num, tu_edpt_dir(ep_addr)); - - if (rx_token == USBHS_TOKEN_PID_OUT) { - uint16_t rx_len = USBHSD->RX_LEN; - - xfer->queued_len += rx_len; - if (rx_len < xfer->max_size) { - xfer->is_last_packet = true; - } - } else if (rx_token == USBHS_TOKEN_PID_IN) { - if (xfer->is_last_packet == true) { - /* Disable EP to avoid ISO_ACT interrupt generation */ - USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_T_EN << ep_num); - } - } + (void) rhport; + + uint8_t int_flag = USBHSD->INT_FG; + uint8_t int_status = USBHSD->INT_ST; + + if (int_flag & USBHS_ISO_ACT_FLAG) { + uint8_t ep_num = int_status & MASK_UIS_ENDP; + uint8_t rx_token = int_status & MASK_UIS_TOKEN; + uint8_t ep_addr = (rx_token == USBHS_TOKEN_PID_IN) ? (TUSB_DIR_IN_MASK | ep_num) : ep_num; + xfer_ctl_t* xfer = XFER_CTL_BASE(ep_num, tu_edpt_dir(ep_addr)); + + if (rx_token == USBHS_TOKEN_PID_OUT) { + uint16_t rx_len = USBHSD->RX_LEN; + + xfer->queued_len += rx_len; + if (rx_len < xfer->max_size) { + xfer->is_last_packet = true; + } + } else if (rx_token == USBHS_TOKEN_PID_IN) { + if (xfer->is_last_packet == true) { + /* Disable EP to avoid ISO_ACT interrupt generation */ + USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_T_EN << ep_num); + } + } - if (xfer->is_last_packet == true) { - ep_set_response_and_toggle(ep_addr, EP_RESPONSE_NAK); - dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); - } else { - /* prepare next part of packet to xref */ - xfer_data_packet(ep_addr, xfer); + if (xfer->is_last_packet == true) { + ep_set_response_and_toggle(ep_addr, EP_RESPONSE_NAK); + dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); + } else { + /* prepare next part of packet to xref */ + xfer_data_packet(ep_addr, xfer); + } + + USBHSD->INT_FG = USBHS_ISO_ACT_FLAG; /* Clear flag */ + } else if (int_flag & USBHS_TRANSFER_FLAG) { + + uint8_t ep_num = int_status & MASK_UIS_ENDP; + uint8_t rx_token = int_status & MASK_UIS_TOKEN; + uint8_t ep_addr = (rx_token == USBHS_TOKEN_PID_IN) ? (TUSB_DIR_IN_MASK | ep_num) : ep_num; + xfer_ctl_t* xfer = XFER_CTL_BASE(ep_num, tu_edpt_dir(ep_addr)); + + if (xfer->is_iso == false) { + if (rx_token == USBHS_TOKEN_PID_OUT) { + uint16_t rx_len = USBHSD->RX_LEN; + + if (ep_num == 0) { + memcpy(&xfer->buffer[xfer->queued_len], ep0_buffer, rx_len); } - USBHSD->INT_FG = USBHS_ISO_ACT_FLAG; /* Clear flag */ - } else if (int_flag & USBHS_TRANSFER_FLAG) { - - uint8_t ep_num = int_status & MASK_UIS_ENDP; - uint8_t rx_token = int_status & MASK_UIS_TOKEN; - uint8_t ep_addr = (rx_token == USBHS_TOKEN_PID_IN) ? (TUSB_DIR_IN_MASK | ep_num) : ep_num; - xfer_ctl_t *xfer = XFER_CTL_BASE(ep_num, tu_edpt_dir(ep_addr)); - - if (xfer->is_iso == false) { - if (rx_token == USBHS_TOKEN_PID_OUT) { - uint16_t rx_len = USBHSD->RX_LEN; - - if (ep_num == 0) { - memcpy(&xfer->buffer[xfer->queued_len], ep0_data_in_out_buffer, rx_len); - } - - xfer->queued_len += rx_len; - if (rx_len < xfer->max_size) { - xfer->is_last_packet = true; - } - - } else if (rx_token == USBHS_TOKEN_PID_IN) { - // Do nothing, no need to update xfer->is_last_packet, it is already updated in xfer_data_packet - // Common processing below - } - - if (xfer->is_last_packet == true) { - ep_set_response_and_toggle(ep_addr, EP_RESPONSE_NAK); - dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); - } else { - /* prepare next part of packet to xref */ - xfer_data_packet(ep_addr, xfer); - } + xfer->queued_len += rx_len; + if (rx_len < xfer->max_size) { + xfer->is_last_packet = true; } - USBHSD->INT_FG = USBHS_TRANSFER_FLAG; /* Clear flag */ - } else if (int_flag & USBHS_SETUP_FLAG) { - ep_set_response_and_toggle(0x80, EP_RESPONSE_NAK); - ep_set_response_and_toggle(0x00, EP_RESPONSE_NAK); - dcd_event_setup_received(0, ep0_data_in_out_buffer, true); + } else if (rx_token == USBHS_TOKEN_PID_IN) { + // Do nothing, no need to update xfer->is_last_packet, it is already updated in xfer_data_packet + // Common processing below + } + + if (xfer->is_last_packet == true) { + ep_set_response_and_toggle(ep_addr, EP_RESPONSE_NAK); + dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); + } else { + /* prepare next part of packet to xref */ + xfer_data_packet(ep_addr, xfer); + } + } - USBHSD->INT_FG = USBHS_SETUP_FLAG; /* Clear flag */ - } else if (int_flag & USBHS_DETECT_FLAG) { + USBHSD->INT_FG = USBHS_TRANSFER_FLAG; /* Clear flag */ + } else if (int_flag & USBHS_SETUP_FLAG) { + ep_set_response_and_toggle(0x80, EP_RESPONSE_NAK); + ep_set_response_and_toggle(0x00, EP_RESPONSE_NAK); + dcd_event_setup_received(0, ep0_buffer, true); - dcd_event_bus_reset(0, TUSB_SPEED_HIGH, true); + USBHSD->INT_FG = USBHS_SETUP_FLAG; /* Clear flag */ + } else if (int_flag & USBHS_DETECT_FLAG) { - USBHSD->DEV_AD = 0; - EP_RX_CTRL(0) = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0; - EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; + dcd_event_bus_reset(0, TUSB_SPEED_HIGH, true); - USBHSD->INT_FG = USBHS_DETECT_FLAG; /* Clear flag */ - } else if (int_flag & USBHS_SUSPEND_FLAG) { - dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SUSPEND }; - dcd_event_handler(&event, true); + USBHSD->DEV_AD = 0; + EP_RX_CTRL(0) = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0; + EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; - USBHSD->INT_FG = USBHS_SUSPEND_FLAG; /* Clear flag */ - } + USBHSD->INT_FG = USBHS_DETECT_FLAG; /* Clear flag */ + } else if (int_flag & USBHS_SUSPEND_FLAG) { + dcd_event_t event = {.rhport = rhport, .event_id = DCD_EVENT_SUSPEND}; + dcd_event_handler(&event, true); + + USBHSD->INT_FG = USBHS_SUSPEND_FLAG; /* Clear flag */ + } } #endif -- cgit v1.3.1 From 953e3bd6344812c910f714952b4dda47ffe53107 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 21 May 2024 16:08:27 +0700 Subject: - minor update to ep_set_response_and_toggle/xfer_data_packet - merge USBHS_ISO_ACT_FLAG, USBHS_TRANSFER_FLAG handler since they are similar - improve uart output - add note for link speed in bus reset --- hw/bsp/ch32v307/debug_uart.c | 2 +- hw/bsp/ch32v307/family.c | 7 +-- src/portable/wch/ch32_usbhs_reg.h | 5 +- src/portable/wch/dcd_ch32_usbhs.c | 104 +++++++++++++++++--------------------- 4 files changed, 54 insertions(+), 64 deletions(-) (limited to 'src/portable') diff --git a/hw/bsp/ch32v307/debug_uart.c b/hw/bsp/ch32v307/debug_uart.c index db3551ca7..fbabeeadc 100644 --- a/hw/bsp/ch32v307/debug_uart.c +++ b/hw/bsp/ch32v307/debug_uart.c @@ -28,7 +28,7 @@ #include -#define UART_RINGBUFFER_SIZE_TX 64 +#define UART_RINGBUFFER_SIZE_TX 128 #define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX-1) static char tx_buf[UART_RINGBUFFER_SIZE_TX]; diff --git a/hw/bsp/ch32v307/family.c b/hw/bsp/ch32v307/family.c index fe37ea8e3..94578b416 100644 --- a/hw/bsp/ch32v307/family.c +++ b/hw/bsp/ch32v307/family.c @@ -72,7 +72,7 @@ void board_init(void) { SysTick_Config(SystemCoreClock / 1000); #endif - usart_printf_init(115200); + usart_printf_init(CFG_BOARD_UART_BAUDRATE); #if CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED // Use Highspeed USB @@ -150,10 +150,11 @@ int board_uart_read(uint8_t* buf, int len) { int board_uart_write(void const* buf, int len) { int txsize = len; + const char* bufc = (const char*) buf; while (txsize--) { - uart_write(*(uint8_t const*) buf); - buf++; + uart_write(*bufc++); } + uart_sync(); return len; } diff --git a/src/portable/wch/ch32_usbhs_reg.h b/src/portable/wch/ch32_usbhs_reg.h index 7428285a5..1c2ed9893 100644 --- a/src/portable/wch/ch32_usbhs_reg.h +++ b/src/portable/wch/ch32_usbhs_reg.h @@ -74,7 +74,10 @@ // USB SPEED TYPE #define USBHS_SPEED_TYPE_OFFSET 0x08 -#define USBSPEED_MASK (0x03) +#define USBHS_SPEED_TYPE_MASK 0x03 +#define USBHS_SPEED_TYPE_FULL 0 +#define USBHS_SPEED_TYPE_HIGH 1 +#define USBHS_SPEED_TYPE_LOW 2 // USB_MIS_ST #define USBHS_MIS_ST_OFFSET 0x09 diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c index dbcf19a7b..8879db98d 100644 --- a/src/portable/wch/dcd_ch32_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -64,9 +64,8 @@ static xfer_ctl_t xfer_status[EP_MAX][2]; /* Endpoint Buffer */ TU_ATTR_ALIGNED(4) static uint8_t ep0_buffer[CFG_TUD_ENDPOINT0_SIZE]; -static void ep_set_response_and_toggle(uint8_t ep_addr, ep_response_list_t response_type) { - uint8_t const ep_num = tu_edpt_number(ep_addr); - if (ep_addr & TUSB_DIR_IN_MASK) { +static void ep_set_response_and_toggle(uint8_t ep_num, tusb_dir_t ep_dir, ep_response_list_t response_type) { + if (ep_dir == TUSB_DIR_IN) { uint8_t response = (response_type == EP_RESPONSE_ACK) ? USBHS_EP_T_RES_ACK : USBHS_EP_T_RES_NAK; if (ep_num == 0) { if (response_type == EP_RESPONSE_ACK) { @@ -97,11 +96,8 @@ static void ep_set_response_and_toggle(uint8_t ep_addr, ep_response_list_t respo } } -static void xfer_data_packet(uint8_t ep_addr, xfer_ctl_t* xfer) { - uint8_t const ep_num = tu_edpt_number(ep_addr); - tusb_dir_t const dir = tu_edpt_dir(ep_addr); - - if (dir == TUSB_DIR_IN) { +static void xfer_data_packet(uint8_t ep_num, tusb_dir_t ep_dir, xfer_ctl_t* xfer) { + if (ep_dir == TUSB_DIR_IN) { uint16_t remaining = xfer->total_len - xfer->queued_len; uint16_t next_tx_size = TU_MIN(remaining, xfer->max_size); @@ -133,7 +129,7 @@ static void xfer_data_packet(uint8_t ep_addr, xfer_ctl_t* xfer) { EP_RX_MAX_LEN(ep_num) = max_possible_rx_size; } } - ep_set_response_and_toggle(ep_addr, USBHS_EP_R_RES_ACK); + ep_set_response_and_toggle(ep_num, ep_dir, USBHS_EP_R_RES_ACK); } void dcd_init(uint8_t rhport) { @@ -154,7 +150,7 @@ void dcd_init(uint8_t rhport) { #endif USBHSD->INT_EN = 0; - USBHSD->INT_EN = USBHS_SETUP_ACT_EN | USBHS_TRANSFER_EN | USBHS_DETECT_EN | USBHS_SUSPEND_EN | USBHS_ISO_ACT_EN; + USBHSD->INT_EN = USBHS_SETUP_ACT_EN | USBHS_TRANSFER_EN | USBHS_BUS_RST_EN | USBHS_SUSPEND_EN | USBHS_ISO_ACT_EN; USBHSD->ENDP_CONFIG = USBHS_EP0_T_EN | USBHS_EP0_R_EN; USBHSD->ENDP_TYPE = 0x00; @@ -328,7 +324,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to xfer->queued_len = 0; xfer->is_last_packet = false; - xfer_data_packet(ep_addr, xfer); + xfer_data_packet(ep_num, dir, xfer); return true; } @@ -339,77 +335,67 @@ void dcd_int_handler(uint8_t rhport) { uint8_t int_flag = USBHSD->INT_FG; uint8_t int_status = USBHSD->INT_ST; - if (int_flag & USBHS_ISO_ACT_FLAG) { - uint8_t ep_num = int_status & MASK_UIS_ENDP; - uint8_t rx_token = int_status & MASK_UIS_TOKEN; - uint8_t ep_addr = (rx_token == USBHS_TOKEN_PID_IN) ? (TUSB_DIR_IN_MASK | ep_num) : ep_num; - xfer_ctl_t* xfer = XFER_CTL_BASE(ep_num, tu_edpt_dir(ep_addr)); + if (int_flag & (USBHS_ISO_ACT_FLAG | USBHS_TRANSFER_FLAG)) { + uint8_t const rx_token = int_status & MASK_UIS_TOKEN; + uint8_t const ep_num = int_status & MASK_UIS_ENDP; + tusb_dir_t const ep_dir = (rx_token == USBHS_TOKEN_PID_IN) ? TUSB_DIR_IN : TUSB_DIR_OUT; + uint8_t const ep_addr = tu_edpt_addr(ep_num, ep_dir); + xfer_ctl_t* xfer = XFER_CTL_BASE(ep_num, ep_dir); if (rx_token == USBHS_TOKEN_PID_OUT) { uint16_t rx_len = USBHSD->RX_LEN; + if (ep_num == 0) { + memcpy(&xfer->buffer[xfer->queued_len], ep0_buffer, rx_len); + } + xfer->queued_len += rx_len; if (rx_len < xfer->max_size) { xfer->is_last_packet = true; } } else if (rx_token == USBHS_TOKEN_PID_IN) { - if (xfer->is_last_packet == true) { + if (xfer->is_iso && xfer->is_last_packet) { /* Disable EP to avoid ISO_ACT interrupt generation */ USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_T_EN << ep_num); + }else { + // Do nothing, no need to update xfer->is_last_packet, it is already updated in xfer_data_packet } } if (xfer->is_last_packet == true) { - ep_set_response_and_toggle(ep_addr, EP_RESPONSE_NAK); + ep_set_response_and_toggle(ep_num, ep_dir, EP_RESPONSE_NAK); dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); } else { /* prepare next part of packet to xref */ - xfer_data_packet(ep_addr, xfer); - } - - USBHSD->INT_FG = USBHS_ISO_ACT_FLAG; /* Clear flag */ - } else if (int_flag & USBHS_TRANSFER_FLAG) { - - uint8_t ep_num = int_status & MASK_UIS_ENDP; - uint8_t rx_token = int_status & MASK_UIS_TOKEN; - uint8_t ep_addr = (rx_token == USBHS_TOKEN_PID_IN) ? (TUSB_DIR_IN_MASK | ep_num) : ep_num; - xfer_ctl_t* xfer = XFER_CTL_BASE(ep_num, tu_edpt_dir(ep_addr)); - - if (xfer->is_iso == false) { - if (rx_token == USBHS_TOKEN_PID_OUT) { - uint16_t rx_len = USBHSD->RX_LEN; - - if (ep_num == 0) { - memcpy(&xfer->buffer[xfer->queued_len], ep0_buffer, rx_len); - } - - xfer->queued_len += rx_len; - if (rx_len < xfer->max_size) { - xfer->is_last_packet = true; - } - - } else if (rx_token == USBHS_TOKEN_PID_IN) { - // Do nothing, no need to update xfer->is_last_packet, it is already updated in xfer_data_packet - // Common processing below - } - - if (xfer->is_last_packet == true) { - ep_set_response_and_toggle(ep_addr, EP_RESPONSE_NAK); - dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); - } else { - /* prepare next part of packet to xref */ - xfer_data_packet(ep_addr, xfer); - } + xfer_data_packet(ep_num, ep_dir, xfer); } - USBHSD->INT_FG = USBHS_TRANSFER_FLAG; /* Clear flag */ + USBHSD->INT_FG = (int_flag & (USBHS_ISO_ACT_FLAG | USBHS_TRANSFER_FLAG)); /* Clear flag */ } else if (int_flag & USBHS_SETUP_FLAG) { - ep_set_response_and_toggle(0x80, EP_RESPONSE_NAK); - ep_set_response_and_toggle(0x00, EP_RESPONSE_NAK); + ep_set_response_and_toggle(0, TUSB_DIR_IN, EP_RESPONSE_NAK); + ep_set_response_and_toggle(0, TUSB_DIR_OUT, EP_RESPONSE_NAK); dcd_event_setup_received(0, ep0_buffer, true); USBHSD->INT_FG = USBHS_SETUP_FLAG; /* Clear flag */ - } else if (int_flag & USBHS_DETECT_FLAG) { + } else if (int_flag & USBHS_BUS_RST_FLAG) { + // TODO CH32 does not detect actual speed at this time (should be known at end of reset) + // This interrupt probably triggered at start of bus reset +// tusb_speed_t actual_speed; +// switch(USBHSD->SPEED_TYPE & USBHS_SPEED_TYPE_MASK){ +// case USBHS_SPEED_TYPE_HIGH: +// actual_speed = TUSB_SPEED_HIGH; +// break; +// case USBHS_SPEED_TYPE_FULL: +// actual_speed = TUSB_SPEED_FULL; +// break; +// case USBHS_SPEED_TYPE_LOW: +// actual_speed = TUSB_SPEED_LOW; +// break; +// default: +// TU_ASSERT(0,); +// break; +// } +// dcd_event_bus_reset(0, actual_speed, true); dcd_event_bus_reset(0, TUSB_SPEED_HIGH, true); @@ -417,7 +403,7 @@ void dcd_int_handler(uint8_t rhport) { EP_RX_CTRL(0) = USBHS_EP_R_RES_ACK | USBHS_EP_R_TOG_0; EP_TX_CTRL(0) = USBHS_EP_T_RES_NAK | USBHS_EP_T_TOG_0; - USBHSD->INT_FG = USBHS_DETECT_FLAG; /* Clear flag */ + USBHSD->INT_FG = USBHS_BUS_RST_FLAG; /* Clear flag */ } else if (int_flag & USBHS_SUSPEND_FLAG) { dcd_event_t event = {.rhport = rhport, .event_id = DCD_EVENT_SUSPEND}; dcd_event_handler(&event, true); -- cgit v1.3.1 From 4a5b190a2209958b875416641b67a4076f14c9e2 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 21 May 2024 18:34:25 +0700 Subject: re-add sof event --- src/portable/wch/ch32_usbhs_reg.h | 5 ++++ src/portable/wch/dcd_ch32_usbhs.c | 62 +++++++++++++++++++++------------------ 2 files changed, 39 insertions(+), 28 deletions(-) (limited to 'src/portable') diff --git a/src/portable/wch/ch32_usbhs_reg.h b/src/portable/wch/ch32_usbhs_reg.h index 1c2ed9893..130e4f223 100644 --- a/src/portable/wch/ch32_usbhs_reg.h +++ b/src/portable/wch/ch32_usbhs_reg.h @@ -63,8 +63,13 @@ // USB DEV AD #define USBHS_DEV_AD_OFFSET 0x03 + // USB FRAME_NO #define USBHS_FRAME_NO_OFFSET 0x04 +#define USBHS_FRAME_NO_NUM_MASK (0x7FF) +#define USBHS_FRAME_NO_MICROFRAME_SHIFT (11) +#define USBHS_FRAME_NO_MICROFRAME_MASK (0x7 << USBHS_FRAME_NO_MICROFRAME_SHIFT) + // USB SUSPEND #define USBHS_SUSPEND_OFFSET 0x06 #define USBHS_DEV_REMOTE_WAKEUP (1 << 2) diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c index 8879db98d..b36c7dd50 100644 --- a/src/portable/wch/dcd_ch32_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -336,40 +336,46 @@ void dcd_int_handler(uint8_t rhport) { uint8_t int_status = USBHSD->INT_ST; if (int_flag & (USBHS_ISO_ACT_FLAG | USBHS_TRANSFER_FLAG)) { - uint8_t const rx_token = int_status & MASK_UIS_TOKEN; - uint8_t const ep_num = int_status & MASK_UIS_ENDP; - tusb_dir_t const ep_dir = (rx_token == USBHS_TOKEN_PID_IN) ? TUSB_DIR_IN : TUSB_DIR_OUT; - uint8_t const ep_addr = tu_edpt_addr(ep_num, ep_dir); - xfer_ctl_t* xfer = XFER_CTL_BASE(ep_num, ep_dir); - - if (rx_token == USBHS_TOKEN_PID_OUT) { - uint16_t rx_len = USBHSD->RX_LEN; + uint8_t const token = int_status & MASK_UIS_TOKEN; + + if (token == USBHS_TOKEN_PID_SOF) { + uint32_t frame_count = USBHSD->FRAME_NO & USBHS_FRAME_NO_NUM_MASK; + dcd_event_sof(rhport, frame_count, true); + }else { + uint8_t const ep_num = int_status & MASK_UIS_ENDP; + tusb_dir_t const ep_dir = (token == USBHS_TOKEN_PID_IN) ? TUSB_DIR_IN : TUSB_DIR_OUT; + uint8_t const ep_addr = tu_edpt_addr(ep_num, ep_dir); + xfer_ctl_t* xfer = XFER_CTL_BASE(ep_num, ep_dir); + + if (token == USBHS_TOKEN_PID_OUT) { + uint16_t rx_len = USBHSD->RX_LEN; + + if (ep_num == 0) { + memcpy(&xfer->buffer[xfer->queued_len], ep0_buffer, rx_len); + } - if (ep_num == 0) { - memcpy(&xfer->buffer[xfer->queued_len], ep0_buffer, rx_len); + xfer->queued_len += rx_len; + if (rx_len < xfer->max_size) { + xfer->is_last_packet = true; + } + } else if (token == USBHS_TOKEN_PID_IN) { + if (xfer->is_iso && xfer->is_last_packet) { + /* Disable EP to avoid ISO_ACT interrupt generation */ + USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_T_EN << ep_num); + } else { + // Do nothing, no need to update xfer->is_last_packet, it is already updated in xfer_data_packet + } } - xfer->queued_len += rx_len; - if (rx_len < xfer->max_size) { - xfer->is_last_packet = true; - } - } else if (rx_token == USBHS_TOKEN_PID_IN) { - if (xfer->is_iso && xfer->is_last_packet) { - /* Disable EP to avoid ISO_ACT interrupt generation */ - USBHSD->ENDP_CONFIG &= ~(USBHS_EP0_T_EN << ep_num); - }else { - // Do nothing, no need to update xfer->is_last_packet, it is already updated in xfer_data_packet + if (xfer->is_last_packet == true) { + ep_set_response_and_toggle(ep_num, ep_dir, EP_RESPONSE_NAK); + dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); + } else { + /* prepare next part of packet to xref */ + xfer_data_packet(ep_num, ep_dir, xfer); } } - if (xfer->is_last_packet == true) { - ep_set_response_and_toggle(ep_num, ep_dir, EP_RESPONSE_NAK); - dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); - } else { - /* prepare next part of packet to xref */ - xfer_data_packet(ep_num, ep_dir, xfer); - } - USBHSD->INT_FG = (int_flag & (USBHS_ISO_ACT_FLAG | USBHS_TRANSFER_FLAG)); /* Clear flag */ } else if (int_flag & USBHS_SETUP_FLAG) { ep_set_response_and_toggle(0, TUSB_DIR_IN, EP_RESPONSE_NAK); -- cgit v1.3.1 From 927015baae9b2d265d1daaa0fc2ffca1aa4f9e91 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 24 May 2024 11:38:44 +0700 Subject: wch usbfs/usbhs need to specify which driver to use. for v307 default to highspeed --- hw/bsp/ch32v307/family.c | 13 +++++---- hw/bsp/ch32v307/family.cmake | 15 +++++++--- hw/bsp/ch32v307/family.mk | 4 +-- src/common/tusb_mcu.h | 50 ++++++++++++++++++++++++++-------- src/device/usbd.c | 2 +- src/portable/synopsys/dwc2/dwc2_type.h | 33 ++++++++++++++++------ src/portable/wch/dcd_ch32_usbfs.c | 3 +- src/portable/wch/dcd_ch32_usbhs.c | 3 +- src/tusb_option.h | 47 ++++++++++++++++++-------------- 9 files changed, 114 insertions(+), 56 deletions(-) (limited to 'src/portable') diff --git a/hw/bsp/ch32v307/family.c b/hw/bsp/ch32v307/family.c index 94578b416..0846b10a9 100644 --- a/hw/bsp/ch32v307/family.c +++ b/hw/bsp/ch32v307/family.c @@ -38,13 +38,13 @@ // TODO maybe having FS as port0, HS as port1 __attribute__((interrupt)) void USBHS_IRQHandler(void) { - #if CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED + #if CFG_TUD_WCH_USBIP_USBHS tud_int_handler(0); #endif } __attribute__((interrupt)) void OTG_FS_IRQHandler(void) { - #if CFG_TUD_MAX_SPEED == OPT_MODE_FULL_SPEED + #if CFG_TUD_WCH_USBIP_USBFS tud_int_handler(0); #endif } @@ -74,15 +74,17 @@ void board_init(void) { usart_printf_init(CFG_BOARD_UART_BAUDRATE); -#if CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED - // Use Highspeed USB +#ifdef CH32V30x_D8C + // v305/v307: Highspeed USB RCC_USBCLK48MConfig(RCC_USBCLK48MCLKSource_USBPHY); RCC_USBHSPLLCLKConfig(RCC_HSBHSPLLCLKSource_HSE); RCC_USBHSConfig(RCC_USBPLL_Div2); RCC_USBHSPLLCKREFCLKConfig(RCC_USBHSPLLCKREFCLK_4M); RCC_USBHSPHYPLLALIVEcmd(ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_USBHS, ENABLE); -#else +#endif + + // Fullspeed USB uint8_t otg_div; switch (SystemCoreClock) { case 48000000: otg_div = RCC_OTGFSCLKSource_PLLCLK_Div1; break; @@ -92,7 +94,6 @@ void board_init(void) { } RCC_OTGFSCLKConfig(otg_div); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE); -#endif GPIO_InitTypeDef GPIO_InitStructure = {0}; diff --git a/hw/bsp/ch32v307/family.cmake b/hw/bsp/ch32v307/family.cmake index fd475c987..af26bfc31 100644 --- a/hw/bsp/ch32v307/family.cmake +++ b/hw/bsp/ch32v307/family.cmake @@ -14,7 +14,7 @@ set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TO set(FAMILY_MCUS CH32V307 CACHE INTERNAL "") set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") -# default to highspeed +# default to highspeed, used to select USBFS / USBHS driver if (NOT DEFINED SPEED) set(SPEED high) endif() @@ -52,9 +52,16 @@ function(add_board_target BOARD_TARGET) ${SDK_SRC_DIR}/Peripheral/inc ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - BOARD_TUD_MAX_SPEED=$,OPT_MODE_HIGH_SPEED,OPT_MODE_FULL_SPEED> - ) + if (SPEED STREQUAL high) + target_compile_definitions(${BOARD_TARGET} PUBLIC + CFG_TUD_WCH_USBIP_USBHS=1 +# BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + ) + else () + target_compile_definitions(${BOARD_TARGET} PUBLIC + CFG_TUD_WCH_USBIP_USBFS=1 + ) + endif () update_board(${BOARD_TARGET}) diff --git a/hw/bsp/ch32v307/family.mk b/hw/bsp/ch32v307/family.mk index 2dbe0c46a..30a070a9b 100644 --- a/hw/bsp/ch32v307/family.mk +++ b/hw/bsp/ch32v307/family.mk @@ -26,11 +26,11 @@ CFLAGS += \ -DCFG_TUSB_MCU=OPT_MCU_CH32V307 \ ifeq ($(SPEED),high) - CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED $(info "Using USBHS driver for HighSpeed mode") + CFLAGS += -DCFG_TUD_WCH_USBIP_USBHS=1 else - CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED $(info "Using USBFS driver for FullSpeed mode") + CFLAGS += -DCFG_TUD_WCH_USBIP_USBFS=1 endif LDFLAGS_GCC += \ diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index abfed2835..af11ecb9b 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -402,28 +402,56 @@ #elif TU_CHECK_MCU(OPT_MCU_F1C100S) #define TUP_DCD_ENDPOINT_MAX 4 -//------------- WCH -------------// -#elif TU_CHECK_MCU(OPT_MCU_CH32V307) - // v307 support both FS and HS +//--------------------------------------------------------------------+ +// WCH +//--------------------------------------------------------------------+ +#elif TU_CHECK_MCU(OPT_MCU_CH32F20X) #define TUP_USBIP_WCH_USBHS #define TUP_USBIP_WCH_USBFS - #define TUP_RHPORT_HIGHSPEED 1 // default to highspeed - #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED ? 16 : 8) + #if !defined(CFG_TUD_WCH_USBIP_USBFS) + #define CFG_TUD_WCH_USBIP_USBFS 0 + #endif -#elif TU_CHECK_MCU(OPT_MCU_CH32F20X) - #define TUP_USBIP_WCH_USBHS - #define TUP_USBIP_WCH_USBFS + #if !defined(CFG_TUD_WCH_USBIP_USBHS) + #define CFG_TUD_WCH_USBIP_USBHS (CFG_TUD_WCH_USBIP_USBFS ? 0 : 1) + #endif - #define TUP_RHPORT_HIGHSPEED 1 // default to highspeed - #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED ? 16 : 8) + #define TUP_RHPORT_HIGHSPEED CFG_TUD_WCH_USBIP_USBHS + #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_WCH_USBIP_USBHS ? 16 : 8) #elif TU_CHECK_MCU(OPT_MCU_CH32V20X) + // v20x support both FSDEV (USBD) and USBFS, default to FSDEV #define TUP_USBIP_WCH_USBFS #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_USBIP_FSDEV + #define TUP_USBIP_FSDEV_CH32 -#endif + #if !defined(CFG_TUD_WCH_USBIP_USBFS) + #define CFG_TUD_WCH_USBIP_USBFS 0 + #endif + #if !defined(CFG_TUD_WCH_FSDEV) + #define CFG_TUD_WCH_USBIP_FSDEV (CFG_TUD_WCH_USBIP_USBFS ? 0 : 1) + #endif + +#elif TU_CHECK_MCU(OPT_MCU_CH32V307) + // v307 support both FS and HS, default to HS + #define TUP_USBIP_WCH_USBHS + #define TUP_USBIP_WCH_USBFS + + #if !defined(CFG_TUD_WCH_USBIP_USBFS) + #define CFG_TUD_WCH_USBIP_USBFS 0 + #endif + + #if !defined(CFG_TUD_WCH_USBIP_USBHS) + #define CFG_TUD_WCH_USBIP_USBHS (CFG_TUD_WCH_USBIP_USBFS ? 0 : 1) + #endif + + #define TUP_RHPORT_HIGHSPEED CFG_TUD_WCH_USBIP_USBHS + #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_WCH_USBIP_USBHS ? 16 : 8) + +#endif //--------------------------------------------------------------------+ // External USB controller diff --git a/src/device/usbd.c b/src/device/usbd.c index 25d890dc7..9a6afd0d1 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -407,7 +407,7 @@ bool tud_init(uint8_t rhport) { // skip if already initialized if (tud_inited()) return true; - TU_LOG_USBD("USBD init on controller %u\r\n", rhport); + TU_LOG_USBD("USBD init on controller %u, Highspeed = %u\r\n", rhport, TUD_OPT_HIGH_SPEED); TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(usbd_device_t)); TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(dcd_event_t)); TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(tu_fifo_t)); diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index c15771237..cb694b326 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -1,17 +1,34 @@ -/** - * @author MCD Application Team - * Ha Thach (tinyusb.org) - * - * @attention - * - *

© Copyright (c) 2019 STMicroelectronics. +/* + * The MIT License (MIT) + * + * Copyright (c) 2024, hathach (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. + * + */ +/**

© Copyright (c) 2019 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause - * */ #ifndef _TUSB_DWC2_TYPES_H_ diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index dafe4414e..9ed370b40 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -27,8 +27,7 @@ #include "tusb_option.h" -// Note: CH32 can have both USB FS and HS, only use this driver if CFG_TUD_MAX_SPEED is full speed -#if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBFS) && (CFG_TUD_MAX_SPEED == OPT_MODE_FULL_SPEED) +#if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBFS) && CFG_TUD_WCH_USBIP_USBFS #include "device/dcd.h" #include "ch32_usbfs_reg.h" diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c index b36c7dd50..622f9c508 100644 --- a/src/portable/wch/dcd_ch32_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -27,8 +27,7 @@ #include "tusb_option.h" -// Note: CH32 can have both USB FS and HS, only use this driver if CFG_TUD_MAX_SPEED is high speed -#if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBHS) && (CFG_TUD_MAX_SPEED == OPT_MODE_HIGH_SPEED) +#if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBHS) && CFG_TUD_WCH_USBIP_USBHS #include "ch32_usbhs_reg.h" #include "device/dcd.h" diff --git a/src/tusb_option.h b/src/tusb_option.h index 318a4c7bd..d74510b60 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -207,19 +207,9 @@ #define OPT_OS_RTTHREAD 6 ///< RT-Thread #define OPT_OS_RTX4 7 ///< Keil RTX 4 -// Allow to use command line to change the config name/location -#ifdef CFG_TUSB_CONFIG_FILE - #include CFG_TUSB_CONFIG_FILE -#else - #include "tusb_config.h" -#endif - -#include "common/tusb_mcu.h" - -//-------------------------------------------------------------------- -// RootHub Mode Configuration -// CFG_TUSB_RHPORTx_MODE contains operation mode and speed for that port -//-------------------------------------------------------------------- +//--------------------------------------------------------------------+ +// Mode and Speed +//--------------------------------------------------------------------+ // Low byte is operational mode #define OPT_MODE_NONE 0x0000 ///< Disabled @@ -233,7 +223,24 @@ #define OPT_MODE_HIGH_SPEED 0x0400 ///< High Speed #define OPT_MODE_SPEED_MASK 0xff00 -//------------- Roothub as Device -------------// +//--------------------------------------------------------------------+ +// Include tusb_config.h and tusb_mcu.h +//--------------------------------------------------------------------+ + +// Allow to use command line to change the config name/location +#ifdef CFG_TUSB_CONFIG_FILE + #include CFG_TUSB_CONFIG_FILE +#else + #include "tusb_config.h" +#endif + +#include "common/tusb_mcu.h" + +//-------------------------------------------------------------------- +// RootHub Mode detection +//-------------------------------------------------------------------- + +//------------- Root hub as Device -------------// #if defined(CFG_TUSB_RHPORT0_MODE) && ((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_DEVICE) #define TUD_RHPORT_MODE (CFG_TUSB_RHPORT0_MODE) @@ -261,7 +268,7 @@ // highspeed support indicator #define TUD_OPT_HIGH_SPEED (CFG_TUD_MAX_SPEED ? (CFG_TUD_MAX_SPEED & OPT_MODE_HIGH_SPEED) : TUP_RHPORT_HIGHSPEED) -//------------- Roothub as Host -------------// +//------------- Root hub as Host -------------// #if defined(CFG_TUSB_RHPORT0_MODE) && ((CFG_TUSB_RHPORT0_MODE) & OPT_MODE_HOST) #define TUH_RHPORT_MODE (CFG_TUSB_RHPORT0_MODE) @@ -467,26 +474,26 @@ #define CFG_TUH_CDC 0 #endif +// FTDI is not part of CDC class, only to re-use CDC driver API #ifndef CFG_TUH_CDC_FTDI - // FTDI is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_FTDI 0 #endif +// List of product IDs that can use the FTDI CDC driver. 0x0403 is FTDI's VID #ifndef CFG_TUH_CDC_FTDI_VID_PID_LIST - // List of product IDs that can use the FTDI CDC driver. 0x0403 is FTDI's VID #define CFG_TUH_CDC_FTDI_VID_PID_LIST \ {0x0403, 0x6001}, {0x0403, 0x6006}, {0x0403, 0x6010}, {0x0403, 0x6011}, \ {0x0403, 0x6014}, {0x0403, 0x6015}, {0x0403, 0x8372}, {0x0403, 0xFBFA}, \ {0x0403, 0xCD18} #endif +// CP210X is not part of CDC class, only to re-use CDC driver API #ifndef CFG_TUH_CDC_CP210X - // CP210X is not part of CDC class, only to re-use CDC driver API #define CFG_TUH_CDC_CP210X 0 #endif +// List of product IDs that can use the CP210X CDC driver. 0x10C4 is Silicon Labs' VID #ifndef CFG_TUH_CDC_CP210X_VID_PID_LIST - // List of product IDs that can use the CP210X CDC driver. 0x10C4 is Silicon Labs' VID #define CFG_TUH_CDC_CP210X_VID_PID_LIST \ {0x10C4, 0xEA60}, {0x10C4, 0xEA70} #endif @@ -496,8 +503,8 @@ #define CFG_TUH_CDC_CH34X 0 #endif +// List of product IDs that can use the CH34X CDC driver #ifndef CFG_TUH_CDC_CH34X_VID_PID_LIST - // List of product IDs that can use the CH34X CDC driver #define CFG_TUH_CDC_CH34X_VID_PID_LIST \ { 0x1a86, 0x5523 }, /* ch341 chip */ \ { 0x1a86, 0x7522 }, /* ch340k chip */ \ -- cgit v1.3.1 From 4ce439a75a6f7aa995c74e7ac32e70ab8216c771 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 24 May 2024 13:58:44 +0700 Subject: add ch32 support for fsdev driver. v20x can select fsdev or usbfs with make/cmake PORT=0/1. default to fsdev --- hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.h | 1 - hw/bsp/ch32v20x/family.c | 151 +++++-- hw/bsp/ch32v20x/family.cmake | 20 +- hw/bsp/ch32v20x/family.mk | 15 +- hw/bsp/ch32v20x/linker/ch32v20x.ld | 166 +++++++- src/common/tusb_compiler.h | 1 + src/common/tusb_mcu.h | 5 +- src/device/dcd.h | 7 +- src/device/usbd.c | 23 +- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 214 ++-------- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h | 551 ------------------------- src/portable/st/stm32_fsdev/fsdev_ch32.h | 232 +++++++++++ src/portable/st/stm32_fsdev/fsdev_common.h | 391 ++++++++++++++++++ src/portable/st/stm32_fsdev/fsdev_stm32.h | 292 +++++++++++++ src/tusb_option.h | 9 + 15 files changed, 1281 insertions(+), 797 deletions(-) delete mode 100644 src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h create mode 100644 src/portable/st/stm32_fsdev/fsdev_ch32.h create mode 100644 src/portable/st/stm32_fsdev/fsdev_common.h create mode 100644 src/portable/st/stm32_fsdev/fsdev_stm32.h (limited to 'src/portable') diff --git a/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.h b/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.h index c8d28d90f..3ed2aef04 100644 --- a/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.h +++ b/hw/bsp/ch32v20x/boards/ch32v203_r0_1v0/board.h @@ -8,7 +8,6 @@ extern "C" { #define LED_PORT GPIOA #define LED_PIN GPIO_Pin_15 #define LED_STATE_ON 0 -#define LED_CLOCK_EN() RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE) #ifdef __cplusplus } diff --git a/hw/bsp/ch32v20x/family.c b/hw/bsp/ch32v20x/family.c index 247dacde6..a0a8c3f50 100644 --- a/hw/bsp/ch32v20x/family.c +++ b/hw/bsp/ch32v20x/family.c @@ -1,82 +1,153 @@ #include #include "ch32v20x.h" + #include "bsp/board_api.h" #include "board.h" -__attribute__((interrupt)) +/* CH32v203 depending on variants can support 2 USB IPs: FSDEV and USBFS. + * By default, we use FSDEV, but you can explicitly select by define: + * - CFG_TUD_WCH_USBIP_FSDEV + * - CFG_TUD_WCH_USBIP_USBFS + */ + +// USBFS +__attribute__((interrupt)) __attribute__((used)) void USBHD_IRQHandler(void) { - tud_int_handler(0); + #if CFG_TUD_WCH_USBIP_USBFS + tud_int_handler(0); + #endif +} + +__attribute__((interrupt)) __attribute__((used)) +void USBHDWakeUp_IRQHandler(void) { + #if CFG_TUD_WCH_USBIP_USBFS + tud_int_handler(0); + #endif +} + +// USBD (fsdev) +__attribute__((interrupt)) __attribute__((used)) +void USB_LP_CAN1_RX0_IRQHandler(void) { + #if CFG_TUD_WCH_USBIP_FSDEV + tud_int_handler(0); + #endif } +__attribute__((interrupt)) __attribute__((used)) +void USB_HP_CAN1_TX_IRQHandler(void) { + #if CFG_TUD_WCH_USBIP_FSDEV + tud_int_handler(0); + #endif + +} + +__attribute__((interrupt)) __attribute__((used)) +void USBWakeUp_IRQHandler(void) { + #if CFG_TUD_WCH_USBIP_FSDEV + tud_int_handler(0); + #endif +} + + #if CFG_TUSB_OS == OPT_OS_NONE volatile uint32_t system_ticks = 0; __attribute__((interrupt)) void SysTick_Handler(void) { - SysTick->SR = 0; - system_ticks++; + SysTick->SR = 0; + system_ticks++; } uint32_t SysTick_Config(uint32_t ticks) { - NVIC_EnableIRQ(SysTicK_IRQn); - SysTick->CTLR = 0; - SysTick->SR = 0; - SysTick->CNT = 0; - SysTick->CMP = ticks-1; - SysTick->CTLR = 0xF; - return 0; + NVIC_EnableIRQ(SysTicK_IRQn); + SysTick->CTLR = 0; + SysTick->SR = 0; + SysTick->CNT = 0; + SysTick->CMP = ticks - 1; + SysTick->CTLR = 0xF; + return 0; } uint32_t board_millis(void) { - return system_ticks; + return system_ticks; } #endif void board_init(void) { - __disable_irq(); + __disable_irq(); #if CFG_TUSB_OS == OPT_OS_NONE - SysTick_Config(SystemCoreClock / 1000); + SysTick_Config(SystemCoreClock / 1000); #endif - switch (SystemCoreClock) { - case 48000000: RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div1); break; - case 96000000: RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div2); break; - case 144000000: RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div3); break; - default: TU_ASSERT(0,); break; - } - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE); - - LED_CLOCK_EN(); - GPIO_InitTypeDef GPIO_InitStructure = { - .GPIO_Pin = LED_PIN, - .GPIO_Mode = GPIO_Mode_Out_OD, - .GPIO_Speed = GPIO_Speed_50MHz, - }; - GPIO_Init(LED_PORT, &GPIO_InitStructure); - - __enable_irq(); - board_delay(2); + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); + + uint8_t usb_div; + switch (SystemCoreClock) { + case 48000000: usb_div = RCC_USBCLKSource_PLLCLK_Div1; break; + case 96000000: usb_div = RCC_USBCLKSource_PLLCLK_Div2; break; + case 144000000: usb_div = RCC_USBCLKSource_PLLCLK_Div3; break; + default: TU_ASSERT(0,); break; + } + RCC_USBCLKConfig(usb_div); + RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE); // FSDEV + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_OTG_FS, ENABLE); // USB FS + + GPIO_InitTypeDef GPIO_InitStructure = { + .GPIO_Pin = LED_PIN, + .GPIO_Mode = GPIO_Mode_Out_OD, + .GPIO_Speed = GPIO_Speed_50MHz, + }; + GPIO_Init(LED_PORT, &GPIO_InitStructure); + + // UART TX is PA9 + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); + GPIO_InitTypeDef usart_init = { + .GPIO_Pin = GPIO_Pin_9, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Mode = GPIO_Mode_AF_PP, + }; + GPIO_Init(GPIOA, &usart_init); + + USART_InitTypeDef usart = { + .USART_BaudRate = 115200, + .USART_WordLength = USART_WordLength_8b, + .USART_StopBits = USART_StopBits_1, + .USART_Parity = USART_Parity_No, + .USART_Mode = USART_Mode_Tx, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + }; + USART_Init(USART1, &usart); + USART_Cmd(USART1, ENABLE); + + __enable_irq(); + board_delay(2); + + printf("SystemCoreClock = %ld\r\n", SystemCoreClock); } void board_led_write(bool state) { - GPIO_WriteBit(LED_PORT, LED_PIN, state); + GPIO_WriteBit(LED_PORT, LED_PIN, state); } uint32_t board_button_read(void) { - return false; + return false; } int board_uart_read(uint8_t *buf, int len) { - (void) buf; - (void) len; - return 0; + (void) buf; + (void) len; + return 0; } int board_uart_write(void const *buf, int len) { - (void) buf; - (void) len; - return len; + const char *bufc = (const char *) buf; + for (int i = 0; i < len; i++) { + while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); + USART_SendData(USART1, *bufc++); + } + + return len; } diff --git a/hw/bsp/ch32v20x/family.cmake b/hw/bsp/ch32v20x/family.cmake index 80b035fc0..3fb1c0e79 100644 --- a/hw/bsp/ch32v20x/family.cmake +++ b/hw/bsp/ch32v20x/family.cmake @@ -14,6 +14,11 @@ set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TO set(FAMILY_MCUS CH32V20X CACHE INTERNAL "") set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") +# Port0 use FSDev, Port1 use USBFS +if (NOT DEFINED PORT) + set(PORT 0) +endif() + #------------------------------------ # BOARD_TARGET #------------------------------------ @@ -48,9 +53,20 @@ function(add_board_target BOARD_TARGET) ) target_compile_definitions(${BOARD_TARGET} PUBLIC CH32V20x_${MCU_VARIANT} - BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED ) + if (PORT EQUAL 0) + target_compile_definitions(${BOARD_TARGET} PUBLIC + CFG_TUD_WCH_USBIP_FSDEV=1 + ) + elseif (PORT EQUAL 1) + target_compile_definitions(${BOARD_TARGET} PUBLIC + CFG_TUD_WCH_USBIP_USBFS=1 + ) + else() + message(FATAL_ERROR "Invalid PORT ${PORT}") + endif() + update_board(${BOARD_TARGET}) if (CMAKE_C_COMPILER_ID STREQUAL "GNU") @@ -99,8 +115,10 @@ function(family_configure_example TARGET RTOS) # Add TinyUSB target and port source family_add_tinyusb(${TARGET} OPT_MCU_CH32V20X ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC ${TOP}/src/portable/wch/dcd_ch32_usbfs.c + ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c ) target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) diff --git a/hw/bsp/ch32v20x/family.mk b/hw/bsp/ch32v20x/family.mk index 5c8b31a1c..49d4d2feb 100644 --- a/hw/bsp/ch32v20x/family.mk +++ b/hw/bsp/ch32v20x/family.mk @@ -14,13 +14,23 @@ SDK_SRC_DIR = $(SDK_DIR)/EVT/EXAM/SRC include $(TOP)/$(BOARD_PATH)/board.mk CPU_CORE ?= rv32imac-ilp32 +# Port0 use FSDev, Port1 use USBFS +PORT ?= 0 + CFLAGS += \ -mcmodel=medany \ -ffat-lto-objects \ -flto \ -DCH32V20x_${MCU_VARIANT} \ - -DCFG_TUSB_MCU=OPT_MCU_CH32V20X \ - -DBOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED \ + -DCFG_TUSB_MCU=OPT_MCU_CH32V20X + +ifeq ($(PORT),0) + $(info "Using FSDEV driver") + CFLAGS += -DCFG_TUD_WCH_USBIP_FSDEV=1 +else + $(info "Using USBFS driver") + CFLAGS += -DCFG_TUD_WCH_USBIP_USBFS=1 +endif LDFLAGS_GCC += \ -nostdlib -nostartfiles \ @@ -30,6 +40,7 @@ LD_FILE = $(FAMILY_PATH)/linker/${CH32_FAMILY}.ld SRC_C += \ src/portable/wch/dcd_ch32_usbfs.c \ + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ $(SDK_SRC_DIR)/Core/core_riscv.c \ $(SDK_SRC_DIR)/Peripheral/src/ch32v20x_gpio.c \ $(SDK_SRC_DIR)/Peripheral/src/ch32v20x_misc.c \ diff --git a/hw/bsp/ch32v20x/linker/ch32v20x.ld b/hw/bsp/ch32v20x/linker/ch32v20x.ld index 6ee2fa1c7..cd5c8dc17 100644 --- a/hw/bsp/ch32v20x/linker/ch32v20x.ld +++ b/hw/bsp/ch32v20x/linker/ch32v20x.ld @@ -1 +1,165 @@ -/* Define default values if not already defined */ __FLASH_SIZE = DEFINED(__flash_size) ? __flash_size : 64K; __RAM_SIZE = DEFINED(__ram_size) ? __ram_size : 20K; MEMORY { FLASH (rx) : ORIGIN = 0x00000000, LENGTH = __FLASH_SIZE RAM (xrw) : ORIGIN = 0x20000000, LENGTH = __RAM_SIZE } ENTRY( _start ) __stack_size = 2048; PROVIDE( _stack_size = __stack_size ); SECTIONS { .init : { _sinit = .; . = ALIGN(4); KEEP(*(SORT_NONE(.init))) . = ALIGN(4); _einit = .; } >FLASH AT>FLASH .vector : { *(.vector); . = ALIGN(64); } >FLASH AT>FLASH .text : { . = ALIGN(4); *(.text) *(.text.*) *(.rodata) *(.rodata*) *(.gnu.linkonce.t.*) . = ALIGN(4); } >FLASH AT>FLASH .fini : { KEEP(*(SORT_NONE(.fini))) . = ALIGN(4); } >FLASH AT>FLASH PROVIDE( _etext = . ); PROVIDE( _eitcm = . ); .preinit_array : { PROVIDE_HIDDEN (__preinit_array_start = .); KEEP (*(.preinit_array)) PROVIDE_HIDDEN (__preinit_array_end = .); } >FLASH AT>FLASH .init_array : { PROVIDE_HIDDEN (__init_array_start = .); KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) PROVIDE_HIDDEN (__init_array_end = .); } >FLASH AT>FLASH .fini_array : { PROVIDE_HIDDEN (__fini_array_start = .); KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) PROVIDE_HIDDEN (__fini_array_end = .); } >FLASH AT>FLASH .ctors : { /* gcc uses crtbegin.o to find the start of the constructors, so we make sure it is first. Because this is a wildcard, it doesn't matter if the user does not actually link against crtbegin.o; the linker won't look for a file to match a wildcard. The wildcard also means that it doesn't matter which directory crtbegin.o is in. */ KEEP (*crtbegin.o(.ctors)) KEEP (*crtbegin?.o(.ctors)) /* We don't want to include the .ctor section from the crtend.o file until after the sorted ctors. The .ctor section from the crtend file contains the end of ctors marker and it must be last */ KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) KEEP (*(SORT(.ctors.*))) KEEP (*(.ctors)) } >FLASH AT>FLASH .dtors : { KEEP (*crtbegin.o(.dtors)) KEEP (*crtbegin?.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) KEEP (*(SORT(.dtors.*))) KEEP (*(.dtors)) } >FLASH AT>FLASH .dalign : { . = ALIGN(4); PROVIDE(_data_vma = .); } >RAM AT>FLASH .dlalign : { . = ALIGN(4); PROVIDE(_data_lma = .); } >FLASH AT>FLASH .data : { *(.gnu.linkonce.r.*) *(.data .data.*) *(.gnu.linkonce.d.*) . = ALIGN(8); PROVIDE( __global_pointer$ = . + 0x800 ); *(.sdata .sdata.*) *(.sdata2.*) *(.gnu.linkonce.s.*) . = ALIGN(8); *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*) . = ALIGN(4); PROVIDE( _edata = .); } >RAM AT>FLASH .bss : { . = ALIGN(4); PROVIDE( _sbss = .); *(.sbss*) *(.gnu.linkonce.sb.*) *(.bss*) *(.gnu.linkonce.b.*) *(COMMON*) . = ALIGN(4); PROVIDE( _ebss = .); } >RAM AT>FLASH PROVIDE( _end = _ebss); PROVIDE( end = . ); .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size : { PROVIDE( _heap_end = . ); . = ALIGN(4); PROVIDE(_susrstack = . ); . = . + __stack_size; PROVIDE( _eusrstack = .); } >RAM } +/* Define default values if not already defined */ +__FLASH_SIZE = DEFINED(__flash_size) ? __flash_size : 64K; +__RAM_SIZE = DEFINED(__ram_size) ? __ram_size : 20K; + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = __FLASH_SIZE + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = __RAM_SIZE +} + +ENTRY( _start ) + +__stack_size = 2048; + +PROVIDE( _stack_size = __stack_size ); + +SECTIONS +{ + .init : + { + _sinit = .; + . = ALIGN(4); + KEEP(*(SORT_NONE(.init))) + . = ALIGN(4); + _einit = .; + } >FLASH AT>FLASH + + .vector : + { + *(.vector); + . = ALIGN(64); + } >FLASH AT>FLASH + + .text : + { + . = ALIGN(4); + *(.text) + *(.text.*) + *(.rodata) + *(.rodata*) + *(.gnu.linkonce.t.*) + . = ALIGN(4); + } >FLASH AT>FLASH + + .fini : + { + KEEP(*(SORT_NONE(.fini))) + . = ALIGN(4); + } >FLASH AT>FLASH + + PROVIDE( _etext = . ); + PROVIDE( _eitcm = . ); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH AT>FLASH + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH AT>FLASH + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH AT>FLASH + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >FLASH AT>FLASH + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >FLASH AT>FLASH + + .dalign : + { + . = ALIGN(4); + PROVIDE(_data_vma = .); + } >RAM AT>FLASH + + .dlalign : + { + . = ALIGN(4); + PROVIDE(_data_lma = .); + } >FLASH AT>FLASH + + .data : + { + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.sdata2.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + . = ALIGN(4); + PROVIDE( _edata = .); + } >RAM AT>FLASH + + .bss : + { + . = ALIGN(4); + PROVIDE( _sbss = .); + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss*) + *(.gnu.linkonce.b.*) + *(COMMON*) + . = ALIGN(4); + PROVIDE( _ebss = .); + } >RAM AT>FLASH + + PROVIDE( _end = _ebss); + PROVIDE( end = . ); + + .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = ALIGN(4); + PROVIDE(_susrstack = . ); + . = . + __stack_size; + PROVIDE( _eusrstack = .); + } >RAM + +} diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index 0d5570b1c..ce5566ffe 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -128,6 +128,7 @@ #define TU_ATTR_SECTION(sec_name) __attribute__ ((section(#sec_name))) #define TU_ATTR_PACKED __attribute__ ((packed)) #define TU_ATTR_WEAK __attribute__ ((weak)) + // #define TU_ATTR_WEAK_ALIAS(f) __attribute__ ((weak, alias(#f)) #ifndef TU_ATTR_ALWAYS_INLINE // allow to override for debug #define TU_ATTR_ALWAYS_INLINE __attribute__ ((always_inline)) #endif diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index af11ecb9b..c66996c4f 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -423,7 +423,6 @@ #elif TU_CHECK_MCU(OPT_MCU_CH32V20X) // v20x support both FSDEV (USBD) and USBFS, default to FSDEV #define TUP_USBIP_WCH_USBFS - #define TUP_DCD_ENDPOINT_MAX 8 #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_CH32 @@ -431,10 +430,12 @@ #define CFG_TUD_WCH_USBIP_USBFS 0 #endif - #if !defined(CFG_TUD_WCH_FSDEV) + #if !defined(CFG_TUD_WCH_USBIP_FSDEV) #define CFG_TUD_WCH_USBIP_FSDEV (CFG_TUD_WCH_USBIP_USBFS ? 0 : 1) #endif + #define TUP_DCD_ENDPOINT_MAX 8 + #elif TU_CHECK_MCU(OPT_MCU_CH32V307) // v307 support both FS and HS, default to HS #define TUP_USBIP_WCH_USBHS diff --git a/src/device/dcd.h b/src/device/dcd.h index 9447d6d9d..2d3dafa4c 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -39,9 +39,6 @@ // Configuration //--------------------------------------------------------------------+ -#ifndef CFG_TUD_ENDPPOINT_MAX - #define CFG_TUD_ENDPPOINT_MAX TUP_DCD_ENDPOINT_MAX -#endif //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES @@ -149,10 +146,10 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr); void dcd_remote_wakeup(uint8_t rhport); // Connect by enabling internal pull-up resistor on D+/D- -void dcd_connect(uint8_t rhport) TU_ATTR_WEAK; +void dcd_connect(uint8_t rhport); // Disconnect by disabling internal pull-up resistor on D+/D- -void dcd_disconnect(uint8_t rhport) TU_ATTR_WEAK; +void dcd_disconnect(uint8_t rhport); // Enable/Disable Start-of-frame interrupt. Default is disabled void dcd_sof_enable(uint8_t rhport, bool en); diff --git a/src/device/usbd.c b/src/device/usbd.c index 9a6afd0d1..88183fad0 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -45,11 +45,6 @@ //--------------------------------------------------------------------+ // Weak stubs: invoked if no strong implementation is available //--------------------------------------------------------------------+ -TU_ATTR_WEAK bool dcd_deinit(uint8_t rhport) { - (void) rhport; - return false; -} - TU_ATTR_WEAK void tud_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr) { (void)rhport; (void)eventid; @@ -60,6 +55,19 @@ TU_ATTR_WEAK void tud_sof_cb(uint32_t frame_count) { (void)frame_count; } +TU_ATTR_WEAK bool dcd_deinit(uint8_t rhport) { + (void) rhport; + return false; +} + +TU_ATTR_WEAK void dcd_connect(uint8_t rhport) { + (void) rhport; +} + +TU_ATTR_WEAK void dcd_disconnect(uint8_t rhport) { + (void) rhport; +} + //--------------------------------------------------------------------+ // Device Data //--------------------------------------------------------------------+ @@ -379,19 +387,16 @@ bool tud_remote_wakeup(void) { } bool tud_disconnect(void) { - TU_VERIFY(dcd_disconnect); dcd_disconnect(_usbd_rhport); return true; } bool tud_connect(void) { - TU_VERIFY(dcd_connect); dcd_connect(_usbd_rhport); return true; } -bool tud_sof_cb_enable(bool en) -{ +bool tud_sof_cb_enable(bool en) { usbd_sof_enable(_usbd_rhport, SOF_CONSUMER_USER, en); return true; } diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index a26c66892..9ce37f992 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -102,25 +102,29 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && defined(TUP_USBIP_FSDEV) +#if CFG_TUD_ENABLED && defined(TUP_USBIP_FSDEV) && \ + !(defined(TUP_USBIP_FSDEV_CH32) && CFG_TUD_WCH_USBIP_FSDEV == 0) #include "device/dcd.h" -#ifdef TUP_USBIP_FSDEV_STM32 -// Undefine to reduce the dependence on HAL -#undef USE_HAL_DRIVER -#include "portable/st/stm32_fsdev/dcd_stm32_fsdev.h" +#if defined(TUP_USBIP_FSDEV_STM32) + // Undefine to reduce the dependence on HAL + #undef USE_HAL_DRIVER + #include "fsdev_stm32.h" +#elif defined(TUP_USBIP_FSDEV_CH32) + #include "fsdev_ch32.h" +#else + #error "Unknown USB IP" #endif -/***************************************************** - * Configuration - *****************************************************/ +#include "fsdev_common.h" -// HW supports max of 8 bidirectional endpoints, but this can be reduced to save RAM -// (8u here would mean 8 IN and 8 OUT) -#ifndef MAX_EP_COUNT -#define MAX_EP_COUNT 8U -#endif +//--------------------------------------------------------------------+ +// Configuration +//--------------------------------------------------------------------+ + +// hardware limit endpoint +#define FSDEV_EP_COUNT 8 // If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it // Both of these MUST be a multiple of 2, and are in byte units. @@ -132,11 +136,6 @@ #define DCD_STM32_BTABLE_SIZE (FSDEV_PMA_SIZE - DCD_STM32_BTABLE_BASE) #endif -/*************************************************** - * Checks, structs, defines, function definitions, etc. - */ - -TU_VERIFY_STATIC((MAX_EP_COUNT) <= STFSDEV_EP_COUNT, "Only 8 endpoints supported on the hardware"); TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) + (DCD_STM32_BTABLE_SIZE)) <= (FSDEV_PMA_SIZE), "BTABLE does not fit in PMA RAM"); TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) % 8) == 0, "BTABLE base must be aligned to 8 bytes"); @@ -162,9 +161,9 @@ typedef struct { bool allocated[2]; } ep_alloc_t; -static xfer_ctl_t xfer_status[MAX_EP_COUNT][2]; +static xfer_ctl_t xfer_status[CFG_TUD_ENDPPOINT_MAX][2]; -static ep_alloc_t ep_alloc_status[STFSDEV_EP_COUNT]; +static ep_alloc_t ep_alloc_status[FSDEV_EP_COUNT]; static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[6]; @@ -199,7 +198,7 @@ TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t *xfer_ctl_ptr(uint32_t ep_addr) uint8_t epnum = tu_edpt_number(ep_addr); uint8_t dir = tu_edpt_dir(ep_addr); // Fix -Werror=null-dereference - TU_ASSERT(epnum < MAX_EP_COUNT, &xfer_status[0][0]); + TU_ASSERT(epnum < CFG_TUD_ENDPPOINT_MAX, &xfer_status[0][0]); return &xfer_status[epnum][dir]; } @@ -239,7 +238,7 @@ void dcd_init(uint8_t rhport) USB->ISTR = 0; // Clear pending interrupts // Reset endpoints to disabled - for (uint32_t i = 0; i < STFSDEV_EP_COUNT; i++) { + for (uint32_t i = 0; i < FSDEV_EP_COUNT; i++) { // This doesn't clear all bits since some bits are "toggle", but does set the type to DISABLED. pcd_set_endpoint(USB, i, 0u); } @@ -248,43 +247,9 @@ void dcd_init(uint8_t rhport) dcd_handle_bus_reset(); // Enable pull-up if supported - if (dcd_connect) { - dcd_connect(rhport); - } -} - -// Define only on MCU with internal pull-up. BSP can define on MCU without internal PU. -#if defined(USB_BCDR_DPPU) - -// Disable internal D+ PU -void dcd_disconnect(uint8_t rhport) -{ - (void)rhport; - USB->BCDR &= ~(USB_BCDR_DPPU); -} - -// Enable internal D+ PU -void dcd_connect(uint8_t rhport) -{ - (void)rhport; - USB->BCDR |= USB_BCDR_DPPU; -} - -#elif defined(SYSCFG_PMC_USB_PU) // works e.g. on STM32L151 -// Disable internal D+ PU -void dcd_disconnect(uint8_t rhport) -{ - (void)rhport; - SYSCFG->PMC &= ~(SYSCFG_PMC_USB_PU); + dcd_connect(rhport); } -// Enable internal D+ PU -void dcd_connect(uint8_t rhport) -{ - (void)rhport; - SYSCFG->PMC |= SYSCFG_PMC_USB_PU; -} -#endif void dcd_sof_enable(uint8_t rhport, bool en) { @@ -298,126 +263,6 @@ void dcd_sof_enable(uint8_t rhport, bool en) } } -// Enable device interrupt -void dcd_int_enable(uint8_t rhport) -{ - (void)rhport; - // Member here forces write to RAM before allowing ISR to execute - __DSB(); - __ISB(); -#if CFG_TUSB_MCU == OPT_MCU_STM32F0 || CFG_TUSB_MCU == OPT_MCU_STM32L0 || CFG_TUSB_MCU == OPT_MCU_STM32L4 - NVIC_EnableIRQ(USB_IRQn); - -#elif CFG_TUSB_MCU == OPT_MCU_STM32L1 - NVIC_EnableIRQ(USB_LP_IRQn); - -#elif CFG_TUSB_MCU == OPT_MCU_STM32F3 -// Some STM32F302/F303 devices allow to remap the USB interrupt vectors from -// shared USB/CAN IRQs to separate CAN and USB IRQs. -// This dynamically checks if this remap is active to enable the right IRQs. -#ifdef SYSCFG_CFGR1_USB_IT_RMP - if (SYSCFG->CFGR1 & SYSCFG_CFGR1_USB_IT_RMP) { - NVIC_EnableIRQ(USB_HP_IRQn); - NVIC_EnableIRQ(USB_LP_IRQn); - NVIC_EnableIRQ(USBWakeUp_RMP_IRQn); - } else -#endif - { - NVIC_EnableIRQ(USB_HP_CAN_TX_IRQn); - NVIC_EnableIRQ(USB_LP_CAN_RX0_IRQn); - NVIC_EnableIRQ(USBWakeUp_IRQn); - } -#elif CFG_TUSB_MCU == OPT_MCU_STM32F1 - NVIC_EnableIRQ(USB_HP_CAN1_TX_IRQn); - NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn); - NVIC_EnableIRQ(USBWakeUp_IRQn); - -#elif CFG_TUSB_MCU == OPT_MCU_STM32G4 - NVIC_EnableIRQ(USB_HP_IRQn); - NVIC_EnableIRQ(USB_LP_IRQn); - NVIC_EnableIRQ(USBWakeUp_IRQn); - -#elif CFG_TUSB_MCU == OPT_MCU_STM32G0 -#ifdef STM32G0B0xx - NVIC_EnableIRQ(USB_IRQn); -#else - NVIC_EnableIRQ(USB_UCPD1_2_IRQn); -#endif - -#elif CFG_TUSB_MCU == OPT_MCU_STM32H5 - NVIC_EnableIRQ(USB_DRD_FS_IRQn); - -#elif CFG_TUSB_MCU == OPT_MCU_STM32WB - NVIC_EnableIRQ(USB_HP_IRQn); - NVIC_EnableIRQ(USB_LP_IRQn); - -#elif CFG_TUSB_MCU == OPT_MCU_STM32L5 - NVIC_EnableIRQ(USB_FS_IRQn); - -#else -#error Unknown arch in USB driver -#endif -} - -// Disable device interrupt -void dcd_int_disable(uint8_t rhport) -{ - (void)rhport; - -#if CFG_TUSB_MCU == OPT_MCU_STM32F0 || CFG_TUSB_MCU == OPT_MCU_STM32L0 || CFG_TUSB_MCU == OPT_MCU_STM32L4 - NVIC_DisableIRQ(USB_IRQn); -#elif CFG_TUSB_MCU == OPT_MCU_STM32L1 - NVIC_DisableIRQ(USB_LP_IRQn); -#elif CFG_TUSB_MCU == OPT_MCU_STM32F3 -// Some STM32F302/F303 devices allow to remap the USB interrupt vectors from -// shared USB/CAN IRQs to separate CAN and USB IRQs. -// This dynamically checks if this remap is active to disable the right IRQs. -#ifdef SYSCFG_CFGR1_USB_IT_RMP - if (SYSCFG->CFGR1 & SYSCFG_CFGR1_USB_IT_RMP) { - NVIC_DisableIRQ(USB_HP_IRQn); - NVIC_DisableIRQ(USB_LP_IRQn); - NVIC_DisableIRQ(USBWakeUp_RMP_IRQn); - } else -#endif - { - NVIC_DisableIRQ(USB_HP_CAN_TX_IRQn); - NVIC_DisableIRQ(USB_LP_CAN_RX0_IRQn); - NVIC_DisableIRQ(USBWakeUp_IRQn); - } -#elif CFG_TUSB_MCU == OPT_MCU_STM32F1 - NVIC_DisableIRQ(USB_HP_CAN1_TX_IRQn); - NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn); - NVIC_DisableIRQ(USBWakeUp_IRQn); - -#elif CFG_TUSB_MCU == OPT_MCU_STM32G4 - NVIC_DisableIRQ(USB_HP_IRQn); - NVIC_DisableIRQ(USB_LP_IRQn); - NVIC_DisableIRQ(USBWakeUp_IRQn); - -#elif CFG_TUSB_MCU == OPT_MCU_STM32G0 -#ifdef STM32G0B0xx - NVIC_DisableIRQ(USB_IRQn); -#else - NVIC_DisableIRQ(USB_UCPD1_2_IRQn); -#endif - -#elif CFG_TUSB_MCU == OPT_MCU_STM32H5 - NVIC_DisableIRQ(USB_DRD_FS_IRQn); - -#elif CFG_TUSB_MCU == OPT_MCU_STM32WB - NVIC_DisableIRQ(USB_HP_IRQn); - NVIC_DisableIRQ(USB_LP_IRQn); - -#elif CFG_TUSB_MCU == OPT_MCU_STM32L5 - NVIC_DisableIRQ(USB_FS_IRQn); - -#else -#error Unknown arch in USB driver -#endif - - // CMSIS has a membar after disabling interrupts -} - // Receive Set Address request, mcu port must also include status IN response void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { @@ -461,7 +306,7 @@ static void dcd_handle_bus_reset(void) { USB->DADDR = 0u; // disable USB peripheral by clearing the EF flag - for (uint32_t i = 0; i < STFSDEV_EP_COUNT; i++) { + for (uint32_t i = 0; i < FSDEV_EP_COUNT; i++) { // Clear EP allocation status ep_alloc_status[i].ep_num = 0xFF; ep_alloc_status[i].ep_type = 0xFF; @@ -470,7 +315,7 @@ static void dcd_handle_bus_reset(void) } // Reset PMA allocation - ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8 * MAX_EP_COUNT; + ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX; dcd_edpt_open(0, &ep0OUT_desc); dcd_edpt_open(0, &ep0IN_desc); @@ -653,7 +498,6 @@ static void dcd_ep_ctr_handler(void) void dcd_int_handler(uint8_t rhport) { - (void)rhport; uint32_t int_status = USB->ISTR; @@ -774,7 +618,7 @@ static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type) uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - for (uint8_t i = 0; i < STFSDEV_EP_COUNT; i++) { + for (uint8_t i = 0; i < FSDEV_EP_COUNT; i++) { // Check if already allocated if (ep_alloc_status[i].allocated[dir] && ep_alloc_status[i].ep_type == ep_type && @@ -818,7 +662,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc) uint16_t pma_addr; uint32_t wType; - TU_ASSERT(ep_idx < STFSDEV_EP_COUNT); + TU_ASSERT(ep_idx < FSDEV_EP_COUNT); TU_ASSERT(buffer_size <= 64); // Set type @@ -865,7 +709,7 @@ void dcd_edpt_close_all(uint8_t rhport) { (void)rhport; - for (uint32_t i = 1; i < STFSDEV_EP_COUNT; i++) { + for (uint32_t i = 1; i < FSDEV_EP_COUNT; i++) { // Reset endpoint pcd_set_endpoint(USB, i, 0); // Clear EP allocation status @@ -876,7 +720,7 @@ void dcd_edpt_close_all(uint8_t rhport) } // Reset PMA allocation - ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8 * MAX_EP_COUNT + 2 * CFG_TUD_ENDPOINT0_SIZE; + ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX + 2 * CFG_TUD_ENDPOINT0_SIZE; } /** @@ -1155,7 +999,7 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui } if (wNBytes) { - temp1 = *srcVal; + temp1 = (uint16_t) *srcVal; *pdwVal = temp1; } diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h deleted file mode 100644 index 7992f34a1..000000000 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.h +++ /dev/null @@ -1,551 +0,0 @@ -/* - * Copyright(c) 2016 STMicroelectronics - * Copyright(c) N Conrad - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. Neither the name of STMicroelectronics nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This file is part of the TinyUSB stack. - */ - -// This file contains source copied from ST's HAL, and thus should have their copyright statement. - -// FSDEV_PMA_SIZE is PMA buffer size in bytes. -// On 512-byte devices, access with a stride of two words (use every other 16-bit address) -// On 1024-byte devices, access with a stride of one word (use every 16-bit address) - -#ifndef PORTABLE_ST_STM32F0_DCD_STM32F0_FSDEV_PVT_ST_H_ -#define PORTABLE_ST_STM32F0_DCD_STM32F0_FSDEV_PVT_ST_H_ - -#if CFG_TUSB_MCU == OPT_MCU_STM32F0 - #include "stm32f0xx.h" - #define FSDEV_PMA_SIZE (1024u) - // F0x2 models are crystal-less - // All have internal D+ pull-up - // 070RB: 2 x 16 bits/word memory LPM Support, BCD Support - // PMA dedicated to USB (no sharing with CAN) - -#elif CFG_TUSB_MCU == OPT_MCU_STM32F1 - #include "stm32f1xx.h" - #define FSDEV_PMA_SIZE (512u) - // NO internal Pull-ups - // *B, and *C: 2 x 16 bits/word - - // F1 names this differently from the rest - #define USB_CNTR_LPMODE USB_CNTR_LP_MODE - -#elif defined(STM32F302xB) || defined(STM32F302xC) || \ - defined(STM32F303xB) || defined(STM32F303xC) || \ - defined(STM32F373xC) - #include "stm32f3xx.h" - #define FSDEV_PMA_SIZE (512u) - // NO internal Pull-ups - // *B, and *C: 1 x 16 bits/word - // PMA dedicated to USB (no sharing with CAN) - -#elif defined(STM32F302x6) || defined(STM32F302x8) || \ - defined(STM32F302xD) || defined(STM32F302xE) || \ - defined(STM32F303xD) || defined(STM32F303xE) - #include "stm32f3xx.h" - #define FSDEV_PMA_SIZE (1024u) - // NO internal Pull-ups - // *6, *8, *D, and *E: 2 x 16 bits/word LPM Support - // When CAN clock is enabled, USB can use first 768 bytes ONLY. - -#elif CFG_TUSB_MCU == OPT_MCU_STM32L0 - #include "stm32l0xx.h" - #define FSDEV_PMA_SIZE (1024u) - -#elif CFG_TUSB_MCU == OPT_MCU_STM32L1 - #include "stm32l1xx.h" - #define FSDEV_PMA_SIZE (512u) - -#elif CFG_TUSB_MCU == OPT_MCU_STM32G4 - #include "stm32g4xx.h" - #define FSDEV_PMA_SIZE (1024u) - -#elif CFG_TUSB_MCU == OPT_MCU_STM32G0 - #include "stm32g0xx.h" - #define FSDEV_BUS_32BIT - #define FSDEV_PMA_SIZE (2048u) - #undef USB_PMAADDR - #define USB_PMAADDR USB_DRD_PMAADDR - #define USB_TypeDef USB_DRD_TypeDef - #define EP0R CHEP0R - #define USB_EP_CTR_RX USB_EP_VTRX - #define USB_EP_CTR_TX USB_EP_VTTX - #define USB_EP_T_FIELD USB_CHEP_UTYPE - #define USB_EPREG_MASK USB_CHEP_REG_MASK - #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK - #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK - #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1 - #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2 - #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1 - #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 - #define USB_EPRX_STAT USB_CH_RX_VALID - #define USB_EPKIND_MASK USB_EP_KIND_MASK - #define USB USB_DRD_FS - #define USB_CNTR_FRES USB_CNTR_USBRST - #define USB_CNTR_RESUME USB_CNTR_L2RES - #define USB_ISTR_EP_ID USB_ISTR_IDN - #define USB_EPADDR_FIELD USB_CHEP_ADDR - #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY - #define USB_CNTR_FSUSP USB_CNTR_SUSPEN - -#elif CFG_TUSB_MCU == OPT_MCU_STM32H5 - #include "stm32h5xx.h" - #define FSDEV_BUS_32BIT - - #if !defined(USB_DRD_BASE) && defined(USB_DRD_FS_BASE) - #define USB_DRD_BASE USB_DRD_FS_BASE - #endif - - #define FSDEV_PMA_SIZE (2048u) - #undef USB_PMAADDR - #define USB_PMAADDR USB_DRD_PMAADDR - #define USB_TypeDef USB_DRD_TypeDef - #define EP0R CHEP0R - #define USB_EP_CTR_RX USB_EP_VTRX - #define USB_EP_CTR_TX USB_EP_VTTX - #define USB_EP_T_FIELD USB_CHEP_UTYPE - #define USB_EPREG_MASK USB_CHEP_REG_MASK - #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK - #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK - #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1 - #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2 - #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1 - #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 - #define USB_EPRX_STAT USB_CH_RX_VALID - #define USB_EPKIND_MASK USB_EP_KIND_MASK - #define USB USB_DRD_FS - #define USB_CNTR_FRES USB_CNTR_USBRST - #define USB_CNTR_RESUME USB_CNTR_L2RES - #define USB_ISTR_EP_ID USB_ISTR_IDN - #define USB_EPADDR_FIELD USB_CHEP_ADDR - #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY - #define USB_CNTR_FSUSP USB_CNTR_SUSPEN - -#elif CFG_TUSB_MCU == OPT_MCU_STM32WB - #include "stm32wbxx.h" - #define FSDEV_PMA_SIZE (1024u) - /* ST provided header has incorrect value */ - #undef USB_PMAADDR - #define USB_PMAADDR USB1_PMAADDR - -#elif CFG_TUSB_MCU == OPT_MCU_STM32L4 - #include "stm32l4xx.h" - #define FSDEV_PMA_SIZE (1024u) - -#elif CFG_TUSB_MCU == OPT_MCU_STM32L5 - #include "stm32l5xx.h" - #define FSDEV_PMA_SIZE (1024u) - - #ifndef USB_PMAADDR - #define USB_PMAADDR (USB_BASE + (USB_PMAADDR_NS - USB_BASE_NS)) - #endif - -#else - #error You are using an untested or unimplemented STM32 variant. Please update the driver. - // This includes L1x0, L1x1, L1x2, L4x2 and L4x3, G1x1, G1x3, and G1x4 -#endif - -// For purposes of accessing the packet -#if ((FSDEV_PMA_SIZE) == 512u) - #define FSDEV_PMA_STRIDE (2u) -#elif ((FSDEV_PMA_SIZE) == 1024u) - #define FSDEV_PMA_STRIDE (1u) -#endif - -// The fsdev_bus_t type can be used for both register and PMA access necessities -// For type-safety create a new macro for the volatile address of PMAADDR -// The compiler should warn us if we cast it to a non-volatile type? -#ifdef FSDEV_BUS_32BIT -typedef uint32_t fsdev_bus_t; -static __IO uint32_t * const pma32 = (__IO uint32_t*)USB_PMAADDR; - -#else -typedef uint16_t fsdev_bus_t; -// Volatile is also needed to prevent the optimizer from changing access to 32-bit (as 32-bit access is forbidden) -static __IO uint16_t * const pma = (__IO uint16_t*)USB_PMAADDR; - -TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t * pcd_btable_word_ptr(USB_TypeDef * USBx, size_t x) { - size_t total_word_offset = (((USBx)->BTABLE)>>1) + x; - total_word_offset *= FSDEV_PMA_STRIDE; - return &(pma[total_word_offset]); -} - -TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) { - return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 1u); -} - -TU_ATTR_ALWAYS_INLINE static inline __IO uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) { - return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 3u); -} -#endif - -/* Aligned buffer size according to hardware */ -TU_ATTR_ALWAYS_INLINE static inline uint16_t pcd_aligned_buffer_size(uint16_t size) { - /* The STM32 full speed USB peripheral supports only a limited set of - * buffer sizes given by the RX buffer entry format in the USB_BTABLE. */ - uint16_t blocksize = (size > 62) ? 32 : 2; - - // Round up while dividing requested size by blocksize - uint16_t numblocks = (size + blocksize - 1) / blocksize ; - - return numblocks * blocksize; -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wRegValue) { -#ifdef FSDEV_BUS_32BIT - (void) USBx; - __O uint32_t *reg = (__O uint32_t *)(USB_DRD_BASE + bEpIdx*4); - *reg = wRegValue; -#else - __O uint16_t *reg = (__O uint16_t *)((&USBx->EP0R) + bEpIdx*2u); - *reg = (uint16_t)wRegValue; -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT - (void) USBx; - __I uint32_t *reg = (__I uint32_t *)(USB_DRD_BASE + bEpIdx*4); -#else - __I uint16_t *reg = (__I uint16_t *)((&USBx->EP0R) + bEpIdx*2u); -#endif - return *reg; -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wType) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= (uint32_t)USB_EP_T_MASK; - regVal |= wType; - regVal |= USB_EP_CTR_RX | USB_EP_CTR_TX; // These clear on write0, so must set high - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_eptype(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EP_T_FIELD; - return regVal; -} - -/** - * @brief Clears bit CTR_RX / CTR_TX in the endpoint register. - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @retval None - */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal &= ~USB_EP_CTR_RX; - regVal |= USB_EP_CTR_TX; // preserve CTR_TX (clears on writing 0) - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal &= ~USB_EP_CTR_TX; - regVal |= USB_EP_CTR_RX; // preserve CTR_RX (clears on writing 0) - pcd_set_endpoint(USBx, bEpIdx,regVal); -} - -/** - * @brief gets counter of the tx buffer. - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @retval Counter value - */ -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT - (void) USBx; - return (pma32[2*bEpIdx] & 0x03FF0000) >> 16; -#else - __I uint16_t *regPtr = pcd_ep_tx_cnt_ptr(USBx, bEpIdx); - return *regPtr & 0x3ffU; -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT - (void) USBx; - return (pma32[2*bEpIdx + 1] & 0x03FF0000) >> 16; -#else - __I uint16_t *regPtr = pcd_ep_rx_cnt_ptr(USBx, bEpIdx); - return *regPtr & 0x3ffU; -#endif -} - -#define pcd_get_ep_dbuf0_cnt pcd_get_ep_tx_cnt -#define pcd_get_ep_dbuf1_cnt pcd_get_ep_rx_cnt - -/** - * @brief Sets address in an endpoint register. - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @param bAddr Address. - * @retval None - */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t bAddr) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal |= bAddr; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx,regVal); -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT - (void) USBx; - return pma32[2*bEpIdx] & 0x0000FFFFu ; -#else - return *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 0u); -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT - (void) USBx; - return pma32[2*bEpIdx + 1] & 0x0000FFFFu; -#else - return *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 2u); -#endif -} - -#define pcd_get_ep_dbuf0_address pcd_get_ep_tx_address -#define pcd_get_ep_dbuf1_address pcd_get_ep_rx_address - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { -#ifdef FSDEV_BUS_32BIT - (void) USBx; - pma32[2*bEpIdx] = (pma32[2*bEpIdx] & 0xFFFF0000u) | (addr & 0x0000FFFCu); -#else - *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 0u) = addr; -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { -#ifdef FSDEV_BUS_32BIT - (void) USBx; - pma32[2*bEpIdx + 1] = (pma32[2*bEpIdx + 1] & 0xFFFF0000u) | (addr & 0x0000FFFCu); -#else - *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 2u) = addr; -#endif -} - -#define pcd_set_ep_dbuf0_address pcd_set_ep_tx_address -#define pcd_set_ep_dbuf1_address pcd_set_ep_rx_address - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { -#ifdef FSDEV_BUS_32BIT - (void) USBx; - pma32[2*bEpIdx] = (pma32[2*bEpIdx] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16); -#else - __IO uint16_t * reg = pcd_ep_tx_cnt_ptr(USBx, bEpIdx); - *reg = (uint16_t) (*reg & (uint16_t) ~0x3FFU) | (wCount & 0x3FFU); -#endif -} - -#define pcd_set_ep_tx_dbuf0_cnt pcd_set_ep_tx_cnt - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_dbuf1_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { -#ifdef FSDEV_BUS_32BIT - (void) USBx; - pma32[2*bEpIdx + 1] = (pma32[2*bEpIdx + 1] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16); -#else - __IO uint16_t * reg = pcd_ep_rx_cnt_ptr(USBx, bEpIdx); - *reg = (uint16_t) (*reg & (uint16_t) ~0x3FFU) | (wCount & 0x3FFU); -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_blsize_num_blocks(USB_TypeDef * USBx, uint32_t rxtx_idx, - uint32_t blocksize, uint32_t numblocks) { - /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ -#ifdef FSDEV_BUS_32BIT - (void) USBx; - pma32[rxtx_idx] = (pma32[rxtx_idx] & 0x0000FFFFu) | (blocksize << 31) | ((numblocks - blocksize) << 26); -#else - __IO uint16_t *pdwReg = pcd_btable_word_ptr(USBx, rxtx_idx*2u + 1u); - *pdwReg = (blocksize << 15) | ((numblocks - blocksize) << 10); -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_bufsize(USB_TypeDef * USBx, uint32_t rxtx_idx, uint32_t wCount) { - wCount = pcd_aligned_buffer_size(wCount); - - /* We assume that the buffer size is already aligned to hardware requirements. */ - uint16_t blocksize = (wCount > 62) ? 1 : 0; - uint16_t numblocks = wCount / (blocksize ? 32 : 2); - - /* There should be no remainder in the above calculation */ - TU_ASSERT((wCount - (numblocks * (blocksize ? 32 : 2))) == 0, /**/); - - /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ - pcd_set_ep_blsize_num_blocks(USBx, rxtx_idx, blocksize, numblocks); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_dbuf0_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { - pcd_set_ep_bufsize(USBx, 2*bEpIdx, wCount); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { - pcd_set_ep_bufsize(USBx, 2*bEpIdx + 1, wCount); -} - -#define pcd_set_ep_rx_dbuf1_cnt pcd_set_ep_rx_cnt - -/** - * @brief sets the status for tx transfer (bits STAT_TX[1:0]). - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @param wState new state - * @retval None - */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPTX_DTOGMASK; - - /* toggle first bit ? */ - if((USB_EPTX_DTOG1 & (wState))!= 0U) - { - regVal ^= USB_EPTX_DTOG1; - } - /* toggle second bit ? */ - if((USB_EPTX_DTOG2 & ((uint32_t)(wState)))!= 0U) - { - regVal ^= USB_EPTX_DTOG2; - } - - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -/** - * @brief sets the status for rx transfer (bits STAT_TX[1:0]) - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @param wState new state - * @retval None - */ - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPRX_DTOGMASK; - - /* toggle first bit ? */ - if((USB_EPRX_DTOG1 & wState)!= 0U) { - regVal ^= USB_EPRX_DTOG1; - } - /* toggle second bit ? */ - if((USB_EPRX_DTOG2 & wState)!= 0U) { - regVal ^= USB_EPRX_DTOG2; - } - - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - return (regVal & USB_EPRX_STAT) >> (12u); -} - - -/** - * @brief Toggles DTOG_RX / DTOG_TX bit in the endpoint register. - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @retval None - */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_RX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_tx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_TX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -/** - * @brief Clears DTOG_RX / DTOG_TX bit in the endpoint register. - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @retval None - */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - if((regVal & USB_EP_DTOG_RX) != 0) { - pcd_rx_dtog(USBx,bEpIdx); - } -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - if((regVal & USB_EP_DTOG_TX) != 0) { - pcd_tx_dtog(USBx,bEpIdx); - } -} - -/** - * @brief set & clear EP_KIND bit. - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @retval None - */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal |= USB_EP_KIND; - regVal &= USB_EPREG_MASK; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPKIND_MASK; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -// This checks if the device has "LPM" -#if defined(USB_ISTR_L1REQ) -#define USB_ISTR_L1REQ_FORCED (USB_ISTR_L1REQ) -#else -#define USB_ISTR_L1REQ_FORCED ((uint16_t)0x0000U) -#endif - -#define USB_ISTR_ALL_EVENTS (USB_ISTR_PMAOVR | USB_ISTR_ERR | USB_ISTR_WKUP | USB_ISTR_SUSP | \ - USB_ISTR_RESET | USB_ISTR_SOF | USB_ISTR_ESOF | USB_ISTR_L1REQ_FORCED ) - -// Number of endpoints in hardware -// TODO should use TUP_DCD_ENDPOINT_MAX -#define STFSDEV_EP_COUNT (8u) - -#endif /* PORTABLE_ST_STM32F0_DCD_STM32F0_FSDEV_PVT_ST_H_ */ diff --git a/src/portable/st/stm32_fsdev/fsdev_ch32.h b/src/portable/st/stm32_fsdev/fsdev_ch32.h new file mode 100644 index 000000000..85fe3266c --- /dev/null +++ b/src/portable/st/stm32_fsdev/fsdev_ch32.h @@ -0,0 +1,232 @@ +/* +* The MIT License (MIT) + * + * Copyright (c) 2024, hathach (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. + * + */ +/**

© Copyright (c) 2016 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + */ + +#ifndef TUSB_FSDEV_CH32_H +#define TUSB_FSDEV_CH32_H + +#include "common/tusb_compiler.h" + +#if CFG_TUSB_MCU == OPT_MCU_CH32V20X + #include + +#elif CFG_TUSB_MCU == OPT_MCU_CH32F20X + #include +#endif + +#define FSDEV_PMA_SIZE (512u) + +// volatile 32-bit aligned +#define _va32 volatile TU_ATTR_ALIGNED(4) + +typedef struct { + _va32 uint16_t EP0R; // 00: USB Endpoint 0 register + _va32 uint16_t EP1R; // 04: USB Endpoint 1 register + _va32 uint16_t EP2R; // 08: USB Endpoint 2 register + _va32 uint16_t EP3R; // 0C: USB Endpoint 3 register + _va32 uint16_t EP4R; // 10: USB Endpoint 4 register + _va32 uint16_t EP5R; // 14: USB Endpoint 5 register + _va32 uint16_t EP6R; // 18: USB Endpoint 6 register + _va32 uint16_t EP7R; // 1C: USB Endpoint 7 register + _va32 uint16_t RESERVED7[16]; // Reserved + _va32 uint16_t CNTR; // 40: Control register + _va32 uint16_t ISTR; // 44: Interrupt status register + _va32 uint16_t FNR; // 48: Frame number register + _va32 uint16_t DADDR; // 4C: Device address register + _va32 uint16_t BTABLE; // 50: Buffer Table address register +} USB_TypeDef; + +TU_VERIFY_STATIC(sizeof(USB_TypeDef) == 0x54, "Size is not correct"); +TU_VERIFY_STATIC(offsetof(USB_TypeDef, CNTR) == 0x40, "Wrong offset"); + +#define USB_BASE (APB1PERIPH_BASE + 0x00005C00UL) /*!< USB_IP Peripheral Registers base address */ +#define USB_PMAADDR (APB1PERIPH_BASE + 0x00006000UL) /*!< USB_IP Packet Memory Area base address */ +#define USB ((USB_TypeDef *)USB_BASE) + +/******************************************************************************/ +/* */ +/* USB Device General registers */ +/* */ +/******************************************************************************/ +#define USB_CNTR (USB_BASE + 0x40U) /*!< Control register */ +#define USB_ISTR (USB_BASE + 0x44U) /*!< Interrupt status register */ +#define USB_FNR (USB_BASE + 0x48U) /*!< Frame number register */ +#define USB_DADDR (USB_BASE + 0x4CU) /*!< Device address register */ +#define USB_BTABLE (USB_BASE + 0x50U) /*!< Buffer Table address register */ + +/**************************** ISTR interrupt events *************************/ +#define USB_ISTR_CTR ((uint16_t)0x8000U) /*!< Correct TRansfer (clear-only bit) */ +#define USB_ISTR_PMAOVR ((uint16_t)0x4000U) /*!< DMA OVeR/underrun (clear-only bit) */ +#define USB_ISTR_ERR ((uint16_t)0x2000U) /*!< ERRor (clear-only bit) */ +#define USB_ISTR_WKUP ((uint16_t)0x1000U) /*!< WaKe UP (clear-only bit) */ +#define USB_ISTR_SUSP ((uint16_t)0x0800U) /*!< SUSPend (clear-only bit) */ +#define USB_ISTR_RESET ((uint16_t)0x0400U) /*!< RESET (clear-only bit) */ +#define USB_ISTR_SOF ((uint16_t)0x0200U) /*!< Start Of Frame (clear-only bit) */ +#define USB_ISTR_ESOF ((uint16_t)0x0100U) /*!< Expected Start Of Frame (clear-only bit) */ +#define USB_ISTR_DIR ((uint16_t)0x0010U) /*!< DIRection of transaction (read-only bit) */ +#define USB_ISTR_EP_ID ((uint16_t)0x000FU) /*!< EndPoint IDentifier (read-only bit) */ + +/* Legacy defines */ +#define USB_ISTR_PMAOVRM USB_ISTR_PMAOVR + +#define USB_CLR_CTR (~USB_ISTR_CTR) /*!< clear Correct TRansfer bit */ +#define USB_CLR_PMAOVR (~USB_ISTR_PMAOVR) /*!< clear DMA OVeR/underrun bit*/ +#define USB_CLR_ERR (~USB_ISTR_ERR) /*!< clear ERRor bit */ +#define USB_CLR_WKUP (~USB_ISTR_WKUP) /*!< clear WaKe UP bit */ +#define USB_CLR_SUSP (~USB_ISTR_SUSP) /*!< clear SUSPend bit */ +#define USB_CLR_RESET (~USB_ISTR_RESET) /*!< clear RESET bit */ +#define USB_CLR_SOF (~USB_ISTR_SOF) /*!< clear Start Of Frame bit */ +#define USB_CLR_ESOF (~USB_ISTR_ESOF) /*!< clear Expected Start Of Frame bit */ + +/* Legacy defines */ +#define USB_CLR_PMAOVRM USB_CLR_PMAOVR + +/************************* CNTR control register bits definitions ***********/ +#define USB_CNTR_CTRM ((uint16_t)0x8000U) /*!< Correct TRansfer Mask */ +#define USB_CNTR_PMAOVR ((uint16_t)0x4000U) /*!< DMA OVeR/underrun Mask */ +#define USB_CNTR_ERRM ((uint16_t)0x2000U) /*!< ERRor Mask */ +#define USB_CNTR_WKUPM ((uint16_t)0x1000U) /*!< WaKe UP Mask */ +#define USB_CNTR_SUSPM ((uint16_t)0x0800U) /*!< SUSPend Mask */ +#define USB_CNTR_RESETM ((uint16_t)0x0400U) /*!< RESET Mask */ +#define USB_CNTR_SOFM ((uint16_t)0x0200U) /*!< Start Of Frame Mask */ +#define USB_CNTR_ESOFM ((uint16_t)0x0100U) /*!< Expected Start Of Frame Mask */ +#define USB_CNTR_RESUME ((uint16_t)0x0010U) /*!< RESUME request */ +#define USB_CNTR_FSUSP ((uint16_t)0x0008U) /*!< Force SUSPend */ +#define USB_CNTR_LPMODE ((uint16_t)0x0004U) /*!< Low-power MODE */ +#define USB_CNTR_PDWN ((uint16_t)0x0002U) /*!< Power DoWN */ +#define USB_CNTR_FRES ((uint16_t)0x0001U) /*!< Force USB RESet */ + +/* Legacy defines */ +#define USB_CNTR_PMAOVRM USB_CNTR_PMAOVR +#define USB_CNTR_LP_MODE USB_CNTR_LPMODE + +/******************** FNR Frame Number Register bit definitions ************/ +#define USB_FNR_RXDP ((uint16_t)0x8000U) /*!< status of D+ data line */ +#define USB_FNR_RXDM ((uint16_t)0x4000U) /*!< status of D- data line */ +#define USB_FNR_LCK ((uint16_t)0x2000U) /*!< LoCKed */ +#define USB_FNR_LSOF ((uint16_t)0x1800U) /*!< Lost SOF */ +#define USB_FNR_FN ((uint16_t)0x07FFU) /*!< Frame Number */ + +/******************** DADDR Device ADDRess bit definitions ****************/ +#define USB_DADDR_EF ((uint8_t)0x80U) /*!< USB device address Enable Function */ +#define USB_DADDR_ADD ((uint8_t)0x7FU) /*!< USB device address */ + +/****************************** Endpoint register *************************/ +#define USB_EP0R USB_BASE /*!< endpoint 0 register address */ +#define USB_EP1R (USB_BASE + 0x04U) /*!< endpoint 1 register address */ +#define USB_EP2R (USB_BASE + 0x08U) /*!< endpoint 2 register address */ +#define USB_EP3R (USB_BASE + 0x0CU) /*!< endpoint 3 register address */ +#define USB_EP4R (USB_BASE + 0x10U) /*!< endpoint 4 register address */ +#define USB_EP5R (USB_BASE + 0x14U) /*!< endpoint 5 register address */ +#define USB_EP6R (USB_BASE + 0x18U) /*!< endpoint 6 register address */ +#define USB_EP7R (USB_BASE + 0x1CU) /*!< endpoint 7 register address */ +/* bit positions */ +#define USB_EP_CTR_RX ((uint16_t)0x8000U) /*!< EndPoint Correct TRansfer RX */ +#define USB_EP_DTOG_RX ((uint16_t)0x4000U) /*!< EndPoint Data TOGGLE RX */ +#define USB_EPRX_STAT ((uint16_t)0x3000U) /*!< EndPoint RX STATus bit field */ +#define USB_EP_SETUP ((uint16_t)0x0800U) /*!< EndPoint SETUP */ +#define USB_EP_T_FIELD ((uint16_t)0x0600U) /*!< EndPoint TYPE */ +#define USB_EP_KIND ((uint16_t)0x0100U) /*!< EndPoint KIND */ +#define USB_EP_CTR_TX ((uint16_t)0x0080U) /*!< EndPoint Correct TRansfer TX */ +#define USB_EP_DTOG_TX ((uint16_t)0x0040U) /*!< EndPoint Data TOGGLE TX */ +#define USB_EPTX_STAT ((uint16_t)0x0030U) /*!< EndPoint TX STATus bit field */ +#define USB_EPADDR_FIELD ((uint16_t)0x000FU) /*!< EndPoint ADDRess FIELD */ + +/* EndPoint REGister MASK (no toggle fields) */ +#define USB_EPREG_MASK (USB_EP_CTR_RX|USB_EP_SETUP|USB_EP_T_FIELD|USB_EP_KIND|USB_EP_CTR_TX|USB_EPADDR_FIELD) + /*!< EP_TYPE[1:0] EndPoint TYPE */ +#define USB_EP_TYPE_MASK ((uint16_t)0x0600U) /*!< EndPoint TYPE Mask */ +#define USB_EP_BULK ((uint16_t)0x0000U) /*!< EndPoint BULK */ +#define USB_EP_CONTROL ((uint16_t)0x0200U) /*!< EndPoint CONTROL */ +#define USB_EP_ISOCHRONOUS ((uint16_t)0x0400U) /*!< EndPoint ISOCHRONOUS */ +#define USB_EP_INTERRUPT ((uint16_t)0x0600U) /*!< EndPoint INTERRUPT */ +#define USB_EP_T_MASK ((uint16_t) ~USB_EP_T_FIELD & USB_EPREG_MASK) + +#define USB_EPKIND_MASK ((uint16_t) ~USB_EP_KIND & USB_EPREG_MASK) /*!< EP_KIND EndPoint KIND */ + /*!< STAT_TX[1:0] STATus for TX transfer */ +#define USB_EP_TX_DIS ((uint16_t)0x0000U) /*!< EndPoint TX DISabled */ +#define USB_EP_TX_STALL ((uint16_t)0x0010U) /*!< EndPoint TX STALLed */ +#define USB_EP_TX_NAK ((uint16_t)0x0020U) /*!< EndPoint TX NAKed */ +#define USB_EP_TX_VALID ((uint16_t)0x0030U) /*!< EndPoint TX VALID */ +#define USB_EPTX_DTOG1 ((uint16_t)0x0010U) /*!< EndPoint TX Data TOGgle bit1 */ +#define USB_EPTX_DTOG2 ((uint16_t)0x0020U) /*!< EndPoint TX Data TOGgle bit2 */ +#define USB_EPTX_DTOGMASK (USB_EPTX_STAT|USB_EPREG_MASK) + /*!< STAT_RX[1:0] STATus for RX transfer */ +#define USB_EP_RX_DIS ((uint16_t)0x0000U) /*!< EndPoint RX DISabled */ +#define USB_EP_RX_STALL ((uint16_t)0x1000U) /*!< EndPoint RX STALLed */ +#define USB_EP_RX_NAK ((uint16_t)0x2000U) /*!< EndPoint RX NAKed */ +#define USB_EP_RX_VALID ((uint16_t)0x3000U) /*!< EndPoint RX VALID */ +#define USB_EPRX_DTOG1 ((uint16_t)0x1000U) /*!< EndPoint RX Data TOGgle bit1 */ +#define USB_EPRX_DTOG2 ((uint16_t)0x2000U) /*!< EndPoint RX Data TOGgle bit1 */ +#define USB_EPRX_DTOGMASK (USB_EPRX_STAT|USB_EPREG_MASK) + + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + +#if CFG_TUSB_MCU == OPT_MCU_CH32V20X +static const IRQn_Type fsdev_irq[] = { + USB_HP_CAN1_TX_IRQn, + USB_LP_CAN1_RX0_IRQn, + USBWakeUp_IRQn +}; +enum { FSDEV_IRQ_NUM = TU_ARRAY_SIZE(fsdev_irq) }; +#else + #error "Unsupported MCU" +#endif + +void dcd_int_enable(uint8_t rhport) { + (void)rhport; + for(uint8_t i=0; i < FSDEV_IRQ_NUM; i++) { + NVIC_EnableIRQ(fsdev_irq[i]); + } +} + +void dcd_int_disable(uint8_t rhport) { + (void)rhport; + for(uint8_t i=0; i < FSDEV_IRQ_NUM; i++) { + NVIC_DisableIRQ(fsdev_irq[i]); + } +} + +void dcd_disconnect(uint8_t rhport) { + (void) rhport; + EXTEN->EXTEN_CTR &= ~EXTEN_USBD_PU_EN; +} + +void dcd_connect(uint8_t rhport) { + (void) rhport; + EXTEN->EXTEN_CTR |= EXTEN_USBD_PU_EN; +} + +#endif diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h new file mode 100644 index 000000000..af5d8afab --- /dev/null +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -0,0 +1,391 @@ +/* + * The MIT License (MIT) + * + * Copyright(c) 2016 STMicroelectronics + * Copyright(c) N Conrad + * Copyright (c) 2024, hathach (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. + * + */ + +#ifndef TUSB_FSDEV_COMMON_H +#define TUSB_FSDEV_COMMON_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "stdint.h" + +// FSDEV_PMA_SIZE is PMA buffer size in bytes. +// On 512-byte devices, access with a stride of two words (use every other 16-bit address) +// On 1024-byte devices, access with a stride of one word (use every 16-bit address) + +// For purposes of accessing the packet +#if ((FSDEV_PMA_SIZE) == 512u) + #define FSDEV_PMA_STRIDE (2u) +#elif ((FSDEV_PMA_SIZE) == 1024u) + #define FSDEV_PMA_STRIDE (1u) +#endif + +// The fsdev_bus_t type can be used for both register and PMA access necessities +// For type-safety create a new macro for the volatile address of PMAADDR +// The compiler should warn us if we cast it to a non-volatile type? +#ifdef FSDEV_BUS_32BIT +typedef uint32_t fsdev_bus_t; +static volatile uint32_t * const pma32 = (volatile uint32_t*)USB_PMAADDR; + +#else +typedef uint16_t fsdev_bus_t; +// Volatile is also needed to prevent the optimizer from changing access to 32-bit (as 32-bit access is forbidden) +static volatile uint16_t * const pma = (volatile uint16_t*)USB_PMAADDR; + +TU_ATTR_ALWAYS_INLINE static inline volatile uint16_t * pcd_btable_word_ptr(USB_TypeDef * USBx, size_t x) { + size_t total_word_offset = (((USBx)->BTABLE)>>1) + x; + total_word_offset *= FSDEV_PMA_STRIDE; + return &(pma[total_word_offset]); +} + +TU_ATTR_ALWAYS_INLINE static inline volatile uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) { + return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 1u); +} + +TU_ATTR_ALWAYS_INLINE static inline volatile uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) { + return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 3u); +} +#endif + +/* Aligned buffer size according to hardware */ +TU_ATTR_ALWAYS_INLINE static inline uint16_t pcd_aligned_buffer_size(uint16_t size) { + /* The STM32 full speed USB peripheral supports only a limited set of + * buffer sizes given by the RX buffer entry format in the USB_BTABLE. */ + uint16_t blocksize = (size > 62) ? 32 : 2; + + // Round up while dividing requested size by blocksize + uint16_t numblocks = (size + blocksize - 1) / blocksize ; + + return numblocks * blocksize; +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wRegValue) { +#ifdef FSDEV_BUS_32BIT + (void) USBx; + volatile uint32_t *reg = (volatile uint32_t *)(USB_DRD_BASE + bEpIdx*4); + *reg = wRegValue; +#else + volatile uint16_t *reg = (volatile uint16_t *)((&USBx->EP0R) + bEpIdx*2u); + *reg = (uint16_t)wRegValue; +#endif +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx) { +#ifdef FSDEV_BUS_32BIT + (void) USBx; + volatile const uint32_t *reg = (volatile const uint32_t *)(USB_DRD_BASE + bEpIdx*4); +#else + volatile const uint16_t *reg = (volatile const uint16_t *)((&USBx->EP0R) + bEpIdx*2u); +#endif + return *reg; +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wType) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= (uint32_t)USB_EP_T_MASK; + regVal |= wType; + regVal |= USB_EP_CTR_RX | USB_EP_CTR_TX; // These clear on write0, so must set high + pcd_set_endpoint(USBx, bEpIdx, regVal); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_eptype(USB_TypeDef * USBx, uint32_t bEpIdx) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= USB_EP_T_FIELD; + return regVal; +} + +/** + * @brief Clears bit CTR_RX / CTR_TX in the endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpIdx Endpoint Number. + * @retval None + */ +TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= USB_EPREG_MASK; + regVal &= ~USB_EP_CTR_RX; + regVal |= USB_EP_CTR_TX; // preserve CTR_TX (clears on writing 0) + pcd_set_endpoint(USBx, bEpIdx, regVal); +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= USB_EPREG_MASK; + regVal &= ~USB_EP_CTR_TX; + regVal |= USB_EP_CTR_RX; // preserve CTR_RX (clears on writing 0) + pcd_set_endpoint(USBx, bEpIdx,regVal); +} + +/** + * @brief gets counter of the tx buffer. + * @param USBx USB peripheral instance register address. + * @param bEpIdx Endpoint Number. + * @retval Counter value + */ +TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { +#ifdef FSDEV_BUS_32BIT + (void) USBx; + return (pma32[2*bEpIdx] & 0x03FF0000) >> 16; +#else + volatile const uint16_t *regPtr = pcd_ep_tx_cnt_ptr(USBx, bEpIdx); + return *regPtr & 0x3ffU; +#endif +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { +#ifdef FSDEV_BUS_32BIT + (void) USBx; + return (pma32[2*bEpIdx + 1] & 0x03FF0000) >> 16; +#else + volatile const uint16_t *regPtr = pcd_ep_rx_cnt_ptr(USBx, bEpIdx); + return *regPtr & 0x3ffU; +#endif +} + +#define pcd_get_ep_dbuf0_cnt pcd_get_ep_tx_cnt +#define pcd_get_ep_dbuf1_cnt pcd_get_ep_rx_cnt + +/** + * @brief Sets address in an endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpIdx Endpoint Number. + * @param bAddr Address. + * @retval None + */ +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t bAddr) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= USB_EPREG_MASK; + regVal |= bAddr; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpIdx,regVal); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { +#ifdef FSDEV_BUS_32BIT + (void) USBx; + return pma32[2*bEpIdx] & 0x0000FFFFu ; +#else + return *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 0u); +#endif +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { +#ifdef FSDEV_BUS_32BIT + (void) USBx; + return pma32[2*bEpIdx + 1] & 0x0000FFFFu; +#else + return *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 2u); +#endif +} + +#define pcd_get_ep_dbuf0_address pcd_get_ep_tx_address +#define pcd_get_ep_dbuf1_address pcd_get_ep_rx_address + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { +#ifdef FSDEV_BUS_32BIT + (void) USBx; + pma32[2*bEpIdx] = (pma32[2*bEpIdx] & 0xFFFF0000u) | (addr & 0x0000FFFCu); +#else + *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 0u) = addr; +#endif +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { +#ifdef FSDEV_BUS_32BIT + (void) USBx; + pma32[2*bEpIdx + 1] = (pma32[2*bEpIdx + 1] & 0xFFFF0000u) | (addr & 0x0000FFFCu); +#else + *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 2u) = addr; +#endif +} + +#define pcd_set_ep_dbuf0_address pcd_set_ep_tx_address +#define pcd_set_ep_dbuf1_address pcd_set_ep_rx_address + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { +#ifdef FSDEV_BUS_32BIT + (void) USBx; + pma32[2*bEpIdx] = (pma32[2*bEpIdx] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16); +#else + volatile uint16_t * reg = pcd_ep_tx_cnt_ptr(USBx, bEpIdx); + *reg = (uint16_t) (*reg & (uint16_t) ~0x3FFU) | (wCount & 0x3FFU); +#endif +} + +#define pcd_set_ep_tx_dbuf0_cnt pcd_set_ep_tx_cnt + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_dbuf1_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { +#ifdef FSDEV_BUS_32BIT + (void) USBx; + pma32[2*bEpIdx + 1] = (pma32[2*bEpIdx + 1] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16); +#else + volatile uint16_t * reg = pcd_ep_rx_cnt_ptr(USBx, bEpIdx); + *reg = (uint16_t) (*reg & (uint16_t) ~0x3FFU) | (wCount & 0x3FFU); +#endif +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_blsize_num_blocks(USB_TypeDef * USBx, uint32_t rxtx_idx, + uint32_t blocksize, uint32_t numblocks) { + /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ +#ifdef FSDEV_BUS_32BIT + (void) USBx; + pma32[rxtx_idx] = (pma32[rxtx_idx] & 0x0000FFFFu) | (blocksize << 31) | ((numblocks - blocksize) << 26); +#else + volatile uint16_t *pdwReg = pcd_btable_word_ptr(USBx, rxtx_idx*2u + 1u); + *pdwReg = (blocksize << 15) | ((numblocks - blocksize) << 10); +#endif +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_bufsize(USB_TypeDef * USBx, uint32_t rxtx_idx, uint32_t wCount) { + wCount = pcd_aligned_buffer_size(wCount); + + /* We assume that the buffer size is already aligned to hardware requirements. */ + uint16_t blocksize = (wCount > 62) ? 1 : 0; + uint16_t numblocks = wCount / (blocksize ? 32 : 2); + + /* There should be no remainder in the above calculation */ + TU_ASSERT((wCount - (numblocks * (blocksize ? 32 : 2))) == 0, /**/); + + /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ + pcd_set_ep_blsize_num_blocks(USBx, rxtx_idx, blocksize, numblocks); +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_dbuf0_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { + pcd_set_ep_bufsize(USBx, 2*bEpIdx, wCount); +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { + pcd_set_ep_bufsize(USBx, 2*bEpIdx + 1, wCount); +} + +#define pcd_set_ep_rx_dbuf1_cnt pcd_set_ep_rx_cnt + +/** + * @brief sets the status for tx transfer (bits STAT_TX[1:0]). + * @param USBx USB peripheral instance register address. + * @param bEpIdx Endpoint Number. + * @param wState new state + * @retval None + */ +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= USB_EPTX_DTOGMASK; + + /* toggle first bit ? */ + if((USB_EPTX_DTOG1 & (wState))!= 0U) + { + regVal ^= USB_EPTX_DTOG1; + } + /* toggle second bit ? */ + if((USB_EPTX_DTOG2 & ((uint32_t)(wState)))!= 0U) + { + regVal ^= USB_EPTX_DTOG2; + } + + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpIdx, regVal); +} + +/** + * @brief sets the status for rx transfer (bits STAT_TX[1:0]) + * @param USBx USB peripheral instance register address. + * @param bEpIdx Endpoint Number. + * @param wState new state + * @retval None + */ + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= USB_EPRX_DTOGMASK; + + /* toggle first bit ? */ + if((USB_EPRX_DTOG1 & wState)!= 0U) { + regVal ^= USB_EPRX_DTOG1; + } + /* toggle second bit ? */ + if((USB_EPRX_DTOG2 & wState)!= 0U) { + regVal ^= USB_EPRX_DTOG2; + } + + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpIdx, regVal); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + return (regVal & USB_EPRX_STAT) >> (12u); +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= USB_EPREG_MASK; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_RX; + pcd_set_endpoint(USBx, bEpIdx, regVal); +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_tx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= USB_EPREG_MASK; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_TX; + pcd_set_endpoint(USBx, bEpIdx, regVal); +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + if((regVal & USB_EP_DTOG_RX) != 0) { + pcd_rx_dtog(USBx,bEpIdx); + } +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + if((regVal & USB_EP_DTOG_TX) != 0) { + pcd_tx_dtog(USBx,bEpIdx); + } +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal |= USB_EP_KIND; + regVal &= USB_EPREG_MASK; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpIdx, regVal); +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= USB_EPKIND_MASK; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpIdx, regVal); +} + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h new file mode 100644 index 000000000..b3fa11b88 --- /dev/null +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -0,0 +1,292 @@ +/* + * The MIT License (MIT) + * + * Copyright(c) N Conrad + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef TUSB_FSDEV_STM32_H +#define TUSB_FSDEV_STM32_H + +#if CFG_TUSB_MCU == OPT_MCU_STM32F0 + #include "stm32f0xx.h" + #define FSDEV_PMA_SIZE (1024u) + // F0x2 models are crystal-less + // All have internal D+ pull-up + // 070RB: 2 x 16 bits/word memory LPM Support, BCD Support + // PMA dedicated to USB (no sharing with CAN) + +#elif CFG_TUSB_MCU == OPT_MCU_STM32F1 + #include "stm32f1xx.h" + #define FSDEV_PMA_SIZE (512u) + // NO internal Pull-ups + // *B, and *C: 2 x 16 bits/word + + // F1 names this differently from the rest + #define USB_CNTR_LPMODE USB_CNTR_LP_MODE + +#elif defined(STM32F302xB) || defined(STM32F302xC) || \ + defined(STM32F303xB) || defined(STM32F303xC) || \ + defined(STM32F373xC) + #include "stm32f3xx.h" + #define FSDEV_PMA_SIZE (512u) + // NO internal Pull-ups + // *B, and *C: 1 x 16 bits/word + // PMA dedicated to USB (no sharing with CAN) + +#elif defined(STM32F302x6) || defined(STM32F302x8) || \ + defined(STM32F302xD) || defined(STM32F302xE) || \ + defined(STM32F303xD) || defined(STM32F303xE) + #include "stm32f3xx.h" + #define FSDEV_PMA_SIZE (1024u) + // NO internal Pull-ups + // *6, *8, *D, and *E: 2 x 16 bits/word LPM Support + // When CAN clock is enabled, USB can use first 768 bytes ONLY. + +#elif CFG_TUSB_MCU == OPT_MCU_STM32L0 + #include "stm32l0xx.h" + #define FSDEV_PMA_SIZE (1024u) + +#elif CFG_TUSB_MCU == OPT_MCU_STM32L1 + #include "stm32l1xx.h" + #define FSDEV_PMA_SIZE (512u) + +#elif CFG_TUSB_MCU == OPT_MCU_STM32G4 + #include "stm32g4xx.h" + #define FSDEV_PMA_SIZE (1024u) + +#elif CFG_TUSB_MCU == OPT_MCU_STM32G0 + #include "stm32g0xx.h" + #define FSDEV_BUS_32BIT + #define FSDEV_PMA_SIZE (2048u) + #undef USB_PMAADDR + #define USB_PMAADDR USB_DRD_PMAADDR + #define USB_TypeDef USB_DRD_TypeDef + #define EP0R CHEP0R + #define USB_EP_CTR_RX USB_EP_VTRX + #define USB_EP_CTR_TX USB_EP_VTTX + #define USB_EP_T_FIELD USB_CHEP_UTYPE + #define USB_EPREG_MASK USB_CHEP_REG_MASK + #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK + #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK + #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1 + #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2 + #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1 + #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 + #define USB_EPRX_STAT USB_CH_RX_VALID + #define USB_EPKIND_MASK USB_EP_KIND_MASK + #define USB USB_DRD_FS + #define USB_CNTR_FRES USB_CNTR_USBRST + #define USB_CNTR_RESUME USB_CNTR_L2RES + #define USB_ISTR_EP_ID USB_ISTR_IDN + #define USB_EPADDR_FIELD USB_CHEP_ADDR + #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY + #define USB_CNTR_FSUSP USB_CNTR_SUSPEN + +#elif CFG_TUSB_MCU == OPT_MCU_STM32H5 + #include "stm32h5xx.h" + #define FSDEV_BUS_32BIT + + #if !defined(USB_DRD_BASE) && defined(USB_DRD_FS_BASE) + #define USB_DRD_BASE USB_DRD_FS_BASE + #endif + + #define FSDEV_PMA_SIZE (2048u) + #undef USB_PMAADDR + #define USB_PMAADDR USB_DRD_PMAADDR + #define USB_TypeDef USB_DRD_TypeDef + #define EP0R CHEP0R + #define USB_EP_CTR_RX USB_EP_VTRX + #define USB_EP_CTR_TX USB_EP_VTTX + #define USB_EP_T_FIELD USB_CHEP_UTYPE + #define USB_EPREG_MASK USB_CHEP_REG_MASK + #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK + #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK + #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1 + #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2 + #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1 + #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 + #define USB_EPRX_STAT USB_CH_RX_VALID + #define USB_EPKIND_MASK USB_EP_KIND_MASK + #define USB USB_DRD_FS + #define USB_CNTR_FRES USB_CNTR_USBRST + #define USB_CNTR_RESUME USB_CNTR_L2RES + #define USB_ISTR_EP_ID USB_ISTR_IDN + #define USB_EPADDR_FIELD USB_CHEP_ADDR + #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY + #define USB_CNTR_FSUSP USB_CNTR_SUSPEN + +#elif CFG_TUSB_MCU == OPT_MCU_STM32WB + #include "stm32wbxx.h" + #define FSDEV_PMA_SIZE (1024u) + /* ST provided header has incorrect value */ + #undef USB_PMAADDR + #define USB_PMAADDR USB1_PMAADDR + +#elif CFG_TUSB_MCU == OPT_MCU_STM32L4 + #include "stm32l4xx.h" + #define FSDEV_PMA_SIZE (1024u) + +#elif CFG_TUSB_MCU == OPT_MCU_STM32L5 + #include "stm32l5xx.h" + #define FSDEV_PMA_SIZE (1024u) + + #ifndef USB_PMAADDR + #define USB_PMAADDR (USB_BASE + (USB_PMAADDR_NS - USB_BASE_NS)) + #endif + +#else + #error You are using an untested or unimplemented STM32 variant. Please update the driver. + // This includes L1x0, L1x1, L1x2, L4x2 and L4x3, G1x1, G1x3, and G1x4 +#endif + +// This checks if the device has "LPM" +#if defined(USB_ISTR_L1REQ) +#define USB_ISTR_L1REQ_FORCED (USB_ISTR_L1REQ) +#else +#define USB_ISTR_L1REQ_FORCED ((uint16_t)0x0000U) +#endif + +#define USB_ISTR_ALL_EVENTS (USB_ISTR_PMAOVR | USB_ISTR_ERR | USB_ISTR_WKUP | USB_ISTR_SUSP | \ + USB_ISTR_RESET | USB_ISTR_SOF | USB_ISTR_ESOF | USB_ISTR_L1REQ_FORCED ) + +//--------------------------------------------------------------------+ +// +//--------------------------------------------------------------------+ + +#if TU_CHECK_MCU(OPT_MCU_STM32L1) && !defined(USBWakeUp_IRQn) + #define USBWakeUp_IRQn USB_FS_WKUP_IRQn +#endif + +static const IRQn_Type fsdev_irq[] = { + #if TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32L0, OPT_MCU_STM32L4) + USB_IRQn, + #elif CFG_TUSB_MCU == OPT_MCU_STM32F1 + USB_HP_CAN1_TX_IRQn, + USB_LP_CAN1_RX0_IRQn, + USBWakeUp_IRQn, + #elif CFG_TUSB_MCU == OPT_MCU_STM32F3 + // USB remap handles dcd functions + USB_HP_CAN_TX_IRQn, + USB_LP_CAN_RX0_IRQn, + USBWakeUp_IRQn, + #elif CFG_TUSB_MCU == OPT_MCU_STM32G0 + #ifdef STM32G0B0xx + USB_IRQn, + #else + USB_UCPD1_2_IRQn, + #endif + #elif TU_CHECK_MCU(OPT_MCU_STM32G4, OPT_MCU_STM32L1) + USB_HP_IRQn, + USB_LP_IRQn, + USBWakeUp_IRQn, + #elif CFG_TUSB_MCU == OPT_MCU_STM32H5 + USB_DRD_FS_IRQn, + #elif CFG_TUSB_MCU == OPT_MCU_STM32L5 + USB_FS_IRQn, + #elif CFG_TUSB_MCU == OPT_MCU_STM32WB + USB_HP_IRQn, + USB_LP_IRQn, + #else + #error Unknown arch in USB driver + #endif +}; +enum { FSDEV_IRQ_NUM = TU_ARRAY_SIZE(fsdev_irq) }; + +void dcd_int_enable(uint8_t rhport) { + (void)rhport; + + // forces write to RAM before allowing ISR to execute + __DSB(); __ISB(); + + #if CFG_TUSB_MCU == OPT_MCU_STM32F3 && defined(SYSCFG_CFGR1_USB_IT_RMP) + // Some STM32F302/F303 devices allow to remap the USB interrupt vectors from + // shared USB/CAN IRQs to separate CAN and USB IRQs. + // This dynamically checks if this remap is active to enable the right IRQs. + if (SYSCFG->CFGR1 & SYSCFG_CFGR1_USB_IT_RMP) { + NVIC_EnableIRQ(USB_HP_IRQn); + NVIC_EnableIRQ(USB_LP_IRQn); + NVIC_EnableIRQ(USBWakeUp_RMP_IRQn); + } else + #endif + { + for (uint8_t i = 0; i < FSDEV_IRQ_NUM; i++) { + NVIC_EnableIRQ(fsdev_irq[i]); + } + } +} + +void dcd_int_disable(uint8_t rhport) { + (void)rhport; + + #if CFG_TUSB_MCU == OPT_MCU_STM32F3 && defined(SYSCFG_CFGR1_USB_IT_RMP) + // Some STM32F302/F303 devices allow to remap the USB interrupt vectors from + // shared USB/CAN IRQs to separate CAN and USB IRQs. + // This dynamically checks if this remap is active to enable the right IRQs. + if (SYSCFG->CFGR1 & SYSCFG_CFGR1_USB_IT_RMP) { + NVIC_DisableIRQ(USB_HP_IRQn); + NVIC_DisableIRQ(USB_LP_IRQn); + NVIC_DisableIRQ(USBWakeUp_RMP_IRQn); + } else + #endif + { + for (uint8_t i = 0; i < FSDEV_IRQ_NUM; i++) { + NVIC_DisableIRQ(fsdev_irq[i]); + } + } + + // CMSIS has a membar after disabling interrupts +} + +// Define only on MCU with internal pull-up. BSP can define on MCU without internal PU. +#if defined(USB_BCDR_DPPU) + +void dcd_disconnect(uint8_t rhport) { + (void)rhport; + USB->BCDR &= ~(USB_BCDR_DPPU); +} + +void dcd_connect(uint8_t rhport) { + (void)rhport; + USB->BCDR |= USB_BCDR_DPPU; +} + +#elif defined(SYSCFG_PMC_USB_PU) // works e.g. on STM32L151 + +void dcd_disconnect(uint8_t rhport) { + (void)rhport; + SYSCFG->PMC &= ~(SYSCFG_PMC_USB_PU); +} + +void dcd_connect(uint8_t rhport) { + (void)rhport; + SYSCFG->PMC |= SYSCFG_PMC_USB_PU; +} +#endif + + +#endif /* TUSB_FSDEV_STM32_H */ diff --git a/src/tusb_option.h b/src/tusb_option.h index d74510b60..674c05e54 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -374,6 +374,15 @@ #define CFG_TUD_INTERFACE_MAX 16 #endif +// default to max hardware endpoint, but can be smaller to save RAM +#ifndef CFG_TUD_ENDPPOINT_MAX + #define CFG_TUD_ENDPPOINT_MAX TUP_DCD_ENDPOINT_MAX +#endif + +#if CFG_TUD_ENDPPOINT_MAX > TUP_DCD_ENDPOINT_MAX + #error "CFG_TUD_ENDPPOINT_MAX must be less than or equal to TUP_DCD_ENDPOINT_MAX" +#endif + // USB 2.0 compliance test mode support #ifndef CFG_TUD_TEST_MODE #define CFG_TUD_TEST_MODE 0 -- cgit v1.3.1 From a2e5ea1882f130ee22eedbb68296b4b5ce561f77 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Wed, 15 May 2024 21:23:39 +1000 Subject: chipidea/mimxrt: Add support for dcd_sof_enable(). --- src/portable/chipidea/ci_hs/dcd_ci_hs.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src/portable') diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index f9ec666e5..93e1d78dd 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -309,10 +309,12 @@ void dcd_disconnect(uint8_t rhport) void dcd_sof_enable(uint8_t rhport, bool en) { - (void) rhport; - (void) en; - - // TODO implement later + ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); + if (en) { + dcd_reg->USBINTR |= INTR_SOF; + } else { + dcd_reg->USBINTR &= ~INTR_SOF; + } } //--------------------------------------------------------------------+ @@ -679,7 +681,8 @@ void dcd_int_handler(uint8_t rhport) if (int_status & INTR_SOF) { - dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); + const uint32_t frame = dcd_reg->FRINDEX; + dcd_event_sof(rhport, frame, true); } } -- cgit v1.3.1 From e229270a1c3d542cdf9924313f585dd43c607de8 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Thu, 16 May 2024 14:12:22 +1000 Subject: microchip samd: Add support for dcd_sof_enable(). --- src/portable/microchip/samd/dcd_samd.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/portable') diff --git a/src/portable/microchip/samd/dcd_samd.c b/src/portable/microchip/samd/dcd_samd.c index 976d3dfd0..005b63faf 100644 --- a/src/portable/microchip/samd/dcd_samd.c +++ b/src/portable/microchip/samd/dcd_samd.c @@ -183,9 +183,12 @@ void dcd_connect(uint8_t rhport) void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; - (void) en; - // TODO implement later + if (en) { + USB->DEVICE.INTENSET.bit.SOF = 1; + } else { + USB->DEVICE.INTENCLR.bit.SOF = 1; + } } /*------------------------------------------------------------------*/ @@ -374,7 +377,9 @@ void dcd_int_handler (uint8_t rhport) if ( int_status & USB_DEVICE_INTFLAG_SOF ) { USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_SOF; - dcd_event_bus_signal(0, DCD_EVENT_SOF, true); + const uint32_t frame = USB->DEVICE.FNUM.bit.FNUM; + dcd_event_sof(0, frame, true); + //dcd_event_bus_signal(0, DCD_EVENT_SOF, true); } // SAMD doesn't distinguish between Suspend and Disconnect state. -- cgit v1.3.1 From 160cd79fdb9fee70894c4d9bfe908af38b88dc46 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Thu, 16 May 2024 16:05:36 +1000 Subject: nrf5x: Add support for dcd_sof_enable(). --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'src/portable') diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index bb07063d2..abce35245 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -120,6 +120,9 @@ static struct { // nRF can only carry one DMA at a time, this is used to guard the access to EasyDMA atomic_flag dma_running; + + // Track whether sof has been manually enabled + bool sof_enabled; } _dcd; /*------------------------------------------------------------------*/ @@ -283,9 +286,13 @@ void dcd_connect(uint8_t rhport) { void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; - (void) en; - - // TODO implement later + if (en) { + _dcd.sof_enabled = true; + NRF_USBD->INTENSET = USBD_INTENSET_SOF_Msk; + } else { + _dcd.sof_enabled = false; + NRF_USBD->INTENCLR = USBD_INTENCLR_SOF_Msk; + } } //--------------------------------------------------------------------+ @@ -607,13 +614,16 @@ void dcd_int_handler(uint8_t rhport) { } } - if (!iso_enabled) { - // ISO endpoint is not used, SOF is only enabled one-time for remote wakeup - // so we disable it now - NRF_USBD->INTENCLR = USBD_INTENSET_SOF_Msk; + if (!iso_enabled && !_dcd.sof_enabled) { + // SOF interrupt not manually enabled and ISO endpoint is not used, + // SOF is only enabled one-time for remote wakeup so we disable it now + + NRF_USBD->INTENCLR = USBD_INTENCLR_SOF_Msk; } - dcd_event_bus_signal(0, DCD_EVENT_SOF, true); + const uint32_t frame = NRF_USBD->FRAMECNTR; + dcd_event_sof(0, frame, true); + //dcd_event_bus_signal(0, DCD_EVENT_SOF, true); } if (int_status & USBD_INTEN_USBEVENT_Msk) { -- cgit v1.3.1 From 087fe79e2cd8558f62442d530ef23d249112d389 Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Sun, 19 May 2024 13:43:30 +1000 Subject: renesas: Add support for dcd_sof_enable(). --- src/portable/renesas/rusb2/dcd_rusb2.c | 40 ++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'src/portable') diff --git a/src/portable/renesas/rusb2/dcd_rusb2.c b/src/portable/renesas/rusb2/dcd_rusb2.c index 50400d1f5..7c6044ca0 100644 --- a/src/portable/renesas/rusb2/dcd_rusb2.c +++ b/src/portable/renesas/rusb2/dcd_rusb2.c @@ -29,10 +29,6 @@ #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 - #include "device/dcd.h" #include "rusb2_type.h" @@ -74,6 +70,8 @@ typedef struct { pipe_state_t pipe[PIPE_COUNT]; uint8_t ep[2][16]; /* a lookup table for a pipe index from an endpoint address */ + // Track whether sof has been manually enabled + bool sof_enabled; } dcd_data_t; static dcd_data_t _dcd; @@ -664,6 +662,10 @@ void dcd_init(uint8_t rhport) rusb2_reg_t* rusb = RUSB2_REG(rhport); rusb2_module_start(rhport, true); +// We disable SOF for now until needed later on. +// Since TinyUSB doesn't use SOF for now, and this interrupt often (1ms interval) +_dcd.sof_enabled = false; + #ifdef RUSB2_SUPPORT_HIGHSPEED if ( rusb2_is_highspeed_rhport(rhport) ) { rusb->SYSCFG_b.HSE = 1; @@ -708,7 +710,7 @@ void dcd_init(uint8_t rhport) 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_DVST_Msk | RUSB2_INTSTS0_CTRT_Msk | (_dcd.sof_enabled ? RUSB2_INTSTS0_SOFR_Msk : 0) | RUSB2_INTSTS0_RESM_Msk; rusb->BEMPENB = 1; rusb->BRDYENB = 1; @@ -756,10 +758,9 @@ void dcd_disconnect(uint8_t rhport) void dcd_sof_enable(uint8_t rhport, bool en) { - (void) rhport; - (void) en; - - // TODO implement later + rusb2_reg_t* rusb = RUSB2_REG(rhport); + _dcd.sof_enabled = en; + rusb->INTENB0_b.SOFE = en ? 1: 0; } //--------------------------------------------------------------------+ @@ -949,18 +950,19 @@ void dcd_int_handler(uint8_t rhport) // Resumed if ( is0 & RUSB2_INTSTS0_RESM_Msk ) { dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); -#if (0 == USE_SOF) - rusb->INTENB0_b.SOFE = 0; -#endif + if (!_dcd.sof_enabled) { + rusb->INTENB0_b.SOFE = 0; + } } // 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) - rusb->INTENB0_b.SOFE = 0; -#endif + const uint32_t frame = rusb->FRMNUM_b.FRNM; + dcd_event_sof(rhport, frame, true); + if (!_dcd.sof_enabled) { + rusb->INTENB0_b.SOFE = 0; + } } // Device state changes @@ -979,9 +981,9 @@ void dcd_int_handler(uint8_t rhport) 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 + if (!_dcd.sof_enabled) { + rusb->INTENB0_b.SOFE = 1; + } default: break; } -- cgit v1.3.1 From 8767d1ab7d2a7d3870d9bc6b6624b5f580f63e9d Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 29 May 2024 15:19:59 +0700 Subject: fix xtensa_api.h include --- src/portable/espressif/esp32sx/dcd_esp32sx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/portable') diff --git a/src/portable/espressif/esp32sx/dcd_esp32sx.c b/src/portable/espressif/esp32sx/dcd_esp32sx.c index bfc0baa56..f912bef89 100644 --- a/src/portable/espressif/esp32sx/dcd_esp32sx.c +++ b/src/portable/espressif/esp32sx/dcd_esp32sx.c @@ -31,7 +31,8 @@ #if (((CFG_TUSB_MCU == OPT_MCU_ESP32S2) || (CFG_TUSB_MCU == OPT_MCU_ESP32S3)) && CFG_TUD_ENABLED) // Espressif -#include "xtensa_api.h" +#include "xtensa/xtensa_api.h" + #include "esp_intr_alloc.h" #include "esp_log.h" #include "soc/dport_reg.h" -- cgit v1.3.1 From 4938128cccd3a76907caf546eacee41e53b989e7 Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Wed, 29 May 2024 12:54:15 -0700 Subject: Make it compile for STM32U545. --- src/portable/synopsys/dwc2/dwc2_stm32.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 3237a50f6..9957976a5 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -89,6 +89,12 @@ extern "C" { #define USB_OTG_FS_PERIPH_BASE USB_OTG_FS_BASE #define EP_MAX_FS 6 #define EP_FIFO_SIZE_FS 1280 + #define USB_OTG_FS_IRQN OTG_FS_IRQn + #elif defined(USB_DRD_FS) + #define USB_OTG_FS_PERIPH_BASE USB_DRD_BASE + #define EP_MAX_FS 6 + #define EP_FIFO_SIZE_FS 1280 + #define USB_OTG_FS_IRQN USB_IRQn #else #define USB_OTG_HS_PERIPH_BASE USB_OTG_HS_BASE #define EP_MAX_HS 9 @@ -109,7 +115,7 @@ extern "C" { // - Port0 to OTG_FS, and Port1 to OTG_HS static const dwc2_controller_t _dwc2_controller[] = { #ifdef USB_OTG_FS_PERIPH_BASE - { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = OTG_FS_IRQn, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, + { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = USB_OTG_FS_IRQN, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, #endif #ifdef USB_OTG_HS_PERIPH_BASE -- cgit v1.3.1 From 22e6b1130fa60b76ed0a1d9b6cc049179606c48c Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Wed, 29 May 2024 13:13:47 -0700 Subject: Cleaner approach. --- src/portable/synopsys/dwc2/dwc2_stm32.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 9957976a5..5743569db 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -84,17 +84,16 @@ extern "C" { #elif CFG_TUSB_MCU == OPT_MCU_STM32U5 #include "stm32u5xx.h" - // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY #ifdef USB_OTG_FS #define USB_OTG_FS_PERIPH_BASE USB_OTG_FS_BASE #define EP_MAX_FS 6 #define EP_FIFO_SIZE_FS 1280 - #define USB_OTG_FS_IRQN OTG_FS_IRQn + // U53x/U54x are fullspeed with built-in FS PHY but not OTG #elif defined(USB_DRD_FS) - #define USB_OTG_FS_PERIPH_BASE USB_DRD_BASE + #define USB_DRD_FS_PERIPH_BASE USB_DRD_BASE #define EP_MAX_FS 6 #define EP_FIFO_SIZE_FS 1280 - #define USB_OTG_FS_IRQN USB_IRQn + // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY #else #define USB_OTG_HS_PERIPH_BASE USB_OTG_HS_BASE #define EP_MAX_HS 9 @@ -114,6 +113,10 @@ extern "C" { // On STM32 for consistency we associate // - Port0 to OTG_FS, and Port1 to OTG_HS static const dwc2_controller_t _dwc2_controller[] = { + #ifdef USB_DRD_FS_PERIPH_BASE + { .reg_base = USB_DRD_FS_PERIPH_BASE, .irqnum = USB_IRQn, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, + #endif + #ifdef USB_OTG_FS_PERIPH_BASE { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = USB_OTG_FS_IRQN, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, #endif -- cgit v1.3.1 From 2e946ac77a8fda2b4b36c19df5294cd7213d46aa Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Wed, 29 May 2024 13:23:18 -0700 Subject: Use correct specs. --- src/portable/synopsys/dwc2/dwc2_stm32.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 5743569db..4f311782d 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -91,8 +91,8 @@ extern "C" { // U53x/U54x are fullspeed with built-in FS PHY but not OTG #elif defined(USB_DRD_FS) #define USB_DRD_FS_PERIPH_BASE USB_DRD_BASE - #define EP_MAX_FS 6 - #define EP_FIFO_SIZE_FS 1280 + #define EP_MAX_FS 8 + #define EP_FIFO_SIZE_FS 2048 // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY #else #define USB_OTG_HS_PERIPH_BASE USB_OTG_HS_BASE -- cgit v1.3.1 From 60d7fcb1ee8dcc4870221e97c1e3fba5463a9d45 Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Thu, 30 May 2024 13:26:14 -0700 Subject: Use correct backend. --- src/common/tusb_mcu.h | 25 +++++++++++++-------- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 2 +- src/portable/st/stm32_fsdev/fsdev_stm32.h | 31 +++++++++++++++++++++++++++ src/portable/synopsys/dwc2/dwc2_stm32.h | 11 +--------- 4 files changed, 49 insertions(+), 20 deletions(-) (limited to 'src/portable') diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index c66996c4f..0f4fca8d1 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -271,17 +271,24 @@ #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32U5) - #define TUP_USBIP_DWC2 - #define TUP_USBIP_DWC2_STM32 + #ifdef USB_DRD_FS + #define TUP_USBIP_FSDEV + #define TUP_USBIP_FSDEV_STM32 + #define TUP_DCD_ENDPOINT_MAX 8 - // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY - #if defined(STM32U595xx) || defined(STM32U599xx) || defined(STM32U5A5xx) || defined(STM32U5A9xx) || \ - defined(STM32U5F7xx) || defined(STM32U5F9xx) || defined(STM32U5G7xx) || defined(STM32U5G9xx) - #define TUP_DCD_ENDPOINT_MAX 9 - #define TUP_RHPORT_HIGHSPEED 1 - #define TUP_USBIP_DWC2_TEST_MODE #else - #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_USBIP_DWC2 + #define TUP_USBIP_DWC2_STM32 + + // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY + #if defined(STM32U595xx) || defined(STM32U599xx) || defined(STM32U5A5xx) || defined(STM32U5A9xx) || \ + defined(STM32U5F7xx) || defined(STM32U5F9xx) || defined(STM32U5G7xx) || defined(STM32U5G9xx) + #define TUP_DCD_ENDPOINT_MAX 9 + #define TUP_RHPORT_HIGHSPEED 1 + #define TUP_USBIP_DWC2_TEST_MODE + #else + #define TUP_DCD_ENDPOINT_MAX 6 + #endif #endif #elif TU_CHECK_MCU(OPT_MCU_STM32L5) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 9ce37f992..5f230d86f 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -232,7 +232,7 @@ void dcd_init(uint8_t rhport) } USB->CNTR = 0; // Enable USB -#if !defined(STM32G0) && !defined(STM32H5) // BTABLE register does not exist any more on STM32G0, it is fixed to USB SRAM base address +#if !defined(STM32G0) && !defined(STM32H5) && !defined(STM32U5) // BTABLE register does not exist any more on STM32G0, it is fixed to USB SRAM base address USB->BTABLE = DCD_STM32_BTABLE_BASE; #endif USB->ISTR = 0; // Clear pending interrupts diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index b3fa11b88..a5199c9e3 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -159,6 +159,35 @@ #define USB_PMAADDR (USB_BASE + (USB_PMAADDR_NS - USB_BASE_NS)) #endif +#elif CFG_TUSB_MCU == OPT_MCU_STM32U5 + #include "stm32u5xx.h" + #define FSDEV_BUS_32BIT + + #define FSDEV_PMA_SIZE (2048u) + #undef USB_PMAADDR + #define USB_PMAADDR USB_DRD_PMAADDR + #define USB_TypeDef USB_DRD_TypeDef + #define EP0R CHEP0R + #define USB_EP_CTR_RX USB_EP_VTRX + #define USB_EP_CTR_TX USB_EP_VTTX + #define USB_EP_T_FIELD USB_CHEP_UTYPE + #define USB_EPREG_MASK USB_CHEP_REG_MASK + #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK + #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK + #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1 + #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2 + #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1 + #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 + #define USB_EPRX_STAT USB_CH_RX_VALID + #define USB_EPKIND_MASK USB_EP_KIND_MASK + #define USB USB_DRD_FS + #define USB_CNTR_FRES USB_CNTR_USBRST + #define USB_CNTR_RESUME USB_CNTR_L2RES + #define USB_ISTR_EP_ID USB_ISTR_IDN + #define USB_EPADDR_FIELD USB_CHEP_ADDR + #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY + #define USB_CNTR_FSUSP USB_CNTR_SUSPEN + #else #error You are using an untested or unimplemented STM32 variant. Please update the driver. // This includes L1x0, L1x1, L1x2, L4x2 and L4x3, G1x1, G1x3, and G1x4 @@ -211,6 +240,8 @@ static const IRQn_Type fsdev_irq[] = { #elif CFG_TUSB_MCU == OPT_MCU_STM32WB USB_HP_IRQn, USB_LP_IRQn, + #elif CFG_TUSB_MCU == OPT_MCU_STM32U5 + USB_IRQn, #else #error Unknown arch in USB driver #endif diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 4f311782d..eaac2c44b 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -84,16 +84,11 @@ extern "C" { #elif CFG_TUSB_MCU == OPT_MCU_STM32U5 #include "stm32u5xx.h" + // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY #ifdef USB_OTG_FS #define USB_OTG_FS_PERIPH_BASE USB_OTG_FS_BASE #define EP_MAX_FS 6 #define EP_FIFO_SIZE_FS 1280 - // U53x/U54x are fullspeed with built-in FS PHY but not OTG - #elif defined(USB_DRD_FS) - #define USB_DRD_FS_PERIPH_BASE USB_DRD_BASE - #define EP_MAX_FS 8 - #define EP_FIFO_SIZE_FS 2048 - // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY #else #define USB_OTG_HS_PERIPH_BASE USB_OTG_HS_BASE #define EP_MAX_HS 9 @@ -113,10 +108,6 @@ extern "C" { // On STM32 for consistency we associate // - Port0 to OTG_FS, and Port1 to OTG_HS static const dwc2_controller_t _dwc2_controller[] = { - #ifdef USB_DRD_FS_PERIPH_BASE - { .reg_base = USB_DRD_FS_PERIPH_BASE, .irqnum = USB_IRQn, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, - #endif - #ifdef USB_OTG_FS_PERIPH_BASE { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = USB_OTG_FS_IRQN, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, #endif -- cgit v1.3.1 From 28c243337591f0ac7745f11737d907d47f0e6320 Mon Sep 17 00:00:00 2001 From: Tinic Uro Date: Wed, 12 Jun 2024 08:08:25 -0700 Subject: Add stm32u545nucleo board. --- hw/bsp/stm32u5/boards/stm32u575nucleo/board.mk | 1 + hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.mk | 1 + hw/bsp/stm32u5/family.c | 17 ++++++++++++++++- hw/bsp/stm32u5/family.cmake | 14 ++++++++++---- hw/bsp/stm32u5/family.mk | 14 ++++++++++++-- src/portable/synopsys/dwc2/dwc2_stm32.h | 2 +- 6 files changed, 41 insertions(+), 8 deletions(-) (limited to 'src/portable') diff --git a/hw/bsp/stm32u5/boards/stm32u575nucleo/board.mk b/hw/bsp/stm32u5/boards/stm32u575nucleo/board.mk index 1dd157a68..c83ec3999 100644 --- a/hw/bsp/stm32u5/boards/stm32u575nucleo/board.mk +++ b/hw/bsp/stm32u5/boards/stm32u575nucleo/board.mk @@ -6,5 +6,6 @@ LD_FILE = ${FAMILY_PATH}/linker/STM32U575xx_FLASH.ld SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32u575xx.s +MCU_VARIANT = stm32u575xx # For flash-jlink target JLINK_DEVICE = stm32u575zi diff --git a/hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.mk b/hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.mk index e759cec24..4bebe3330 100644 --- a/hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.mk +++ b/hw/bsp/stm32u5/boards/stm32u5a5nucleo/board.mk @@ -7,5 +7,6 @@ LD_FILE = ${BOARD_PATH}/STM32U5A5ZJTXQ_FLASH.ld SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32u5a5xx.s +MCU_VARIANT = stm32u5a5xx # For flash-jlink target JLINK_DEVICE = stm32u575zi diff --git a/hw/bsp/stm32u5/family.c b/hw/bsp/stm32u5/family.c index d779b5c96..0f0868839 100644 --- a/hw/bsp/stm32u5/family.c +++ b/hw/bsp/stm32u5/family.c @@ -72,7 +72,9 @@ void board_init(void) { __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOE_CLK_ENABLE(); +#ifdef GPIOF __HAL_RCC_GPIOF_CLK_ENABLE(); +#endif __HAL_RCC_GPIOG_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); @@ -140,6 +142,17 @@ void board_init(void) { GPIO_InitStruct.Alternate = GPIO_AF10_USB; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); +#ifdef USB_OTG_HS + // STM32U535/STM32U545 + + /* Enable USB power on Pwrctrl CR2 register */ + HAL_PWREx_EnableVddUSB(); + + /* USB clock enable */ + __HAL_RCC_USB_FS_CLK_ENABLE(); + +#endif + #ifdef USB_OTG_FS #if CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) @@ -170,7 +183,9 @@ void board_init(void) { /* USB clock enable */ __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); -#else +#endif + +#ifdef USB_OTG_HS // STM59x/Ax/Fx/Gx only have 1 USB HS port #if CFG_TUSB_OS == OPT_OS_FREERTOS diff --git a/hw/bsp/stm32u5/family.cmake b/hw/bsp/stm32u5/family.cmake index 7402540b7..c19bce64b 100644 --- a/hw/bsp/stm32u5/family.cmake +++ b/hw/bsp/stm32u5/family.cmake @@ -102,10 +102,16 @@ function(family_configure_example TARGET RTOS) # Add TinyUSB target and port source family_add_tinyusb(${TARGET} OPT_MCU_STM32U5 ${RTOS}) - target_sources(${TARGET}-tinyusb PUBLIC - ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c - #${TOP}/src/portable/st/typec/typec_stm32.c - ) + if ((${MCU_VARIANT} EQUAL "stm32u535xx") OR (${MCU_VARIANT} EQUAL "stm32u545xx")) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c + ) + else () + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c + #${TOP}/src/portable/st/typec/typec_stm32.c + ) + endif () target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) # Link dependencies diff --git a/hw/bsp/stm32u5/family.mk b/hw/bsp/stm32u5/family.mk index be5809340..45f9aa33e 100644 --- a/hw/bsp/stm32u5/family.mk +++ b/hw/bsp/stm32u5/family.mk @@ -27,18 +27,28 @@ LDFLAGS_GCC += \ --specs=nosys.specs --specs=nano.specs SRC_C += \ - src/portable/synopsys/dwc2/dcd_dwc2.c \ $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_cortex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_gpio.c \ - $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_icache.c \ + $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_icache.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_pwr_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_rcc_ex.c \ $(ST_HAL_DRIVER)/Src/stm32$(ST_FAMILY)xx_hal_uart.c +ifeq ($(MCU_VARIANT),stm32u545xx) +SRC_C += \ + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +else ($(MCU_VARIANT),stm32u535xx) +SRC_C += \ + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +else +SRC_C += \ + src/portable/synopsys/dwc2/dcd_dwc2.c +endif + INC += \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(ST_CMSIS)/Include \ diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index eaac2c44b..3237a50f6 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -109,7 +109,7 @@ extern "C" { // - Port0 to OTG_FS, and Port1 to OTG_HS static const dwc2_controller_t _dwc2_controller[] = { #ifdef USB_OTG_FS_PERIPH_BASE - { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = USB_OTG_FS_IRQN, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, + { .reg_base = USB_OTG_FS_PERIPH_BASE, .irqnum = OTG_FS_IRQn, .ep_count = EP_MAX_FS, .ep_fifo_size = EP_FIFO_SIZE_FS }, #endif #ifdef USB_OTG_HS_PERIPH_BASE -- cgit v1.3.1 From 2ed027f2bdedae81f20d7417ad7f018a6de9357a Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 14 Jun 2024 12:51:28 +0700 Subject: use stock core_riscv.h for ch32 v2 v3 --- hw/bsp/ch32v20x/core_riscv.h | 572 ------------------------------- hw/bsp/ch32v20x/family.c | 12 + hw/bsp/ch32v20x/family.cmake | 1 + hw/bsp/ch32v20x/family.mk | 4 + hw/bsp/ch32v307/core_riscv.h | 379 -------------------- hw/bsp/ch32v307/debug_uart.c | 9 + hw/bsp/ch32v307/family.c | 13 + hw/bsp/ch32v307/family.cmake | 1 + hw/bsp/ch32v307/family.mk | 4 + src/portable/st/stm32_fsdev/fsdev_ch32.h | 12 +- src/portable/wch/ch32_usbfs_reg.h | 11 + src/portable/wch/ch32_usbhs_reg.h | 12 + 12 files changed, 78 insertions(+), 952 deletions(-) delete mode 100644 hw/bsp/ch32v20x/core_riscv.h delete mode 100644 hw/bsp/ch32v307/core_riscv.h (limited to 'src/portable') diff --git a/hw/bsp/ch32v20x/core_riscv.h b/hw/bsp/ch32v20x/core_riscv.h deleted file mode 100644 index be1b52a6c..000000000 --- a/hw/bsp/ch32v20x/core_riscv.h +++ /dev/null @@ -1,572 +0,0 @@ -/********************************** (C) COPYRIGHT ******************************* - * File Name : core_riscv.h - * Author : WCH - * Version : V1.0.0 - * Date : 2021/06/06 - * Description : RISC-V Core Peripheral Access Layer Header File for CH32V20x -********************************************************************************* -* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. -* Attention: This software (modified or not) and binary are used for -* microcontroller manufactured by Nanjing Qinheng Microelectronics. -*******************************************************************************/ -#ifndef __CORE_RISCV_H__ -#define __CORE_RISCV_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* IO definitions */ -#ifdef __cplusplus - #define __I volatile /* defines 'read only' permissions */ -#else - #define __I volatile const /* defines 'read only' permissions */ -#endif -#define __O volatile /* defines 'write only' permissions */ -#define __IO volatile /* defines 'read / write' permissions */ - -/* Standard Peripheral Library old types (maintained for legacy purpose) */ -typedef __I uint64_t vuc64; /* Read Only */ -typedef __I uint32_t vuc32; /* Read Only */ -typedef __I uint16_t vuc16; /* Read Only */ -typedef __I uint8_t vuc8; /* Read Only */ - -typedef const uint64_t uc64; /* Read Only */ -typedef const uint32_t uc32; /* Read Only */ -typedef const uint16_t uc16; /* Read Only */ -typedef const uint8_t uc8; /* Read Only */ - -typedef __I int64_t vsc64; /* Read Only */ -typedef __I int32_t vsc32; /* Read Only */ -typedef __I int16_t vsc16; /* Read Only */ -typedef __I int8_t vsc8; /* Read Only */ - -typedef const int64_t sc64; /* Read Only */ -typedef const int32_t sc32; /* Read Only */ -typedef const int16_t sc16; /* Read Only */ -typedef const int8_t sc8; /* Read Only */ - -typedef __IO uint64_t vu64; -typedef __IO uint32_t vu32; -typedef __IO uint16_t vu16; -typedef __IO uint8_t vu8; - -typedef uint64_t u64; -typedef uint32_t u32; -typedef uint16_t u16; -typedef uint8_t u8; - -typedef __IO int64_t vs64; -typedef __IO int32_t vs32; -typedef __IO int16_t vs16; -typedef __IO int8_t vs8; - -typedef int64_t s64; -typedef int32_t s32; -typedef int16_t s16; -typedef int8_t s8; - -typedef enum {NoREADY = 0, READY = !NoREADY} ErrorStatus; - -typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; - -typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; - -#define RV_STATIC_INLINE static inline - -/* memory mapped structure for Program Fast Interrupt Controller (PFIC) */ -typedef struct{ - __I uint32_t ISR[8]; - __I uint32_t IPR[8]; - __IO uint32_t ITHRESDR; - __IO uint32_t RESERVED; - __IO uint32_t CFGR; - __I uint32_t GISR; - __IO uint8_t VTFIDR[4]; - uint8_t RESERVED0[12]; - __IO uint32_t VTFADDR[4]; - uint8_t RESERVED1[0x90]; - __O uint32_t IENR[8]; - uint8_t RESERVED2[0x60]; - __O uint32_t IRER[8]; - uint8_t RESERVED3[0x60]; - __O uint32_t IPSR[8]; - uint8_t RESERVED4[0x60]; - __O uint32_t IPRR[8]; - uint8_t RESERVED5[0x60]; - __IO uint32_t IACTR[8]; - uint8_t RESERVED6[0xE0]; - __IO uint8_t IPRIOR[256]; - uint8_t RESERVED7[0x810]; - __IO uint32_t SCTLR; -}PFIC_Type; - -/* memory mapped structure for SysTick */ -typedef struct -{ - __IO uint32_t CTLR; - __IO uint32_t SR; - __IO uint64_t CNT; - __IO uint64_t CMP; -}SysTick_Type; - -#define PFIC ((PFIC_Type *) 0xE000E000 ) -#define NVIC PFIC -#define NVIC_KEY1 ((uint32_t)0xFA050000) -#define NVIC_KEY2 ((uint32_t)0xBCAF0000) -#define NVIC_KEY3 ((uint32_t)0xBEEF0000) - -#define SysTick ((SysTick_Type *) 0xE000F000) - -/********************************************************************* - * @fn __enable_irq - * - * @brief Enable Global Interrupt - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __enable_irq(void) -{ - __asm volatile ("csrw 0x800, %0" : : "r" (0x6088) ); -} - -/********************************************************************* - * @fn __disable_irq - * - * @brief Disable Global Interrupt - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __disable_irq(void) -{ - __asm volatile ("csrw 0x800, %0" : : "r" (0x6000) ); -} - -/********************************************************************* - * @fn __NOP - * - * @brief nop - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __NOP(void) -{ - __asm volatile ("nop"); -} - -/********************************************************************* - * @fn NVIC_EnableIRQ - * - * @brief Disable Interrupt - * - * @param IRQn - Interrupt Numbers - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) -{ - NVIC->IENR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_DisableIRQ - * - * @brief Disable Interrupt - * - * @param IRQn - Interrupt Numbers - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) -{ - NVIC->IRER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_GetStatusIRQ - * - * @brief Get Interrupt Enable State - * - * @param IRQn - Interrupt Numbers - * - * @return 1 - Interrupt Pending Enable - * 0 - Interrupt Pending Disable - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetStatusIRQ(IRQn_Type IRQn) -{ - return((uint32_t) ((NVIC->ISR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - -/********************************************************************* - * @fn NVIC_GetPendingIRQ - * - * @brief Get Interrupt Pending State - * - * @param IRQn - Interrupt Numbers - * - * @return 1 - Interrupt Pending Enable - * 0 - Interrupt Pending Disable - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) -{ - return((uint32_t) ((NVIC->IPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - -/********************************************************************* - * @fn NVIC_SetPendingIRQ - * - * @brief Set Interrupt Pending - * - * @param IRQn - Interrupt Numbers - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC->IPSR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_ClearPendingIRQ - * - * @brief Clear Interrupt Pending - * - * @param IRQn - Interrupt Numbers - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC->IPRR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_GetActive - * - * @brief Get Interrupt Active State - * - * @param IRQn - Interrupt Numbers - * - * @return 1 - Interrupt Active - * 0 - Interrupt No Active - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) -{ - return((uint32_t)((NVIC->IACTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - -/********************************************************************* - * @fn NVIC_SetPriority - * - * @brief Set Interrupt Priority - * - * @param IRQn - Interrupt Numbers - * priority - bit7 - Pre-emption Priority - * bit[6:5] - Subpriority - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint8_t priority) -{ - NVIC->IPRIOR[(uint32_t)(IRQn)] = priority; -} - -/********************************************************************* - * @fn __WFI - * - * @brief Wait for Interrupt - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFI(void) -{ - NVIC->SCTLR &= ~(1<<3); // wfi - asm volatile ("wfi"); -} - -/********************************************************************* - * @fn _SEV - * - * @brief Set Event - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void _SEV(void) -{ - uint32_t t; - - t = NVIC->SCTLR; - NVIC->SCTLR |= (1<<3)|(1<<5); - NVIC->SCTLR = (NVIC->SCTLR & ~(1<<5)) | ( t & (1<<5)); -} - -/********************************************************************* - * @fn _WFE - * - * @brief Wait for Events - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void _WFE(void) -{ - NVIC->SCTLR |= (1<<3); - asm volatile ("wfi"); -} - -/********************************************************************* - * @fn __WFE - * - * @brief Wait for Events - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFE(void) -{ - _SEV(); - _WFE(); - _WFE(); -} - -/********************************************************************* - * @fn SetVTFIRQ - * - * @brief Set VTF Interrupt - * - * @param addr - VTF interrupt service function base address. - * IRQn - Interrupt Numbers - * num - VTF Interrupt Numbers - * NewState - DISABLE or ENABLE - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void SetVTFIRQ(uint32_t addr, IRQn_Type IRQn, uint8_t num, FunctionalState NewState){ - if(num > 3) return ; - - if (NewState != DISABLE) - { - NVIC->VTFIDR[num] = IRQn; - NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)|0x1); - } - else{ - NVIC->VTFIDR[num] = IRQn; - NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)&(~0x1)); - } -} - -/********************************************************************* - * @fn NVIC_SystemReset - * - * @brief Initiate a system reset request - * - * @return none - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void NVIC_SystemReset(void) -{ - NVIC->CFGR = NVIC_KEY3|(1<<7); -} - -/********************************************************************* - * @fn __AMOADD_W - * - * @brief Atomic Add with 32bit value - * Atomically ADD 32bit value with value in memory using amoadd.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be ADDed - * - * @return return memory value + add value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOADD_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amoadd.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOAND_W - * - * @brief Atomic And with 32bit value - * Atomically AND 32bit value with value in memory using amoand.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be ANDed - * - * @return return memory value & and value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOAND_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amoand.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOMAX_W - * - * @brief Atomic signed MAX with 32bit value - * Atomically signed max compare 32bit value with value in memory using amomax.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be compared - * - * @return the bigger value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOMAX_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amomax.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOMAXU_W - * - * @brief Atomic unsigned MAX with 32bit value - * Atomically unsigned max compare 32bit value with value in memory using amomaxu.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be compared - * - * @return return the bigger value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOMAXU_W(volatile uint32_t *addr, uint32_t value) -{ - uint32_t result; - - __asm volatile ("amomaxu.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOMIN_W - * - * @brief Atomic signed MIN with 32bit value - * Atomically signed min compare 32bit value with value in memory using amomin.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be compared - * - * @return the smaller value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOMIN_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amomin.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOMINU_W - * - * @brief Atomic unsigned MIN with 32bit value - * Atomically unsigned min compare 32bit value with value in memory using amominu.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be compared - * - * @return the smaller value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOMINU_W(volatile uint32_t *addr, uint32_t value) -{ - uint32_t result; - - __asm volatile ("amominu.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOOR_W - * - * @brief Atomic OR with 32bit value - * Atomically OR 32bit value with value in memory using amoor.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be ORed - * - * @return return memory value | and value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOOR_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amoor.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/********************************************************************* - * @fn __AMOSWAP_W - * - * @brief Atomically swap new 32bit value into memory using amoswap.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * newval - New value to be stored into the address - * - * @return return the original value in memory - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE uint32_t __AMOSWAP_W(volatile uint32_t *addr, uint32_t newval) -{ - uint32_t result; - - __asm volatile ("amoswap.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(newval) : "memory"); - return result; -} - -/********************************************************************* - * @fn __AMOXOR_W - * - * @brief Atomic XOR with 32bit value - * Atomically XOR 32bit value with value in memory using amoxor.d. - * - * @param addr - Address pointer to data, address need to be 4byte aligned - * value - value to be XORed - * - * @return return memory value ^ and value - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE int32_t __AMOXOR_W(volatile int32_t *addr, int32_t value) -{ - int32_t result; - - __asm volatile ("amoxor.w %0, %2, %1" : \ - "=r"(result), "+A"(*addr) : "r"(value) : "memory"); - return *addr; -} - -/* Core_Exported_Functions */ -extern uint32_t __get_MSTATUS(void); -extern void __set_MSTATUS(uint32_t value); -extern uint32_t __get_MISA(void); -extern void __set_MISA(uint32_t value); -extern uint32_t __get_MTVEC(void); -extern void __set_MTVEC(uint32_t value); -extern uint32_t __get_MSCRATCH(void); -extern void __set_MSCRATCH(uint32_t value); -extern uint32_t __get_MEPC(void); -extern void __set_MEPC(uint32_t value); -extern uint32_t __get_MCAUSE(void); -extern void __set_MCAUSE(uint32_t value); -extern uint32_t __get_MTVAL(void); -extern void __set_MTVAL(uint32_t value); -extern uint32_t __get_MVENDORID(void); -extern uint32_t __get_MARCHID(void); -extern uint32_t __get_MIMPID(void); -extern uint32_t __get_MHARTID(void); -extern uint32_t __get_SP(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/hw/bsp/ch32v20x/family.c b/hw/bsp/ch32v20x/family.c index c32cfd46e..8575f5699 100644 --- a/hw/bsp/ch32v20x/family.c +++ b/hw/bsp/ch32v20x/family.c @@ -1,6 +1,18 @@ #include + +// https://github.com/openwch/ch32v307/pull/90 +// https://github.com/openwch/ch32v20x/pull/12 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif + #include "ch32v20x.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #include "bsp/board_api.h" #include "board.h" diff --git a/hw/bsp/ch32v20x/family.cmake b/hw/bsp/ch32v20x/family.cmake index 1d574fdf8..28fd13697 100644 --- a/hw/bsp/ch32v20x/family.cmake +++ b/hw/bsp/ch32v20x/family.cmake @@ -49,6 +49,7 @@ function(add_board_target BOARD_TARGET) ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_SRC_DIR}/Core ${SDK_SRC_DIR}/Peripheral/inc ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ) diff --git a/hw/bsp/ch32v20x/family.mk b/hw/bsp/ch32v20x/family.mk index 49d4d2feb..daf3148f8 100644 --- a/hw/bsp/ch32v20x/family.mk +++ b/hw/bsp/ch32v20x/family.mk @@ -24,6 +24,9 @@ CFLAGS += \ -DCH32V20x_${MCU_VARIANT} \ -DCFG_TUSB_MCU=OPT_MCU_CH32V20X +# https://github.com/openwch/ch32v20x/pull/12 +CFLAGS += -Wno-error=strict-prototypes + ifeq ($(PORT),0) $(info "Using FSDEV driver") CFLAGS += -DCFG_TUD_WCH_USBIP_FSDEV=1 @@ -51,6 +54,7 @@ SRC_S += $(SDK_SRC_DIR)/Startup/startup_ch32v20x_${MCU_VARIANT}.S INC += \ $(TOP)/$(BOARD_PATH) \ + $(TOP)/$(SDK_SRC_DIR)/Core \ $(TOP)/$(SDK_SRC_DIR)/Peripheral/inc \ FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V diff --git a/hw/bsp/ch32v307/core_riscv.h b/hw/bsp/ch32v307/core_riscv.h deleted file mode 100644 index a7ce10a00..000000000 --- a/hw/bsp/ch32v307/core_riscv.h +++ /dev/null @@ -1,379 +0,0 @@ -/********************************** (C) COPYRIGHT ******************************* -* File Name : core_riscv.h -* Author : WCH -* Version : V1.0.0 -* Date : 2021/06/06 -* Description : RISC-V Core Peripheral Access Layer Header File for CH32V30x -* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. -* SPDX-License-Identifier: Apache-2.0 -*******************************************************************************/ -#ifndef __CORE_RISCV_H__ -#define __CORE_RISCV_H__ - -/* IO definitions */ -#ifdef __cplusplus - #define __I volatile /* defines 'read only' permissions */ -#else - #define __I volatile const /* defines 'read only' permissions */ -#endif -#define __O volatile /* defines 'write only' permissions */ -#define __IO volatile /* defines 'read / write' permissions */ - -/* Standard Peripheral Library old types (maintained for legacy purpose) */ -typedef __I uint64_t vuc64; /* Read Only */ -typedef __I uint32_t vuc32; /* Read Only */ -typedef __I uint16_t vuc16; /* Read Only */ -typedef __I uint8_t vuc8; /* Read Only */ - -typedef const uint64_t uc64; /* Read Only */ -typedef const uint32_t uc32; /* Read Only */ -typedef const uint16_t uc16; /* Read Only */ -typedef const uint8_t uc8; /* Read Only */ - -typedef __I int64_t vsc64; /* Read Only */ -typedef __I int32_t vsc32; /* Read Only */ -typedef __I int16_t vsc16; /* Read Only */ -typedef __I int8_t vsc8; /* Read Only */ - -typedef const int64_t sc64; /* Read Only */ -typedef const int32_t sc32; /* Read Only */ -typedef const int16_t sc16; /* Read Only */ -typedef const int8_t sc8; /* Read Only */ - -typedef __IO uint64_t vu64; -typedef __IO uint32_t vu32; -typedef __IO uint16_t vu16; -typedef __IO uint8_t vu8; - -typedef uint64_t u64; -typedef uint32_t u32; -typedef uint16_t u16; -typedef uint8_t u8; - -typedef __IO int64_t vs64; -typedef __IO int32_t vs32; -typedef __IO int16_t vs16; -typedef __IO int8_t vs8; - -typedef int64_t s64; -typedef int32_t s32; -typedef int16_t s16; -typedef int8_t s8; - -typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus; - -typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; - -typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus; - -#define RV_STATIC_INLINE static inline - -/* memory mapped structure for Program Fast Interrupt Controller (PFIC) */ -typedef struct{ - __I uint32_t ISR[8]; - __I uint32_t IPR[8]; - __IO uint32_t ITHRESDR; - __IO uint32_t RESERVED; - __IO uint32_t CFGR; - __I uint32_t GISR; - uint8_t VTFIDR[4]; - uint8_t RESERVED0[12]; - __IO uint32_t VTFADDR[4]; - uint8_t RESERVED1[0x90]; - __O uint32_t IENR[8]; - uint8_t RESERVED2[0x60]; - __O uint32_t IRER[8]; - uint8_t RESERVED3[0x60]; - __O uint32_t IPSR[8]; - uint8_t RESERVED4[0x60]; - __O uint32_t IPRR[8]; - uint8_t RESERVED5[0x60]; - __IO uint32_t IACTR[8]; - uint8_t RESERVED6[0xE0]; - __IO uint8_t IPRIOR[256]; - uint8_t RESERVED7[0x810]; - __IO uint32_t SCTLR; -}PFIC_Type; - -/* memory mapped structure for SysTick */ -typedef struct -{ - __IO u32 CTLR; - __IO u32 SR; - __IO u64 CNT; - __IO u64 CMP; -}SysTick_Type; - - -#define PFIC ((PFIC_Type *) 0xE000E000 ) -#define NVIC PFIC -#define NVIC_KEY1 ((uint32_t)0xFA050000) -#define NVIC_KEY2 ((uint32_t)0xBCAF0000) -#define NVIC_KEY3 ((uint32_t)0xBEEF0000) - -#define SysTick ((SysTick_Type *) 0xE000F000) - - -/********************************************************************* - * @fn __enable_irq - * - * @brief Enable Global Interrupt - * - * @return none - */ -RV_STATIC_INLINE void __enable_irq(void) -{ - __asm volatile ("csrw 0x800, %0" : : "r" (0x6088) ); -} - -/********************************************************************* - * @fn __disable_irq - * - * @brief Disable Global Interrupt - * - * @return none - */ -RV_STATIC_INLINE void __disable_irq(void) -{ - __asm volatile ("csrw 0x800, %0" : : "r" (0x6000) ); -} - -/********************************************************************* - * @fn __NOP - * - * @brief nop - * - * @return none - */ -RV_STATIC_INLINE void __NOP(void) -{ - __asm volatile ("nop"); -} - -/********************************************************************* - * @fn NVIC_EnableIRQ - * - * @brief Enable Interrupt - * - * @param IRQn: Interrupt Numbers - * - * @return none - */ -RV_STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) -{ - NVIC->IENR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_DisableIRQ - * - * @brief Disable Interrupt - * - * @param IRQn: Interrupt Numbers - * - * @return none - */ -RV_STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) -{ - NVIC->IRER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_GetStatusIRQ - * - * @brief Get Interrupt Enable State - * - * @param IRQn: Interrupt Numbers - * - * @return 1 - Interrupt Enable - * 0 - Interrupt Disable - */ -RV_STATIC_INLINE uint32_t NVIC_GetStatusIRQ(IRQn_Type IRQn) -{ - return((uint32_t) ((NVIC->ISR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - -/********************************************************************* - * @fn NVIC_GetPendingIRQ - * - * @brief Get Interrupt Pending State - * - * @param IRQn: Interrupt Numbers - * - * @return 1 - Interrupt Pending Enable - * 0 - Interrupt Pending Disable - */ -RV_STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) -{ - return((uint32_t) ((NVIC->IPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - -/********************************************************************* - * @fn NVIC_SetPendingIRQ - * - * @brief Set Interrupt Pending - * - * @param IRQn: Interrupt Numbers - * - * @return None - */ -RV_STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) -{ - NVIC->IPSR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_ClearPendingIRQ - * - * @brief Clear Interrupt Pending - * - * @param IRQn: Interrupt Numbers - * - * @return None - */ -RV_STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) -{ - NVIC->IPRR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); -} - -/********************************************************************* - * @fn NVIC_GetActive - * - * @brief Get Interrupt Active State - * - * @param IRQn: Interrupt Numbers - * - * @return 1 - Interrupt Active - * 0 - Interrupt No Active - */ -RV_STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) -{ - return((uint32_t)((NVIC->IACTR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); -} - -/********************************************************************* - * @fn NVIC_SetPriority - * - * @brief Set Interrupt Priority - * - * @param IRQn - Interrupt Numbers - * priority - - * bit7 - pre-emption priority - * bit6~bit4 - subpriority - * @return None - */ -RV_STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint8_t priority) -{ - NVIC->IPRIOR[(uint32_t)(IRQn)] = priority; -} - -/********************************************************************* - * @fn __WFI - * - * @brief Wait for Interrupt - * - * @return None - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFI(void) -{ - NVIC->SCTLR &= ~(1<<3); // wfi - asm volatile ("wfi"); -} - -/********************************************************************* - * @fn __WFE - * - * @brief Wait for Events - * - * @return None - */ -__attribute__( ( always_inline ) ) RV_STATIC_INLINE void __WFE(void) -{ - uint32_t t; - - t = NVIC->SCTLR; - NVIC->SCTLR |= (1<<3)|(1<<5); // (wfi->wfe)+(__sev) - NVIC->SCTLR = (NVIC->SCTLR & ~(1<<5)) | ( t & (1<<5)); - asm volatile ("wfi"); - asm volatile ("wfi"); -} - -/********************************************************************* - * @fn SetVTFIRQ - * - * @brief Set VTF Interrupt - * - * @param add - VTF interrupt service function base address. - * IRQn -Interrupt Numbers - * num - VTF Interrupt Numbers - * NewState - DISABLE or ENABLE - * @return None - */ -RV_STATIC_INLINE void SetVTFIRQ(uint32_t addr, IRQn_Type IRQn, uint8_t num, FunctionalState NewState){ - if(num > 3) return ; - - if (NewState != DISABLE) - { - NVIC->VTFIDR[num] = IRQn; - NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)|0x1); - } - else{ - NVIC->VTFIDR[num] = IRQn; - NVIC->VTFADDR[num] = ((addr&0xFFFFFFFE)&(~0x1)); - } -} - -/********************************************************************* - * @fn NVIC_SystemReset - * - * @brief Initiate a system reset request - * - * @return None - */ -RV_STATIC_INLINE void NVIC_SystemReset(void) -{ - NVIC->CFGR = NVIC_KEY3|(1<<7); -} - - -/* Core_Exported_Functions */ -extern uint32_t __get_FFLAGS(void); -extern void __set_FFLAGS(uint32_t value); -extern uint32_t __get_FRM(void); -extern void __set_FRM(uint32_t value); -extern uint32_t __get_FCSR(void); -extern void __set_FCSR(uint32_t value); -extern uint32_t __get_MSTATUS(void); -extern void __set_MSTATUS(uint32_t value); -extern uint32_t __get_MISA(void); -extern void __set_MISA(uint32_t value); -extern uint32_t __get_MIE(void); -extern void __set_MIE(uint32_t value); -extern uint32_t __get_MTVEC(void); -extern void __set_MTVEC(uint32_t value); -extern uint32_t __get_MSCRATCH(void); -extern void __set_MSCRATCH(uint32_t value); -extern uint32_t __get_MEPC(void); -extern void __set_MEPC(uint32_t value); -extern uint32_t __get_MCAUSE(void); -extern void __set_MCAUSE(uint32_t value); -extern uint32_t __get_MTVAL(void); -extern void __set_MTVAL(uint32_t value); -extern uint32_t __get_MIP(void); -extern void __set_MIP(uint32_t value); -extern uint32_t __get_MCYCLE(void); -extern void __set_MCYCLE(uint32_t value); -extern uint32_t __get_MCYCLEH(void); -extern void __set_MCYCLEH(uint32_t value); -extern uint32_t __get_MINSTRET(void); -extern void __set_MINSTRET(uint32_t value); -extern uint32_t __get_MINSTRETH(void); -extern void __set_MINSTRETH(uint32_t value); -extern uint32_t __get_MVENDORID(void); -extern uint32_t __get_MARCHID(void); -extern uint32_t __get_MIMPID(void); -extern uint32_t __get_MHARTID(void); -extern uint32_t __get_SP(void); - - -#endif diff --git a/hw/bsp/ch32v307/debug_uart.c b/hw/bsp/ch32v307/debug_uart.c index fbabeeadc..2fd3a9d64 100644 --- a/hw/bsp/ch32v307/debug_uart.c +++ b/hw/bsp/ch32v307/debug_uart.c @@ -25,8 +25,17 @@ */ #include "debug_uart.h" + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif + #include +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif #define UART_RINGBUFFER_SIZE_TX 128 #define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX-1) diff --git a/hw/bsp/ch32v307/family.c b/hw/bsp/ch32v307/family.c index 0846b10a9..adf2dbea5 100644 --- a/hw/bsp/ch32v307/family.c +++ b/hw/bsp/ch32v307/family.c @@ -25,9 +25,22 @@ */ #include "stdio.h" + +// https://github.com/openwch/ch32v307/pull/90 +// https://github.com/openwch/ch32v20x/pull/12 + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif + #include "debug_uart.h" #include "ch32v30x.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #include "bsp/board_api.h" #include "board.h" diff --git a/hw/bsp/ch32v307/family.cmake b/hw/bsp/ch32v307/family.cmake index af26bfc31..d603af62d 100644 --- a/hw/bsp/ch32v307/family.cmake +++ b/hw/bsp/ch32v307/family.cmake @@ -49,6 +49,7 @@ function(add_board_target BOARD_TARGET) ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} ) target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_SRC_DIR}/Core ${SDK_SRC_DIR}/Peripheral/inc ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ) diff --git a/hw/bsp/ch32v307/family.mk b/hw/bsp/ch32v307/family.mk index 30a070a9b..bf2732106 100644 --- a/hw/bsp/ch32v307/family.mk +++ b/hw/bsp/ch32v307/family.mk @@ -25,6 +25,9 @@ CFLAGS += \ -fsigned-char \ -DCFG_TUSB_MCU=OPT_MCU_CH32V307 \ +# https://github.com/openwch/ch32v307/pull/90 +CFLAGS += -Wno-error=strict-prototypes + ifeq ($(SPEED),high) $(info "Using USBHS driver for HighSpeed mode") CFLAGS += -DCFG_TUD_WCH_USBIP_USBHS=1 @@ -51,6 +54,7 @@ SRC_S += \ INC += \ $(TOP)/$(BOARD_PATH) \ + $(TOP)/$(SDK_SRC_DIR)/Core \ $(TOP)/$(SDK_SRC_DIR)/Peripheral/inc # For freeRTOS port source diff --git a/src/portable/st/stm32_fsdev/fsdev_ch32.h b/src/portable/st/stm32_fsdev/fsdev_ch32.h index 85fe3266c..dbf2a0289 100644 --- a/src/portable/st/stm32_fsdev/fsdev_ch32.h +++ b/src/portable/st/stm32_fsdev/fsdev_ch32.h @@ -36,13 +36,23 @@ #include "common/tusb_compiler.h" +// https://github.com/openwch/ch32v307/pull/90 +// https://github.com/openwch/ch32v20x/pull/12 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif + #if CFG_TUSB_MCU == OPT_MCU_CH32V20X #include - #elif CFG_TUSB_MCU == OPT_MCU_CH32F20X #include #endif +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + #define FSDEV_PMA_SIZE (512u) // volatile 32-bit aligned diff --git a/src/portable/wch/ch32_usbfs_reg.h b/src/portable/wch/ch32_usbfs_reg.h index 0a50a6169..ef6ebf2dc 100644 --- a/src/portable/wch/ch32_usbfs_reg.h +++ b/src/portable/wch/ch32_usbfs_reg.h @@ -28,6 +28,13 @@ #ifndef USB_CH32_USBFS_REG_H #define USB_CH32_USBFS_REG_H +// https://github.com/openwch/ch32v307/pull/90 +// https://github.com/openwch/ch32v20x/pull/12 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif + #if CFG_TUSB_MCU == OPT_MCU_CH32V307 #include #define USBHD_IRQn OTG_FS_IRQn @@ -39,6 +46,10 @@ #include #endif +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + // CTRL #define USBFS_CTRL_DMA_EN (1 << 0) #define USBFS_CTRL_CLR_ALL (1 << 1) diff --git a/src/portable/wch/ch32_usbhs_reg.h b/src/portable/wch/ch32_usbhs_reg.h index 130e4f223..87300b497 100644 --- a/src/portable/wch/ch32_usbhs_reg.h +++ b/src/portable/wch/ch32_usbhs_reg.h @@ -28,12 +28,24 @@ #ifndef USB_CH32_USBHS_REG_H #define USB_CH32_USBHS_REG_H +// https://github.com/openwch/ch32v307/pull/90 +// https://github.com/openwch/ch32v20x/pull/12 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif + #if CFG_TUSB_MCU == OPT_MCU_CH32V307 #include #elif CFG_TUSB_MCU == OPT_MCU_CH32F20X #include #endif +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + + /******************* GLOBAL ******************/ // USB CONTROL -- cgit v1.3.1 From 33f5547ed435f33259afc2a8e906eb7a258fbdd6 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 14 Jun 2024 16:06:37 +0700 Subject: add ch32v103 bsp support, compile but does not run, probably due to compile/linker issue --- .../ch32v10x/boards/ch32v103r_r1_1v0/board.cmake | 8 + hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.h | 20 + hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk | 7 + hw/bsp/ch32v10x/ch32v10x_conf.h | 37 ++ hw/bsp/ch32v10x/ch32v10x_it.h | 15 + hw/bsp/ch32v10x/family.c | 147 +++++ hw/bsp/ch32v10x/family.cmake | 117 ++++ hw/bsp/ch32v10x/family.mk | 53 ++ hw/bsp/ch32v10x/linker/ch32v10x.ld | 165 ++++++ hw/bsp/ch32v10x/system_ch32v10x.c | 600 +++++++++++++++++++++ hw/bsp/ch32v10x/system_ch32v10x.h | 29 + hw/bsp/ch32v10x/wch-riscv.cfg | 17 + hw/bsp/ch32v20x/family.mk | 10 +- hw/bsp/family_support.cmake | 2 +- src/common/tusb_mcu.h | 9 + src/portable/wch/ch32_usbfs_reg.h | 67 ++- src/tusb_option.h | 6 +- tools/get_deps.py | 3 + 18 files changed, 1296 insertions(+), 16 deletions(-) create mode 100644 hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.cmake create mode 100644 hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.h create mode 100644 hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk create mode 100644 hw/bsp/ch32v10x/ch32v10x_conf.h create mode 100644 hw/bsp/ch32v10x/ch32v10x_it.h create mode 100644 hw/bsp/ch32v10x/family.c create mode 100644 hw/bsp/ch32v10x/family.cmake create mode 100644 hw/bsp/ch32v10x/family.mk create mode 100644 hw/bsp/ch32v10x/linker/ch32v10x.ld create mode 100644 hw/bsp/ch32v10x/system_ch32v10x.c create mode 100644 hw/bsp/ch32v10x/system_ch32v10x.h create mode 100644 hw/bsp/ch32v10x/wch-riscv.cfg (limited to 'src/portable') diff --git a/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.cmake b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.cmake new file mode 100644 index 000000000..f6e47ba30 --- /dev/null +++ b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.cmake @@ -0,0 +1,8 @@ +set(LD_FLASH_SIZE 64K) +set(LD_RAM_SIZE 20K) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + CFG_EXAMPLE_MSC_DUAL_READONLY + ) +endfunction() diff --git a/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.h b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.h new file mode 100644 index 000000000..3b1187c3a --- /dev/null +++ b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.h @@ -0,0 +1,20 @@ +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define LED_PORT GPIOA +#define LED_PIN GPIO_Pin_10 +#define LED_STATE_ON 0 + +#define BUTTON_PORT GPIOA +#define BUTTON_PIN GPIO_Pin_1 +#define BUTTON_STATE_ACTIVE 0 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk new file mode 100644 index 000000000..7d7462312 --- /dev/null +++ b/hw/bsp/ch32v10x/boards/ch32v103r_r1_1v0/board.mk @@ -0,0 +1,7 @@ +MCU_VARIANT = D6 + +CFLAGS += -DCFG_EXAMPLE_MSC_DUAL_READONLY + +LDFLAGS += \ + -Wl,--defsym=__flash_size=64K \ + -Wl,--defsym=__ram_size=20K \ diff --git a/hw/bsp/ch32v10x/ch32v10x_conf.h b/hw/bsp/ch32v10x/ch32v10x_conf.h new file mode 100644 index 000000000..939c0fbde --- /dev/null +++ b/hw/bsp/ch32v10x/ch32v10x_conf.h @@ -0,0 +1,37 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : ch32v10x_conf.h + * Author : WCH + * Version : V1.0.0 + * Date : 2020/04/30 + * Description : Library configuration file. +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef __CH32V10x_CONF_H +#define __CH32V10x_CONF_H + +#include "ch32v10x_adc.h" +#include "ch32v10x_bkp.h" +#include "ch32v10x_crc.h" +#include "ch32v10x_dbgmcu.h" +#include "ch32v10x_dma.h" +#include "ch32v10x_exti.h" +#include "ch32v10x_flash.h" +#include "ch32v10x_gpio.h" +#include "ch32v10x_i2c.h" +#include "ch32v10x_iwdg.h" +#include "ch32v10x_pwr.h" +#include "ch32v10x_rcc.h" +#include "ch32v10x_rtc.h" +#include "ch32v10x_spi.h" +#include "ch32v10x_tim.h" +#include "ch32v10x_usart.h" +#include "ch32v10x_wwdg.h" +#include "ch32v10x_usb.h" +#include "ch32v10x_usb_host.h" +#include "ch32v10x_it.h" +#include "ch32v10x_misc.h" + +#endif /* __CH32V10x_CONF_H */ diff --git a/hw/bsp/ch32v10x/ch32v10x_it.h b/hw/bsp/ch32v10x/ch32v10x_it.h new file mode 100644 index 000000000..13afc2412 --- /dev/null +++ b/hw/bsp/ch32v10x/ch32v10x_it.h @@ -0,0 +1,15 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : ch32v10x_it.h + * Author : WCH + * Version : V1.0.0 + * Date : 2022/08/20 + * Description : This file contains the headers of the interrupt handlers. +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef __CH32V10x_IT_H +#define __CH32V10x_IT_H + +#endif /* __CH32V10x_IT_H */ diff --git a/hw/bsp/ch32v10x/family.c b/hw/bsp/ch32v10x/family.c new file mode 100644 index 000000000..6de17521e --- /dev/null +++ b/hw/bsp/ch32v10x/family.c @@ -0,0 +1,147 @@ +#include + +// https://github.com/openwch/ch32v307/pull/90 +// https://github.com/openwch/ch32v20x/pull/12 +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" +#endif + +#include "ch32v10x.h" + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +#include "bsp/board_api.h" +#include "board.h" + +__attribute__((interrupt)) __attribute__((used)) +void USBHD_IRQHandler(void) { + #if CFG_TUD_WCH_USBIP_USBFS + tud_int_handler(0); + #endif +} + +__attribute__((interrupt)) __attribute__((used)) +void USBHDWakeUp_IRQHandler(void) { + #if CFG_TUD_WCH_USBIP_USBFS + tud_int_handler(0); + #endif +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +__attribute__((interrupt)) __attribute__((used)) +void SysTick_Handler(void) { + SysTick->CNTL0 = SysTick->CNTL1 = SysTick->CNTL2 = SysTick->CNTL3 = 0; + SysTick->CNTH0 = SysTick->CNTH1 = SysTick->CNTH2 = SysTick->CNTH3 = 0; + system_ticks++; +} + +uint32_t SysTick_Config(uint32_t ticks) { + NVIC_EnableIRQ(SysTicK_IRQn); + SysTick->CTLR = 0; + SysTick->CNTL0 = SysTick->CNTL1 = SysTick->CNTL2 = SysTick->CNTL3 = 0; + SysTick->CNTH0 = SysTick->CNTH1 = SysTick->CNTH2 = SysTick->CNTH3 = 0; + + SysTick->CMPLR0 = (u8)(ticks & 0xFF); + SysTick->CMPLR1 = (u8)(ticks >> 8); + SysTick->CMPLR2 = (u8)(ticks >> 16); + SysTick->CMPLR3 = (u8)(ticks >> 24); + + SysTick->CMPHR0 = SysTick->CMPHR1 = SysTick->CMPHR2 = SysTick->CMPHR3 = 0; + SysTick->CTLR = 1; + return 0; +} + +uint32_t board_millis(void) { + return system_ticks; +} +#endif + +void board_init(void) { + __disable_irq(); + +#if CFG_TUSB_OS == OPT_OS_NONE + SysTick_Config(SystemCoreClock / 1000); +#endif + + uint8_t usb_div; + switch (SystemCoreClock) { + case 48000000: usb_div = RCC_USBCLKSource_PLLCLK_Div1; break; + case 72000000: usb_div = RCC_USBCLKSource_PLLCLK_1Div5; break; + default: TU_ASSERT(0,); break; + } + RCC_USBCLKConfig(usb_div); + RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE); + + RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); + + #ifdef LED_PIN + GPIO_InitTypeDef led_init = { + .GPIO_Pin = LED_PIN, + .GPIO_Mode = GPIO_Mode_Out_OD, + .GPIO_Speed = GPIO_Speed_50MHz, + }; + GPIO_Init(LED_PORT, &led_init); + #endif + + #ifdef BUTTON_PIN + GPIO_InitTypeDef button_init = { + .GPIO_Pin = BUTTON_PIN, + .GPIO_Mode = GPIO_Mode_IPU, + .GPIO_Speed = GPIO_Speed_50MHz, + }; + GPIO_Init(BUTTON_PORT, &button_init); + #endif + + // UART TX is PA9 + RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); + GPIO_InitTypeDef usart_init = { + .GPIO_Pin = GPIO_Pin_9, + .GPIO_Speed = GPIO_Speed_50MHz, + .GPIO_Mode = GPIO_Mode_AF_PP, + }; + GPIO_Init(GPIOA, &usart_init); + + USART_InitTypeDef usart = { + .USART_BaudRate = 115200, + .USART_WordLength = USART_WordLength_8b, + .USART_StopBits = USART_StopBits_1, + .USART_Parity = USART_Parity_No, + .USART_Mode = USART_Mode_Tx, + .USART_HardwareFlowControl = USART_HardwareFlowControl_None, + }; + USART_Init(USART1, &usart); + USART_Cmd(USART1, ENABLE); + + __enable_irq(); + + board_led_write(true); +} + +void board_led_write(bool state) { + GPIO_WriteBit(LED_PORT, LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) { + return BUTTON_STATE_ACTIVE == GPIO_ReadInputDataBit(BUTTON_PORT, BUTTON_PIN); +} + +int board_uart_read(uint8_t *buf, int len) { + (void) buf; + (void) len; + return 0; +} + +int board_uart_write(void const *buf, int len) { + const char *bufc = (const char *) buf; + for (int i = 0; i < len; i++) { + while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); + USART_SendData(USART1, *bufc++); + } + + return len; +} diff --git a/hw/bsp/ch32v10x/family.cmake b/hw/bsp/ch32v10x/family.cmake new file mode 100644 index 000000000..b0d8241d3 --- /dev/null +++ b/hw/bsp/ch32v10x/family.cmake @@ -0,0 +1,117 @@ +include_guard() + +#set(UF2_FAMILY_ID 0x699b62ec) +set(CH32_FAMILY ch32v10x) +set(SDK_DIR ${TOP}/hw/mcu/wch/ch32v103) +set(SDK_SRC_DIR ${SDK_DIR}/EVT/EXAM/SRC) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR rv32imac-ilp32 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS CH32V103 CACHE INTERNAL "") +set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif() + + if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/linker/${CH32_FAMILY}.ld) + endif () + set(LD_FILE_Clang ${LD_FILE_GNU}) + + if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${SDK_SRC_DIR}/Startup/startup_${CH32_FAMILY}.S) + endif () + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + + add_library(${BOARD_TARGET} STATIC + ${SDK_SRC_DIR}/Core/core_riscv.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_gpio.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_misc.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_rcc.c + ${SDK_SRC_DIR}/Peripheral/src/${CH32_FAMILY}_usart.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_${CH32_FAMILY}.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_SRC_DIR}/Core + ${SDK_SRC_DIR}/Peripheral/inc + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(${BOARD_TARGET} PUBLIC + -mcmodel=medany + ) + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -Wl,--defsym=__flash_size=${LD_FLASH_SIZE} + -Wl,--defsym=__ram_size=${LD_RAM_SIZE} + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + message(FATAL_ERROR "Clang is not supported for MSP432E4") + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_CH32V103 ${RTOS}) + + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/wch/dcd_ch32_usbfs.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_openocd_wch(${TARGET}) + + #family_add_uf2(${TARGET} ${UF2_FAMILY_ID}) + #family_flash_uf2(${TARGET} ${UF2_FAMILY_ID}) +endfunction() diff --git a/hw/bsp/ch32v10x/family.mk b/hw/bsp/ch32v10x/family.mk new file mode 100644 index 000000000..d96d5012e --- /dev/null +++ b/hw/bsp/ch32v10x/family.mk @@ -0,0 +1,53 @@ +# https://www.embecosm.com/resources/tool-chain-downloads/#riscv-stable +#CROSS_COMPILE ?= riscv32-unknown-elf- + +# Toolchain from https://nucleisys.com/download.php +#CROSS_COMPILE ?= riscv-nuclei-elf- + +# Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack +CROSS_COMPILE ?= riscv-none-elf- + +CH32_FAMILY = ch32v10x +SDK_DIR = hw/mcu/wch/ch32v103 +SDK_SRC_DIR = $(SDK_DIR)/EVT/EXAM/SRC + +include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= rv32imac-ilp32 + +# Port0 use FSDev, Port1 use USBFS +PORT ?= 0 + +CFLAGS += \ + -mcmodel=medany \ + -ffat-lto-objects \ + -flto \ + -DCFG_TUSB_MCU=OPT_MCU_CH32V103 + +# https://github.com/openwch/ch32v20x/pull/12 +CFLAGS += -Wno-error=strict-prototypes + +LDFLAGS_GCC += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs \ + +LD_FILE = $(FAMILY_PATH)/linker/${CH32_FAMILY}.ld + +SRC_C += \ + src/portable/wch/dcd_ch32_usbfs.c \ + $(SDK_SRC_DIR)/Core/core_riscv.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_gpio.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_misc.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_rcc.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_usart.c \ + +SRC_S += $(SDK_SRC_DIR)/Startup/startup_${CH32_FAMILY}.S + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/$(SDK_SRC_DIR)/Core \ + $(TOP)/$(SDK_SRC_DIR)/Peripheral/inc \ + +FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V + +OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg +flash: flash-openocd-wch diff --git a/hw/bsp/ch32v10x/linker/ch32v10x.ld b/hw/bsp/ch32v10x/linker/ch32v10x.ld new file mode 100644 index 000000000..cd5c8dc17 --- /dev/null +++ b/hw/bsp/ch32v10x/linker/ch32v10x.ld @@ -0,0 +1,165 @@ +/* Define default values if not already defined */ +__FLASH_SIZE = DEFINED(__flash_size) ? __flash_size : 64K; +__RAM_SIZE = DEFINED(__ram_size) ? __ram_size : 20K; + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = __FLASH_SIZE + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = __RAM_SIZE +} + +ENTRY( _start ) + +__stack_size = 2048; + +PROVIDE( _stack_size = __stack_size ); + +SECTIONS +{ + .init : + { + _sinit = .; + . = ALIGN(4); + KEEP(*(SORT_NONE(.init))) + . = ALIGN(4); + _einit = .; + } >FLASH AT>FLASH + + .vector : + { + *(.vector); + . = ALIGN(64); + } >FLASH AT>FLASH + + .text : + { + . = ALIGN(4); + *(.text) + *(.text.*) + *(.rodata) + *(.rodata*) + *(.gnu.linkonce.t.*) + . = ALIGN(4); + } >FLASH AT>FLASH + + .fini : + { + KEEP(*(SORT_NONE(.fini))) + . = ALIGN(4); + } >FLASH AT>FLASH + + PROVIDE( _etext = . ); + PROVIDE( _eitcm = . ); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH AT>FLASH + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH AT>FLASH + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH AT>FLASH + + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >FLASH AT>FLASH + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >FLASH AT>FLASH + + .dalign : + { + . = ALIGN(4); + PROVIDE(_data_vma = .); + } >RAM AT>FLASH + + .dlalign : + { + . = ALIGN(4); + PROVIDE(_data_lma = .); + } >FLASH AT>FLASH + + .data : + { + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.sdata2.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + . = ALIGN(4); + PROVIDE( _edata = .); + } >RAM AT>FLASH + + .bss : + { + . = ALIGN(4); + PROVIDE( _sbss = .); + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss*) + *(.gnu.linkonce.b.*) + *(COMMON*) + . = ALIGN(4); + PROVIDE( _ebss = .); + } >RAM AT>FLASH + + PROVIDE( _end = _ebss); + PROVIDE( end = . ); + + .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = ALIGN(4); + PROVIDE(_susrstack = . ); + . = . + __stack_size; + PROVIDE( _eusrstack = .); + } >RAM + +} diff --git a/hw/bsp/ch32v10x/system_ch32v10x.c b/hw/bsp/ch32v10x/system_ch32v10x.c new file mode 100644 index 000000000..b083b83b4 --- /dev/null +++ b/hw/bsp/ch32v10x/system_ch32v10x.c @@ -0,0 +1,600 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : system_ch32v10x.c + * Author : WCH + * Version : V1.0.0 + * Date : 2020/04/30 + * Description : CH32V10x Device Peripheral Access Layer System Source File. +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#include "ch32v10x.h" + +/* + * Uncomment the line corresponding to the desired System clock (SYSCLK) frequency (after + * reset the HSI is used as SYSCLK source). + * If none of the define below is enabled, the HSI is used as System clock source. + */ +//#define SYSCLK_FREQ_HSE HSE_VALUE +//#define SYSCLK_FREQ_48MHz_HSE 48000000 +//#define SYSCLK_FREQ_56MHz_HSE 56000000 +#define SYSCLK_FREQ_72MHz_HSE 72000000 +//#define SYSCLK_FREQ_HSI HSI_VALUE +//#define SYSCLK_FREQ_48MHz_HSI 48000000 +//#define SYSCLK_FREQ_56MHz_HSI 56000000 +//#define SYSCLK_FREQ_72MHz_HSI 72000000 + +/* Clock Definitions */ +#ifdef SYSCLK_FREQ_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_48MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_56MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_72MHz_HSE +uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSE; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_48MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz_HSI; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_56MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz_HSI; /* System Clock Frequency (Core Clock) */ +#elif defined SYSCLK_FREQ_72MHz_HSI +uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz_HSI; /* System Clock Frequency (Core Clock) */ +#else +uint32_t SystemCoreClock = HSI_VALUE; /* System Clock Frequency (Core Clock) */ + +#endif + +__I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; + +/* ch32v10x_system_private_function_proto_types */ +static void SetSysClock(void); + +#ifdef SYSCLK_FREQ_HSE +static void SetSysClockToHSE( void ); +#elif defined SYSCLK_FREQ_48MHz_HSE +static void SetSysClockTo48_HSE( void ); +#elif defined SYSCLK_FREQ_56MHz_HSE +static void SetSysClockTo56_HSE( void ); +#elif defined SYSCLK_FREQ_72MHz_HSE +static void SetSysClockTo72_HSE( void ); +#elif defined SYSCLK_FREQ_48MHz_HSI +static void SetSysClockTo48_HSI( void ); +#elif defined SYSCLK_FREQ_56MHz_HSI +static void SetSysClockTo56_HSI( void ); +#elif defined SYSCLK_FREQ_72MHz_HSI +static void SetSysClockTo72_HSI( void ); + +#endif + +/********************************************************************* + * @fn SystemInit + * + * @brief Setup the microcontroller system Initialize the Embedded Flash Interface, + * the PLL and update the SystemCoreClock variable. + * + * @return none + */ +void SystemInit(void) +{ + RCC->CTLR |= (uint32_t)0x00000001; + RCC->CFGR0 &= (uint32_t)0xF8FF0000; + RCC->CTLR &= (uint32_t)0xFEF6FFFF; + RCC->CTLR &= (uint32_t)0xFFFBFFFF; + RCC->CFGR0 &= (uint32_t)0xFF80FFFF; + RCC->INTR = 0x009F0000; + SetSysClock(); +} + +/********************************************************************* + * @fn SystemCoreClockUpdate + * + * @brief Update SystemCoreClock variable according to Clock Register Values. + * + * @return none + */ +void SystemCoreClockUpdate(void) +{ + uint32_t tmp = 0, pllmull = 0, pllsource = 0; + + tmp = RCC->CFGR0 & RCC_SWS; + + switch(tmp) + { + case 0x00: + SystemCoreClock = HSI_VALUE; + break; + case 0x04: + SystemCoreClock = HSE_VALUE; + break; + case 0x08: + pllmull = RCC->CFGR0 & RCC_PLLMULL; + pllsource = RCC->CFGR0 & RCC_PLLSRC; + pllmull = (pllmull >> 18) + 2; + if(pllsource == 0x00) + { + if( EXTEN->EXTEN_CTR & EXTEN_PLL_HSI_PRE ) + { + SystemCoreClock = ( HSI_VALUE ) * pllmull; + } + else + { + SystemCoreClock = ( HSI_VALUE >> 1 ) * pllmull; + } + } + else + { + if((RCC->CFGR0 & RCC_PLLXTPRE) != (uint32_t)RESET) + { + SystemCoreClock = (HSE_VALUE >> 1) * pllmull; + } + else + { + SystemCoreClock = HSE_VALUE * pllmull; + } + } + break; + default: + SystemCoreClock = HSI_VALUE; + break; + } + + tmp = AHBPrescTable[((RCC->CFGR0 & RCC_HPRE) >> 4)]; + SystemCoreClock >>= tmp; +} + +/********************************************************************* + * @fn SetSysClock + * + * @brief Configures the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClock(void) +{ + //GPIO_IPD_Unused(); +#ifdef SYSCLK_FREQ_HSE + SetSysClockToHSE(); +#elif defined SYSCLK_FREQ_48MHz_HSE + SetSysClockTo48_HSE(); +#elif defined SYSCLK_FREQ_56MHz_HSE + SetSysClockTo56_HSE(); +#elif defined SYSCLK_FREQ_72MHz_HSE + SetSysClockTo72_HSE(); +#elif defined SYSCLK_FREQ_48MHz_HSI + SetSysClockTo48_HSI(); +#elif defined SYSCLK_FREQ_56MHz_HSI + SetSysClockTo56_HSI(); +#elif defined SYSCLK_FREQ_72MHz_HSI + SetSysClockTo72_HSI(); + +#endif + + /* If none of the define above is enabled, the HSI is used as System clock + * source (default after reset) + */ +} + +#ifdef SYSCLK_FREQ_HSE + +/********************************************************************* + * @fn SetSysClockToHSE + * + * @brief Sets HSE as System clock source and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockToHSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if(HSEStatus == (uint32_t)0x01) + { + FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; + /* Flash 0 wait state */ + FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); + FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_0; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV1; + + /* Select HSE as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_HSE; + + /* Wait till HSE is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x04) + { + } + } + else + { + /* If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + + +#elif defined SYSCLK_FREQ_48MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo48_HSE + * + * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo48_HSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if(HSEStatus == (uint32_t)0x01) + { + /* Enable Prefetch Buffer */ + FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; + + /* Flash 1 wait state */ + FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); + FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_1; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSE * 6 = 48 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLMULL6); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_56MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo56_HSE + * + * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo56_HSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if(HSEStatus == (uint32_t)0x01) + { + /* Enable Prefetch Buffer */ + FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; + + /* Flash 2 wait state */ + FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); + FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_2; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSE * 7 = 56 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLMULL7); + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_72MHz_HSE + +/********************************************************************* + * @fn SetSysClockTo72_HSE + * + * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo72_HSE(void) +{ + __IO uint32_t StartUpCounter = 0, HSEStatus = 0; + + RCC->CTLR |= ((uint32_t)RCC_HSEON); + + /* Wait till HSE is ready and if Time out is reached exit */ + do + { + HSEStatus = RCC->CTLR & RCC_HSERDY; + StartUpCounter++; + } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT)); + + if((RCC->CTLR & RCC_HSERDY) != RESET) + { + HSEStatus = (uint32_t)0x01; + } + else + { + HSEStatus = (uint32_t)0x00; + } + + if(HSEStatus == (uint32_t)0x01) + { + /* Enable Prefetch Buffer */ + FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; + + /* Flash 2 wait state */ + FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); + FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_2; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | + RCC_PLLMULL)); + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSE | RCC_PLLMULL9); + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } + } + else + { + /* + * If HSE fails to start-up, the application will have wrong clock + * configuration. User can add here some code to deal with this error + */ + } +} + +#elif defined SYSCLK_FREQ_48MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo48_HSI + * + * @brief Sets System clock frequency to 48MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo48_HSI(void) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* Enable Prefetch Buffer */ + FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; + + /* Flash 1 wait state */ + FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); + FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_1; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 6 = 48 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL6); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } +} + +#elif defined SYSCLK_FREQ_56MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo56_HSI + * + * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo56_HSI(void) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* Enable Prefetch Buffer */ + FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; + + /* Flash 1 wait state */ + FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); + FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_1; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 7 = 56 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL7); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } +} + +#elif defined SYSCLK_FREQ_72MHz_HSI + +/********************************************************************* + * @fn SetSysClockTo72_HSI + * + * @brief Sets System clock frequency to 72MHz and configure HCLK, PCLK2 and PCLK1 prescalers. + * + * @return none + */ +static void SetSysClockTo72_HSI(void) +{ + EXTEN->EXTEN_CTR |= EXTEN_PLL_HSI_PRE; + + /* Enable Prefetch Buffer */ + FLASH->ACTLR |= FLASH_ACTLR_PRFTBE; + + /* Flash 1 wait state */ + FLASH->ACTLR &= (uint32_t)((uint32_t)~FLASH_ACTLR_LATENCY); + FLASH->ACTLR |= (uint32_t)FLASH_ACTLR_LATENCY_1; + + /* HCLK = SYSCLK */ + RCC->CFGR0 |= (uint32_t)RCC_HPRE_DIV1; + /* PCLK2 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE2_DIV1; + /* PCLK1 = HCLK */ + RCC->CFGR0 |= (uint32_t)RCC_PPRE1_DIV2; + + /* PLL configuration: PLLCLK = HSI * 9 = 72 MHz */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_PLLSRC | RCC_PLLXTPRE | RCC_PLLMULL)); + RCC->CFGR0 |= (uint32_t)(RCC_PLLSRC_HSI_Div2 | RCC_PLLMULL9); + + /* Enable PLL */ + RCC->CTLR |= RCC_PLLON; + /* Wait till PLL is ready */ + while((RCC->CTLR & RCC_PLLRDY) == 0) + { + } + /* Select PLL as system clock source */ + RCC->CFGR0 &= (uint32_t)((uint32_t) ~(RCC_SW)); + RCC->CFGR0 |= (uint32_t)RCC_SW_PLL; + /* Wait till PLL is used as system clock source */ + while((RCC->CFGR0 & (uint32_t)RCC_SWS) != (uint32_t)0x08) + { + } +} + +#endif diff --git a/hw/bsp/ch32v10x/system_ch32v10x.h b/hw/bsp/ch32v10x/system_ch32v10x.h new file mode 100644 index 000000000..d15624520 --- /dev/null +++ b/hw/bsp/ch32v10x/system_ch32v10x.h @@ -0,0 +1,29 @@ +/********************************** (C) COPYRIGHT ******************************* + * File Name : system_ch32v10x.h + * Author : WCH + * Version : V1.0.0 + * Date : 2020/04/30 + * Description : CH32V10x Device Peripheral Access Layer System Header File. +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef __SYSTEM_CH32V10x_H +#define __SYSTEM_CH32V10x_H + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock) */ + +/* System_Exported_Functions */ +extern void SystemInit(void); +extern void SystemCoreClockUpdate(void); + +#ifdef __cplusplus +} +#endif + +#endif /*__CH32V10x_SYSTEM_H */ diff --git a/hw/bsp/ch32v10x/wch-riscv.cfg b/hw/bsp/ch32v10x/wch-riscv.cfg new file mode 100644 index 000000000..aa35aa9c5 --- /dev/null +++ b/hw/bsp/ch32v10x/wch-riscv.cfg @@ -0,0 +1,17 @@ +adapter driver wlinke +adapter speed 6000 +transport select sdi + +wlink_set_address 0x00000000 +set _CHIPNAME wch_riscv +sdi newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001 + +set _TARGETNAME $_CHIPNAME.cpu + +target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME +$_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 10000 -work-area-backup 1 +set _FLASHNAME $_CHIPNAME.flash + +flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0 + +echo "Ready for Remote Connections" diff --git a/hw/bsp/ch32v20x/family.mk b/hw/bsp/ch32v20x/family.mk index daf3148f8..4485091dc 100644 --- a/hw/bsp/ch32v20x/family.mk +++ b/hw/bsp/ch32v20x/family.mk @@ -45,12 +45,12 @@ SRC_C += \ src/portable/wch/dcd_ch32_usbfs.c \ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ $(SDK_SRC_DIR)/Core/core_riscv.c \ - $(SDK_SRC_DIR)/Peripheral/src/ch32v20x_gpio.c \ - $(SDK_SRC_DIR)/Peripheral/src/ch32v20x_misc.c \ - $(SDK_SRC_DIR)/Peripheral/src/ch32v20x_rcc.c \ - $(SDK_SRC_DIR)/Peripheral/src/ch32v20x_usart.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_gpio.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_misc.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_rcc.c \ + $(SDK_SRC_DIR)/Peripheral/src/${CH32_FAMILY}_usart.c \ -SRC_S += $(SDK_SRC_DIR)/Startup/startup_ch32v20x_${MCU_VARIANT}.S +SRC_S += $(SDK_SRC_DIR)/Startup/startup_${CH32_FAMILY}_${MCU_VARIANT}.S INC += \ $(TOP)/$(BOARD_PATH) \ diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index d9443f811..94d55f04a 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -443,7 +443,7 @@ function(family_flash_openocd TARGET) # note skip verify since it has issue with rp2040 add_custom_target(${TARGET}-openocd DEPENDS ${TARGET} - COMMAND ${OPENOCD} ${OPTION_LIST} -c "program $ reset" ${OPTION_LIST2} -c exit + COMMAND ${OPENOCD} ${OPTION_LIST} -c init -c halt -c "program $ reset" ${OPTION_LIST2} -c exit VERBATIM ) endfunction() diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index c66996c4f..d9d11e96d 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -420,6 +420,15 @@ #define TUP_RHPORT_HIGHSPEED CFG_TUD_WCH_USBIP_USBHS #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_WCH_USBIP_USBHS ? 16 : 8) +#elif TU_CHECK_MCU(OPT_MCU_CH32V103) + #define TUP_USBIP_WCH_USBFS + + #if !defined(CFG_TUD_WCH_USBIP_USBFS) + #define CFG_TUD_WCH_USBIP_USBFS 1 + #endif + + #define TUP_DCD_ENDPOINT_MAX 8 + #elif TU_CHECK_MCU(OPT_MCU_CH32V20X) // v20x support both FSDEV (USBD) and USBFS, default to FSDEV #define TUP_USBIP_WCH_USBFS diff --git a/src/portable/wch/ch32_usbfs_reg.h b/src/portable/wch/ch32_usbfs_reg.h index ef6ebf2dc..68be64f5e 100644 --- a/src/portable/wch/ch32_usbfs_reg.h +++ b/src/portable/wch/ch32_usbfs_reg.h @@ -35,15 +35,68 @@ #pragma GCC diagnostic ignored "-Wstrict-prototypes" #endif -#if CFG_TUSB_MCU == OPT_MCU_CH32V307 - #include - #define USBHD_IRQn OTG_FS_IRQn - +#if CFG_TUSB_MCU == OPT_MCU_CH32F20X + #include +#elif CFG_TUSB_MCU == OPT_MCU_CH32V103 + #include + typedef struct + { + __IO uint8_t BASE_CTRL; + __IO uint8_t UDEV_CTRL; + __IO uint8_t INT_EN; + __IO uint8_t DEV_ADDR; + __IO uint8_t Reserve0; + __IO uint8_t MIS_ST; + __IO uint8_t INT_FG; + __IO uint8_t INT_ST; + __IO uint32_t RX_LEN; + __IO uint8_t UEP4_1_MOD; + __IO uint8_t UEP2_3_MOD; + __IO uint8_t UEP5_6_MOD; + __IO uint8_t UEP7_MOD; + __IO uint32_t UEP0_DMA; + __IO uint32_t UEP1_DMA; + __IO uint32_t UEP2_DMA; + __IO uint32_t UEP3_DMA; + __IO uint32_t UEP4_DMA; + __IO uint32_t UEP5_DMA; + __IO uint32_t UEP6_DMA; + __IO uint32_t UEP7_DMA; + __IO uint16_t UEP0_TX_LEN; + __IO uint8_t UEP0_TX_CTRL; + __IO uint8_t UEP0_RX_CTRL; + __IO uint16_t UEP1_TX_LEN; + __IO uint8_t UEP1_TX_CTRL; + __IO uint8_t UEP1_RX_CTRL; + __IO uint16_t UEP2_TX_LEN; + __IO uint8_t UEP2_TX_CTRL; + __IO uint8_t UEP2_RX_CTRL; + __IO uint16_t UEP3_TX_LEN; + __IO uint8_t UEP3_TX_CTRL; + __IO uint8_t UEP3_RX_CTRL; + __IO uint16_t UEP4_TX_LEN; + __IO uint8_t UEP4_TX_CTRL; + __IO uint8_t UEP4_RX_CTRL; + __IO uint16_t UEP5_TX_LEN; + __IO uint8_t UEP5_TX_CTRL; + __IO uint8_t UEP5_RX_CTRL; + __IO uint16_t UEP6_TX_LEN; + __IO uint8_t UEP6_TX_CTRL; + __IO uint8_t UEP6_RX_CTRL; + __IO uint16_t UEP7_TX_LEN; + __IO uint8_t UEP7_TX_CTRL; + __IO uint8_t UEP7_RX_CTRL; + __IO uint32_t Reserve1; + __IO uint32_t OTG_CR; + __IO uint32_t OTG_SR; + } USBOTG_FS_TypeDef; + + #define USBOTG_FS ((USBOTG_FS_TypeDef *) 0x40023400) #elif CFG_TUSB_MCU == OPT_MCU_CH32V20X #include - -#elif CFG_TUSB_MCU == OPT_MCU_CH32F20X - #include +#elif CFG_TUSB_MCU == OPT_MCU_CH32V307 + #include + #define USBHD_IRQn OTG_FS_IRQn #endif #ifdef __GNUC__ diff --git a/src/tusb_option.h b/src/tusb_option.h index db8b94580..1ca09e902 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_OPTION_H_ -#define _TUSB_OPTION_H_ +#ifndef TUSB_OPTION_H_ +#define TUSB_OPTION_H_ #include "common/tusb_compiler.h" @@ -182,7 +182,7 @@ #define OPT_MCU_CH32V307 2200 ///< WCH CH32V307 #define OPT_MCU_CH32F20X 2210 ///< WCH CH32F20x #define OPT_MCU_CH32V20X 2220 ///< WCH CH32V20X - +#define OPT_MCU_CH32V103 2230 ///< WCH CH32V103 // NXP LPC MCX #define OPT_MCU_MCXN9 2300 ///< NXP MCX N9 Series diff --git a/tools/get_deps.py b/tools/get_deps.py index 50cc5c893..92bfb86a2 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -168,6 +168,9 @@ deps_optional = { 'hw/mcu/ti': ['https://github.com/hathach/ti_driver.git', '143ed6cc20a7615d042b03b21e070197d473e6e5', 'msp430 msp432e4 tm4c'], + 'hw/mcu/wch/ch32v103': ['https://github.com/openwch/ch32v103.git', + '7578cae0b21f86dd053a1f781b2fc6ab99d0ec17', + 'ch32v10x'], 'hw/mcu/wch/ch32v20x': ['https://github.com/openwch/ch32v20x.git', 'de6d68c654340d7f27b00cebbfc9aa2740a1abc2', 'ch32v20x'], -- cgit v1.3.1 From 9ae00535737f6f442a9ca7ad3167f686c0d557b1 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 14 Jun 2024 16:08:26 +0700 Subject: newline --- src/portable/st/stm32_fsdev/fsdev_ch32.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/fsdev_ch32.h b/src/portable/st/stm32_fsdev/fsdev_ch32.h index dbf2a0289..f63a80d56 100644 --- a/src/portable/st/stm32_fsdev/fsdev_ch32.h +++ b/src/portable/st/stm32_fsdev/fsdev_ch32.h @@ -43,10 +43,10 @@ #pragma GCC diagnostic ignored "-Wstrict-prototypes" #endif -#if CFG_TUSB_MCU == OPT_MCU_CH32V20X - #include -#elif CFG_TUSB_MCU == OPT_MCU_CH32F20X +#if CFG_TUSB_MCU == OPT_MCU_CH32F20X #include +#elif CFG_TUSB_MCU == OPT_MCU_CH32V20X + #include #endif #ifdef __GNUC__ -- cgit v1.3.1 From 00062ddb0cda4e46750c7df09aa31026cc03b5ee Mon Sep 17 00:00:00 2001 From: Okarss <104319900+Okarss@users.noreply.github.com> Date: Fri, 14 Jun 2024 18:16:09 +0300 Subject: [STM32 FSDEV] Simplify toggle bit logic --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 12 ++++++------ src/portable/st/stm32_fsdev/fsdev_common.h | 24 ++---------------------- 2 files changed, 8 insertions(+), 28 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 9ce37f992..b5b89c577 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -215,20 +215,20 @@ void dcd_init(uint8_t rhport) /* The RM mentions to use a special ordering of PDWN and FRES, but this isn't done in HAL. * Here, the RM is followed. */ - for (uint32_t i = 0; i < 200; i++) { // should be a few us - asm("NOP"); + for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us + __DSB(); } // Perform USB peripheral reset USB->CNTR = USB_CNTR_FRES | USB_CNTR_PDWN; - for (uint32_t i = 0; i < 200; i++) { // should be a few us - asm("NOP"); + for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us + __DSB(); } USB->CNTR &= ~USB_CNTR_PDWN; // Wait startup time, for F042 and F070, this is <= 1 us. - for (uint32_t i = 0; i < 200; i++) { // should be a few us - asm("NOP"); + for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us + __DSB(); } USB->CNTR = 0; // Enable USB diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index af5d8afab..e8a6af8cb 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -295,18 +295,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, u TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); regVal &= USB_EPTX_DTOGMASK; - - /* toggle first bit ? */ - if((USB_EPTX_DTOG1 & (wState))!= 0U) - { - regVal ^= USB_EPTX_DTOG1; - } - /* toggle second bit ? */ - if((USB_EPTX_DTOG2 & ((uint32_t)(wState)))!= 0U) - { - regVal ^= USB_EPTX_DTOG2; - } - + regVal ^= wState; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; pcd_set_endpoint(USBx, bEpIdx, regVal); } @@ -322,16 +311,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); regVal &= USB_EPRX_DTOGMASK; - - /* toggle first bit ? */ - if((USB_EPRX_DTOG1 & wState)!= 0U) { - regVal ^= USB_EPRX_DTOG1; - } - /* toggle second bit ? */ - if((USB_EPRX_DTOG2 & wState)!= 0U) { - regVal ^= USB_EPRX_DTOG2; - } - + regVal ^= wState; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; pcd_set_endpoint(USBx, bEpIdx, regVal); } -- cgit v1.3.1 From fb6a6acbff81a98e37b86a0dc3370d4076bb356c Mon Sep 17 00:00:00 2001 From: Okarss <104319900+Okarss@users.noreply.github.com> Date: Fri, 14 Jun 2024 18:39:48 +0300 Subject: Revert the DSB because of RISC-V --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index b5b89c577..4e31c99fa 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -216,19 +216,19 @@ void dcd_init(uint8_t rhport) * Here, the RM is followed. */ for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us - __DSB(); + asm("NOP"); } // Perform USB peripheral reset USB->CNTR = USB_CNTR_FRES | USB_CNTR_PDWN; for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us - __DSB(); + asm("NOP"); } USB->CNTR &= ~USB_CNTR_PDWN; // Wait startup time, for F042 and F070, this is <= 1 us. for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us - __DSB(); + asm("NOP"); } USB->CNTR = 0; // Enable USB -- cgit v1.3.1 From 5f060a357d34257f5a742ebf78c5e4e0873c7a13 Mon Sep 17 00:00:00 2001 From: Okarss <104319900+Okarss@users.noreply.github.com> Date: Fri, 14 Jun 2024 21:23:17 +0300 Subject: Update the STM32 documentation --- README.rst | 5 +++-- docs/reference/supported.rst | 20 +++++++++++++++++--- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 10 ++++++++-- src/portable/st/stm32_fsdev/fsdev_stm32.h | 2 +- 4 files changed, 29 insertions(+), 8 deletions(-) (limited to 'src/portable') diff --git a/README.rst b/README.rst index b5f9fc149..1ae8c5375 100644 --- a/README.rst +++ b/README.rst @@ -151,8 +151,9 @@ Following CPUs are supported, check out `Supported Devices`_ for comprehensive l +--------------+------------------------------------------------------------+ | Sony | CXD56 | +--------------+------------------------------------------------------------+ -| ST STM32 | F0, F1, F2, F3, F4, F7, H5, H7, G0, G4, L0, L1, L4, L4+, | -| | U5, WB | +| ST STM32 | F0, F1, F2, F3, F4, F7, G0, G4, H5, H7, | +| | | +| | L0, L1, L4, L4+, L5, U5, WB | +--------------+------------------------------------------------------------+ | TI | MSP430, MSP432E4, TM4C123 | +--------------+------------------------------------------------------------+ diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index 3ca203e88..d0e0bf1af 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -104,11 +104,17 @@ Supported MCUs | +-----------------------+--------+------+-----------+-------------------+--------------+ | | F7 | ✔ | | ✔ | dwc2 | | | +-----------------------+--------+------+-----------+-------------------+--------------+ -| | H7 | ✔ | | ✔ | dwc2 | | +| | G0 | ✔ | ✖ | ✖ | stm32_fsdev | | | +-----------------------+--------+------+-----------+-------------------+--------------+ | | G4 | ✔ | ✖ | ✖ | stm32_fsdev | | | +-----------------------+--------+------+-----------+-------------------+--------------+ -| | L0, L1 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | H5 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | H7 | ✔ | | ✔ | dwc2 | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | L0 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ +| | L1 | ✔ | ✖ | ✖ | stm32_fsdev | | | +----+------------------+--------+------+-----------+-------------------+--------------+ | | L4 | 4x2, 4x3 | ✔ | ✖ | ✖ | stm32_fsdev | | | | +------------------+--------+------+-----------+-------------------+--------------+ @@ -116,8 +122,14 @@ Supported MCUs | +----+------------------+--------+------+-----------+-------------------+--------------+ | | L4+ | ✔ | | | dwc2 | | | +-----------------------+--------+------+-----------+-------------------+--------------+ -| | U5 | ✔ | | ✔ | dwc2 | | +| | L5 | ✔ | ✖ | ✖ | stm32_fsdev | | | +-----------------------+--------+------+-----------+-------------------+--------------+ +| | U5 | 535, 545 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | +------------------+--------+------+-----------+-------------------+--------------+ +| | | 575, 585 | ✔ | | ✖ | dwc2 | | +| | +------------------+--------+------+-----------+-------------------+--------------+ +| | | 59x,5Ax,5Fx,5Gx | ✔ | | ✔ | dwc2 | | +| +----+------------------+--------+------+-----------+-------------------+--------------+ | | WBx5 | ✔ | | | stm32_fsdev | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ | TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | | @@ -129,7 +141,9 @@ Supported MCUs | ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ | WCH | CH32F20x | ✔ | | ✔ | ch32f205 | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ | | CH32V20x | ✔ | | ✖ | ch32v20x | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ | | CH32V307 | ✔ | | ✔ | ch32v307 | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 9ce37f992..0ecb6ea05 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -37,14 +37,20 @@ * It also should work with minimal changes for any ST MCU with an "USB A"/"PCD"/"HCD" peripheral. This * covers: * - * F04x, F072, F078, 070x6/B 1024 byte buffer + * F04x, F072, F078, F070x6/B 1024 byte buffer * F102, F103 512 byte buffer; no internal D+ pull-up (maybe many more changes?) * F302xB/C, F303xB/C, F373 512 byte buffer; no internal D+ pull-up * F302x6/8, F302xD/E2, F303xD/E 1024 byte buffer; no internal D+ pull-up + * G0 2048 byte buffer; 32-bit bus + * G4 1024 byte buffer + * H5 2048 byte buffer; 32-bit bus * L0x2, L0x3 1024 byte buffer * L1 512 byte buffer * L4x2, L4x3 1024 byte buffer - * G0 2048 byte buffer + * L5 1024 byte buffer + * U0 1024 byte buffer; 32-bit bus + * U535, U545 2048 byte buffer; 32-bit bus + * WB35, WB55 1024 byte buffer * * To use this driver, you must: * - If you are using a device with crystal-less USB, set up the clock recovery system (CRS) diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index b3fa11b88..524efc75f 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -161,7 +161,7 @@ #else #error You are using an untested or unimplemented STM32 variant. Please update the driver. - // This includes L1x0, L1x1, L1x2, L4x2 and L4x3, G1x1, G1x3, and G1x4 + // This includes U0 #endif // This checks if the device has "LPM" -- cgit v1.3.1 From d945261aef7e2c922153e2a85d00791dd1930740 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 18 Jun 2024 12:53:02 +0700 Subject: LOG3 in isr --- examples/host/device_info/src/tusb_config.h | 2 +- src/portable/nordic/nrf5x/dcd_nrf5x.c | 4 ++-- src/portable/nxp/khci/dcd_khci.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/portable') diff --git a/examples/host/device_info/src/tusb_config.h b/examples/host/device_info/src/tusb_config.h index 484f651b1..2e9731eaf 100644 --- a/examples/host/device_info/src/tusb_config.h +++ b/examples/host/device_info/src/tusb_config.h @@ -70,7 +70,7 @@ #define CFG_TUH_ENABLED 1 #if CFG_TUSB_MCU == OPT_MCU_RP2040 - #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller + // #define CFG_TUH_RPI_PIO_USB 1 // use pio-usb as host controller // #define CFG_TUH_MAX3421 1 // use max3421 as host controller // host roothub port is 1 if using either pio-usb or max3421 diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index abce35245..1cc5c1836 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -907,9 +907,9 @@ void tusb_hal_nrf_power_event(uint32_t event) { USB_EVT_READY = 2 }; -#if CFG_TUSB_DEBUG >= 2 +#if CFG_TUSB_DEBUG >= 3 const char* const power_evt_str[] = {"Detected", "Removed", "Ready"}; - TU_LOG(2, "Power USB event: %s\r\n", power_evt_str[event]); + TU_LOG(3, "Power USB event: %s\r\n", power_evt_str[event]); #endif switch (event) { diff --git a/src/portable/nxp/khci/dcd_khci.c b/src/portable/nxp/khci/dcd_khci.c index dc71117b3..ef61146aa 100644 --- a/src/portable/nxp/khci/dcd_khci.c +++ b/src/portable/nxp/khci/dcd_khci.c @@ -540,7 +540,7 @@ void dcd_int_handler(uint8_t rhport) } if (is & USB_ISTAT_SLEEP_MASK) { - // TU_LOG2("Suspend: "); TU_LOG2_HEX(is); + // TU_LOG3("Suspend: "); TU_LOG2_HEX(is); // Note Host usually has extra delay after bus reset (without SOF), which could falsely // detected as Sleep event. Though usbd has debouncing logic so we are good -- cgit v1.3.1 From 5083d1eb3399d605d64b3e30a784731f330e7774 Mon Sep 17 00:00:00 2001 From: Okarss <104319900+Okarss@users.noreply.github.com> Date: Tue, 18 Jun 2024 12:12:44 +0300 Subject: Update Host mode information for FSDEV devices --- docs/reference/supported.rst | 13 +++++++------ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 6 +++--- 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'src/portable') diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index d0e0bf1af..441c885ac 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -104,11 +104,11 @@ Supported MCUs | +-----------------------+--------+------+-----------+-------------------+--------------+ | | F7 | ✔ | | ✔ | dwc2 | | | +-----------------------+--------+------+-----------+-------------------+--------------+ -| | G0 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | G0 | ✔ | | ✖ | stm32_fsdev | | | +-----------------------+--------+------+-----------+-------------------+--------------+ | | G4 | ✔ | ✖ | ✖ | stm32_fsdev | | | +-----------------------+--------+------+-----------+-------------------+--------------+ -| | H5 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | H5 | ✔ | | ✖ | stm32_fsdev | | | +-----------------------+--------+------+-----------+-------------------+--------------+ | | H7 | ✔ | | ✔ | dwc2 | | | +-----------------------+--------+------+-----------+-------------------+--------------+ @@ -124,13 +124,13 @@ Supported MCUs | +-----------------------+--------+------+-----------+-------------------+--------------+ | | L5 | ✔ | ✖ | ✖ | stm32_fsdev | | | +-----------------------+--------+------+-----------+-------------------+--------------+ -| | U5 | 535, 545 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | U5 | 535, 545 | ✔ | | ✖ | stm32_fsdev | | | | +------------------+--------+------+-----------+-------------------+--------------+ | | | 575, 585 | ✔ | | ✖ | dwc2 | | | | +------------------+--------+------+-----------+-------------------+--------------+ | | | 59x,5Ax,5Fx,5Gx | ✔ | | ✔ | dwc2 | | | +----+------------------+--------+------+-----------+-------------------+--------------+ -| | WBx5 | ✔ | | | stm32_fsdev | | +| | WBx5 | ✔ | ✖ | ✖ | stm32_fsdev | | +--------------+-----------------------+--------+------+-----------+-------------------+--------------+ | TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | | | +-----------------------+--------+------+-----------+-------------------+--------------+ @@ -153,8 +153,9 @@ Table Legend = =================== ✔ Supported -⚠ WIP/partial support -✖ Not supported +⚠ Partial support +✖ Not supported by hardware +[empty] Unknown = =================== Supported Boards diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 0ecb6ea05..fb499fa18 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -41,15 +41,15 @@ * F102, F103 512 byte buffer; no internal D+ pull-up (maybe many more changes?) * F302xB/C, F303xB/C, F373 512 byte buffer; no internal D+ pull-up * F302x6/8, F302xD/E2, F303xD/E 1024 byte buffer; no internal D+ pull-up - * G0 2048 byte buffer; 32-bit bus + * G0 2048 byte buffer; 32-bit bus; host mode * G4 1024 byte buffer - * H5 2048 byte buffer; 32-bit bus + * H5 2048 byte buffer; 32-bit bus; host mode * L0x2, L0x3 1024 byte buffer * L1 512 byte buffer * L4x2, L4x3 1024 byte buffer * L5 1024 byte buffer * U0 1024 byte buffer; 32-bit bus - * U535, U545 2048 byte buffer; 32-bit bus + * U535, U545 2048 byte buffer; 32-bit bus; host mode * WB35, WB55 1024 byte buffer * * To use this driver, you must: -- cgit v1.3.1 From 0d79da37e79b8abd04f7f9ba9c15114d84e9810a Mon Sep 17 00:00:00 2001 From: Andrew Leech Date: Thu, 20 Jun 2024 15:15:51 +1000 Subject: synopsys/dwc2_esp32: Add header for vTaskDelay. --- src/portable/synopsys/dwc2/dwc2_esp32.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dwc2_esp32.h b/src/portable/synopsys/dwc2/dwc2_esp32.h index c50dd66b8..932f52f40 100644 --- a/src/portable/synopsys/dwc2/dwc2_esp32.h +++ b/src/portable/synopsys/dwc2/dwc2_esp32.h @@ -35,6 +35,7 @@ #include "esp_intr_alloc.h" #include "soc/periph_defs.h" //#include "soc/usb_periph.h" +#include "freertos/task.h" #define DWC2_REG_BASE 0x60080000UL #define DWC2_EP_MAX 6 // USB_OUT_EP_NUM. TODO ESP32Sx only has 5 tx fifo (5 endpoint IN) -- cgit v1.3.1 From 6d4e2f6c16e239889195fcfbd81b4d27b6ff1979 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Thu, 27 Jun 2024 22:02:18 +0200 Subject: Fix GenID 3.10 issue on STM32L4. --- src/portable/synopsys/dwc2/dcd_dwc2.c | 66 ++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 32 deletions(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index ffcb52f40..2871927be 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1032,21 +1032,7 @@ static void handle_rxflvl_irq(uint8_t rhport) { // XFRC complete is additionally generated when // - setup packet is received // - complete the data stage of control write is complete - if ((epnum == 0) && (bcnt == 0) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { - uint32_t doepint = epout->doepint; - - if (doepint & (DOEPINT_STPKTRX | DOEPINT_OTEPSPR)) { - // skip this "no-data" transfer complete event - // Note: STPKTRX will be clear later by setup received handler - uint32_t clear_flags = DOEPINT_XFRC; - - if (doepint & DOEPINT_OTEPSPR) clear_flags |= DOEPINT_OTEPSPR; - - epout->doepint = clear_flags; - - // TU_LOG(DWC2_DEBUG, " FIX extra transfer complete on setup/data compete\r\n"); - } - } + // It will be handled in handle_epout_irq() break; default: // Invalid @@ -1073,23 +1059,23 @@ static void handle_epout_irq(uint8_t rhport) { xfer_ctl_t* xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT); - if (doepint & DOEPINT_STUP) { - // STPKTRX is only available for version from 3_00a - if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { - epout->doepint = DOEPINT_STPKTRX; - } - } else if (doepint & DOEPINT_OTEPSPR) { - epout->doepint = DOEPINT_OTEPSPR; - } else { - if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { - epout->doepint = DOEPINT_STPKTRX; + if(dma_enabled(rhport)) { + if (doepint & DOEPINT_STUP) { + // STPKTRX is only available for version from 3_00a + if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { + epout->doepint = DOEPINT_STPKTRX; + } + } else if (doepint & DOEPINT_OTEPSPR) { + epout->doepint = DOEPINT_OTEPSPR; } else { - // EP0 can only handle one packet - if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { - // Schedule another packet to be received. - edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { + epout->doepint = DOEPINT_STPKTRX; } else { - if(dma_enabled(rhport)) { + // EP0 can only handle one packet + if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { + // Schedule another packet to be received. + edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + } else { // Fix packet length uint16_t remain = (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos; xfer->total_len -= remain; @@ -1097,8 +1083,24 @@ static void handle_epout_irq(uint8_t rhport) { if(n == 0 && xfer->total_len == 0) { dma_stpkt_rx(rhport); } + + dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); } + } + } + } else { + if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) { + epout->doepint = DOEPINT_STPKTRX; + } else { + if ((doepint & DOEPINT_OTEPSPR) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) { + epout->doepint = DOEPINT_OTEPSPR; + } + // EP0 can only handle one packet + if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { + // Schedule another packet to be received. + edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + } else { dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); } } @@ -1108,10 +1110,10 @@ static void handle_epout_irq(uint8_t rhport) { // SETUP packet Setup Phase done. if (doepint & DOEPINT_STUP) { epout->doepint = DOEPINT_STUP; - if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { + if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { epout->doepint = DOEPINT_STPKTRX; } - if(dma_enabled(rhport) && (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a)) { + if(dma_enabled(rhport) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { dma_stpkt_rx(rhport); } -- cgit v1.3.1 From 0f288326cc80dba192d08b74116aa0be91a81a6f Mon Sep 17 00:00:00 2001 From: Brent Kowal Date: Fri, 28 Jun 2024 16:55:27 -0400 Subject: Initial Commit for MAX32 Support Initial commit for the port of TUSB to MAX32xxx parts, staring with MAX32690 - Added dcd_max32.c (based on dcd_musb.c) for interfacing with the peripheral - Added MAX32690 part family support - Added max32690evkit board support - Updated examples for unique EP number requirement - Updated get_deps.py to fetch the MSDK Known Issues / Additional Testing Required - msc_dual_lun only shown 1 volume on Windows - USBTMC does not have a valid Windowsdriver - DFU does not have a valid Windows driver - WebUSB is "Device not Recognized" - Need to test build scripts with IAR and Clang --- examples/device/cdc_msc/src/usb_descriptors.c | 10 + .../device/cdc_msc_freertos/src/usb_descriptors.c | 10 + examples/device/cdc_uac2/src/usb_descriptors.c | 10 + .../dynamic_configuration/src/usb_descriptors.c | 13 + examples/device/midi_test/src/usb_descriptors.c | 4 + examples/device/msc_dual_lun/src/usb_descriptors.c | 6 + .../device/net_lwip_webserver/src/tusb_config.h | 2 + .../net_lwip_webserver/src/usb_descriptors.c | 7 + examples/device/uac2_headset/src/usb_descriptors.c | 7 + .../device/webusb_serial/src/usb_descriptors.c | 7 + hw/bsp/board_mcu.h | 3 + hw/bsp/max32690/FreeRTOSConfig/FreeRTOSConfig.h | 149 ++++ hw/bsp/max32690/boards/max32690evkit/board.cmake | 1 + hw/bsp/max32690/boards/max32690evkit/board.h | 56 ++ hw/bsp/max32690/boards/max32690evkit/board.mk | 1 + hw/bsp/max32690/family.c | 159 ++++ hw/bsp/max32690/family.cmake | 152 ++++ hw/bsp/max32690/family.mk | 106 +++ hw/bsp/max32690/max32690.ld | 162 ++++ src/common/tusb_mcu.h | 8 + src/portable/analog/max32/dcd_max32.c | 841 +++++++++++++++++++++ src/tusb_option.h | 3 + tools/get_deps.py | 3 + 23 files changed, 1720 insertions(+) create mode 100644 hw/bsp/max32690/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/max32690/boards/max32690evkit/board.cmake create mode 100644 hw/bsp/max32690/boards/max32690evkit/board.h create mode 100644 hw/bsp/max32690/boards/max32690evkit/board.mk create mode 100644 hw/bsp/max32690/family.c create mode 100644 hw/bsp/max32690/family.cmake create mode 100644 hw/bsp/max32690/family.mk create mode 100644 hw/bsp/max32690/max32690.ld create mode 100644 src/portable/analog/max32/dcd_max32.c (limited to 'src/portable') diff --git a/examples/device/cdc_msc/src/usb_descriptors.c b/examples/device/cdc_msc/src/usb_descriptors.c index 2afa24903..1ca614f4e 100644 --- a/examples/device/cdc_msc/src/usb_descriptors.c +++ b/examples/device/cdc_msc/src/usb_descriptors.c @@ -125,6 +125,16 @@ enum { #define EPNUM_MSC_OUT 0x04 #define EPNUM_MSC_IN 0x85 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 + // MAX32 doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_CDC_NOTIF 0x81 + #define EPNUM_CDC_OUT 0x02 + #define EPNUM_CDC_IN 0x83 + + #define EPNUM_MSC_OUT 0x04 + #define EPNUM_MSC_IN 0x85 + #else #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 diff --git a/examples/device/cdc_msc_freertos/src/usb_descriptors.c b/examples/device/cdc_msc_freertos/src/usb_descriptors.c index 9c29701c7..f563e80d3 100644 --- a/examples/device/cdc_msc_freertos/src/usb_descriptors.c +++ b/examples/device/cdc_msc_freertos/src/usb_descriptors.c @@ -106,6 +106,16 @@ enum #define EPNUM_MSC_OUT 0x04 #define EPNUM_MSC_IN 0x85 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 + // MAX32 doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_CDC_NOTIF 0x81 + #define EPNUM_CDC_OUT 0x02 + #define EPNUM_CDC_IN 0x83 + + #define EPNUM_MSC_OUT 0x04 + #define EPNUM_MSC_IN 0x85 + #else #define EPNUM_CDC_NOTIF 0x81 #define EPNUM_CDC_OUT 0x02 diff --git a/examples/device/cdc_uac2/src/usb_descriptors.c b/examples/device/cdc_uac2/src/usb_descriptors.c index 72a695622..43e8cf3d7 100644 --- a/examples/device/cdc_uac2/src/usb_descriptors.c +++ b/examples/device/cdc_uac2/src/usb_descriptors.c @@ -117,6 +117,16 @@ uint8_t const * tud_descriptor_device_cb(void) #define EPNUM_CDC_OUT 0x04 #define EPNUM_CDC_IN 0x85 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 + // MAX32 doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_AUDIO_IN 0x01 + #define EPNUM_AUDIO_OUT 0x02 + + #define EPNUM_CDC_NOTIF 0x83 + #define EPNUM_CDC_OUT 0x04 + #define EPNUM_CDC_IN 0x85 + #else #define EPNUM_AUDIO_IN 0x01 #define EPNUM_AUDIO_OUT 0x01 diff --git a/examples/device/dynamic_configuration/src/usb_descriptors.c b/examples/device/dynamic_configuration/src/usb_descriptors.c index 7f35b4b22..eebdd4f69 100644 --- a/examples/device/dynamic_configuration/src/usb_descriptors.c +++ b/examples/device/dynamic_configuration/src/usb_descriptors.c @@ -158,6 +158,19 @@ enum #define EPNUM_1_MSC_OUT 0x01 #define EPNUM_1_MSC_IN 0x82 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 + // FT9XX doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_0_CDC_NOTIF 0x81 + #define EPNUM_0_CDC_OUT 0x02 + #define EPNUM_0_CDC_IN 0x83 + + #define EPNUM_0_MIDI_OUT 0x04 + #define EPNUM_0_MIDI_IN 0x85 + + #define EPNUM_1_MSC_OUT 0x01 + #define EPNUM_1_MSC_IN 0x82 + #else #define EPNUM_0_CDC_NOTIF 0x81 #define EPNUM_0_CDC_OUT 0x02 diff --git a/examples/device/midi_test/src/usb_descriptors.c b/examples/device/midi_test/src/usb_descriptors.c index 9781d3d6f..797b50ab2 100644 --- a/examples/device/midi_test/src/usb_descriptors.c +++ b/examples/device/midi_test/src/usb_descriptors.c @@ -90,6 +90,10 @@ enum // On Bridgetek FT9xx endpoint numbers must be unique... #define EPNUM_MIDI_OUT 0x02 #define EPNUM_MIDI_IN 0x03 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 + // On MAX32 endpoint numbers must be unique... + #define EPNUM_MIDI_OUT 0x02 + #define EPNUM_MIDI_IN 0x03 #else #define EPNUM_MIDI_OUT 0x01 #define EPNUM_MIDI_IN 0x01 diff --git a/examples/device/msc_dual_lun/src/usb_descriptors.c b/examples/device/msc_dual_lun/src/usb_descriptors.c index c0610945f..e32466228 100644 --- a/examples/device/msc_dual_lun/src/usb_descriptors.c +++ b/examples/device/msc_dual_lun/src/usb_descriptors.c @@ -97,6 +97,12 @@ enum #define EPNUM_MSC_OUT 0x01 #define EPNUM_MSC_IN 0x82 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 + // MAX32 doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_MSC_OUT 0x01 + #define EPNUM_MSC_IN 0x82 + #else #define EPNUM_MSC_OUT 0x01 #define EPNUM_MSC_IN 0x81 diff --git a/examples/device/net_lwip_webserver/src/tusb_config.h b/examples/device/net_lwip_webserver/src/tusb_config.h index d3e094517..2f641f33e 100644 --- a/examples/device/net_lwip_webserver/src/tusb_config.h +++ b/examples/device/net_lwip_webserver/src/tusb_config.h @@ -91,6 +91,8 @@ extern "C" { #define USE_ECM 1 #elif TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32F1) #define USE_ECM 1 +#elif TU_CHECK_MCU(OPT_MCU_MAX32690) + #define USE_ECM 1 #else #define USE_ECM 0 #define INCLUDE_IPERF diff --git a/examples/device/net_lwip_webserver/src/usb_descriptors.c b/examples/device/net_lwip_webserver/src/usb_descriptors.c index da628c8be..ba30b869e 100644 --- a/examples/device/net_lwip_webserver/src/usb_descriptors.c +++ b/examples/device/net_lwip_webserver/src/usb_descriptors.c @@ -120,6 +120,13 @@ uint8_t const * tud_descriptor_device_cb(void) #define EPNUM_NET_OUT 0x02 #define EPNUM_NET_IN 0x83 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 + // MAX32 doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_NET_NOTIF 0x81 + #define EPNUM_NET_OUT 0x02 + #define EPNUM_NET_IN 0x83 + #else #define EPNUM_NET_NOTIF 0x81 #define EPNUM_NET_OUT 0x02 diff --git a/examples/device/uac2_headset/src/usb_descriptors.c b/examples/device/uac2_headset/src/usb_descriptors.c index ff4dc2acc..bfc8a4ab5 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.c +++ b/examples/device/uac2_headset/src/usb_descriptors.c @@ -104,6 +104,13 @@ uint8_t const * tud_descriptor_device_cb(void) #define EPNUM_AUDIO_OUT 0x02 #define EPNUM_AUDIO_INT 0x03 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 + // MAX32 doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_AUDIO_IN 0x01 + #define EPNUM_AUDIO_OUT 0x02 + #define EPNUM_AUDIO_INT 0x03 + #else #define EPNUM_AUDIO_IN 0x01 #define EPNUM_AUDIO_OUT 0x01 diff --git a/examples/device/webusb_serial/src/usb_descriptors.c b/examples/device/webusb_serial/src/usb_descriptors.c index b01fae8e3..bcfbe590e 100644 --- a/examples/device/webusb_serial/src/usb_descriptors.c +++ b/examples/device/webusb_serial/src/usb_descriptors.c @@ -105,6 +105,13 @@ enum #define EPNUM_CDC_OUT 3 #define EPNUM_VENDOR_IN 4 #define EPNUM_VENDOR_OUT 5 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 + // MAX32 doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_CDC_IN 2 + #define EPNUM_CDC_OUT 3 + #define EPNUM_VENDOR_IN 4 + #define EPNUM_VENDOR_OUT 5 #else #define EPNUM_CDC_IN 2 #define EPNUM_CDC_OUT 2 diff --git a/hw/bsp/board_mcu.h b/hw/bsp/board_mcu.h index 013eb1c83..436164c35 100644 --- a/hw/bsp/board_mcu.h +++ b/hw/bsp/board_mcu.h @@ -170,6 +170,9 @@ #elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837) // no header needed +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 + #include "max32690.h" + #else #error "Missing MCU header" #endif diff --git a/hw/bsp/max32690/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/max32690/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..e5a76af85 --- /dev/null +++ b/hw/bsp/max32690/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,149 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "mxc_device.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS __NVIC_PRIO_BITS + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<ldoctrl |= MXC_F_MCR_LDOCTRL_0P9EN; + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_USB); + MXC_SYS_Reset_Periph(MXC_SYS_RESET0_USB); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) { + #if LED_STATE_ON + state = !state; + #endif + if(state) { + MXC_GPIO_OutClr(LED_PORT, LED_PIN); + } else { + MXC_GPIO_OutSet(LED_PORT, LED_PIN); + } +} + +uint32_t board_button_read(void) { + uint32_t state = MXC_GPIO_InGet(BUTTON_PORT, BUTTON_PIN) ? 1 : 0; + return BUTTON_STATE_ACTIVE == state; +} + +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + uint8_t hw_id[MXC_SYS_USN_CHECKSUM_LEN]; //USN Buffer + /* All other 2nd parameter is optional checkum buffer */ + MXC_SYS_GetUSN(hw_id, NULL); + + size_t act_len = TU_MIN(max_len, MXC_SYS_USN_LEN); + memcpy(id, hw_id, act_len); + return act_len; +} + +int board_uart_read(uint8_t *buf, int len) { + int uart_val; + int act_len = 0; + + while( act_len < len ) { + if((uart_val = MXC_UART_ReadCharacterRaw(ConsoleUart)) == E_UNDERFLOW) { + break; + } else { + *buf++ = (uint8_t)uart_val; + act_len++; + } + } + return act_len; +} + +int board_uart_write(void const *buf, int len) { + int act_len = 0; + const uint8_t* ch_ptr = (const uint8_t*)buf; + while(act_len < len){ + MXC_UART_WriteCharacter(ConsoleUart, *ch_ptr++); + act_len++; + } + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +void SysTick_Handler(void) { + system_ticks++; +} + +uint32_t board_millis(void) { + return system_ticks; +} +#endif + +void HardFault_Handler(void) { + __asm("BKPT #0\n"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) { +} diff --git a/hw/bsp/max32690/family.cmake b/hw/bsp/max32690/family.cmake new file mode 100644 index 000000000..e1d797f58 --- /dev/null +++ b/hw/bsp/max32690/family.cmake @@ -0,0 +1,152 @@ +include_guard() + +set(MAX32_PERIPH ${TOP}/hw/mcu/analog/max32/Libraries/PeriphDrivers) +set(MAX32_CMSIS ${TOP}/hw/mcu/analog/max32/Libraries/CMSIS) +set(CMSIS_5 ${TOP}/lib/CMSIS_5) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# Get the linker file from current location (family) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/max32690.ld) +set(LD_FILE_Clang ${LD_FILE_GNU}) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) +set(JLINK_DEVICE max32690) + +set(FAMILY_MCUS MAX32690 CACHE INTERNAL "") + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + TARGET=MAX32690 + TARGET_REV=0x4131 + MXC_ASSERT_ENABLE + MAX32690 + FLASH_ORIGIN=0x10000000 + FLASH_SIZE=0x340000 + SRAM_ORIGIN=0x20000000 + SRAM_SIZE=0x100000 + IAR_PRAGMAS=0 + CFG_TUSB_MCU=OPT_MCU_MAX32690 + BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + ) +endfunction() + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif () + + # Startup & Linker script + set(STARTUP_FILE_GNU ${MAX32_CMSIS}/Device/Maxim/MAX32690/Source/GCC/startup_max32690.s) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + set(STARTUP_FILE_IAR ${MAX32_CMSIS}/Device/Maxim/MAX32690/Source/IAR/startup_max32690.s) + + set(PERIPH_SRC ${MAX32_PERIPH}/Source) + add_library(${BOARD_TARGET} STATIC + ${MAX32_CMSIS}/Device/Maxim/MAX32690/Source/heap.c + ${MAX32_CMSIS}/Device/Maxim/MAX32690/Source/system_max32690.c + ${PERIPH_SRC}/SYS/mxc_assert.c + ${PERIPH_SRC}/SYS/mxc_delay.c + ${PERIPH_SRC}/SYS/mxc_lock.c + ${PERIPH_SRC}/SYS/nvic_table.c + ${PERIPH_SRC}/SYS/pins_me18.c + ${PERIPH_SRC}/SYS/sys_me18.c + ${PERIPH_SRC}/CTB/ctb_me18.c + ${PERIPH_SRC}/CTB/ctb_reva.c + ${PERIPH_SRC}/CTB/ctb_common.c + ${PERIPH_SRC}/FLC/flc_common.c + ${PERIPH_SRC}/FLC/flc_me18.c + ${PERIPH_SRC}/FLC/flc_reva.c + ${PERIPH_SRC}/GPIO/gpio_common.c + ${PERIPH_SRC}/GPIO/gpio_me18.c + ${PERIPH_SRC}/GPIO/gpio_reva.c + ${PERIPH_SRC}/ICC/icc_me18.c + ${PERIPH_SRC}/ICC/icc_reva.c + ${PERIPH_SRC}/UART/uart_common.c + ${PERIPH_SRC}/UART/uart_me18.c + ${PERIPH_SRC}/UART/uart_revb.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${MAX32_CMSIS}/Include + ${MAX32_CMSIS}/Device/Maxim/MAX32690/Include + ${MAX32_PERIPH}/Include/MAX32690 + ${PERIPH_SRC}/SYS + ${PERIPH_SRC}/GPIO + ${PERIPH_SRC}/CTB + ${PERIPH_SRC}/ICC + ${PERIPH_SRC}/FLC + ${PERIPH_SRC}/UART + ) + + target_compile_options(${TARGET} PRIVATE + -Wno-error=strict-prototypes + ) + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_MAX32690 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/analog/max32/dcd_max32.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + target_compile_options(${TARGET}-tinyusb PRIVATE + -Wno-error=strict-prototypes + ) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_flash_jlink(${TARGET}) +endfunction() diff --git a/hw/bsp/max32690/family.mk b/hw/bsp/max32690/family.mk new file mode 100644 index 000000000..08d5e8671 --- /dev/null +++ b/hw/bsp/max32690/family.mk @@ -0,0 +1,106 @@ +DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/analog/max32 + +# Important locations in the hw support for MCU +MAX32_CMSIS = hw/mcu/analog/max32/Libraries/CMSIS +MAX32_PERIPH = hw/mcu/analog/max32/Libraries/PeriphDrivers + +# Add any board specific make rules +include $(TOP)/$(BOARD_PATH)/board.mk + +CPU_CORE ?= cortex-m4 +PORT ?= 0 + +# GCC +SRC_S_GCC += $(MAX32_CMSIS)/Device/Maxim/MAX32690/Source/GCC/startup_max32690.s +LD_FILE = $(FAMILY_PATH)/max32690.ld + +# IAR +SRC_S_IAR += $(MAX32_CMSIS)/Device/Maxim/MAX32690/Source/IAR/startup_max32690.s + +# -------------- +# Compiler Flags +# -------------- +# Flags for the MAX32690 SDK +CFLAGS += -DTARGET=MAX32690 \ + -DTARGET_REV=0x4131 \ + -DMXC_ASSERT_ENABLE \ + -DMAX32690 \ + -DFLASH_ORIGIN=0x10000000 \ + -DFLASH_SIZE=0x340000 \ + -DSRAM_ORIGIN=0x20000000 \ + -DSRAM_SIZE=0x100000 \ + -DIAR_PRAGMAS=0 + +# Flags for TUSB features +CFLAGS += \ + -DCFG_TUSB_MCU=OPT_MCU_MAX32690 \ + -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + +# mcu driver cause following warnings +CFLAGS += -Wno-error=unused-parameter \ + -Wno-error=strict-prototypes \ + -Wno-error=old-style-declaration \ + -Wno-error=sign-compare \ + -Wno-error=cast-qual \ + -Wno-lto-type-mismatch + +LDFLAGS_GCC += -nostartfiles --specs=nosys.specs --specs=nano.specs + +# For flash-jlink target +JLINK_DEVICE = max32690 + +# flash target using Jlik +flash: flash-jlink + +# Optional flash option when running within an installed MSDK to use OpenOCD +# Mainline OpenOCD does not yet have the MAX32's flash algorithm integrated. +# If the MSDK is installed, flash-msdk can be run to utilize the the modified +# openocd with the algorithms +MAXIM_PATH := $(subst \,/,$(MAXIM_PATH)) +flash-msdk: + $(MAXIM_PATH)/Tools/OpenOCD/openocd -s $(MAXIM_PATH)/Tools/OpenOCD/scripts \ + -f interface/cmsis-dap.cfg -f target/max32690.cfg \ + -c "program $(BUILD)/$(PROJECT).elf verify; init; reset; exit" + +# ----------------- +# Sources & Include +# ----------------- +PERIPH_SRC = $(TOP)/$(MAX32_PERIPH)/Source +SRC_C += \ + src/portable/analog/max32/dcd_max32.c \ + $(MAX32_CMSIS)/Device/Maxim/MAX32690/Source/heap.c \ + $(MAX32_CMSIS)/Device/Maxim/MAX32690/Source/system_max32690.c \ + $(PERIPH_SRC)/SYS/mxc_assert.c \ + $(PERIPH_SRC)/SYS/mxc_delay.c \ + $(PERIPH_SRC)/SYS/mxc_lock.c \ + $(PERIPH_SRC)/SYS/nvic_table.c \ + $(PERIPH_SRC)/SYS/pins_me18.c \ + $(PERIPH_SRC)/SYS/sys_me18.c \ + $(PERIPH_SRC)/CTB/ctb_me18.c \ + $(PERIPH_SRC)/CTB/ctb_reva.c \ + $(PERIPH_SRC)/CTB/ctb_common.c \ + $(PERIPH_SRC)/FLC/flc_common.c \ + $(PERIPH_SRC)/FLC/flc_me18.c \ + $(PERIPH_SRC)/FLC/flc_reva.c \ + $(PERIPH_SRC)/GPIO/gpio_common.c \ + $(PERIPH_SRC)/GPIO/gpio_me18.c \ + $(PERIPH_SRC)/GPIO/gpio_reva.c \ + $(PERIPH_SRC)/ICC/icc_me18.c \ + $(PERIPH_SRC)/ICC/icc_reva.c \ + $(PERIPH_SRC)/UART/uart_common.c \ + $(PERIPH_SRC)/UART/uart_me18.c \ + $(PERIPH_SRC)/UART/uart_revb.c \ + + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(MAX32_CMSIS)/Include \ + $(TOP)/$(MAX32_CMSIS)/Device/Maxim/MAX32690/Include \ + $(TOP)/$(MAX32_PERIPH)/Include/MAX32690 \ + $(PERIPH_SRC)/SYS \ + $(PERIPH_SRC)/GPIO \ + $(PERIPH_SRC)/CTB \ + $(PERIPH_SRC)/ICC \ + $(PERIPH_SRC)/FLC \ + $(PERIPH_SRC)/UART diff --git a/hw/bsp/max32690/max32690.ld b/hw/bsp/max32690/max32690.ld new file mode 100644 index 000000000..35886fe3a --- /dev/null +++ b/hw/bsp/max32690/max32690.ld @@ -0,0 +1,162 @@ +MEMORY { + ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x00020000 /* 128kB ROM */ + FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 0x00340000 + SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00100000 + + /* + * Note that CS0/CS1 address mappings may be reversed using MXC_HPC->mbr0 and ->mbr1 + * The following mappings are selected for simplicity + */ + HPB_CS0 (rwx) : ORIGIN = 0x60000000, LENGTH = 0x10000000 /* External Hyperbus/Xccelabus chip select 0 */ + HPB_CS1 (rwx) : ORIGIN = 0x70000000, LENGTH = 0x10000000 /* External Hyperbus/Xccelabus chip select 1 */ +} + +SECTIONS { + .rom : + { + KEEP(*(.rom_vector)) + *(.rom_handlers*) + } > ROM + + .text : + { + _text = .; + KEEP(*(.isr_vector)) + EXCLUDE_FILE (*riscv.o) *(.text*) /* program code, exclude RISCV code */ + *(.rodata*) /* read-only data: "const" */ + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + /* C++ Exception handling */ + KEEP(*(.eh_frame*)) + _etext = .; + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + /* These sections allow code to be compiled/linked for HPB addresses, but reside in + * flash until copied by code to the external HPB flash device + */ + .hpb_cs0_section : + { + __hpb_cs0_start = ABSOLUTE(.); + KEEP(*(.hpb_cs0_section*)) + } > HPB_CS0 AT>FLASH + + __load_start_hpb_cs0 = LOADADDR(.hpb_cs0_section); + __load_length_hpb_cs0 = SIZEOF(.hpb_cs0_section); + + .hpb_cs1_section : + { + __hpb_cs1_start = ABSOLUTE(.); + KEEP(*(.hpb_cs1_section*)) + } > HPB_CS1 AT>FLASH + + __load_start_hpb_cs1 = LOADADDR(.hpb_cs1_section); + __load_length_hpb_cs1 = SIZEOF(.hpb_cs1_section); + + /* Binary import */ + .bin_storage : + { + FILL(0xFF) + _bin_start_ = .; + KEEP(*(.bin_storage_img)) + _bin_end_ = .; + . = ALIGN(4); + } > FLASH + + /* it's used for C++ exception handling */ + /* we need to keep this to avoid overlapping */ + .ARM.exidx : + { + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } > FLASH + + .data : + { + _data = ALIGN(., 4); + *(vtable) + *(.data*) /*read-write initialized data: initialized global variable*/ + + /* These array sections are used by __libc_init_array to call static C++ constructors */ + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + /* Run the flash programming functions from SRAM */ + *(.flashprog) + + _edata = ALIGN(., 4); + } > SRAM AT>FLASH + __load_data = LOADADDR(.data); + + .bss : + { + . = ALIGN(4); + _bss = .; + *(.bss*) /*read-write zero initialized data: uninitialzed global variable*/ + *(COMMON) + _ebss = ALIGN(., 4); + } > SRAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(SRAM) + LENGTH(SRAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > SRAM + + .heap (COPY): + { + . = ALIGN(4); + *(.heap*) + __HeapLimit = ABSOLUTE(__StackLimit); + } > SRAM + + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack") +} diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index c66996c4f..a68e160bd 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -452,6 +452,14 @@ #define TUP_RHPORT_HIGHSPEED CFG_TUD_WCH_USBIP_USBHS #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_WCH_USBIP_USBHS ? 16 : 8) +//--------------------------------------------------------------------+ +// Analog Devices +//--------------------------------------------------------------------+ +#elif TU_CHECK_MCU(OPT_MCU_MAX32690) + #define TUP_DCD_ENDPOINT_MAX 12 + #define TUP_RHPORT_HIGHSPEED 1 + + #endif //--------------------------------------------------------------------+ diff --git a/src/portable/analog/max32/dcd_max32.c b/src/portable/analog/max32/dcd_max32.c new file mode 100644 index 000000000..150d476fa --- /dev/null +++ b/src/portable/analog/max32/dcd_max32.c @@ -0,0 +1,841 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Koji KITAYAMA + * Copyright (c) 2024 Brent Kowal (Analog Devices, Inc) + * + * 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 CFG_TUD_ENABLED && TU_CHECK_MCU(OPT_MCU_MAX32690) + +#if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) +/* GCC warns that an address may be unaligned, even though + * the target CPU has the capability for unaligned memory access. */ +_Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); +#endif + +#include "device/dcd.h" + +#include "mxc_delay.h" +#include "mxc_device.h" +#include "mxc_sys.h" +#include "nvic_table.h" +#include "usbhs_regs.h" + +#define USBHS_M31_CLOCK_RECOVERY + +/*------------------------------------------------------------------ + * MACRO TYPEDEF CONSTANT ENUM DECLARATION + *------------------------------------------------------------------*/ +#define REQUEST_TYPE_INVALID (0xFFu) + + +typedef union { + uint8_t u8; + uint16_t u16; + uint32_t u32; +} hw_fifo_t; + +typedef struct TU_ATTR_PACKED +{ + void *buf; /* the start address of a transfer data buffer */ + uint16_t length; /* the number of bytes in the buffer */ + uint16_t remaining; /* the number of bytes remaining in the buffer */ +} pipe_state_t; + +typedef struct +{ + tusb_control_request_t setup_packet; + uint16_t remaining_ctrl; /* The number of bytes remaining in data stage of control transfer. */ + int8_t status_out; + pipe_state_t pipe0; + pipe_state_t pipe[2][TUP_DCD_ENDPOINT_MAX - 1]; /* pipe[direction][endpoint number - 1] */ + uint16_t pipe_buf_is_fifo[2]; /* Bitmap. Each bit means whether 1:TU_FIFO or 0:POD. */ +} dcd_data_t; + +/*------------------------------------------------------------------ + * INTERNAL OBJECT & FUNCTION DECLARATION + *------------------------------------------------------------------*/ +static dcd_data_t _dcd; + + +static volatile void* edpt_get_fifo_ptr(unsigned epnum) +{ + volatile uint32_t *ptr; + + ptr = &MXC_USBHS->fifo0; + ptr += epnum; /* Pointer math: multiplies ep by sizeof(uint32_t) */ + + return (volatile void *)ptr; +} + +static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) +{ + volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; + uintptr_t addr = (uintptr_t)buf; + while (len >= 4) { + reg->u32 = *(uint32_t const *)addr; + addr += 4; + len -= 4; + } + if (len >= 2) { + reg->u16 = *(uint16_t const *)addr; + addr += 2; + len -= 2; + } + if (len) { + reg->u8 = *(uint8_t const *)addr; + } +} + +static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) +{ + volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; + uintptr_t addr = (uintptr_t)buf; + while (len >= 4) { + *(uint32_t *)addr = reg->u32; + addr += 4; + len -= 4; + } + if (len >= 2) { + *(uint16_t *)addr = reg->u16; + addr += 2; + len -= 2; + } + if (len) { + *(uint8_t *)addr = reg->u8; + } +} + +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}, + }; + 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; + if (rem) { + len = TU_MIN(rem, info.len_wrap); + ops[dir].pipe_read_write(info.ptr_wrap, fifo, len); + rem -= len; + } + ops[dir].tu_fifo_advance(f, total_len - rem); +} + +static void process_setup_packet(uint8_t rhport) +{ + uint32_t *p = (void*)&_dcd.setup_packet; + p[0] = MXC_USBHS->fifo0; + p[1] = MXC_USBHS->fifo0; + + _dcd.pipe0.buf = NULL; + _dcd.pipe0.length = 0; + _dcd.pipe0.remaining = 0; + dcd_event_setup_received(rhport, (const uint8_t*)(uintptr_t)&_dcd.setup_packet, true); + + const unsigned len = _dcd.setup_packet.wLength; + _dcd.remaining_ctrl = len; + const unsigned dir_in = tu_edpt_dir(_dcd.setup_packet.bmRequestType); + /* Clear RX FIFO and reverse the transaction direction */ + if (len && dir_in) { + MXC_USBHS->index = 0; + MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_OUTPKTRDY; + } +} + +static bool handle_xfer_in(uint_fast8_t ep_addr) +{ + unsigned epnum = tu_edpt_number(ep_addr); + unsigned epnum_minus1 = epnum - 1; + pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; + const unsigned rem = pipe->remaining; + + //This function should not be for ep0 + TU_ASSERT(epnum); + + if (!rem) { + pipe->buf = NULL; + return true; + } + + MXC_USBHS->index = epnum; + const unsigned mps = MXC_USBHS->inmaxp; + const unsigned len = TU_MIN(mps, rem); + void *buf = pipe->buf; + volatile void* fifo_ptr = edpt_get_fifo_ptr(epnum); + // 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, fifo_ptr, len, TUSB_DIR_IN); + } else { + pipe_write_packet(buf,fifo_ptr, len); + pipe->buf = buf + len; + } + pipe->remaining = rem - len; + } + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_INPKTRDY; //TODO: Verify a | isnt needed + + return false; +} + +static bool handle_xfer_out(uint_fast8_t ep_addr) +{ + unsigned epnum = tu_edpt_number(ep_addr); + unsigned epnum_minus1 = epnum - 1; + pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; + + //This function should not be for ep0 + TU_ASSERT(epnum); + + MXC_USBHS->index = epnum; + + TU_ASSERT(MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY); + + const unsigned mps = MXC_USBHS->outmaxp; + const unsigned rem = pipe->remaining; + const unsigned vld = MXC_USBHS->outcount; + const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); + void *buf = pipe->buf; + volatile void* fifo_ptr = edpt_get_fifo_ptr(epnum); + if (len) { + if (_dcd.pipe_buf_is_fifo[TUSB_DIR_OUT] & TU_BIT(epnum_minus1)) { + pipe_read_write_packet_ff(buf,fifo_ptr, len, TUSB_DIR_OUT); + } else { + pipe_read_packet(buf, fifo_ptr, len); + pipe->buf = buf + len; + } + pipe->remaining = rem - len; + } + if ((len < mps) || (rem == len)) { + pipe->buf = NULL; + return NULL != buf; + } + MXC_USBHS->outcsrl = 0; /* Clear RXRDY bit */ //TODO: Verify just setting to 0 is ok + return false; +} + +static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) +{ + (void)rhport; + + unsigned epnum = tu_edpt_number(ep_addr); + unsigned epnum_minus1 = epnum - 1; + unsigned dir_in = tu_edpt_dir(ep_addr); + + pipe_state_t *pipe = &_dcd.pipe[dir_in][epnum_minus1]; + pipe->buf = buffer; + pipe->length = total_bytes; + pipe->remaining = total_bytes; + + if (dir_in) { + handle_xfer_in(ep_addr); + } else { + MXC_USBHS->index = epnum; + if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY){ + MXC_USBHS->outcsrl = 0; //TODO: Verify just setting to 0 is ok + } + } + return true; +} + +static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) +{ + (void)rhport; + TU_ASSERT(total_bytes <= 64); /* Current implementation supports for only up to 64 bytes. */ + + const unsigned req = _dcd.setup_packet.bmRequestType; + TU_ASSERT(req != REQUEST_TYPE_INVALID || total_bytes == 0); + + if (req == REQUEST_TYPE_INVALID || _dcd.status_out) { + /* STATUS OUT stage. + * MUSB controller automatically handles STATUS OUT packets without + * software helps. We do not have to do anything. And STATUS stage + * 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. */ + _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\r\n"); + } + return true; + } + const unsigned dir_in = tu_edpt_dir(ep_addr); + MXC_USBHS->index = 0; + if (tu_edpt_dir(req) == dir_in) { /* DATA stage */ + TU_ASSERT(total_bytes <= _dcd.remaining_ctrl); + const unsigned rem = _dcd.remaining_ctrl; + const unsigned len = TU_MIN(TU_MIN(rem, 64), total_bytes); + volatile void* fifo_ptr = edpt_get_fifo_ptr(0); + if (dir_in) { + pipe_write_packet(buffer, fifo_ptr, len); + + _dcd.pipe0.buf = buffer + len; + _dcd.pipe0.length = len; + _dcd.pipe0.remaining = 0; + + _dcd.remaining_ctrl = rem - len; + if ((len < 64) || (rem == len)) { + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; /* Change to STATUS/SETUP stage */ + _dcd.status_out = 1; + /* Flush TX FIFO and reverse the transaction direction. */ + MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_INPKTRDY | MXC_F_USBHS_CSR0_DATA_END; + } else { + MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_INPKTRDY; /* Flush TX FIFO to return ACK. */ + } + } else { + _dcd.pipe0.buf = buffer; + _dcd.pipe0.length = len; + _dcd.pipe0.remaining = len; + MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_OUTPKTRDY; /* Clear RX FIFO to return ACK. */ + } + } else if (dir_in) { + _dcd.pipe0.buf = NULL; + _dcd.pipe0.length = 0; + _dcd.pipe0.remaining = 0; + /* Clear RX FIFO and reverse the transaction direction */ + MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_OUTPKTRDY | MXC_F_USBHS_CSR0_DATA_END; + } + return true; +} + +static void process_ep0(uint8_t rhport) +{ + MXC_USBHS->index = 0; + uint_fast8_t csrl = MXC_USBHS->csr0; + + if (csrl & MXC_F_USBHS_CSR0_SENT_STALL) { + /* Returned STALL packet to HOST. */ + MXC_USBHS->csr0 = 0; /* Clear STALL */ + return; + } + + unsigned req = _dcd.setup_packet.bmRequestType; + if (csrl & MXC_F_USBHS_CSR0_SETUP_END) { + TU_LOG1(" ABORT by the next packets\r\n"); + MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_SETUP_END; + if (req != REQUEST_TYPE_INVALID && _dcd.pipe0.buf) { + /* DATA stage was aborted by receiving STATUS or SETUP packet. */ + _dcd.pipe0.buf = NULL; + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; + dcd_event_xfer_complete(rhport, + req & TUSB_DIR_IN_MASK, + _dcd.pipe0.length - _dcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + } + req = REQUEST_TYPE_INVALID; + if (!(csrl & MXC_F_USBHS_CSR0_OUTPKTRDY)) return; /* Received SETUP packet */ + } + + if (csrl & MXC_F_USBHS_CSR0_OUTPKTRDY) { + /* Received SETUP or DATA OUT packet */ + if (req == REQUEST_TYPE_INVALID) { + /* SETUP */ + TU_ASSERT(sizeof(tusb_control_request_t) == MXC_USBHS->count0,); + process_setup_packet(rhport); + return; + } + if (_dcd.pipe0.buf) { + /* DATA OUT */ + const unsigned vld = MXC_USBHS->count0; + const unsigned rem = _dcd.pipe0.remaining; + const unsigned len = TU_MIN(TU_MIN(rem, 64), vld); + volatile void* fifo_ptr = edpt_get_fifo_ptr(0); + pipe_read_packet(_dcd.pipe0.buf, fifo_ptr, len); + + _dcd.pipe0.remaining = rem - len; + _dcd.remaining_ctrl -= len; + + _dcd.pipe0.buf = NULL; + dcd_event_xfer_complete(rhport, + tu_edpt_addr(0, TUSB_DIR_OUT), + _dcd.pipe0.length - _dcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + } + return; + } + + /* When CSRL0 is zero, it means that completion of sending a any length packet + * or receiving a zero length packet. */ + if (req != REQUEST_TYPE_INVALID && !tu_edpt_dir(req)) { + /* STATUS IN */ + if (*(const uint16_t*)(uintptr_t)&_dcd.setup_packet == 0x0500) { + /* The address must be changed on completion of the control transfer. */ + MXC_USBHS->faddr = (uint8_t)_dcd.setup_packet.wValue; + } + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; + dcd_event_xfer_complete(rhport, + tu_edpt_addr(0, TUSB_DIR_IN), + _dcd.pipe0.length - _dcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + return; + } + if (_dcd.pipe0.buf) { + /* DATA IN */ + _dcd.pipe0.buf = NULL; + dcd_event_xfer_complete(rhport, + tu_edpt_addr(0, TUSB_DIR_IN), + _dcd.pipe0.length - _dcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + } +} + +static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) +{ + bool completed; + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned epnum = tu_edpt_number(ep_addr); + + MXC_USBHS->index = epnum; + + if (dir_in) { + if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_SENTSTALL) { + MXC_USBHS->incsrl &= ~(MXC_F_USBHS_INCSRL_SENTSTALL | MXC_F_USBHS_INCSRL_UNDERRUN); + return; + } + completed = handle_xfer_in(ep_addr); + } else { + if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_SENTSTALL) { + MXC_USBHS->outcsrl &= ~(MXC_F_USBHS_OUTCSRL_SENTSTALL | MXC_F_USBHS_OUTCSRL_OVERRUN); + return; + } + completed = handle_xfer_out(ep_addr); + } + + if (completed) { + pipe_state_t *pipe = &_dcd.pipe[dir_in][tu_edpt_number(ep_addr) - 1]; + dcd_event_xfer_complete(rhport, ep_addr, + pipe->length - pipe->remaining, + XFER_RESULT_SUCCESS, true); + } +} + +static void process_bus_reset(uint8_t rhport) +{ + (void)rhport; + TU_LOG0("------Bus Reset\r\n"); + /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), + * a control transfer state is SETUP or STATUS stage. */ + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; + _dcd.status_out = 0; + /* When pipe0.buf has not NULL, DATA stage works in progress. */ + _dcd.pipe0.buf = NULL; + + MXC_USBHS->intrinen = 1; /* Enable only EP0 */ + MXC_USBHS->introuten = 0; + + + /* Clear FIFO settings */ + for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { + MXC_USBHS->index = i; + if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_INPKTRDY) { + /* Per musbhsfc_pg, only flush FIFO if IN packet loaded */ + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_FLUSHFIFO; + } + + if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { + /* Per musbhsfc_pg, only flush FIFO if OUT packet is ready */ + MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_FLUSHFIFO; + } + } + dcd_event_bus_reset(0, (MXC_USBHS->power & MXC_F_USBHS_POWER_HS_MODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); +} + +/*------------------------------------------------------------------ + * Device API + *------------------------------------------------------------------*/ + +void dcd_init(uint8_t rhport) +{ + (void)rhport; + MXC_USBHS->intrusben |= MXC_F_USBHS_INTRUSBEN_SUSPEND_INT_EN; + + //Interrupt for VBUS disconnect + MXC_USBHS->mxm_int_en |= MXC_F_USBHS_MXM_INT_EN_NOVBUS; + + NVIC_ClearPendingIRQ(USB_IRQn); + dcd_edpt_close_all(rhport); + + //Unsuspend the MAC + MXC_USBHS->mxm_suspend = 0; + + /* Configure PHY */ + MXC_USBHS->m31_phy_xcfgi_31_0 = (0x1 << 3) | (0x1 << 11); + MXC_USBHS->m31_phy_xcfgi_63_32 = 0; + MXC_USBHS->m31_phy_xcfgi_95_64 = 0x1 << (72-64); + MXC_USBHS->m31_phy_xcfgi_127_96 = 0; + + +#ifdef USBHS_M31_CLOCK_RECOVERY + MXC_USBHS->m31_phy_noncry_rstb = 1; + MXC_USBHS->m31_phy_noncry_en = 1; + MXC_USBHS->m31_phy_outclksel = 0; + MXC_USBHS->m31_phy_coreclkin = 0; + MXC_USBHS->m31_phy_xtlsel = 2; /* Select 25 MHz clock */ +#else + /* Use this option to feed the PHY a 30 MHz clock, which is them used as a PLL reference */ + /* As it depends on the system core clock, this should probably be done at the SYS level */ + MXC_USBHS->m31_phy_noncry_rstb = 0; + MXC_USBHS->m31_phy_noncry_en = 0; + MXC_USBHS->m31_phy_outclksel = 1; + MXC_USBHS->m31_phy_coreclkin = 1; + MXC_USBHS->m31_phy_xtlsel = 3; /* Select 30 MHz clock */ +#endif + MXC_USBHS->m31_phy_pll_en = 1; + MXC_USBHS->m31_phy_oscouten = 1; + + /* Reset PHY */ + MXC_USBHS->m31_phy_ponrst = 0; + MXC_USBHS->m31_phy_ponrst = 1; + + dcd_connect(rhport); +} + +void dcd_int_enable(uint8_t rhport) +{ + (void)rhport; + NVIC_EnableIRQ(USB_IRQn); +} + +void dcd_int_disable(uint8_t rhport) +{ + (void)rhport; + NVIC_DisableIRQ(USB_IRQn); +} + +// Receive Set Address request, mcu port must also include status IN response +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) +{ + (void)rhport; + (void)dev_addr; + _dcd.pipe0.buf = NULL; + _dcd.pipe0.length = 0; + _dcd.pipe0.remaining = 0; + /* Clear RX FIFO to return ACK. */ + MXC_USBHS->index = 0; + MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_OUTPKTRDY | MXC_F_USBHS_CSR0_DATA_END; +} + +// Wake up host +void dcd_remote_wakeup(uint8_t rhport) +{ + (void)rhport; + MXC_USBHS->power |= MXC_F_USBHS_POWER_RESUME; + +#if CFG_TUSB_OS != OPT_OS_NONE + osal_task_delay(10); +#else + MXC_Delay(MXC_DELAY_MSEC(10)); +#endif + + MXC_USBHS->power &= ~MXC_F_USBHS_POWER_RESUME; +} + +// Connect by enabling internal pull-up resistor on D+/D- +void dcd_connect(uint8_t rhport) +{ + (void)rhport; + MXC_USBHS->power |= TUD_OPT_HIGH_SPEED ? MXC_F_USBHS_POWER_HS_ENABLE : 0; + MXC_USBHS->power |= MXC_F_USBHS_POWER_SOFTCONN; +} + +// Disconnect by disabling internal pull-up resistor on D+/D- +void dcd_disconnect(uint8_t rhport) +{ + (void)rhport; + MXC_USBHS->power &= ~MXC_F_USBHS_POWER_SOFTCONN; +} + +void dcd_sof_enable(uint8_t rhport, bool en) +{ + (void) rhport; + (void) en; + + // TODO implement later +} + +//--------------------------------------------------------------------+ +// Endpoint API +//--------------------------------------------------------------------+ + +// Configure endpoint's registers according to descriptor +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) +{ + (void) rhport; + + const unsigned ep_addr = ep_desc->bEndpointAddress; + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned xfer = ep_desc->bmAttributes.xfer; + const unsigned mps = tu_edpt_packet_size(ep_desc); + + TU_ASSERT(epn < TUP_DCD_ENDPOINT_MAX); + + pipe_state_t *pipe = &_dcd.pipe[dir_in][epn - 1]; + pipe->buf = NULL; + pipe->length = 0; + pipe->remaining = 0; + + MXC_USBHS->index = epn; + + if (dir_in) { + MXC_USBHS->inmaxp = mps; + MXC_USBHS->incsru = (MXC_F_USBHS_INCSRU_DPKTBUFDIS | MXC_F_USBHS_INCSRU_MODE) | ((xfer == TUSB_XFER_ISOCHRONOUS) ? MXC_F_USBHS_INCSRU_ISO : 0); + if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_INPKTRDY) { + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG | MXC_F_USBHS_INCSRL_FLUSHFIFO; + } else { + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG; + } + MXC_USBHS->intrinen |= TU_BIT(epn); + } else { + MXC_USBHS->outmaxp = mps; + MXC_USBHS->outcsru = (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS) | ((xfer == TUSB_XFER_ISOCHRONOUS) ? MXC_F_USBHS_OUTCSRU_ISO : 0); + if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { + MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG | MXC_F_USBHS_OUTCSRL_FLUSHFIFO; + } else { + MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG; + } + MXC_USBHS->introuten |= TU_BIT(epn); + } + + return true; +} + +void dcd_edpt_close_all(uint8_t rhport) +{ + (void) rhport; + + MXC_SYS_Crit_Enter(); + MXC_USBHS->intrinen = 1; /* Enable only EP0 */ + MXC_USBHS->introuten = 0; + + for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { + MXC_USBHS->index = i; + MXC_USBHS->inmaxp = 0; + MXC_USBHS->incsru = MXC_F_USBHS_INCSRU_DPKTBUFDIS; + + if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_INPKTRDY) { + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG | MXC_F_USBHS_INCSRL_FLUSHFIFO; + } else { + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG; + } + + MXC_USBHS->outmaxp = 0; + MXC_USBHS->outcsru = MXC_F_USBHS_OUTCSRU_DPKTBUFDIS; + + if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { + MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG | MXC_F_USBHS_OUTCSRL_FLUSHFIFO; + } else { + MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG; + } + } + MXC_SYS_Crit_Exit(); +} + +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + unsigned const epn = tu_edpt_number(ep_addr); + unsigned const dir_in = tu_edpt_dir(ep_addr); + + MXC_SYS_Crit_Enter(); + MXC_USBHS->index = epn; + if (dir_in) { + MXC_USBHS->intrinen &= ~TU_BIT(epn); + MXC_USBHS->inmaxp = 0; + MXC_USBHS->incsru = MXC_F_USBHS_INCSRU_DPKTBUFDIS; + if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_INPKTRDY) { + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG | MXC_F_USBHS_INCSRL_FLUSHFIFO; + } else { + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG; + } + } else { + MXC_USBHS->introuten &= ~TU_BIT(epn); + MXC_USBHS->outmaxp = 0; + MXC_USBHS->outcsru = MXC_F_USBHS_OUTCSRU_DPKTBUFDIS; + if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { + MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG | MXC_F_USBHS_OUTCSRL_FLUSHFIFO; + } else { + MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG; + } + } + MXC_SYS_Crit_Exit(); +} + +// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) +{ + (void)rhport; + bool ret; + unsigned const epnum = tu_edpt_number(ep_addr); + MXC_SYS_Crit_Enter(); + if (epnum) { + _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] &= ~TU_BIT(epnum - 1); + ret = edpt_n_xfer(rhport, ep_addr, buffer, total_bytes); + } else + ret = edpt0_xfer(rhport, ep_addr, buffer, total_bytes); + MXC_SYS_Crit_Exit(); + return ret; +} + +// Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c +bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) +{ + (void)rhport; + bool ret; + unsigned const epnum = tu_edpt_number(ep_addr); + TU_ASSERT(epnum); + MXC_SYS_Crit_Enter(); + _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] |= TU_BIT(epnum - 1); + ret = edpt_n_xfer(rhport, ep_addr, (uint8_t*)ff, total_bytes); + MXC_SYS_Crit_Exit(); + return ret; +} + +// Stall endpoint +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + unsigned const epn = tu_edpt_number(ep_addr); + MXC_SYS_Crit_Enter(); + MXC_USBHS->index = epn; + if (0 == epn) { + if (!ep_addr) { /* Ignore EP80 */ + _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; + _dcd.pipe0.buf = NULL; + MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SEND_STALL; + } + } else { + if (tu_edpt_dir(ep_addr)) { /* IN */ + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_SENDSTALL; + } else { /* OUT */ + TU_ASSERT(!(MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY),); + MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_SENDSTALL; + } + } + MXC_SYS_Crit_Exit(); +} + +// clear stall, data toggle is also reset to DATA0 +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) +{ + (void)rhport; + unsigned const epn = tu_edpt_number(ep_addr); + MXC_SYS_Crit_Enter(); + MXC_USBHS->index = epn; + if (tu_edpt_dir(ep_addr)) { /* IN */ + /* IN endpoint */ + if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_INPKTRDY) { + /* Per musbhsfc_pg, only flush FIFO if IN packet loaded */ + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG | MXC_F_USBHS_INCSRL_FLUSHFIFO; + } else { + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG; + } + } else { /* OUT */ + /* Otherwise, must be OUT endpoint */ + if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { + /* Per musbhsfc_pg, only flush FIFO if OUT packet is ready */ + MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG | MXC_F_USBHS_OUTCSRL_FLUSHFIFO; + } else { + MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG; + } + } + MXC_SYS_Crit_Exit(); +} + +/*------------------------------------------------------------------- + * ISR + *-------------------------------------------------------------------*/ +void dcd_int_handler(uint8_t rhport) +{ + uint_fast8_t is, txis, rxis; + uint32_t mxm_int, mxm_int_en, mxm_is; + uint32_t saved_index; + + /* Save current index register */ + saved_index = MXC_USBHS->index; + + is = MXC_USBHS->intrusb; /* read and clear interrupt status */ + txis = MXC_USBHS->intrin; /* read and clear interrupt status */ + rxis = MXC_USBHS->introut; /* read and clear interrupt status */ + + /* These USB interrupt flags are W1C. */ + /* Order of volatile accesses must be separated for IAR */ + mxm_int = MXC_USBHS->mxm_int; + mxm_int_en = MXC_USBHS->mxm_int_en; + mxm_is = mxm_int & mxm_int_en; + MXC_USBHS->mxm_int = mxm_is; + + is &= MXC_USBHS->intrusben; /* Clear disabled interrupts */ + + if (mxm_is & MXC_F_USBHS_MXM_INT_NOVBUS) { + dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); + } + if (is & MXC_F_USBHS_INTRUSB_SOF_INT) { + dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); + } + if (is & MXC_F_USBHS_INTRUSB_RESET_INT) { + process_bus_reset(rhport); + } + if (is & MXC_F_USBHS_INTRUSB_RESUME_INT) { + dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); + } + if (is & MXC_F_USBHS_INTRUSB_SUSPEND_INT) { + dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); + } + + txis &= MXC_USBHS->intrinen; /* Clear disabled interrupts */ + if (txis & MXC_F_USBHS_INTRIN_EP0_IN_INT) { + process_ep0(rhport); + txis &= ~TU_BIT(0); + } + while (txis) { + unsigned const num = __builtin_ctz(txis); + process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_IN)); + txis &= ~TU_BIT(num); + } + rxis &= MXC_USBHS->introuten; /* Clear disabled interrupts */ + while (rxis) { + unsigned const num = __builtin_ctz(rxis); + process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_OUT)); + rxis &= ~TU_BIT(num); + } + + /* Restore register index before exiting ISR */ + MXC_USBHS->index = saved_index; +} + +#endif diff --git a/src/tusb_option.h b/src/tusb_option.h index db8b94580..18f78b49c 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -188,6 +188,9 @@ #define OPT_MCU_MCXN9 2300 ///< NXP MCX N9 Series #define OPT_MCU_MCXA15 2301 ///< NXP MCX A15 Series +// Analog Devices +#define OPT_MCU_MAX32690 2400 ///< ADI MAX32690 + // Check if configured MCU is one of listed // Apply _TU_CHECK_MCU with || as separator to list of input #define _TU_CHECK_MCU(_m) (CFG_TUSB_MCU == _m) diff --git a/tools/get_deps.py b/tools/get_deps.py index 50cc5c893..e05cc4d76 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -24,6 +24,9 @@ deps_optional = { 'hw/mcu/allwinner': ['https://github.com/hathach/allwinner_driver.git', '8e5e89e8e132c0fd90e72d5422e5d3d68232b756', 'fc100s'], + 'hw/mcu/analog/max32' : ['https://github.com/analogdevicesinc/msdk.git', + 'b20b398d3e5e2007594e54a74ba3d2a2e50ddd75', + 'max32690'], 'hw/mcu/bridgetek/ft9xx/ft90x-sdk': ['https://github.com/BRTSG-FOSS/ft90x-sdk.git', '91060164afe239fcb394122e8bf9eb24d3194eb1', 'brtmm90x'], -- cgit v1.3.1 From 0b82af61f3ca7f6b708399c49519fb109ab33abb Mon Sep 17 00:00:00 2001 From: Brent Kowal Date: Mon, 1 Jul 2024 16:31:17 -0400 Subject: AD-APARD32690-SL Support and Cleanup - Added BSP for AD-APARD32690-SL board (apard32690) - Ran clang-formatting on previously committed code - Removed LOG messages from dcd_max32.c --- hw/bsp/max32690/boards/apard32690/board.cmake | 1 + hw/bsp/max32690/boards/apard32690/board.h | 56 +++++ hw/bsp/max32690/boards/apard32690/board.mk | 1 + hw/bsp/max32690/boards/max32690evkit/board.h | 22 +- hw/bsp/max32690/family.c | 32 +-- src/portable/analog/max32/dcd_max32.c | 339 ++++++++++++-------------- 6 files changed, 239 insertions(+), 212 deletions(-) create mode 100644 hw/bsp/max32690/boards/apard32690/board.cmake create mode 100644 hw/bsp/max32690/boards/apard32690/board.h create mode 100644 hw/bsp/max32690/boards/apard32690/board.mk (limited to 'src/portable') diff --git a/hw/bsp/max32690/boards/apard32690/board.cmake b/hw/bsp/max32690/boards/apard32690/board.cmake new file mode 100644 index 000000000..9dc6962eb --- /dev/null +++ b/hw/bsp/max32690/boards/apard32690/board.cmake @@ -0,0 +1 @@ +# Nothing to be done at the board level diff --git a/hw/bsp/max32690/boards/apard32690/board.h b/hw/bsp/max32690/boards/apard32690/board.h new file mode 100644 index 000000000..f94097ca9 --- /dev/null +++ b/hw/bsp/max32690/boards/apard32690/board.h @@ -0,0 +1,56 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024, Brent Kowal (Analog Devices, Inc) + * + * 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. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#include "gpio.h" +#include "mxc_sys.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// LED +#define LED_PORT MXC_GPIO2 +#define LED_PIN MXC_GPIO_PIN_1 +#define LED_VDDIO MXC_GPIO_VSSEL_VDDIOH +#define LED_STATE_ON 1 + +// Button +#define BUTTON_PORT MXC_GPIO1 +#define BUTTON_PIN MXC_GPIO_PIN_27 +#define BUTTON_PULL MXC_GPIO_PAD_NONE +#define BUTTON_STATE_ACTIVE 1 + +// UART Enable for UART on ARM SWD Connector +#define UART_NUM 0 + +#ifdef __cplusplus +} +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/max32690/boards/apard32690/board.mk b/hw/bsp/max32690/boards/apard32690/board.mk new file mode 100644 index 000000000..a813a5327 --- /dev/null +++ b/hw/bsp/max32690/boards/apard32690/board.mk @@ -0,0 +1 @@ +# No specific build requirements for the board. diff --git a/hw/bsp/max32690/boards/max32690evkit/board.h b/hw/bsp/max32690/boards/max32690evkit/board.h index f5a904702..05d60f220 100644 --- a/hw/bsp/max32690/boards/max32690evkit/board.h +++ b/hw/bsp/max32690/boards/max32690evkit/board.h @@ -31,26 +31,26 @@ #include "mxc_sys.h" #ifdef __cplusplus - extern "C" { +extern "C" { #endif // LED -#define LED_PORT MXC_GPIO0 -#define LED_PIN MXC_GPIO_PIN_14 -#define LED_VDDIO MXC_GPIO_VSSEL_VDDIOH -#define LED_STATE_ON 0 +#define LED_PORT MXC_GPIO0 +#define LED_PIN MXC_GPIO_PIN_14 +#define LED_VDDIO MXC_GPIO_VSSEL_VDDIOH +#define LED_STATE_ON 0 // Button -#define BUTTON_PORT MXC_GPIO4 -#define BUTTON_PIN MXC_GPIO_PIN_0 -#define BUTTON_PULL MXC_GPIO_PAD_PULL_UP -#define BUTTON_STATE_ACTIVE 0 +#define BUTTON_PORT MXC_GPIO4 +#define BUTTON_PIN MXC_GPIO_PIN_0 +#define BUTTON_PULL MXC_GPIO_PAD_PULL_UP +#define BUTTON_STATE_ACTIVE 0 // UART Enable for EvKit's Integrated FTDI Adapter. Pin Mux handled by the HAL -#define UART_NUM 2 +#define UART_NUM 2 #ifdef __cplusplus - } +} #endif #endif /* BOARD_H_ */ diff --git a/hw/bsp/max32690/family.c b/hw/bsp/max32690/family.c index f443bc575..acd6e2593 100644 --- a/hw/bsp/max32690/family.c +++ b/hw/bsp/max32690/family.c @@ -24,12 +24,12 @@ * This file is part of the TinyUSB stack. */ -#include "bsp/board_api.h" #include "board.h" -#include "mxc_device.h" +#include "bsp/board_api.h" +#include "gpio.h" #include "mcr_regs.h" +#include "mxc_device.h" #include "uart.h" -#include "gpio.h" //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler @@ -49,7 +49,7 @@ void board_init(void) { SysTick_Config(SystemCoreClock / 1000); #elif CFG_TUSB_OS == OPT_OS_FREERTOS // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) - NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + NVIC_SetPriority(USB_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); #endif mxc_gpio_cfg_t gpioConfig; @@ -87,10 +87,10 @@ void board_init(void) { //--------------------------------------------------------------------+ void board_led_write(bool state) { - #if LED_STATE_ON - state = !state; - #endif - if(state) { +#if LED_STATE_ON + state = !state; +#endif + if (state) { MXC_GPIO_OutClr(LED_PORT, LED_PIN); } else { MXC_GPIO_OutSet(LED_PORT, LED_PIN); @@ -103,9 +103,9 @@ uint32_t board_button_read(void) { } size_t board_get_unique_id(uint8_t id[], size_t max_len) { - uint8_t hw_id[MXC_SYS_USN_CHECKSUM_LEN]; //USN Buffer - /* All other 2nd parameter is optional checkum buffer */ - MXC_SYS_GetUSN(hw_id, NULL); + uint8_t hw_id[MXC_SYS_USN_CHECKSUM_LEN];//USN Buffer + /* All other 2nd parameter is optional checkum buffer */ + MXC_SYS_GetUSN(hw_id, NULL); size_t act_len = TU_MIN(max_len, MXC_SYS_USN_LEN); memcpy(id, hw_id, act_len); @@ -116,11 +116,11 @@ int board_uart_read(uint8_t *buf, int len) { int uart_val; int act_len = 0; - while( act_len < len ) { - if((uart_val = MXC_UART_ReadCharacterRaw(ConsoleUart)) == E_UNDERFLOW) { + while (act_len < len) { + if ((uart_val = MXC_UART_ReadCharacterRaw(ConsoleUart)) == E_UNDERFLOW) { break; } else { - *buf++ = (uint8_t)uart_val; + *buf++ = (uint8_t) uart_val; act_len++; } } @@ -129,8 +129,8 @@ int board_uart_read(uint8_t *buf, int len) { int board_uart_write(void const *buf, int len) { int act_len = 0; - const uint8_t* ch_ptr = (const uint8_t*)buf; - while(act_len < len){ + const uint8_t *ch_ptr = (const uint8_t *) buf; + while (act_len < len) { MXC_UART_WriteCharacter(ConsoleUart, *ch_ptr++); act_len++; } diff --git a/src/portable/analog/max32/dcd_max32.c b/src/portable/analog/max32/dcd_max32.c index 150d476fa..b3370ddd1 100644 --- a/src/portable/analog/max32/dcd_max32.c +++ b/src/portable/analog/max32/dcd_max32.c @@ -29,49 +29,48 @@ #if CFG_TUD_ENABLED && TU_CHECK_MCU(OPT_MCU_MAX32690) -#if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) + #if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) /* GCC warns that an address may be unaligned, even though * the target CPU has the capability for unaligned memory access. */ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); -#endif + #endif -#include "device/dcd.h" + #include "device/dcd.h" -#include "mxc_delay.h" -#include "mxc_device.h" -#include "mxc_sys.h" -#include "nvic_table.h" -#include "usbhs_regs.h" + #include "mxc_delay.h" + #include "mxc_device.h" + #include "mxc_sys.h" + #include "nvic_table.h" + #include "usbhs_regs.h" -#define USBHS_M31_CLOCK_RECOVERY + #define USBHS_M31_CLOCK_RECOVERY -/*------------------------------------------------------------------ + /*------------------------------------------------------------------ * MACRO TYPEDEF CONSTANT ENUM DECLARATION *------------------------------------------------------------------*/ -#define REQUEST_TYPE_INVALID (0xFFu) + #define REQUEST_TYPE_INVALID (0xFFu) typedef union { - uint8_t u8; - uint16_t u16; - uint32_t u32; + uint8_t u8; + uint16_t u16; + uint32_t u32; } hw_fifo_t; -typedef struct TU_ATTR_PACKED -{ - void *buf; /* the start address of a transfer data buffer */ - uint16_t length; /* the number of bytes in the buffer */ - uint16_t remaining; /* the number of bytes remaining in the buffer */ +typedef struct TU_ATTR_PACKED { + void *buf; /* the start address of a transfer data buffer */ + uint16_t length; /* the number of bytes in the buffer */ + uint16_t remaining; /* the number of bytes remaining in the buffer */ } pipe_state_t; typedef struct { tusb_control_request_t setup_packet; - uint16_t remaining_ctrl; /* The number of bytes remaining in data stage of control transfer. */ - int8_t status_out; + uint16_t remaining_ctrl; /* The number of bytes remaining in data stage of control transfer. */ + int8_t status_out; pipe_state_t pipe0; - pipe_state_t pipe[2][TUP_DCD_ENDPOINT_MAX - 1]; /* pipe[direction][endpoint number - 1] */ - uint16_t pipe_buf_is_fifo[2]; /* Bitmap. Each bit means whether 1:TU_FIFO or 0:POD. */ + pipe_state_t pipe[2][TUP_DCD_ENDPOINT_MAX - 1]; /* pipe[direction][endpoint number - 1] */ + uint16_t pipe_buf_is_fifo[2]; /* Bitmap. Each bit means whether 1:TU_FIFO or 0:POD. */ } dcd_data_t; /*------------------------------------------------------------------ @@ -80,63 +79,59 @@ typedef struct static dcd_data_t _dcd; -static volatile void* edpt_get_fifo_ptr(unsigned epnum) -{ - volatile uint32_t *ptr; +static volatile void *edpt_get_fifo_ptr(unsigned epnum) { + volatile uint32_t *ptr; - ptr = &MXC_USBHS->fifo0; - ptr += epnum; /* Pointer math: multiplies ep by sizeof(uint32_t) */ + ptr = &MXC_USBHS->fifo0; + ptr += epnum; /* Pointer math: multiplies ep by sizeof(uint32_t) */ - return (volatile void *)ptr; + return (volatile void *) ptr; } -static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) -{ - volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; - uintptr_t addr = (uintptr_t)buf; +static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) { + volatile hw_fifo_t *reg = (volatile hw_fifo_t *) fifo; + uintptr_t addr = (uintptr_t) buf; while (len >= 4) { - reg->u32 = *(uint32_t const *)addr; + reg->u32 = *(uint32_t const *) addr; addr += 4; - len -= 4; + len -= 4; } if (len >= 2) { - reg->u16 = *(uint16_t const *)addr; + reg->u16 = *(uint16_t const *) addr; addr += 2; - len -= 2; + len -= 2; } if (len) { - reg->u8 = *(uint8_t const *)addr; + reg->u8 = *(uint8_t const *) addr; } } -static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) -{ - volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; - uintptr_t addr = (uintptr_t)buf; +static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) { + volatile hw_fifo_t *reg = (volatile hw_fifo_t *) fifo; + uintptr_t addr = (uintptr_t) buf; while (len >= 4) { - *(uint32_t *)addr = reg->u32; + *(uint32_t *) addr = reg->u32; addr += 4; - len -= 4; + len -= 4; } if (len >= 2) { - *(uint16_t *)addr = reg->u16; + *(uint16_t *) addr = reg->u16; addr += 2; - len -= 2; + len -= 2; } if (len) { - *(uint8_t *)addr = reg->u8; + *(uint8_t *) addr = reg->u8; } } -static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigned len, unsigned dir) -{ +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}, + /* 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}, }; tu_fifo_buffer_info_t info; ops[dir].tu_fifo_get_info(f, &info); @@ -152,19 +147,18 @@ static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigne ops[dir].tu_fifo_advance(f, total_len - rem); } -static void process_setup_packet(uint8_t rhport) -{ - uint32_t *p = (void*)&_dcd.setup_packet; - p[0] = MXC_USBHS->fifo0; - p[1] = MXC_USBHS->fifo0; +static void process_setup_packet(uint8_t rhport) { + uint32_t *p = (void *) &_dcd.setup_packet; + p[0] = MXC_USBHS->fifo0; + p[1] = MXC_USBHS->fifo0; - _dcd.pipe0.buf = NULL; - _dcd.pipe0.length = 0; + _dcd.pipe0.buf = NULL; + _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; - dcd_event_setup_received(rhport, (const uint8_t*)(uintptr_t)&_dcd.setup_packet, true); + dcd_event_setup_received(rhport, (const uint8_t *) (uintptr_t) &_dcd.setup_packet, true); - const unsigned len = _dcd.setup_packet.wLength; - _dcd.remaining_ctrl = len; + const unsigned len = _dcd.setup_packet.wLength; + _dcd.remaining_ctrl = len; const unsigned dir_in = tu_edpt_dir(_dcd.setup_packet.bmRequestType); /* Clear RX FIFO and reverse the transaction direction */ if (len && dir_in) { @@ -173,12 +167,11 @@ static void process_setup_packet(uint8_t rhport) } } -static bool handle_xfer_in(uint_fast8_t ep_addr) -{ +static bool handle_xfer_in(uint_fast8_t ep_addr) { unsigned epnum = tu_edpt_number(ep_addr); unsigned epnum_minus1 = epnum - 1; - pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; - const unsigned rem = pipe->remaining; + pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; + const unsigned rem = pipe->remaining; //This function should not be for ep0 TU_ASSERT(epnum); @@ -191,28 +184,26 @@ static bool handle_xfer_in(uint_fast8_t ep_addr) MXC_USBHS->index = epnum; const unsigned mps = MXC_USBHS->inmaxp; const unsigned len = TU_MIN(mps, rem); - void *buf = pipe->buf; - volatile void* fifo_ptr = edpt_get_fifo_ptr(epnum); - // TU_LOG1(" %p mps %d len %d rem %d\r\n", buf, mps, len, rem); + void *buf = pipe->buf; + volatile void *fifo_ptr = edpt_get_fifo_ptr(epnum); if (len) { if (_dcd.pipe_buf_is_fifo[TUSB_DIR_IN] & TU_BIT(epnum_minus1)) { pipe_read_write_packet_ff(buf, fifo_ptr, len, TUSB_DIR_IN); } else { - pipe_write_packet(buf,fifo_ptr, len); - pipe->buf = buf + len; + pipe_write_packet(buf, fifo_ptr, len); + pipe->buf = buf + len; } pipe->remaining = rem - len; } - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_INPKTRDY; //TODO: Verify a | isnt needed + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_INPKTRDY;//TODO: Verify a | isnt needed return false; } -static bool handle_xfer_out(uint_fast8_t ep_addr) -{ +static bool handle_xfer_out(uint_fast8_t ep_addr) { unsigned epnum = tu_edpt_number(ep_addr); unsigned epnum_minus1 = epnum - 1; - pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; + pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; //This function should not be for ep0 TU_ASSERT(epnum); @@ -225,14 +216,14 @@ static bool handle_xfer_out(uint_fast8_t ep_addr) const unsigned rem = pipe->remaining; const unsigned vld = MXC_USBHS->outcount; const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); - void *buf = pipe->buf; - volatile void* fifo_ptr = edpt_get_fifo_ptr(epnum); + void *buf = pipe->buf; + volatile void *fifo_ptr = edpt_get_fifo_ptr(epnum); if (len) { if (_dcd.pipe_buf_is_fifo[TUSB_DIR_OUT] & TU_BIT(epnum_minus1)) { - pipe_read_write_packet_ff(buf,fifo_ptr, len, TUSB_DIR_OUT); + pipe_read_write_packet_ff(buf, fifo_ptr, len, TUSB_DIR_OUT); } else { pipe_read_packet(buf, fifo_ptr, len); - pipe->buf = buf + len; + pipe->buf = buf + len; } pipe->remaining = rem - len; } @@ -240,37 +231,35 @@ static bool handle_xfer_out(uint_fast8_t ep_addr) pipe->buf = NULL; return NULL != buf; } - MXC_USBHS->outcsrl = 0; /* Clear RXRDY bit */ //TODO: Verify just setting to 0 is ok + MXC_USBHS->outcsrl = 0; /* Clear RXRDY bit *///TODO: Verify just setting to 0 is ok return false; } -static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) -{ - (void)rhport; +static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { + (void) rhport; - unsigned epnum = tu_edpt_number(ep_addr); + unsigned epnum = tu_edpt_number(ep_addr); unsigned epnum_minus1 = epnum - 1; - unsigned dir_in = tu_edpt_dir(ep_addr); + unsigned dir_in = tu_edpt_dir(ep_addr); pipe_state_t *pipe = &_dcd.pipe[dir_in][epnum_minus1]; - pipe->buf = buffer; - pipe->length = total_bytes; - pipe->remaining = total_bytes; + pipe->buf = buffer; + pipe->length = total_bytes; + pipe->remaining = total_bytes; if (dir_in) { handle_xfer_in(ep_addr); } else { MXC_USBHS->index = epnum; - if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY){ - MXC_USBHS->outcsrl = 0; //TODO: Verify just setting to 0 is ok + if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { + MXC_USBHS->outcsrl = 0;//TODO: Verify just setting to 0 is ok } } return true; } -static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) -{ - (void)rhport; +static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { + (void) rhport; TU_ASSERT(total_bytes <= 64); /* Current implementation supports for only up to 64 bytes. */ const unsigned req = _dcd.setup_packet.bmRequestType; @@ -299,15 +288,15 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ TU_ASSERT(total_bytes <= _dcd.remaining_ctrl); const unsigned rem = _dcd.remaining_ctrl; const unsigned len = TU_MIN(TU_MIN(rem, 64), total_bytes); - volatile void* fifo_ptr = edpt_get_fifo_ptr(0); + volatile void *fifo_ptr = edpt_get_fifo_ptr(0); if (dir_in) { pipe_write_packet(buffer, fifo_ptr, len); - _dcd.pipe0.buf = buffer + len; - _dcd.pipe0.length = len; + _dcd.pipe0.buf = buffer + len; + _dcd.pipe0.length = len; _dcd.pipe0.remaining = 0; - _dcd.remaining_ctrl = rem - len; + _dcd.remaining_ctrl = rem - len; if ((len < 64) || (rem == len)) { _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; /* Change to STATUS/SETUP stage */ _dcd.status_out = 1; @@ -317,14 +306,14 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_INPKTRDY; /* Flush TX FIFO to return ACK. */ } } else { - _dcd.pipe0.buf = buffer; - _dcd.pipe0.length = len; + _dcd.pipe0.buf = buffer; + _dcd.pipe0.length = len; _dcd.pipe0.remaining = len; MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_OUTPKTRDY; /* Clear RX FIFO to return ACK. */ } } else if (dir_in) { _dcd.pipe0.buf = NULL; - _dcd.pipe0.length = 0; + _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; /* Clear RX FIFO and reverse the transaction direction */ MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_OUTPKTRDY | MXC_F_USBHS_CSR0_DATA_END; @@ -332,8 +321,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ return true; } -static void process_ep0(uint8_t rhport) -{ +static void process_ep0(uint8_t rhport) { MXC_USBHS->index = 0; uint_fast8_t csrl = MXC_USBHS->csr0; @@ -364,7 +352,7 @@ static void process_ep0(uint8_t rhport) /* Received SETUP or DATA OUT packet */ if (req == REQUEST_TYPE_INVALID) { /* SETUP */ - TU_ASSERT(sizeof(tusb_control_request_t) == MXC_USBHS->count0,); + TU_ASSERT(sizeof(tusb_control_request_t) == MXC_USBHS->count0, ); process_setup_packet(rhport); return; } @@ -373,7 +361,7 @@ static void process_ep0(uint8_t rhport) const unsigned vld = MXC_USBHS->count0; const unsigned rem = _dcd.pipe0.remaining; const unsigned len = TU_MIN(TU_MIN(rem, 64), vld); - volatile void* fifo_ptr = edpt_get_fifo_ptr(0); + volatile void *fifo_ptr = edpt_get_fifo_ptr(0); pipe_read_packet(_dcd.pipe0.buf, fifo_ptr, len); _dcd.pipe0.remaining = rem - len; @@ -392,9 +380,9 @@ static void process_ep0(uint8_t rhport) * or receiving a zero length packet. */ if (req != REQUEST_TYPE_INVALID && !tu_edpt_dir(req)) { /* STATUS IN */ - if (*(const uint16_t*)(uintptr_t)&_dcd.setup_packet == 0x0500) { + if (*(const uint16_t *) (uintptr_t) &_dcd.setup_packet == 0x0500) { /* The address must be changed on completion of the control transfer. */ - MXC_USBHS->faddr = (uint8_t)_dcd.setup_packet.wValue; + MXC_USBHS->faddr = (uint8_t) _dcd.setup_packet.wValue; } _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; dcd_event_xfer_complete(rhport, @@ -413,11 +401,10 @@ static void process_ep0(uint8_t rhport) } } -static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) -{ +static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) { bool completed; - const unsigned dir_in = tu_edpt_dir(ep_addr); - const unsigned epnum = tu_edpt_number(ep_addr); + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned epnum = tu_edpt_number(ep_addr); MXC_USBHS->index = epnum; @@ -443,10 +430,8 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) } } -static void process_bus_reset(uint8_t rhport) -{ - (void)rhport; - TU_LOG0("------Bus Reset\r\n"); +static void process_bus_reset(uint8_t rhport) { + (void) rhport; /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), * a control transfer state is SETUP or STATUS stage. */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; @@ -462,14 +447,14 @@ static void process_bus_reset(uint8_t rhport) for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { MXC_USBHS->index = i; if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_INPKTRDY) { - /* Per musbhsfc_pg, only flush FIFO if IN packet loaded */ - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_FLUSHFIFO; - } + /* Per musbhsfc_pg, only flush FIFO if IN packet loaded */ + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_FLUSHFIFO; + } - if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { - /* Per musbhsfc_pg, only flush FIFO if OUT packet is ready */ - MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_FLUSHFIFO; - } + if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { + /* Per musbhsfc_pg, only flush FIFO if OUT packet is ready */ + MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_FLUSHFIFO; + } } dcd_event_bus_reset(0, (MXC_USBHS->power & MXC_F_USBHS_POWER_HS_MODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); } @@ -478,9 +463,8 @@ static void process_bus_reset(uint8_t rhport) * Device API *------------------------------------------------------------------*/ -void dcd_init(uint8_t rhport) -{ - (void)rhport; +void dcd_init(uint8_t rhport) { + (void) rhport; MXC_USBHS->intrusben |= MXC_F_USBHS_INTRUSBEN_SUSPEND_INT_EN; //Interrupt for VBUS disconnect @@ -495,17 +479,17 @@ void dcd_init(uint8_t rhport) /* Configure PHY */ MXC_USBHS->m31_phy_xcfgi_31_0 = (0x1 << 3) | (0x1 << 11); MXC_USBHS->m31_phy_xcfgi_63_32 = 0; - MXC_USBHS->m31_phy_xcfgi_95_64 = 0x1 << (72-64); + MXC_USBHS->m31_phy_xcfgi_95_64 = 0x1 << (72 - 64); MXC_USBHS->m31_phy_xcfgi_127_96 = 0; -#ifdef USBHS_M31_CLOCK_RECOVERY + #ifdef USBHS_M31_CLOCK_RECOVERY MXC_USBHS->m31_phy_noncry_rstb = 1; MXC_USBHS->m31_phy_noncry_en = 1; MXC_USBHS->m31_phy_outclksel = 0; MXC_USBHS->m31_phy_coreclkin = 0; MXC_USBHS->m31_phy_xtlsel = 2; /* Select 25 MHz clock */ -#else + #else /* Use this option to feed the PHY a 30 MHz clock, which is them used as a PLL reference */ /* As it depends on the system core clock, this should probably be done at the SYS level */ MXC_USBHS->m31_phy_noncry_rstb = 0; @@ -513,7 +497,7 @@ void dcd_init(uint8_t rhport) MXC_USBHS->m31_phy_outclksel = 1; MXC_USBHS->m31_phy_coreclkin = 1; MXC_USBHS->m31_phy_xtlsel = 3; /* Select 30 MHz clock */ -#endif + #endif MXC_USBHS->m31_phy_pll_en = 1; MXC_USBHS->m31_phy_oscouten = 1; @@ -524,25 +508,22 @@ void dcd_init(uint8_t rhport) dcd_connect(rhport); } -void dcd_int_enable(uint8_t rhport) -{ - (void)rhport; +void dcd_int_enable(uint8_t rhport) { + (void) rhport; NVIC_EnableIRQ(USB_IRQn); } -void dcd_int_disable(uint8_t rhport) -{ - (void)rhport; +void dcd_int_disable(uint8_t rhport) { + (void) rhport; NVIC_DisableIRQ(USB_IRQn); } // Receive Set Address request, mcu port must also include status IN response -void dcd_set_address(uint8_t rhport, uint8_t dev_addr) -{ - (void)rhport; - (void)dev_addr; - _dcd.pipe0.buf = NULL; - _dcd.pipe0.length = 0; +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { + (void) rhport; + (void) dev_addr; + _dcd.pipe0.buf = NULL; + _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; /* Clear RX FIFO to return ACK. */ MXC_USBHS->index = 0; @@ -550,37 +531,33 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) } // Wake up host -void dcd_remote_wakeup(uint8_t rhport) -{ - (void)rhport; +void dcd_remote_wakeup(uint8_t rhport) { + (void) rhport; MXC_USBHS->power |= MXC_F_USBHS_POWER_RESUME; -#if CFG_TUSB_OS != OPT_OS_NONE + #if CFG_TUSB_OS != OPT_OS_NONE osal_task_delay(10); -#else + #else MXC_Delay(MXC_DELAY_MSEC(10)); -#endif + #endif MXC_USBHS->power &= ~MXC_F_USBHS_POWER_RESUME; } // Connect by enabling internal pull-up resistor on D+/D- -void dcd_connect(uint8_t rhport) -{ - (void)rhport; +void dcd_connect(uint8_t rhport) { + (void) rhport; MXC_USBHS->power |= TUD_OPT_HIGH_SPEED ? MXC_F_USBHS_POWER_HS_ENABLE : 0; MXC_USBHS->power |= MXC_F_USBHS_POWER_SOFTCONN; } // Disconnect by disabling internal pull-up resistor on D+/D- -void dcd_disconnect(uint8_t rhport) -{ - (void)rhport; +void dcd_disconnect(uint8_t rhport) { + (void) rhport; MXC_USBHS->power &= ~MXC_F_USBHS_POWER_SOFTCONN; } -void dcd_sof_enable(uint8_t rhport, bool en) -{ +void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; @@ -592,21 +569,20 @@ void dcd_sof_enable(uint8_t rhport, bool en) //--------------------------------------------------------------------+ // Configure endpoint's registers according to descriptor -bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) -{ +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) { (void) rhport; const unsigned ep_addr = ep_desc->bEndpointAddress; - const unsigned epn = tu_edpt_number(ep_addr); - const unsigned dir_in = tu_edpt_dir(ep_addr); - const unsigned xfer = ep_desc->bmAttributes.xfer; - const unsigned mps = tu_edpt_packet_size(ep_desc); + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned xfer = ep_desc->bmAttributes.xfer; + const unsigned mps = tu_edpt_packet_size(ep_desc); TU_ASSERT(epn < TUP_DCD_ENDPOINT_MAX); pipe_state_t *pipe = &_dcd.pipe[dir_in][epn - 1]; - pipe->buf = NULL; - pipe->length = 0; + pipe->buf = NULL; + pipe->length = 0; pipe->remaining = 0; MXC_USBHS->index = epn; @@ -634,8 +610,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) return true; } -void dcd_edpt_close_all(uint8_t rhport) -{ +void dcd_edpt_close_all(uint8_t rhport) { (void) rhport; MXC_SYS_Crit_Enter(); @@ -665,10 +640,9 @@ void dcd_edpt_close_all(uint8_t rhport) MXC_SYS_Crit_Exit(); } -void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) -{ - (void)rhport; - unsigned const epn = tu_edpt_number(ep_addr); +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; + unsigned const epn = tu_edpt_number(ep_addr); unsigned const dir_in = tu_edpt_dir(ep_addr); MXC_SYS_Crit_Enter(); @@ -683,7 +657,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG; } } else { - MXC_USBHS->introuten &= ~TU_BIT(epn); + MXC_USBHS->introuten &= ~TU_BIT(epn); MXC_USBHS->outmaxp = 0; MXC_USBHS->outcsru = MXC_F_USBHS_OUTCSRU_DPKTBUFDIS; if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { @@ -696,9 +670,8 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) } // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack -bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) -{ - (void)rhport; +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { + (void) rhport; bool ret; unsigned const epnum = tu_edpt_number(ep_addr); MXC_SYS_Crit_Enter(); @@ -712,23 +685,21 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t } // Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c -bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) -{ - (void)rhport; +bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes) { + (void) rhport; bool ret; unsigned const epnum = tu_edpt_number(ep_addr); TU_ASSERT(epnum); MXC_SYS_Crit_Enter(); _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] |= TU_BIT(epnum - 1); - ret = edpt_n_xfer(rhport, ep_addr, (uint8_t*)ff, total_bytes); + ret = edpt_n_xfer(rhport, ep_addr, (uint8_t *) ff, total_bytes); MXC_SYS_Crit_Exit(); return ret; } // Stall endpoint -void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) -{ - (void)rhport; +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; unsigned const epn = tu_edpt_number(ep_addr); MXC_SYS_Crit_Enter(); MXC_USBHS->index = epn; @@ -742,7 +713,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) if (tu_edpt_dir(ep_addr)) { /* IN */ MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_SENDSTALL; } else { /* OUT */ - TU_ASSERT(!(MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY),); + TU_ASSERT(!(MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY), ); MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_SENDSTALL; } } @@ -750,9 +721,8 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) } // clear stall, data toggle is also reset to DATA0 -void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) -{ - (void)rhport; +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; unsigned const epn = tu_edpt_number(ep_addr); MXC_SYS_Crit_Enter(); MXC_USBHS->index = epn; @@ -779,8 +749,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) /*------------------------------------------------------------------- * ISR *-------------------------------------------------------------------*/ -void dcd_int_handler(uint8_t rhport) -{ +void dcd_int_handler(uint8_t rhport) { uint_fast8_t is, txis, rxis; uint32_t mxm_int, mxm_int_en, mxm_is; uint32_t saved_index; @@ -788,7 +757,7 @@ void dcd_int_handler(uint8_t rhport) /* Save current index register */ saved_index = MXC_USBHS->index; - is = MXC_USBHS->intrusb; /* read and clear interrupt status */ + is = MXC_USBHS->intrusb; /* read and clear interrupt status */ txis = MXC_USBHS->intrin; /* read and clear interrupt status */ rxis = MXC_USBHS->introut; /* read and clear interrupt status */ -- cgit v1.3.1 From 2353c4ffbaa50072d89008df7a06a7732c824018 Mon Sep 17 00:00:00 2001 From: Brent Kowal Date: Mon, 1 Jul 2024 17:31:38 -0400 Subject: Add MAX78002 Support -Added support for MAX78002, MAX78002EVKIT -Added provisions for remaining MAX32 USB parts --- examples/device/cdc_msc/src/usb_descriptors.c | 3 +- .../device/cdc_msc_freertos/src/usb_descriptors.c | 3 +- examples/device/cdc_uac2/src/usb_descriptors.c | 3 +- .../dynamic_configuration/src/usb_descriptors.c | 3 +- examples/device/midi_test/src/usb_descriptors.c | 3 +- examples/device/msc_dual_lun/src/usb_descriptors.c | 3 +- .../device/net_lwip_webserver/src/tusb_config.h | 2 +- .../net_lwip_webserver/src/usb_descriptors.c | 3 +- examples/device/uac2_headset/src/usb_descriptors.c | 3 +- .../device/webusb_serial/src/usb_descriptors.c | 3 +- hw/bsp/board_mcu.h | 9 ++ hw/bsp/max78002/FreeRTOSConfig/FreeRTOSConfig.h | 149 +++++++++++++++++ hw/bsp/max78002/boards/max78002evkit/board.cmake | 1 + hw/bsp/max78002/boards/max78002evkit/board.h | 58 +++++++ hw/bsp/max78002/boards/max78002evkit/board.mk | 1 + hw/bsp/max78002/family.c | 158 ++++++++++++++++++ hw/bsp/max78002/family.cmake | 152 +++++++++++++++++ hw/bsp/max78002/family.mk | 104 ++++++++++++ hw/bsp/max78002/max78002.ld | 180 +++++++++++++++++++++ src/common/tusb_mcu.h | 3 +- src/portable/analog/max32/dcd_max32.c | 3 +- src/tusb_option.h | 3 + tools/get_deps.py | 2 +- 23 files changed, 839 insertions(+), 13 deletions(-) create mode 100644 hw/bsp/max78002/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/max78002/boards/max78002evkit/board.cmake create mode 100644 hw/bsp/max78002/boards/max78002evkit/board.h create mode 100644 hw/bsp/max78002/boards/max78002evkit/board.mk create mode 100644 hw/bsp/max78002/family.c create mode 100644 hw/bsp/max78002/family.cmake create mode 100644 hw/bsp/max78002/family.mk create mode 100644 hw/bsp/max78002/max78002.ld (limited to 'src/portable') diff --git a/examples/device/cdc_msc/src/usb_descriptors.c b/examples/device/cdc_msc/src/usb_descriptors.c index 1ca614f4e..fac7cce8f 100644 --- a/examples/device/cdc_msc/src/usb_descriptors.c +++ b/examples/device/cdc_msc/src/usb_descriptors.c @@ -125,7 +125,8 @@ enum { #define EPNUM_MSC_OUT 0x04 #define EPNUM_MSC_IN 0x85 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ + CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 // MAX32 doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_NOTIF 0x81 diff --git a/examples/device/cdc_msc_freertos/src/usb_descriptors.c b/examples/device/cdc_msc_freertos/src/usb_descriptors.c index f563e80d3..917b73e10 100644 --- a/examples/device/cdc_msc_freertos/src/usb_descriptors.c +++ b/examples/device/cdc_msc_freertos/src/usb_descriptors.c @@ -106,7 +106,8 @@ enum #define EPNUM_MSC_OUT 0x04 #define EPNUM_MSC_IN 0x85 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ + CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 // MAX32 doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_NOTIF 0x81 diff --git a/examples/device/cdc_uac2/src/usb_descriptors.c b/examples/device/cdc_uac2/src/usb_descriptors.c index 43e8cf3d7..ab1a2ee83 100644 --- a/examples/device/cdc_uac2/src/usb_descriptors.c +++ b/examples/device/cdc_uac2/src/usb_descriptors.c @@ -117,7 +117,8 @@ uint8_t const * tud_descriptor_device_cb(void) #define EPNUM_CDC_OUT 0x04 #define EPNUM_CDC_IN 0x85 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ + CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 // MAX32 doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_AUDIO_IN 0x01 diff --git a/examples/device/dynamic_configuration/src/usb_descriptors.c b/examples/device/dynamic_configuration/src/usb_descriptors.c index eebdd4f69..20f237155 100644 --- a/examples/device/dynamic_configuration/src/usb_descriptors.c +++ b/examples/device/dynamic_configuration/src/usb_descriptors.c @@ -158,7 +158,8 @@ enum #define EPNUM_1_MSC_OUT 0x01 #define EPNUM_1_MSC_IN 0x82 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ + CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 // FT9XX doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_0_CDC_NOTIF 0x81 diff --git a/examples/device/midi_test/src/usb_descriptors.c b/examples/device/midi_test/src/usb_descriptors.c index 797b50ab2..41e6e1818 100644 --- a/examples/device/midi_test/src/usb_descriptors.c +++ b/examples/device/midi_test/src/usb_descriptors.c @@ -90,7 +90,8 @@ enum // On Bridgetek FT9xx endpoint numbers must be unique... #define EPNUM_MIDI_OUT 0x02 #define EPNUM_MIDI_IN 0x03 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ + CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 // On MAX32 endpoint numbers must be unique... #define EPNUM_MIDI_OUT 0x02 #define EPNUM_MIDI_IN 0x03 diff --git a/examples/device/msc_dual_lun/src/usb_descriptors.c b/examples/device/msc_dual_lun/src/usb_descriptors.c index e32466228..c55bab0d8 100644 --- a/examples/device/msc_dual_lun/src/usb_descriptors.c +++ b/examples/device/msc_dual_lun/src/usb_descriptors.c @@ -97,7 +97,8 @@ enum #define EPNUM_MSC_OUT 0x01 #define EPNUM_MSC_IN 0x82 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ + CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 // MAX32 doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_MSC_OUT 0x01 diff --git a/examples/device/net_lwip_webserver/src/tusb_config.h b/examples/device/net_lwip_webserver/src/tusb_config.h index 2f641f33e..22082fc81 100644 --- a/examples/device/net_lwip_webserver/src/tusb_config.h +++ b/examples/device/net_lwip_webserver/src/tusb_config.h @@ -91,7 +91,7 @@ extern "C" { #define USE_ECM 1 #elif TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32F1) #define USE_ECM 1 -#elif TU_CHECK_MCU(OPT_MCU_MAX32690) +#elif TU_CHECK_MCU(OPT_MCU_MAX32690, OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX78002) #define USE_ECM 1 #else #define USE_ECM 0 diff --git a/examples/device/net_lwip_webserver/src/usb_descriptors.c b/examples/device/net_lwip_webserver/src/usb_descriptors.c index ba30b869e..012e1bcd8 100644 --- a/examples/device/net_lwip_webserver/src/usb_descriptors.c +++ b/examples/device/net_lwip_webserver/src/usb_descriptors.c @@ -120,7 +120,8 @@ uint8_t const * tud_descriptor_device_cb(void) #define EPNUM_NET_OUT 0x02 #define EPNUM_NET_IN 0x83 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ + CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 // MAX32 doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_NET_NOTIF 0x81 diff --git a/examples/device/uac2_headset/src/usb_descriptors.c b/examples/device/uac2_headset/src/usb_descriptors.c index bfc8a4ab5..a042ad206 100644 --- a/examples/device/uac2_headset/src/usb_descriptors.c +++ b/examples/device/uac2_headset/src/usb_descriptors.c @@ -104,7 +104,8 @@ uint8_t const * tud_descriptor_device_cb(void) #define EPNUM_AUDIO_OUT 0x02 #define EPNUM_AUDIO_INT 0x03 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ + CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 // MAX32 doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_AUDIO_IN 0x01 diff --git a/examples/device/webusb_serial/src/usb_descriptors.c b/examples/device/webusb_serial/src/usb_descriptors.c index bcfbe590e..ae1051af6 100644 --- a/examples/device/webusb_serial/src/usb_descriptors.c +++ b/examples/device/webusb_serial/src/usb_descriptors.c @@ -105,7 +105,8 @@ enum #define EPNUM_CDC_OUT 3 #define EPNUM_VENDOR_IN 4 #define EPNUM_VENDOR_OUT 5 -#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ + CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 // MAX32 doesn't support a same endpoint number with different direction IN and OUT // e.g EP1 OUT & EP1 IN cannot exist together #define EPNUM_CDC_IN 2 diff --git a/hw/bsp/board_mcu.h b/hw/bsp/board_mcu.h index 436164c35..d3a33cf36 100644 --- a/hw/bsp/board_mcu.h +++ b/hw/bsp/board_mcu.h @@ -173,6 +173,15 @@ #elif CFG_TUSB_MCU == OPT_MCU_MAX32690 #include "max32690.h" +#elif CFG_TUSB_MCU == OPT_MCU_MAX32650 + #include "max32650.h" + +#elif CFG_TUSB_MCU == OPT_MCU_MAX32666 + #include "max32665.h" + +#elif CFG_TUSB_MCU == OPT_MCU_MAX78002 + #include "max78002.h" + #else #error "Missing MCU header" #endif diff --git a/hw/bsp/max78002/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/max78002/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..e5a76af85 --- /dev/null +++ b/hw/bsp/max78002/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,149 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "mxc_device.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS __NVIC_PRIO_BITS + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<vssel |= UART_VDDIO_BITS; //Set necessary bits to 3.3V + + //USB + MXC_MCR->ldoctrl |= MXC_F_MCR_LDOCTRL_0P9EN; + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_USB); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) { +#if LED_STATE_ON + state = !state; +#endif + if (state) { + MXC_GPIO_OutClr(LED_PORT, LED_PIN); + } else { + MXC_GPIO_OutSet(LED_PORT, LED_PIN); + } +} + +uint32_t board_button_read(void) { + uint32_t state = MXC_GPIO_InGet(BUTTON_PORT, BUTTON_PIN) ? 1 : 0; + return BUTTON_STATE_ACTIVE == state; +} + +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + uint8_t hw_id[MXC_SYS_USN_CHECKSUM_LEN];//USN Buffer + /* All other 2nd parameter is optional checkum buffer */ + MXC_SYS_GetUSN(hw_id, NULL); + + size_t act_len = TU_MIN(max_len, MXC_SYS_USN_LEN); + memcpy(id, hw_id, act_len); + return act_len; +} + +int board_uart_read(uint8_t *buf, int len) { + int uart_val; + int act_len = 0; + + while (act_len < len) { + if ((uart_val = MXC_UART_ReadCharacterRaw(ConsoleUart)) == E_UNDERFLOW) { + break; + } else { + *buf++ = (uint8_t) uart_val; + act_len++; + } + } + return act_len; +} + +int board_uart_write(void const *buf, int len) { + int act_len = 0; + const uint8_t *ch_ptr = (const uint8_t *) buf; + while (act_len < len) { + MXC_UART_WriteCharacter(ConsoleUart, *ch_ptr++); + act_len++; + } + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +void SysTick_Handler(void) { + system_ticks++; +} + +uint32_t board_millis(void) { + return system_ticks; +} +#endif + +void HardFault_Handler(void) { + __asm("BKPT #0\n"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) { +} diff --git a/hw/bsp/max78002/family.cmake b/hw/bsp/max78002/family.cmake new file mode 100644 index 000000000..43b172b9f --- /dev/null +++ b/hw/bsp/max78002/family.cmake @@ -0,0 +1,152 @@ +include_guard() + +set(MAX32_PERIPH ${TOP}/hw/mcu/analog/max32/Libraries/PeriphDrivers) +set(MAX32_CMSIS ${TOP}/hw/mcu/analog/max32/Libraries/CMSIS) +set(CMSIS_5 ${TOP}/lib/CMSIS_5) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# Get the linker file from current location (family) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/max78002.ld) +set(LD_FILE_Clang ${LD_FILE_GNU}) + +# toolchain set up +set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) +set(JLINK_DEVICE max78000) + +set(FAMILY_MCUS MAX78002 CACHE INTERNAL "") + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + TARGET=MAX78002 + TARGET_REV=0x4131 + MXC_ASSERT_ENABLE + MAX78002 + IAR_PRAGMAS=0 + CFG_TUSB_MCU=OPT_MCU_MAX78002 + BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + ) +endfunction() + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +# only need to be built ONCE for all examples +function(add_board_target BOARD_TARGET) + if (TARGET ${BOARD_TARGET}) + return() + endif () + + # Startup & Linker script + set(STARTUP_FILE_GNU ${MAX32_CMSIS}/Device/Maxim/MAX78002/Source/GCC/startup_max78002.S) + set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + #set(STARTUP_FILE_IAR ?) + + set(PERIPH_SRC ${MAX32_PERIPH}/Source) + add_library(${BOARD_TARGET} STATIC + ${MAX32_CMSIS}/Device/Maxim/MAX78002/Source/heap.c + ${MAX32_CMSIS}/Device/Maxim/MAX78002/Source/system_max78002.c + ${PERIPH_SRC}/SYS/mxc_assert.c + ${PERIPH_SRC}/SYS/mxc_delay.c + ${PERIPH_SRC}/SYS/mxc_lock.c + ${PERIPH_SRC}/SYS/nvic_table.c + ${PERIPH_SRC}/SYS/pins_ai87.c + ${PERIPH_SRC}/SYS/sys_ai87.c + ${PERIPH_SRC}/AES/aes_ai87.c + ${PERIPH_SRC}/AES/aes_revb.c + ${PERIPH_SRC}/FLC/flc_common.c + ${PERIPH_SRC}/FLC/flc_ai87.c + ${PERIPH_SRC}/FLC/flc_reva.c + ${PERIPH_SRC}/GPIO/gpio_common.c + ${PERIPH_SRC}/GPIO/gpio_ai87.c + ${PERIPH_SRC}/GPIO/gpio_reva.c + ${PERIPH_SRC}/ICC/icc_ai87.c + ${PERIPH_SRC}/ICC/icc_reva.c + ${PERIPH_SRC}/TRNG/trng_ai87.c + ${PERIPH_SRC}/TRNG/trng_revb.c + ${PERIPH_SRC}/UART/uart_common.c + ${PERIPH_SRC}/UART/uart_ai87.c + ${PERIPH_SRC}/UART/uart_revb.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_5}/CMSIS/Core/Include + ${MAX32_CMSIS}/Include + ${MAX32_CMSIS}/Device/Maxim/MAX78002/Include + ${MAX32_PERIPH}/Include/MAX78002 + ${PERIPH_SRC}/SYS + ${PERIPH_SRC}/GPIO + ${PERIPH_SRC}/AES + ${PERIPH_SRC}/TRNG + ${PERIPH_SRC}/ICC + ${PERIPH_SRC}/FLC + ${PERIPH_SRC}/UART + ) + + target_compile_options(${TARGET} PRIVATE + -Wno-error=strict-prototypes + -Wno-error=redundant-decls + ) + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${BOARD_TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () +endfunction() + + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + + # Board target + add_board_target(board_${BOARD}) + + #---------- Port Specific ---------- + # These files are built for each example since it depends on example's tusb_config.h + target_sources(${TARGET} PUBLIC + # BSP + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ) + target_include_directories(${TARGET} PUBLIC + # family, hw, board + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + # Add TinyUSB target and port source + family_add_tinyusb(${TARGET} OPT_MCU_MAX78002 ${RTOS}) + target_sources(${TARGET}-tinyusb PUBLIC + ${TOP}/src/portable/analog/max32/dcd_max32.c + ) + target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) + target_compile_options(${TARGET}-tinyusb PRIVATE + -Wno-error=strict-prototypes + -Wno-error=redundant-decls + ) + + # Link dependencies + target_link_libraries(${TARGET} PUBLIC board_${BOARD} ${TARGET}-tinyusb) + + # Flashing + family_flash_jlink(${TARGET}) +endfunction() diff --git a/hw/bsp/max78002/family.mk b/hw/bsp/max78002/family.mk new file mode 100644 index 000000000..825920596 --- /dev/null +++ b/hw/bsp/max78002/family.mk @@ -0,0 +1,104 @@ +DEPS_SUBMODULES += lib/CMSIS_5 hw/mcu/analog/max32 + +# Important locations in the hw support for MCU +MAX32_CMSIS = hw/mcu/analog/max32/Libraries/CMSIS +MAX32_PERIPH = hw/mcu/analog/max32/Libraries/PeriphDrivers + +# Add any board specific make rules +include $(TOP)/$(BOARD_PATH)/board.mk + +CPU_CORE ?= cortex-m4 +PORT ?= 0 + +# GCC +SRC_S_GCC += $(MAX32_CMSIS)/Device/Maxim/MAX78002/Source/GCC/startup_max78002.S +LD_FILE = $(FAMILY_PATH)/max78002.ld + +# IAR +#SRC_S_IAR += + +# -------------- +# Compiler Flags +# -------------- +# Flags for the MAX78002 SDK +CFLAGS += -DTARGET=MAX78002 \ + -DTARGET_REV=0x4131 \ + -DMXC_ASSERT_ENABLE \ + -DMAX78002 \ + -DIAR_PRAGMAS=0 + +# Flags for TUSB features +CFLAGS += \ + -DCFG_TUSB_MCU=OPT_MCU_MAX78002 \ + -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + +# mcu driver cause following warnings +CFLAGS += -Wno-error=redundant-decls \ + -Wno-error=strict-prototypes \ + -Wno-error=unused-parameter \ + -Wno-error=enum-conversion \ + -Wno-error=sign-compare \ + -Wno-error=cast-qual + +LDFLAGS_GCC += -nostartfiles --specs=nosys.specs --specs=nano.specs + +# For flash-jlink target +JLINK_DEVICE = max78000 + +# flash target using Jlik +flash: flash-jlink + +# Optional flash option when running within an installed MSDK to use OpenOCD +# Mainline OpenOCD does not yet have the MAX32's flash algorithm integrated. +# If the MSDK is installed, flash-msdk can be run to utilize the the modified +# openocd with the algorithms +MAXIM_PATH := $(subst \,/,$(MAXIM_PATH)) +flash-msdk: + $(MAXIM_PATH)/Tools/OpenOCD/openocd -s $(MAXIM_PATH)/Tools/OpenOCD/scripts \ + -f interface/cmsis-dap.cfg -f target/max78002.cfg \ + -c "program $(BUILD)/$(PROJECT).elf verify; init; reset; exit" + +# ----------------- +# Sources & Include +# ----------------- +PERIPH_SRC = $(TOP)/$(MAX32_PERIPH)/Source +SRC_C += \ + src/portable/analog/max32/dcd_max32.c \ + $(MAX32_CMSIS)/Device/Maxim/MAX78002/Source/heap.c \ + $(MAX32_CMSIS)/Device/Maxim/MAX78002/Source/system_max78002.c \ + $(PERIPH_SRC)/SYS/mxc_assert.c \ + $(PERIPH_SRC)/SYS/mxc_delay.c \ + $(PERIPH_SRC)/SYS/mxc_lock.c \ + $(PERIPH_SRC)/SYS/nvic_table.c \ + $(PERIPH_SRC)/SYS/pins_ai87.c \ + $(PERIPH_SRC)/SYS/sys_ai87.c \ + $(PERIPH_SRC)/AES/aes_ai87.c \ + $(PERIPH_SRC)/AES/aes_revb.c \ + $(PERIPH_SRC)/FLC/flc_common.c \ + $(PERIPH_SRC)/FLC/flc_ai87.c \ + $(PERIPH_SRC)/FLC/flc_reva.c \ + $(PERIPH_SRC)/GPIO/gpio_common.c \ + $(PERIPH_SRC)/GPIO/gpio_ai87.c \ + $(PERIPH_SRC)/GPIO/gpio_reva.c \ + $(PERIPH_SRC)/ICC/icc_ai87.c \ + $(PERIPH_SRC)/ICC/icc_reva.c \ + $(PERIPH_SRC)/TRNG/trng_ai87.c \ + $(PERIPH_SRC)/TRNG/trng_revb.c \ + $(PERIPH_SRC)/UART/uart_common.c \ + $(PERIPH_SRC)/UART/uart_ai87.c \ + $(PERIPH_SRC)/UART/uart_revb.c \ + + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(MAX32_CMSIS)/Include \ + $(TOP)/$(MAX32_CMSIS)/Device/Maxim/MAX78002/Include \ + $(TOP)/$(MAX32_PERIPH)/Include/MAX78002 \ + $(PERIPH_SRC)/SYS \ + $(PERIPH_SRC)/GPIO \ + $(PERIPH_SRC)/AES \ + $(PERIPH_SRC)/ICC \ + $(PERIPH_SRC)/FLC \ + $(PERIPH_SRC)/TRNG \ + $(PERIPH_SRC)/UART diff --git a/hw/bsp/max78002/max78002.ld b/hw/bsp/max78002/max78002.ld new file mode 100644 index 000000000..5f9ed9356 --- /dev/null +++ b/hw/bsp/max78002/max78002.ld @@ -0,0 +1,180 @@ +MEMORY { + ROM (rx) : ORIGIN = 0x00000000, LENGTH = 0x00010000 /* 64 kB ROM */ + FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 0x00280000 /* 2.5 MB Flash */ + SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00060000 /* 384 kB SRAM */ + /*CSI2 (rwx) : ORIGIN = 0x2001F000, LENGTH = 0x00001000 4096 B CSI2 Buffer */ +} + +SECTIONS { + .rom : + { + KEEP(*(.rom_vector)) + *(.rom_handlers*) + } > ROM + + .text : + { + _text = .; + KEEP(*(.isr_vector)) + EXCLUDE_FILE (*riscv.o) *(.text*) /* Program code (exclude RISCV code) */ + *(.rodata*) /* read-only data: "const" */ + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + /* C++ Exception handling */ + KEEP(*(.eh_frame*)) + _etext = .; + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + /* Binary import */ + .bin_storage : + { + FILL(0xFF) + _bin_start_ = .; + KEEP(*(.bin_storage_img)) + _bin_end_ = .; + . = ALIGN(4); + } > FLASH + + .rom_code : + { + . = ALIGN(16); + _sran_code = .; + *(.rom_code_section) + _esran_code = .; + } > ROM + + .flash_code : + { + . = ALIGN(16); + _sran_code = .; + *(.flash_code_section) + _esran_code = .; + } > FLASH + + .sram_code : + { + . = ALIGN(16); + _sran_code = .; + *(.sram_code_section) + _esran_code = .; + } > SRAM + + /* it's used for C++ exception handling */ + /* we need to keep this to avoid overlapping */ + .ARM.exidx : + { + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } > FLASH + + .data : + { + _data = ALIGN(., 4); + _csi = . + 0x20000; + *(vtable) + *(.data*) /*read-write initialized data: initialized global variable*/ + + + /* These array sections are used by __libc_init_array to call static C++ constructors */ + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + _edata = ALIGN(., 4); + + } > SRAM AT>FLASH + __load_data = LOADADDR(.data); + + .bss : + { + . = ALIGN(4); + _bss = .; + *(.bss*) /*read-write zero initialized data: uninitialzed global variable*/ + *(COMMON) + _ebss = ALIGN(., 4); + } > SRAM + + .shared : + { + . = ALIGN(4); + _shared = .; + *(.mailbox*) + . = ALIGN(4); + *(.shared*) /*read-write zero initialized data: uninitialzed global variable*/ + _eshared = ALIGN(., 4); + } > SRAM + __shared_data = LOADADDR(.shared); + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(SRAM) + LENGTH(SRAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > SRAM + + .heap (COPY): + { + . = ALIGN(4); + *(.heap*) + __HeapLimit = ABSOLUTE(__StackLimit); + } > SRAM + + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack") + + /* Section used by RISCV loader projects. See RISCV_LOAD documentation in the build system. */ + .riscv_flash : + { + /* Align address to mod 256 with a small offset. This is required to match the flash page size.*/ + . = ALIGN(256); /* ALIGN operatator is used here. Note that (. & 0x1FFFFF00) was used in the past, but a strange bug was seen on Windows where the & did not behave as expected.*/ + . += 0x100; + _riscv_boot = .; + KEEP(*riscv.o (.text*)) + } > FLASH +} diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index a68e160bd..07cdf3ff0 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -455,7 +455,8 @@ //--------------------------------------------------------------------+ // Analog Devices //--------------------------------------------------------------------+ -#elif TU_CHECK_MCU(OPT_MCU_MAX32690) +#elif TU_CHECK_MCU(OPT_MCU_MAX32690, OPT_MCU_MAX32666, \ + OPT_MCU_MAX32650, OPT_MCU_MAX78002) #define TUP_DCD_ENDPOINT_MAX 12 #define TUP_RHPORT_HIGHSPEED 1 diff --git a/src/portable/analog/max32/dcd_max32.c b/src/portable/analog/max32/dcd_max32.c index b3370ddd1..7226003de 100644 --- a/src/portable/analog/max32/dcd_max32.c +++ b/src/portable/analog/max32/dcd_max32.c @@ -27,7 +27,8 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && TU_CHECK_MCU(OPT_MCU_MAX32690) +#if CFG_TUD_ENABLED && \ + TU_CHECK_MCU(OPT_MCU_MAX32690, OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX78002) #if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) /* GCC warns that an address may be unaligned, even though diff --git a/src/tusb_option.h b/src/tusb_option.h index 18f78b49c..1290d605c 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -190,6 +190,9 @@ // Analog Devices #define OPT_MCU_MAX32690 2400 ///< ADI MAX32690 +#define OPT_MCU_MAX32666 2401 ///< ADI MAX32666/5 +#define OPT_MCU_MAX32650 2402 ///< ADI MAX32650/1/2 +#define OPT_MCU_MAX78002 2403 ///< ADI MAX78002 // Check if configured MCU is one of listed // Apply _TU_CHECK_MCU with || as separator to list of input diff --git a/tools/get_deps.py b/tools/get_deps.py index e05cc4d76..fe548f4ab 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -26,7 +26,7 @@ deps_optional = { 'fc100s'], 'hw/mcu/analog/max32' : ['https://github.com/analogdevicesinc/msdk.git', 'b20b398d3e5e2007594e54a74ba3d2a2e50ddd75', - 'max32690'], + 'max32690 max32650 max32666 max78002'], 'hw/mcu/bridgetek/ft9xx/ft90x-sdk': ['https://github.com/BRTSG-FOSS/ft90x-sdk.git', '91060164afe239fcb394122e8bf9eb24d3194eb1', 'brtmm90x'], -- cgit v1.3.1 From 13f5f20c981cc54baa8438e275524db03fb79e94 Mon Sep 17 00:00:00 2001 From: Brent Kowal Date: Thu, 11 Jul 2024 12:13:30 -0400 Subject: Pre-commit fixes. Resolve codespell and EOF errors found in the pre-commit CI task. --- hw/bsp/max32650/README.md | 2 +- hw/bsp/max32650/boards/max32650evkit/max32650.ld | 2 +- hw/bsp/max32650/boards/max32650fthr/max32650.ld | 2 +- hw/bsp/max32650/boards/max32651evkit/max32651.ld | 2 +- hw/bsp/max32650/family.mk | 2 +- hw/bsp/max32666/family.c | 2 +- hw/bsp/max32666/max32666.ld | 2 +- hw/bsp/max32690/family.c | 2 +- hw/bsp/max32690/max32690.ld | 2 +- hw/bsp/max78002/family.c | 2 +- hw/bsp/max78002/max78002.ld | 4 ++-- src/portable/analog/max32/dcd_max32.c | 2 +- 12 files changed, 13 insertions(+), 13 deletions(-) (limited to 'src/portable') diff --git a/hw/bsp/max32650/README.md b/hw/bsp/max32650/README.md index cb8069bba..ca66a1ac4 100644 --- a/hw/bsp/max32650/README.md +++ b/hw/bsp/max32650/README.md @@ -43,4 +43,4 @@ MAX32651EVKIT. To flash the signed image, the MSDK's OpenOCD variant must be used. To flash the MAX32651EVKIT please install the bundled MSDK, and utilize the `flash-msdk` -and `-msdk` rule and target. \ No newline at end of file +and `-msdk` rule and target. diff --git a/hw/bsp/max32650/boards/max32650evkit/max32650.ld b/hw/bsp/max32650/boards/max32650evkit/max32650.ld index 3a1e5100d..0e56a91ec 100644 --- a/hw/bsp/max32650/boards/max32650evkit/max32650.ld +++ b/hw/bsp/max32650/boards/max32650evkit/max32650.ld @@ -85,7 +85,7 @@ SECTIONS { { . = ALIGN(4); _bss = .; - *(.bss*) /*read-write zero initialized data: uninitialzed global variable*/ + *(.bss*) /*read-write zero initialized data: uninitialized global variable*/ *(COMMON) _ebss = ALIGN(., 4); } > SRAM diff --git a/hw/bsp/max32650/boards/max32650fthr/max32650.ld b/hw/bsp/max32650/boards/max32650fthr/max32650.ld index 3a1e5100d..0e56a91ec 100644 --- a/hw/bsp/max32650/boards/max32650fthr/max32650.ld +++ b/hw/bsp/max32650/boards/max32650fthr/max32650.ld @@ -85,7 +85,7 @@ SECTIONS { { . = ALIGN(4); _bss = .; - *(.bss*) /*read-write zero initialized data: uninitialzed global variable*/ + *(.bss*) /*read-write zero initialized data: uninitialized global variable*/ *(COMMON) _ebss = ALIGN(., 4); } > SRAM diff --git a/hw/bsp/max32650/boards/max32651evkit/max32651.ld b/hw/bsp/max32650/boards/max32651evkit/max32651.ld index a873463d4..3921d10f2 100644 --- a/hw/bsp/max32650/boards/max32651evkit/max32651.ld +++ b/hw/bsp/max32650/boards/max32651evkit/max32651.ld @@ -98,7 +98,7 @@ SECTIONS { { . = ALIGN(4); _bss = .; - *(.bss*) /*read-write zero initialized data: uninitialzed global variable*/ + *(.bss*) /*read-write zero initialized data: uninitialized global variable*/ *(COMMON) _ebss = ALIGN(., 4); } > SRAM diff --git a/hw/bsp/max32650/family.mk b/hw/bsp/max32650/family.mk index 577d96717..0718523c3 100644 --- a/hw/bsp/max32650/family.mk +++ b/hw/bsp/max32650/family.mk @@ -121,7 +121,7 @@ SIGN_EXE := sign_app.exe endif endif -# Rule to sign the build. This will in-place modifiy the existing .elf file +# Rule to sign the build. This will in-place modify the existing .elf file # an populate the .sig section with the signature value sign-build: $(BUILD)/$(PROJECT).elf $(OBJCOPY) $(BUILD)/$(PROJECT).elf -R .sig -O binary $(BUILD)/$(PROJECT).bin diff --git a/hw/bsp/max32666/family.c b/hw/bsp/max32666/family.c index 98e1248d7..1398e09ff 100644 --- a/hw/bsp/max32666/family.c +++ b/hw/bsp/max32666/family.c @@ -106,7 +106,7 @@ uint32_t board_button_read(void) { size_t board_get_unique_id(uint8_t id[], size_t max_len) { uint8_t hw_id[MXC_SYS_USN_CHECKSUM_LEN];//USN Buffer - /* All other 2nd parameter is optional checkum buffer */ + /* All other 2nd parameter is optional checksum buffer */ MXC_SYS_GetUSN(hw_id, NULL); size_t act_len = TU_MIN(max_len, MXC_SYS_USN_LEN); diff --git a/hw/bsp/max32666/max32666.ld b/hw/bsp/max32666/max32666.ld index dcf61a3d0..06c124247 100644 --- a/hw/bsp/max32666/max32666.ld +++ b/hw/bsp/max32666/max32666.ld @@ -101,7 +101,7 @@ SECTIONS { { . = ALIGN(4); _bss = .; - *(.bss*) /*read-write zero initialized data: uninitialzed global variable*/ + *(.bss*) /*read-write zero initialized data: uninitialized global variable*/ *(COMMON) _ebss = ALIGN(., 4); } > SRAM diff --git a/hw/bsp/max32690/family.c b/hw/bsp/max32690/family.c index acd6e2593..f4998bdbe 100644 --- a/hw/bsp/max32690/family.c +++ b/hw/bsp/max32690/family.c @@ -104,7 +104,7 @@ uint32_t board_button_read(void) { size_t board_get_unique_id(uint8_t id[], size_t max_len) { uint8_t hw_id[MXC_SYS_USN_CHECKSUM_LEN];//USN Buffer - /* All other 2nd parameter is optional checkum buffer */ + /* All other 2nd parameter is optional checksum buffer */ MXC_SYS_GetUSN(hw_id, NULL); size_t act_len = TU_MIN(max_len, MXC_SYS_USN_LEN); diff --git a/hw/bsp/max32690/max32690.ld b/hw/bsp/max32690/max32690.ld index 3d857b4e8..64b906a54 100644 --- a/hw/bsp/max32690/max32690.ld +++ b/hw/bsp/max32690/max32690.ld @@ -130,7 +130,7 @@ SECTIONS { { . = ALIGN(4); _bss = .; - *(.bss*) /*read-write zero initialized data: uninitialzed global variable*/ + *(.bss*) /*read-write zero initialized data: uninitialized global variable*/ *(COMMON) _ebss = ALIGN(., 4); } > SRAM diff --git a/hw/bsp/max78002/family.c b/hw/bsp/max78002/family.c index c105f056b..7758083a2 100644 --- a/hw/bsp/max78002/family.c +++ b/hw/bsp/max78002/family.c @@ -103,7 +103,7 @@ uint32_t board_button_read(void) { size_t board_get_unique_id(uint8_t id[], size_t max_len) { uint8_t hw_id[MXC_SYS_USN_CHECKSUM_LEN];//USN Buffer - /* All other 2nd parameter is optional checkum buffer */ + /* All other 2nd parameter is optional checksum buffer */ MXC_SYS_GetUSN(hw_id, NULL); size_t act_len = TU_MIN(max_len, MXC_SYS_USN_LEN); diff --git a/hw/bsp/max78002/max78002.ld b/hw/bsp/max78002/max78002.ld index 60f99e28f..e5c4866ee 100644 --- a/hw/bsp/max78002/max78002.ld +++ b/hw/bsp/max78002/max78002.ld @@ -127,7 +127,7 @@ SECTIONS { { . = ALIGN(4); _bss = .; - *(.bss*) /*read-write zero initialized data: uninitialzed global variable*/ + *(.bss*) /*read-write zero initialized data: uninitialized global variable*/ *(COMMON) _ebss = ALIGN(., 4); } > SRAM @@ -138,7 +138,7 @@ SECTIONS { _shared = .; *(.mailbox*) . = ALIGN(4); - *(.shared*) /*read-write zero initialized data: uninitialzed global variable*/ + *(.shared*) /*read-write zero initialized data: uninitialized global variable*/ _eshared = ALIGN(., 4); } > SRAM __shared_data = LOADADDR(.shared); diff --git a/src/portable/analog/max32/dcd_max32.c b/src/portable/analog/max32/dcd_max32.c index 7226003de..df616120a 100644 --- a/src/portable/analog/max32/dcd_max32.c +++ b/src/portable/analog/max32/dcd_max32.c @@ -196,7 +196,7 @@ static bool handle_xfer_in(uint_fast8_t ep_addr) { } pipe->remaining = rem - len; } - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_INPKTRDY;//TODO: Verify a | isnt needed + MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_INPKTRDY;//TODO: Verify a | isn't needed return false; } -- cgit v1.3.1 From 4ce1cce40a01dce56cab2c73745f4f2c9d212b25 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 12 Jul 2024 20:17:14 +0700 Subject: simplify dwc2 test mode - all dwc2 ip seems to support test mode in both fs/hs -> remove TUP_USBIP_DWC2_TEST_MODE - remove dcd_check_test_mode_support(), all should be supported - move enum tusb_feature_test_mode_t to tusb_types.h --- src/common/tusb_mcu.h | 3 -- src/common/tusb_types.h | 9 ++++++ src/device/dcd.h | 13 +------- src/device/usbd.c | 56 +++++++++++------------------------ src/portable/synopsys/dwc2/dcd_dwc2.c | 20 +++---------- src/tusb_option.h | 2 +- 6 files changed, 32 insertions(+), 71 deletions(-) (limited to 'src/portable') diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 80826c895..637281bfc 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -195,7 +195,6 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32F4) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 - #define TUP_USBIP_DWC2_TEST_MODE // For most mcu, FS has 4, HS has 6. TODO 446/469/479 HS has 9 #define TUP_DCD_ENDPOINT_MAX 6 @@ -210,7 +209,6 @@ // MCU with on-chip HS Phy #if defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F733xx) #define TUP_RHPORT_HIGHSPEED 1 // Port0: FS, Port1: HS - #define TUP_USBIP_DWC2_TEST_MODE #endif #elif TU_CHECK_MCU(OPT_MCU_STM32H7) @@ -285,7 +283,6 @@ defined(STM32U5F7xx) || defined(STM32U5F9xx) || defined(STM32U5G7xx) || defined(STM32U5G9xx) #define TUP_DCD_ENDPOINT_MAX 9 #define TUP_RHPORT_HIGHSPEED 1 - #define TUP_USBIP_DWC2_TEST_MODE #else #define TUP_DCD_ENDPOINT_MAX 6 #endif diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index b571f9b72..1501a5af6 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -214,6 +214,15 @@ enum { #define TUSB_DESC_CONFIG_POWER_MA(x) ((x)/2) +// USB 2.0 Spec Table 9-7: Test Mode Selectors +typedef enum { + TUSB_FEATURE_TEST_J = 1, + TUSB_FEATURE_TEST_K, + TUSB_FEATURE_TEST_SE0_NAK, + TUSB_FEATURE_TEST_PACKET, + TUSB_FEATURE_TEST_FORCE_ENABLE, +} tusb_feature_test_mode_t; + //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ diff --git a/src/device/dcd.h b/src/device/dcd.h index f6735b077..5356e9be1 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -89,14 +89,6 @@ typedef struct TU_ATTR_ALIGNED(4) { }; } dcd_event_t; -typedef enum { - TEST_J = 1, - TEST_K, - TEST_SE0_NAK, - TEST_PACKET, - TEST_FORCE_ENABLE, -} test_mode_t; - //TU_VERIFY_STATIC(sizeof(dcd_event_t) <= 12, "size is not correct"); //--------------------------------------------------------------------+ @@ -150,11 +142,8 @@ void dcd_disconnect(uint8_t rhport); void dcd_sof_enable(uint8_t rhport, bool en); #if CFG_TUD_TEST_MODE -// Check if the test mode is supported, returns true is test mode selector is supported -bool dcd_check_test_mode_support(test_mode_t test_selector) TU_ATTR_WEAK; - // Put device into a test mode (needs power cycle to quit) -void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) TU_ATTR_WEAK; +void dcd_enter_test_mode(uint8_t rhport, tusb_feature_test_mode_t test_selector); #endif //--------------------------------------------------------------------+ // Endpoint API diff --git a/src/device/usbd.c b/src/device/usbd.c index 800d9c824..4105a71a4 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -321,9 +321,17 @@ TU_ATTR_ALWAYS_INLINE static inline bool queue_event(dcd_event_t const * event, static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request); static bool process_set_config(uint8_t rhport, uint8_t cfg_num); static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const * p_request); + #if CFG_TUD_TEST_MODE -static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request); +static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) { + TU_VERIFY(CONTROL_STAGE_ACK == stage); + uint8_t const selector = tu_u16_high(request->wIndex); + TU_LOG_USBD(" Enter Test Mode (test selector index: %d)\r\n", selector); + dcd_enter_test_mode(rhport, (tusb_feature_test_mode_t) selector); + return true; +} #endif + // from usbd_control.c void usbd_control_reset(void); void usbd_control_set_request(tusb_control_request_t const *request); @@ -695,7 +703,7 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const } if ( TUSB_REQ_TYPE_STANDARD != p_request->bmRequestType_bit.type ) { - // Non standard request is not supported + // Non-standard request is not supported TU_BREAKPOINT(); return false; } @@ -759,43 +767,27 @@ static bool process_control_request(uint8_t rhport, tusb_control_request_t const break; case TUSB_REQ_SET_FEATURE: - // Handle the feature selector - switch(p_request->wValue) - { - // Support for remote wakeup + switch(p_request->wValue) { case TUSB_REQ_FEATURE_REMOTE_WAKEUP: 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; tud_control_status(rhport, p_request); break; -#if CFG_TUD_TEST_MODE - // Support for TEST_MODE + #if CFG_TUD_TEST_MODE case TUSB_REQ_FEATURE_TEST_MODE: { // Only handle the test mode if supported and valid - TU_VERIFY(dcd_enter_test_mode && dcd_check_test_mode_support && 0 == tu_u16_low(p_request->wIndex)); - - uint8_t selector = tu_u16_high(p_request->wIndex); - - // Stall request if the selected test mode isn't supported - if (!dcd_check_test_mode_support((test_mode_t)selector)) - { - TU_LOG_USBD(" Unsupported Test Mode (test selector index: %d)\r\n", selector); + TU_VERIFY(0 == tu_u16_low(p_request->wIndex)); - return false; - } - - // Acknowledge request - tud_control_status(rhport, p_request); - - TU_LOG_USBD(" Enter Test Mode (test selector index: %d)\r\n", selector); + uint8_t const selector = tu_u16_high(p_request->wIndex); + TU_VERIFY(TUSB_FEATURE_TEST_J <= selector && selector <= TUSB_FEATURE_TEST_FORCE_ENABLE); usbd_control_set_complete_callback(process_test_mode_cb); + tud_control_status(rhport, p_request); break; } -#endif /* CFG_TUD_TEST_MODE */ + #endif /* CFG_TUD_TEST_MODE */ // Stall unsupported feature selector default: return false; @@ -1127,20 +1119,6 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const } } -#if CFG_TUD_TEST_MODE -static bool process_test_mode_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) -{ - // At this point it should already be ensured that dcd_enter_test_mode() is defined - - // Only enter the test mode after the request for it has completed - TU_VERIFY(CONTROL_STAGE_ACK == stage); - - dcd_enter_test_mode(rhport, (test_mode_t)tu_u16_high(request->wIndex)); - - return true; -} -#endif /* CFG_TUD_TEST_MODE */ - //--------------------------------------------------------------------+ // DCD Event Handler //--------------------------------------------------------------------+ diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index dbcd586c5..9a38b46dc 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1195,25 +1195,13 @@ void dcd_int_handler(uint8_t rhport) { // } } -#if defined(TUP_USBIP_DWC2_TEST_MODE) && CFG_TUD_TEST_MODE - -bool dcd_check_test_mode_support(test_mode_t test_selector) { - // Check if test mode selector is unsupported - if (TEST_FORCE_ENABLE < test_selector || TEST_J > test_selector) { - return false; - } - - return true; -} - -void dcd_enter_test_mode(uint8_t rhport, test_mode_t test_selector) { - // Get port address... +#if CFG_TUD_TEST_MODE +void dcd_enter_test_mode(uint8_t rhport, tusb_feature_test_mode_t test_selector) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); // Enable the test mode - dwc2->dctl = (dwc2->dctl & ~DCTL_TCTL_Msk) | (test_selector << DCTL_TCTL_Pos); + dwc2->dctl = (dwc2->dctl & ~DCTL_TCTL_Msk) | (((uint8_t) test_selector) << DCTL_TCTL_Pos); } - -#endif /* TUP_USBIP_DWC2_TEST_MODE && CFG_TUD_TEST_MODE */ +#endif #endif diff --git a/src/tusb_option.h b/src/tusb_option.h index 8990cf92b..f2cc284dc 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -381,7 +381,7 @@ #error "CFG_TUD_ENDPPOINT_MAX must be less than or equal to TUP_DCD_ENDPOINT_MAX" #endif -// USB 2.0 compliance test mode support +// USB 2.0 7.1.20: compliance test mode support #ifndef CFG_TUD_TEST_MODE #define CFG_TUD_TEST_MODE 0 #endif -- cgit v1.3.1 From 770efd9b46db0f8723beebe4bfa4d6694bac2901 Mon Sep 17 00:00:00 2001 From: Liam Fraser Date: Wed, 17 Jul 2024 13:03:09 +0100 Subject: RP2040: Use our own unaligned memcpy to avoid alignment faults with some memcpy implementations --- src/portable/raspberrypi/rp2040/rp2040_usb.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/portable') diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index 1ca711c77..c5d1ba3ce 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -53,6 +53,14 @@ TU_ATTR_ALWAYS_INLINE static inline bool is_host_mode(void) { //--------------------------------------------------------------------+ // Implementation //--------------------------------------------------------------------+ +// Provide own byte by byte memcpy as not all copies are aligned +static void unaligned_memcpy(void *dst, const void *src, size_t n) { + uint8_t *dst_byte = (uint8_t*)dst; + const uint8_t *src_byte = (const uint8_t*)src; + while (n--) { + *dst_byte++ = *src_byte++; + } +} void rp2040_usb_init(void) { // Reset usb controller @@ -125,7 +133,7 @@ static uint32_t __tusb_irq_path_func(prepare_ep_buffer)(struct hw_endpoint* ep, if (!ep->rx) { // Copy data from user buffer to hw buffer - memcpy(ep->hw_data_buf + buf_id * 64, ep->user_buf, buflen); + unaligned_memcpy(ep->hw_data_buf + buf_id * 64, ep->user_buf, buflen); ep->user_buf += buflen; // Mark as full @@ -230,7 +238,7 @@ static uint16_t __tusb_irq_path_func(sync_ep_buffer)(struct hw_endpoint* ep, uin // we have received AFTER we have copied it to the user buffer at the appropriate offset assert(buf_ctrl & USB_BUF_CTRL_FULL); - memcpy(ep->user_buf, ep->hw_data_buf + buf_id * 64, xferred_bytes); + unaligned_memcpy(ep->user_buf, ep->hw_data_buf + buf_id * 64, xferred_bytes); ep->xferred_len = (uint16_t) (ep->xferred_len + xferred_bytes); ep->user_buf += xferred_bytes; } -- cgit v1.3.1 From 3804ab9a67737732fe6bcc8e0b016ea00d47ff12 Mon Sep 17 00:00:00 2001 From: Liam Fraser Date: Wed, 17 Jul 2024 15:40:34 +0100 Subject: RP2040: no need to clear usb_hw (usb registers) as they are reset to default state by a hardware reset --- src/portable/raspberrypi/rp2040/rp2040_usb.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/portable') diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index c5d1ba3ce..43f48da39 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -75,7 +75,6 @@ void rp2040_usb_init(void) { #pragma GCC diagnostic ignored "-Wstringop-overflow" #endif #endif - memset(usb_hw, 0, sizeof(*usb_hw)); memset(usb_dpram, 0, sizeof(*usb_dpram)); #ifdef __GNUC__ #pragma GCC diagnostic pop -- cgit v1.3.1 From 4de46fcf975d57983192874feea9d94427f5de50 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Jul 2024 16:01:39 +0700 Subject: fix a bug in fsdev introduced by #1942 --- hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake | 1 - hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake | 1 - hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake | 1 - hw/bsp/ch32v20x/family.cmake | 6 ++++++ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 2 +- 5 files changed, 7 insertions(+), 4 deletions(-) (limited to 'src/portable') diff --git a/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake b/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake index adb0ea741..4aae6bdc2 100644 --- a/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake +++ b/hw/bsp/ch32v20x/boards/ch32v203c_r0_1v0/board.cmake @@ -10,7 +10,6 @@ set(LD_RAM_SIZE 20K) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC SYSCLK_FREQ_144MHz_HSE=144000000 - CH32_FLASH_ENHANCE_READ_MODE=1 CFG_EXAMPLE_MSC_DUAL_READONLY ) endfunction() diff --git a/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake b/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake index 6fe3e05b2..ecb8b378f 100644 --- a/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake +++ b/hw/bsp/ch32v20x/boards/ch32v203g_r0_1v0/board.cmake @@ -8,7 +8,6 @@ set(LD_RAM_SIZE 10K) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC SYSCLK_FREQ_144MHz_HSI=144000000 - CH32_FLASH_ENHANCE_READ_MODE=1 CFG_EXAMPLE_MSC_DUAL_READONLY ) endfunction() diff --git a/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake b/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake index ed7365797..a0bf12b5c 100644 --- a/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake +++ b/hw/bsp/ch32v20x/boards/nanoch32v203/board.cmake @@ -8,7 +8,6 @@ set(LD_RAM_SIZE 20K) function(update_board TARGET) target_compile_definitions(${TARGET} PUBLIC SYSCLK_FREQ_144MHz_HSE=144000000 - CH32_FLASH_ENHANCE_READ_MODE=1 CFG_EXAMPLE_MSC_DUAL_READONLY ) endfunction() diff --git a/hw/bsp/ch32v20x/family.cmake b/hw/bsp/ch32v20x/family.cmake index bf929b862..380ef190d 100644 --- a/hw/bsp/ch32v20x/family.cmake +++ b/hw/bsp/ch32v20x/family.cmake @@ -72,6 +72,12 @@ function(add_board_target BOARD_TARGET) update_board(${BOARD_TARGET}) + if (LD_FLASH_SIZE STREQUAL 224K) + target_compile_definitions(${BOARD_TARGET} PUBLIC + CH32_FLASH_ENHANCE_READ_MODE=1 + ) + endif() + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") target_compile_options(${BOARD_TARGET} PUBLIC -mcmodel=medany diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 8bfb899ca..39f33bc34 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -1004,7 +1004,7 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui srcVal++; } - if (wNBytes) { + if (wNBytes & 0x01) { temp1 = (uint16_t) *srcVal; *pdwVal = temp1; } -- cgit v1.3.1 From c0f38ebf8d483da02a9074eaf021e1660a55fd75 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 23 Jul 2024 19:53:41 +0700 Subject: fsdev read/write packet use unaligned function --- hw/bsp/ch32v20x/family.c | 11 +++ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 108 +++++++++++--------------- src/portable/st/stm32_fsdev/fsdev_common.h | 13 +++- 3 files changed, 64 insertions(+), 68 deletions(-) (limited to 'src/portable') diff --git a/hw/bsp/ch32v20x/family.c b/hw/bsp/ch32v20x/family.c index 542d4b5db..43dd7e032 100644 --- a/hw/bsp/ch32v20x/family.c +++ b/hw/bsp/ch32v20x/family.c @@ -173,6 +173,17 @@ uint32_t board_button_read(void) { return false; } +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + (void) max_len; + volatile uint32_t* ch32_uuid = ((volatile uint32_t*) 0x1FFFF7E8UL); + uint32_t* serial_32 = (uint32_t*) (uintptr_t) id; + serial_32[0] = ch32_uuid[0]; + serial_32[1] = ch32_uuid[1]; + serial_32[2] = ch32_uuid[2]; + + return 12; +} + int board_uart_read(uint8_t *buf, int len) { (void) buf; (void) len; diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 39f33bc34..8c2b10691 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -426,6 +426,8 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) dcd_read_packet_memory(userMemBuf, pcd_get_ep_rx_address(USB, EPindex), 8); dcd_event_setup_received(0, (uint8_t *)userMemBuf, true); #endif + } else { + TU_BREAKPOINT(); } } else { // Clear RX CTR interrupt flag @@ -941,27 +943,26 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) } #ifdef FSDEV_BUS_32BIT -static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes) -{ - const uint8_t *srcVal = src; +static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes) { + const uint8_t *src8 = src; volatile uint32_t *dst32 = (volatile uint32_t *)(USB_PMAADDR + dst); for (uint32_t n = wNBytes / 4; n > 0; --n) { - *dst32++ = tu_unaligned_read32(srcVal); - srcVal += 4; + *dst32++ = tu_unaligned_read32(src8); + src8 += 4; } - wNBytes = wNBytes & 0x03; - if (wNBytes) { - uint32_t wrVal = *srcVal; - wNBytes--; + uint16_t odd = wNBytes & 0x03; + if (odd) { + uint32_t wrVal = *src8; + odd--; - if (wNBytes) { - wrVal |= *++srcVal << 8; - wNBytes--; + if (odd) { + wrVal |= *++src8 << 8; + odd--; - if (wNBytes) { - wrVal |= *++srcVal << 16; + if (odd) { + wrVal |= *++src8 << 16; } } @@ -974,39 +975,26 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui // Packet buffer access can only be 8- or 16-bit. /** * @brief Copy a buffer from user memory area to packet memory area (PMA). - * This uses byte-access for user memory (so support non-aligned buffers) - * and 16-bit access for packet memory. + * This uses un-aligned for user memory and 16-bit access for packet memory. * @param dst, byte address in PMA; must be 16-bit aligned * @param src pointer to user memory area. * @param wPMABufAddr address into PMA. * @param wNBytes no. of bytes to be copied. * @retval None */ -static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes) -{ +static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes) { uint32_t n = (uint32_t)wNBytes >> 1U; - uint16_t temp1, temp2; - const uint8_t *srcVal; - - // The GCC optimizer will combine access to 32-bit sizes if we let it. Force - // it volatile so that it won't do that. - __IO uint16_t *pdwVal; - - srcVal = src; - pdwVal = &pma[FSDEV_PMA_STRIDE * (dst >> 1)]; + const uint8_t *src8 = src; + volatile uint16_t *pdw16 = &pma[FSDEV_PMA_STRIDE * (dst >> 1)]; while (n--) { - temp1 = (uint16_t)*srcVal; - srcVal++; - temp2 = temp1 | ((uint16_t)(((uint16_t)(*srcVal)) << 8U)); - *pdwVal = temp2; - pdwVal += FSDEV_PMA_STRIDE; - srcVal++; + *pdw16 = tu_unaligned_read16(src8); + src8 += 2; + pdw16 += FSDEV_PMA_STRIDE; } if (wNBytes & 0x01) { - temp1 = (uint16_t) *srcVal; - *pdwVal = temp1; + *pdw16 = (uint16_t) *src8; } return true; @@ -1091,27 +1079,27 @@ static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNB #ifdef FSDEV_BUS_32BIT static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes) { - uint8_t *dstVal = dst; + uint8_t *dst8 = dst; volatile uint32_t *src32 = (volatile uint32_t *)(USB_PMAADDR + src); for (uint32_t n = wNBytes / 4; n > 0; --n) { - tu_unaligned_write32(dstVal, *src32++); - dstVal += 4; + tu_unaligned_write32(dst8, *src32++); + dst8 += 4; } - wNBytes = wNBytes & 0x03; - if (wNBytes) { + uint16_t odd = wNBytes & 0x03; + if (odd) { uint32_t rdVal = *src32; - *dstVal = tu_u32_byte0(rdVal); - wNBytes--; + *dst8 = tu_u32_byte0(rdVal); + odd--; - if (wNBytes) { - *++dstVal = tu_u32_byte1(rdVal); - wNBytes--; + if (odd) { + *++dst8 = tu_u32_byte1(rdVal); + odd--; - if (wNBytes) { - *++dstVal = tu_u32_byte2(rdVal); + if (odd) { + *++dst8 = tu_u32_byte2(rdVal); } } } @@ -1121,33 +1109,25 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t #else /** * @brief Copy a buffer from packet memory area (PMA) to user memory area. - * Uses byte-access of system memory and 16-bit access of packet memory + * Uses unaligned for system memory and 16-bit access of packet memory * @param wNBytes no. of bytes to be copied. * @retval None */ -static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes) -{ +static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes) { uint32_t n = (uint32_t)wNBytes >> 1U; - // The GCC optimizer will combine access to 32-bit sizes if we let it. Force - // it volatile so that it won't do that. - __IO const uint16_t *pdwVal; - uint32_t temp; - - pdwVal = &pma[FSDEV_PMA_STRIDE * (src >> 1)]; - uint8_t *dstVal = (uint8_t *)dst; + volatile const uint16_t *pdw16 = &pma[FSDEV_PMA_STRIDE * (src >> 1)]; + uint8_t *dst8 = (uint8_t *)dst; while (n--) { - temp = *pdwVal; - pdwVal += FSDEV_PMA_STRIDE; - *dstVal++ = ((temp >> 0) & 0xFF); - *dstVal++ = ((temp >> 8) & 0xFF); + tu_unaligned_write16(dst8, *pdw16); + dst8 += 2; + pdw16 += FSDEV_PMA_STRIDE; } if (wNBytes & 0x01) { - temp = *pdwVal; - pdwVal += FSDEV_PMA_STRIDE; - *dstVal++ = ((temp >> 0) & 0xFF); + *dst8++ = tu_u16_low(*pdw16); } + return true; } #endif diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index e8a6af8cb..920c17a04 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -35,14 +35,19 @@ #include "stdint.h" // FSDEV_PMA_SIZE is PMA buffer size in bytes. -// On 512-byte devices, access with a stride of two words (use every other 16-bit address) -// On 1024-byte devices, access with a stride of one word (use every 16-bit address) +// - 512-byte devices, access with a stride of two words (use every other 16-bit address) +// - 1024-byte devices, access with a stride of one word (use every 16-bit address) +// - 2048-byte devices, access with 32-bit address // For purposes of accessing the packet -#if ((FSDEV_PMA_SIZE) == 512u) +#if FSDEV_PMA_SIZE == 512 #define FSDEV_PMA_STRIDE (2u) -#elif ((FSDEV_PMA_SIZE) == 1024u) +#elif FSDEV_PMA_SIZE == 1024 #define FSDEV_PMA_STRIDE (1u) +#elif FSDEV_PMA_SIZE == 2048 + #ifndef FSDEV_BUS_32BIT + #warning "FSDEV_PMA_SIZE is 2048, but FSDEV_BUS_32BIT is not defined" + #endif #endif // The fsdev_bus_t type can be used for both register and PMA access necessities -- cgit v1.3.1 From 2f8078f5b57568f32e0d4d87c95fb32e00389b3d Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 24 Jul 2024 16:59:12 +0700 Subject: minor changes --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 111 ++++++++++---------------- 1 file changed, 43 insertions(+), 68 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 8c2b10691..8eb463351 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -180,7 +180,7 @@ static uint8_t remoteWakeCountdown; // When wake is requested //--------------------------------------------------------------------+ // into the stack. -static void dcd_handle_bus_reset(void); +static void handle_bus_reset(uint8_t rhport); static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix); static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr); static void dcd_ep_ctr_handler(void); @@ -212,18 +212,12 @@ TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t *xfer_ctl_ptr(uint32_t ep_addr) //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ - -void dcd_init(uint8_t rhport) -{ - /* Clocks should already be enabled */ - /* Use __HAL_RCC_USB_CLK_ENABLE(); to enable the clocks before calling this function */ - - /* The RM mentions to use a special ordering of PDWN and FRES, but this isn't done in HAL. - * Here, the RM is followed. */ - +void dcd_init(uint8_t rhport) { + // Follow the RM mentions to use a special ordering of PDWN and FRES for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us asm("NOP"); } + // Perform USB peripheral reset USB->CNTR = USB_CNTR_FRES | USB_CNTR_PDWN; for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us @@ -238,9 +232,11 @@ void dcd_init(uint8_t rhport) } USB->CNTR = 0; // Enable USB -#if !defined(STM32G0) && !defined(STM32H5) && !defined(STM32U5) // BTABLE register does not exist any more on STM32G0, it is fixed to USB SRAM base address +#if !defined(STM32G0) && !defined(STM32H5) && !defined(STM32U5) + // BTABLE register does not exist any more on STM32G0, it is fixed to USB SRAM base address USB->BTABLE = DCD_STM32_BTABLE_BASE; #endif + USB->ISTR = 0; // Clear pending interrupts // Reset endpoints to disabled @@ -250,17 +246,14 @@ void dcd_init(uint8_t rhport) } USB->CNTR |= USB_CNTR_RESETM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; - dcd_handle_bus_reset(); + handle_bus_reset(rhport); // Enable pull-up if supported dcd_connect(rhport); } - -void dcd_sof_enable(uint8_t rhport, bool en) -{ +void dcd_sof_enable(uint8_t rhport, bool en) { (void)rhport; - (void)en; if (en) { USB->CNTR |= USB_CNTR_SOFM; @@ -270,9 +263,7 @@ void dcd_sof_enable(uint8_t rhport, bool en) } // Receive Set Address request, mcu port must also include status IN response -void dcd_set_address(uint8_t rhport, uint8_t dev_addr) -{ - (void)rhport; +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void)dev_addr; // Respond with status @@ -282,35 +273,15 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) // do it at dcd_edpt0_status_complete() } -void dcd_remote_wakeup(uint8_t rhport) -{ +void dcd_remote_wakeup(uint8_t rhport) { (void)rhport; USB->CNTR |= USB_CNTR_RESUME; remoteWakeCountdown = 4u; // required to be 1 to 15 ms, ESOF should trigger every 1ms. } -static const tusb_desc_endpoint_t ep0OUT_desc = { - .bLength = sizeof(tusb_desc_endpoint_t), - .bDescriptorType = TUSB_DESC_ENDPOINT, - .bEndpointAddress = 0x00, - .bmAttributes = {.xfer = TUSB_XFER_CONTROL}, - .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, - .bInterval = 0 -}; - -static const tusb_desc_endpoint_t ep0IN_desc = { - .bLength = sizeof(tusb_desc_endpoint_t), - .bDescriptorType = TUSB_DESC_ENDPOINT, - .bEndpointAddress = 0x80, - .bmAttributes = {.xfer = TUSB_XFER_CONTROL}, - .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, - .bInterval = 0 -}; - -static void dcd_handle_bus_reset(void) -{ - USB->DADDR = 0u; // disable USB peripheral by clearing the EF flag +static void handle_bus_reset(uint8_t rhport) { + USB->DADDR = 0u; // disable USB Function for (uint32_t i = 0; i < FSDEV_EP_COUNT; i++) { // Clear EP allocation status @@ -323,17 +294,26 @@ static void dcd_handle_bus_reset(void) // Reset PMA allocation ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX; - dcd_edpt_open(0, &ep0OUT_desc); - dcd_edpt_open(0, &ep0IN_desc); + tusb_desc_endpoint_t ep0_desc = { + .bLength = sizeof(tusb_desc_endpoint_t), + .bDescriptorType = TUSB_DESC_ENDPOINT, + .bEndpointAddress = 0x00, + .bmAttributes = {.xfer = TUSB_XFER_CONTROL}, + .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, + .bInterval = 0 + }; + + dcd_edpt_open(rhport, &ep0_desc); + + ep0_desc.bEndpointAddress = 0x80; + dcd_edpt_open(rhport, &ep0_desc); - USB->DADDR = USB_DADDR_EF; // Set enable flag, and leaving the device address as zero. + USB->DADDR = USB_DADDR_EF; // Enable USB Function } // Handle CTR interrupt for the TX/IN direction -// // Upon call, (wIstr & USB_ISTR_DIR) == 0U -static void dcd_ep_ctr_tx_handler(uint32_t wIstr) -{ +static void dcd_ep_ctr_tx_handler(uint32_t wIstr) { uint32_t EPindex = wIstr & USB_ISTR_EP_ID; uint32_t wEPRegVal = pcd_get_endpoint(USB, EPindex); uint8_t ep_addr = (wEPRegVal & USB_EPADDR_FIELD) | TUSB_DIR_IN_MASK; @@ -406,6 +386,7 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) // Verify the CTR_RX bit is set. This was in the ST Micro code, // but I'm not sure it's actually necessary? if ((wEPRegVal & USB_EP_CTR_RX) == 0U) { + // TU_ASSERT(false, ); return; } @@ -504,10 +485,7 @@ static void dcd_ep_ctr_handler(void) } } -void dcd_int_handler(uint8_t rhport) -{ - (void)rhport; - +void dcd_int_handler(uint8_t rhport) { uint32_t int_status = USB->ISTR; // const uint32_t handled_ints = USB_ISTR_CTR | USB_ISTR_RESET | USB_ISTR_WKUP // | USB_ISTR_SUSP | USB_ISTR_SOF | USB_ISTR_ESOF; @@ -526,7 +504,7 @@ void dcd_int_handler(uint8_t rhport) if (int_status & USB_ISTR_RESET) { // USBRST is start of reset. USB->ISTR = (fsdev_bus_t)~USB_ISTR_RESET; - dcd_handle_bus_reset(); + handle_bus_reset(rhport); dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); return; // Don't do the rest of the things here; perhaps they've been cleared? } @@ -659,13 +637,12 @@ static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type) // The STM32F0 doesn't seem to like |= or &= to manipulate the EP#R registers, // so I'm using the #define from HAL here, instead. -bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc) -{ +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { (void)rhport; - uint8_t const ep_addr = p_endpoint_desc->bEndpointAddress; - uint8_t const ep_idx = dcd_ep_alloc(ep_addr, p_endpoint_desc->bmAttributes.xfer); + uint8_t const ep_addr = desc_ep->bEndpointAddress; + uint8_t const ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer); uint8_t const dir = tu_edpt_dir(ep_addr); - const uint16_t packet_size = tu_edpt_packet_size(p_endpoint_desc); + const uint16_t packet_size = tu_edpt_packet_size(desc_ep); const uint16_t buffer_size = pcd_aligned_buffer_size(packet_size); uint16_t pma_addr; uint32_t wType; @@ -674,7 +651,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc) TU_ASSERT(buffer_size <= 64); // Set type - switch (p_endpoint_desc->bmAttributes.xfer) { + switch (desc_ep->bmAttributes.xfer) { case TUSB_XFER_CONTROL: wType = USB_EP_CONTROL; break; @@ -807,7 +784,6 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoin } // Currently, single-buffered, and only 64 bytes at a time (max) - static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { uint16_t len = (uint16_t)(xfer->total_len - xfer->queued_len); @@ -1007,8 +983,7 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui * @param wNBytes no. of bytes to be copied. * @retval None */ -static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNBytes) -{ +static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNBytes) { // Since we copy from a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies tu_fifo_buffer_info_t info; tu_fifo_get_read_info(ff, &info); @@ -1042,8 +1017,9 @@ static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNB dst += 4; // Copy rest of wrapped byte - if (wCnt) + if (wCnt) { dcd_write_packet_memory(dst, info.ptr_wrap, wCnt); + } } #else if ((cnt_lin & 0x01) && cnt_wrap) { @@ -1077,8 +1053,7 @@ static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNB } #ifdef FSDEV_BUS_32BIT -static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes) -{ +static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes) { uint8_t *dst8 = dst; volatile uint32_t *src32 = (volatile uint32_t *)(USB_PMAADDR + src); @@ -1138,8 +1113,7 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t * @param wNBytes no. of bytes to be copied. * @retval None */ -static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBytes) -{ +static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBytes) { // Since we copy into a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies // Check for first linear part tu_fifo_buffer_info_t info; @@ -1173,8 +1147,9 @@ static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBy } // Copy rest of wrapped byte - if (wCnt) + if (wCnt) { dcd_read_packet_memory(info.ptr_wrap, src, wCnt); + } } #else if ((cnt_lin & 0x01) && cnt_wrap) { -- cgit v1.3.1 From 0eb0baed190ea671b74528942e4fda87acd259a8 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 25 Jul 2024 11:53:42 +0700 Subject: fsdev: remove unused _setup_packet --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 38 +++++++++++---------------- 1 file changed, 16 insertions(+), 22 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 8eb463351..602b220ab 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -168,11 +168,8 @@ typedef struct { } ep_alloc_t; static xfer_ctl_t xfer_status[CFG_TUD_ENDPPOINT_MAX][2]; - static ep_alloc_t ep_alloc_status[FSDEV_EP_COUNT]; -static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[6]; - static uint8_t remoteWakeCountdown; // When wake is requested //--------------------------------------------------------------------+ @@ -386,18 +383,28 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) // Verify the CTR_RX bit is set. This was in the ST Micro code, // but I'm not sure it's actually necessary? if ((wEPRegVal & USB_EP_CTR_RX) == 0U) { - // TU_ASSERT(false, ); return; } - if ((ep_addr == 0U) && ((wEPRegVal & USB_EP_SETUP) != 0U)) { + if (wEPRegVal & USB_EP_SETUP) { /* Setup packet */ uint32_t count = pcd_get_ep_rx_cnt(USB, EPindex); // Setup packet should always be 8 bytes. If not, ignore it, and try again. if (count == 8) { - // Must reset EP to NAK (in case it had been stalling) (though, maybe too late here) + // Must reset EP to NAK (in case it had been stalling) pcd_set_ep_rx_status(USB, 0u, USB_EP_RX_NAK); pcd_set_ep_tx_status(USB, 0u, USB_EP_TX_NAK); + + // set both data toggle to 1 + uint32_t regVal = pcd_get_endpoint(USB, 0); + if ((regVal & USB_EP_DTOG_TX) == 0) { + pcd_tx_dtog(USB, 0); + } + + if ((regVal & USB_EP_DTOG_RX) == 0) { + pcd_rx_dtog(USB, 0); + } + #ifdef FSDEV_BUS_32BIT dcd_event_setup_received(0, (uint8_t *)(USB_PMAADDR + pcd_get_ep_rx_address(USB, EPindex)), true); #else @@ -405,17 +412,14 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) // user memory, to allow for the 32-bit access that memcpy performs. uint8_t userMemBuf[8]; dcd_read_packet_memory(userMemBuf, pcd_get_ep_rx_address(USB, EPindex), 8); - dcd_event_setup_received(0, (uint8_t *)userMemBuf, true); + dcd_event_setup_received(0, (uint8_t*) userMemBuf, true); #endif - } else { - TU_BREAKPOINT(); } } else { // Clear RX CTR interrupt flag if (ep_addr != 0u) { pcd_clear_rx_ep_ctr(USB, EPindex); } - uint32_t count; uint16_t addr; /* Read from correct register when ISOCHRONOUS (double buffered) */ @@ -553,18 +557,14 @@ void dcd_int_handler(uint8_t rhport) { // Invoked when a control transfer's status stage is complete. // May help DCD to prepare for next control transfer, this API is optional. -void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) -{ +void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request) { (void)rhport; if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && request->bRequest == TUSB_REQ_SET_ADDRESS) { uint8_t const dev_addr = (uint8_t)request->wValue; - - // Setting new address after the whole request is complete - USB->DADDR &= ~USB_DADDR_ADD; - USB->DADDR |= dev_addr; // leave the enable bit set + USB->DADDR = (USB_DADDR_EF | dev_addr); } } @@ -834,12 +834,6 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) if (dir == TUSB_DIR_IN) { dcd_transmit_packet(xfer, ep_idx); } else { - // A setup token can occur immediately after an OUT STATUS packet so make sure we have a valid - // buffer for the control endpoint. - if (ep_idx == 0 && xfer->buffer == NULL) { - xfer->buffer = (uint8_t *)_setup_packet; - } - uint32_t cnt = (uint32_t ) tu_min16(xfer->total_len, xfer->max_packet_size); uint16_t ep_reg = pcd_get_endpoint(USB, ep_idx); -- cgit v1.3.1 From 02caf007723551f878ab3675c14681801f16354e Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 25 Jul 2024 19:00:59 +0700 Subject: simplify btable rx/tx count/address access --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 20 +--- src/portable/st/stm32_fsdev/fsdev_common.h | 136 ++++++++++++++++++-------- 2 files changed, 98 insertions(+), 58 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 602b220ab..927ecac85 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -129,21 +129,7 @@ // Configuration //--------------------------------------------------------------------+ -// hardware limit endpoint -#define FSDEV_EP_COUNT 8 -// If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it -// Both of these MUST be a multiple of 2, and are in byte units. -#ifndef DCD_STM32_BTABLE_BASE -#define DCD_STM32_BTABLE_BASE 0U -#endif - -#ifndef DCD_STM32_BTABLE_SIZE -#define DCD_STM32_BTABLE_SIZE (FSDEV_PMA_SIZE - DCD_STM32_BTABLE_BASE) -#endif - -TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) + (DCD_STM32_BTABLE_SIZE)) <= (FSDEV_PMA_SIZE), "BTABLE does not fit in PMA RAM"); -TU_VERIFY_STATIC(((DCD_STM32_BTABLE_BASE) % 8) == 0, "BTABLE base must be aligned to 8 bytes"); //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF @@ -231,7 +217,7 @@ void dcd_init(uint8_t rhport) { #if !defined(STM32G0) && !defined(STM32H5) && !defined(STM32U5) // BTABLE register does not exist any more on STM32G0, it is fixed to USB SRAM base address - USB->BTABLE = DCD_STM32_BTABLE_BASE; + USB->BTABLE = FSDEV_BTABLE_BASE; #endif USB->ISTR = 0; // Clear pending interrupts @@ -289,7 +275,7 @@ static void handle_bus_reset(uint8_t rhport) { } // Reset PMA allocation - ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX; + ep_buf_ptr = FSDEV_BTABLE_BASE + 8 * FSDEV_EP_COUNT; tusb_desc_endpoint_t ep0_desc = { .bLength = sizeof(tusb_desc_endpoint_t), @@ -705,7 +691,7 @@ void dcd_edpt_close_all(uint8_t rhport) } // Reset PMA allocation - ep_buf_ptr = DCD_STM32_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX + 2 * CFG_TUD_ENDPOINT0_SIZE; + ep_buf_ptr = FSDEV_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX + 2 * CFG_TUD_ENDPOINT0_SIZE; } /** diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 920c17a04..d0f928552 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -34,6 +34,14 @@ #include "stdint.h" +// If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it +// Both of these MUST be a multiple of 2, and are in byte units. +#ifndef FSDEV_BTABLE_BASE +#define FSDEV_BTABLE_BASE 0U +#endif + +TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 bytes"); + // FSDEV_PMA_SIZE is PMA buffer size in bytes. // - 512-byte devices, access with a stride of two words (use every other 16-bit address) // - 1024-byte devices, access with a stride of one word (use every 16-bit address) @@ -41,15 +49,50 @@ // For purposes of accessing the packet #if FSDEV_PMA_SIZE == 512 - #define FSDEV_PMA_STRIDE (2u) + #define FSDEV_PMA_STRIDE (2u) // 1x16 bit access scheme + #define pma_aligned TU_ATTR_ALIGNED(4) #elif FSDEV_PMA_SIZE == 1024 - #define FSDEV_PMA_STRIDE (1u) + #define FSDEV_PMA_STRIDE (1u) // 2x16 bit access scheme + #define pma_aligned #elif FSDEV_PMA_SIZE == 2048 #ifndef FSDEV_BUS_32BIT #warning "FSDEV_PMA_SIZE is 2048, but FSDEV_BUS_32BIT is not defined" #endif + #define FSDEV_PMA_STRIDE (1u) // 32 bit access scheme + #define pma_aligned #endif +// hardware limit endpoint +#define FSDEV_EP_COUNT 8 + +// Buffer Table is located in Packet Memory Area (PMA) and therefore its address access is forced to either +// 16-bit or 32-bit depending on FSDEV_BUS_32BIT. +typedef struct { + union { + struct { + volatile pma_aligned uint16_t tx_addr; + volatile pma_aligned uint16_t tx_count; + volatile pma_aligned uint16_t rx_addr; + volatile pma_aligned uint16_t rx_count; + } ep16[FSDEV_EP_COUNT]; + + struct { + volatile uint32_t tx_count_addr; + volatile uint32_t rx_count_addr; + } ep32[FSDEV_EP_COUNT]; + }; +} fsdev_btable_t; + +TU_VERIFY_STATIC(sizeof(fsdev_btable_t) == FSDEV_EP_COUNT*8*FSDEV_PMA_STRIDE, "size is not correct"); +TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE does not fit in PMA RAM"); + + +#define FSDEV_BTABLE ((volatile fsdev_btable_t*) (USB_PMAADDR+FSDEV_BTABLE_BASE)) + +//--------------------------------------------------------------------+ +// Helper +//--------------------------------------------------------------------+ + // The fsdev_bus_t type can be used for both register and PMA access necessities // For type-safety create a new macro for the volatile address of PMAADDR // The compiler should warn us if we cast it to a non-volatile type? @@ -110,6 +153,21 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx return *reg; } +/** + * @brief Sets address in an endpoint register. + * @param USBx USB peripheral instance register address. + * @param bEpIdx Endpoint Number. + * @param bAddr Address. + * @retval None + */ +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t bAddr) { + uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); + regVal &= USB_EPREG_MASK; + regVal |= bAddr; + regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; + pcd_set_endpoint(USBx, bEpIdx,regVal); +} + TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wType) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); regVal &= (uint32_t)USB_EP_T_MASK; @@ -153,58 +211,47 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, * @retval Counter value */ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - return (pma32[2*bEpIdx] & 0x03FF0000) >> 16; + uint16_t count; +#ifdef FSDEV_BUS_32BIT + count = (FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr >> 16); #else - volatile const uint16_t *regPtr = pcd_ep_tx_cnt_ptr(USBx, bEpIdx); - return *regPtr & 0x3ffU; + count = FSDEV_BTABLE->ep16[bEpIdx].tx_count; #endif + + return count & 0x3FFU; } TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - return (pma32[2*bEpIdx + 1] & 0x03FF0000) >> 16; + uint16_t count; +#ifdef FSDEV_BUS_32BIT + count = (FSDEV_BTABLE->ep32[bEpIdx].rx_count_addr >> 16); #else - volatile const uint16_t *regPtr = pcd_ep_rx_cnt_ptr(USBx, bEpIdx); - return *regPtr & 0x3ffU; + count = FSDEV_BTABLE->ep16[bEpIdx].rx_count; #endif + + return count & 0x3FFU; } #define pcd_get_ep_dbuf0_cnt pcd_get_ep_tx_cnt #define pcd_get_ep_dbuf1_cnt pcd_get_ep_rx_cnt -/** - * @brief Sets address in an endpoint register. - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @param bAddr Address. - * @retval None - */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t bAddr) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal |= bAddr; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx,regVal); -} - TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - return pma32[2*bEpIdx] & 0x0000FFFFu ; +#ifdef FSDEV_BUS_32BIT + return FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr & 0x0000FFFFu; #else - return *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 0u); + return FSDEV_BTABLE->ep16[bEpIdx].tx_addr; #endif } TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - return pma32[2*bEpIdx + 1] & 0x0000FFFFu; +#ifdef FSDEV_BUS_32BIT + return FSDEV_BTABLE->ep32[bEpIdx].rx_count_addr & 0x0000FFFFu; #else - return *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 2u); + return FSDEV_BTABLE->ep16[bEpIdx].rx_addr; #endif } @@ -212,20 +259,24 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * #define pcd_get_ep_dbuf1_address pcd_get_ep_rx_address TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - pma32[2*bEpIdx] = (pma32[2*bEpIdx] & 0xFFFF0000u) | (addr & 0x0000FFFCu); +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr; + count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); + FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr = count_addr; #else - *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 0u) = addr; + FSDEV_BTABLE->ep16[bEpIdx].tx_addr = addr; #endif } TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - pma32[2*bEpIdx + 1] = (pma32[2*bEpIdx + 1] & 0xFFFF0000u) | (addr & 0x0000FFFCu); +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx].rx_count_addr; + count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); + FSDEV_BTABLE->ep32[bEpIdx].rx_count_addr = count_addr; #else - *pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 2u) = addr; + FSDEV_BTABLE->ep16[bEpIdx].rx_addr = addr; #endif } @@ -233,12 +284,15 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USB #define pcd_set_ep_dbuf1_address pcd_set_ep_rx_address TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - pma32[2*bEpIdx] = (pma32[2*bEpIdx] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16); +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr; + count_addr = (count_addr & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16); + FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr = count_addr; #else - volatile uint16_t * reg = pcd_ep_tx_cnt_ptr(USBx, bEpIdx); - *reg = (uint16_t) (*reg & (uint16_t) ~0x3FFU) | (wCount & 0x3FFU); + uint16_t count = FSDEV_BTABLE->ep16[bEpIdx].tx_count; + count = (count & ~0x3FFU) | (wCount & 0x3FFU); + FSDEV_BTABLE->ep16[bEpIdx].tx_count = count; #endif } -- cgit v1.3.1 From 5122d6d109f8c4b31b6cbe29c685fad30a8961fe Mon Sep 17 00:00:00 2001 From: Brent Kowal Date: Thu, 25 Jul 2024 09:08:37 -0400 Subject: Combined DCD MUSB implementations Combined the new MAX32 MUSB implementation with the existing (TI) implementation to provide generic code base for working the MUSB DCD peripheral. - Added abstraction calls for FIFO setup, EP registers, Ctrl registers and interrupt setup. - Combined TM4C and MSP432E into a single header file. - Created musb_max32.h, and removed the MAX32 specific C implementation. - Updated MAX32 build system to use dcd_musb.c. - Added MAX32 conditions for cdc_dual_ports example descriptors missed during first testing. --- .../device/cdc_dual_ports/src/usb_descriptors.c | 12 + hw/bsp/max32650/family.cmake | 2 +- hw/bsp/max32650/family.mk | 2 +- hw/bsp/max32666/family.cmake | 2 +- hw/bsp/max32666/family.mk | 2 +- hw/bsp/max32690/family.cmake | 2 +- hw/bsp/max32690/family.mk | 2 +- hw/bsp/max78002/family.cmake | 2 +- hw/bsp/max78002/family.mk | 2 +- src/portable/analog/max32/dcd_max32.c | 811 --------------------- src/portable/mentor/musb/dcd_musb.c | 436 ++++------- src/portable/mentor/musb/hcd_musb.c | 12 +- src/portable/mentor/musb/musb_max32.h | 221 ++++++ src/portable/mentor/musb/musb_msp432e.h | 40 - src/portable/mentor/musb/musb_ti.h | 285 ++++++++ src/portable/mentor/musb/musb_tm4c.h | 45 -- src/portable/mentor/musb/musb_type.h | 33 + 17 files changed, 711 insertions(+), 1200 deletions(-) delete mode 100644 src/portable/analog/max32/dcd_max32.c create mode 100644 src/portable/mentor/musb/musb_max32.h delete mode 100644 src/portable/mentor/musb/musb_msp432e.h create mode 100644 src/portable/mentor/musb/musb_ti.h delete mode 100644 src/portable/mentor/musb/musb_tm4c.h (limited to 'src/portable') diff --git a/examples/device/cdc_dual_ports/src/usb_descriptors.c b/examples/device/cdc_dual_ports/src/usb_descriptors.c index de2505c07..808d78411 100644 --- a/examples/device/cdc_dual_ports/src/usb_descriptors.c +++ b/examples/device/cdc_dual_ports/src/usb_descriptors.c @@ -120,6 +120,18 @@ enum #define EPNUM_CDC_1_OUT 0x05 #define EPNUM_CDC_1_IN 0x86 +#elif CFG_TUSB_MCU == OPT_MCU_MAX32690 || CFG_TUSB_MCU == OPT_MCU_MAX32650 || \ + CFG_TUSB_MCU == OPT_MCU_MAX32666 || CFG_TUSB_MCU == OPT_MCU_MAX78002 + // MAX32 doesn't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_CDC_0_NOTIF 0x81 + #define EPNUM_CDC_0_OUT 0x02 + #define EPNUM_CDC_0_IN 0x83 + + #define EPNUM_CDC_1_NOTIF 0x84 + #define EPNUM_CDC_1_OUT 0x05 + #define EPNUM_CDC_1_IN 0x86 + #else #define EPNUM_CDC_0_NOTIF 0x81 #define EPNUM_CDC_0_OUT 0x02 diff --git a/hw/bsp/max32650/family.cmake b/hw/bsp/max32650/family.cmake index 129d99af8..92b68a1cd 100644 --- a/hw/bsp/max32650/family.cmake +++ b/hw/bsp/max32650/family.cmake @@ -132,7 +132,7 @@ function(family_configure_example TARGET RTOS) # Add TinyUSB target and port source family_add_tinyusb(${TARGET} OPT_MCU_MAX32650 ${RTOS}) target_sources(${TARGET}-tinyusb PUBLIC - ${TOP}/src/portable/analog/max32/dcd_max32.c + ${TOP}/src/portable/mentor/musb/dcd_musb.c ) target_compile_options(${TARGET} PRIVATE -Wno-error=strict-prototypes diff --git a/hw/bsp/max32650/family.mk b/hw/bsp/max32650/family.mk index 0718523c3..359261216 100644 --- a/hw/bsp/max32650/family.mk +++ b/hw/bsp/max32650/family.mk @@ -62,7 +62,7 @@ flash: $(DEFAULT_FLASH) # ----------------- PERIPH_SRC = $(TOP)/$(MAX32_PERIPH)/Source SRC_C += \ - src/portable/analog/max32/dcd_max32.c \ + src/portable/mentor/musb/dcd_musb.c \ $(MAX32_CMSIS)/Device/Maxim/MAX32650/Source/heap.c \ $(MAX32_CMSIS)/Device/Maxim/MAX32650/Source/system_max32650.c \ $(MAX32_CMSIS)/Device/Maxim/MAX32650/Source/header_MAX32650.c \ diff --git a/hw/bsp/max32666/family.cmake b/hw/bsp/max32666/family.cmake index ef2a2bb63..eb9d2175f 100644 --- a/hw/bsp/max32666/family.cmake +++ b/hw/bsp/max32666/family.cmake @@ -127,7 +127,7 @@ function(family_configure_example TARGET RTOS) # Add TinyUSB target and port source family_add_tinyusb(${TARGET} OPT_MCU_MAX32666 ${RTOS}) target_sources(${TARGET}-tinyusb PUBLIC - ${TOP}/src/portable/analog/max32/dcd_max32.c + ${TOP}/src/portable/mentor/musb/dcd_musb.c ) target_compile_options(${TARGET} PRIVATE -Wno-error=strict-prototypes diff --git a/hw/bsp/max32666/family.mk b/hw/bsp/max32666/family.mk index 31f81f014..720d994ef 100644 --- a/hw/bsp/max32666/family.mk +++ b/hw/bsp/max32666/family.mk @@ -57,7 +57,7 @@ flash-msdk: $(BUILD)/$(PROJECT).elf # ----------------- PERIPH_SRC = $(TOP)/$(MAX32_PERIPH)/Source SRC_C += \ - src/portable/analog/max32/dcd_max32.c \ + src/portable/mentor/musb/dcd_musb.c \ $(MAX32_CMSIS)/Device/Maxim/MAX32665/Source/heap.c \ $(MAX32_CMSIS)/Device/Maxim/MAX32665/Source/system_max32665.c \ $(PERIPH_SRC)/SYS/mxc_assert.c \ diff --git a/hw/bsp/max32690/family.cmake b/hw/bsp/max32690/family.cmake index d7a562956..2a9422dbe 100644 --- a/hw/bsp/max32690/family.cmake +++ b/hw/bsp/max32690/family.cmake @@ -132,7 +132,7 @@ function(family_configure_example TARGET RTOS) # Add TinyUSB target and port source family_add_tinyusb(${TARGET} OPT_MCU_MAX32690 ${RTOS}) target_sources(${TARGET}-tinyusb PUBLIC - ${TOP}/src/portable/analog/max32/dcd_max32.c + ${TOP}/src/portable/mentor/musb/dcd_musb.c ) target_compile_options(${TARGET} PRIVATE -Wno-error=strict-prototypes diff --git a/hw/bsp/max32690/family.mk b/hw/bsp/max32690/family.mk index 9360a07c6..c533cf4a4 100644 --- a/hw/bsp/max32690/family.mk +++ b/hw/bsp/max32690/family.mk @@ -64,7 +64,7 @@ flash-msdk: $(BUILD)/$(PROJECT).elf # ----------------- PERIPH_SRC = $(TOP)/$(MAX32_PERIPH)/Source SRC_C += \ - src/portable/analog/max32/dcd_max32.c \ + src/portable/mentor/musb/dcd_musb.c \ $(MAX32_CMSIS)/Device/Maxim/MAX32690/Source/heap.c \ $(MAX32_CMSIS)/Device/Maxim/MAX32690/Source/system_max32690.c \ $(PERIPH_SRC)/SYS/mxc_assert.c \ diff --git a/hw/bsp/max78002/family.cmake b/hw/bsp/max78002/family.cmake index 83fd3007f..090f1da43 100644 --- a/hw/bsp/max78002/family.cmake +++ b/hw/bsp/max78002/family.cmake @@ -137,7 +137,7 @@ function(family_configure_example TARGET RTOS) # Add TinyUSB target and port source family_add_tinyusb(${TARGET} OPT_MCU_MAX78002 ${RTOS}) target_sources(${TARGET}-tinyusb PUBLIC - ${TOP}/src/portable/analog/max32/dcd_max32.c + ${TOP}/src/portable/mentor/musb/dcd_musb.c ) target_link_libraries(${TARGET}-tinyusb PUBLIC board_${BOARD}) target_compile_options(${TARGET}-tinyusb PRIVATE diff --git a/hw/bsp/max78002/family.mk b/hw/bsp/max78002/family.mk index 8df8517da..5297815de 100644 --- a/hw/bsp/max78002/family.mk +++ b/hw/bsp/max78002/family.mk @@ -60,7 +60,7 @@ flash-msdk: $(BUILD)/$(PROJECT).elf # ----------------- PERIPH_SRC = $(TOP)/$(MAX32_PERIPH)/Source SRC_C += \ - src/portable/analog/max32/dcd_max32.c \ + src/portable/mentor/musb/dcd_musb.c \ $(MAX32_CMSIS)/Device/Maxim/MAX78002/Source/heap.c \ $(MAX32_CMSIS)/Device/Maxim/MAX78002/Source/system_max78002.c \ $(PERIPH_SRC)/SYS/mxc_assert.c \ diff --git a/src/portable/analog/max32/dcd_max32.c b/src/portable/analog/max32/dcd_max32.c deleted file mode 100644 index df616120a..000000000 --- a/src/portable/analog/max32/dcd_max32.c +++ /dev/null @@ -1,811 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2021 Koji KITAYAMA - * Copyright (c) 2024 Brent Kowal (Analog Devices, Inc) - * - * 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 CFG_TUD_ENABLED && \ - TU_CHECK_MCU(OPT_MCU_MAX32690, OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX78002) - - #if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) -/* GCC warns that an address may be unaligned, even though - * the target CPU has the capability for unaligned memory access. */ -_Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); - #endif - - #include "device/dcd.h" - - #include "mxc_delay.h" - #include "mxc_device.h" - #include "mxc_sys.h" - #include "nvic_table.h" - #include "usbhs_regs.h" - - #define USBHS_M31_CLOCK_RECOVERY - - /*------------------------------------------------------------------ - * MACRO TYPEDEF CONSTANT ENUM DECLARATION - *------------------------------------------------------------------*/ - #define REQUEST_TYPE_INVALID (0xFFu) - - -typedef union { - uint8_t u8; - uint16_t u16; - uint32_t u32; -} hw_fifo_t; - -typedef struct TU_ATTR_PACKED { - void *buf; /* the start address of a transfer data buffer */ - uint16_t length; /* the number of bytes in the buffer */ - uint16_t remaining; /* the number of bytes remaining in the buffer */ -} pipe_state_t; - -typedef struct -{ - tusb_control_request_t setup_packet; - uint16_t remaining_ctrl; /* The number of bytes remaining in data stage of control transfer. */ - int8_t status_out; - pipe_state_t pipe0; - pipe_state_t pipe[2][TUP_DCD_ENDPOINT_MAX - 1]; /* pipe[direction][endpoint number - 1] */ - uint16_t pipe_buf_is_fifo[2]; /* Bitmap. Each bit means whether 1:TU_FIFO or 0:POD. */ -} dcd_data_t; - -/*------------------------------------------------------------------ - * INTERNAL OBJECT & FUNCTION DECLARATION - *------------------------------------------------------------------*/ -static dcd_data_t _dcd; - - -static volatile void *edpt_get_fifo_ptr(unsigned epnum) { - volatile uint32_t *ptr; - - ptr = &MXC_USBHS->fifo0; - ptr += epnum; /* Pointer math: multiplies ep by sizeof(uint32_t) */ - - return (volatile void *) ptr; -} - -static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) { - volatile hw_fifo_t *reg = (volatile hw_fifo_t *) fifo; - uintptr_t addr = (uintptr_t) buf; - while (len >= 4) { - reg->u32 = *(uint32_t const *) addr; - addr += 4; - len -= 4; - } - if (len >= 2) { - reg->u16 = *(uint16_t const *) addr; - addr += 2; - len -= 2; - } - if (len) { - reg->u8 = *(uint8_t const *) addr; - } -} - -static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) { - volatile hw_fifo_t *reg = (volatile hw_fifo_t *) fifo; - uintptr_t addr = (uintptr_t) buf; - while (len >= 4) { - *(uint32_t *) addr = reg->u32; - addr += 4; - len -= 4; - } - if (len >= 2) { - *(uint16_t *) addr = reg->u16; - addr += 2; - len -= 2; - } - if (len) { - *(uint8_t *) addr = reg->u8; - } -} - -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}, - }; - 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; - if (rem) { - len = TU_MIN(rem, info.len_wrap); - ops[dir].pipe_read_write(info.ptr_wrap, fifo, len); - rem -= len; - } - ops[dir].tu_fifo_advance(f, total_len - rem); -} - -static void process_setup_packet(uint8_t rhport) { - uint32_t *p = (void *) &_dcd.setup_packet; - p[0] = MXC_USBHS->fifo0; - p[1] = MXC_USBHS->fifo0; - - _dcd.pipe0.buf = NULL; - _dcd.pipe0.length = 0; - _dcd.pipe0.remaining = 0; - dcd_event_setup_received(rhport, (const uint8_t *) (uintptr_t) &_dcd.setup_packet, true); - - const unsigned len = _dcd.setup_packet.wLength; - _dcd.remaining_ctrl = len; - const unsigned dir_in = tu_edpt_dir(_dcd.setup_packet.bmRequestType); - /* Clear RX FIFO and reverse the transaction direction */ - if (len && dir_in) { - MXC_USBHS->index = 0; - MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_OUTPKTRDY; - } -} - -static bool handle_xfer_in(uint_fast8_t ep_addr) { - unsigned epnum = tu_edpt_number(ep_addr); - unsigned epnum_minus1 = epnum - 1; - pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; - const unsigned rem = pipe->remaining; - - //This function should not be for ep0 - TU_ASSERT(epnum); - - if (!rem) { - pipe->buf = NULL; - return true; - } - - MXC_USBHS->index = epnum; - const unsigned mps = MXC_USBHS->inmaxp; - const unsigned len = TU_MIN(mps, rem); - void *buf = pipe->buf; - volatile void *fifo_ptr = edpt_get_fifo_ptr(epnum); - if (len) { - if (_dcd.pipe_buf_is_fifo[TUSB_DIR_IN] & TU_BIT(epnum_minus1)) { - pipe_read_write_packet_ff(buf, fifo_ptr, len, TUSB_DIR_IN); - } else { - pipe_write_packet(buf, fifo_ptr, len); - pipe->buf = buf + len; - } - pipe->remaining = rem - len; - } - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_INPKTRDY;//TODO: Verify a | isn't needed - - return false; -} - -static bool handle_xfer_out(uint_fast8_t ep_addr) { - unsigned epnum = tu_edpt_number(ep_addr); - unsigned epnum_minus1 = epnum - 1; - pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; - - //This function should not be for ep0 - TU_ASSERT(epnum); - - MXC_USBHS->index = epnum; - - TU_ASSERT(MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY); - - const unsigned mps = MXC_USBHS->outmaxp; - const unsigned rem = pipe->remaining; - const unsigned vld = MXC_USBHS->outcount; - const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); - void *buf = pipe->buf; - volatile void *fifo_ptr = edpt_get_fifo_ptr(epnum); - if (len) { - if (_dcd.pipe_buf_is_fifo[TUSB_DIR_OUT] & TU_BIT(epnum_minus1)) { - pipe_read_write_packet_ff(buf, fifo_ptr, len, TUSB_DIR_OUT); - } else { - pipe_read_packet(buf, fifo_ptr, len); - pipe->buf = buf + len; - } - pipe->remaining = rem - len; - } - if ((len < mps) || (rem == len)) { - pipe->buf = NULL; - return NULL != buf; - } - MXC_USBHS->outcsrl = 0; /* Clear RXRDY bit *///TODO: Verify just setting to 0 is ok - return false; -} - -static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { - (void) rhport; - - unsigned epnum = tu_edpt_number(ep_addr); - unsigned epnum_minus1 = epnum - 1; - unsigned dir_in = tu_edpt_dir(ep_addr); - - pipe_state_t *pipe = &_dcd.pipe[dir_in][epnum_minus1]; - pipe->buf = buffer; - pipe->length = total_bytes; - pipe->remaining = total_bytes; - - if (dir_in) { - handle_xfer_in(ep_addr); - } else { - MXC_USBHS->index = epnum; - if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { - MXC_USBHS->outcsrl = 0;//TODO: Verify just setting to 0 is ok - } - } - return true; -} - -static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { - (void) rhport; - TU_ASSERT(total_bytes <= 64); /* Current implementation supports for only up to 64 bytes. */ - - const unsigned req = _dcd.setup_packet.bmRequestType; - TU_ASSERT(req != REQUEST_TYPE_INVALID || total_bytes == 0); - - if (req == REQUEST_TYPE_INVALID || _dcd.status_out) { - /* STATUS OUT stage. - * MUSB controller automatically handles STATUS OUT packets without - * software helps. We do not have to do anything. And STATUS stage - * 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. */ - _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\r\n"); - } - return true; - } - const unsigned dir_in = tu_edpt_dir(ep_addr); - MXC_USBHS->index = 0; - if (tu_edpt_dir(req) == dir_in) { /* DATA stage */ - TU_ASSERT(total_bytes <= _dcd.remaining_ctrl); - const unsigned rem = _dcd.remaining_ctrl; - const unsigned len = TU_MIN(TU_MIN(rem, 64), total_bytes); - volatile void *fifo_ptr = edpt_get_fifo_ptr(0); - if (dir_in) { - pipe_write_packet(buffer, fifo_ptr, len); - - _dcd.pipe0.buf = buffer + len; - _dcd.pipe0.length = len; - _dcd.pipe0.remaining = 0; - - _dcd.remaining_ctrl = rem - len; - if ((len < 64) || (rem == len)) { - _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; /* Change to STATUS/SETUP stage */ - _dcd.status_out = 1; - /* Flush TX FIFO and reverse the transaction direction. */ - MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_INPKTRDY | MXC_F_USBHS_CSR0_DATA_END; - } else { - MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_INPKTRDY; /* Flush TX FIFO to return ACK. */ - } - } else { - _dcd.pipe0.buf = buffer; - _dcd.pipe0.length = len; - _dcd.pipe0.remaining = len; - MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_OUTPKTRDY; /* Clear RX FIFO to return ACK. */ - } - } else if (dir_in) { - _dcd.pipe0.buf = NULL; - _dcd.pipe0.length = 0; - _dcd.pipe0.remaining = 0; - /* Clear RX FIFO and reverse the transaction direction */ - MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_OUTPKTRDY | MXC_F_USBHS_CSR0_DATA_END; - } - return true; -} - -static void process_ep0(uint8_t rhport) { - MXC_USBHS->index = 0; - uint_fast8_t csrl = MXC_USBHS->csr0; - - if (csrl & MXC_F_USBHS_CSR0_SENT_STALL) { - /* Returned STALL packet to HOST. */ - MXC_USBHS->csr0 = 0; /* Clear STALL */ - return; - } - - unsigned req = _dcd.setup_packet.bmRequestType; - if (csrl & MXC_F_USBHS_CSR0_SETUP_END) { - TU_LOG1(" ABORT by the next packets\r\n"); - MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_SETUP_END; - if (req != REQUEST_TYPE_INVALID && _dcd.pipe0.buf) { - /* DATA stage was aborted by receiving STATUS or SETUP packet. */ - _dcd.pipe0.buf = NULL; - _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; - dcd_event_xfer_complete(rhport, - req & TUSB_DIR_IN_MASK, - _dcd.pipe0.length - _dcd.pipe0.remaining, - XFER_RESULT_SUCCESS, true); - } - req = REQUEST_TYPE_INVALID; - if (!(csrl & MXC_F_USBHS_CSR0_OUTPKTRDY)) return; /* Received SETUP packet */ - } - - if (csrl & MXC_F_USBHS_CSR0_OUTPKTRDY) { - /* Received SETUP or DATA OUT packet */ - if (req == REQUEST_TYPE_INVALID) { - /* SETUP */ - TU_ASSERT(sizeof(tusb_control_request_t) == MXC_USBHS->count0, ); - process_setup_packet(rhport); - return; - } - if (_dcd.pipe0.buf) { - /* DATA OUT */ - const unsigned vld = MXC_USBHS->count0; - const unsigned rem = _dcd.pipe0.remaining; - const unsigned len = TU_MIN(TU_MIN(rem, 64), vld); - volatile void *fifo_ptr = edpt_get_fifo_ptr(0); - pipe_read_packet(_dcd.pipe0.buf, fifo_ptr, len); - - _dcd.pipe0.remaining = rem - len; - _dcd.remaining_ctrl -= len; - - _dcd.pipe0.buf = NULL; - dcd_event_xfer_complete(rhport, - tu_edpt_addr(0, TUSB_DIR_OUT), - _dcd.pipe0.length - _dcd.pipe0.remaining, - XFER_RESULT_SUCCESS, true); - } - return; - } - - /* When CSRL0 is zero, it means that completion of sending a any length packet - * or receiving a zero length packet. */ - if (req != REQUEST_TYPE_INVALID && !tu_edpt_dir(req)) { - /* STATUS IN */ - if (*(const uint16_t *) (uintptr_t) &_dcd.setup_packet == 0x0500) { - /* The address must be changed on completion of the control transfer. */ - MXC_USBHS->faddr = (uint8_t) _dcd.setup_packet.wValue; - } - _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; - dcd_event_xfer_complete(rhport, - tu_edpt_addr(0, TUSB_DIR_IN), - _dcd.pipe0.length - _dcd.pipe0.remaining, - XFER_RESULT_SUCCESS, true); - return; - } - if (_dcd.pipe0.buf) { - /* DATA IN */ - _dcd.pipe0.buf = NULL; - dcd_event_xfer_complete(rhport, - tu_edpt_addr(0, TUSB_DIR_IN), - _dcd.pipe0.length - _dcd.pipe0.remaining, - XFER_RESULT_SUCCESS, true); - } -} - -static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) { - bool completed; - const unsigned dir_in = tu_edpt_dir(ep_addr); - const unsigned epnum = tu_edpt_number(ep_addr); - - MXC_USBHS->index = epnum; - - if (dir_in) { - if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_SENTSTALL) { - MXC_USBHS->incsrl &= ~(MXC_F_USBHS_INCSRL_SENTSTALL | MXC_F_USBHS_INCSRL_UNDERRUN); - return; - } - completed = handle_xfer_in(ep_addr); - } else { - if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_SENTSTALL) { - MXC_USBHS->outcsrl &= ~(MXC_F_USBHS_OUTCSRL_SENTSTALL | MXC_F_USBHS_OUTCSRL_OVERRUN); - return; - } - completed = handle_xfer_out(ep_addr); - } - - if (completed) { - pipe_state_t *pipe = &_dcd.pipe[dir_in][tu_edpt_number(ep_addr) - 1]; - dcd_event_xfer_complete(rhport, ep_addr, - pipe->length - pipe->remaining, - XFER_RESULT_SUCCESS, true); - } -} - -static void process_bus_reset(uint8_t rhport) { - (void) rhport; - /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), - * a control transfer state is SETUP or STATUS stage. */ - _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; - _dcd.status_out = 0; - /* When pipe0.buf has not NULL, DATA stage works in progress. */ - _dcd.pipe0.buf = NULL; - - MXC_USBHS->intrinen = 1; /* Enable only EP0 */ - MXC_USBHS->introuten = 0; - - - /* Clear FIFO settings */ - for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { - MXC_USBHS->index = i; - if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_INPKTRDY) { - /* Per musbhsfc_pg, only flush FIFO if IN packet loaded */ - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_FLUSHFIFO; - } - - if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { - /* Per musbhsfc_pg, only flush FIFO if OUT packet is ready */ - MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_FLUSHFIFO; - } - } - dcd_event_bus_reset(0, (MXC_USBHS->power & MXC_F_USBHS_POWER_HS_MODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); -} - -/*------------------------------------------------------------------ - * Device API - *------------------------------------------------------------------*/ - -void dcd_init(uint8_t rhport) { - (void) rhport; - MXC_USBHS->intrusben |= MXC_F_USBHS_INTRUSBEN_SUSPEND_INT_EN; - - //Interrupt for VBUS disconnect - MXC_USBHS->mxm_int_en |= MXC_F_USBHS_MXM_INT_EN_NOVBUS; - - NVIC_ClearPendingIRQ(USB_IRQn); - dcd_edpt_close_all(rhport); - - //Unsuspend the MAC - MXC_USBHS->mxm_suspend = 0; - - /* Configure PHY */ - MXC_USBHS->m31_phy_xcfgi_31_0 = (0x1 << 3) | (0x1 << 11); - MXC_USBHS->m31_phy_xcfgi_63_32 = 0; - MXC_USBHS->m31_phy_xcfgi_95_64 = 0x1 << (72 - 64); - MXC_USBHS->m31_phy_xcfgi_127_96 = 0; - - - #ifdef USBHS_M31_CLOCK_RECOVERY - MXC_USBHS->m31_phy_noncry_rstb = 1; - MXC_USBHS->m31_phy_noncry_en = 1; - MXC_USBHS->m31_phy_outclksel = 0; - MXC_USBHS->m31_phy_coreclkin = 0; - MXC_USBHS->m31_phy_xtlsel = 2; /* Select 25 MHz clock */ - #else - /* Use this option to feed the PHY a 30 MHz clock, which is them used as a PLL reference */ - /* As it depends on the system core clock, this should probably be done at the SYS level */ - MXC_USBHS->m31_phy_noncry_rstb = 0; - MXC_USBHS->m31_phy_noncry_en = 0; - MXC_USBHS->m31_phy_outclksel = 1; - MXC_USBHS->m31_phy_coreclkin = 1; - MXC_USBHS->m31_phy_xtlsel = 3; /* Select 30 MHz clock */ - #endif - MXC_USBHS->m31_phy_pll_en = 1; - MXC_USBHS->m31_phy_oscouten = 1; - - /* Reset PHY */ - MXC_USBHS->m31_phy_ponrst = 0; - MXC_USBHS->m31_phy_ponrst = 1; - - dcd_connect(rhport); -} - -void dcd_int_enable(uint8_t rhport) { - (void) rhport; - NVIC_EnableIRQ(USB_IRQn); -} - -void dcd_int_disable(uint8_t rhport) { - (void) rhport; - NVIC_DisableIRQ(USB_IRQn); -} - -// Receive Set Address request, mcu port must also include status IN response -void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { - (void) rhport; - (void) dev_addr; - _dcd.pipe0.buf = NULL; - _dcd.pipe0.length = 0; - _dcd.pipe0.remaining = 0; - /* Clear RX FIFO to return ACK. */ - MXC_USBHS->index = 0; - MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SERV_OUTPKTRDY | MXC_F_USBHS_CSR0_DATA_END; -} - -// Wake up host -void dcd_remote_wakeup(uint8_t rhport) { - (void) rhport; - MXC_USBHS->power |= MXC_F_USBHS_POWER_RESUME; - - #if CFG_TUSB_OS != OPT_OS_NONE - osal_task_delay(10); - #else - MXC_Delay(MXC_DELAY_MSEC(10)); - #endif - - MXC_USBHS->power &= ~MXC_F_USBHS_POWER_RESUME; -} - -// Connect by enabling internal pull-up resistor on D+/D- -void dcd_connect(uint8_t rhport) { - (void) rhport; - MXC_USBHS->power |= TUD_OPT_HIGH_SPEED ? MXC_F_USBHS_POWER_HS_ENABLE : 0; - MXC_USBHS->power |= MXC_F_USBHS_POWER_SOFTCONN; -} - -// Disconnect by disabling internal pull-up resistor on D+/D- -void dcd_disconnect(uint8_t rhport) { - (void) rhport; - MXC_USBHS->power &= ~MXC_F_USBHS_POWER_SOFTCONN; -} - -void dcd_sof_enable(uint8_t rhport, bool en) { - (void) rhport; - (void) en; - - // TODO implement later -} - -//--------------------------------------------------------------------+ -// Endpoint API -//--------------------------------------------------------------------+ - -// Configure endpoint's registers according to descriptor -bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc) { - (void) rhport; - - const unsigned ep_addr = ep_desc->bEndpointAddress; - const unsigned epn = tu_edpt_number(ep_addr); - const unsigned dir_in = tu_edpt_dir(ep_addr); - const unsigned xfer = ep_desc->bmAttributes.xfer; - const unsigned mps = tu_edpt_packet_size(ep_desc); - - TU_ASSERT(epn < TUP_DCD_ENDPOINT_MAX); - - pipe_state_t *pipe = &_dcd.pipe[dir_in][epn - 1]; - pipe->buf = NULL; - pipe->length = 0; - pipe->remaining = 0; - - MXC_USBHS->index = epn; - - if (dir_in) { - MXC_USBHS->inmaxp = mps; - MXC_USBHS->incsru = (MXC_F_USBHS_INCSRU_DPKTBUFDIS | MXC_F_USBHS_INCSRU_MODE) | ((xfer == TUSB_XFER_ISOCHRONOUS) ? MXC_F_USBHS_INCSRU_ISO : 0); - if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_INPKTRDY) { - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG | MXC_F_USBHS_INCSRL_FLUSHFIFO; - } else { - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG; - } - MXC_USBHS->intrinen |= TU_BIT(epn); - } else { - MXC_USBHS->outmaxp = mps; - MXC_USBHS->outcsru = (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS) | ((xfer == TUSB_XFER_ISOCHRONOUS) ? MXC_F_USBHS_OUTCSRU_ISO : 0); - if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { - MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG | MXC_F_USBHS_OUTCSRL_FLUSHFIFO; - } else { - MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG; - } - MXC_USBHS->introuten |= TU_BIT(epn); - } - - return true; -} - -void dcd_edpt_close_all(uint8_t rhport) { - (void) rhport; - - MXC_SYS_Crit_Enter(); - MXC_USBHS->intrinen = 1; /* Enable only EP0 */ - MXC_USBHS->introuten = 0; - - for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { - MXC_USBHS->index = i; - MXC_USBHS->inmaxp = 0; - MXC_USBHS->incsru = MXC_F_USBHS_INCSRU_DPKTBUFDIS; - - if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_INPKTRDY) { - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG | MXC_F_USBHS_INCSRL_FLUSHFIFO; - } else { - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG; - } - - MXC_USBHS->outmaxp = 0; - MXC_USBHS->outcsru = MXC_F_USBHS_OUTCSRU_DPKTBUFDIS; - - if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { - MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG | MXC_F_USBHS_OUTCSRL_FLUSHFIFO; - } else { - MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG; - } - } - MXC_SYS_Crit_Exit(); -} - -void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; - unsigned const epn = tu_edpt_number(ep_addr); - unsigned const dir_in = tu_edpt_dir(ep_addr); - - MXC_SYS_Crit_Enter(); - MXC_USBHS->index = epn; - if (dir_in) { - MXC_USBHS->intrinen &= ~TU_BIT(epn); - MXC_USBHS->inmaxp = 0; - MXC_USBHS->incsru = MXC_F_USBHS_INCSRU_DPKTBUFDIS; - if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_INPKTRDY) { - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG | MXC_F_USBHS_INCSRL_FLUSHFIFO; - } else { - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG; - } - } else { - MXC_USBHS->introuten &= ~TU_BIT(epn); - MXC_USBHS->outmaxp = 0; - MXC_USBHS->outcsru = MXC_F_USBHS_OUTCSRU_DPKTBUFDIS; - if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { - MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG | MXC_F_USBHS_OUTCSRL_FLUSHFIFO; - } else { - MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG; - } - } - MXC_SYS_Crit_Exit(); -} - -// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack -bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { - (void) rhport; - bool ret; - unsigned const epnum = tu_edpt_number(ep_addr); - MXC_SYS_Crit_Enter(); - if (epnum) { - _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] &= ~TU_BIT(epnum - 1); - ret = edpt_n_xfer(rhport, ep_addr, buffer, total_bytes); - } else - ret = edpt0_xfer(rhport, ep_addr, buffer, total_bytes); - MXC_SYS_Crit_Exit(); - return ret; -} - -// Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c -bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes) { - (void) rhport; - bool ret; - unsigned const epnum = tu_edpt_number(ep_addr); - TU_ASSERT(epnum); - MXC_SYS_Crit_Enter(); - _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] |= TU_BIT(epnum - 1); - ret = edpt_n_xfer(rhport, ep_addr, (uint8_t *) ff, total_bytes); - MXC_SYS_Crit_Exit(); - return ret; -} - -// Stall endpoint -void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; - unsigned const epn = tu_edpt_number(ep_addr); - MXC_SYS_Crit_Enter(); - MXC_USBHS->index = epn; - if (0 == epn) { - if (!ep_addr) { /* Ignore EP80 */ - _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; - _dcd.pipe0.buf = NULL; - MXC_USBHS->csr0 = MXC_F_USBHS_CSR0_SEND_STALL; - } - } else { - if (tu_edpt_dir(ep_addr)) { /* IN */ - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_SENDSTALL; - } else { /* OUT */ - TU_ASSERT(!(MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY), ); - MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_SENDSTALL; - } - } - MXC_SYS_Crit_Exit(); -} - -// clear stall, data toggle is also reset to DATA0 -void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; - unsigned const epn = tu_edpt_number(ep_addr); - MXC_SYS_Crit_Enter(); - MXC_USBHS->index = epn; - if (tu_edpt_dir(ep_addr)) { /* IN */ - /* IN endpoint */ - if (MXC_USBHS->incsrl & MXC_F_USBHS_INCSRL_INPKTRDY) { - /* Per musbhsfc_pg, only flush FIFO if IN packet loaded */ - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG | MXC_F_USBHS_INCSRL_FLUSHFIFO; - } else { - MXC_USBHS->incsrl = MXC_F_USBHS_INCSRL_CLRDATATOG; - } - } else { /* OUT */ - /* Otherwise, must be OUT endpoint */ - if (MXC_USBHS->outcsrl & MXC_F_USBHS_OUTCSRL_OUTPKTRDY) { - /* Per musbhsfc_pg, only flush FIFO if OUT packet is ready */ - MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG | MXC_F_USBHS_OUTCSRL_FLUSHFIFO; - } else { - MXC_USBHS->outcsrl = MXC_F_USBHS_OUTCSRL_CLRDATATOG; - } - } - MXC_SYS_Crit_Exit(); -} - -/*------------------------------------------------------------------- - * ISR - *-------------------------------------------------------------------*/ -void dcd_int_handler(uint8_t rhport) { - uint_fast8_t is, txis, rxis; - uint32_t mxm_int, mxm_int_en, mxm_is; - uint32_t saved_index; - - /* Save current index register */ - saved_index = MXC_USBHS->index; - - is = MXC_USBHS->intrusb; /* read and clear interrupt status */ - txis = MXC_USBHS->intrin; /* read and clear interrupt status */ - rxis = MXC_USBHS->introut; /* read and clear interrupt status */ - - /* These USB interrupt flags are W1C. */ - /* Order of volatile accesses must be separated for IAR */ - mxm_int = MXC_USBHS->mxm_int; - mxm_int_en = MXC_USBHS->mxm_int_en; - mxm_is = mxm_int & mxm_int_en; - MXC_USBHS->mxm_int = mxm_is; - - is &= MXC_USBHS->intrusben; /* Clear disabled interrupts */ - - if (mxm_is & MXC_F_USBHS_MXM_INT_NOVBUS) { - dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); - } - if (is & MXC_F_USBHS_INTRUSB_SOF_INT) { - dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); - } - if (is & MXC_F_USBHS_INTRUSB_RESET_INT) { - process_bus_reset(rhport); - } - if (is & MXC_F_USBHS_INTRUSB_RESUME_INT) { - dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); - } - if (is & MXC_F_USBHS_INTRUSB_SUSPEND_INT) { - dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); - } - - txis &= MXC_USBHS->intrinen; /* Clear disabled interrupts */ - if (txis & MXC_F_USBHS_INTRIN_EP0_IN_INT) { - process_ep0(rhport); - txis &= ~TU_BIT(0); - } - while (txis) { - unsigned const num = __builtin_ctz(txis); - process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_IN)); - txis &= ~TU_BIT(num); - } - rxis &= MXC_USBHS->introuten; /* Clear disabled interrupts */ - while (rxis) { - unsigned const num = __builtin_ctz(rxis); - process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_OUT)); - rxis &= ~TU_BIT(num); - } - - /* Restore register index before exiting ISR */ - MXC_USBHS->index = saved_index; -} - -#endif diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index a817c5d6e..ee36656fd 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -2,6 +2,7 @@ * The MIT License (MIT) * * Copyright (c) 2021 Koji KITAYAMA + * Copyright (c) 2024, Brent Kowal (Analog Devices, Inc) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,8 +27,7 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && \ - TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) +#if CFG_TUD_ENABLED #if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) /* GCC warns that an address may be unaligned, even though @@ -35,43 +35,30 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); #endif +#include "musb_type.h" #include "device/dcd.h" -#if TU_CHECK_MCU(OPT_MCU_MSP432E4) - #include "musb_msp432e.h" - -#elif TU_CHECK_MCU(OPT_MCU_TM4C123, OPT_MCU_TM4C129) - #include "musb_tm4c.h" - - // HACK generalize later - #include "musb_type.h" - #define FIFO0_WORD FIFO0 - #define FIFO1_WORD FIFO1 - +// Following symbols must be defined by port header +// - musb_dcd_int_enable/disable/clear/get_enable +// - musb_dcd_int_handler_enter/exit +// - musb_dcd_epn_regs: Get memory mapped struct of end point registers +// - musb_dcd_ep0_regs: Get memory mapped struct of EP0 registers +// - musb_dcd_ctl_regs: Get memory mapped struct of control registers +// - musb_dcd_ep_get_fifo_ptr: Gets the address of the provided EP's FIFO +// - musb_dcd_setup_fifo/reset_fifo: Configuration of the EP's FIFO +#if TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) + #include "musb_ti.h" +#elif TU_CHECK_MCU(OPT_MCU_MAX32690, OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX78002) + #include "musb_max32.h" #else - #error "Unsupported MCUs" + #error "Unsupported MCU" #endif /*------------------------------------------------------------------ * MACRO TYPEDEF CONSTANT ENUM DECLARATION *------------------------------------------------------------------*/ -#define REQUEST_TYPE_INVALID (0xFFu) -typedef struct { - uint_fast16_t beg; /* offset of including first element */ - uint_fast16_t end; /* offset of excluding the last element */ -} free_block_t; - -typedef struct TU_ATTR_PACKED { - uint16_t TXMAXP; - uint8_t TXCSRL; - uint8_t TXCSRH; - uint16_t RXMAXP; - uint8_t RXCSRL; - uint8_t RXCSRH; - uint16_t RXCOUNT; - uint16_t RESERVED[3]; -} hw_endpoint_t; +#define REQUEST_TYPE_INVALID (0xFFu) typedef union { uint8_t u8; @@ -92,7 +79,7 @@ typedef struct uint16_t remaining_ctrl; /* The number of bytes remaining in data stage of control transfer. */ int8_t status_out; pipe_state_t pipe0; - pipe_state_t pipe[2][7]; /* pipe[direction][endpoint number - 1] */ + pipe_state_t pipe[2][TUP_DCD_ENDPOINT_MAX-1]; /* pipe[direction][endpoint number - 1] */ uint16_t pipe_buf_is_fifo[2]; /* Bitmap. Each bit means whether 1:TU_FIFO or 0:POD. */ } dcd_data_t; @@ -102,126 +89,6 @@ typedef struct static dcd_data_t _dcd; -static inline free_block_t *find_containing_block(free_block_t *beg, free_block_t *end, uint_fast16_t addr) -{ - free_block_t *cur = beg; - for (; cur < end && ((addr < cur->beg) || (cur->end <= addr)); ++cur) ; - return cur; -} - -static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_fast16_t addr, uint_fast16_t size) -{ - free_block_t *p = find_containing_block(blks, blks + num, addr); - TU_ASSERT(p != blks + num, -2); - if (p->beg == addr) { - /* Shrink block */ - p->beg = addr + size; - if (p->beg != p->end) return 0; - /* remove block */ - free_block_t *end = blks + num; - while (p + 1 < end) { - *p = *(p + 1); - ++p; - } - return -1; - } else { - /* Split into 2 blocks */ - free_block_t tmp = { - .beg = addr + size, - .end = p->end - }; - p->end = addr; - if (p->beg == p->end) { - if (tmp.beg != tmp.end) { - *p = tmp; - return 0; - } - /* remove block */ - free_block_t *end = blks + num; - while (p + 1 < end) { - *p = *(p + 1); - ++p; - } - return -1; - } - if (tmp.beg == tmp.end) return 0; - blks[num] = tmp; - return 1; - } -} - -static inline unsigned free_block_size(free_block_t const *blk) -{ - return blk->end - blk->beg; -} - -#if 0 -static inline void print_block_list(free_block_t const *blk, unsigned num) -{ - TU_LOG1("*************\r\n"); - for (unsigned i = 0; i < num; ++i) { - TU_LOG1(" Blk%u %u %u\r\n", i, blk->beg, blk->end); - ++blk; - } -} -#else -#define print_block_list(a,b) -#endif - -static unsigned find_free_memory(uint_fast16_t size_in_log2_minus3) -{ - free_block_t free_blocks[2 * (TUP_DCD_ENDPOINT_MAX - 1)]; - unsigned num_blocks = 1; - - /* Initialize free memory block list */ - free_blocks[0].beg = 64 / 8; - free_blocks[0].end = (4 << 10) / 8; /* 4KiB / 8 bytes */ - for (int i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { - uint_fast16_t addr; - int num; - USB0->EPIDX = i; - addr = USB0->TXFIFOADD; - if (addr) { - unsigned sz = USB0->TXFIFOSZ; - unsigned sft = (sz & USB_TXFIFOSZ_SIZE_M) + ((sz & USB_TXFIFOSZ_DPB) ? 1: 0); - num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); - TU_ASSERT(-2 < num, 0); - num_blocks += num; - print_block_list(free_blocks, num_blocks); - } - addr = USB0->RXFIFOADD; - if (addr) { - unsigned sz = USB0->RXFIFOSZ; - unsigned sft = (sz & USB_RXFIFOSZ_SIZE_M) + ((sz & USB_RXFIFOSZ_DPB) ? 1: 0); - num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); - TU_ASSERT(-2 < num, 0); - num_blocks += num; - print_block_list(free_blocks, num_blocks); - } - } - print_block_list(free_blocks, num_blocks); - - /* Find the best fit memory block */ - uint_fast16_t size_in_8byte_unit = 1 << size_in_log2_minus3; - free_block_t const *min = NULL; - uint_fast16_t min_sz = 0xFFFFu; - free_block_t const *end = &free_blocks[num_blocks]; - for (free_block_t const *cur = &free_blocks[0]; cur < end; ++cur) { - uint_fast16_t sz = free_block_size(cur); - if (sz < size_in_8byte_unit) continue; - if (size_in_8byte_unit == sz) return cur->beg; - if (sz < min_sz) min = cur; - } - TU_ASSERT(min, 0); - return min->beg; -} - -static inline volatile hw_endpoint_t* edpt_regs(unsigned epnum_minus1) -{ - volatile hw_endpoint_t *regs = (volatile hw_endpoint_t*)((uintptr_t)&USB0->TXMAXP1); - return regs + epnum_minus1; -} - static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) { volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; @@ -287,8 +154,10 @@ static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigne static void process_setup_packet(uint8_t rhport) { uint32_t *p = (void*)&_dcd.setup_packet; - p[0] = USB0->FIFO0_WORD; - p[1] = USB0->FIFO0_WORD; + volatile uint32_t *fifo_ptr = musb_dcd_ep_get_fifo_ptr(rhport, 0); + volatile musb_dcd_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); + p[0] = *fifo_ptr; + p[1] = *fifo_ptr; _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; @@ -299,12 +168,13 @@ static void process_setup_packet(uint8_t rhport) _dcd.remaining_ctrl = len; const unsigned dir_in = tu_edpt_dir(_dcd.setup_packet.bmRequestType); /* Clear RX FIFO and reverse the transaction direction */ - if (len && dir_in) USB0->CSRL0 = USB_CSRL0_RXRDYC; + if (len && dir_in) ep0_regs->CSRL0 = USB_CSRL0_RXRDYC; } -static bool handle_xfer_in(uint_fast8_t ep_addr) +static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr) { - unsigned epnum_minus1 = tu_edpt_number(ep_addr) - 1; + unsigned epnum = tu_edpt_number(ep_addr); + unsigned epnum_minus1 = epnum - 1; pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; const unsigned rem = pipe->remaining; @@ -313,30 +183,32 @@ static bool handle_xfer_in(uint_fast8_t ep_addr) return true; } - volatile hw_endpoint_t *regs = edpt_regs(epnum_minus1); + volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); const unsigned mps = regs->TXMAXP; const unsigned len = TU_MIN(mps, rem); void *buf = pipe->buf; + volatile void *fifo_ptr = musb_dcd_ep_get_fifo_ptr(rhport, epnum); // 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); + pipe_read_write_packet_ff(buf, fifo_ptr, len, TUSB_DIR_IN); } else { - pipe_write_packet(buf, &USB0->FIFO1_WORD + epnum_minus1, len); + pipe_write_packet(buf, fifo_ptr, len); pipe->buf = buf + len; } pipe->remaining = rem - len; } regs->TXCSRL = USB_TXCSRL1_TXRDY; - // TU_LOG1(" TXCSRL%d = %x %d\r\n", epnum_minus1 + 1, regs->TXCSRL, rem - len); + // TU_LOG1(" TXCSRL%d = %x %d\r\n", epnum, regs->TXCSRL, rem - len); return false; } -static bool handle_xfer_out(uint_fast8_t ep_addr) +static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr) { - unsigned epnum_minus1 = tu_edpt_number(ep_addr) - 1; + unsigned epnum = tu_edpt_number(ep_addr); + unsigned epnum_minus1 = epnum - 1; pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; - volatile hw_endpoint_t *regs = edpt_regs(epnum_minus1); + volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); // TU_LOG1(" RXCSRL%d = %x\r\n", epnum_minus1 + 1, regs->RXCSRL); TU_ASSERT(regs->RXCSRL & USB_RXCSRL1_RXRDY); @@ -346,11 +218,12 @@ static bool handle_xfer_out(uint_fast8_t ep_addr) const unsigned vld = regs->RXCOUNT; const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); void *buf = pipe->buf; + volatile void *fifo_ptr = musb_dcd_ep_get_fifo_ptr(rhport, epnum); if (len) { if (_dcd.pipe_buf_is_fifo[TUSB_DIR_OUT] & TU_BIT(epnum_minus1)) { - pipe_read_write_packet_ff(buf, &USB0->FIFO1_WORD + epnum_minus1, len, TUSB_DIR_OUT); + pipe_read_write_packet_ff(buf, fifo_ptr, len, TUSB_DIR_OUT); } else { - pipe_read_packet(buf, &USB0->FIFO1_WORD + epnum_minus1, len); + pipe_read_packet(buf, fifo_ptr, len); pipe->buf = buf + len; } pipe->remaining = rem - len; @@ -365,9 +238,8 @@ static bool handle_xfer_out(uint_fast8_t ep_addr) static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { - (void)rhport; - - unsigned epnum_minus1 = tu_edpt_number(ep_addr) - 1; + unsigned epnum = tu_edpt_number(ep_addr); + unsigned epnum_minus1 = epnum - 1; unsigned dir_in = tu_edpt_dir(ep_addr); pipe_state_t *pipe = &_dcd.pipe[dir_in][epnum_minus1]; @@ -376,9 +248,9 @@ static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16 pipe->remaining = total_bytes; if (dir_in) { - handle_xfer_in(ep_addr); + handle_xfer_in(rhport, ep_addr); } else { - volatile hw_endpoint_t *regs = edpt_regs(epnum_minus1); + volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); if (regs->RXCSRL & USB_RXCSRL1_RXRDY) regs->RXCSRL = 0; } return true; @@ -388,7 +260,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ { (void)rhport; TU_ASSERT(total_bytes <= 64); /* Current implementation supports for only up to 64 bytes. */ - + volatile musb_dcd_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); const unsigned req = _dcd.setup_packet.bmRequestType; TU_ASSERT(req != REQUEST_TYPE_INVALID || total_bytes == 0); @@ -399,7 +271,7 @@ 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\r\n", USB0->CSRL0); + // TU_LOG1(" STATUS OUT ep0_regs->CSRL0 = %x\r\n", ep0_regs->CSRL0); _dcd.status_out = 0; if (req == REQUEST_TYPE_INVALID) { dcd_event_xfer_complete(rhport, ep_addr, total_bytes, XFER_RESULT_SUCCESS, false); @@ -415,8 +287,9 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ TU_ASSERT(total_bytes <= _dcd.remaining_ctrl); const unsigned rem = _dcd.remaining_ctrl; const unsigned len = TU_MIN(TU_MIN(rem, 64), total_bytes); + volatile void *fifo_ptr = musb_dcd_ep_get_fifo_ptr(rhport, 0); if (dir_in) { - pipe_write_packet(buffer, &USB0->FIFO0_WORD, len); + pipe_write_packet(buffer, fifo_ptr, len); _dcd.pipe0.buf = buffer + len; _dcd.pipe0.length = len; @@ -427,45 +300,46 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; /* Change to STATUS/SETUP stage */ _dcd.status_out = 1; /* Flush TX FIFO and reverse the transaction direction. */ - USB0->CSRL0 = USB_CSRL0_TXRDY | USB_CSRL0_DATAEND; + ep0_regs->CSRL0 = USB_CSRL0_TXRDY | USB_CSRL0_DATAEND; } else { - USB0->CSRL0 = USB_CSRL0_TXRDY; /* Flush TX FIFO to return ACK. */ + ep0_regs->CSRL0 = USB_CSRL0_TXRDY; /* Flush TX FIFO to return ACK. */ } - // TU_LOG1(" IN USB0->CSRL0 = %x\r\n", USB0->CSRL0); + // TU_LOG1(" IN ep0_regs->CSRL0 = %x\r\n", ep0_regs->CSRL0); } else { - // TU_LOG1(" OUT USB0->CSRL0 = %x\r\n", USB0->CSRL0); + // TU_LOG1(" OUT ep0_regs->CSRL0 = %x\r\n", ep0_regs->CSRL0); _dcd.pipe0.buf = buffer; _dcd.pipe0.length = len; _dcd.pipe0.remaining = len; - USB0->CSRL0 = USB_CSRL0_RXRDYC; /* Clear RX FIFO to return ACK. */ + ep0_regs->CSRL0 = USB_CSRL0_RXRDYC; /* Clear RX FIFO to return ACK. */ } } else if (dir_in) { - // TU_LOG1(" STATUS IN USB0->CSRL0 = %x\r\n", USB0->CSRL0); + // TU_LOG1(" STATUS IN ep0_regs->CSRL0 = %x\r\n", ep0_regs->CSRL0); _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; /* Clear RX FIFO and reverse the transaction direction */ - USB0->CSRL0 = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; + ep0_regs->CSRL0 = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; } return true; } static void process_ep0(uint8_t rhport) { - uint_fast8_t csrl = USB0->CSRL0; + volatile musb_dcd_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); + uint_fast8_t csrl = ep0_regs->CSRL0; - // TU_LOG1(" EP0 USB0->CSRL0 = %x\r\n", csrl); + // TU_LOG1(" EP0 ep0_regs->CSRL0 = %x\r\n", csrl); if (csrl & USB_CSRL0_STALLED) { /* Returned STALL packet to HOST. */ - USB0->CSRL0 = 0; /* Clear STALL */ + ep0_regs->CSRL0 = 0; /* Clear STALL */ return; } unsigned req = _dcd.setup_packet.bmRequestType; if (csrl & USB_CSRL0_SETEND) { TU_LOG1(" ABORT by the next packets\r\n"); - USB0->CSRL0 = USB_CSRL0_SETENDC; + ep0_regs->CSRL0 = USB_CSRL0_SETENDC; if (req != REQUEST_TYPE_INVALID && _dcd.pipe0.buf) { /* DATA stage was aborted by receiving STATUS or SETUP packet. */ _dcd.pipe0.buf = NULL; @@ -483,16 +357,17 @@ static void process_ep0(uint8_t rhport) /* Received SETUP or DATA OUT packet */ if (req == REQUEST_TYPE_INVALID) { /* SETUP */ - TU_ASSERT(sizeof(tusb_control_request_t) == USB0->COUNT0,); + TU_ASSERT(sizeof(tusb_control_request_t) == ep0_regs->COUNT0,); process_setup_packet(rhport); return; } if (_dcd.pipe0.buf) { /* DATA OUT */ - const unsigned vld = USB0->COUNT0; + const unsigned vld = ep0_regs->COUNT0; const unsigned rem = _dcd.pipe0.remaining; const unsigned len = TU_MIN(TU_MIN(rem, 64), vld); - pipe_read_packet(_dcd.pipe0.buf, &USB0->FIFO0_WORD, len); + volatile void *fifo_ptr = musb_dcd_ep_get_fifo_ptr(rhport, 0); + pipe_read_packet(_dcd.pipe0.buf, fifo_ptr, len); _dcd.pipe0.remaining = rem - len; _dcd.remaining_ctrl -= len; @@ -506,13 +381,15 @@ static void process_ep0(uint8_t rhport) return; } + volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + /* When CSRL0 is zero, it means that completion of sending a any length packet * or receiving a zero length packet. */ if (req != REQUEST_TYPE_INVALID && !tu_edpt_dir(req)) { /* STATUS IN */ if (*(const uint16_t*)(uintptr_t)&_dcd.setup_packet == 0x0500) { /* The address must be changed on completion of the control transfer. */ - USB0->FADDR = (uint8_t)_dcd.setup_packet.wValue; + ctrl_regs->FADDR = (uint8_t)_dcd.setup_packet.wValue; } _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; dcd_event_xfer_complete(rhport, @@ -535,27 +412,28 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) { bool completed; const unsigned dir_in = tu_edpt_dir(ep_addr); - const unsigned epn_minus1 = tu_edpt_number(ep_addr) - 1; + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned epn_minus1 = epn - 1; - volatile hw_endpoint_t *regs = edpt_regs(epn_minus1); + volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); if (dir_in) { - // TU_LOG1(" TXCSRL%d = %x\r\n", epn_minus1 + 1, regs->TXCSRL); + // TU_LOG1(" TXCSRL%d = %x\r\n", epn, regs->TXCSRL); if (regs->TXCSRL & USB_TXCSRL1_STALLED) { regs->TXCSRL &= ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_UNDRN); return; } - completed = handle_xfer_in(ep_addr); + completed = handle_xfer_in(rhport, ep_addr); } else { - // TU_LOG1(" RXCSRL%d = %x\r\n", epn_minus1 + 1, regs->RXCSRL); + // TU_LOG1(" RXCSRL%d = %x\r\n", epn, regs->RXCSRL); if (regs->RXCSRL & USB_RXCSRL1_STALLED) { regs->RXCSRL &= ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_OVER); return; } - completed = handle_xfer_out(ep_addr); + completed = handle_xfer_out(rhport, ep_addr); } if (completed) { - pipe_state_t *pipe = &_dcd.pipe[dir_in][tu_edpt_number(ep_addr) - 1]; + pipe_state_t *pipe = &_dcd.pipe[dir_in][epn_minus1]; dcd_event_xfer_complete(rhport, ep_addr, pipe->length - pipe->remaining, XFER_RESULT_SUCCESS, true); @@ -564,6 +442,7 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) static void process_bus_reset(uint8_t rhport) { + volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), * a control transfer state is SETUP or STATUS stage. */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; @@ -571,18 +450,15 @@ static void process_bus_reset(uint8_t rhport) /* When pipe0.buf has not NULL, DATA stage works in progress. */ _dcd.pipe0.buf = NULL; - USB0->TXIE = 1; /* Enable only EP0 */ - USB0->RXIE = 0; + ctrl_regs->TXIE = 1; /* Enable only EP0 */ + ctrl_regs->RXIE = 0; /* Clear FIFO settings */ for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { - USB0->EPIDX = i; - USB0->TXFIFOSZ = 0; - USB0->TXFIFOADD = 0; - USB0->RXFIFOSZ = 0; - USB0->RXFIFOADD = 0; + musb_dcd_reset_fifo(rhport, i, 0); + musb_dcd_reset_fifo(rhport, i, 1); } - dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); + dcd_event_bus_reset(rhport, (ctrl_regs->POWER & USB_POWER_HSMODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); } /*------------------------------------------------------------------ @@ -591,61 +467,60 @@ static void process_bus_reset(uint8_t rhport) void dcd_init(uint8_t rhport) { - (void)rhport; - USB0->IE |= USB_IE_SUSPND; - NVIC_ClearPendingIRQ(USB0_IRQn); - + volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + ctrl_regs->IE |= USB_IE_SUSPND; + musb_dcd_int_clear(rhport); + musb_dcd_phy_init(rhport); dcd_connect(rhport); } void dcd_int_enable(uint8_t rhport) { - (void)rhport; - NVIC_EnableIRQ(USB0_IRQn); + musb_dcd_int_enable(rhport); } void dcd_int_disable(uint8_t rhport) { - (void)rhport; - NVIC_DisableIRQ(USB0_IRQn); + musb_dcd_int_disable(rhport); } // Receive Set Address request, mcu port must also include status IN response void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { - (void)rhport; (void)dev_addr; + volatile musb_dcd_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; /* Clear RX FIFO to return ACK. */ - USB0->CSRL0 = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; + ep0_regs->CSRL0 = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; } // Wake up host void dcd_remote_wakeup(uint8_t rhport) { - (void)rhport; - USB0->POWER |= USB_POWER_RESUME; + volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + ctrl_regs->POWER |= USB_POWER_RESUME; unsigned cnt = SystemCoreClock / 1000; while (cnt--) __NOP(); - USB0->POWER &= ~USB_POWER_RESUME; + ctrl_regs->POWER &= ~USB_POWER_RESUME; } // Connect by enabling internal pull-up resistor on D+/D- void dcd_connect(uint8_t rhport) { - (void)rhport; - USB0->POWER |= USB_POWER_SOFTCONN; + volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + ctrl_regs->POWER |= TUD_OPT_HIGH_SPEED ? USB_POWER_HSENAB : 0; + ctrl_regs->POWER |= USB_POWER_SOFTCONN; } // Disconnect by disabling internal pull-up resistor on D+/D- void dcd_disconnect(uint8_t rhport) { - (void)rhport; - USB0->POWER &= ~USB_POWER_SOFTCONN; + volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + ctrl_regs->POWER &= ~USB_POWER_SOFTCONN; } void dcd_sof_enable(uint8_t rhport, bool en) @@ -663,8 +538,6 @@ void dcd_sof_enable(uint8_t rhport, bool en) // Configure endpoint's registers according to descriptor bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { - (void) rhport; - const unsigned ep_addr = ep_desc->bEndpointAddress; const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir_in = tu_edpt_dir(ep_addr); @@ -678,7 +551,8 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) pipe->length = 0; pipe->remaining = 0; - volatile hw_endpoint_t *regs = edpt_regs(epn - 1); + volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); + volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); if (dir_in) { regs->TXMAXP = mps; regs->TXCSRH = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_TXCSRH1_ISO : 0; @@ -686,7 +560,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; else regs->TXCSRL = USB_TXCSRL1_CLRDT; - USB0->TXIE |= TU_BIT(epn); + ctrl_regs->TXIE |= TU_BIT(epn); } else { regs->RXMAXP = mps; regs->RXCSRH = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_RXCSRH1_ISO : 0; @@ -694,36 +568,25 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; else regs->RXCSRL = USB_RXCSRL1_CLRDT; - USB0->RXIE |= TU_BIT(epn); + ctrl_regs->RXIE |= TU_BIT(epn); } /* Setup FIFO */ - int size_in_log2_minus3 = 28 - TU_MIN(28, __CLZ((uint32_t)mps)); - if ((8u << size_in_log2_minus3) < mps) ++size_in_log2_minus3; - unsigned addr = find_free_memory(size_in_log2_minus3); - TU_ASSERT(addr); - - USB0->EPIDX = epn; - if (dir_in) { - USB0->TXFIFOADD = addr; - USB0->TXFIFOSZ = size_in_log2_minus3; - } else { - USB0->RXFIFOADD = addr; - USB0->RXFIFOSZ = size_in_log2_minus3; - } + musb_dcd_setup_fifo(rhport, epn, dir_in, mps); return true; } void dcd_edpt_close_all(uint8_t rhport) { - (void) rhport; - volatile hw_endpoint_t *regs = (volatile hw_endpoint_t *)(uintptr_t)&USB0->TXMAXP1; - unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); - NVIC_DisableIRQ(USB0_IRQn); - USB0->TXIE = 1; /* Enable only EP0 */ - USB0->RXIE = 0; + volatile musb_dcd_epn_regs_t *regs; + volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + unsigned const ie = musb_dcd_get_int_enable(rhport); + musb_dcd_int_disable(rhport); + ctrl_regs->TXIE = 1; /* Enable only EP0 */ + ctrl_regs->RXIE = 0; for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { + regs = musb_dcd_epn_regs(rhport, i); regs->TXMAXP = 0; regs->TXCSRH = 0; if (regs->TXCSRL & USB_TXCSRL1_TXRDY) @@ -738,50 +601,41 @@ void dcd_edpt_close_all(uint8_t rhport) else regs->RXCSRL = USB_RXCSRL1_CLRDT; - USB0->EPIDX = i; - USB0->TXFIFOSZ = 0; - USB0->TXFIFOADD = 0; - USB0->RXFIFOSZ = 0; - USB0->RXFIFOADD = 0; + musb_dcd_reset_fifo(rhport, i, 0); + musb_dcd_reset_fifo(rhport, i, 1); + } - if (ie) NVIC_EnableIRQ(USB0_IRQn); + if (ie) musb_dcd_int_enable(rhport); } void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { - (void)rhport; unsigned const epn = tu_edpt_number(ep_addr); unsigned const dir_in = tu_edpt_dir(ep_addr); - hw_endpoint_t volatile *regs = edpt_regs(epn - 1); - unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); - NVIC_DisableIRQ(USB0_IRQn); + volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); + volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + unsigned const ie = musb_dcd_get_int_enable(rhport); + musb_dcd_int_disable(rhport); if (dir_in) { - USB0->TXIE &= ~TU_BIT(epn); + ctrl_regs->TXIE &= ~TU_BIT(epn); regs->TXMAXP = 0; regs->TXCSRH = 0; if (regs->TXCSRL & USB_TXCSRL1_TXRDY) regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; else regs->TXCSRL = USB_TXCSRL1_CLRDT; - - USB0->EPIDX = epn; - USB0->TXFIFOSZ = 0; - USB0->TXFIFOADD = 0; } else { - USB0->RXIE &= ~TU_BIT(epn); + ctrl_regs->RXIE &= ~TU_BIT(epn); regs->RXMAXP = 0; regs->RXCSRH = 0; if (regs->RXCSRL & USB_RXCSRL1_RXRDY) regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; else regs->RXCSRL = USB_RXCSRL1_CLRDT; - - USB0->EPIDX = epn; - USB0->RXFIFOSZ = 0; - USB0->RXFIFOADD = 0; } - if (ie) NVIC_EnableIRQ(USB0_IRQn); + musb_dcd_reset_fifo(rhport, epn, dir_in); + if (ie) musb_dcd_int_enable(rhport); } // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack @@ -791,14 +645,14 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t bool ret; // 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); + unsigned const ie = musb_dcd_get_int_enable(rhport); + musb_dcd_int_disable(rhport); if (epnum) { _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] &= ~TU_BIT(epnum - 1); ret = edpt_n_xfer(rhport, ep_addr, buffer, total_bytes); } else ret = edpt0_xfer(rhport, ep_addr, buffer, total_bytes); - if (ie) NVIC_EnableIRQ(USB0_IRQn); + if (ie) musb_dcd_int_enable(rhport); return ret; } @@ -810,29 +664,29 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_ // 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); - NVIC_DisableIRQ(USB0_IRQn); + unsigned const ie = musb_dcd_get_int_enable(rhport); + musb_dcd_int_disable(rhport); _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] |= TU_BIT(epnum - 1); ret = edpt_n_xfer(rhport, ep_addr, (uint8_t*)ff, total_bytes); - if (ie) NVIC_EnableIRQ(USB0_IRQn); + if (ie) musb_dcd_int_enable(rhport); return ret; } // Stall endpoint void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { - (void)rhport; unsigned const epn = tu_edpt_number(ep_addr); - unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); - NVIC_DisableIRQ(USB0_IRQn); + unsigned const ie = musb_dcd_get_int_enable(rhport); + musb_dcd_int_disable(rhport); if (0 == epn) { + volatile musb_dcd_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); if (!ep_addr) { /* Ignore EP80 */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; _dcd.pipe0.buf = NULL; - USB0->CSRL0 = USB_CSRL0_STALL; + ep0_regs->CSRL0 = USB_CSRL0_STALL; } } else { - volatile hw_endpoint_t *regs = edpt_regs(epn - 1); + volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); if (tu_edpt_dir(ep_addr)) { /* IN */ regs->TXCSRL = USB_TXCSRL1_STALL; } else { /* OUT */ @@ -840,7 +694,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) regs->RXCSRL = USB_RXCSRL1_STALL; } } - if (ie) NVIC_EnableIRQ(USB0_IRQn); + if (ie) musb_dcd_int_enable(rhport); } // clear stall, data toggle is also reset to DATA0 @@ -848,15 +702,15 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; unsigned const epn = tu_edpt_number(ep_addr); - hw_endpoint_t volatile *regs = edpt_regs(epn - 1); - unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); - NVIC_DisableIRQ(USB0_IRQn); + musb_dcd_epn_regs_t volatile *regs = musb_dcd_epn_regs(rhport, epn); + unsigned const ie = musb_dcd_get_int_enable(rhport); + musb_dcd_int_disable(rhport); if (tu_edpt_dir(ep_addr)) { /* IN */ regs->TXCSRL = USB_TXCSRL1_CLRDT; } else { /* OUT */ regs->RXCSRL = USB_RXCSRL1_CLRDT; } - if (ie) NVIC_EnableIRQ(USB0_IRQn); + if (ie) musb_dcd_int_enable(rhport); } /*------------------------------------------------------------------- @@ -865,13 +719,18 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) void dcd_int_handler(uint8_t rhport) { uint_fast8_t is, txis, rxis; + volatile musb_dcd_ctl_regs_t *ctrl_regs; + + //Part specific ISR setup/entry + musb_dcd_int_handler_enter(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 */ + ctrl_regs = musb_dcd_ctl_regs(rhport); + is = ctrl_regs->IS; /* read and clear interrupt status */ + txis = ctrl_regs->TXIS; /* read and clear interrupt status */ + rxis = ctrl_regs->RXIS; /* read and clear interrupt status */ // TU_LOG1("D%2x T%2x R%2x\r\n", is, txis, rxis); - is &= USB0->IE; /* Clear disabled interrupts */ + is &= ctrl_regs->IE; /* Clear disabled interrupts */ if (is & USB_IS_DISCON) { } if (is & USB_IS_SOF) { @@ -887,7 +746,7 @@ void dcd_int_handler(uint8_t rhport) dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); } - txis &= USB0->TXIE; /* Clear disabled interrupts */ + txis &= ctrl_regs->TXIE; /* Clear disabled interrupts */ if (txis & USB_TXIE_EP0) { process_ep0(rhport); txis &= ~TU_BIT(0); @@ -897,12 +756,15 @@ void dcd_int_handler(uint8_t rhport) process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_IN)); txis &= ~TU_BIT(num); } - rxis &= USB0->RXIE; /* Clear disabled interrupts */ + rxis &= ctrl_regs->RXIE; /* Clear disabled interrupts */ while (rxis) { unsigned const num = __builtin_ctz(rxis); process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_OUT)); rxis &= ~TU_BIT(num); } + + //Part specific ISR exit + musb_dcd_int_handler_exit(rhport); } #endif diff --git a/src/portable/mentor/musb/hcd_musb.c b/src/portable/mentor/musb/hcd_musb.c index 5312c2812..8fc225676 100644 --- a/src/portable/mentor/musb/hcd_musb.c +++ b/src/portable/mentor/musb/hcd_musb.c @@ -37,16 +37,10 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); #include "host/hcd.h" -#if TU_CHECK_MCU(OPT_MCU_MSP432E4) - #include "musb_msp432e.h" - -#elif TU_CHECK_MCU(OPT_MCU_TM4C123, OPT_MCU_TM4C129) - #include "musb_tm4c.h" - - // HACK generalize later - #include "musb_type.h" - #define FIFO0_WORD FIFO0 +#include "musb_type.h" +#if TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) + #include "musb_ti.h" #else #error "Unsupported MCUs" #endif diff --git a/src/portable/mentor/musb/musb_max32.h b/src/portable/mentor/musb/musb_max32.h new file mode 100644 index 000000000..297a695f8 --- /dev/null +++ b/src/portable/mentor/musb/musb_max32.h @@ -0,0 +1,221 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024, Brent Kowal (Analog Devices, Inc) + * + * 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. + */ + +#ifndef _TUSB_MUSB_MAX32_H_ +#define _TUSB_MUSB_MAX32_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#if TU_CHECK_MCU(OPT_MCU_MAX32690, OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX78002) + #include "mxc_device.h" + #include "usbhs_regs.h" +#else + #error "Unsupported MCUs" +#endif + + +#if CFG_TUD_ENABLED +#define USBHS_M31_CLOCK_RECOVERY + +// Mapping of peripheral instances to port. Currently just 1. +static mxc_usbhs_regs_t* const musb_periph_inst[] = { + MXC_USBHS +}; + +// Mapping of IRQ numbers to port. Currently just 1. +static const IRQn_Type musb_irqs[] = { + USB_IRQn +}; + +TU_ATTR_ALWAYS_INLINE +static inline void musb_dcd_int_enable(uint8_t rhport) +{ + NVIC_EnableIRQ(musb_irqs[rhport]); +} + +TU_ATTR_ALWAYS_INLINE +static inline void musb_dcd_int_disable(uint8_t rhport) +{ + NVIC_DisableIRQ(musb_irqs[rhport]); +} + +TU_ATTR_ALWAYS_INLINE +static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) +{ + return NVIC_GetEnableIRQ(musb_irqs[rhport]); +} + +TU_ATTR_ALWAYS_INLINE +static inline void musb_dcd_int_clear(uint8_t rhport) +{ + NVIC_ClearPendingIRQ(musb_irqs[rhport]); +} + +//Used to save and restore user's register map when interrupt occurs +static volatile unsigned isr_saved_index = 0; + +static inline void musb_dcd_int_handler_enter(uint8_t rhport) +{ + uint32_t mxm_int, mxm_int_en, mxm_is; + + //save current register index + isr_saved_index = musb_periph_inst[rhport]->index; + + //Handle PHY specific events + mxm_int = musb_periph_inst[rhport]->mxm_int; + mxm_int_en = musb_periph_inst[rhport]->mxm_int_en; + mxm_is = mxm_int & mxm_int_en; + musb_periph_inst[rhport]->mxm_int = mxm_is; + + if (mxm_is & MXC_F_USBHS_MXM_INT_NOVBUS) { + dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); + } +} + +static inline void musb_dcd_int_handler_exit(uint8_t rhport) +{ + //restore register index + musb_periph_inst[rhport]->index = isr_saved_index; +} + +static inline void musb_dcd_phy_init(uint8_t rhport) +{ + //Interrupt for VBUS disconnect + musb_periph_inst[rhport]->mxm_int_en |= MXC_F_USBHS_MXM_INT_EN_NOVBUS; + + musb_dcd_int_clear(rhport); + + //Unsuspend the MAC + musb_periph_inst[rhport]->mxm_suspend = 0; + + // Configure PHY + musb_periph_inst[rhport]->m31_phy_xcfgi_31_0 = (0x1 << 3) | (0x1 << 11); + musb_periph_inst[rhport]->m31_phy_xcfgi_63_32 = 0; + musb_periph_inst[rhport]->m31_phy_xcfgi_95_64 = 0x1 << (72 - 64); + musb_periph_inst[rhport]->m31_phy_xcfgi_127_96 = 0; + + + #ifdef USBHS_M31_CLOCK_RECOVERY + musb_periph_inst[rhport]->m31_phy_noncry_rstb = 1; + musb_periph_inst[rhport]->m31_phy_noncry_en = 1; + musb_periph_inst[rhport]->m31_phy_outclksel = 0; + musb_periph_inst[rhport]->m31_phy_coreclkin = 0; + musb_periph_inst[rhport]->m31_phy_xtlsel = 2; /* Select 25 MHz clock */ + #else + musb_periph_inst[rhport]->m31_phy_noncry_rstb = 0; + musb_periph_inst[rhport]->m31_phy_noncry_en = 0; + musb_periph_inst[rhport]->m31_phy_outclksel = 1; + musb_periph_inst[rhport]->m31_phy_coreclkin = 1; + musb_periph_inst[rhport]->m31_phy_xtlsel = 3; /* Select 30 MHz clock */ + #endif + musb_periph_inst[rhport]->m31_phy_pll_en = 1; + musb_periph_inst[rhport]->m31_phy_oscouten = 1; + + /* Reset PHY */ + musb_periph_inst[rhport]->m31_phy_ponrst = 0; + musb_periph_inst[rhport]->m31_phy_ponrst = 1; +} + +static inline volatile musb_dcd_ctl_regs_t* musb_dcd_ctl_regs(uint8_t rhport) +{ + volatile musb_dcd_ctl_regs_t *regs = (volatile musb_dcd_ctl_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->faddr)); + return regs; +} + +static inline volatile musb_dcd_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) +{ + //Need to set index to map EP registers + musb_periph_inst[rhport]->index = epnum; + volatile musb_dcd_epn_regs_t *regs = (volatile musb_dcd_epn_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->inmaxp)); + return regs; +} + +static inline volatile musb_dcd_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) +{ + //Need to set index to map EP0 registers + musb_periph_inst[rhport]->index = 0; + volatile musb_dcd_ep0_regs_t *regs = (volatile musb_dcd_ep0_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->csr0)); + return regs; +} + +static volatile void *musb_dcd_ep_get_fifo_ptr(uint8_t rhport, unsigned epnum) +{ + volatile uint32_t *ptr; + + ptr = &(musb_periph_inst[rhport]->fifo0); + ptr += epnum; + + return (volatile void *) ptr; +} + + +static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) +{ + (void)mps; + + //Most likely the caller has already grabbed the right register block. But + //as a precaution save and restore the register bank anyways + unsigned saved_index = musb_periph_inst[rhport]->index; + + musb_periph_inst[rhport]->index = epnum; + + //Disable double buffering + if(dir_in) { + musb_periph_inst[rhport]->incsru |= (MXC_F_USBHS_INCSRU_DPKTBUFDIS | MXC_F_USBHS_INCSRU_MODE); + } else { + musb_periph_inst[rhport]->outcsru |= (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS); + } + + musb_periph_inst[rhport]->index = saved_index; +} + +static inline void musb_dcd_reset_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in) +{ + //Most likely the caller has already grabbed the right register block. But + //as a precaution save and restore the register bank anyways + unsigned saved_index = musb_periph_inst[rhport]->index; + + musb_periph_inst[rhport]->index = epnum; + + //Disable double buffering + if(dir_in) { + musb_periph_inst[rhport]->incsru |= (MXC_F_USBHS_INCSRU_DPKTBUFDIS); + } else { + musb_periph_inst[rhport]->outcsru |= (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS); + } + + musb_periph_inst[rhport]->index = saved_index; +} + +#endif // CFG_TUD_ENABLED + +#ifdef __cplusplus + } +#endif + +#endif // _TUSB_MUSB_MAX32_H_ diff --git a/src/portable/mentor/musb/musb_msp432e.h b/src/portable/mentor/musb/musb_msp432e.h deleted file mode 100644 index fce21de88..000000000 --- a/src/portable/mentor/musb/musb_msp432e.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2021, 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. - */ - -#ifndef _TUSB_MUSB_MSP432E_H_ -#define _TUSB_MUSB_MSP432E_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#include "msp.h" - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h new file mode 100644 index 000000000..dbf82f391 --- /dev/null +++ b/src/portable/mentor/musb/musb_ti.h @@ -0,0 +1,285 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024, Brent Kowal (Analog Devices, Inc) + * + * 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. + */ + +#ifndef _TUSB_MUSB_TI_H_ +#define _TUSB_MUSB_TI_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#if CFG_TUSB_MCU == OPT_MCU_TM4C123 + #include "TM4C123.h" + #define FIFO0_WORD FIFO0 + #define FIFO1_WORD FIFO1 +//#elif CFG_TUSB_MCU == OPT_MCU_TM4C129 +#elif CFG_TUSB_MCU == OPT_MCU_MSP432E4 + #include "msp.h" +#else + #error "Unsupported MCUs" +#endif + + +// Header supports both device and host modes. Only include whats necessary +#if CFG_TUD_ENABLED + +// Mapping of peripheral instances to port. Currently just 1. +static USB0_Type* const musb_periph_inst[] = { + USB0 +}; + +// Mapping of IRQ numbers to port. Currently just 1. +static const IRQn_Type musb_irqs[] = { + USB0_IRQn +}; + +static inline void musb_dcd_phy_init(uint8_t rhport){ + (void)rhport; + //Nothing to do for this part +} + +TU_ATTR_ALWAYS_INLINE +static inline void musb_dcd_int_enable(uint8_t rhport) +{ + NVIC_EnableIRQ(musb_irqs[rhport]); +} + +TU_ATTR_ALWAYS_INLINE +static inline void musb_dcd_int_disable(uint8_t rhport) +{ + NVIC_DisableIRQ(musb_irqs[rhport]); +} + +TU_ATTR_ALWAYS_INLINE +static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) +{ + return NVIC_GetEnableIRQ(musb_irqs[rhport]); +} + +TU_ATTR_ALWAYS_INLINE +static inline void musb_dcd_int_clear(uint8_t rhport) +{ + NVIC_ClearPendingIRQ(musb_irqs[rhport]); +} + +static inline void musb_dcd_int_handler_enter(uint8_t rhport){ + (void)rhport; + //Nothing to do for this part +} + +static inline void musb_dcd_int_handler_exit(uint8_t rhport){ + (void)rhport; + //Nothing to do for this part +} + +static inline volatile musb_dcd_ctl_regs_t* musb_dcd_ctl_regs(uint8_t rhport) +{ + volatile musb_dcd_ctl_regs_t *regs = (volatile musb_dcd_ctl_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->FADDR)); + return regs; +} + +static inline volatile musb_dcd_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) +{ + uintptr_t baseptr = (uintptr_t)&(musb_periph_inst[rhport]->TXMAXP1); + + //On the TI parts, the epn registers are 16-bytes apart. The core regs defined + //by musb_dcd_epn_regs and 6 reserved/other use bytes + volatile musb_dcd_epn_regs_t *regs = (volatile musb_dcd_epn_regs_t*)(baseptr + ((epnum - 1)*16)); + return regs; +} + +static inline volatile musb_dcd_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) +{ + volatile musb_dcd_ep0_regs_t *regs = (volatile musb_dcd_ep0_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->CSRL0)); + return regs; +} + +static volatile void *musb_dcd_ep_get_fifo_ptr(uint8_t rhport, unsigned epnum) +{ + if(epnum){ + return (volatile void *)(&(musb_periph_inst[rhport]->FIFO1_WORD) + (epnum - 1)); + } else { + return (volatile void *)&(musb_periph_inst[rhport]->FIFO0_WORD); + } +} + + +typedef struct { + uint_fast16_t beg; /* offset of including first element */ + uint_fast16_t end; /* offset of excluding the last element */ +} free_block_t; + +static inline free_block_t *find_containing_block(free_block_t *beg, free_block_t *end, uint_fast16_t addr) +{ + free_block_t *cur = beg; + for (; cur < end && ((addr < cur->beg) || (cur->end <= addr)); ++cur) ; + return cur; +} + +static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_fast16_t addr, uint_fast16_t size) +{ + free_block_t *p = find_containing_block(blks, blks + num, addr); + TU_ASSERT(p != blks + num, -2); + if (p->beg == addr) { + /* Shrink block */ + p->beg = addr + size; + if (p->beg != p->end) return 0; + /* remove block */ + free_block_t *end = blks + num; + while (p + 1 < end) { + *p = *(p + 1); + ++p; + } + return -1; + } else { + /* Split into 2 blocks */ + free_block_t tmp = { + .beg = addr + size, + .end = p->end + }; + p->end = addr; + if (p->beg == p->end) { + if (tmp.beg != tmp.end) { + *p = tmp; + return 0; + } + /* remove block */ + free_block_t *end = blks + num; + while (p + 1 < end) { + *p = *(p + 1); + ++p; + } + return -1; + } + if (tmp.beg == tmp.end) return 0; + blks[num] = tmp; + return 1; + } +} + +static inline unsigned free_block_size(free_block_t const *blk) +{ + return blk->end - blk->beg; +} + +#if 0 +static inline void print_block_list(free_block_t const *blk, unsigned num) +{ + TU_LOG1("*************\r\n"); + for (unsigned i = 0; i < num; ++i) { + TU_LOG1(" Blk%u %u %u\r\n", i, blk->beg, blk->end); + ++blk; + } +} +#else +#define print_block_list(a,b) +#endif + +static unsigned find_free_memory(uint8_t rhport, uint_fast16_t size_in_log2_minus3) +{ + free_block_t free_blocks[2 * (TUP_DCD_ENDPOINT_MAX - 1)]; + unsigned num_blocks = 1; + + /* Initialize free memory block list */ + free_blocks[0].beg = 64 / 8; + free_blocks[0].end = (4 << 10) / 8; /* 4KiB / 8 bytes */ + for (int i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { + uint_fast16_t addr; + int num; + musb_periph_inst[rhport]->EPIDX = i; + addr = musb_periph_inst[rhport]->TXFIFOADD; + if (addr) { + unsigned sz = musb_periph_inst[rhport]->TXFIFOSZ; + unsigned sft = (sz & USB_TXFIFOSZ_SIZE_M) + ((sz & USB_TXFIFOSZ_DPB) ? 1: 0); + num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); + TU_ASSERT(-2 < num, 0); + num_blocks += num; + print_block_list(free_blocks, num_blocks); + } + addr = musb_periph_inst[rhport]->RXFIFOADD; + if (addr) { + unsigned sz = musb_periph_inst[rhport]->RXFIFOSZ; + unsigned sft = (sz & USB_RXFIFOSZ_SIZE_M) + ((sz & USB_RXFIFOSZ_DPB) ? 1: 0); + num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); + TU_ASSERT(-2 < num, 0); + num_blocks += num; + print_block_list(free_blocks, num_blocks); + } + } + print_block_list(free_blocks, num_blocks); + + /* Find the best fit memory block */ + uint_fast16_t size_in_8byte_unit = 1 << size_in_log2_minus3; + free_block_t const *min = NULL; + uint_fast16_t min_sz = 0xFFFFu; + free_block_t const *end = &free_blocks[num_blocks]; + for (free_block_t const *cur = &free_blocks[0]; cur < end; ++cur) { + uint_fast16_t sz = free_block_size(cur); + if (sz < size_in_8byte_unit) continue; + if (size_in_8byte_unit == sz) return cur->beg; + if (sz < min_sz) min = cur; + } + TU_ASSERT(min, 0); + return min->beg; +} + + +static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) +{ + int size_in_log2_minus3 = 28 - TU_MIN(28, __CLZ((uint32_t)mps)); + if ((8u << size_in_log2_minus3) < mps) ++size_in_log2_minus3; + unsigned addr = find_free_memory(rhport, size_in_log2_minus3); + TU_ASSERT(addr,); + + musb_periph_inst[rhport]->EPIDX = epnum; + if (dir_in) { + musb_periph_inst[rhport]->TXFIFOADD = addr; + musb_periph_inst[rhport]->TXFIFOSZ = size_in_log2_minus3; + } else { + musb_periph_inst[rhport]->RXFIFOADD = addr; + musb_periph_inst[rhport]->RXFIFOSZ = size_in_log2_minus3; + } +} + +static inline void musb_dcd_reset_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in) +{ + musb_periph_inst[rhport]->EPIDX = epnum; + if (dir_in) { + musb_periph_inst[rhport]->TXFIFOADD = 0; + musb_periph_inst[rhport]->TXFIFOSZ = 0; + } else { + musb_periph_inst[rhport]->RXFIFOADD = 0; + musb_periph_inst[rhport]->RXFIFOSZ = 0; + } +} + +#endif // CFG_TUD_ENABLED + +#ifdef __cplusplus + } +#endif + +#endif // _TUSB_MUSB_TI_H_ diff --git a/src/portable/mentor/musb/musb_tm4c.h b/src/portable/mentor/musb/musb_tm4c.h deleted file mode 100644 index 65a1751b0..000000000 --- a/src/portable/mentor/musb/musb_tm4c.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2021, 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. - */ - -#ifndef _TUSB_MUSB_TM4C_H_ -#define _TUSB_MUSB_TM4C_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#if CFG_TUSB_MCU == OPT_MCU_TM4C123 - #include "TM4C123.h" -//#elif CFG_TUSB_MCU == OPT_MCU_TM4C129 -#else - #error "Unsupported MCUs" -#endif - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index 8f83305a5..e8af8f19b 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -35,10 +35,43 @@ #ifndef _TUSB_MUSB_TYPE_H_ #define _TUSB_MUSB_TYPE_H_ +#include "stdint.h" + #ifdef __cplusplus extern "C" { #endif +// Endpoint register mapping. Non-zero end points. +typedef struct TU_ATTR_PACKED { + uint16_t TXMAXP; + uint8_t TXCSRL; + uint8_t TXCSRH; + uint16_t RXMAXP; + uint8_t RXCSRL; + uint8_t RXCSRH; + uint16_t RXCOUNT; +} musb_dcd_epn_regs_t; + +// Endpoint 0 register mapping. +typedef struct TU_ATTR_PACKED { + uint8_t CSRL0; + uint8_t CSRH0; + uint32_t RESERVED; + uint8_t COUNT0; +} musb_dcd_ep0_regs_t; + +// Control register mapping +typedef struct TU_ATTR_PACKED { + uint8_t FADDR; + uint8_t POWER; + uint16_t TXIS; + uint16_t RXIS; + uint16_t TXIE; + uint16_t RXIE; + uint8_t IS; + uint8_t IE; +} musb_dcd_ctl_regs_t; + //***************************************************************************** // // The following are defines for the bit fields in the USB_O_FADDR register. -- cgit v1.3.1 From 3b8f9a2b1f43a8353c1556e30a61dd0c2416c57f Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 25 Jul 2024 23:51:20 +0700 Subject: refactor btable tx/rx into arr[2] --- src/portable/st/stm32_fsdev/fsdev_common.h | 95 ++++++++++++++++-------------- 1 file changed, 51 insertions(+), 44 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index d0f928552..7d1f7fd90 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -69,17 +69,18 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 b // 16-bit or 32-bit depending on FSDEV_BUS_32BIT. typedef struct { union { + // 0: tx, 1: rx + + // strictly 16-bit access (could be 32-bit aligned) struct { - volatile pma_aligned uint16_t tx_addr; - volatile pma_aligned uint16_t tx_count; - volatile pma_aligned uint16_t rx_addr; - volatile pma_aligned uint16_t rx_count; - } ep16[FSDEV_EP_COUNT]; + volatile pma_aligned uint16_t addr; + volatile pma_aligned uint16_t count; + } ep16[FSDEV_EP_COUNT][2]; + // strictly 32-bit access struct { - volatile uint32_t tx_count_addr; - volatile uint32_t rx_count_addr; - } ep32[FSDEV_EP_COUNT]; + volatile uint32_t count_addr; + } ep32[FSDEV_EP_COUNT][2]; }; } fsdev_btable_t; @@ -204,6 +205,24 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, pcd_set_endpoint(USBx, bEpIdx,regVal); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_count(uint32_t ep_id, uint8_t is_rx) { + uint16_t count; +#ifdef FSDEV_BUS_32BIT + count = (FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr >> 16); +#else + count = FSDEV_BTABLE->ep16[ep_id][is_rx].count; +#endif + return count & 0x3FFU; +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uint8_t is_rx) { +#ifdef FSDEV_BUS_32BIT + return FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr & 0x0000FFFFu; +#else + return FSDEV_BTABLE->ep16[ep_id][is_rx].addr; +#endif +} + /** * @brief gets counter of the tx buffer. * @param USBx USB peripheral instance register address. @@ -212,26 +231,12 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, */ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { (void) USBx; - uint16_t count; -#ifdef FSDEV_BUS_32BIT - count = (FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr >> 16); -#else - count = FSDEV_BTABLE->ep16[bEpIdx].tx_count; -#endif - - return count & 0x3FFU; + return btable_get_count(bEpIdx, 0); } TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { (void) USBx; - uint16_t count; -#ifdef FSDEV_BUS_32BIT - count = (FSDEV_BTABLE->ep32[bEpIdx].rx_count_addr >> 16); -#else - count = FSDEV_BTABLE->ep16[bEpIdx].rx_count; -#endif - - return count & 0x3FFU; + return btable_get_count(bEpIdx, 1); } #define pcd_get_ep_dbuf0_cnt pcd_get_ep_tx_cnt @@ -239,44 +244,46 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USB TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { (void) USBx; -#ifdef FSDEV_BUS_32BIT - return FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr & 0x0000FFFFu; -#else - return FSDEV_BTABLE->ep16[bEpIdx].tx_addr; -#endif + return btable_get_addr(bEpIdx, 0); } TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { (void) USBx; -#ifdef FSDEV_BUS_32BIT - return FSDEV_BTABLE->ep32[bEpIdx].rx_count_addr & 0x0000FFFFu; -#else - return FSDEV_BTABLE->ep16[bEpIdx].rx_addr; -#endif + return btable_get_addr(bEpIdx, 1); } #define pcd_get_ep_dbuf0_address pcd_get_ep_tx_address #define pcd_get_ep_dbuf1_address pcd_get_ep_rx_address + +//TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_set_addr(uint32_t ep_id, uint8_t is_rx, uint16_t addr) { +// +//} +// +//TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_set_count(uint32_t ep_id, uint8_t is_rx, uint16_t count) { +// +//} + + TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { (void) USBx; #ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr; + uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx][0].count_addr; count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); - FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr = count_addr; + FSDEV_BTABLE->ep32[bEpIdx][0].count_addr = count_addr; #else - FSDEV_BTABLE->ep16[bEpIdx].tx_addr = addr; + FSDEV_BTABLE->ep16[bEpIdx][0].addr = addr; #endif } TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { (void) USBx; #ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx].rx_count_addr; + uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx][1].count_addr; count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); - FSDEV_BTABLE->ep32[bEpIdx].rx_count_addr = count_addr; + FSDEV_BTABLE->ep32[bEpIdx][1].count_addr = count_addr; #else - FSDEV_BTABLE->ep16[bEpIdx].rx_addr = addr; + FSDEV_BTABLE->ep16[bEpIdx][1].addr = addr; #endif } @@ -286,13 +293,13 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USB TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { (void) USBx; #ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr; + uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx][0].count_addr; count_addr = (count_addr & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16); - FSDEV_BTABLE->ep32[bEpIdx].tx_count_addr = count_addr; + FSDEV_BTABLE->ep32[bEpIdx][0].count_addr = count_addr; #else - uint16_t count = FSDEV_BTABLE->ep16[bEpIdx].tx_count; + uint16_t count = FSDEV_BTABLE->ep16[bEpIdx][0].count; count = (count & ~0x3FFU) | (wCount & 0x3FFU); - FSDEV_BTABLE->ep16[bEpIdx].tx_count = count; + FSDEV_BTABLE->ep16[bEpIdx][0].count = count; #endif } -- cgit v1.3.1 From 75d3a3be84fa50abd5519e1879aa5dafc4a5c37d Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 26 Jul 2024 00:02:06 +0700 Subject: implement btable_set_addr/count --- src/portable/st/stm32_fsdev/fsdev_common.h | 51 +++++++++++++----------------- 1 file changed, 22 insertions(+), 29 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 7d1f7fd90..58a9ed96d 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -256,51 +256,44 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * #define pcd_get_ep_dbuf1_address pcd_get_ep_rx_address -//TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_set_addr(uint32_t ep_id, uint8_t is_rx, uint16_t addr) { -// -//} -// -//TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_set_count(uint32_t ep_id, uint8_t is_rx, uint16_t count) { -// -//} - - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { - (void) USBx; +TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t is_rx, uint16_t addr) { #ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx][0].count_addr; + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr; count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); - FSDEV_BTABLE->ep32[bEpIdx][0].count_addr = count_addr; + FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr = count_addr; #else - FSDEV_BTABLE->ep16[bEpIdx][0].addr = addr; + FSDEV_BTABLE->ep16[ep_id][is_rx].addr = addr; #endif } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { - (void) USBx; +TU_ATTR_ALWAYS_INLINE static inline void btable_set_count(uint32_t ep_id, uint8_t is_rx, uint16_t byte_count) { #ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx][1].count_addr; - count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); - FSDEV_BTABLE->ep32[bEpIdx][1].count_addr = count_addr; + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr; + count_addr = (count_addr & ~0x03FF0000u) | ((byte_count & 0x3FFu) << 16); + FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr = count_addr; #else - FSDEV_BTABLE->ep16[bEpIdx][1].addr = addr; + uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][is_rx].count; + cnt = (cnt & ~0x3FFU) | (byte_count & 0x3FFU); + FSDEV_BTABLE->ep16[ep_id][is_rx].count = cnt; #endif } +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { + (void) USBx; + btable_set_addr(bEpIdx, 0, addr); +} + +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { + (void) USBx; + btable_set_addr(bEpIdx, 1, addr); +} + #define pcd_set_ep_dbuf0_address pcd_set_ep_tx_address #define pcd_set_ep_dbuf1_address pcd_set_ep_rx_address TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { (void) USBx; -#ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[bEpIdx][0].count_addr; - count_addr = (count_addr & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16); - FSDEV_BTABLE->ep32[bEpIdx][0].count_addr = count_addr; -#else - uint16_t count = FSDEV_BTABLE->ep16[bEpIdx][0].count; - count = (count & ~0x3FFU) | (wCount & 0x3FFU); - FSDEV_BTABLE->ep16[bEpIdx][0].count = count; -#endif + btable_set_count(bEpIdx, 0, wCount); } #define pcd_set_ep_tx_dbuf0_cnt pcd_set_ep_tx_cnt -- cgit v1.3.1 From 6771ef35d9fd61bcddb305dedef7d9f4addf86a5 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 30 Jul 2024 11:17:55 +0700 Subject: more btable set/get clean up --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 54 +++++++++------------------ src/portable/st/stm32_fsdev/fsdev_common.h | 24 +----------- 2 files changed, 19 insertions(+), 59 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 927ecac85..fc1627a1c 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -320,12 +320,8 @@ static void dcd_ep_ctr_tx_handler(uint32_t wIstr) { return; } xfer->iso_in_sending = false; - - if (wEPRegVal & USB_EP_DTOG_TX) { - pcd_set_ep_tx_dbuf0_cnt(USB, EPindex, 0); - } else { - pcd_set_ep_tx_dbuf1_cnt(USB, EPindex, 0); - } + uint8_t buf_id = (wEPRegVal & USB_EP_DTOG_TX) ? 0 : 1; + btable_set_count(EPindex, buf_id, 0); } if ((xfer->total_len != xfer->queued_len)) { @@ -406,21 +402,16 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) if (ep_addr != 0u) { pcd_clear_rx_ep_ctr(USB, EPindex); } - uint32_t count; - uint16_t addr; - /* Read from correct register when ISOCHRONOUS (double buffered) */ + + uint8_t buf_id; if ((wEPRegVal & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { - if (wEPRegVal & USB_EP_DTOG_RX) { - count = pcd_get_ep_dbuf0_cnt(USB, EPindex); - addr = pcd_get_ep_dbuf0_address(USB, EPindex); - } else { - count = pcd_get_ep_dbuf1_cnt(USB, EPindex); - addr = pcd_get_ep_dbuf1_address(USB, EPindex); - } + // ISO endpoints are double buffered + buf_id = (wEPRegVal & USB_EP_DTOG_RX) ? 0 : 1; } else { - count = pcd_get_ep_rx_cnt(USB, EPindex); - addr = pcd_get_ep_rx_address(USB, EPindex); + buf_id = 1; } + uint32_t count = btable_get_count(EPindex, buf_id); + uint16_t addr = (uint16_t) btable_get_addr(EPindex, buf_id); TU_ASSERT(count <= xfer->max_packet_size, /**/); @@ -630,7 +621,6 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { uint8_t const dir = tu_edpt_dir(ep_addr); const uint16_t packet_size = tu_edpt_packet_size(desc_ep); const uint16_t buffer_size = pcd_aligned_buffer_size(packet_size); - uint16_t pma_addr; uint32_t wType; TU_ASSERT(ep_idx < FSDEV_EP_COUNT); @@ -658,7 +648,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { pcd_set_ep_address(USB, ep_idx, tu_edpt_number(ep_addr)); /* Create a packet memory buffer area. */ - pma_addr = dcd_pma_alloc(buffer_size, false); + uint16_t pma_addr = dcd_pma_alloc(buffer_size, false); if (dir == TUSB_DIR_IN) { pcd_set_ep_tx_address(USB, ep_idx, pma_addr); @@ -732,11 +722,9 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet uint32_t pma_addr = dcd_pma_alloc(buffer_size, true); uint16_t pma_addr2 = pma_addr; #endif - pcd_set_ep_tx_address(USB, ep_idx, pma_addr); - pcd_set_ep_rx_address(USB, ep_idx, pma_addr2); - + btable_set_addr(ep_idx, 0, pma_addr); + btable_set_addr(ep_idx, 1, pma_addr2); pcd_set_eptype(USB, ep_idx, USB_EP_ISOCHRONOUS); - xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; return true; @@ -770,8 +758,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoin } // Currently, single-buffered, and only 64 bytes at a time (max) -static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) -{ +static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { uint16_t len = (uint16_t)(xfer->total_len - xfer->queued_len); if (len > xfer->max_packet_size) { len = xfer->max_packet_size; @@ -779,20 +766,15 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) uint16_t ep_reg = pcd_get_endpoint(USB, ep_ix); bool const is_iso = (ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; - uint16_t addr_ptr; + uint8_t buf_id; if (is_iso) { - if (ep_reg & USB_EP_DTOG_TX) { - addr_ptr = pcd_get_ep_dbuf1_address(USB, ep_ix); - pcd_set_ep_tx_dbuf1_cnt(USB, ep_ix, len); - } else { - addr_ptr = pcd_get_ep_dbuf0_address(USB, ep_ix); - pcd_set_ep_tx_dbuf0_cnt(USB, ep_ix, len); - } + buf_id = (ep_reg & USB_EP_DTOG_TX) ? 1 : 0; } else { - addr_ptr = pcd_get_ep_tx_address(USB, ep_ix); - pcd_set_ep_tx_cnt(USB, ep_ix, len); + buf_id = 0; } + uint16_t addr_ptr = (uint16_t) btable_get_addr(ep_ix, buf_id); + btable_set_count(ep_ix, buf_id, len); if (xfer->ff) { dcd_write_packet_memory_ff(xfer->ff, addr_ptr, len); diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 58a9ed96d..72db609cb 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -69,7 +69,7 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 b // 16-bit or 32-bit depending on FSDEV_BUS_32BIT. typedef struct { union { - // 0: tx, 1: rx + // 0: TX (IN), 1: RX (OUT) // strictly 16-bit access (could be 32-bit aligned) struct { @@ -239,9 +239,6 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USB return btable_get_count(bEpIdx, 1); } -#define pcd_get_ep_dbuf0_cnt pcd_get_ep_tx_cnt -#define pcd_get_ep_dbuf1_cnt pcd_get_ep_rx_cnt - TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { (void) USBx; return btable_get_addr(bEpIdx, 0); @@ -252,10 +249,6 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * return btable_get_addr(bEpIdx, 1); } -#define pcd_get_ep_dbuf0_address pcd_get_ep_tx_address -#define pcd_get_ep_dbuf1_address pcd_get_ep_rx_address - - TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t is_rx, uint16_t addr) { #ifdef FSDEV_BUS_32BIT uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr; @@ -288,26 +281,11 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USB btable_set_addr(bEpIdx, 1, addr); } -#define pcd_set_ep_dbuf0_address pcd_set_ep_tx_address -#define pcd_set_ep_dbuf1_address pcd_set_ep_rx_address - TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { (void) USBx; btable_set_count(bEpIdx, 0, wCount); } -#define pcd_set_ep_tx_dbuf0_cnt pcd_set_ep_tx_cnt - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_dbuf1_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { -#ifdef FSDEV_BUS_32BIT - (void) USBx; - pma32[2*bEpIdx + 1] = (pma32[2*bEpIdx + 1] & ~0x03FF0000u) | ((wCount & 0x3FFu) << 16); -#else - volatile uint16_t * reg = pcd_ep_rx_cnt_ptr(USBx, bEpIdx); - *reg = (uint16_t) (*reg & (uint16_t) ~0x3FFU) | (wCount & 0x3FFU); -#endif -} - TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_blsize_num_blocks(USB_TypeDef * USBx, uint32_t rxtx_idx, uint32_t blocksize, uint32_t numblocks) { /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ -- cgit v1.3.1 From 749f0921745ffe3647e6955b41b15e9643f3f3c4 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 30 Jul 2024 12:46:09 +0700 Subject: refactor btable_set_rx_bufsize() --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 23 ++--- src/portable/st/stm32_fsdev/fsdev_common.h | 122 ++++++-------------------- 2 files changed, 41 insertions(+), 104 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index fc1627a1c..cd00e6395 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -370,7 +370,7 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) if (wEPRegVal & USB_EP_SETUP) { /* Setup packet */ - uint32_t count = pcd_get_ep_rx_cnt(USB, EPindex); + uint32_t count = btable_get_count(EPindex, BTABLE_BUF_RX); // Setup packet should always be 8 bytes. If not, ignore it, and try again. if (count == 8) { // Must reset EP to NAK (in case it had been stalling) @@ -387,13 +387,14 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) pcd_rx_dtog(USB, 0); } + uint16_t rx_addr = btable_get_addr(EPindex, BTABLE_BUF_RX); #ifdef FSDEV_BUS_32BIT - dcd_event_setup_received(0, (uint8_t *)(USB_PMAADDR + pcd_get_ep_rx_address(USB, EPindex)), true); + dcd_event_setup_received(0, (uint8_t *)(USB_PMAADDR + rx_addr), true); #else // The setup_received function uses memcpy, so this must first copy the setup data into // user memory, to allow for the 32-bit access that memcpy performs. uint8_t userMemBuf[8]; - dcd_read_packet_memory(userMemBuf, pcd_get_ep_rx_address(USB, EPindex), 8); + dcd_read_packet_memory(userMemBuf, rx_addr, 8); dcd_event_setup_received(0, (uint8_t*) userMemBuf, true); #endif } @@ -434,7 +435,7 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) if ((wEPRegVal & USB_EP_TYPE_MASK) != USB_EP_ISOCHRONOUS) { uint16_t remaining = xfer->total_len - xfer->queued_len; uint16_t cnt = tu_min16(remaining, xfer->max_packet_size); - pcd_set_ep_rx_cnt(USB, EPindex, cnt); + btable_set_rx_bufsize(EPindex, BTABLE_BUF_RX, cnt); } pcd_set_ep_rx_status(USB, EPindex, USB_EP_RX_VALID); } @@ -445,7 +446,7 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) // (Based on the docs, it seems SETUP will always be accepted after CTR is cleared) if (ep_addr == 0u) { // Always be prepared for a status packet... - pcd_set_ep_rx_cnt(USB, EPindex, CFG_TUD_ENDPOINT0_SIZE); + btable_set_rx_bufsize(EPindex, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE); pcd_clear_rx_ep_ctr(USB, EPindex); } } @@ -651,11 +652,11 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { uint16_t pma_addr = dcd_pma_alloc(buffer_size, false); if (dir == TUSB_DIR_IN) { - pcd_set_ep_tx_address(USB, ep_idx, pma_addr); + btable_set_addr(ep_idx, BTABLE_BUF_TX, pma_addr); pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_NAK); pcd_clear_tx_dtog(USB, ep_idx); } else { - pcd_set_ep_rx_address(USB, ep_idx, pma_addr); + btable_set_addr(ep_idx, BTABLE_BUF_RX, pma_addr); pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_NAK); pcd_clear_rx_dtog(USB, ep_idx); } @@ -771,7 +772,7 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { if (is_iso) { buf_id = (ep_reg & USB_EP_DTOG_TX) ? 1 : 0; } else { - buf_id = 0; + buf_id = BTABLE_BUF_TX; } uint16_t addr_ptr = (uint16_t) btable_get_addr(ep_ix, buf_id); btable_set_count(ep_ix, buf_id, len); @@ -806,10 +807,10 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) uint16_t ep_reg = pcd_get_endpoint(USB, ep_idx); if ((ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { - pcd_set_ep_rx_dbuf0_cnt(USB, ep_idx, cnt); - pcd_set_ep_rx_dbuf1_cnt(USB, ep_idx, cnt); + btable_set_rx_bufsize(ep_idx, 0, cnt); + btable_set_rx_bufsize(ep_idx, 1, cnt); } else { - pcd_set_ep_rx_cnt(USB, ep_idx, cnt); + btable_set_rx_bufsize(ep_idx, BTABLE_BUF_RX, cnt); } pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_VALID); diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 72db609cb..05354d705 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -62,6 +62,11 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 b #define pma_aligned #endif +enum { + BTABLE_BUF_TX = 0, + BTABLE_BUF_RX = 1 +}; + // hardware limit endpoint #define FSDEV_EP_COUNT 8 @@ -105,20 +110,6 @@ static volatile uint32_t * const pma32 = (volatile uint32_t*)USB_PMAADDR; typedef uint16_t fsdev_bus_t; // Volatile is also needed to prevent the optimizer from changing access to 32-bit (as 32-bit access is forbidden) static volatile uint16_t * const pma = (volatile uint16_t*)USB_PMAADDR; - -TU_ATTR_ALWAYS_INLINE static inline volatile uint16_t * pcd_btable_word_ptr(USB_TypeDef * USBx, size_t x) { - size_t total_word_offset = (((USBx)->BTABLE)>>1) + x; - total_word_offset *= FSDEV_PMA_STRIDE; - return &(pma[total_word_offset]); -} - -TU_ATTR_ALWAYS_INLINE static inline volatile uint16_t* pcd_ep_tx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) { - return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 1u); -} - -TU_ATTR_ALWAYS_INLINE static inline volatile uint16_t* pcd_ep_rx_cnt_ptr(USB_TypeDef * USBx, uint32_t bEpIdx) { - return pcd_btable_word_ptr(USBx,(bEpIdx)*4u + 3u); -} #endif /* Aligned buffer size according to hardware */ @@ -205,100 +196,47 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, pcd_set_endpoint(USBx, bEpIdx,regVal); } -TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_count(uint32_t ep_id, uint8_t is_rx) { +TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_count(uint32_t ep_id, uint8_t buf_id) { uint16_t count; #ifdef FSDEV_BUS_32BIT - count = (FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr >> 16); + count = (FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr >> 16); #else - count = FSDEV_BTABLE->ep16[ep_id][is_rx].count; + count = FSDEV_BTABLE->ep16[ep_id][buf_id].count; #endif return count & 0x3FFU; } -TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uint8_t is_rx) { +TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uint8_t buf_id) { #ifdef FSDEV_BUS_32BIT - return FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr & 0x0000FFFFu; + return FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr & 0x0000FFFFu; #else - return FSDEV_BTABLE->ep16[ep_id][is_rx].addr; + return FSDEV_BTABLE->ep16[ep_id][buf_id].addr; #endif } -/** - * @brief gets counter of the tx buffer. - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @retval Counter value - */ -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { - (void) USBx; - return btable_get_count(bEpIdx, 0); -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx) { - (void) USBx; - return btable_get_count(bEpIdx, 1); -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { - (void) USBx; - return btable_get_addr(bEpIdx, 0); -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx) { - (void) USBx; - return btable_get_addr(bEpIdx, 1); -} - -TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t is_rx, uint16_t addr) { +TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t buf_id, uint16_t addr) { #ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr; + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); - FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr = count_addr; + FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; #else - FSDEV_BTABLE->ep16[ep_id][is_rx].addr = addr; + FSDEV_BTABLE->ep16[ep_id][buf_id].addr = addr; #endif } -TU_ATTR_ALWAYS_INLINE static inline void btable_set_count(uint32_t ep_id, uint8_t is_rx, uint16_t byte_count) { +TU_ATTR_ALWAYS_INLINE static inline void btable_set_count(uint32_t ep_id, uint8_t buf_id, uint16_t byte_count) { #ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr; + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; count_addr = (count_addr & ~0x03FF0000u) | ((byte_count & 0x3FFu) << 16); - FSDEV_BTABLE->ep32[ep_id][is_rx].count_addr = count_addr; + FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; #else - uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][is_rx].count; + uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][buf_id].count; cnt = (cnt & ~0x3FFU) | (byte_count & 0x3FFU); - FSDEV_BTABLE->ep16[ep_id][is_rx].count = cnt; + FSDEV_BTABLE->ep16[ep_id][buf_id].count = cnt; #endif } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { - (void) USBx; - btable_set_addr(bEpIdx, 0, addr); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t addr) { - (void) USBx; - btable_set_addr(bEpIdx, 1, addr); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { - (void) USBx; - btable_set_count(bEpIdx, 0, wCount); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_blsize_num_blocks(USB_TypeDef * USBx, uint32_t rxtx_idx, - uint32_t blocksize, uint32_t numblocks) { - /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ -#ifdef FSDEV_BUS_32BIT - (void) USBx; - pma32[rxtx_idx] = (pma32[rxtx_idx] & 0x0000FFFFu) | (blocksize << 31) | ((numblocks - blocksize) << 26); -#else - volatile uint16_t *pdwReg = pcd_btable_word_ptr(USBx, rxtx_idx*2u + 1u); - *pdwReg = (blocksize << 15) | ((numblocks - blocksize) << 10); -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_bufsize(USB_TypeDef * USBx, uint32_t rxtx_idx, uint32_t wCount) { +TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint32_t wCount) { wCount = pcd_aligned_buffer_size(wCount); /* We assume that the buffer size is already aligned to hardware requirements. */ @@ -309,19 +247,17 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_bufsize(USB_TypeDef * USBx, TU_ASSERT((wCount - (numblocks * (blocksize ? 32 : 2))) == 0, /**/); /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ - pcd_set_ep_blsize_num_blocks(USBx, rxtx_idx, blocksize, numblocks); -} + uint16_t bl_nb = (blocksize << 15) | ((numblocks - blocksize) << 10); -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_dbuf0_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { - pcd_set_ep_bufsize(USBx, 2*bEpIdx, wCount); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_cnt(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wCount) { - pcd_set_ep_bufsize(USBx, 2*bEpIdx + 1, wCount); +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; + count_addr = (bl_nb << 16) | (count_addr & 0x0000FFFFu); + FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; +#else + FSDEV_BTABLE->ep16[ep_id][buf_id].count = bl_nb; +#endif } -#define pcd_set_ep_rx_dbuf1_cnt pcd_set_ep_rx_cnt - /** * @brief sets the status for tx transfer (bits STAT_TX[1:0]). * @param USBx USB peripheral instance register address. -- cgit v1.3.1 From b15814b2f9579ef126b2ad30b6fff0e338ead3ef Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 30 Jul 2024 16:29:54 +0700 Subject: move align buffer to pma_alloc() --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 32 +++--- src/portable/st/stm32_fsdev/fsdev_common.h | 140 +++++++++++++------------- 2 files changed, 85 insertions(+), 87 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index cd00e6395..2be6ef031 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -170,7 +170,7 @@ static void dcd_ep_ctr_handler(void); // PMA allocation/access static uint16_t ep_buf_ptr; ///< Points to first free memory location -static uint32_t dcd_pma_alloc(uint16_t length, bool dbuf); +static uint32_t dcd_pma_alloc(uint16_t len, bool dbuf); static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type); static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes); static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes); @@ -551,21 +551,19 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *req * In case of double buffering, high 16bit is the address of 2nd buffer * During failure, TU_ASSERT is used. If this happens, rework/reallocate memory manually. */ -static uint32_t dcd_pma_alloc(uint16_t length, bool dbuf) +static uint32_t dcd_pma_alloc(uint16_t len, bool dbuf) { - // Ensure allocated buffer is aligned -#ifdef FSDEV_BUS_32BIT - length = (length + 3) & ~0x03; -#else - length = (length + 1) & ~0x01; -#endif + uint8_t blsize, num_block; + uint16_t aligned_len = pma_align_buffer_size(len, &blsize, &num_block); + (void) blsize; + (void) num_block; uint32_t addr = ep_buf_ptr; - ep_buf_ptr = (uint16_t)(ep_buf_ptr + length); // increment buffer pointer + ep_buf_ptr = (uint16_t)(ep_buf_ptr + aligned_len); // increment buffer pointer if (dbuf) { addr |= ((uint32_t)ep_buf_ptr) << 16; - ep_buf_ptr = (uint16_t)(ep_buf_ptr + length); // increment buffer pointer + ep_buf_ptr = (uint16_t)(ep_buf_ptr + aligned_len); // increment buffer pointer } // Verify packet buffer is not overflowed @@ -621,11 +619,9 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { uint8_t const ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer); uint8_t const dir = tu_edpt_dir(ep_addr); const uint16_t packet_size = tu_edpt_packet_size(desc_ep); - const uint16_t buffer_size = pcd_aligned_buffer_size(packet_size); uint32_t wType; TU_ASSERT(ep_idx < FSDEV_EP_COUNT); - TU_ASSERT(buffer_size <= 64); // Set type switch (desc_ep->bmAttributes.xfer) { @@ -649,7 +645,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { pcd_set_ep_address(USB, ep_idx, tu_edpt_number(ep_addr)); /* Create a packet memory buffer area. */ - uint16_t pma_addr = dcd_pma_alloc(buffer_size, false); + uint16_t pma_addr = dcd_pma_alloc(packet_size, false); if (dir == TUSB_DIR_IN) { btable_set_addr(ep_idx, BTABLE_BUF_TX, pma_addr); @@ -707,22 +703,20 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) } } -bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) -{ +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void)rhport; uint8_t const ep_idx = dcd_ep_alloc(ep_addr, TUSB_XFER_ISOCHRONOUS); - const uint16_t buffer_size = pcd_aligned_buffer_size(largest_packet_size); /* Create a packet memory buffer area. Enable double buffering for devices with 2048 bytes PMA, for smaller devices double buffering occupy too much space. */ + uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, true); #if FSDEV_PMA_SIZE > 1024u - uint32_t pma_addr = dcd_pma_alloc(buffer_size, true); uint16_t pma_addr2 = pma_addr >> 16; #else - uint32_t pma_addr = dcd_pma_alloc(buffer_size, true); uint16_t pma_addr2 = pma_addr; #endif + btable_set_addr(ep_idx, 0, pma_addr); btable_set_addr(ep_idx, 1, pma_addr2); pcd_set_eptype(USB, ep_idx, USB_EP_ISOCHRONOUS); @@ -803,7 +797,7 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) if (dir == TUSB_DIR_IN) { dcd_transmit_packet(xfer, ep_idx); } else { - uint32_t cnt = (uint32_t ) tu_min16(xfer->total_len, xfer->max_packet_size); + uint32_t cnt = (uint32_t) tu_min16(xfer->total_len, xfer->max_packet_size); uint16_t ep_reg = pcd_get_endpoint(USB, ep_idx); if ((ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 05354d705..c8d259cfa 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -96,7 +96,7 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE #define FSDEV_BTABLE ((volatile fsdev_btable_t*) (USB_PMAADDR+FSDEV_BTABLE_BASE)) //--------------------------------------------------------------------+ -// Helper +// BTable //--------------------------------------------------------------------+ // The fsdev_bus_t type can be used for both register and PMA access necessities @@ -112,18 +112,84 @@ typedef uint16_t fsdev_bus_t; static volatile uint16_t * const pma = (volatile uint16_t*)USB_PMAADDR; #endif +TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uint8_t buf_id) { +#ifdef FSDEV_BUS_32BIT + return FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr & 0x0000FFFFu; +#else + return FSDEV_BTABLE->ep16[ep_id][buf_id].addr; +#endif +} + +TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t buf_id, uint16_t addr) { +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; + count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); + FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; +#else + FSDEV_BTABLE->ep16[ep_id][buf_id].addr = addr; +#endif +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_count(uint32_t ep_id, uint8_t buf_id) { + uint16_t count; +#ifdef FSDEV_BUS_32BIT + count = (FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr >> 16); +#else + count = FSDEV_BTABLE->ep16[ep_id][buf_id].count; +#endif + return count & 0x3FFU; +} + +TU_ATTR_ALWAYS_INLINE static inline void btable_set_count(uint32_t ep_id, uint8_t buf_id, uint16_t byte_count) { +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; + count_addr = (count_addr & ~0x03FF0000u) | ((byte_count & 0x3FFu) << 16); + FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; +#else + uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][buf_id].count; + cnt = (cnt & ~0x3FFU) | (byte_count & 0x3FFU); + FSDEV_BTABLE->ep16[ep_id][buf_id].count = cnt; +#endif +} + /* Aligned buffer size according to hardware */ -TU_ATTR_ALWAYS_INLINE static inline uint16_t pcd_aligned_buffer_size(uint16_t size) { +TU_ATTR_ALWAYS_INLINE static inline uint16_t pma_align_buffer_size(uint16_t size, uint8_t* blsize, uint8_t* num_block) { /* The STM32 full speed USB peripheral supports only a limited set of * buffer sizes given by the RX buffer entry format in the USB_BTABLE. */ - uint16_t blocksize = (size > 62) ? 32 : 2; + uint16_t block_in_bytes; + if (size > 62) { + block_in_bytes = 32; + *blsize = 1; + } else { + block_in_bytes = 2; + *blsize = 0; + } + + *num_block = tu_div_ceil(size, block_in_bytes); - // Round up while dividing requested size by blocksize - uint16_t numblocks = (size + blocksize - 1) / blocksize ; + return (*num_block) * block_in_bytes; +} + +TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint32_t wCount) { + uint8_t blsize, num_block; + (void) pma_align_buffer_size(wCount, &blsize, &num_block); - return numblocks * blocksize; + /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ + uint16_t bl_nb = (blsize << 15) | ((num_block - blsize) << 10); + +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; + count_addr = (bl_nb << 16) | (count_addr & 0x0000FFFFu); + FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; +#else + FSDEV_BTABLE->ep16[ep_id][buf_id].count = bl_nb; +#endif } +//--------------------------------------------------------------------+ +// Endpoint +//--------------------------------------------------------------------+ + TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wRegValue) { #ifdef FSDEV_BUS_32BIT (void) USBx; @@ -196,68 +262,6 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, pcd_set_endpoint(USBx, bEpIdx,regVal); } -TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_count(uint32_t ep_id, uint8_t buf_id) { - uint16_t count; -#ifdef FSDEV_BUS_32BIT - count = (FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr >> 16); -#else - count = FSDEV_BTABLE->ep16[ep_id][buf_id].count; -#endif - return count & 0x3FFU; -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uint8_t buf_id) { -#ifdef FSDEV_BUS_32BIT - return FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr & 0x0000FFFFu; -#else - return FSDEV_BTABLE->ep16[ep_id][buf_id].addr; -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t buf_id, uint16_t addr) { -#ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; - count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); - FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; -#else - FSDEV_BTABLE->ep16[ep_id][buf_id].addr = addr; -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline void btable_set_count(uint32_t ep_id, uint8_t buf_id, uint16_t byte_count) { -#ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; - count_addr = (count_addr & ~0x03FF0000u) | ((byte_count & 0x3FFu) << 16); - FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; -#else - uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][buf_id].count; - cnt = (cnt & ~0x3FFU) | (byte_count & 0x3FFU); - FSDEV_BTABLE->ep16[ep_id][buf_id].count = cnt; -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint32_t wCount) { - wCount = pcd_aligned_buffer_size(wCount); - - /* We assume that the buffer size is already aligned to hardware requirements. */ - uint16_t blocksize = (wCount > 62) ? 1 : 0; - uint16_t numblocks = wCount / (blocksize ? 32 : 2); - - /* There should be no remainder in the above calculation */ - TU_ASSERT((wCount - (numblocks * (blocksize ? 32 : 2))) == 0, /**/); - - /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ - uint16_t bl_nb = (blocksize << 15) | ((numblocks - blocksize) << 10); - -#ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; - count_addr = (bl_nb << 16) | (count_addr & 0x0000FFFFu); - FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; -#else - FSDEV_BTABLE->ep16[ep_id][buf_id].count = bl_nb; -#endif -} - /** * @brief sets the status for tx transfer (bits STAT_TX[1:0]). * @param USBx USB peripheral instance register address. -- cgit v1.3.1 From 1cf8e34ae5fc6466d07ac438691391c7a5a809ff Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 30 Jul 2024 20:32:26 +0700 Subject: improve set endpoint --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 41 +++++----- src/portable/st/stm32_fsdev/fsdev_ch32.h | 35 ++++----- src/portable/st/stm32_fsdev/fsdev_common.h | 104 +++++++++++++++++--------- src/portable/st/stm32_fsdev/fsdev_stm32.h | 17 +++++ 4 files changed, 125 insertions(+), 72 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 2be6ef031..6007b4a02 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -616,24 +616,24 @@ static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type) bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { (void)rhport; uint8_t const ep_addr = desc_ep->bEndpointAddress; - uint8_t const ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer); uint8_t const dir = tu_edpt_dir(ep_addr); const uint16_t packet_size = tu_edpt_packet_size(desc_ep); - uint32_t wType; - + uint8_t const ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer); TU_ASSERT(ep_idx < FSDEV_EP_COUNT); + uint32_t ep_reg = FSDEV_REG->ep[ep_idx].reg & ~USB_EPREG_MASK; + ep_reg |= tu_edpt_number(ep_addr) | USB_EP_CTR_RX | USB_EP_CTR_TX; + // Set type switch (desc_ep->bmAttributes.xfer) { case TUSB_XFER_CONTROL: - wType = USB_EP_CONTROL; + ep_reg |= USB_EP_CONTROL; break; case TUSB_XFER_BULK: - wType = USB_EP_CONTROL; + ep_reg |= USB_EP_CONTROL; // FIXME should it be bulk? break; - case TUSB_XFER_INTERRUPT: - wType = USB_EP_INTERRUPT; + ep_reg |= USB_EP_INTERRUPT; break; default: @@ -641,24 +641,23 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { TU_ASSERT(false); } - pcd_set_eptype(USB, ep_idx, wType); - pcd_set_ep_address(USB, ep_idx, tu_edpt_number(ep_addr)); - /* Create a packet memory buffer area. */ uint16_t pma_addr = dcd_pma_alloc(packet_size, false); + btable_set_addr(ep_idx, dir == TUSB_DIR_IN ? BTABLE_BUF_TX : BTABLE_BUF_RX, pma_addr); + + xfer_ctl_ptr(ep_addr)->max_packet_size = packet_size; + xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; if (dir == TUSB_DIR_IN) { - btable_set_addr(ep_idx, BTABLE_BUF_TX, pma_addr); - pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_NAK); - pcd_clear_tx_dtog(USB, ep_idx); + ep_reg = ep_add_tx_status(ep_reg, USB_EP_TX_NAK); + ep_reg = ep_add_tx_dtog(ep_reg, 0); + ep_reg &= ~(USB_EPRX_STAT | USB_EP_DTOG_RX); } else { - btable_set_addr(ep_idx, BTABLE_BUF_RX, pma_addr); - pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_NAK); - pcd_clear_rx_dtog(USB, ep_idx); + ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_NAK); + ep_reg = ep_add_rx_dtog(ep_reg, 0); + ep_reg &= ~(USB_EPTX_STAT | USB_EP_DTOG_TX); } - - xfer_ctl_ptr(ep_addr)->max_packet_size = packet_size; - xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; + pcd_set_endpoint(USB, ep_idx, ep_reg); return true; } @@ -731,7 +730,8 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoin uint8_t const ep_addr = p_endpoint_desc->bEndpointAddress; uint8_t const ep_idx = xfer_ctl_ptr(ep_addr)->ep_idx; uint8_t const dir = tu_edpt_dir(ep_addr); - const uint16_t packet_size = tu_edpt_packet_size(p_endpoint_desc); + + xfer_ctl_ptr(ep_addr)->max_packet_size = tu_edpt_packet_size(p_endpoint_desc); pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_DIS); pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_DIS); @@ -747,7 +747,6 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoin pcd_tx_dtog(USB, ep_idx); } - xfer_ctl_ptr(ep_addr)->max_packet_size = packet_size; return true; } diff --git a/src/portable/st/stm32_fsdev/fsdev_ch32.h b/src/portable/st/stm32_fsdev/fsdev_ch32.h index f63a80d56..81ef08b8a 100644 --- a/src/portable/st/stm32_fsdev/fsdev_ch32.h +++ b/src/portable/st/stm32_fsdev/fsdev_ch32.h @@ -55,28 +55,29 @@ #define FSDEV_PMA_SIZE (512u) +#if 1 // volatile 32-bit aligned -#define _va32 volatile TU_ATTR_ALIGNED(4) +#define _vaa32 volatile TU_ATTR_ALIGNED(4) typedef struct { - _va32 uint16_t EP0R; // 00: USB Endpoint 0 register - _va32 uint16_t EP1R; // 04: USB Endpoint 1 register - _va32 uint16_t EP2R; // 08: USB Endpoint 2 register - _va32 uint16_t EP3R; // 0C: USB Endpoint 3 register - _va32 uint16_t EP4R; // 10: USB Endpoint 4 register - _va32 uint16_t EP5R; // 14: USB Endpoint 5 register - _va32 uint16_t EP6R; // 18: USB Endpoint 6 register - _va32 uint16_t EP7R; // 1C: USB Endpoint 7 register - _va32 uint16_t RESERVED7[16]; // Reserved - _va32 uint16_t CNTR; // 40: Control register - _va32 uint16_t ISTR; // 44: Interrupt status register - _va32 uint16_t FNR; // 48: Frame number register - _va32 uint16_t DADDR; // 4C: Device address register - _va32 uint16_t BTABLE; // 50: Buffer Table address register + _vaa32 uint16_t EP0R; // 00: USB Endpoint 0 register + _vaa32 uint16_t EP1R; // 04: USB Endpoint 1 register + _vaa32 uint16_t EP2R; // 08: USB Endpoint 2 register + _vaa32 uint16_t EP3R; // 0C: USB Endpoint 3 register + _vaa32 uint16_t EP4R; // 10: USB Endpoint 4 register + _vaa32 uint16_t EP5R; // 14: USB Endpoint 5 register + _vaa32 uint16_t EP6R; // 18: USB Endpoint 6 register + _vaa32 uint16_t EP7R; // 1C: USB Endpoint 7 register + _vaa32 uint16_t RESERVED7[16]; // Reserved + _vaa32 uint16_t CNTR; // 40: Control register + _vaa32 uint16_t ISTR; // 44: Interrupt status register + _vaa32 uint16_t FNR; // 48: Frame number register + _vaa32 uint16_t DADDR; // 4C: Device address register + _vaa32 uint16_t BTABLE; // 50: Buffer Table address register } USB_TypeDef; +#endif -TU_VERIFY_STATIC(sizeof(USB_TypeDef) == 0x54, "Size is not correct"); -TU_VERIFY_STATIC(offsetof(USB_TypeDef, CNTR) == 0x40, "Wrong offset"); +#define FSDEV_REG_BASE 0x40005C00UL #define USB_BASE (APB1PERIPH_BASE + 0x00005C00UL) /*!< USB_IP Peripheral Registers base address */ #define USB_PMAADDR (APB1PERIPH_BASE + 0x00006000UL) /*!< USB_IP Packet Memory Area base address */ diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index c8d259cfa..3d1e1fe4a 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -95,9 +95,8 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE #define FSDEV_BTABLE ((volatile fsdev_btable_t*) (USB_PMAADDR+FSDEV_BTABLE_BASE)) -//--------------------------------------------------------------------+ -// BTable -//--------------------------------------------------------------------+ +// volatile 32-bit aligned +#define _va32 volatile TU_ATTR_ALIGNED(4) // The fsdev_bus_t type can be used for both register and PMA access necessities // For type-safety create a new macro for the volatile address of PMAADDR @@ -112,6 +111,39 @@ typedef uint16_t fsdev_bus_t; static volatile uint16_t * const pma = (volatile uint16_t*)USB_PMAADDR; #endif +typedef struct { +// _va32 fsdev_bus_t EP0R; // 00: USB Endpoint 0 register +// _va32 fsdev_bus_t EP1R; // 04: USB Endpoint 1 register +// _va32 fsdev_bus_t EP2R; // 08: USB Endpoint 2 register +// _va32 fsdev_bus_t EP3R; // 0C: USB Endpoint 3 register +// _va32 fsdev_bus_t EP4R; // 10: USB Endpoint 4 register +// _va32 fsdev_bus_t EP5R; // 14: USB Endpoint 5 register +// _va32 fsdev_bus_t EP6R; // 18: USB Endpoint 6 register +// _va32 fsdev_bus_t EP7R; // 1C: USB Endpoint 7 register + struct { + _va32 fsdev_bus_t reg; + }ep[FSDEV_EP_COUNT]; + + _va32 uint32_t RESERVED7[8]; // Reserved + _va32 fsdev_bus_t CNTR; // 40: Control register + _va32 fsdev_bus_t ISTR; // 44: Interrupt status register + _va32 fsdev_bus_t FNR; // 48: Frame number register + _va32 fsdev_bus_t DADDR; // 4C: Device address register + _va32 fsdev_bus_t BTABLE; // 50: Buffer Table address register (16-bit only) + _va32 fsdev_bus_t LPMCSR; // 54: LPM Control and Status Register (32-bit only) + _va32 fsdev_bus_t BCDR; // 58: Battery Charging Detector Register (32-bit only) +} fsdev_regs_t; + +TU_VERIFY_STATIC(offsetof(fsdev_regs_t, CNTR) == 0x40, "Wrong offset"); +TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct"); + +#define FSDEV_REG ((fsdev_regs_t*) FSDEV_REG_BASE) + + +//--------------------------------------------------------------------+ +// BTable +//--------------------------------------------------------------------+ + TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uint8_t buf_id) { #ifdef FSDEV_BUS_32BIT return FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr & 0x0000FFFFu; @@ -191,24 +223,13 @@ TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, u //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wRegValue) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - volatile uint32_t *reg = (volatile uint32_t *)(USB_DRD_BASE + bEpIdx*4); - *reg = wRegValue; -#else - volatile uint16_t *reg = (volatile uint16_t *)((&USBx->EP0R) + bEpIdx*2u); - *reg = (uint16_t)wRegValue; -#endif + FSDEV_REG->ep[bEpIdx].reg = (fsdev_bus_t) wRegValue; } TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx) { -#ifdef FSDEV_BUS_32BIT (void) USBx; - volatile const uint32_t *reg = (volatile const uint32_t *)(USB_DRD_BASE + bEpIdx*4); -#else - volatile const uint16_t *reg = (volatile const uint16_t *)((&USBx->EP0R) + bEpIdx*2u); -#endif - return *reg; + return FSDEV_REG->ep[bEpIdx].reg; } /** @@ -262,6 +283,21 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, pcd_set_endpoint(USBx, bEpIdx,regVal); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_tx_status(uint32_t reg, uint32_t state) { + return reg | ((reg ^ state) & USB_EPTX_STAT); +} +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_rx_status(uint32_t reg, uint32_t state) { + return reg | ((reg ^ state) & USB_EPRX_STAT); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_tx_dtog(uint32_t reg, uint32_t state) { + return reg | ((reg ^ state) & USB_EP_DTOG_TX); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_rx_dtog(uint32_t reg, uint32_t state) { + return reg | ((reg ^ state) & USB_EP_DTOG_RX); +} + /** * @brief sets the status for tx transfer (bits STAT_TX[1:0]). * @param USBx USB peripheral instance register address. @@ -293,10 +329,10 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx pcd_set_endpoint(USBx, bEpIdx, regVal); } -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - return (regVal & USB_EPRX_STAT) >> (12u); -} +//TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx) { +// uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); +// return (regVal & USB_EPRX_STAT) >> (12u); +//} TU_ATTR_ALWAYS_INLINE static inline void pcd_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); @@ -326,20 +362,20 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx, } } -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal |= USB_EP_KIND; - regVal &= USB_EPREG_MASK; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPKIND_MASK; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} +//TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) { +// uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); +// regVal |= USB_EP_KIND; +// regVal &= USB_EPREG_MASK; +// regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; +// pcd_set_endpoint(USBx, bEpIdx, regVal); +//} +// +//TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) { +// uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); +// regVal &= USB_EPKIND_MASK; +// regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; +// pcd_set_endpoint(USBx, bEpIdx, regVal); +//} #ifdef __cplusplus } diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index a8f61a35f..f89882e0d 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -35,6 +35,7 @@ #if CFG_TUSB_MCU == OPT_MCU_STM32F0 #include "stm32f0xx.h" #define FSDEV_PMA_SIZE (1024u) + #define FSDEV_REG_BASE USB_BASE // F0x2 models are crystal-less // All have internal D+ pull-up // 070RB: 2 x 16 bits/word memory LPM Support, BCD Support @@ -193,6 +194,22 @@ // This includes U0 #endif +#if defined(USB_BASE) + #define FSDEV_REG_BASE USB_BASE +#elif defined(USB_DRD_BASE) + #define FSDEV_REG_BASE USB_DRD_BASE +#else + #error "FSDEV_REG_BASE not defined" +#endif + +#ifndef USB_EPTX_STAT +#define USB_EPTX_STAT 0x0030U +#endif + +#ifndef USB_EPRX_STAT +#define USB_EPRX_STAT 0x3000U +#endif + // This checks if the device has "LPM" #if defined(USB_ISTR_L1REQ) #define USB_ISTR_L1REQ_FORCED (USB_ISTR_L1REQ) -- cgit v1.3.1 From f4aaad6869db74a4fba6eeb716d20be85978a311 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 30 Jul 2024 21:35:24 +0700 Subject: add edpt0_open(), slightly update dtog --- src/device/dcd.h | 2 +- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 74 +++++++++++++++------------ src/portable/st/stm32_fsdev/fsdev_common.h | 30 +++++++---- src/portable/st/stm32_fsdev/fsdev_stm32.h | 8 --- 4 files changed, 62 insertions(+), 52 deletions(-) (limited to 'src/portable') diff --git a/src/device/dcd.h b/src/device/dcd.h index b25b47025..41e0fbee3 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -180,7 +180,7 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr); TU_ATTR_WEAK bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size); // Configure and enable an ISO endpoint according to descriptor -TU_ATTR_WEAK bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc); +TU_ATTR_WEAK bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep); //--------------------------------------------------------------------+ // Event API (implemented by stack) diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 6007b4a02..834de6998 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -178,6 +178,8 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNBytes); static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBytes); +TU_ATTR_UNUSED static void edpt0_open(uint8_t rhport); + //--------------------------------------------------------------------+ // Inline helper //--------------------------------------------------------------------+ @@ -277,19 +279,7 @@ static void handle_bus_reset(uint8_t rhport) { // Reset PMA allocation ep_buf_ptr = FSDEV_BTABLE_BASE + 8 * FSDEV_EP_COUNT; - tusb_desc_endpoint_t ep0_desc = { - .bLength = sizeof(tusb_desc_endpoint_t), - .bDescriptorType = TUSB_DESC_ENDPOINT, - .bEndpointAddress = 0x00, - .bmAttributes = {.xfer = TUSB_XFER_CONTROL}, - .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE, - .bInterval = 0 - }; - - dcd_edpt_open(rhport, &ep0_desc); - - ep0_desc.bEndpointAddress = 0x80; - dcd_edpt_open(rhport, &ep0_desc); + edpt0_open(rhport); // open control endpoint (both IN & OUT) USB->DADDR = USB_DADDR_EF; // Enable USB Function } @@ -610,8 +600,32 @@ static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type) TU_ASSERT(0); } -// The STM32F0 doesn't seem to like |= or &= to manipulate the EP#R registers, -// so I'm using the #define from HAL here, instead. +void edpt0_open(uint8_t rhport) { + (void) rhport; + + dcd_ep_alloc(0x0, TUSB_XFER_CONTROL); + dcd_ep_alloc(0x80, TUSB_XFER_CONTROL); + + xfer_status[0][0].max_packet_size = CFG_TUD_ENDPOINT0_SIZE; + xfer_status[0][0].ep_idx = 0; + + xfer_status[0][1].max_packet_size = CFG_TUD_ENDPOINT0_SIZE; + xfer_status[0][1].ep_idx = 0; + + uint16_t pma_addr0 = dcd_pma_alloc(CFG_TUD_ENDPOINT0_SIZE, false); + uint16_t pma_addr1 = dcd_pma_alloc(CFG_TUD_ENDPOINT0_SIZE, false); + + btable_set_addr(0, BTABLE_BUF_RX, pma_addr0); + btable_set_addr(0, BTABLE_BUF_TX, pma_addr1); + + uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK; + ep_reg |= USB_EP_CONTROL | USB_EP_CTR_RX | USB_EP_CTR_TX; + ep_reg = ep_add_tx_status(ep_reg, USB_EP_TX_NAK); + ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_NAK); + // no need to explicitly set DTOG bits since we aren't masked DTOG bit + + pcd_set_endpoint(USB, 0, ep_reg); +} bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { (void)rhport; @@ -626,9 +640,6 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { // Set type switch (desc_ep->bmAttributes.xfer) { - case TUSB_XFER_CONTROL: - ep_reg |= USB_EP_CONTROL; - break; case TUSB_XFER_BULK: ep_reg |= USB_EP_CONTROL; // FIXME should it be bulk? break; @@ -718,35 +729,34 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet btable_set_addr(ep_idx, 0, pma_addr); btable_set_addr(ep_idx, 1, pma_addr2); - pcd_set_eptype(USB, ep_idx, USB_EP_ISOCHRONOUS); xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; + pcd_set_eptype(USB, ep_idx, USB_EP_ISOCHRONOUS); + return true; } -bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc) -{ +bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { (void)rhport; - uint8_t const ep_addr = p_endpoint_desc->bEndpointAddress; + uint8_t const ep_addr = desc_ep->bEndpointAddress; uint8_t const ep_idx = xfer_ctl_ptr(ep_addr)->ep_idx; uint8_t const dir = tu_edpt_dir(ep_addr); - xfer_ctl_ptr(ep_addr)->max_packet_size = tu_edpt_packet_size(p_endpoint_desc); - - pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_DIS); - pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_DIS); + xfer_ctl_ptr(ep_addr)->max_packet_size = tu_edpt_packet_size(desc_ep); - pcd_set_ep_address(USB, ep_idx, tu_edpt_number(ep_addr)); - - pcd_clear_tx_dtog(USB, ep_idx); - pcd_clear_rx_dtog(USB, ep_idx); + uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK; + ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_RX | USB_EP_CTR_TX; + ep_reg = ep_add_tx_status(ep_reg, USB_EP_TX_DIS); + ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_DIS); + // no need to explicitly set DTOG bits since we aren't masked DTOG bit if (dir == TUSB_DIR_IN) { - pcd_rx_dtog(USB, ep_idx); + ep_reg = ep_add_rx_dtog(ep_reg, 1); } else { - pcd_tx_dtog(USB, ep_idx); + ep_reg = ep_add_tx_dtog(ep_reg, 1); } + pcd_set_endpoint(USB, ep_idx, ep_reg); return true; } diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 3d1e1fe4a..53b2af0a2 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -112,14 +112,6 @@ static volatile uint16_t * const pma = (volatile uint16_t*)USB_PMAADDR; #endif typedef struct { -// _va32 fsdev_bus_t EP0R; // 00: USB Endpoint 0 register -// _va32 fsdev_bus_t EP1R; // 04: USB Endpoint 1 register -// _va32 fsdev_bus_t EP2R; // 08: USB Endpoint 2 register -// _va32 fsdev_bus_t EP3R; // 0C: USB Endpoint 3 register -// _va32 fsdev_bus_t EP4R; // 10: USB Endpoint 4 register -// _va32 fsdev_bus_t EP5R; // 14: USB Endpoint 5 register -// _va32 fsdev_bus_t EP6R; // 18: USB Endpoint 6 register -// _va32 fsdev_bus_t EP7R; // 1C: USB Endpoint 7 register struct { _va32 fsdev_bus_t reg; }ep[FSDEV_EP_COUNT]; @@ -140,6 +132,22 @@ TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct"); #define FSDEV_REG ((fsdev_regs_t*) FSDEV_REG_BASE) +#ifndef USB_EPTX_STAT +#define USB_EPTX_STAT 0x0030U +#endif + +#ifndef USB_EPRX_STAT +#define USB_EPRX_STAT 0x3000U +#endif + +#ifndef USB_EP_DTOG_TX_Pos +#define USB_EP_DTOG_TX_Pos (6U) +#endif + +#ifndef USB_EP_DTOG_RX_Pos +#define USB_EP_DTOG_RX_Pos (14U) +#endif + //--------------------------------------------------------------------+ // BTable //--------------------------------------------------------------------+ @@ -244,7 +252,7 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_address(USB_TypeDef * USBx, regVal &= USB_EPREG_MASK; regVal |= bAddr; regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx,regVal); + pcd_set_endpoint(USBx, bEpIdx, regVal); } TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wType) { @@ -291,11 +299,11 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_rx_status(uint32_t reg, uint } TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_tx_dtog(uint32_t reg, uint32_t state) { - return reg | ((reg ^ state) & USB_EP_DTOG_TX); + return reg | ((reg ^ (state << USB_EP_DTOG_TX_Pos)) & USB_EP_DTOG_TX); } TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_rx_dtog(uint32_t reg, uint32_t state) { - return reg | ((reg ^ state) & USB_EP_DTOG_RX); + return reg | ((reg ^ (state << USB_EP_DTOG_RX_Pos)) & USB_EP_DTOG_RX); } /** diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index f89882e0d..f20505f28 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -202,14 +202,6 @@ #error "FSDEV_REG_BASE not defined" #endif -#ifndef USB_EPTX_STAT -#define USB_EPTX_STAT 0x0030U -#endif - -#ifndef USB_EPRX_STAT -#define USB_EPRX_STAT 0x3000U -#endif - // This checks if the device has "LPM" #if defined(USB_ISTR_L1REQ) #define USB_ISTR_L1REQ_FORCED (USB_ISTR_L1REQ) -- cgit v1.3.1 From 0c8d41e25ec3f691f3125f634659f52d084e8995 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 09:46:31 +0700 Subject: correct ep toggle bit --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 32 +++++++++------------------ src/portable/st/stm32_fsdev/fsdev_common.h | 8 +++---- 2 files changed, 15 insertions(+), 25 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 834de6998..5cba9ca40 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -350,8 +350,6 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) uint32_t wEPRegVal = pcd_get_endpoint(USB, EPindex); uint8_t ep_addr = wEPRegVal & USB_EPADDR_FIELD; - xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); - // Verify the CTR_RX bit is set. This was in the ST Micro code, // but I'm not sure it's actually necessary? if ((wEPRegVal & USB_EP_CTR_RX) == 0U) { @@ -359,34 +357,26 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) } if (wEPRegVal & USB_EP_SETUP) { - /* Setup packet */ uint32_t count = btable_get_count(EPindex, BTABLE_BUF_RX); // Setup packet should always be 8 bytes. If not, ignore it, and try again. if (count == 8) { - // Must reset EP to NAK (in case it had been stalling) - pcd_set_ep_rx_status(USB, 0u, USB_EP_RX_NAK); - pcd_set_ep_tx_status(USB, 0u, USB_EP_TX_NAK); - - // set both data toggle to 1 - uint32_t regVal = pcd_get_endpoint(USB, 0); - if ((regVal & USB_EP_DTOG_TX) == 0) { - pcd_tx_dtog(USB, 0); - } - - if ((regVal & USB_EP_DTOG_RX) == 0) { - pcd_rx_dtog(USB, 0); - } - uint16_t rx_addr = btable_get_addr(EPindex, BTABLE_BUF_RX); #ifdef FSDEV_BUS_32BIT dcd_event_setup_received(0, (uint8_t *)(USB_PMAADDR + rx_addr), true); #else // The setup_received function uses memcpy, so this must first copy the setup data into // user memory, to allow for the 32-bit access that memcpy performs. - uint8_t userMemBuf[8]; + uint32_t userMemBuf[2]; dcd_read_packet_memory(userMemBuf, rx_addr, 8); dcd_event_setup_received(0, (uint8_t*) userMemBuf, true); #endif + + // Reset EP to NAK (in case it had been stalling) + wEPRegVal = ep_add_tx_status(wEPRegVal, USB_EP_TX_NAK); + wEPRegVal = ep_add_rx_status(wEPRegVal, USB_EP_RX_NAK); + wEPRegVal = ep_add_tx_dtog(wEPRegVal, 1); + wEPRegVal = ep_add_rx_dtog(wEPRegVal, 1); + pcd_set_endpoint(USB, 0, wEPRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX); } } else { // Clear RX CTR interrupt flag @@ -394,6 +384,8 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) pcd_clear_rx_ep_ctr(USB, EPindex); } + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); + uint8_t buf_id; if ((wEPRegVal & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { // ISO endpoints are double buffered @@ -404,13 +396,11 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) uint32_t count = btable_get_count(EPindex, buf_id); uint16_t addr = (uint16_t) btable_get_addr(EPindex, buf_id); - TU_ASSERT(count <= xfer->max_packet_size, /**/); - if (count != 0U) { if (xfer->ff) { dcd_read_packet_memory_ff(xfer->ff, addr, count); } else { - dcd_read_packet_memory(&(xfer->buffer[xfer->queued_len]), addr, count); + dcd_read_packet_memory(xfer->buffer + xfer->queued_len, addr, count); } xfer->queued_len = (uint16_t)(xfer->queued_len + count); diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 53b2af0a2..09bf4c2ca 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -292,18 +292,18 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, } TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_tx_status(uint32_t reg, uint32_t state) { - return reg | ((reg ^ state) & USB_EPTX_STAT); + return reg ^ state; } TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_rx_status(uint32_t reg, uint32_t state) { - return reg | ((reg ^ state) & USB_EPRX_STAT); + return reg ^ state; } TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_tx_dtog(uint32_t reg, uint32_t state) { - return reg | ((reg ^ (state << USB_EP_DTOG_TX_Pos)) & USB_EP_DTOG_TX); + return reg ^ (state << USB_EP_DTOG_TX_Pos); } TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_rx_dtog(uint32_t reg, uint32_t state) { - return reg | ((reg ^ (state << USB_EP_DTOG_RX_Pos)) & USB_EP_DTOG_RX); + return reg ^ (state << USB_EP_DTOG_RX_Pos); } /** -- cgit v1.3.1 From 126778298e6ab23f2117b60d479d31e4de7d276f Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 11:35:09 +0700 Subject: enhance dcd_ep_ctr_rx_handler() --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 128 ++++++++++++-------------- 1 file changed, 58 insertions(+), 70 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 5cba9ca40..c7a25ba5e 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -178,7 +178,7 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNBytes); static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBytes); -TU_ATTR_UNUSED static void edpt0_open(uint8_t rhport); +static void edpt0_open(uint8_t rhport); //--------------------------------------------------------------------+ // Inline helper @@ -285,10 +285,8 @@ static void handle_bus_reset(uint8_t rhport) { } // Handle CTR interrupt for the TX/IN direction -// Upon call, (wIstr & USB_ISTR_DIR) == 0U -static void dcd_ep_ctr_tx_handler(uint32_t wIstr) { - uint32_t EPindex = wIstr & USB_ISTR_EP_ID; - uint32_t wEPRegVal = pcd_get_endpoint(USB, EPindex); +static void dcd_ep_ctr_tx_handler(uint32_t ep_id) { + uint32_t wEPRegVal = pcd_get_endpoint(USB, ep_id); uint8_t ep_addr = (wEPRegVal & USB_EPADDR_FIELD) | TUSB_DIR_IN_MASK; // Verify the CTR_TX bit is set. This was in the ST Micro code, @@ -298,7 +296,7 @@ static void dcd_ep_ctr_tx_handler(uint32_t wIstr) { } /* clear int flag */ - pcd_clear_tx_ep_ctr(USB, EPindex); + pcd_clear_tx_ep_ctr(USB, ep_id); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); @@ -311,20 +309,18 @@ static void dcd_ep_ctr_tx_handler(uint32_t wIstr) { } xfer->iso_in_sending = false; uint8_t buf_id = (wEPRegVal & USB_EP_DTOG_TX) ? 0 : 1; - btable_set_count(EPindex, buf_id, 0); + btable_set_count(ep_id, buf_id, 0); } if ((xfer->total_len != xfer->queued_len)) { - dcd_transmit_packet(xfer, EPindex); + dcd_transmit_packet(xfer, ep_id); } else { dcd_event_xfer_complete(0, ep_addr, xfer->total_len, XFER_RESULT_SUCCESS, true); } } // Handle CTR interrupt for the RX/OUT direction -// Upon call, (wIstr & USB_ISTR_DIR) == 0U -static void dcd_ep_ctr_rx_handler(uint32_t wIstr) -{ +static void dcd_ep_ctr_rx_handler(uint32_t ep_id) { #ifdef FSDEV_BUS_32BIT /* https://www.st.com/resource/en/errata_sheet/es0561-stm32h503cbebkbrb-device-errata-stmicroelectronics.pdf * From STM32H503 errata 2.15.1: Buffer description table update completes after CTR interrupt triggers @@ -346,103 +342,92 @@ static void dcd_ep_ctr_rx_handler(uint32_t wIstr) } #endif - uint32_t EPindex = wIstr & USB_ISTR_EP_ID; - uint32_t wEPRegVal = pcd_get_endpoint(USB, EPindex); - uint8_t ep_addr = wEPRegVal & USB_EPADDR_FIELD; + uint32_t ep_reg = pcd_get_endpoint(USB, ep_id); + uint8_t ep_addr = ep_reg & USB_EPADDR_FIELD; // Verify the CTR_RX bit is set. This was in the ST Micro code, // but I'm not sure it's actually necessary? - if ((wEPRegVal & USB_EP_CTR_RX) == 0U) { + if ((ep_reg & USB_EP_CTR_RX) == 0U) { return; } - if (wEPRegVal & USB_EP_SETUP) { - uint32_t count = btable_get_count(EPindex, BTABLE_BUF_RX); + // Clear RX CTR and reserved TX CTR + ep_reg = (ep_reg & ~USB_EP_CTR_RX) | USB_EP_CTR_TX; + + if (ep_reg & USB_EP_SETUP) { + uint32_t count = btable_get_count(ep_id, BTABLE_BUF_RX); // Setup packet should always be 8 bytes. If not, ignore it, and try again. if (count == 8) { - uint16_t rx_addr = btable_get_addr(EPindex, BTABLE_BUF_RX); -#ifdef FSDEV_BUS_32BIT - dcd_event_setup_received(0, (uint8_t *)(USB_PMAADDR + rx_addr), true); -#else - // The setup_received function uses memcpy, so this must first copy the setup data into - // user memory, to allow for the 32-bit access that memcpy performs. - uint32_t userMemBuf[2]; - dcd_read_packet_memory(userMemBuf, rx_addr, 8); - dcd_event_setup_received(0, (uint8_t*) userMemBuf, true); -#endif + uint16_t rx_addr = btable_get_addr(ep_id, BTABLE_BUF_RX); + uint32_t setup_packet[2]; + dcd_read_packet_memory(setup_packet, rx_addr, 8); + dcd_event_setup_received(0, (uint8_t*) setup_packet, true); // Reset EP to NAK (in case it had been stalling) - wEPRegVal = ep_add_tx_status(wEPRegVal, USB_EP_TX_NAK); - wEPRegVal = ep_add_rx_status(wEPRegVal, USB_EP_RX_NAK); - wEPRegVal = ep_add_tx_dtog(wEPRegVal, 1); - wEPRegVal = ep_add_rx_dtog(wEPRegVal, 1); - pcd_set_endpoint(USB, 0, wEPRegVal | USB_EP_CTR_RX | USB_EP_CTR_TX); + ep_reg = ep_add_tx_status(ep_reg, USB_EP_TX_NAK); + ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_NAK); + ep_reg = ep_add_tx_dtog(ep_reg, 1); + ep_reg = ep_add_rx_dtog(ep_reg, 1); + } else { + ep_reg &= USB_EPREG_MASK; // reversed all toggle } } else { - // Clear RX CTR interrupt flag - if (ep_addr != 0u) { - pcd_clear_rx_ep_ctr(USB, EPindex); - } + ep_reg &= USB_EPRX_STAT | USB_EPREG_MASK; // reversed all toggle except RX Status + bool const is_iso = (ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); uint8_t buf_id; - if ((wEPRegVal & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { - // ISO endpoints are double buffered - buf_id = (wEPRegVal & USB_EP_DTOG_RX) ? 0 : 1; + if (is_iso) { + buf_id = (ep_reg & USB_EP_DTOG_RX) ? 0 : 1; // ISO are double buffered } else { - buf_id = 1; + buf_id = BTABLE_BUF_RX; } - uint32_t count = btable_get_count(EPindex, buf_id); - uint16_t addr = (uint16_t) btable_get_addr(EPindex, buf_id); + uint32_t rx_count = btable_get_count(ep_id, buf_id); + uint16_t pma_addr = (uint16_t) btable_get_addr(ep_id, buf_id); - if (count != 0U) { + if (rx_count != 0) { if (xfer->ff) { - dcd_read_packet_memory_ff(xfer->ff, addr, count); + dcd_read_packet_memory_ff(xfer->ff, pma_addr, rx_count); } else { - dcd_read_packet_memory(xfer->buffer + xfer->queued_len, addr, count); + dcd_read_packet_memory(xfer->buffer + xfer->queued_len, pma_addr, rx_count); } - xfer->queued_len = (uint16_t)(xfer->queued_len + count); + xfer->queued_len = (uint16_t)(xfer->queued_len + rx_count); } - if ((count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { + if ((rx_count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { // all bytes received or short packet dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); + + if (ep_addr == 0u) { + // prepared for status packet + btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE); + } + + ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_NAK); } else { - /* Set endpoint active again for receiving more data. - * Note that isochronous endpoints stay active always */ - if ((wEPRegVal & USB_EP_TYPE_MASK) != USB_EP_ISOCHRONOUS) { - uint16_t remaining = xfer->total_len - xfer->queued_len; - uint16_t cnt = tu_min16(remaining, xfer->max_packet_size); - btable_set_rx_bufsize(EPindex, BTABLE_BUF_RX, cnt); + // Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always + if (!is_iso) { + uint16_t const cnt = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); + btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, cnt); } - pcd_set_ep_rx_status(USB, EPindex, USB_EP_RX_VALID); + ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_VALID); } } - // For EP0, prepare to receive another SETUP packet. - // Clear CTR last so that a new packet does not overwrite the packing being read. - // (Based on the docs, it seems SETUP will always be accepted after CTR is cleared) - if (ep_addr == 0u) { - // Always be prepared for a status packet... - btable_set_rx_bufsize(EPindex, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE); - pcd_clear_rx_ep_ctr(USB, EPindex); - } + pcd_set_endpoint(USB, ep_id, ep_reg); } -static void dcd_ep_ctr_handler(void) -{ +static void dcd_ep_ctr_handler(void) { uint32_t wIstr; - /* stay in loop while pending interrupts */ while (((wIstr = USB->ISTR) & USB_ISTR_CTR) != 0U) { + uint32_t ep_id = wIstr & USB_ISTR_EP_ID; if ((wIstr & USB_ISTR_DIR) == 0U) { - /* TX/IN */ - dcd_ep_ctr_tx_handler(wIstr); + dcd_ep_ctr_tx_handler(ep_id); // TX/IN } else { - /* RX/OUT*/ - dcd_ep_ctr_rx_handler(wIstr); + dcd_ep_ctr_rx_handler(ep_id); // RX/OUT } } } @@ -609,11 +594,14 @@ void edpt0_open(uint8_t rhport) { btable_set_addr(0, BTABLE_BUF_TX, pma_addr1); uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK; - ep_reg |= USB_EP_CONTROL | USB_EP_CTR_RX | USB_EP_CTR_TX; + ep_reg |= USB_EP_CONTROL; // | USB_EP_CTR_RX | USB_EP_CTR_TX; ep_reg = ep_add_tx_status(ep_reg, USB_EP_TX_NAK); ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_NAK); // no need to explicitly set DTOG bits since we aren't masked DTOG bit + // prepare for setup packet + btable_set_rx_bufsize(0, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE); + pcd_set_endpoint(USB, 0, ep_reg); } -- cgit v1.3.1 From e60efec6b71701946677440629437bedbd5bef9b Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 12:09:50 +0700 Subject: improve using ep_add_status/ep_add_dtog --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 68 +++++++++------------------ src/portable/st/stm32_fsdev/fsdev_common.h | 26 +++++----- 2 files changed, 37 insertions(+), 57 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index c7a25ba5e..c1d550ea8 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -364,10 +364,11 @@ static void dcd_ep_ctr_rx_handler(uint32_t ep_id) { dcd_event_setup_received(0, (uint8_t*) setup_packet, true); // Reset EP to NAK (in case it had been stalling) - ep_reg = ep_add_tx_status(ep_reg, USB_EP_TX_NAK); - ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_NAK); - ep_reg = ep_add_tx_dtog(ep_reg, 1); - ep_reg = ep_add_rx_dtog(ep_reg, 1); + ep_reg = ep_add_status(ep_reg, TUSB_DIR_IN, EP_STAT_NAK); + ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); + + ep_reg = ep_add_dtog(ep_reg, TUSB_DIR_IN, 1); + ep_reg = ep_add_dtog(ep_reg, TUSB_DIR_OUT, 1); } else { ep_reg &= USB_EPREG_MASK; // reversed all toggle } @@ -404,15 +405,14 @@ static void dcd_ep_ctr_rx_handler(uint32_t ep_id) { // prepared for status packet btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE); } - - ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_NAK); + ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); } else { // Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always if (!is_iso) { uint16_t const cnt = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, cnt); } - ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_VALID); + ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_VALID); } } @@ -594,9 +594,9 @@ void edpt0_open(uint8_t rhport) { btable_set_addr(0, BTABLE_BUF_TX, pma_addr1); uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK; - ep_reg |= USB_EP_CONTROL; // | USB_EP_CTR_RX | USB_EP_CTR_TX; - ep_reg = ep_add_tx_status(ep_reg, USB_EP_TX_NAK); - ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_NAK); + ep_reg |= USB_EP_CONTROL; + ep_reg = ep_add_status(ep_reg, TUSB_DIR_IN, EP_STAT_NAK); + ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); // no need to explicitly set DTOG bits since we aren't masked DTOG bit // prepare for setup packet @@ -637,15 +637,16 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { xfer_ctl_ptr(ep_addr)->max_packet_size = packet_size; xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; + ep_reg = ep_add_status(ep_reg, dir, EP_STAT_NAK); + ep_reg = ep_add_dtog(ep_reg, dir, 0); + + // reserve other direction toggle bits if (dir == TUSB_DIR_IN) { - ep_reg = ep_add_tx_status(ep_reg, USB_EP_TX_NAK); - ep_reg = ep_add_tx_dtog(ep_reg, 0); ep_reg &= ~(USB_EPRX_STAT | USB_EP_DTOG_RX); } else { - ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_NAK); - ep_reg = ep_add_rx_dtog(ep_reg, 0); ep_reg &= ~(USB_EPTX_STAT | USB_EP_DTOG_TX); } + pcd_set_endpoint(USB, ep_idx, ep_reg); return true; @@ -669,28 +670,6 @@ void dcd_edpt_close_all(uint8_t rhport) ep_buf_ptr = FSDEV_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX + 2 * CFG_TUD_ENDPOINT0_SIZE; } -/** - * Close an endpoint. - * - * This function may be called with interrupts enabled or disabled. - * - * This also clears transfers in progress, should there be any. - */ -void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) -{ - (void)rhport; - - xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); - uint8_t const ep_idx = xfer->ep_idx; - uint8_t const dir = tu_edpt_dir(ep_addr); - - if (dir == TUSB_DIR_IN) { - pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_DIS); - } else { - pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_DIS); - } -} - bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void)rhport; @@ -724,15 +703,11 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK; ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_RX | USB_EP_CTR_TX; - ep_reg = ep_add_tx_status(ep_reg, USB_EP_TX_DIS); - ep_reg = ep_add_rx_status(ep_reg, USB_EP_RX_DIS); + ep_reg = ep_add_status(ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED); + ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED); - // no need to explicitly set DTOG bits since we aren't masked DTOG bit - if (dir == TUSB_DIR_IN) { - ep_reg = ep_add_rx_dtog(ep_reg, 1); - } else { - ep_reg = ep_add_tx_dtog(ep_reg, 1); - } + ep_add_dtog(ep_reg, dir, 0); + ep_add_dtog(ep_reg, 1-dir, 1); pcd_set_endpoint(USB, ep_idx, ep_reg); @@ -838,14 +813,15 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) } } -void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) -{ +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); uint8_t const ep_idx = xfer->ep_idx; uint8_t const dir = tu_edpt_dir(ep_addr); +// uint32_t ep_reg = pcd_get_endpoint(USB, ep_idx); + if (dir == TUSB_DIR_IN) { // IN if (pcd_get_eptype(USB, ep_idx) != USB_EP_ISOCHRONOUS) { pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_NAK); diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 09bf4c2ca..676596c73 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -140,6 +140,10 @@ TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct"); #define USB_EPRX_STAT 0x3000U #endif +#ifndef USB_EPTX_STAT_Pos +#define USB_EPTX_STAT_Pos (4U) +#endif + #ifndef USB_EP_DTOG_TX_Pos #define USB_EP_DTOG_TX_Pos (6U) #endif @@ -148,6 +152,13 @@ TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct"); #define USB_EP_DTOG_RX_Pos (14U) #endif +typedef enum { + EP_STAT_DISABLED = 0, + EP_STAT_STALL = 1, + EP_STAT_NAK = 2, + EP_STAT_VALID = 3 +}ep_stat_t; + //--------------------------------------------------------------------+ // BTable //--------------------------------------------------------------------+ @@ -291,19 +302,12 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, pcd_set_endpoint(USBx, bEpIdx,regVal); } -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_tx_status(uint32_t reg, uint32_t state) { - return reg ^ state; -} -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_rx_status(uint32_t reg, uint32_t state) { - return reg ^ state; -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_tx_dtog(uint32_t reg, uint32_t state) { - return reg ^ (state << USB_EP_DTOG_TX_Pos); +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_status(uint32_t reg, tusb_dir_t dir, ep_stat_t state) { + return reg ^ (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_rx_dtog(uint32_t reg, uint32_t state) { - return reg ^ (state << USB_EP_DTOG_RX_Pos); +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_dtog(uint32_t reg, tusb_dir_t dir, uint8_t state) { + return reg ^ (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } /** -- cgit v1.3.1 From 76cc721e8f508a02f6d4f5a1f27b24ffb9a63b7b Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 12:44:02 +0700 Subject: clean up dcd_edpt_stall/clear_statll --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 53 ++++++++----------- src/portable/st/stm32_fsdev/fsdev_common.h | 75 +++------------------------ 2 files changed, 28 insertions(+), 100 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index c1d550ea8..1d3d8cd96 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -375,7 +375,7 @@ static void dcd_ep_ctr_rx_handler(uint32_t ep_id) { } else { ep_reg &= USB_EPRX_STAT | USB_EPREG_MASK; // reversed all toggle except RX Status - bool const is_iso = (ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; + bool const is_iso = ep_is_iso(ep_reg); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); uint8_t buf_id; @@ -748,9 +748,8 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { dcd_int_enable(0); } -static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) -{ - (void)rhport; +static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); uint8_t const ep_idx = xfer->ep_idx; @@ -762,7 +761,7 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) uint32_t cnt = (uint32_t) tu_min16(xfer->total_len, xfer->max_packet_size); uint16_t ep_reg = pcd_get_endpoint(USB, ep_idx); - if ((ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { + if (ep_is_iso(ep_reg)) { btable_set_rx_bufsize(ep_idx, 0, cnt); btable_set_rx_bufsize(ep_idx, 1, cnt); } else { @@ -775,10 +774,8 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) return true; } -bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) -{ +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); - xfer->buffer = buffer; xfer->ff = NULL; xfer->total_len = total_bytes; @@ -787,8 +784,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to return edpt_xfer(rhport, ep_addr); } -bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes) -{ +bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes) { xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); xfer->buffer = NULL; xfer->ff = ff; @@ -798,19 +794,19 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t return edpt_xfer(rhport, ep_addr); } -void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) -{ +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); uint8_t const ep_idx = xfer->ep_idx; uint8_t const dir = tu_edpt_dir(ep_addr); - if (dir == TUSB_DIR_IN) { - pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_STALL); - } else { - pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_STALL); - } + uint32_t ep_reg = pcd_get_endpoint(USB, ep_idx); + ep_reg |= USB_EP_CTR_RX | USB_EP_CTR_TX; // reserve CTR bits + ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); + ep_reg = ep_add_status(ep_reg, dir, EP_STAT_STALL); + + pcd_set_endpoint(USB, ep_idx, ep_reg); } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { @@ -819,23 +815,16 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); uint8_t const ep_idx = xfer->ep_idx; uint8_t const dir = tu_edpt_dir(ep_addr); + uint32_t ep_reg = pcd_get_endpoint(USB, ep_idx); + ep_reg |= USB_EP_CTR_RX | USB_EP_CTR_TX; // reserve CTR bits + ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir) | EP_DTOG_MASK(dir); -// uint32_t ep_reg = pcd_get_endpoint(USB, ep_idx); - - if (dir == TUSB_DIR_IN) { // IN - if (pcd_get_eptype(USB, ep_idx) != USB_EP_ISOCHRONOUS) { - pcd_set_ep_tx_status(USB, ep_idx, USB_EP_TX_NAK); - } - - /* Reset to DATA0 if clearing stall condition. */ - pcd_clear_tx_dtog(USB, ep_idx); - } else { // OUT - if (pcd_get_eptype(USB, ep_idx) != USB_EP_ISOCHRONOUS) { - pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_NAK); - } - /* Reset to DATA0 if clearing stall condition. */ - pcd_clear_rx_dtog(USB, ep_idx); + if (!ep_is_iso(ep_reg)) { + ep_reg = ep_add_status(ep_reg, dir, EP_STAT_NAK); } + ep_reg = ep_add_dtog(ep_reg, dir, 0); // Reset to DATA0 + + pcd_set_endpoint(USB, ep_idx, ep_reg); } #ifdef FSDEV_BUS_32BIT diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 676596c73..3b14c0334 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -159,6 +159,9 @@ typedef enum { EP_STAT_VALID = 3 }ep_stat_t; +#define EP_STAT_MASK(_dir) (3u << (USB_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8))) +#define EP_DTOG_MASK(_dir) (1u << (USB_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8))) + //--------------------------------------------------------------------+ // BTable //--------------------------------------------------------------------+ @@ -274,26 +277,6 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint pcd_set_endpoint(USBx, bEpIdx, regVal); } -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_eptype(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EP_T_FIELD; - return regVal; -} - -/** - * @brief Clears bit CTR_RX / CTR_TX in the endpoint register. - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @retval None - */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal &= ~USB_EP_CTR_RX; - regVal |= USB_EP_CTR_TX; // preserve CTR_TX (clears on writing 0) - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); regVal &= USB_EPREG_MASK; @@ -310,6 +293,10 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_dtog(uint32_t reg, tusb_dir_ return reg ^ (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } +TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) { + return (reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; +} + /** * @brief sets the status for tx transfer (bits STAT_TX[1:0]). * @param USBx USB peripheral instance register address. @@ -341,54 +328,6 @@ TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx pcd_set_endpoint(USBx, bEpIdx, regVal); } -//TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx) { -// uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); -// return (regVal & USB_EPRX_STAT) >> (12u); -//} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_RX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_tx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX|USB_EP_DTOG_TX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_rx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - if((regVal & USB_EP_DTOG_RX) != 0) { - pcd_rx_dtog(USBx,bEpIdx); - } -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_dtog(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - if((regVal & USB_EP_DTOG_TX) != 0) { - pcd_tx_dtog(USBx,bEpIdx); - } -} - -//TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) { -// uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); -// regVal |= USB_EP_KIND; -// regVal &= USB_EPREG_MASK; -// regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; -// pcd_set_endpoint(USBx, bEpIdx, regVal); -//} -// -//TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_ep_kind(USB_TypeDef * USBx, uint32_t bEpIdx) { -// uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); -// regVal &= USB_EPKIND_MASK; -// regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; -// pcd_set_endpoint(USBx, bEpIdx, regVal); -//} - #ifdef __cplusplus } #endif -- cgit v1.3.1 From 8139840d7ace72be6829eb1b879747ac5352cc31 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 15:32:37 +0700 Subject: fix ep_add_dtog() --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 5 ++--- src/portable/st/stm32_fsdev/fsdev_common.h | 17 +++-------------- 2 files changed, 5 insertions(+), 17 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 1d3d8cd96..6d185ced1 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -705,9 +705,8 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_RX | USB_EP_CTR_TX; ep_reg = ep_add_status(ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED); ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED); - - ep_add_dtog(ep_reg, dir, 0); - ep_add_dtog(ep_reg, 1-dir, 1); + ep_reg = ep_add_dtog(ep_reg, dir, 0); + ep_reg = ep_add_dtog(ep_reg, 1-dir, 1); pcd_set_endpoint(USB, ep_idx, ep_reg); diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 3b14c0334..73dc070ed 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -254,20 +254,9 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx return FSDEV_REG->ep[bEpIdx].reg; } -/** - * @brief Sets address in an endpoint register. - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @param bAddr Address. - * @retval None - */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_address(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t bAddr) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal |= bAddr; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} +//TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value) { +// FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value; +//} TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wType) { uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); -- cgit v1.3.1 From 3156f1c4a75e0aa7d506631a50da41ea7f38280d Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 16:52:00 +0700 Subject: remove all pcd ep read, modify write --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 63 ++++++++++----------- src/portable/st/stm32_fsdev/fsdev_common.h | 79 ++++++++------------------- 2 files changed, 52 insertions(+), 90 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 6d185ced1..58de125d9 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -286,21 +286,15 @@ static void handle_bus_reset(uint8_t rhport) { // Handle CTR interrupt for the TX/IN direction static void dcd_ep_ctr_tx_handler(uint32_t ep_id) { - uint32_t wEPRegVal = pcd_get_endpoint(USB, ep_id); - uint8_t ep_addr = (wEPRegVal & USB_EPADDR_FIELD) | TUSB_DIR_IN_MASK; + uint32_t ep_reg = pcd_get_endpoint(USB, ep_id) & USB_EPREG_MASK; - // Verify the CTR_TX bit is set. This was in the ST Micro code, - // but I'm not sure it's actually necessary? - if ((wEPRegVal & USB_EP_CTR_TX) == 0U) { - return; - } - - /* clear int flag */ - pcd_clear_tx_ep_ctr(USB, ep_id); + // Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary? + TU_VERIFY(ep_reg & USB_EP_CTR_TX, ); + uint8_t ep_addr = (ep_reg & USB_EPADDR_FIELD) | TUSB_DIR_IN_MASK; xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); - if ((wEPRegVal & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS) { + if (ep_is_iso(ep_reg)) { // Ignore spurious interrupts that we don't schedule // host can send IN token while there is no data to send, since ISO does not have NAK // this will result to zero length packet --> trigger interrupt (which cannot be masked) @@ -308,14 +302,19 @@ static void dcd_ep_ctr_tx_handler(uint32_t ep_id) { return; } xfer->iso_in_sending = false; - uint8_t buf_id = (wEPRegVal & USB_EP_DTOG_TX) ? 0 : 1; + uint8_t buf_id = (ep_reg & USB_EP_DTOG_TX) ? 0 : 1; btable_set_count(ep_id, buf_id, 0); } - if ((xfer->total_len != xfer->queued_len)) { - dcd_transmit_packet(xfer, ep_id); + if (xfer->total_len != xfer->queued_len) { + dcd_transmit_packet(xfer, ep_id); // also clear CTR bit } else { dcd_event_xfer_complete(0, ep_addr, xfer->total_len, XFER_RESULT_SUCCESS, true); + + // Clear CTR TX and reserved CTR RX + ep_reg = (ep_reg & ~USB_EP_CTR_TX) | USB_EP_CTR_RX; + + pcd_set_endpoint(USB, ep_id, ep_reg); } } @@ -343,15 +342,13 @@ static void dcd_ep_ctr_rx_handler(uint32_t ep_id) { #endif uint32_t ep_reg = pcd_get_endpoint(USB, ep_id); - uint8_t ep_addr = ep_reg & USB_EPADDR_FIELD; - // Verify the CTR_RX bit is set. This was in the ST Micro code, - // but I'm not sure it's actually necessary? - if ((ep_reg & USB_EP_CTR_RX) == 0U) { - return; - } + // Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary? + TU_VERIFY(ep_reg & USB_EP_CTR_RX, ); - // Clear RX CTR and reserved TX CTR + uint8_t const ep_addr = ep_reg & USB_EPADDR_FIELD; + + // Clear CTR RX and reserved CTR TX ep_reg = (ep_reg & ~USB_EP_CTR_RX) | USB_EP_CTR_TX; if (ep_reg & USB_EP_SETUP) { @@ -688,8 +685,6 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet btable_set_addr(ep_idx, 1, pma_addr2); xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; - pcd_set_eptype(USB, ep_idx, USB_EP_ISOCHRONOUS); - return true; } @@ -715,13 +710,9 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) // Currently, single-buffered, and only 64 bytes at a time (max) static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { - uint16_t len = (uint16_t)(xfer->total_len - xfer->queued_len); - if (len > xfer->max_packet_size) { - len = xfer->max_packet_size; - } - - uint16_t ep_reg = pcd_get_endpoint(USB, ep_ix); - bool const is_iso = (ep_reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; + uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); + uint16_t ep_reg = pcd_get_endpoint(USB, ep_ix) | EP_CTR_TXRX; + bool const is_iso = ep_is_iso(ep_reg); uint8_t buf_id; if (is_iso) { @@ -739,8 +730,12 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { } xfer->queued_len = (uint16_t)(xfer->queued_len + len); + ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_IN); + ep_reg = ep_add_status(ep_reg, TUSB_DIR_IN, EP_STAT_VALID); + ep_reg = ep_clear_ctr(ep_reg, TUSB_DIR_IN); + dcd_int_disable(0); - pcd_set_ep_tx_status(USB, ep_ix, USB_EP_TX_VALID); + pcd_set_endpoint(USB, ep_ix, ep_reg); if (is_iso) { xfer->iso_in_sending = true; } @@ -758,7 +753,9 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) { dcd_transmit_packet(xfer, ep_idx); } else { uint32_t cnt = (uint32_t) tu_min16(xfer->total_len, xfer->max_packet_size); - uint16_t ep_reg = pcd_get_endpoint(USB, ep_idx); + uint16_t ep_reg = pcd_get_endpoint(USB, ep_idx) | USB_EP_CTR_TX; + ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); // keep CTR TX, clear CTR RX + ep_reg = ep_add_status(ep_reg, dir, EP_STAT_VALID); if (ep_is_iso(ep_reg)) { btable_set_rx_bufsize(ep_idx, 0, cnt); @@ -767,7 +764,7 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) { btable_set_rx_bufsize(ep_idx, BTABLE_BUF_RX, cnt); } - pcd_set_ep_rx_status(USB, ep_idx, USB_EP_RX_VALID); + pcd_set_endpoint(USB, ep_idx, ep_reg); } return true; diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 73dc070ed..67ee72d0e 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -141,17 +141,20 @@ TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct"); #endif #ifndef USB_EPTX_STAT_Pos -#define USB_EPTX_STAT_Pos (4U) +#define USB_EPTX_STAT_Pos 4u #endif #ifndef USB_EP_DTOG_TX_Pos -#define USB_EP_DTOG_TX_Pos (6U) +#define USB_EP_DTOG_TX_Pos 6u #endif -#ifndef USB_EP_DTOG_RX_Pos -#define USB_EP_DTOG_RX_Pos (14U) +#ifndef USB_EP_CTR_TX_Pos +#define USB_EP_CTR_TX_Pos 7u #endif + +#define EP_CTR_TXRX (USB_EP_CTR_TX | USB_EP_CTR_RX) + typedef enum { EP_STAT_DISABLED = 0, EP_STAT_STALL = 1, @@ -244,34 +247,23 @@ TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, u // Endpoint //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wRegValue) { +TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t ep_id, uint32_t value) { (void) USBx; - FSDEV_REG->ep[bEpIdx].reg = (fsdev_bus_t) wRegValue; + FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value; } -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t bEpIdx) { - (void) USBx; - return FSDEV_REG->ep[bEpIdx].reg; -} - -//TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value) { +// write ep register with clear CTR_RX and CTR_TX mask (0 is no clear) +//TU_ATTR_ALWAYS_INLINE static inline void ep_write_with_clear_ctr(uint32_t ep_id, uint32_t value, uint32_t clear_ctr_mask) { +// value |= USB_EP_CTR_RX | USB_EP_CTR_TX; +// if (clear_ctr_mask) { +// value &= ~clear_ctr_mask; +// } // FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value; //} -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_eptype(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wType) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= (uint32_t)USB_EP_T_MASK; - regVal |= wType; - regVal |= USB_EP_CTR_RX | USB_EP_CTR_TX; // These clear on write0, so must set high - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -TU_ATTR_ALWAYS_INLINE static inline void pcd_clear_tx_ep_ctr(USB_TypeDef * USBx, uint32_t bEpIdx) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPREG_MASK; - regVal &= ~USB_EP_CTR_TX; - regVal |= USB_EP_CTR_RX; // preserve CTR_RX (clears on writing 0) - pcd_set_endpoint(USBx, bEpIdx,regVal); +TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t ep_id) { + (void) USBx; + return FSDEV_REG->ep[ep_id].reg; } TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_status(uint32_t reg, tusb_dir_t dir, ep_stat_t state) { @@ -282,39 +274,12 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_dtog(uint32_t reg, tusb_dir_ return reg ^ (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } -TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) { - return (reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_clear_ctr(uint32_t reg, tusb_dir_t dir) { + return reg & ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } -/** - * @brief sets the status for tx transfer (bits STAT_TX[1:0]). - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @param wState new state - * @retval None - */ -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_tx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPTX_DTOGMASK; - regVal ^= wState; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx, regVal); -} - -/** - * @brief sets the status for rx transfer (bits STAT_TX[1:0]) - * @param USBx USB peripheral instance register address. - * @param bEpIdx Endpoint Number. - * @param wState new state - * @retval None - */ - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_ep_rx_status(USB_TypeDef * USBx, uint32_t bEpIdx, uint32_t wState) { - uint32_t regVal = pcd_get_endpoint(USBx, bEpIdx); - regVal &= USB_EPRX_DTOGMASK; - regVal ^= wState; - regVal |= USB_EP_CTR_RX|USB_EP_CTR_TX; - pcd_set_endpoint(USBx, bEpIdx, regVal); +TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) { + return (reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; } #ifdef __cplusplus -- cgit v1.3.1 From ee831d27ac692d33ea6240b8bce24dc98f3bf74b Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 16:53:16 +0700 Subject: rename to ep_read/write(), drop USBx argument --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 34 ++++++------ src/portable/st/stm32_fsdev/fsdev_common.h | 76 +++++++++++++-------------- 2 files changed, 54 insertions(+), 56 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 58de125d9..47b3264b1 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -227,7 +227,7 @@ void dcd_init(uint8_t rhport) { // Reset endpoints to disabled for (uint32_t i = 0; i < FSDEV_EP_COUNT; i++) { // This doesn't clear all bits since some bits are "toggle", but does set the type to DISABLED. - pcd_set_endpoint(USB, i, 0u); + ep_write(i, 0u); } USB->CNTR |= USB_CNTR_RESETM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; @@ -286,7 +286,7 @@ static void handle_bus_reset(uint8_t rhport) { // Handle CTR interrupt for the TX/IN direction static void dcd_ep_ctr_tx_handler(uint32_t ep_id) { - uint32_t ep_reg = pcd_get_endpoint(USB, ep_id) & USB_EPREG_MASK; + uint32_t ep_reg = ep_read(ep_id) & USB_EPREG_MASK; // Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary? TU_VERIFY(ep_reg & USB_EP_CTR_TX, ); @@ -314,7 +314,7 @@ static void dcd_ep_ctr_tx_handler(uint32_t ep_id) { // Clear CTR TX and reserved CTR RX ep_reg = (ep_reg & ~USB_EP_CTR_TX) | USB_EP_CTR_RX; - pcd_set_endpoint(USB, ep_id, ep_reg); + ep_write(ep_id, ep_reg); } } @@ -341,7 +341,7 @@ static void dcd_ep_ctr_rx_handler(uint32_t ep_id) { } #endif - uint32_t ep_reg = pcd_get_endpoint(USB, ep_id); + uint32_t ep_reg = ep_read(ep_id); // Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary? TU_VERIFY(ep_reg & USB_EP_CTR_RX, ); @@ -413,7 +413,7 @@ static void dcd_ep_ctr_rx_handler(uint32_t ep_id) { } } - pcd_set_endpoint(USB, ep_id, ep_reg); + ep_write(ep_id, ep_reg); } static void dcd_ep_ctr_handler(void) { @@ -599,7 +599,7 @@ void edpt0_open(uint8_t rhport) { // prepare for setup packet btable_set_rx_bufsize(0, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE); - pcd_set_endpoint(USB, 0, ep_reg); + ep_write(0, ep_reg); } bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { @@ -644,7 +644,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { ep_reg &= ~(USB_EPTX_STAT | USB_EP_DTOG_TX); } - pcd_set_endpoint(USB, ep_idx, ep_reg); + ep_write(ep_idx, ep_reg); return true; } @@ -655,7 +655,7 @@ void dcd_edpt_close_all(uint8_t rhport) for (uint32_t i = 1; i < FSDEV_EP_COUNT; i++) { // Reset endpoint - pcd_set_endpoint(USB, i, 0); + ep_write(i, 0); // Clear EP allocation status ep_alloc_status[i].ep_num = 0xFF; ep_alloc_status[i].ep_type = 0xFF; @@ -703,7 +703,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) ep_reg = ep_add_dtog(ep_reg, dir, 0); ep_reg = ep_add_dtog(ep_reg, 1-dir, 1); - pcd_set_endpoint(USB, ep_idx, ep_reg); + ep_write(ep_idx, ep_reg); return true; } @@ -711,7 +711,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) // Currently, single-buffered, and only 64 bytes at a time (max) static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); - uint16_t ep_reg = pcd_get_endpoint(USB, ep_ix) | EP_CTR_TXRX; + uint16_t ep_reg = ep_read(ep_ix) | EP_CTR_TXRX; bool const is_iso = ep_is_iso(ep_reg); uint8_t buf_id; @@ -735,7 +735,7 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { ep_reg = ep_clear_ctr(ep_reg, TUSB_DIR_IN); dcd_int_disable(0); - pcd_set_endpoint(USB, ep_ix, ep_reg); + ep_write(ep_ix, ep_reg); if (is_iso) { xfer->iso_in_sending = true; } @@ -753,7 +753,7 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) { dcd_transmit_packet(xfer, ep_idx); } else { uint32_t cnt = (uint32_t) tu_min16(xfer->total_len, xfer->max_packet_size); - uint16_t ep_reg = pcd_get_endpoint(USB, ep_idx) | USB_EP_CTR_TX; + uint16_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX; ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); // keep CTR TX, clear CTR RX ep_reg = ep_add_status(ep_reg, dir, EP_STAT_VALID); @@ -764,7 +764,7 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) { btable_set_rx_bufsize(ep_idx, BTABLE_BUF_RX, cnt); } - pcd_set_endpoint(USB, ep_idx, ep_reg); + ep_write(ep_idx, ep_reg); } return true; @@ -797,12 +797,12 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { uint8_t const ep_idx = xfer->ep_idx; uint8_t const dir = tu_edpt_dir(ep_addr); - uint32_t ep_reg = pcd_get_endpoint(USB, ep_idx); + uint32_t ep_reg = ep_read(ep_idx); ep_reg |= USB_EP_CTR_RX | USB_EP_CTR_TX; // reserve CTR bits ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); ep_reg = ep_add_status(ep_reg, dir, EP_STAT_STALL); - pcd_set_endpoint(USB, ep_idx, ep_reg); + ep_write(ep_idx, ep_reg); } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { @@ -811,7 +811,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); uint8_t const ep_idx = xfer->ep_idx; uint8_t const dir = tu_edpt_dir(ep_addr); - uint32_t ep_reg = pcd_get_endpoint(USB, ep_idx); + uint32_t ep_reg = ep_read(ep_idx); ep_reg |= USB_EP_CTR_RX | USB_EP_CTR_TX; // reserve CTR bits ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir) | EP_DTOG_MASK(dir); @@ -820,7 +820,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { } ep_reg = ep_add_dtog(ep_reg, dir, 0); // Reset to DATA0 - pcd_set_endpoint(USB, ep_idx, ep_reg); + ep_write(ep_idx, ep_reg); } #ifdef FSDEV_BUS_32BIT diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 67ee72d0e..4ada26895 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -165,6 +165,43 @@ typedef enum { #define EP_STAT_MASK(_dir) (3u << (USB_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8))) #define EP_DTOG_MASK(_dir) (1u << (USB_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8))) +//--------------------------------------------------------------------+ +// Endpoint +//--------------------------------------------------------------------+ + +TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value) { + FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value; +} + +// write ep register with clear CTR_RX and CTR_TX mask (0 is no clear) +//TU_ATTR_ALWAYS_INLINE static inline void ep_write_with_clear_ctr(uint32_t ep_id, uint32_t value, uint32_t clear_ctr_mask) { +// value |= USB_EP_CTR_RX | USB_EP_CTR_TX; +// if (clear_ctr_mask) { +// value &= ~clear_ctr_mask; +// } +// FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value; +//} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_read(uint32_t ep_id) { + return FSDEV_REG->ep[ep_id].reg; +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_status(uint32_t reg, tusb_dir_t dir, ep_stat_t state) { + return reg ^ (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_dtog(uint32_t reg, tusb_dir_t dir, uint8_t state) { + return reg ^ (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_clear_ctr(uint32_t reg, tusb_dir_t dir) { + return reg & ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); +} + +TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) { + return (reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; +} + //--------------------------------------------------------------------+ // BTable //--------------------------------------------------------------------+ @@ -243,45 +280,6 @@ TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, u #endif } -//--------------------------------------------------------------------+ -// Endpoint -//--------------------------------------------------------------------+ - -TU_ATTR_ALWAYS_INLINE static inline void pcd_set_endpoint(USB_TypeDef * USBx, uint32_t ep_id, uint32_t value) { - (void) USBx; - FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value; -} - -// write ep register with clear CTR_RX and CTR_TX mask (0 is no clear) -//TU_ATTR_ALWAYS_INLINE static inline void ep_write_with_clear_ctr(uint32_t ep_id, uint32_t value, uint32_t clear_ctr_mask) { -// value |= USB_EP_CTR_RX | USB_EP_CTR_TX; -// if (clear_ctr_mask) { -// value &= ~clear_ctr_mask; -// } -// FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value; -//} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t pcd_get_endpoint(USB_TypeDef * USBx, uint32_t ep_id) { - (void) USBx; - return FSDEV_REG->ep[ep_id].reg; -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_status(uint32_t reg, tusb_dir_t dir, ep_stat_t state) { - return reg ^ (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_dtog(uint32_t reg, tusb_dir_t dir, uint8_t state) { - return reg ^ (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_clear_ctr(uint32_t reg, tusb_dir_t dir) { - return reg & ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); -} - -TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) { - return (reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; -} - #ifdef __cplusplus } #endif -- cgit v1.3.1 From ce0fdc56097efda926c2c3776eec345c920b6cc6 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 17:10:43 +0700 Subject: refactor dcd_ep_ctr_handler --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 37 +++++++++++---------------- src/portable/st/stm32_fsdev/fsdev_common.h | 2 ++ 2 files changed, 17 insertions(+), 22 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 47b3264b1..381dfdd94 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -166,7 +166,6 @@ static uint8_t remoteWakeCountdown; // When wake is requested static void handle_bus_reset(uint8_t rhport); static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix); static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr); -static void dcd_ep_ctr_handler(void); // PMA allocation/access static uint16_t ep_buf_ptr; ///< Points to first free memory location @@ -285,7 +284,7 @@ static void handle_bus_reset(uint8_t rhport) { } // Handle CTR interrupt for the TX/IN direction -static void dcd_ep_ctr_tx_handler(uint32_t ep_id) { +static void handle_ctr_tx(uint32_t ep_id) { uint32_t ep_reg = ep_read(ep_id) & USB_EPREG_MASK; // Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary? @@ -319,7 +318,7 @@ static void dcd_ep_ctr_tx_handler(uint32_t ep_id) { } // Handle CTR interrupt for the RX/OUT direction -static void dcd_ep_ctr_rx_handler(uint32_t ep_id) { +static void handle_ctr_rx(uint32_t ep_id) { #ifdef FSDEV_BUS_32BIT /* https://www.st.com/resource/en/errata_sheet/es0561-stm32h503cbebkbrb-device-errata-stmicroelectronics.pdf * From STM32H503 errata 2.15.1: Buffer description table update completes after CTR interrupt triggers @@ -416,19 +415,6 @@ static void dcd_ep_ctr_rx_handler(uint32_t ep_id) { ep_write(ep_id, ep_reg); } -static void dcd_ep_ctr_handler(void) { - uint32_t wIstr; - /* stay in loop while pending interrupts */ - while (((wIstr = USB->ISTR) & USB_ISTR_CTR) != 0U) { - uint32_t ep_id = wIstr & USB_ISTR_EP_ID; - if ((wIstr & USB_ISTR_DIR) == 0U) { - dcd_ep_ctr_tx_handler(ep_id); // TX/IN - } else { - dcd_ep_ctr_rx_handler(ep_id); // RX/OUT - } - } -} - void dcd_int_handler(uint8_t rhport) { uint32_t int_status = USB->ISTR; // const uint32_t handled_ints = USB_ISTR_CTR | USB_ISTR_RESET | USB_ISTR_WKUP @@ -453,12 +439,6 @@ void dcd_int_handler(uint8_t rhport) { return; // Don't do the rest of the things here; perhaps they've been cleared? } - if (int_status & USB_ISTR_CTR) { - /* servicing of the endpoint correct transfer interrupt */ - /* clear of the CTR flag into the sub */ - dcd_ep_ctr_handler(); - } - if (int_status & USB_ISTR_WKUP) { USB->CNTR &= ~USB_CNTR_LPMODE; USB->CNTR &= ~USB_CNTR_FSUSP; @@ -489,6 +469,19 @@ void dcd_int_handler(uint8_t rhport) { } USB->ISTR = (fsdev_bus_t)~USB_ISTR_ESOF; } + + // loop to handle all pending CTR interrupts + while (int_status & USB_ISTR_CTR) { + uint32_t const ep_id = int_status & USB_ISTR_EP_ID; + + if ((int_status & USB_ISTR_DIR) == 0U) { + handle_ctr_tx(ep_id); // TX/IN + } else { + handle_ctr_rx(ep_id); // RX/OUT or both (RX/TX !!) + } + + int_status = USB->ISTR; + } } //--------------------------------------------------------------------+ diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h index 4ada26895..dd030652b 100644 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ b/src/portable/st/stm32_fsdev/fsdev_common.h @@ -167,6 +167,8 @@ typedef enum { //--------------------------------------------------------------------+ // Endpoint +// - CTR is write 0 to clear +// - DTOG and STAT are write 1 to toggle //--------------------------------------------------------------------+ TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value) { -- cgit v1.3.1 From 26b0df2c26d31eef1a0d4012d42534f9c434f4eb Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 17:24:41 +0700 Subject: refactor xfer_ctl_ptr() to take epnum/dir to reduce computation --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 77 +++++++++++++++------------ 1 file changed, 43 insertions(+), 34 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 381dfdd94..d0a51d48e 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -165,7 +165,7 @@ static uint8_t remoteWakeCountdown; // When wake is requested // into the stack. static void handle_bus_reset(uint8_t rhport); static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix); -static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr); +static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir); // PMA allocation/access static uint16_t ep_buf_ptr; ///< Points to first free memory location @@ -183,13 +183,7 @@ static void edpt0_open(uint8_t rhport); // Inline helper //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t *xfer_ctl_ptr(uint32_t ep_addr) -{ - uint8_t epnum = tu_edpt_number(ep_addr); - uint8_t dir = tu_edpt_dir(ep_addr); - // Fix -Werror=null-dereference - TU_ASSERT(epnum < CFG_TUD_ENDPPOINT_MAX, &xfer_status[0][0]); - +TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t *xfer_ctl_ptr(uint8_t epnum, uint8_t dir) { return &xfer_status[epnum][dir]; } @@ -290,8 +284,9 @@ static void handle_ctr_tx(uint32_t ep_id) { // Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary? TU_VERIFY(ep_reg & USB_EP_CTR_TX, ); + uint8_t const ep_num = ep_reg & USB_EPADDR_FIELD; uint8_t ep_addr = (ep_reg & USB_EPADDR_FIELD) | TUSB_DIR_IN_MASK; - xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_IN); if (ep_is_iso(ep_reg)) { // Ignore spurious interrupts that we don't schedule @@ -344,11 +339,9 @@ static void handle_ctr_rx(uint32_t ep_id) { // Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary? TU_VERIFY(ep_reg & USB_EP_CTR_RX, ); + ep_reg = (ep_reg & ~USB_EP_CTR_RX) | USB_EP_CTR_TX; // Clear CTR RX and reserved CTR TX - uint8_t const ep_addr = ep_reg & USB_EPADDR_FIELD; - - // Clear CTR RX and reserved CTR TX - ep_reg = (ep_reg & ~USB_EP_CTR_RX) | USB_EP_CTR_TX; + uint8_t const ep_num = ep_reg & USB_EPADDR_FIELD; if (ep_reg & USB_EP_SETUP) { uint32_t count = btable_get_count(ep_id, BTABLE_BUF_RX); @@ -372,7 +365,7 @@ static void handle_ctr_rx(uint32_t ep_id) { ep_reg &= USB_EPRX_STAT | USB_EPREG_MASK; // reversed all toggle except RX Status bool const is_iso = ep_is_iso(ep_reg); - xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_OUT); uint8_t buf_id; if (is_iso) { @@ -394,10 +387,11 @@ static void handle_ctr_rx(uint32_t ep_id) { } if ((rx_count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { + uint8_t const ep_addr = ep_num; // all bytes received or short packet dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); - if (ep_addr == 0u) { + if (ep_num == 0) { // prepared for status packet btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE); } @@ -598,6 +592,7 @@ void edpt0_open(uint8_t rhport) { bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { (void)rhport; uint8_t const ep_addr = desc_ep->bEndpointAddress; + uint8_t const ep_num = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); const uint16_t packet_size = tu_edpt_packet_size(desc_ep); uint8_t const ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer); @@ -624,8 +619,9 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { uint16_t pma_addr = dcd_pma_alloc(packet_size, false); btable_set_addr(ep_idx, dir == TUSB_DIR_IN ? BTABLE_BUF_TX : BTABLE_BUF_RX, pma_addr); - xfer_ctl_ptr(ep_addr)->max_packet_size = packet_size; - xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); + xfer->max_packet_size = packet_size; + xfer->ep_idx = ep_idx; ep_reg = ep_add_status(ep_reg, dir, EP_STAT_NAK); ep_reg = ep_add_dtog(ep_reg, dir, 0); @@ -663,6 +659,8 @@ void dcd_edpt_close_all(uint8_t rhport) bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void)rhport; + uint8_t const ep_num = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); uint8_t const ep_idx = dcd_ep_alloc(ep_addr, TUSB_XFER_ISOCHRONOUS); /* Create a packet memory buffer area. Enable double buffering for devices with 2048 bytes PMA, @@ -676,7 +674,9 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet btable_set_addr(ep_idx, 0, pma_addr); btable_set_addr(ep_idx, 1, pma_addr2); - xfer_ctl_ptr(ep_addr)->ep_idx = ep_idx; + + xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, dir); + xfer->ep_idx = ep_idx; return true; } @@ -684,10 +684,13 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { (void)rhport; uint8_t const ep_addr = desc_ep->bEndpointAddress; - uint8_t const ep_idx = xfer_ctl_ptr(ep_addr)->ep_idx; + uint8_t const ep_num = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); + xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, dir); - xfer_ctl_ptr(ep_addr)->max_packet_size = tu_edpt_packet_size(desc_ep); + uint8_t const ep_idx = xfer->ep_idx; + + xfer->max_packet_size = tu_edpt_packet_size(desc_ep); uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK; ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_RX | USB_EP_CTR_TX; @@ -735,12 +738,11 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { dcd_int_enable(0); } -static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) { +static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { (void) rhport; - xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); uint8_t const ep_idx = xfer->ep_idx; - uint8_t const dir = tu_edpt_dir(ep_addr); if (dir == TUSB_DIR_IN) { dcd_transmit_packet(xfer, ep_idx); @@ -764,31 +766,37 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_addr) { } bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { - xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); + uint8_t const ep_num = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); + xfer->buffer = buffer; xfer->ff = NULL; xfer->total_len = total_bytes; xfer->queued_len = 0; - return edpt_xfer(rhport, ep_addr); + return edpt_xfer(rhport, ep_num, dir); } bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes) { - xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); + uint8_t const ep_num = tu_edpt_number(ep_addr); + uint8_t const dir = tu_edpt_dir(ep_addr); + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); + xfer->buffer = NULL; xfer->ff = ff; xfer->total_len = total_bytes; xfer->queued_len = 0; - return edpt_xfer(rhport, ep_addr); + return edpt_xfer(rhport, ep_num, dir); } void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; - - xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); - uint8_t const ep_idx = xfer->ep_idx; + uint8_t const ep_num = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); + uint8_t const ep_idx = xfer->ep_idx; uint32_t ep_reg = ep_read(ep_idx); ep_reg |= USB_EP_CTR_RX | USB_EP_CTR_TX; // reserve CTR bits @@ -801,11 +809,12 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; - xfer_ctl_t *xfer = xfer_ctl_ptr(ep_addr); - uint8_t const ep_idx = xfer->ep_idx; + uint8_t const ep_num = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); - uint32_t ep_reg = ep_read(ep_idx); - ep_reg |= USB_EP_CTR_RX | USB_EP_CTR_TX; // reserve CTR bits + xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); + uint8_t const ep_idx = xfer->ep_idx; + + uint32_t ep_reg = ep_read(ep_idx) | EP_CTR_TXRX; ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir) | EP_DTOG_MASK(dir); if (!ep_is_iso(ep_reg)) { -- cgit v1.3.1 From 7954d9cb4c486b263bed8984b7dd7553092150f9 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 18:15:22 +0700 Subject: rename to fsdev_type.h, use FSDDEV_REG instead of USB --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 57 ++--- src/portable/st/stm32_fsdev/fsdev_common.h | 289 -------------------------- src/portable/st/stm32_fsdev/fsdev_stm32.h | 2 + src/portable/st/stm32_fsdev/fsdev_type.h | 286 +++++++++++++++++++++++++ 4 files changed, 317 insertions(+), 317 deletions(-) delete mode 100644 src/portable/st/stm32_fsdev/fsdev_common.h create mode 100644 src/portable/st/stm32_fsdev/fsdev_type.h (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index d0a51d48e..29e1ca111 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -123,7 +123,7 @@ #error "Unknown USB IP" #endif -#include "fsdev_common.h" +#include "fsdev_type.h" //--------------------------------------------------------------------+ // Configuration @@ -197,25 +197,25 @@ void dcd_init(uint8_t rhport) { } // Perform USB peripheral reset - USB->CNTR = USB_CNTR_FRES | USB_CNTR_PDWN; + FSDEV_REG->CNTR = USB_CNTR_FRES | USB_CNTR_PDWN; for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us asm("NOP"); } - USB->CNTR &= ~USB_CNTR_PDWN; + FSDEV_REG->CNTR &= ~USB_CNTR_PDWN; // Wait startup time, for F042 and F070, this is <= 1 us. for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us asm("NOP"); } - USB->CNTR = 0; // Enable USB + FSDEV_REG->CNTR = 0; // Enable USB -#if !defined(STM32G0) && !defined(STM32H5) && !defined(STM32U5) - // BTABLE register does not exist any more on STM32G0, it is fixed to USB SRAM base address - USB->BTABLE = FSDEV_BTABLE_BASE; +#if !defined(FSDEV_BUS_32BIT) + // BTABLE register does not exist any more on 32-bit bus devices + FSDEV_REG->BTABLE = FSDEV_BTABLE_BASE; #endif - USB->ISTR = 0; // Clear pending interrupts + FSDEV_REG->ISTR = 0; // Clear pending interrupts // Reset endpoints to disabled for (uint32_t i = 0; i < FSDEV_EP_COUNT; i++) { @@ -223,7 +223,7 @@ void dcd_init(uint8_t rhport) { ep_write(i, 0u); } - USB->CNTR |= USB_CNTR_RESETM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; + FSDEV_REG->CNTR |= USB_CNTR_RESETM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; handle_bus_reset(rhport); // Enable pull-up if supported @@ -234,9 +234,9 @@ void dcd_sof_enable(uint8_t rhport, bool en) { (void)rhport; if (en) { - USB->CNTR |= USB_CNTR_SOFM; + FSDEV_REG->CNTR |= USB_CNTR_SOFM; } else { - USB->CNTR &= ~USB_CNTR_SOFM; + FSDEV_REG->CNTR &= ~USB_CNTR_SOFM; } } @@ -254,12 +254,12 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { void dcd_remote_wakeup(uint8_t rhport) { (void)rhport; - USB->CNTR |= USB_CNTR_RESUME; + FSDEV_REG->CNTR |= USB_CNTR_RESUME; remoteWakeCountdown = 4u; // required to be 1 to 15 ms, ESOF should trigger every 1ms. } static void handle_bus_reset(uint8_t rhport) { - USB->DADDR = 0u; // disable USB Function + FSDEV_REG->DADDR = 0u; // disable USB Function for (uint32_t i = 0; i < FSDEV_EP_COUNT; i++) { // Clear EP allocation status @@ -274,7 +274,7 @@ static void handle_bus_reset(uint8_t rhport) { edpt0_open(rhport); // open control endpoint (both IN & OUT) - USB->DADDR = USB_DADDR_EF; // Enable USB Function + FSDEV_REG->DADDR = USB_DADDR_EF; // Enable USB Function } // Handle CTR interrupt for the TX/IN direction @@ -410,7 +410,7 @@ static void handle_ctr_rx(uint32_t ep_id) { } void dcd_int_handler(uint8_t rhport) { - uint32_t int_status = USB->ISTR; + uint32_t int_status = FSDEV_REG->ISTR; // const uint32_t handled_ints = USB_ISTR_CTR | USB_ISTR_RESET | USB_ISTR_WKUP // | USB_ISTR_SUSP | USB_ISTR_SOF | USB_ISTR_ESOF; // unused IRQs: (USB_ISTR_PMAOVR | USB_ISTR_ERR | USB_ISTR_L1REQ ) @@ -421,23 +421,23 @@ void dcd_int_handler(uint8_t rhport) { /* Put SOF flag at the beginning of ISR in case to get least amount of jitter if it is used for timing purposes */ if (int_status & USB_ISTR_SOF) { - USB->ISTR = (fsdev_bus_t)~USB_ISTR_SOF; - dcd_event_sof(0, USB->FNR & USB_FNR_FN, true); + FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_SOF; + dcd_event_sof(0, FSDEV_REG->FNR & USB_FNR_FN, true); } if (int_status & USB_ISTR_RESET) { // USBRST is start of reset. - USB->ISTR = (fsdev_bus_t)~USB_ISTR_RESET; + FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_RESET; handle_bus_reset(rhport); dcd_event_bus_reset(0, TUSB_SPEED_FULL, true); return; // Don't do the rest of the things here; perhaps they've been cleared? } if (int_status & USB_ISTR_WKUP) { - USB->CNTR &= ~USB_CNTR_LPMODE; - USB->CNTR &= ~USB_CNTR_FSUSP; + FSDEV_REG->CNTR &= ~USB_CNTR_LPMODE; + FSDEV_REG->CNTR &= ~USB_CNTR_FSUSP; - USB->ISTR = (fsdev_bus_t)~USB_ISTR_WKUP; + FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_WKUP; dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } @@ -446,22 +446,22 @@ void dcd_int_handler(uint8_t rhport) { * these events cannot be differentiated, so we only trigger suspend. */ /* Force low-power mode in the macrocell */ - USB->CNTR |= USB_CNTR_FSUSP; - USB->CNTR |= USB_CNTR_LPMODE; + FSDEV_REG->CNTR |= USB_CNTR_FSUSP; + FSDEV_REG->CNTR |= USB_CNTR_LPMODE; /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ - USB->ISTR = (fsdev_bus_t)~USB_ISTR_SUSP; + FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_SUSP; dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true); } if (int_status & USB_ISTR_ESOF) { if (remoteWakeCountdown == 1u) { - USB->CNTR &= ~USB_CNTR_RESUME; + FSDEV_REG->CNTR &= ~USB_CNTR_RESUME; } if (remoteWakeCountdown > 0u) { remoteWakeCountdown--; } - USB->ISTR = (fsdev_bus_t)~USB_ISTR_ESOF; + FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_ESOF; } // loop to handle all pending CTR interrupts @@ -474,7 +474,7 @@ void dcd_int_handler(uint8_t rhport) { handle_ctr_rx(ep_id); // RX/OUT or both (RX/TX !!) } - int_status = USB->ISTR; + int_status = FSDEV_REG->ISTR; } } @@ -488,10 +488,11 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *req (void)rhport; if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && + request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && request->bRequest == TUSB_REQ_SET_ADDRESS) { uint8_t const dev_addr = (uint8_t)request->wValue; - USB->DADDR = (USB_DADDR_EF | dev_addr); + FSDEV_REG->DADDR = (USB_DADDR_EF | dev_addr); } } diff --git a/src/portable/st/stm32_fsdev/fsdev_common.h b/src/portable/st/stm32_fsdev/fsdev_common.h deleted file mode 100644 index dd030652b..000000000 --- a/src/portable/st/stm32_fsdev/fsdev_common.h +++ /dev/null @@ -1,289 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright(c) 2016 STMicroelectronics - * Copyright(c) N Conrad - * Copyright (c) 2024, hathach (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. - * - */ - -#ifndef TUSB_FSDEV_COMMON_H -#define TUSB_FSDEV_COMMON_H - -#ifdef __cplusplus - extern "C" { -#endif - -#include "stdint.h" - -// If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it -// Both of these MUST be a multiple of 2, and are in byte units. -#ifndef FSDEV_BTABLE_BASE -#define FSDEV_BTABLE_BASE 0U -#endif - -TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 bytes"); - -// FSDEV_PMA_SIZE is PMA buffer size in bytes. -// - 512-byte devices, access with a stride of two words (use every other 16-bit address) -// - 1024-byte devices, access with a stride of one word (use every 16-bit address) -// - 2048-byte devices, access with 32-bit address - -// For purposes of accessing the packet -#if FSDEV_PMA_SIZE == 512 - #define FSDEV_PMA_STRIDE (2u) // 1x16 bit access scheme - #define pma_aligned TU_ATTR_ALIGNED(4) -#elif FSDEV_PMA_SIZE == 1024 - #define FSDEV_PMA_STRIDE (1u) // 2x16 bit access scheme - #define pma_aligned -#elif FSDEV_PMA_SIZE == 2048 - #ifndef FSDEV_BUS_32BIT - #warning "FSDEV_PMA_SIZE is 2048, but FSDEV_BUS_32BIT is not defined" - #endif - #define FSDEV_PMA_STRIDE (1u) // 32 bit access scheme - #define pma_aligned -#endif - -enum { - BTABLE_BUF_TX = 0, - BTABLE_BUF_RX = 1 -}; - -// hardware limit endpoint -#define FSDEV_EP_COUNT 8 - -// Buffer Table is located in Packet Memory Area (PMA) and therefore its address access is forced to either -// 16-bit or 32-bit depending on FSDEV_BUS_32BIT. -typedef struct { - union { - // 0: TX (IN), 1: RX (OUT) - - // strictly 16-bit access (could be 32-bit aligned) - struct { - volatile pma_aligned uint16_t addr; - volatile pma_aligned uint16_t count; - } ep16[FSDEV_EP_COUNT][2]; - - // strictly 32-bit access - struct { - volatile uint32_t count_addr; - } ep32[FSDEV_EP_COUNT][2]; - }; -} fsdev_btable_t; - -TU_VERIFY_STATIC(sizeof(fsdev_btable_t) == FSDEV_EP_COUNT*8*FSDEV_PMA_STRIDE, "size is not correct"); -TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE does not fit in PMA RAM"); - - -#define FSDEV_BTABLE ((volatile fsdev_btable_t*) (USB_PMAADDR+FSDEV_BTABLE_BASE)) - -// volatile 32-bit aligned -#define _va32 volatile TU_ATTR_ALIGNED(4) - -// The fsdev_bus_t type can be used for both register and PMA access necessities -// For type-safety create a new macro for the volatile address of PMAADDR -// The compiler should warn us if we cast it to a non-volatile type? -#ifdef FSDEV_BUS_32BIT -typedef uint32_t fsdev_bus_t; -static volatile uint32_t * const pma32 = (volatile uint32_t*)USB_PMAADDR; - -#else -typedef uint16_t fsdev_bus_t; -// Volatile is also needed to prevent the optimizer from changing access to 32-bit (as 32-bit access is forbidden) -static volatile uint16_t * const pma = (volatile uint16_t*)USB_PMAADDR; -#endif - -typedef struct { - struct { - _va32 fsdev_bus_t reg; - }ep[FSDEV_EP_COUNT]; - - _va32 uint32_t RESERVED7[8]; // Reserved - _va32 fsdev_bus_t CNTR; // 40: Control register - _va32 fsdev_bus_t ISTR; // 44: Interrupt status register - _va32 fsdev_bus_t FNR; // 48: Frame number register - _va32 fsdev_bus_t DADDR; // 4C: Device address register - _va32 fsdev_bus_t BTABLE; // 50: Buffer Table address register (16-bit only) - _va32 fsdev_bus_t LPMCSR; // 54: LPM Control and Status Register (32-bit only) - _va32 fsdev_bus_t BCDR; // 58: Battery Charging Detector Register (32-bit only) -} fsdev_regs_t; - -TU_VERIFY_STATIC(offsetof(fsdev_regs_t, CNTR) == 0x40, "Wrong offset"); -TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct"); - -#define FSDEV_REG ((fsdev_regs_t*) FSDEV_REG_BASE) - - -#ifndef USB_EPTX_STAT -#define USB_EPTX_STAT 0x0030U -#endif - -#ifndef USB_EPRX_STAT -#define USB_EPRX_STAT 0x3000U -#endif - -#ifndef USB_EPTX_STAT_Pos -#define USB_EPTX_STAT_Pos 4u -#endif - -#ifndef USB_EP_DTOG_TX_Pos -#define USB_EP_DTOG_TX_Pos 6u -#endif - -#ifndef USB_EP_CTR_TX_Pos -#define USB_EP_CTR_TX_Pos 7u -#endif - - -#define EP_CTR_TXRX (USB_EP_CTR_TX | USB_EP_CTR_RX) - -typedef enum { - EP_STAT_DISABLED = 0, - EP_STAT_STALL = 1, - EP_STAT_NAK = 2, - EP_STAT_VALID = 3 -}ep_stat_t; - -#define EP_STAT_MASK(_dir) (3u << (USB_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8))) -#define EP_DTOG_MASK(_dir) (1u << (USB_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8))) - -//--------------------------------------------------------------------+ -// Endpoint -// - CTR is write 0 to clear -// - DTOG and STAT are write 1 to toggle -//--------------------------------------------------------------------+ - -TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value) { - FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value; -} - -// write ep register with clear CTR_RX and CTR_TX mask (0 is no clear) -//TU_ATTR_ALWAYS_INLINE static inline void ep_write_with_clear_ctr(uint32_t ep_id, uint32_t value, uint32_t clear_ctr_mask) { -// value |= USB_EP_CTR_RX | USB_EP_CTR_TX; -// if (clear_ctr_mask) { -// value &= ~clear_ctr_mask; -// } -// FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value; -//} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_read(uint32_t ep_id) { - return FSDEV_REG->ep[ep_id].reg; -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_status(uint32_t reg, tusb_dir_t dir, ep_stat_t state) { - return reg ^ (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_dtog(uint32_t reg, tusb_dir_t dir, uint8_t state) { - return reg ^ (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_clear_ctr(uint32_t reg, tusb_dir_t dir) { - return reg & ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); -} - -TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) { - return (reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; -} - -//--------------------------------------------------------------------+ -// BTable -//--------------------------------------------------------------------+ - -TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uint8_t buf_id) { -#ifdef FSDEV_BUS_32BIT - return FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr & 0x0000FFFFu; -#else - return FSDEV_BTABLE->ep16[ep_id][buf_id].addr; -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t buf_id, uint16_t addr) { -#ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; - count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); - FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; -#else - FSDEV_BTABLE->ep16[ep_id][buf_id].addr = addr; -#endif -} - -TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_count(uint32_t ep_id, uint8_t buf_id) { - uint16_t count; -#ifdef FSDEV_BUS_32BIT - count = (FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr >> 16); -#else - count = FSDEV_BTABLE->ep16[ep_id][buf_id].count; -#endif - return count & 0x3FFU; -} - -TU_ATTR_ALWAYS_INLINE static inline void btable_set_count(uint32_t ep_id, uint8_t buf_id, uint16_t byte_count) { -#ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; - count_addr = (count_addr & ~0x03FF0000u) | ((byte_count & 0x3FFu) << 16); - FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; -#else - uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][buf_id].count; - cnt = (cnt & ~0x3FFU) | (byte_count & 0x3FFU); - FSDEV_BTABLE->ep16[ep_id][buf_id].count = cnt; -#endif -} - -/* Aligned buffer size according to hardware */ -TU_ATTR_ALWAYS_INLINE static inline uint16_t pma_align_buffer_size(uint16_t size, uint8_t* blsize, uint8_t* num_block) { - /* The STM32 full speed USB peripheral supports only a limited set of - * buffer sizes given by the RX buffer entry format in the USB_BTABLE. */ - uint16_t block_in_bytes; - if (size > 62) { - block_in_bytes = 32; - *blsize = 1; - } else { - block_in_bytes = 2; - *blsize = 0; - } - - *num_block = tu_div_ceil(size, block_in_bytes); - - return (*num_block) * block_in_bytes; -} - -TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint32_t wCount) { - uint8_t blsize, num_block; - (void) pma_align_buffer_size(wCount, &blsize, &num_block); - - /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ - uint16_t bl_nb = (blsize << 15) | ((num_block - blsize) << 10); - -#ifdef FSDEV_BUS_32BIT - uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; - count_addr = (bl_nb << 16) | (count_addr & 0x0000FFFFu); - FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; -#else - FSDEV_BTABLE->ep16[ep_id][buf_id].count = bl_nb; -#endif -} - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index f20505f28..bb2c72fd1 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -198,6 +198,8 @@ #define FSDEV_REG_BASE USB_BASE #elif defined(USB_DRD_BASE) #define FSDEV_REG_BASE USB_DRD_BASE +#elif defined(USB_DRD_FS_BASE) + #define FSDEV_REG_BASE USB_DRD_FS_BASE #else #error "FSDEV_REG_BASE not defined" #endif diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h new file mode 100644 index 000000000..116017f63 --- /dev/null +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -0,0 +1,286 @@ +/* + * The MIT License (MIT) + * + * Copyright(c) 2016 STMicroelectronics + * Copyright(c) N Conrad + * Copyright (c) 2024, hathach (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. + * + */ + +#ifndef TUSB_FSDEV_TYPE_H +#define TUSB_FSDEV_TYPE_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "stdint.h" + +// If sharing with CAN, one can set this to be non-zero to give CAN space where it wants it +// Both of these MUST be a multiple of 2, and are in byte units. +#ifndef FSDEV_BTABLE_BASE +#define FSDEV_BTABLE_BASE 0U +#endif + +TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 bytes"); + +// FSDEV_PMA_SIZE is PMA buffer size in bytes. +// - 512-byte devices, access with a stride of two words (use every other 16-bit address) +// - 1024-byte devices, access with a stride of one word (use every 16-bit address) +// - 2048-byte devices, access with 32-bit address + +// For purposes of accessing the packet +#if FSDEV_PMA_SIZE == 512 + #define FSDEV_PMA_STRIDE (2u) // 1x16 bit access scheme + #define pma_aligned TU_ATTR_ALIGNED(4) +#elif FSDEV_PMA_SIZE == 1024 + #define FSDEV_PMA_STRIDE (1u) // 2x16 bit access scheme + #define pma_aligned +#elif FSDEV_PMA_SIZE == 2048 + #ifndef FSDEV_BUS_32BIT + #warning "FSDEV_PMA_SIZE is 2048, but FSDEV_BUS_32BIT is not defined" + #endif + #define FSDEV_PMA_STRIDE (1u) // 32 bit access scheme + #define pma_aligned +#endif + +//--------------------------------------------------------------------+ +// BTable Typedef +//--------------------------------------------------------------------+ +enum { + BTABLE_BUF_TX = 0, + BTABLE_BUF_RX = 1 +}; + +// hardware limit endpoint +#define FSDEV_EP_COUNT 8 + +// Buffer Table is located in Packet Memory Area (PMA) and therefore its address access is forced to either +// 16-bit or 32-bit depending on FSDEV_BUS_32BIT. +typedef struct { + union { + // 0: TX (IN), 1: RX (OUT) + + // strictly 16-bit access (could be 32-bit aligned) + struct { + volatile pma_aligned uint16_t addr; + volatile pma_aligned uint16_t count; + } ep16[FSDEV_EP_COUNT][2]; + + // strictly 32-bit access + struct { + volatile uint32_t count_addr; + } ep32[FSDEV_EP_COUNT][2]; + }; +} fsdev_btable_t; + +TU_VERIFY_STATIC(sizeof(fsdev_btable_t) == FSDEV_EP_COUNT*8*FSDEV_PMA_STRIDE, "size is not correct"); +TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE does not fit in PMA RAM"); + +#define FSDEV_BTABLE ((volatile fsdev_btable_t*) (USB_PMAADDR+FSDEV_BTABLE_BASE)) + +//--------------------------------------------------------------------+ +// Registers Typedef +//--------------------------------------------------------------------+ + +// volatile 32-bit aligned +#define _va32 volatile TU_ATTR_ALIGNED(4) + +// The fsdev_bus_t type can be used for both register and PMA access necessities +// For type-safety create a new macro for the volatile address of PMAADDR +// The compiler should warn us if we cast it to a non-volatile type? +#ifdef FSDEV_BUS_32BIT +typedef uint32_t fsdev_bus_t; +static volatile uint32_t * const pma32 = (volatile uint32_t*)USB_PMAADDR; + +#else +typedef uint16_t fsdev_bus_t; +// Volatile is also needed to prevent the optimizer from changing access to 32-bit (as 32-bit access is forbidden) +static volatile uint16_t * const pma = (volatile uint16_t*)USB_PMAADDR; +#endif + +typedef struct { + struct { + _va32 fsdev_bus_t reg; + }ep[FSDEV_EP_COUNT]; + + _va32 uint32_t RESERVED7[8]; // Reserved + _va32 fsdev_bus_t CNTR; // 40: Control register + _va32 fsdev_bus_t ISTR; // 44: Interrupt status register + _va32 fsdev_bus_t FNR; // 48: Frame number register + _va32 fsdev_bus_t DADDR; // 4C: Device address register + _va32 fsdev_bus_t BTABLE; // 50: Buffer Table address register (16-bit only) + _va32 fsdev_bus_t LPMCSR; // 54: LPM Control and Status Register (32-bit only) + _va32 fsdev_bus_t BCDR; // 58: Battery Charging Detector Register (32-bit only) +} fsdev_regs_t; + +TU_VERIFY_STATIC(offsetof(fsdev_regs_t, CNTR) == 0x40, "Wrong offset"); +TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct"); + +#define FSDEV_REG ((fsdev_regs_t*) FSDEV_REG_BASE) + + +#ifndef USB_EPTX_STAT +#define USB_EPTX_STAT 0x0030U +#endif + +#ifndef USB_EPRX_STAT +#define USB_EPRX_STAT 0x3000U +#endif + +#ifndef USB_EPTX_STAT_Pos +#define USB_EPTX_STAT_Pos 4u +#endif + +#ifndef USB_EP_DTOG_TX_Pos +#define USB_EP_DTOG_TX_Pos 6u +#endif + +#ifndef USB_EP_CTR_TX_Pos +#define USB_EP_CTR_TX_Pos 7u +#endif + + +#define EP_CTR_TXRX (USB_EP_CTR_TX | USB_EP_CTR_RX) + +typedef enum { + EP_STAT_DISABLED = 0, + EP_STAT_STALL = 1, + EP_STAT_NAK = 2, + EP_STAT_VALID = 3 +}ep_stat_t; + +#define EP_STAT_MASK(_dir) (3u << (USB_EPTX_STAT_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8))) +#define EP_DTOG_MASK(_dir) (1u << (USB_EP_DTOG_TX_Pos + ((_dir) == TUSB_DIR_IN ? 0 : 8))) + +//--------------------------------------------------------------------+ +// Endpoint Helper +// - CTR is write 0 to clear +// - DTOG and STAT are write 1 to toggle +//--------------------------------------------------------------------+ + +TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value) { + FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value; +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_read(uint32_t ep_id) { + return FSDEV_REG->ep[ep_id].reg; +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_status(uint32_t reg, tusb_dir_t dir, ep_stat_t state) { + return reg ^ (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_dtog(uint32_t reg, tusb_dir_t dir, uint8_t state) { + return reg ^ (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_clear_ctr(uint32_t reg, tusb_dir_t dir) { + return reg & ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); +} + +TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) { + return (reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; +} + +//--------------------------------------------------------------------+ +// BTable Helper +//--------------------------------------------------------------------+ + +TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_addr(uint32_t ep_id, uint8_t buf_id) { +#ifdef FSDEV_BUS_32BIT + return FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr & 0x0000FFFFu; +#else + return FSDEV_BTABLE->ep16[ep_id][buf_id].addr; +#endif +} + +TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t buf_id, uint16_t addr) { +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; + count_addr = (count_addr & 0xFFFF0000u) | (addr & 0x0000FFFCu); + FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; +#else + FSDEV_BTABLE->ep16[ep_id][buf_id].addr = addr; +#endif +} + +TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_count(uint32_t ep_id, uint8_t buf_id) { + uint16_t count; +#ifdef FSDEV_BUS_32BIT + count = (FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr >> 16); +#else + count = FSDEV_BTABLE->ep16[ep_id][buf_id].count; +#endif + return count & 0x3FFU; +} + +TU_ATTR_ALWAYS_INLINE static inline void btable_set_count(uint32_t ep_id, uint8_t buf_id, uint16_t byte_count) { +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; + count_addr = (count_addr & ~0x03FF0000u) | ((byte_count & 0x3FFu) << 16); + FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; +#else + uint16_t cnt = FSDEV_BTABLE->ep16[ep_id][buf_id].count; + cnt = (cnt & ~0x3FFU) | (byte_count & 0x3FFU); + FSDEV_BTABLE->ep16[ep_id][buf_id].count = cnt; +#endif +} + +/* Aligned buffer size according to hardware */ +TU_ATTR_ALWAYS_INLINE static inline uint16_t pma_align_buffer_size(uint16_t size, uint8_t* blsize, uint8_t* num_block) { + /* The STM32 full speed USB peripheral supports only a limited set of + * buffer sizes given by the RX buffer entry format in the USB_BTABLE. */ + uint16_t block_in_bytes; + if (size > 62) { + block_in_bytes = 32; + *blsize = 1; + } else { + block_in_bytes = 2; + *blsize = 0; + } + + *num_block = tu_div_ceil(size, block_in_bytes); + + return (*num_block) * block_in_bytes; +} + +TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint32_t wCount) { + uint8_t blsize, num_block; + (void) pma_align_buffer_size(wCount, &blsize, &num_block); + + /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ + uint16_t bl_nb = (blsize << 15) | ((num_block - blsize) << 10); + +#ifdef FSDEV_BUS_32BIT + uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; + count_addr = (bl_nb << 16) | (count_addr & 0x0000FFFFu); + FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr = count_addr; +#else + FSDEV_BTABLE->ep16[ep_id][buf_id].count = bl_nb; +#endif +} + +#ifdef __cplusplus + } +#endif + +#endif -- cgit v1.3.1 From 7d9b39946601e1c7cd393d09db40892bca5cf477 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 18:28:17 +0700 Subject: fix ep type bulk typo --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 29e1ca111..346cf8164 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -488,7 +488,6 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *req (void)rhport; if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && - request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && request->bRequest == TUSB_REQ_SET_ADDRESS) { uint8_t const dev_addr = (uint8_t)request->wValue; @@ -605,7 +604,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { // Set type switch (desc_ep->bmAttributes.xfer) { case TUSB_XFER_BULK: - ep_reg |= USB_EP_CONTROL; // FIXME should it be bulk? + ep_reg |= USB_EP_BULK; break; case TUSB_XFER_INTERRUPT: ep_reg |= USB_EP_INTERRUPT; -- cgit v1.3.1 From 332f75cd44b58d340d36f30dbeb64742767a521c Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 31 Jul 2024 20:53:42 +0700 Subject: simplify read/write 16-bit packet --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 139 +++++++++++++------------- src/portable/st/stm32_fsdev/fsdev_ch32.h | 23 ----- src/portable/st/stm32_fsdev/fsdev_type.h | 38 ++++--- 3 files changed, 87 insertions(+), 113 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 346cf8164..cff328418 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -171,8 +171,8 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir); static uint16_t ep_buf_ptr; ///< Points to first free memory location static uint32_t dcd_pma_alloc(uint16_t len, bool dbuf); static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type); -static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes); -static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes); +static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes); +static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes); static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNBytes); static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBytes); @@ -828,10 +828,10 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { #ifdef FSDEV_BUS_32BIT static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes) { const uint8_t *src8 = src; - volatile uint32_t *dst32 = (volatile uint32_t *)(USB_PMAADDR + dst); + volatile uint32_t *pma32 = (volatile uint32_t *)(USB_PMAADDR + dst); for (uint32_t n = wNBytes / 4; n > 0; --n) { - *dst32++ = tu_unaligned_read32(src8); + *pma32++ = tu_unaligned_read32(src8); src8 += 4; } @@ -849,11 +849,41 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui } } - *dst32 = wrVal; + *pma32 = wrVal; } return true; } + +static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes) { + uint8_t *dst8 = dst; + volatile uint32_t *src32 = (volatile uint32_t *)(USB_PMAADDR + src); + + for (uint32_t n = wNBytes / 4; n > 0; --n) { + tu_unaligned_write32(dst8, *src32++); + dst8 += 4; + } + + uint16_t odd = wNBytes & 0x03; + if (odd) { + uint32_t rdVal = *src32; + + *dst8 = tu_u32_byte0(rdVal); + odd--; + + if (odd) { + *++dst8 = tu_u32_byte1(rdVal); + odd--; + + if (odd) { + *++dst8 = tu_u32_byte2(rdVal); + } + } + } + + return true; +} + #else // Packet buffer access can only be 8- or 16-bit. /** @@ -862,26 +892,52 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui * @param dst, byte address in PMA; must be 16-bit aligned * @param src pointer to user memory area. * @param wPMABufAddr address into PMA. - * @param wNBytes no. of bytes to be copied. + * @param nbytes no. of bytes to be copied. * @retval None */ -static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes) { - uint32_t n = (uint32_t)wNBytes >> 1U; +static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes) { + uint32_t n16 = (uint32_t)nbytes >> 1U; const uint8_t *src8 = src; - volatile uint16_t *pdw16 = &pma[FSDEV_PMA_STRIDE * (dst >> 1)]; + fsdev_pma16_t* pma16 = (fsdev_pma16_t*) (USB_PMAADDR + FSDEV_PMA_STRIDE * dst); - while (n--) { - *pdw16 = tu_unaligned_read16(src8); + while (n16--) { + pma16->u16 = tu_unaligned_read16(src8); src8 += 2; - pdw16 += FSDEV_PMA_STRIDE; + pma16++; + } + + if (nbytes & 0x01) { + pma16->u16 = (uint16_t) *src8; + } + + return true; +} + +/** + * @brief Copy a buffer from packet memory area (PMA) to user memory area. + * Uses unaligned for system memory and 16-bit access of packet memory + * @param nbytes no. of bytes to be copied. + * @retval None + */ +static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes) { + uint32_t n16 = (uint32_t)nbytes >> 1U; + fsdev_pma16_t* pma16 = (fsdev_pma16_t*) (USB_PMAADDR + FSDEV_PMA_STRIDE * src); + uint8_t *dst8 = (uint8_t *)dst; + + while (n16--) { + uint16_t temp16 = pma16->u16; + tu_unaligned_write16(dst8, temp16); + dst8 += 2; + pma16++; } - if (wNBytes & 0x01) { - *pdw16 = (uint16_t) *src8; + if (nbytes & 0x01) { + *dst8++ = tu_u16_low(pma16->u16); } return true; } + #endif /** @@ -959,61 +1015,6 @@ static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNB return true; } -#ifdef FSDEV_BUS_32BIT -static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes) { - uint8_t *dst8 = dst; - volatile uint32_t *src32 = (volatile uint32_t *)(USB_PMAADDR + src); - - for (uint32_t n = wNBytes / 4; n > 0; --n) { - tu_unaligned_write32(dst8, *src32++); - dst8 += 4; - } - - uint16_t odd = wNBytes & 0x03; - if (odd) { - uint32_t rdVal = *src32; - - *dst8 = tu_u32_byte0(rdVal); - odd--; - - if (odd) { - *++dst8 = tu_u32_byte1(rdVal); - odd--; - - if (odd) { - *++dst8 = tu_u32_byte2(rdVal); - } - } - } - - return true; -} -#else -/** - * @brief Copy a buffer from packet memory area (PMA) to user memory area. - * Uses unaligned for system memory and 16-bit access of packet memory - * @param wNBytes no. of bytes to be copied. - * @retval None - */ -static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes) { - uint32_t n = (uint32_t)wNBytes >> 1U; - volatile const uint16_t *pdw16 = &pma[FSDEV_PMA_STRIDE * (src >> 1)]; - uint8_t *dst8 = (uint8_t *)dst; - - while (n--) { - tu_unaligned_write16(dst8, *pdw16); - dst8 += 2; - pdw16 += FSDEV_PMA_STRIDE; - } - - if (wNBytes & 0x01) { - *dst8++ = tu_u16_low(*pdw16); - } - - return true; -} -#endif - /** * @brief Copy a buffer from user packet memory area (PMA) to FIFO. * Uses byte-access of system memory and 16-bit access of packet memory diff --git a/src/portable/st/stm32_fsdev/fsdev_ch32.h b/src/portable/st/stm32_fsdev/fsdev_ch32.h index 81ef08b8a..8c0961bb9 100644 --- a/src/portable/st/stm32_fsdev/fsdev_ch32.h +++ b/src/portable/st/stm32_fsdev/fsdev_ch32.h @@ -54,29 +54,6 @@ #endif #define FSDEV_PMA_SIZE (512u) - -#if 1 -// volatile 32-bit aligned -#define _vaa32 volatile TU_ATTR_ALIGNED(4) - -typedef struct { - _vaa32 uint16_t EP0R; // 00: USB Endpoint 0 register - _vaa32 uint16_t EP1R; // 04: USB Endpoint 1 register - _vaa32 uint16_t EP2R; // 08: USB Endpoint 2 register - _vaa32 uint16_t EP3R; // 0C: USB Endpoint 3 register - _vaa32 uint16_t EP4R; // 10: USB Endpoint 4 register - _vaa32 uint16_t EP5R; // 14: USB Endpoint 5 register - _vaa32 uint16_t EP6R; // 18: USB Endpoint 6 register - _vaa32 uint16_t EP7R; // 1C: USB Endpoint 7 register - _vaa32 uint16_t RESERVED7[16]; // Reserved - _vaa32 uint16_t CNTR; // 40: Control register - _vaa32 uint16_t ISTR; // 44: Interrupt status register - _vaa32 uint16_t FNR; // 48: Frame number register - _vaa32 uint16_t DADDR; // 4C: Device address register - _vaa32 uint16_t BTABLE; // 50: Buffer Table address register -} USB_TypeDef; -#endif - #define FSDEV_REG_BASE 0x40005C00UL #define USB_BASE (APB1PERIPH_BASE + 0x00005C00UL) /*!< USB_IP Peripheral Registers base address */ diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h index 116017f63..e4a0f3f28 100644 --- a/src/portable/st/stm32_fsdev/fsdev_type.h +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -75,21 +75,19 @@ enum { // Buffer Table is located in Packet Memory Area (PMA) and therefore its address access is forced to either // 16-bit or 32-bit depending on FSDEV_BUS_32BIT. -typedef struct { - union { - // 0: TX (IN), 1: RX (OUT) - - // strictly 16-bit access (could be 32-bit aligned) - struct { - volatile pma_aligned uint16_t addr; - volatile pma_aligned uint16_t count; - } ep16[FSDEV_EP_COUNT][2]; - - // strictly 32-bit access - struct { - volatile uint32_t count_addr; - } ep32[FSDEV_EP_COUNT][2]; - }; +typedef union { + // 0: TX (IN), 1: RX (OUT) + + // strictly 16-bit access (could be 32-bit aligned) + struct { + volatile pma_aligned uint16_t addr; + volatile pma_aligned uint16_t count; + } ep16[FSDEV_EP_COUNT][2]; + + // strictly 32-bit access + struct { + volatile uint32_t count_addr; + } ep32[FSDEV_EP_COUNT][2]; } fsdev_btable_t; TU_VERIFY_STATIC(sizeof(fsdev_btable_t) == FSDEV_EP_COUNT*8*FSDEV_PMA_STRIDE, "size is not correct"); @@ -97,6 +95,10 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE #define FSDEV_BTABLE ((volatile fsdev_btable_t*) (USB_PMAADDR+FSDEV_BTABLE_BASE)) +typedef struct { + volatile pma_aligned uint16_t u16; +} fsdev_pma16_t; + //--------------------------------------------------------------------+ // Registers Typedef //--------------------------------------------------------------------+ @@ -105,16 +107,10 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE #define _va32 volatile TU_ATTR_ALIGNED(4) // The fsdev_bus_t type can be used for both register and PMA access necessities -// For type-safety create a new macro for the volatile address of PMAADDR -// The compiler should warn us if we cast it to a non-volatile type? #ifdef FSDEV_BUS_32BIT typedef uint32_t fsdev_bus_t; -static volatile uint32_t * const pma32 = (volatile uint32_t*)USB_PMAADDR; - #else typedef uint16_t fsdev_bus_t; -// Volatile is also needed to prevent the optimizer from changing access to 32-bit (as 32-bit access is forbidden) -static volatile uint16_t * const pma = (volatile uint16_t*)USB_PMAADDR; #endif typedef struct { -- cgit v1.3.1 From af8609e96e269a423449cfb679977c150494c3a4 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 1 Aug 2024 18:36:28 +0700 Subject: fsdev improve ep bit manipulation --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 46 +++++++++++++-------------- src/portable/st/stm32_fsdev/fsdev_type.h | 17 +++++----- 2 files changed, 31 insertions(+), 32 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index cff328418..d1c40deb6 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -353,11 +353,11 @@ static void handle_ctr_rx(uint32_t ep_id) { dcd_event_setup_received(0, (uint8_t*) setup_packet, true); // Reset EP to NAK (in case it had been stalling) - ep_reg = ep_add_status(ep_reg, TUSB_DIR_IN, EP_STAT_NAK); - ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); + ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_NAK); + ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); - ep_reg = ep_add_dtog(ep_reg, TUSB_DIR_IN, 1); - ep_reg = ep_add_dtog(ep_reg, TUSB_DIR_OUT, 1); + ep_add_dtog(&ep_reg, TUSB_DIR_IN, 1); + ep_add_dtog(&ep_reg, TUSB_DIR_OUT, 1); } else { ep_reg &= USB_EPREG_MASK; // reversed all toggle } @@ -395,14 +395,14 @@ static void handle_ctr_rx(uint32_t ep_id) { // prepared for status packet btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE); } - ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); + ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); } else { // Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always if (!is_iso) { uint16_t const cnt = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, cnt); } - ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_VALID); + ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_VALID); } } @@ -579,8 +579,8 @@ void edpt0_open(uint8_t rhport) { uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK; ep_reg |= USB_EP_CONTROL; - ep_reg = ep_add_status(ep_reg, TUSB_DIR_IN, EP_STAT_NAK); - ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); + ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_NAK); + ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); // no need to explicitly set DTOG bits since we aren't masked DTOG bit // prepare for setup packet @@ -623,8 +623,8 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { xfer->max_packet_size = packet_size; xfer->ep_idx = ep_idx; - ep_reg = ep_add_status(ep_reg, dir, EP_STAT_NAK); - ep_reg = ep_add_dtog(ep_reg, dir, 0); + ep_add_status(&ep_reg, dir, EP_STAT_NAK); + ep_add_dtog(&ep_reg, dir, 0); // reserve other direction toggle bits if (dir == TUSB_DIR_IN) { @@ -694,10 +694,10 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK; ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_RX | USB_EP_CTR_TX; - ep_reg = ep_add_status(ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED); - ep_reg = ep_add_status(ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED); - ep_reg = ep_add_dtog(ep_reg, dir, 0); - ep_reg = ep_add_dtog(ep_reg, 1-dir, 1); + ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED); + ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED); + ep_add_dtog(&ep_reg, dir, 0); + ep_add_dtog(&ep_reg, 1-dir, 1); ep_write(ep_idx, ep_reg); @@ -707,7 +707,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) // Currently, single-buffered, and only 64 bytes at a time (max) static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); - uint16_t ep_reg = ep_read(ep_ix) | EP_CTR_TXRX; + uint32_t ep_reg = ep_read(ep_ix) | EP_CTR_TXRX; bool const is_iso = ep_is_iso(ep_reg); uint8_t buf_id; @@ -727,8 +727,8 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { xfer->queued_len = (uint16_t)(xfer->queued_len + len); ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_IN); - ep_reg = ep_add_status(ep_reg, TUSB_DIR_IN, EP_STAT_VALID); - ep_reg = ep_clear_ctr(ep_reg, TUSB_DIR_IN); + ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_VALID); + ep_clear_ctr(&ep_reg, TUSB_DIR_IN); dcd_int_disable(0); ep_write(ep_ix, ep_reg); @@ -748,9 +748,9 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { dcd_transmit_packet(xfer, ep_idx); } else { uint32_t cnt = (uint32_t) tu_min16(xfer->total_len, xfer->max_packet_size); - uint16_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX; - ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); // keep CTR TX, clear CTR RX - ep_reg = ep_add_status(ep_reg, dir, EP_STAT_VALID); + uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX; // keep CTR TX, clear CTR RX + ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); + ep_add_status(&ep_reg, dir, EP_STAT_VALID); if (ep_is_iso(ep_reg)) { btable_set_rx_bufsize(ep_idx, 0, cnt); @@ -801,7 +801,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { uint32_t ep_reg = ep_read(ep_idx); ep_reg |= USB_EP_CTR_RX | USB_EP_CTR_TX; // reserve CTR bits ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); - ep_reg = ep_add_status(ep_reg, dir, EP_STAT_STALL); + ep_add_status(&ep_reg, dir, EP_STAT_STALL); ep_write(ep_idx, ep_reg); } @@ -818,9 +818,9 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir) | EP_DTOG_MASK(dir); if (!ep_is_iso(ep_reg)) { - ep_reg = ep_add_status(ep_reg, dir, EP_STAT_NAK); + ep_add_status(&ep_reg, dir, EP_STAT_NAK); } - ep_reg = ep_add_dtog(ep_reg, dir, 0); // Reset to DATA0 + ep_add_dtog(&ep_reg, dir, 0); // Reset to DATA0 ep_write(ep_idx, ep_reg); } diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h index e4a0f3f28..a44d8b35b 100644 --- a/src/portable/st/stm32_fsdev/fsdev_type.h +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -75,10 +75,9 @@ enum { // Buffer Table is located in Packet Memory Area (PMA) and therefore its address access is forced to either // 16-bit or 32-bit depending on FSDEV_BUS_32BIT. +// 0: TX (IN), 1: RX (OUT) typedef union { - // 0: TX (IN), 1: RX (OUT) - - // strictly 16-bit access (could be 32-bit aligned) + // data is strictly 16-bit access (address could be 32-bit aligned) struct { volatile pma_aligned uint16_t addr; volatile pma_aligned uint16_t count; @@ -181,16 +180,16 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_read(uint32_t ep_id) { return FSDEV_REG->ep[ep_id].reg; } -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_status(uint32_t reg, tusb_dir_t dir, ep_stat_t state) { - return reg ^ (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); +TU_ATTR_ALWAYS_INLINE static inline void ep_add_status(uint32_t* reg, tusb_dir_t dir, ep_stat_t state) { + *reg ^= (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_add_dtog(uint32_t reg, tusb_dir_t dir, uint8_t state) { - return reg ^ (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); +TU_ATTR_ALWAYS_INLINE static inline void ep_add_dtog(uint32_t* reg, tusb_dir_t dir, uint8_t state) { + *reg ^= (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_clear_ctr(uint32_t reg, tusb_dir_t dir) { - return reg & ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); +TU_ATTR_ALWAYS_INLINE static inline void ep_clear_ctr(uint32_t* reg, tusb_dir_t dir) { + *reg &= ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) { -- cgit v1.3.1 From e180d915c64c98ce7349cf4696f23abd55a91e19 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 1 Aug 2024 23:08:12 +0700 Subject: read/write packet enhancement, merge 16-bit and 32-bit together --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 139 +++++++++----------------- src/portable/st/stm32_fsdev/fsdev_type.h | 24 +++-- 2 files changed, 60 insertions(+), 103 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index d1c40deb6..2aa776dbb 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -825,121 +825,76 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { ep_write(ep_idx, ep_reg); } -#ifdef FSDEV_BUS_32BIT -static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t wNBytes) { - const uint8_t *src8 = src; - volatile uint32_t *pma32 = (volatile uint32_t *)(USB_PMAADDR + dst); - - for (uint32_t n = wNBytes / 4; n > 0; --n) { - *pma32++ = tu_unaligned_read32(src8); - src8 += 4; - } - - uint16_t odd = wNBytes & 0x03; - if (odd) { - uint32_t wrVal = *src8; - odd--; - - if (odd) { - wrVal |= *++src8 << 8; - odd--; - - if (odd) { - wrVal |= *++src8 << 16; - } - } - - *pma32 = wrVal; - } +// Write to packet memory area (PMA) from user memory +// - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT +// - Uses unaligned for RAM (since M0 cannot access unaligned address) +static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes) { + enum { BUS_SIZE = sizeof(fsdev_bus_t) }; + uint32_t n_write = nbytes / BUS_SIZE; - return true; -} + fsdev_pma_buf_t* pma_buf = PMA_BUF_AT(dst); + const uint8_t *src8 = src; -static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t wNBytes) { - uint8_t *dst8 = dst; - volatile uint32_t *src32 = (volatile uint32_t *)(USB_PMAADDR + src); + while (n_write--) { + #ifdef FSDEV_BUS_32BIT + pma_buf->value = tu_unaligned_read32(src8); + #else + pma_buf->value = tu_unaligned_read16(src8); + #endif - for (uint32_t n = wNBytes / 4; n > 0; --n) { - tu_unaligned_write32(dst8, *src32++); - dst8 += 4; + src8 += BUS_SIZE; + pma_buf++; } - uint16_t odd = wNBytes & 0x03; + // odd bytes e.g 1 for 16-bit or 1-3 for 32-bit + uint16_t odd = nbytes & (BUS_SIZE - 1); if (odd) { - uint32_t rdVal = *src32; - - *dst8 = tu_u32_byte0(rdVal); - odd--; - - if (odd) { - *++dst8 = tu_u32_byte1(rdVal); - odd--; - - if (odd) { - *++dst8 = tu_u32_byte2(rdVal); - } + fsdev_bus_t temp = 0; + for(uint16_t i = 0; i < odd; i++) { + temp |= *src8++ << (i * 8); } + pma_buf->value = temp; } return true; } -#else -// Packet buffer access can only be 8- or 16-bit. -/** - * @brief Copy a buffer from user memory area to packet memory area (PMA). - * This uses un-aligned for user memory and 16-bit access for packet memory. - * @param dst, byte address in PMA; must be 16-bit aligned - * @param src pointer to user memory area. - * @param wPMABufAddr address into PMA. - * @param nbytes no. of bytes to be copied. - * @retval None - */ -static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes) { - uint32_t n16 = (uint32_t)nbytes >> 1U; - const uint8_t *src8 = src; - fsdev_pma16_t* pma16 = (fsdev_pma16_t*) (USB_PMAADDR + FSDEV_PMA_STRIDE * dst); - - while (n16--) { - pma16->u16 = tu_unaligned_read16(src8); - src8 += 2; - pma16++; - } +// Read from packet memory area (PMA) to user memory. +// - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT +// - Uses unaligned for RAM (since M0 cannot access unaligned address) +static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes) { + enum { BUS_SIZE = sizeof(fsdev_bus_t) }; + uint32_t n_write = nbytes / BUS_SIZE; - if (nbytes & 0x01) { - pma16->u16 = (uint16_t) *src8; - } + fsdev_pma_buf_t* pma_buf = PMA_BUF_AT(src); + uint8_t *dst8 = (uint8_t *)dst; - return true; -} + while (n_write--) { + fsdev_bus_t temp = pma_buf->value; -/** - * @brief Copy a buffer from packet memory area (PMA) to user memory area. - * Uses unaligned for system memory and 16-bit access of packet memory - * @param nbytes no. of bytes to be copied. - * @retval None - */ -static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes) { - uint32_t n16 = (uint32_t)nbytes >> 1U; - fsdev_pma16_t* pma16 = (fsdev_pma16_t*) (USB_PMAADDR + FSDEV_PMA_STRIDE * src); - uint8_t *dst8 = (uint8_t *)dst; + #ifdef FSDEV_BUS_32BIT + tu_unaligned_write32(dst8, temp); + #else + tu_unaligned_write16(dst8, temp); + #endif - while (n16--) { - uint16_t temp16 = pma16->u16; - tu_unaligned_write16(dst8, temp16); - dst8 += 2; - pma16++; + dst8 += BUS_SIZE; + pma_buf++; } - if (nbytes & 0x01) { - *dst8++ = tu_u16_low(pma16->u16); + // odd bytes e.g 1 for 16-bit or 1-3 for 32-bit + uint16_t odd = nbytes & (BUS_SIZE - 1); + if (odd) { + fsdev_bus_t temp = pma_buf->value; + while (odd--) { + *dst8++ = (uint8_t) (temp & 0xfful); + temp >>= 8; + } } return true; } -#endif - /** * @brief Copy from FIFO to packet memory area (PMA). * Uses byte-access of system memory and 16-bit access of packet memory diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h index a44d8b35b..cac3b4386 100644 --- a/src/portable/st/stm32_fsdev/fsdev_type.h +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -1,9 +1,8 @@ /* * The MIT License (MIT) * - * Copyright(c) 2016 STMicroelectronics * Copyright(c) N Conrad - * Copyright (c) 2024, hathach (tinyusb.org) + * Copyright(c) 2024, hathach (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 @@ -23,6 +22,7 @@ * 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. */ #ifndef TUSB_FSDEV_TYPE_H @@ -62,6 +62,13 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 b #define pma_aligned #endif +// The fsdev_bus_t type can be used for both register and PMA access necessities +#ifdef FSDEV_BUS_32BIT + typedef uint32_t fsdev_bus_t; +#else + typedef uint16_t fsdev_bus_t; +#endif + //--------------------------------------------------------------------+ // BTable Typedef //--------------------------------------------------------------------+ @@ -95,8 +102,10 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE #define FSDEV_BTABLE ((volatile fsdev_btable_t*) (USB_PMAADDR+FSDEV_BTABLE_BASE)) typedef struct { - volatile pma_aligned uint16_t u16; -} fsdev_pma16_t; + volatile pma_aligned fsdev_bus_t value; +} fsdev_pma_buf_t; + +#define PMA_BUF_AT(_addr) ((fsdev_pma_buf_t*) (USB_PMAADDR + FSDEV_PMA_STRIDE*(_addr))) //--------------------------------------------------------------------+ // Registers Typedef @@ -105,13 +114,6 @@ typedef struct { // volatile 32-bit aligned #define _va32 volatile TU_ATTR_ALIGNED(4) -// The fsdev_bus_t type can be used for both register and PMA access necessities -#ifdef FSDEV_BUS_32BIT -typedef uint32_t fsdev_bus_t; -#else -typedef uint16_t fsdev_bus_t; -#endif - typedef struct { struct { _va32 fsdev_bus_t reg; -- cgit v1.3.1 From 91e5a066c5b259c38d663d21e3485b2feecb779d Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 2 Aug 2024 17:12:28 +0700 Subject: more fsdev clean up hil test boards in parallel --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 8 -- src/portable/st/stm32_fsdev/fsdev_ch32.h | 18 +--- src/portable/st/stm32_fsdev/fsdev_stm32.h | 50 +++++------ src/portable/st/stm32_fsdev/fsdev_type.h | 29 ++++--- test/hil/hil_test.py | 120 +++++++++++++------------- 5 files changed, 102 insertions(+), 123 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 2aa776dbb..cbd240ca1 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -114,8 +114,6 @@ #include "device/dcd.h" #if defined(TUP_USBIP_FSDEV_STM32) - // Undefine to reduce the dependence on HAL - #undef USE_HAL_DRIVER #include "fsdev_stm32.h" #elif defined(TUP_USBIP_FSDEV_CH32) #include "fsdev_ch32.h" @@ -125,12 +123,6 @@ #include "fsdev_type.h" -//--------------------------------------------------------------------+ -// Configuration -//--------------------------------------------------------------------+ - - - //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ diff --git a/src/portable/st/stm32_fsdev/fsdev_ch32.h b/src/portable/st/stm32_fsdev/fsdev_ch32.h index 8c0961bb9..518197c47 100644 --- a/src/portable/st/stm32_fsdev/fsdev_ch32.h +++ b/src/portable/st/stm32_fsdev/fsdev_ch32.h @@ -54,22 +54,8 @@ #endif #define FSDEV_PMA_SIZE (512u) -#define FSDEV_REG_BASE 0x40005C00UL - -#define USB_BASE (APB1PERIPH_BASE + 0x00005C00UL) /*!< USB_IP Peripheral Registers base address */ -#define USB_PMAADDR (APB1PERIPH_BASE + 0x00006000UL) /*!< USB_IP Packet Memory Area base address */ -#define USB ((USB_TypeDef *)USB_BASE) - -/******************************************************************************/ -/* */ -/* USB Device General registers */ -/* */ -/******************************************************************************/ -#define USB_CNTR (USB_BASE + 0x40U) /*!< Control register */ -#define USB_ISTR (USB_BASE + 0x44U) /*!< Interrupt status register */ -#define USB_FNR (USB_BASE + 0x48U) /*!< Frame number register */ -#define USB_DADDR (USB_BASE + 0x4CU) /*!< Device address register */ -#define USB_BTABLE (USB_BASE + 0x50U) /*!< Buffer Table address register */ +#define FSDEV_REG_BASE (APB1PERIPH_BASE + 0x00005C00UL) +#define FSDEV_PMA_BASE (APB1PERIPH_BASE + 0x00006000UL) /**************************** ISTR interrupt events *************************/ #define USB_ISTR_CTR ((uint16_t)0x8000U) /*!< Correct TRansfer (clear-only bit) */ diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index bb2c72fd1..99fe8d55f 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -82,12 +82,9 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32G0 #include "stm32g0xx.h" - #define FSDEV_BUS_32BIT #define FSDEV_PMA_SIZE (2048u) - #undef USB_PMAADDR - #define USB_PMAADDR USB_DRD_PMAADDR - #define USB_TypeDef USB_DRD_TypeDef - #define EP0R CHEP0R + #define USB USB_DRD_FS + #define USB_EP_CTR_RX USB_EP_VTRX #define USB_EP_CTR_TX USB_EP_VTTX #define USB_EP_T_FIELD USB_CHEP_UTYPE @@ -100,7 +97,6 @@ #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 #define USB_EPRX_STAT USB_CH_RX_VALID #define USB_EPKIND_MASK USB_EP_KIND_MASK - #define USB USB_DRD_FS #define USB_CNTR_FRES USB_CNTR_USBRST #define USB_CNTR_RESUME USB_CNTR_L2RES #define USB_ISTR_EP_ID USB_ISTR_IDN @@ -110,17 +106,9 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32H5 #include "stm32h5xx.h" - #define FSDEV_BUS_32BIT - - #if !defined(USB_DRD_BASE) && defined(USB_DRD_FS_BASE) - #define USB_DRD_BASE USB_DRD_FS_BASE - #endif - #define FSDEV_PMA_SIZE (2048u) - #undef USB_PMAADDR - #define USB_PMAADDR USB_DRD_PMAADDR - #define USB_TypeDef USB_DRD_TypeDef - #define EP0R CHEP0R + #define USB USB_DRD_FS + #define USB_EP_CTR_RX USB_EP_VTRX #define USB_EP_CTR_TX USB_EP_VTTX #define USB_EP_T_FIELD USB_CHEP_UTYPE @@ -133,7 +121,6 @@ #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 #define USB_EPRX_STAT USB_CH_RX_VALID #define USB_EPKIND_MASK USB_EP_KIND_MASK - #define USB USB_DRD_FS #define USB_CNTR_FRES USB_CNTR_USBRST #define USB_CNTR_RESUME USB_CNTR_L2RES #define USB_ISTR_EP_ID USB_ISTR_IDN @@ -144,9 +131,8 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32WB #include "stm32wbxx.h" #define FSDEV_PMA_SIZE (1024u) - /* ST provided header has incorrect value */ - #undef USB_PMAADDR - #define USB_PMAADDR USB1_PMAADDR + /* ST provided header has incorrect value of USB_PMAADDR */ + #define FSDEV_PMA_BASE USB1_PMAADDR #elif CFG_TUSB_MCU == OPT_MCU_STM32L4 #include "stm32l4xx.h" @@ -162,13 +148,9 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32U5 #include "stm32u5xx.h" - #define FSDEV_BUS_32BIT - #define FSDEV_PMA_SIZE (2048u) - #undef USB_PMAADDR - #define USB_PMAADDR USB_DRD_PMAADDR - #define USB_TypeDef USB_DRD_TypeDef - #define EP0R CHEP0R + #define USB USB_DRD_FS + #define USB_EP_CTR_RX USB_EP_VTRX #define USB_EP_CTR_TX USB_EP_VTTX #define USB_EP_T_FIELD USB_CHEP_UTYPE @@ -181,7 +163,6 @@ #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 #define USB_EPRX_STAT USB_CH_RX_VALID #define USB_EPKIND_MASK USB_EP_KIND_MASK - #define USB USB_DRD_FS #define USB_CNTR_FRES USB_CNTR_USBRST #define USB_CNTR_RESUME USB_CNTR_L2RES #define USB_ISTR_EP_ID USB_ISTR_IDN @@ -194,6 +175,10 @@ // This includes U0 #endif +//--------------------------------------------------------------------+ +// Register and PMA Base Address +//--------------------------------------------------------------------+ +#ifndef FSDEV_REG_BASE #if defined(USB_BASE) #define FSDEV_REG_BASE USB_BASE #elif defined(USB_DRD_BASE) @@ -203,6 +188,17 @@ #else #error "FSDEV_REG_BASE not defined" #endif +#endif + +#ifndef FSDEV_PMA_BASE +#if defined(USB_PMAADDR) + #define FSDEV_PMA_BASE USB_PMAADDR +#elif defined(USB_DRD_PMAADDR) + #define FSDEV_PMA_BASE USB_DRD_PMAADDR +#else + #error "FSDEV_PMA_BASE not defined" +#endif +#endif // This checks if the device has "LPM" #if defined(USB_ISTR_L1REQ) diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h index cac3b4386..bdff2c940 100644 --- a/src/portable/st/stm32_fsdev/fsdev_type.h +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -49,17 +49,18 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 b // For purposes of accessing the packet #if FSDEV_PMA_SIZE == 512 - #define FSDEV_PMA_STRIDE (2u) // 1x16 bit access scheme - #define pma_aligned TU_ATTR_ALIGNED(4) + // 1x16 bit / word access scheme + #define FSDEV_PMA_STRIDE 2 + #define pma_access_scheme TU_ATTR_ALIGNED(4) #elif FSDEV_PMA_SIZE == 1024 - #define FSDEV_PMA_STRIDE (1u) // 2x16 bit access scheme - #define pma_aligned + // 2x16 bit / word access scheme + #define FSDEV_PMA_STRIDE 1 + #define pma_access_scheme #elif FSDEV_PMA_SIZE == 2048 - #ifndef FSDEV_BUS_32BIT - #warning "FSDEV_PMA_SIZE is 2048, but FSDEV_BUS_32BIT is not defined" - #endif - #define FSDEV_PMA_STRIDE (1u) // 32 bit access scheme - #define pma_aligned + // 32 bit access scheme + #define FSDEV_BUS_32BIT + #define FSDEV_PMA_STRIDE 1 + #define pma_access_scheme #endif // The fsdev_bus_t type can be used for both register and PMA access necessities @@ -86,8 +87,8 @@ enum { typedef union { // data is strictly 16-bit access (address could be 32-bit aligned) struct { - volatile pma_aligned uint16_t addr; - volatile pma_aligned uint16_t count; + volatile pma_access_scheme uint16_t addr; + volatile pma_access_scheme uint16_t count; } ep16[FSDEV_EP_COUNT][2]; // strictly 32-bit access @@ -99,13 +100,13 @@ typedef union { TU_VERIFY_STATIC(sizeof(fsdev_btable_t) == FSDEV_EP_COUNT*8*FSDEV_PMA_STRIDE, "size is not correct"); TU_VERIFY_STATIC(FSDEV_BTABLE_BASE + FSDEV_EP_COUNT*8 <= FSDEV_PMA_SIZE, "BTABLE does not fit in PMA RAM"); -#define FSDEV_BTABLE ((volatile fsdev_btable_t*) (USB_PMAADDR+FSDEV_BTABLE_BASE)) +#define FSDEV_BTABLE ((volatile fsdev_btable_t*) (FSDEV_PMA_BASE + FSDEV_PMA_STRIDE*(FSDEV_BTABLE_BASE))) typedef struct { - volatile pma_aligned fsdev_bus_t value; + volatile pma_access_scheme fsdev_bus_t value; } fsdev_pma_buf_t; -#define PMA_BUF_AT(_addr) ((fsdev_pma_buf_t*) (USB_PMAADDR + FSDEV_PMA_STRIDE*(_addr))) +#define PMA_BUF_AT(_addr) ((fsdev_pma_buf_t*) (FSDEV_PMA_BASE + FSDEV_PMA_STRIDE*(_addr))) //--------------------------------------------------------------------+ // Registers Typedef diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index bdc48591e..6b8ba0675 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -34,6 +34,7 @@ import subprocess import json import glob import platform +from multiprocessing import Pool # for RPI double reset if platform.machine() == 'aarch64': @@ -130,10 +131,11 @@ def run_cmd(cmd): def flash_jlink(board, firmware): script = ['halt', 'r', f'loadfile {firmware}.elf', 'r', 'go', 'exit'] - with open('flash.jlink', 'w') as f: + f_jlink = f'{board["name"]}_{os.path.basename(firmware)}.jlink' + with open(f_jlink, 'w') as f: f.writelines(f'{s}\n' for s in script) - ret = run_cmd(f'JLinkExe -USB {board["flasher_sn"]} {board["flasher_args"]} -if swd -JTAGConf -1,-1 -speed auto -NoGui 1 -ExitOnError 1 -CommandFile flash.jlink') - os.remove('flash.jlink') + ret = run_cmd(f'JLinkExe -USB {board["flasher_sn"]} {board["flasher_args"]} -if swd -JTAGConf -1,-1 -speed auto -NoGui 1 -ExitOnError 1 -CommandFile {f_jlink}') + os.remove(f_jlink) return ret @@ -327,6 +329,61 @@ def test_hid_composite_freertos(id): # ------------------------------------------------------------- # Main # ------------------------------------------------------------- +# all possible tests: board_test is added last to disable board's usb +all_tests = [ + 'cdc_dual_ports', + 'cdc_msc', + #'cdc_msc_freertos', + 'dfu', + #'dfu_runtime', + 'hid_boot_interface', + 'board_test' +] + + +def test_board(item): + name = item['name'] + flasher = item['flasher'].lower() + + # default to all tests + if 'tests' in item: + test_list = item['tests'] + ['board_test'] + else: + test_list = list(all_tests) + + # remove skip_tests + if 'tests_skip' in item: + for skip in item['tests_skip']: + if skip in test_list: + test_list.remove(skip) + + for test in test_list: + fw_dir = f'cmake-build/cmake-build-{name}/device/{test}' + if not os.path.exists(fw_dir): + fw_dir = f'examples/cmake-build-{name}/device/{test}' + fw_name = f'{fw_dir}/{test}' + print(f'{name:20} {test:20} ... ', end='') + + if not os.path.exists(fw_dir): + print('Skip') + continue + + # flash firmware. It may fail randomly, retry a few times + for i in range(3): + ret = globals()[f'flash_{flasher}'](item, fw_name) + if ret.returncode == 0: + break + else: + print(f'Flashing failed, retry {i+1}') + time.sleep(1) + + assert ret.returncode == 0, 'Flash failed\n' + ret.stdout.decode() + + # run test + globals()[f'test_{test}'](item['uid']) + print('OK') + + def main(): """ Hardware test on specified boards @@ -345,66 +402,13 @@ def main(): with open(config_file) as f: config = json.load(f) - # all possible tests: board_test is added last to disable board's usb - all_tests = [ - 'cdc_dual_ports', - 'cdc_msc', - 'cdc_msc_freertos', - 'dfu', - 'dfu_runtime', - 'hid_boot_interface', - 'board_test' - ] - if len(boards) == 0: config_boards = config['boards'] else: config_boards = [e for e in config['boards'] if e['name'] in boards] - for item in config_boards: - name = item['name'] - print(f'Testing board:{name}') - flasher = item['flasher'].lower() - - # default to all tests - if 'tests' in item: - test_list = item['tests'] + ['board_test'] - else: - test_list = list(all_tests) - - # remove skip_tests - if 'tests_skip' in item: - for skip in item['tests_skip']: - if skip in test_list: - test_list.remove(skip) - - for test in test_list: - fw_dir = f'cmake-build/cmake-build-{name}/device/{test}' - if not os.path.exists(fw_dir): - fw_dir = f'examples/cmake-build-{name}/device/{test}' - fw_name = f'{fw_dir}/{test}' - print(f' {test} ... ', end='') - sys.stdout.flush() - - if not os.path.exists(fw_dir): - print('Skip') - continue - - # flash firmware. It may fail randomly, retry a few times - for i in range(3): - ret = globals()[f'flash_{flasher}'](item, fw_name) - if ret.returncode == 0: - break - else: - print(f'Flashing failed, retry {i+1}') - time.sleep(1) - - assert ret.returncode == 0, 'Flash failed\n' + ret.stdout.decode() - - # run test - globals()[f'test_{test}'](item['uid']) - - print('OK') + with Pool(processes=os.cpu_count()) as pool: + pool.map(test_board, config_boards) if __name__ == '__main__': -- cgit v1.3.1 From 315dae6a85cbb3df5b30429b28d8c74130f44db6 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 5 Aug 2024 17:43:27 +0700 Subject: finally fixed fsdev setup handling, which cause race condition for ch32v203 --- src/device/usbd.c | 1 - src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 59 ++++++++++++++------------- src/portable/st/stm32_fsdev/fsdev_type.h | 3 -- 3 files changed, 30 insertions(+), 33 deletions(-) (limited to 'src/portable') diff --git a/src/device/usbd.c b/src/device/usbd.c index 6d27a3735..7089e9cf1 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1201,7 +1201,6 @@ TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const* event, bool in_isr) break; case DCD_EVENT_SETUP_RECEIVED: - // TU_ASSERT(event->setup_received.bRequest != 0,); // for catching issue with ch32v203 and windows with -O0/-Og _usbd_queued_setup++; send = true; break; diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index cbd240ca1..43636198a 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -147,7 +147,6 @@ typedef struct { static xfer_ctl_t xfer_status[CFG_TUD_ENDPPOINT_MAX][2]; static ep_alloc_t ep_alloc_status[FSDEV_EP_COUNT]; - static uint8_t remoteWakeCountdown; // When wake is requested //--------------------------------------------------------------------+ @@ -171,6 +170,10 @@ static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBy static void edpt0_open(uint8_t rhport); +TU_ATTR_ALWAYS_INLINE static inline void edpt0_prepare_setup(void) { + btable_set_rx_bufsize(0, BTABLE_BUF_RX, 8); +} + //--------------------------------------------------------------------+ // Inline helper //--------------------------------------------------------------------+ @@ -340,21 +343,24 @@ static void handle_ctr_rx(uint32_t ep_id) { // Setup packet should always be 8 bytes. If not, ignore it, and try again. if (count == 8) { uint16_t rx_addr = btable_get_addr(ep_id, BTABLE_BUF_RX); - uint32_t setup_packet[2]; + uint8_t setup_packet[8] TU_ATTR_ALIGNED(4); + dcd_read_packet_memory(setup_packet, rx_addr, 8); dcd_event_setup_received(0, (uint8_t*) setup_packet, true); - // Reset EP to NAK (in case it had been stalling) + // Reset EP to NAK and set both toggle to 1 ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_NAK); ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); - ep_add_dtog(&ep_reg, TUSB_DIR_IN, 1); ep_add_dtog(&ep_reg, TUSB_DIR_OUT, 1); } else { + // Missed an setup packet !!! + TU_BREAKPOINT(); ep_reg &= USB_EPREG_MASK; // reversed all toggle + edpt0_prepare_setup(); } } else { - ep_reg &= USB_EPRX_STAT | USB_EPREG_MASK; // reversed all toggle except RX Status + ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_OUT); // reversed all toggle except RX Status bool const is_iso = ep_is_iso(ep_reg); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_OUT); @@ -374,20 +380,13 @@ static void handle_ctr_rx(uint32_t ep_id) { } else { dcd_read_packet_memory(xfer->buffer + xfer->queued_len, pma_addr, rx_count); } - xfer->queued_len = (uint16_t)(xfer->queued_len + rx_count); } if ((rx_count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { - uint8_t const ep_addr = ep_num; // all bytes received or short packet - dcd_event_xfer_complete(0, ep_addr, xfer->queued_len, XFER_RESULT_SUCCESS, true); - - if (ep_num == 0) { - // prepared for status packet - btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE); - } ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); + dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); } else { // Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always if (!is_iso) { @@ -485,6 +484,8 @@ void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *req uint8_t const dev_addr = (uint8_t)request->wValue; FSDEV_REG->DADDR = (USB_DADDR_EF | dev_addr); } + + edpt0_prepare_setup(); } /*** @@ -569,15 +570,13 @@ void edpt0_open(uint8_t rhport) { btable_set_addr(0, BTABLE_BUF_RX, pma_addr0); btable_set_addr(0, BTABLE_BUF_TX, pma_addr1); - uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK; + uint32_t ep_reg = ep_read(0) & ~USB_EPREG_MASK; // only get toggle bits ep_reg |= USB_EP_CONTROL; ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_NAK); ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); // no need to explicitly set DTOG bits since we aren't masked DTOG bit - // prepare for setup packet - btable_set_rx_bufsize(0, BTABLE_BUF_RX, CFG_TUD_ENDPOINT0_SIZE); - + edpt0_prepare_setup(); // prepare for setup packet ep_write(0, ep_reg); } @@ -590,7 +589,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { uint8_t const ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer); TU_ASSERT(ep_idx < FSDEV_EP_COUNT); - uint32_t ep_reg = FSDEV_REG->ep[ep_idx].reg & ~USB_EPREG_MASK; + uint32_t ep_reg = ep_read(ep_idx) & ~USB_EPREG_MASK; ep_reg |= tu_edpt_number(ep_addr) | USB_EP_CTR_RX | USB_EP_CTR_TX; // Set type @@ -684,7 +683,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) xfer->max_packet_size = tu_edpt_packet_size(desc_ep); - uint32_t ep_reg = FSDEV_REG->ep[0].reg & ~USB_EPREG_MASK; + uint32_t ep_reg = ep_read(ep_idx) & ~USB_EPREG_MASK; ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_RX | USB_EP_CTR_TX; ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED); ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED); @@ -699,7 +698,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) // Currently, single-buffered, and only 64 bytes at a time (max) static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); - uint32_t ep_reg = ep_read(ep_ix) | EP_CTR_TXRX; + uint32_t ep_reg = ep_read(ep_ix) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR bits bool const is_iso = ep_is_iso(ep_reg); uint8_t buf_id; @@ -709,14 +708,17 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { buf_id = BTABLE_BUF_TX; } uint16_t addr_ptr = (uint16_t) btable_get_addr(ep_ix, buf_id); - btable_set_count(ep_ix, buf_id, len); - if (xfer->ff) { - dcd_write_packet_memory_ff(xfer->ff, addr_ptr, len); - } else { - dcd_write_packet_memory(addr_ptr, &(xfer->buffer[xfer->queued_len]), len); + if (len) { + if (xfer->ff) { + dcd_write_packet_memory_ff(xfer->ff, addr_ptr, len); + } else { + dcd_write_packet_memory(addr_ptr, &(xfer->buffer[xfer->queued_len]), len); + } + xfer->queued_len = (uint16_t) (xfer->queued_len + len); } - xfer->queued_len = (uint16_t)(xfer->queued_len + len); + + btable_set_count(ep_ix, buf_id, len); ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_IN); ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_VALID); @@ -790,8 +792,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); uint8_t const ep_idx = xfer->ep_idx; - uint32_t ep_reg = ep_read(ep_idx); - ep_reg |= USB_EP_CTR_RX | USB_EP_CTR_TX; // reserve CTR bits + uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR bits ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); ep_add_status(&ep_reg, dir, EP_STAT_STALL); @@ -806,7 +807,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); uint8_t const ep_idx = xfer->ep_idx; - uint32_t ep_reg = ep_read(ep_idx) | EP_CTR_TXRX; + uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR bits ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir) | EP_DTOG_MASK(dir); if (!ep_is_iso(ep_reg)) { diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h index bdff2c940..8432df4b0 100644 --- a/src/portable/st/stm32_fsdev/fsdev_type.h +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -156,9 +156,6 @@ TU_VERIFY_STATIC(sizeof(fsdev_regs_t) == 0x5C, "Size is not correct"); #define USB_EP_CTR_TX_Pos 7u #endif - -#define EP_CTR_TXRX (USB_EP_CTR_TX | USB_EP_CTR_RX) - typedef enum { EP_STAT_DISABLED = 0, EP_STAT_STALL = 1, -- cgit v1.3.1 From d680424f62b0d677158af7219b319a24f5497d1c Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 6 Aug 2024 22:18:25 +0700 Subject: improve dcd_int_handler() - skip DIR and use CTR TX/RX to handle complete transfer - clear CTR first, except for setup which we need to get data first - separate handle_ctr_setup() --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 238 ++++++++++++-------------- src/portable/st/stm32_fsdev/fsdev_type.h | 26 ++- 2 files changed, 132 insertions(+), 132 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 43636198a..97529997d 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -4,7 +4,6 @@ * Copyright (c) 2019 Nathan Conrad * * Portions: - * Copyright (c) 2016 STMicroelectronics * Copyright (c) 2019 Ha Thach (tinyusb.org) * Copyright (c) 2022 Simon Küppers (skuep) * Copyright (c) 2022 HiFiPhile @@ -215,10 +214,11 @@ void dcd_init(uint8_t rhport) { // Reset endpoints to disabled for (uint32_t i = 0; i < FSDEV_EP_COUNT; i++) { // This doesn't clear all bits since some bits are "toggle", but does set the type to DISABLED. - ep_write(i, 0u); + ep_write(i, 0u, false); } FSDEV_REG->CNTR |= USB_CNTR_RESETM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; + //| USB_CNTR_ERRM | USB_CNTR_PMAOVRM; handle_bus_reset(rhport); // Enable pull-up if supported @@ -274,13 +274,10 @@ static void handle_bus_reset(uint8_t rhport) { // Handle CTR interrupt for the TX/IN direction static void handle_ctr_tx(uint32_t ep_id) { - uint32_t ep_reg = ep_read(ep_id) & USB_EPREG_MASK; - - // Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary? - TU_VERIFY(ep_reg & USB_EP_CTR_TX, ); + uint32_t ep_reg = ep_read(ep_id) | USB_EP_CTR_TX | USB_EP_CTR_RX; + ep_reg &= USB_EPREG_MASK; uint8_t const ep_num = ep_reg & USB_EPADDR_FIELD; - uint8_t ep_addr = (ep_reg & USB_EPADDR_FIELD) | TUSB_DIR_IN_MASK; xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_IN); if (ep_is_iso(ep_reg)) { @@ -296,108 +293,72 @@ static void handle_ctr_tx(uint32_t ep_id) { } if (xfer->total_len != xfer->queued_len) { - dcd_transmit_packet(xfer, ep_id); // also clear CTR bit + dcd_transmit_packet(xfer, ep_id); } else { - dcd_event_xfer_complete(0, ep_addr, xfer->total_len, XFER_RESULT_SUCCESS, true); + dcd_event_xfer_complete(0, ep_num | TUSB_DIR_IN_MASK, xfer->queued_len, XFER_RESULT_SUCCESS, true); + } +} - // Clear CTR TX and reserved CTR RX - ep_reg = (ep_reg & ~USB_EP_CTR_TX) | USB_EP_CTR_RX; +static void handle_ctr_setup(uint32_t ep_id) { + uint16_t rx_count = btable_get_count(ep_id, BTABLE_BUF_RX); + uint16_t rx_addr = btable_get_addr(ep_id, BTABLE_BUF_RX); + uint8_t setup_packet[8] TU_ATTR_ALIGNED(4); - ep_write(ep_id, ep_reg); + dcd_read_packet_memory(setup_packet, rx_addr, rx_count); + + // Clear CTR RX if another setup packet arrived before this, it will be discarded + ep_write_clear_ctr(ep_id, TUSB_DIR_OUT); + + // Setup packet should always be 8 bytes. If not, we probably missed the packet + if (rx_count == 8) { + dcd_event_setup_received(0, (uint8_t*) setup_packet, true); + // Hardware should reset EP0 RX/TX to NAK and both toggle to 1 + } else { + // Missed setup packet !!! + TU_BREAKPOINT(); + edpt0_prepare_setup(); } } // Handle CTR interrupt for the RX/OUT direction static void handle_ctr_rx(uint32_t ep_id) { -#ifdef FSDEV_BUS_32BIT - /* https://www.st.com/resource/en/errata_sheet/es0561-stm32h503cbebkbrb-device-errata-stmicroelectronics.pdf - * From STM32H503 errata 2.15.1: Buffer description table update completes after CTR interrupt triggers - * Description: - * - During OUT transfers, the correct transfer interrupt (CTR) is triggered a little before the last USB SRAM accesses - * have completed. If the software responds quickly to the interrupt, the full buffer contents may not be correct. - * Workaround: - * - Software should ensure that a small delay is included before accessing the SRAM contents. This delay - * should be 800 ns in Full Speed mode and 6.4 μs in Low Speed mode - * - Since H5 can run up to 250Mhz -> 1 cycle = 4ns. Per errata, we need to wait 200 cycles. Though executing code - * also takes time, so we'll wait 60 cycles (count = 20). - * - Since Low Speed mode is not supported/popular, we will ignore it for now. - * - * Note: this errata also seems to apply to G0, U5, H5 etc. - */ - volatile uint32_t cycle_count = 20; // defined as PCD_RX_PMA_CNT in stm32 hal_driver - while (cycle_count > 0U) { - cycle_count--; // each count take 3 cycles (1 for sub, jump, and compare) - } -#endif - - uint32_t ep_reg = ep_read(ep_id); - - // Verify the CTR bit is set. This was in the ST Micro code, but I'm not sure it's actually necessary? - TU_VERIFY(ep_reg & USB_EP_CTR_RX, ); - ep_reg = (ep_reg & ~USB_EP_CTR_RX) | USB_EP_CTR_TX; // Clear CTR RX and reserved CTR TX + uint32_t ep_reg = ep_read(ep_id) | USB_EP_CTR_TX | USB_EP_CTR_RX; + ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_OUT); // will change RX Status, reserved other toggle bits uint8_t const ep_num = ep_reg & USB_EPADDR_FIELD; + bool const is_iso = ep_is_iso(ep_reg); + xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_OUT); - if (ep_reg & USB_EP_SETUP) { - uint32_t count = btable_get_count(ep_id, BTABLE_BUF_RX); - // Setup packet should always be 8 bytes. If not, ignore it, and try again. - if (count == 8) { - uint16_t rx_addr = btable_get_addr(ep_id, BTABLE_BUF_RX); - uint8_t setup_packet[8] TU_ATTR_ALIGNED(4); - - dcd_read_packet_memory(setup_packet, rx_addr, 8); - dcd_event_setup_received(0, (uint8_t*) setup_packet, true); - - // Reset EP to NAK and set both toggle to 1 - ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_NAK); - ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); - ep_add_dtog(&ep_reg, TUSB_DIR_IN, 1); - ep_add_dtog(&ep_reg, TUSB_DIR_OUT, 1); - } else { - // Missed an setup packet !!! - TU_BREAKPOINT(); - ep_reg &= USB_EPREG_MASK; // reversed all toggle - edpt0_prepare_setup(); - } + uint8_t buf_id; + if (is_iso) { + buf_id = (ep_reg & USB_EP_DTOG_RX) ? 0 : 1; // ISO are double buffered } else { - ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_OUT); // reversed all toggle except RX Status - - bool const is_iso = ep_is_iso(ep_reg); - xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_OUT); + buf_id = BTABLE_BUF_RX; + } + uint16_t const rx_count = btable_get_count(ep_id, buf_id); + uint16_t pma_addr = (uint16_t) btable_get_addr(ep_id, buf_id); - uint8_t buf_id; - if (is_iso) { - buf_id = (ep_reg & USB_EP_DTOG_RX) ? 0 : 1; // ISO are double buffered + if (rx_count != 0) { + if (xfer->ff) { + dcd_read_packet_memory_ff(xfer->ff, pma_addr, rx_count); } else { - buf_id = BTABLE_BUF_RX; - } - uint32_t rx_count = btable_get_count(ep_id, buf_id); - uint16_t pma_addr = (uint16_t) btable_get_addr(ep_id, buf_id); - - if (rx_count != 0) { - if (xfer->ff) { - dcd_read_packet_memory_ff(xfer->ff, pma_addr, rx_count); - } else { - dcd_read_packet_memory(xfer->buffer + xfer->queued_len, pma_addr, rx_count); - } - xfer->queued_len = (uint16_t)(xfer->queued_len + rx_count); + dcd_read_packet_memory(xfer->buffer + xfer->queued_len, pma_addr, rx_count); } + xfer->queued_len += rx_count; + } - if ((rx_count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { - // all bytes received or short packet - ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); - dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); - } else { - // Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always - if (!is_iso) { - uint16_t const cnt = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); - btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, cnt); - } - ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_VALID); + if ((rx_count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { + // all bytes received or short packet + dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); + } else { + // Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always + if (!is_iso) { + uint16_t const cnt = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); + btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, cnt); } + ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_VALID); + ep_write(ep_id, ep_reg, false); } - - ep_write(ep_id, ep_reg); } void dcd_int_handler(uint8_t rhport) { @@ -406,10 +367,6 @@ void dcd_int_handler(uint8_t rhport) { // | USB_ISTR_SUSP | USB_ISTR_SOF | USB_ISTR_ESOF; // unused IRQs: (USB_ISTR_PMAOVR | USB_ISTR_ERR | USB_ISTR_L1REQ ) - // The ST driver loops here on the CTR bit, but that loop has been moved into the - // dcd_ep_ctr_handler(), so less need to loop here. The other interrupts shouldn't - // be triggered repeatedly. - /* Put SOF flag at the beginning of ISR in case to get least amount of jitter if it is used for timing purposes */ if (int_status & USB_ISTR_SOF) { FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_SOF; @@ -455,17 +412,51 @@ void dcd_int_handler(uint8_t rhport) { FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_ESOF; } +// if (int_status & (USB_ISTR_ERR | USB_ISTR_PMAOVR)) { +// TU_BREAKPOINT(); +// } + // loop to handle all pending CTR interrupts - while (int_status & USB_ISTR_CTR) { - uint32_t const ep_id = int_status & USB_ISTR_EP_ID; + while (FSDEV_REG->ISTR & USB_ISTR_CTR) { + // skip DIR bit, and use CTR TX/RX instead, since there is chance we have both TX/RX completed in one interrupt + uint32_t const ep_id = FSDEV_REG->ISTR & USB_ISTR_EP_ID; + uint32_t const ep_reg = ep_read(ep_id); + + if (ep_reg & USB_EP_CTR_RX) { + #ifdef FSDEV_BUS_32BIT + /* https://www.st.com/resource/en/errata_sheet/es0561-stm32h503cbebkbrb-device-errata-stmicroelectronics.pdf + * https://www.st.com/resource/en/errata_sheet/es0587-stm32u535xx-and-stm32u545xx-device-errata-stmicroelectronics.pdf + * From H503/U535 errata: Buffer description table update completes after CTR interrupt triggers + * Description: + * - During OUT transfers, the correct transfer interrupt (CTR) is triggered a little before the last USB SRAM accesses + * have completed. If the software responds quickly to the interrupt, the full buffer contents may not be correct. + * Workaround: + * - Software should ensure that a small delay is included before accessing the SRAM contents. This delay + * should be 800 ns in Full Speed mode and 6.4 μs in Low Speed mode + * - Since H5 can run up to 250Mhz -> 1 cycle = 4ns. Per errata, we need to wait 200 cycles. Though executing code + * also takes time, so we'll wait 60 cycles (count = 20). + * - Since Low Speed mode is not supported/popular, we will ignore it for now. + * + * Note: this errata may also apply to G0, U5, H5 etc. + */ + volatile uint32_t cycle_count = 20; // defined as PCD_RX_PMA_CNT in stm32 hal_driver + while (cycle_count > 0U) { + cycle_count--; // each count take 3 cycles (1 for sub, jump, and compare) + } + #endif - if ((int_status & USB_ISTR_DIR) == 0U) { - handle_ctr_tx(ep_id); // TX/IN - } else { - handle_ctr_rx(ep_id); // RX/OUT or both (RX/TX !!) + if (ep_reg & USB_EP_SETUP) { + handle_ctr_setup(ep_id); + } else { + ep_write_clear_ctr(ep_id, TUSB_DIR_OUT); + handle_ctr_rx(ep_id); + } } - int_status = FSDEV_REG->ISTR; + if (ep_reg & USB_EP_CTR_TX) { + ep_write_clear_ctr(ep_id, TUSB_DIR_IN); + handle_ctr_tx(ep_id); + } } } @@ -577,7 +568,7 @@ void edpt0_open(uint8_t rhport) { // no need to explicitly set DTOG bits since we aren't masked DTOG bit edpt0_prepare_setup(); // prepare for setup packet - ep_write(0, ep_reg); + ep_write(0, ep_reg, false); } bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { @@ -590,7 +581,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { TU_ASSERT(ep_idx < FSDEV_EP_COUNT); uint32_t ep_reg = ep_read(ep_idx) & ~USB_EPREG_MASK; - ep_reg |= tu_edpt_number(ep_addr) | USB_EP_CTR_RX | USB_EP_CTR_TX; + ep_reg |= tu_edpt_number(ep_addr) | USB_EP_CTR_TX | USB_EP_CTR_RX; // Set type switch (desc_ep->bmAttributes.xfer) { @@ -624,18 +615,17 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { ep_reg &= ~(USB_EPTX_STAT | USB_EP_DTOG_TX); } - ep_write(ep_idx, ep_reg); + ep_write(ep_idx, ep_reg, true); return true; } -void dcd_edpt_close_all(uint8_t rhport) -{ - (void)rhport; +void dcd_edpt_close_all(uint8_t rhport) { + dcd_int_disable(rhport); for (uint32_t i = 1; i < FSDEV_EP_COUNT; i++) { // Reset endpoint - ep_write(i, 0); + ep_write(i, 0, false); // Clear EP allocation status ep_alloc_status[i].ep_num = 0xFF; ep_alloc_status[i].ep_type = 0xFF; @@ -643,6 +633,8 @@ void dcd_edpt_close_all(uint8_t rhport) ep_alloc_status[i].allocated[1] = false; } + dcd_int_enable(rhport); + // Reset PMA allocation ep_buf_ptr = FSDEV_BTABLE_BASE + 8 * CFG_TUD_ENDPPOINT_MAX + 2 * CFG_TUD_ENDPOINT0_SIZE; } @@ -684,13 +676,13 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) xfer->max_packet_size = tu_edpt_packet_size(desc_ep); uint32_t ep_reg = ep_read(ep_idx) & ~USB_EPREG_MASK; - ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_RX | USB_EP_CTR_TX; + ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_TX | USB_EP_CTR_RX; ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED); ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED); ep_add_dtog(&ep_reg, dir, 0); ep_add_dtog(&ep_reg, 1-dir, 1); - ep_write(ep_idx, ep_reg); + ep_write(ep_idx, ep_reg, true); return true; } @@ -698,7 +690,9 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) // Currently, single-buffered, and only 64 bytes at a time (max) static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); - uint32_t ep_reg = ep_read(ep_ix) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR bits + uint32_t ep_reg = ep_read(ep_ix) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR RX + ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_IN); // only change TX Status, reserve other toggle bits + bool const is_iso = ep_is_iso(ep_reg); uint8_t buf_id; @@ -715,21 +709,16 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { } else { dcd_write_packet_memory(addr_ptr, &(xfer->buffer[xfer->queued_len]), len); } - xfer->queued_len = (uint16_t) (xfer->queued_len + len); + xfer->queued_len += len; } btable_set_count(ep_ix, buf_id, len); - - ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_IN); ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_VALID); - ep_clear_ctr(&ep_reg, TUSB_DIR_IN); - dcd_int_disable(0); - ep_write(ep_ix, ep_reg); if (is_iso) { xfer->iso_in_sending = true; } - dcd_int_enable(0); + ep_write(ep_ix, ep_reg, true); } static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { @@ -741,8 +730,8 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { if (dir == TUSB_DIR_IN) { dcd_transmit_packet(xfer, ep_idx); } else { - uint32_t cnt = (uint32_t) tu_min16(xfer->total_len, xfer->max_packet_size); - uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX; // keep CTR TX, clear CTR RX + uint16_t cnt = tu_min16(xfer->total_len, xfer->max_packet_size); + uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // keep CTR TX ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); ep_add_status(&ep_reg, dir, EP_STAT_VALID); @@ -753,7 +742,7 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { btable_set_rx_bufsize(ep_idx, BTABLE_BUF_RX, cnt); } - ep_write(ep_idx, ep_reg); + ep_write(ep_idx, ep_reg, true); } return true; @@ -796,7 +785,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); ep_add_status(&ep_reg, dir, EP_STAT_STALL); - ep_write(ep_idx, ep_reg); + ep_write(ep_idx, ep_reg, true); } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { @@ -814,8 +803,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { ep_add_status(&ep_reg, dir, EP_STAT_NAK); } ep_add_dtog(&ep_reg, dir, 0); // Reset to DATA0 - - ep_write(ep_idx, ep_reg); + ep_write(ep_idx, ep_reg, true); } // Write to packet memory area (PMA) from user memory diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h index 8432df4b0..f29abd703 100644 --- a/src/portable/st/stm32_fsdev/fsdev_type.h +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -172,8 +172,24 @@ typedef enum { // - DTOG and STAT are write 1 to toggle //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value) { +TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value, bool need_exclusive) { + if (need_exclusive) { + dcd_int_disable(0); + } + FSDEV_REG->ep[ep_id].reg = (fsdev_bus_t) value; + + if (need_exclusive) { + dcd_int_enable(0); + } +} + +TU_ATTR_ALWAYS_INLINE static inline void ep_write_clear_ctr(uint32_t ep_id, tusb_dir_t dir) { + uint32_t reg = FSDEV_REG->ep[ep_id].reg; + reg |= USB_EP_CTR_TX | USB_EP_CTR_RX; + reg &= USB_EPREG_MASK; + reg &= ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); + ep_write(ep_id, reg, false); } TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_read(uint32_t ep_id) { @@ -188,10 +204,6 @@ TU_ATTR_ALWAYS_INLINE static inline void ep_add_dtog(uint32_t* reg, tusb_dir_t d *reg ^= (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } -TU_ATTR_ALWAYS_INLINE static inline void ep_clear_ctr(uint32_t* reg, tusb_dir_t dir) { - *reg &= ~(1 << (USB_EP_CTR_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); -} - TU_ATTR_ALWAYS_INLINE static inline bool ep_is_iso(uint32_t reg) { return (reg & USB_EP_TYPE_MASK) == USB_EP_ISOCHRONOUS; } @@ -218,7 +230,7 @@ TU_ATTR_ALWAYS_INLINE static inline void btable_set_addr(uint32_t ep_id, uint8_t #endif } -TU_ATTR_ALWAYS_INLINE static inline uint32_t btable_get_count(uint32_t ep_id, uint8_t buf_id) { +TU_ATTR_ALWAYS_INLINE static inline uint16_t btable_get_count(uint32_t ep_id, uint8_t buf_id) { uint16_t count; #ifdef FSDEV_BUS_32BIT count = (FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr >> 16); @@ -258,7 +270,7 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t pma_align_buffer_size(uint16_t size return (*num_block) * block_in_bytes; } -TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint32_t wCount) { +TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, uint8_t buf_id, uint16_t wCount) { uint8_t blsize, num_block; (void) pma_align_buffer_size(wCount, &blsize, &num_block); -- cgit v1.3.1 From 0860cd3b5e95a7366bc2c68eb7648e8479059172 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 6 Aug 2024 22:20:24 +0700 Subject: minor rename --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 28 +++++++++++++-------------- src/portable/st/stm32_fsdev/fsdev_type.h | 4 ++-- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 97529997d..2075babe3 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -356,7 +356,7 @@ static void handle_ctr_rx(uint32_t ep_id) { uint16_t const cnt = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, cnt); } - ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_VALID); + ep_change_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_VALID); ep_write(ep_id, ep_reg, false); } } @@ -563,8 +563,8 @@ void edpt0_open(uint8_t rhport) { uint32_t ep_reg = ep_read(0) & ~USB_EPREG_MASK; // only get toggle bits ep_reg |= USB_EP_CONTROL; - ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_NAK); - ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); + ep_change_status(&ep_reg, TUSB_DIR_IN, EP_STAT_NAK); + ep_change_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_NAK); // no need to explicitly set DTOG bits since we aren't masked DTOG bit edpt0_prepare_setup(); // prepare for setup packet @@ -605,8 +605,8 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { xfer->max_packet_size = packet_size; xfer->ep_idx = ep_idx; - ep_add_status(&ep_reg, dir, EP_STAT_NAK); - ep_add_dtog(&ep_reg, dir, 0); + ep_change_status(&ep_reg, dir, EP_STAT_NAK); + ep_change_dtog(&ep_reg, dir, 0); // reserve other direction toggle bits if (dir == TUSB_DIR_IN) { @@ -677,10 +677,10 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) uint32_t ep_reg = ep_read(ep_idx) & ~USB_EPREG_MASK; ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_TX | USB_EP_CTR_RX; - ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED); - ep_add_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED); - ep_add_dtog(&ep_reg, dir, 0); - ep_add_dtog(&ep_reg, 1-dir, 1); + ep_change_status(&ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED); + ep_change_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED); + ep_change_dtog(&ep_reg, dir, 0); + ep_change_dtog(&ep_reg, 1 - dir, 1); ep_write(ep_idx, ep_reg, true); @@ -713,7 +713,7 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { } btable_set_count(ep_ix, buf_id, len); - ep_add_status(&ep_reg, TUSB_DIR_IN, EP_STAT_VALID); + ep_change_status(&ep_reg, TUSB_DIR_IN, EP_STAT_VALID); if (is_iso) { xfer->iso_in_sending = true; @@ -733,7 +733,7 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { uint16_t cnt = tu_min16(xfer->total_len, xfer->max_packet_size); uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // keep CTR TX ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); - ep_add_status(&ep_reg, dir, EP_STAT_VALID); + ep_change_status(&ep_reg, dir, EP_STAT_VALID); if (ep_is_iso(ep_reg)) { btable_set_rx_bufsize(ep_idx, 0, cnt); @@ -783,7 +783,7 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR bits ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); - ep_add_status(&ep_reg, dir, EP_STAT_STALL); + ep_change_status(&ep_reg, dir, EP_STAT_STALL); ep_write(ep_idx, ep_reg, true); } @@ -800,9 +800,9 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir) | EP_DTOG_MASK(dir); if (!ep_is_iso(ep_reg)) { - ep_add_status(&ep_reg, dir, EP_STAT_NAK); + ep_change_status(&ep_reg, dir, EP_STAT_NAK); } - ep_add_dtog(&ep_reg, dir, 0); // Reset to DATA0 + ep_change_dtog(&ep_reg, dir, 0); // Reset to DATA0 ep_write(ep_idx, ep_reg, true); } diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h index f29abd703..d5028c702 100644 --- a/src/portable/st/stm32_fsdev/fsdev_type.h +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -196,11 +196,11 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_read(uint32_t ep_id) { return FSDEV_REG->ep[ep_id].reg; } -TU_ATTR_ALWAYS_INLINE static inline void ep_add_status(uint32_t* reg, tusb_dir_t dir, ep_stat_t state) { +TU_ATTR_ALWAYS_INLINE static inline void ep_change_status(uint32_t* reg, tusb_dir_t dir, ep_stat_t state) { *reg ^= (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } -TU_ATTR_ALWAYS_INLINE static inline void ep_add_dtog(uint32_t* reg, tusb_dir_t dir, uint8_t state) { +TU_ATTR_ALWAYS_INLINE static inline void ep_change_dtog(uint32_t* reg, tusb_dir_t dir, uint8_t state) { *reg ^= (state << (USB_EP_DTOG_TX_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } -- cgit v1.3.1 From 3a2216306769f0af0ceb3dde7528dfb182fec8f5 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 7 Aug 2024 15:16:22 +0700 Subject: fix v203 race condition between rx bufsize and RX_STAT which cause PMAOVR fix set_rx_bufsize with invalid value for zero length packet --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 28 ++++++++++++++++----------- src/portable/st/stm32_fsdev/fsdev_type.h | 17 ++++++++++------ 2 files changed, 28 insertions(+), 17 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 2075babe3..cd7410488 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -217,8 +217,8 @@ void dcd_init(uint8_t rhport) { ep_write(i, 0u, false); } - FSDEV_REG->CNTR |= USB_CNTR_RESETM | USB_CNTR_ESOFM | USB_CNTR_CTRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM; - //| USB_CNTR_ERRM | USB_CNTR_PMAOVRM; + FSDEV_REG->CNTR |= USB_CNTR_RESETM | USB_CNTR_ESOFM | USB_CNTR_CTRM | + USB_CNTR_SUSPM | USB_CNTR_WKUPM | USB_CNTR_PMAOVRM; handle_bus_reset(rhport); // Enable pull-up if supported @@ -349,6 +349,10 @@ static void handle_ctr_rx(uint32_t ep_id) { if ((rx_count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { // all bytes received or short packet + + // reset rx bufsize to mps to prevent race condition to cause PMAOVR (occurs with ch32v203 with msc write10) + btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, xfer->max_packet_size); + dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); } else { // Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always @@ -412,9 +416,10 @@ void dcd_int_handler(uint8_t rhport) { FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_ESOF; } -// if (int_status & (USB_ISTR_ERR | USB_ISTR_PMAOVR)) { -// TU_BREAKPOINT(); -// } + if (int_status & USB_ISTR_PMAOVR) { + TU_BREAKPOINT(); + FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_PMAOVR; + } // loop to handle all pending CTR interrupts while (FSDEV_REG->ISTR & USB_ISTR_CTR) { @@ -446,7 +451,7 @@ void dcd_int_handler(uint8_t rhport) { #endif if (ep_reg & USB_EP_SETUP) { - handle_ctr_setup(ep_id); + handle_ctr_setup(ep_id); // CTR will be clear after copied setup packet } else { ep_write_clear_ctr(ep_id, TUSB_DIR_OUT); handle_ctr_rx(ep_id); @@ -690,7 +695,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) // Currently, single-buffered, and only 64 bytes at a time (max) static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); - uint32_t ep_reg = ep_read(ep_ix) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR RX + uint32_t ep_reg = ep_read(ep_ix) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_IN); // only change TX Status, reserve other toggle bits bool const is_iso = ep_is_iso(ep_reg); @@ -730,10 +735,10 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { if (dir == TUSB_DIR_IN) { dcd_transmit_packet(xfer, ep_idx); } else { - uint16_t cnt = tu_min16(xfer->total_len, xfer->max_packet_size); - uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // keep CTR TX + uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); - ep_change_status(&ep_reg, dir, EP_STAT_VALID); + + uint16_t cnt = tu_min16(xfer->total_len, xfer->max_packet_size); if (ep_is_iso(ep_reg)) { btable_set_rx_bufsize(ep_idx, 0, cnt); @@ -742,7 +747,8 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { btable_set_rx_bufsize(ep_idx, BTABLE_BUF_RX, cnt); } - ep_write(ep_idx, ep_reg, true); + ep_change_status(&ep_reg, dir, EP_STAT_VALID); + ep_write(ep_idx, ep_reg, false); } return true; diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h index d5028c702..6c5ccae89 100644 --- a/src/portable/st/stm32_fsdev/fsdev_type.h +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -172,6 +172,10 @@ typedef enum { // - DTOG and STAT are write 1 to toggle //--------------------------------------------------------------------+ +TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_read(uint32_t ep_id) { + return FSDEV_REG->ep[ep_id].reg; +} + TU_ATTR_ALWAYS_INLINE static inline void ep_write(uint32_t ep_id, uint32_t value, bool need_exclusive) { if (need_exclusive) { dcd_int_disable(0); @@ -192,10 +196,6 @@ TU_ATTR_ALWAYS_INLINE static inline void ep_write_clear_ctr(uint32_t ep_id, tusb ep_write(ep_id, reg, false); } -TU_ATTR_ALWAYS_INLINE static inline uint32_t ep_read(uint32_t ep_id) { - return FSDEV_REG->ep[ep_id].reg; -} - TU_ATTR_ALWAYS_INLINE static inline void ep_change_status(uint32_t* reg, tusb_dir_t dir, ep_stat_t state) { *reg ^= (state << (USB_EPTX_STAT_Pos + (dir == TUSB_DIR_IN ? 0 : 8))); } @@ -260,13 +260,13 @@ TU_ATTR_ALWAYS_INLINE static inline uint16_t pma_align_buffer_size(uint16_t size if (size > 62) { block_in_bytes = 32; *blsize = 1; + *num_block = tu_div_ceil(size, 32); } else { block_in_bytes = 2; *blsize = 0; + *num_block = tu_div_ceil(size, 2); } - *num_block = tu_div_ceil(size, block_in_bytes); - return (*num_block) * block_in_bytes; } @@ -276,6 +276,10 @@ TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, u /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ uint16_t bl_nb = (blsize << 15) | ((num_block - blsize) << 10); + if (bl_nb == 0) { + // 0 is invalid, set up blsize to 1 + bl_nb = 1 << 15; + } #ifdef FSDEV_BUS_32BIT uint32_t count_addr = FSDEV_BTABLE->ep32[ep_id][buf_id].count_addr; @@ -284,6 +288,7 @@ TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, u #else FSDEV_BTABLE->ep16[ep_id][buf_id].count = bl_nb; #endif + } #ifdef __cplusplus -- cgit v1.3.1 From 57c26fdc72dccee1da569e90f46b4060a97d47a7 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 8 Aug 2024 00:27:51 +0700 Subject: use EP_KIND for STATUS OUT to fix OUT packet is auto accepted after SETUP without usbd consent --- .idea/cmake.xml | 15 +++++------ src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 36 +++++++++++++++++---------- src/portable/st/stm32_fsdev/fsdev_type.h | 4 +-- 3 files changed, 33 insertions(+), 22 deletions(-) (limited to 'src/portable') diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 67e793016..bf5696725 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -89,19 +89,20 @@ - - + + + - + - + - + @@ -133,8 +134,8 @@ - - + + diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index cd7410488..89697106d 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -147,6 +147,7 @@ typedef struct { static xfer_ctl_t xfer_status[CFG_TUD_ENDPPOINT_MAX][2]; static ep_alloc_t ep_alloc_status[FSDEV_EP_COUNT]; static uint8_t remoteWakeCountdown; // When wake is requested +static uint8_t _setup_dir; // for detecting status OUT //--------------------------------------------------------------------+ // Prototypes @@ -311,6 +312,7 @@ static void handle_ctr_setup(uint32_t ep_id) { // Setup packet should always be 8 bytes. If not, we probably missed the packet if (rx_count == 8) { + _setup_dir = (setup_packet[0] & 0x80 ? TUSB_DIR_IN : TUSB_DIR_OUT); dcd_event_setup_received(0, (uint8_t*) setup_packet, true); // Hardware should reset EP0 RX/TX to NAK and both toggle to 1 } else { @@ -323,8 +325,6 @@ static void handle_ctr_setup(uint32_t ep_id) { // Handle CTR interrupt for the RX/OUT direction static void handle_ctr_rx(uint32_t ep_id) { uint32_t ep_reg = ep_read(ep_id) | USB_EP_CTR_TX | USB_EP_CTR_RX; - ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_OUT); // will change RX Status, reserved other toggle bits - uint8_t const ep_num = ep_reg & USB_EPADDR_FIELD; bool const is_iso = ep_is_iso(ep_reg); xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_OUT); @@ -345,6 +345,13 @@ static void handle_ctr_rx(uint32_t ep_id) { dcd_read_packet_memory(xfer->buffer + xfer->queued_len, pma_addr, rx_count); } xfer->queued_len += rx_count; + } else { + // ZLP Status OUT + if (ep_num == 0 && (ep_reg & USB_EP_KIND) ) { + ep_reg &= USB_EPREG_MASK; + ep_reg &= ~USB_EP_KIND; // clear kind bit + ep_write(ep_id, ep_reg, false); + } } if ((rx_count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { @@ -360,6 +367,7 @@ static void handle_ctr_rx(uint32_t ep_id) { uint16_t const cnt = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, cnt); } + ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_OUT); // will change RX Status, reserved other toggle bits ep_change_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_VALID); ep_write(ep_id, ep_reg, false); } @@ -367,9 +375,6 @@ static void handle_ctr_rx(uint32_t ep_id) { void dcd_int_handler(uint8_t rhport) { uint32_t int_status = FSDEV_REG->ISTR; - // const uint32_t handled_ints = USB_ISTR_CTR | USB_ISTR_RESET | USB_ISTR_WKUP - // | USB_ISTR_SUSP | USB_ISTR_SOF | USB_ISTR_ESOF; - // unused IRQs: (USB_ISTR_PMAOVR | USB_ISTR_ERR | USB_ISTR_L1REQ ) /* Put SOF flag at the beginning of ISR in case to get least amount of jitter if it is used for timing purposes */ if (int_status & USB_ISTR_SOF) { @@ -738,17 +743,22 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); - uint16_t cnt = tu_min16(xfer->total_len, xfer->max_packet_size); - - if (ep_is_iso(ep_reg)) { - btable_set_rx_bufsize(ep_idx, 0, cnt); - btable_set_rx_bufsize(ep_idx, 1, cnt); + if ( ep_num == 0 && dir == TUSB_DIR_OUT && _setup_dir == TUSB_DIR_IN ) { + // use EP0 OUT status stage, otherwise OUT packet right after SETUP will be accepted without + // the usbd (software) consent + ep_reg |= USB_EP_KIND; } else { - btable_set_rx_bufsize(ep_idx, BTABLE_BUF_RX, cnt); - } + uint16_t cnt = tu_min16(xfer->total_len, xfer->max_packet_size); + if (ep_is_iso(ep_reg)) { + btable_set_rx_bufsize(ep_idx, 0, cnt); + btable_set_rx_bufsize(ep_idx, 1, cnt); + } else { + btable_set_rx_bufsize(ep_idx, BTABLE_BUF_RX, cnt); + } + } ep_change_status(&ep_reg, dir, EP_STAT_VALID); - ep_write(ep_idx, ep_reg, false); + ep_write(ep_idx, ep_reg, true); } return true; diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h index 6c5ccae89..7ebc32255 100644 --- a/src/portable/st/stm32_fsdev/fsdev_type.h +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -277,8 +277,8 @@ TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, u /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ uint16_t bl_nb = (blsize << 15) | ((num_block - blsize) << 10); if (bl_nb == 0) { - // 0 is invalid, set up blsize to 1 - bl_nb = 1 << 15; + // zlp but 0 is invalid value, set num_block to 1 (2 bytes) + bl_nb = 1 << 10; } #ifdef FSDEV_BUS_32BIT -- cgit v1.3.1 From bd64625df271c461c3d6008f96c630c61218f451 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 8 Aug 2024 12:40:11 +0700 Subject: revert the use of EP_KIND. ch32v203 seems to unconditionally accept ZLP on EP0 OUT, which can incorrectly use queued_len of previous transfer. So reset total_len and queued_len to 0. --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 38 +++++++++------------------ 1 file changed, 13 insertions(+), 25 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 89697106d..bbdfbaa09 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -147,7 +147,6 @@ typedef struct { static xfer_ctl_t xfer_status[CFG_TUD_ENDPPOINT_MAX][2]; static ep_alloc_t ep_alloc_status[FSDEV_EP_COUNT]; static uint8_t remoteWakeCountdown; // When wake is requested -static uint8_t _setup_dir; // for detecting status OUT //--------------------------------------------------------------------+ // Prototypes @@ -312,7 +311,6 @@ static void handle_ctr_setup(uint32_t ep_id) { // Setup packet should always be 8 bytes. If not, we probably missed the packet if (rx_count == 8) { - _setup_dir = (setup_packet[0] & 0x80 ? TUSB_DIR_IN : TUSB_DIR_OUT); dcd_event_setup_received(0, (uint8_t*) setup_packet, true); // Hardware should reset EP0 RX/TX to NAK and both toggle to 1 } else { @@ -345,22 +343,17 @@ static void handle_ctr_rx(uint32_t ep_id) { dcd_read_packet_memory(xfer->buffer + xfer->queued_len, pma_addr, rx_count); } xfer->queued_len += rx_count; - } else { - // ZLP Status OUT - if (ep_num == 0 && (ep_reg & USB_EP_KIND) ) { - ep_reg &= USB_EPREG_MASK; - ep_reg &= ~USB_EP_KIND; // clear kind bit - ep_write(ep_id, ep_reg, false); - } } - if ((rx_count < xfer->max_packet_size) || (xfer->queued_len == xfer->total_len)) { + if ((rx_count < xfer->max_packet_size) || (xfer->queued_len >= xfer->total_len)) { // all bytes received or short packet + dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); - // reset rx bufsize to mps to prevent race condition to cause PMAOVR (occurs with ch32v203 with msc write10) + // For ch32v203: reset rx bufsize to mps to prevent race condition to cause PMAOVR (occurs with msc write10) + // also ch32 seems to unconditionally accept ZLP on EP0 OUT, which can incorrectly use queued_len of previous + // transfer. So reset total_len and queued_len to 0. btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, xfer->max_packet_size); - - dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); + xfer->total_len = xfer->queued_len = 0; } else { // Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always if (!is_iso) { @@ -743,20 +736,15 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { uint32_t ep_reg = ep_read(ep_idx) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(dir); - if ( ep_num == 0 && dir == TUSB_DIR_OUT && _setup_dir == TUSB_DIR_IN ) { - // use EP0 OUT status stage, otherwise OUT packet right after SETUP will be accepted without - // the usbd (software) consent - ep_reg |= USB_EP_KIND; - } else { - uint16_t cnt = tu_min16(xfer->total_len, xfer->max_packet_size); + uint16_t cnt = tu_min16(xfer->total_len, xfer->max_packet_size); - if (ep_is_iso(ep_reg)) { - btable_set_rx_bufsize(ep_idx, 0, cnt); - btable_set_rx_bufsize(ep_idx, 1, cnt); - } else { - btable_set_rx_bufsize(ep_idx, BTABLE_BUF_RX, cnt); - } + if (ep_is_iso(ep_reg)) { + btable_set_rx_bufsize(ep_idx, 0, cnt); + btable_set_rx_bufsize(ep_idx, 1, cnt); + } else { + btable_set_rx_bufsize(ep_idx, BTABLE_BUF_RX, cnt); } + ep_change_status(&ep_reg, dir, EP_STAT_VALID); ep_write(ep_idx, ep_reg, true); } -- cgit v1.3.1 From 1ea38ebe13f07c4db99ae39f207e55815d3701b3 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 8 Aug 2024 15:43:11 +0700 Subject: refactor read/write pma from/to fifo --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 247 ++++++++++---------------- src/portable/st/stm32_fsdev/fsdev_type.h | 8 + 2 files changed, 98 insertions(+), 157 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index bbdfbaa09..252969648 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -336,14 +336,12 @@ static void handle_ctr_rx(uint32_t ep_id) { uint16_t const rx_count = btable_get_count(ep_id, buf_id); uint16_t pma_addr = (uint16_t) btable_get_addr(ep_id, buf_id); - if (rx_count != 0) { - if (xfer->ff) { - dcd_read_packet_memory_ff(xfer->ff, pma_addr, rx_count); - } else { - dcd_read_packet_memory(xfer->buffer + xfer->queued_len, pma_addr, rx_count); - } - xfer->queued_len += rx_count; + if (xfer->ff) { + dcd_read_packet_memory_ff(xfer->ff, pma_addr, rx_count); + } else { + dcd_read_packet_memory(xfer->buffer + xfer->queued_len, pma_addr, rx_count); } + xfer->queued_len += rx_count; if ((rx_count < xfer->max_packet_size) || (xfer->queued_len >= xfer->total_len)) { // all bytes received or short packet @@ -706,14 +704,12 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { } uint16_t addr_ptr = (uint16_t) btable_get_addr(ep_ix, buf_id); - if (len) { - if (xfer->ff) { - dcd_write_packet_memory_ff(xfer->ff, addr_ptr, len); - } else { - dcd_write_packet_memory(addr_ptr, &(xfer->buffer[xfer->queued_len]), len); - } - xfer->queued_len += len; + if (xfer->ff) { + dcd_write_packet_memory_ff(xfer->ff, addr_ptr, len); + } else { + dcd_write_packet_memory(addr_ptr, &(xfer->buffer[xfer->queued_len]), len); } + xfer->queued_len += len; btable_set_count(ep_ix, buf_id, len); ep_change_status(&ep_reg, TUSB_DIR_IN, EP_STAT_VALID); @@ -814,25 +810,20 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { // - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT // - Uses unaligned for RAM (since M0 cannot access unaligned address) static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, uint16_t nbytes) { - enum { BUS_SIZE = sizeof(fsdev_bus_t) }; - uint32_t n_write = nbytes / BUS_SIZE; + if (nbytes == 0) return true; + uint32_t n_write = nbytes / FSDEV_BUS_SIZE; fsdev_pma_buf_t* pma_buf = PMA_BUF_AT(dst); const uint8_t *src8 = src; while (n_write--) { - #ifdef FSDEV_BUS_32BIT - pma_buf->value = tu_unaligned_read32(src8); - #else - pma_buf->value = tu_unaligned_read16(src8); - #endif - - src8 += BUS_SIZE; + pma_buf->value = fsdevbus_unaligned_read(src8); + src8 += FSDEV_BUS_SIZE; pma_buf++; } // odd bytes e.g 1 for 16-bit or 1-3 for 32-bit - uint16_t odd = nbytes & (BUS_SIZE - 1); + uint16_t odd = nbytes & (FSDEV_BUS_SIZE - 1); if (odd) { fsdev_bus_t temp = 0; for(uint16_t i = 0; i < odd; i++) { @@ -848,27 +839,20 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, ui // - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT // - Uses unaligned for RAM (since M0 cannot access unaligned address) static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t nbytes) { - enum { BUS_SIZE = sizeof(fsdev_bus_t) }; - uint32_t n_write = nbytes / BUS_SIZE; + if (nbytes == 0) return true; + uint32_t n_read = nbytes / FSDEV_BUS_SIZE; fsdev_pma_buf_t* pma_buf = PMA_BUF_AT(src); uint8_t *dst8 = (uint8_t *)dst; - while (n_write--) { - fsdev_bus_t temp = pma_buf->value; - - #ifdef FSDEV_BUS_32BIT - tu_unaligned_write32(dst8, temp); - #else - tu_unaligned_write16(dst8, temp); - #endif - - dst8 += BUS_SIZE; + while (n_read--) { + fsdevbus_unaligned_write(dst8, (fsdev_bus_t ) pma_buf->value); + dst8 += FSDEV_BUS_SIZE; pma_buf++; } // odd bytes e.g 1 for 16-bit or 1-3 for 32-bit - uint16_t odd = nbytes & (BUS_SIZE - 1); + uint16_t odd = nbytes & (FSDEV_BUS_SIZE - 1); if (odd) { fsdev_bus_t temp = pma_buf->value; while (odd--) { @@ -880,156 +864,105 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, uint16_t return true; } -/** - * @brief Copy from FIFO to packet memory area (PMA). - * Uses byte-access of system memory and 16-bit access of packet memory - * @param wNBytes no. of bytes to be copied. - * @retval None - */ +// Write to PMA from FIFO static bool dcd_write_packet_memory_ff(tu_fifo_t *ff, uint16_t dst, uint16_t wNBytes) { + if (wNBytes == 0) return true; + // Since we copy from a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies tu_fifo_buffer_info_t info; tu_fifo_get_read_info(ff, &info); - uint16_t cnt_lin = TU_MIN(wNBytes, info.len_lin); - uint16_t cnt_wrap = TU_MIN(wNBytes - cnt_lin, info.len_wrap); + uint16_t cnt_lin = tu_min16(wNBytes, info.len_lin); + uint16_t cnt_wrap = tu_min16(wNBytes - cnt_lin, info.len_wrap); + uint16_t const cnt_total = cnt_lin + cnt_wrap; // We want to read from the FIFO and write it into the PMA, if LIN part is ODD and has WRAPPED part, - // last lin byte will be combined with wrapped part - // To ensure PMA is always access aligned (dst aligned to 16 or 32 bit) -#ifdef FSDEV_BUS_32BIT - if ((cnt_lin & 0x03) && cnt_wrap) { - // Copy first linear part - dcd_write_packet_memory(dst, info.ptr_lin, cnt_lin & ~0x03); - dst += cnt_lin & ~0x03; - - // Copy last linear bytes & first wrapped bytes to buffer - uint32_t i; - uint8_t tmp[4]; - for (i = 0; i < (cnt_lin & 0x03); i++) { - tmp[i] = ((uint8_t *)info.ptr_lin)[(cnt_lin & ~0x03) + i]; - } - uint32_t wCnt = cnt_wrap; - for (; i < 4 && wCnt > 0; i++, wCnt--) { - tmp[i] = *(uint8_t *)info.ptr_wrap; - info.ptr_wrap = (uint8_t *)info.ptr_wrap + 1; + // last lin byte will be combined with wrapped part To ensure PMA is always access aligned + uint16_t lin_even = cnt_lin & ~(FSDEV_BUS_SIZE - 1); + uint16_t lin_odd = cnt_lin & (FSDEV_BUS_SIZE - 1); + uint8_t const *src8 = (uint8_t const*) info.ptr_lin; + + // write even linear part + dcd_write_packet_memory(dst, src8, lin_even); + dst += lin_even; + src8 += lin_even; + + if (lin_odd == 0) { + src8 = (uint8_t const*) info.ptr_wrap; + } else { + // Combine last linear bytes + first wrapped bytes to form fsdev bus width data + fsdev_bus_t temp = 0; + uint16_t i; + for(i = 0; i < lin_odd; i++) { + temp |= *src8++ << (i * 8); } - // Write unaligned buffer - dcd_write_packet_memory(dst, &tmp, 4); - dst += 4; - - // Copy rest of wrapped byte - if (wCnt) { - dcd_write_packet_memory(dst, info.ptr_wrap, wCnt); - } - } -#else - if ((cnt_lin & 0x01) && cnt_wrap) { - // Copy first linear part - dcd_write_packet_memory(dst, info.ptr_lin, cnt_lin & ~0x01); - dst += cnt_lin & ~0x01; - - // Copy last linear byte & first wrapped byte - uint16_t tmp = ((uint8_t *)info.ptr_lin)[cnt_lin - 1] | ((uint16_t)(((uint8_t *)info.ptr_wrap)[0]) << 8U); - dcd_write_packet_memory(dst, &tmp, 2); - dst += 2; - - // Copy rest of wrapped byte - dcd_write_packet_memory(dst, ((uint8_t *)info.ptr_wrap) + 1, cnt_wrap - 1); - } -#endif - else { - // Copy linear part - dcd_write_packet_memory(dst, info.ptr_lin, cnt_lin); - dst += info.len_lin; - - if (info.len_wrap) { - // Copy wrapped byte - dcd_write_packet_memory(dst, info.ptr_wrap, cnt_wrap); + src8 = (uint8_t const*) info.ptr_wrap; + for(; i < FSDEV_BUS_SIZE && cnt_wrap > 0; i++, cnt_wrap--) { + temp |= *src8++ << (i * 8); } + + dcd_write_packet_memory(dst, &temp, FSDEV_BUS_SIZE); + dst += FSDEV_BUS_SIZE; } - tu_fifo_advance_read_pointer(ff, cnt_lin + cnt_wrap); + // write the rest of the wrapped part + dcd_write_packet_memory(dst, src8, cnt_wrap); + tu_fifo_advance_read_pointer(ff, cnt_total); return true; } -/** - * @brief Copy a buffer from user packet memory area (PMA) to FIFO. - * Uses byte-access of system memory and 16-bit access of packet memory - * @param wNBytes no. of bytes to be copied. - * @retval None - */ +// Read from PMA to FIFO static bool dcd_read_packet_memory_ff(tu_fifo_t *ff, uint16_t src, uint16_t wNBytes) { + if (wNBytes == 0) return true; + // Since we copy into a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies // Check for first linear part tu_fifo_buffer_info_t info; tu_fifo_get_write_info(ff, &info); // We want to read from the FIFO - uint16_t cnt_lin = TU_MIN(wNBytes, info.len_lin); - uint16_t cnt_wrap = TU_MIN(wNBytes - cnt_lin, info.len_wrap); - - // We want to read from PMA and write it into the FIFO, if LIN part is ODD and has WRAPPED part, - // last lin byte will be combined with wrapped part - // To ensure PMA is always access aligned (src aligned to 16 or 32 bit) -#ifdef FSDEV_BUS_32BIT - if ((cnt_lin & 0x03) && cnt_wrap) { - // Copy first linear part - dcd_read_packet_memory(info.ptr_lin, src, cnt_lin & ~0x03); - src += cnt_lin & ~0x03; - - // Copy last linear bytes & first wrapped bytes - uint8_t tmp[4]; - dcd_read_packet_memory(tmp, src, 4); - src += 4; - - uint32_t i; - for (i = 0; i < (cnt_lin & 0x03); i++) { - ((uint8_t *)info.ptr_lin)[(cnt_lin & ~0x03) + i] = tmp[i]; - } - uint32_t wCnt = cnt_wrap; - for (; i < 4 && wCnt > 0; i++, wCnt--) { - *(uint8_t *)info.ptr_wrap = tmp[i]; - info.ptr_wrap = (uint8_t *)info.ptr_wrap + 1; - } + uint16_t cnt_lin = tu_min16(wNBytes, info.len_lin); + uint16_t cnt_wrap = tu_min16(wNBytes - cnt_lin, info.len_wrap); + uint16_t cnt_total = cnt_lin + cnt_wrap; - // Copy rest of wrapped byte - if (wCnt) { - dcd_read_packet_memory(info.ptr_wrap, src, wCnt); - } - } -#else - if ((cnt_lin & 0x01) && cnt_wrap) { - // Copy first linear part - dcd_read_packet_memory(info.ptr_lin, src, cnt_lin & ~0x01); - src += cnt_lin & ~0x01; + // We want to read from the FIFO and write it into the PMA, if LIN part is ODD and has WRAPPED part, + // last lin byte will be combined with wrapped part To ensure PMA is always access aligned - // Copy last linear byte & first wrapped byte - uint8_t tmp[2]; - dcd_read_packet_memory(tmp, src, 2); - src += 2; + uint16_t lin_even = cnt_lin & ~(FSDEV_BUS_SIZE - 1); + uint16_t lin_odd = cnt_lin & (FSDEV_BUS_SIZE - 1); + uint8_t *dst8 = (uint8_t *) info.ptr_lin; - ((uint8_t *)info.ptr_lin)[cnt_lin - 1] = tmp[0]; - ((uint8_t *)info.ptr_wrap)[0] = tmp[1]; + // read even linear part + dcd_read_packet_memory(dst8, src, lin_even); + dst8 += lin_even; + src += lin_even; - // Copy rest of wrapped byte - dcd_read_packet_memory(((uint8_t *)info.ptr_wrap) + 1, src, cnt_wrap - 1); - } -#endif - else { - // Copy linear part - dcd_read_packet_memory(info.ptr_lin, src, cnt_lin); - src += cnt_lin; - - if (info.len_wrap) { - // Copy wrapped byte - dcd_read_packet_memory(info.ptr_wrap, src, cnt_wrap); + if (lin_odd == 0) { + dst8 = (uint8_t *) info.ptr_wrap; + } else { + // Combine last linear bytes + first wrapped bytes to form fsdev bus width data + fsdev_bus_t temp; + dcd_read_packet_memory(&temp, src, FSDEV_BUS_SIZE); + src += FSDEV_BUS_SIZE; + + uint16_t i; + for (i = 0; i < lin_odd; i++) { + *dst8++ = (uint8_t) (temp & 0xfful); + temp >>= 8; + } + + dst8 = (uint8_t *) info.ptr_wrap; + for (; i < FSDEV_BUS_SIZE && cnt_wrap > 0; i++, cnt_wrap--) { + *dst8++ = (uint8_t) (temp & 0xfful); + temp >>= 8; } } - tu_fifo_advance_write_pointer(ff, cnt_lin + cnt_wrap); + // read the rest of the wrapped part + dcd_read_packet_memory(dst8, src, cnt_wrap); + tu_fifo_advance_write_pointer(ff, cnt_total); return true; } diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h index 7ebc32255..26717fab0 100644 --- a/src/portable/st/stm32_fsdev/fsdev_type.h +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -66,10 +66,18 @@ TU_VERIFY_STATIC(FSDEV_BTABLE_BASE % 8 == 0, "BTABLE base must be aligned to 8 b // The fsdev_bus_t type can be used for both register and PMA access necessities #ifdef FSDEV_BUS_32BIT typedef uint32_t fsdev_bus_t; + #define fsdevbus_unaligned_read(_addr) tu_unaligned_read32(_addr) + #define fsdevbus_unaligned_write(_addr, _value) tu_unaligned_write32(_addr, _value) #else typedef uint16_t fsdev_bus_t; + #define fsdevbus_unaligned_read(_addr) tu_unaligned_read16(_addr) + #define fsdevbus_unaligned_write(_addr, _value) tu_unaligned_write16(_addr, _value) #endif +enum { + FSDEV_BUS_SIZE = sizeof(fsdev_bus_t), +}; + //--------------------------------------------------------------------+ // BTable Typedef //--------------------------------------------------------------------+ -- cgit v1.3.1 From a621c4b6fcd89df9b86d2911414e05e2e15184ec Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 12 Aug 2024 16:39:25 +0700 Subject: fix more race with ch32v203 and setup when queuing zlp. improve hil test failed output --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 22 ++++--- src/portable/st/stm32_fsdev/fsdev_type.h | 5 +- test/hil/hil_test.py | 93 ++++++++++++++++----------- 3 files changed, 73 insertions(+), 47 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 252969648..1e0e9c447 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -345,12 +345,14 @@ static void handle_ctr_rx(uint32_t ep_id) { if ((rx_count < xfer->max_packet_size) || (xfer->queued_len >= xfer->total_len)) { // all bytes received or short packet - dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); // For ch32v203: reset rx bufsize to mps to prevent race condition to cause PMAOVR (occurs with msc write10) - // also ch32 seems to unconditionally accept ZLP on EP0 OUT, which can incorrectly use queued_len of previous - // transfer. So reset total_len and queued_len to 0. btable_set_rx_bufsize(ep_id, BTABLE_BUF_RX, xfer->max_packet_size); + + dcd_event_xfer_complete(0, ep_num, xfer->queued_len, XFER_RESULT_SUCCESS, true); + + // ch32 seems to unconditionally accept ZLP on EP0 OUT, which can incorrectly use queued_len of previous + // transfer. So reset total_len and queued_len to 0. xfer->total_len = xfer->queued_len = 0; } else { // Set endpoint active again for receiving more data. Note that isochronous endpoints stay active always @@ -412,11 +414,6 @@ void dcd_int_handler(uint8_t rhport) { FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_ESOF; } - if (int_status & USB_ISTR_PMAOVR) { - TU_BREAKPOINT(); - FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_PMAOVR; - } - // loop to handle all pending CTR interrupts while (FSDEV_REG->ISTR & USB_ISTR_CTR) { // skip DIR bit, and use CTR TX/RX instead, since there is chance we have both TX/RX completed in one interrupt @@ -459,6 +456,11 @@ void dcd_int_handler(uint8_t rhport) { handle_ctr_tx(ep_id); } } + + if (int_status & USB_ISTR_PMAOVR) { + TU_BREAKPOINT(); + FSDEV_REG->ISTR = (fsdev_bus_t)~USB_ISTR_PMAOVR; + } } //--------------------------------------------------------------------+ @@ -806,6 +808,10 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { ep_write(ep_idx, ep_reg, true); } +//--------------------------------------------------------------------+ +// PMA read/write +//--------------------------------------------------------------------+ + // Write to packet memory area (PMA) from user memory // - Packet memory must be either strictly 16-bit or 32-bit depending on FSDEV_BUS_32BIT // - Uses unaligned for RAM (since M0 cannot access unaligned address) diff --git a/src/portable/st/stm32_fsdev/fsdev_type.h b/src/portable/st/stm32_fsdev/fsdev_type.h index 26717fab0..cf36576bb 100644 --- a/src/portable/st/stm32_fsdev/fsdev_type.h +++ b/src/portable/st/stm32_fsdev/fsdev_type.h @@ -285,8 +285,9 @@ TU_ATTR_ALWAYS_INLINE static inline void btable_set_rx_bufsize(uint32_t ep_id, u /* Encode into register. When BLSIZE==1, we need to subtract 1 block count */ uint16_t bl_nb = (blsize << 15) | ((num_block - blsize) << 10); if (bl_nb == 0) { - // zlp but 0 is invalid value, set num_block to 1 (2 bytes) - bl_nb = 1 << 10; + // zlp but 0 is invalid value, set blsize to 1 (32 bytes) + // Note: lower value can cause PMAOVR on setup with ch32v203 + bl_nb = 1 << 15; } #ifdef FSDEV_BUS_32BIT diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index b67520576..01ca93c7a 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -36,7 +36,7 @@ import glob import platform from multiprocessing import Pool -ENUM_TIMEOUT = 30 +ENUM_TIMEOUT = 20 # get usb serial by id @@ -110,7 +110,8 @@ def run_cmd(cmd): #print(cmd) r = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) if r.returncode != 0: - title = 'command error' + title = f'COMMAND FAILED: {cmd}' + print() if os.getenv('CI'): print(f"::group::{title}") print(r.stdout.decode("utf-8")) @@ -198,14 +199,15 @@ def flash_esptool(board, firmware): # ------------------------------------------------------------- # Tests # ------------------------------------------------------------- -def test_board_test(id): +def test_board_test(board): # Dummy test pass -def test_cdc_dual_ports(id): - port1 = get_serial_dev(id, 'TinyUSB', "TinyUSB_Device", 0) - port2 = get_serial_dev(id, 'TinyUSB', "TinyUSB_Device", 2) +def test_cdc_dual_ports(board): + uid = board['uid'] + port1 = get_serial_dev(uid, 'TinyUSB', "TinyUSB_Device", 0) + port2 = get_serial_dev(uid, 'TinyUSB', "TinyUSB_Device", 2) ser1 = open_serial_dev(port1) ser2 = open_serial_dev(port2) @@ -224,9 +226,10 @@ def test_cdc_dual_ports(id): assert ser2.read(100) == str2.upper(), 'Port2 wrong data' -def test_cdc_msc(id): +def test_cdc_msc(board): + uid = board['uid'] # Echo test - port = get_serial_dev(id, 'TinyUSB', "TinyUSB_Device", 0) + port = get_serial_dev(uid, 'TinyUSB', "TinyUSB_Device", 0) ser = open_serial_dev(port) str = b"test_str" @@ -235,7 +238,7 @@ def test_cdc_msc(id): assert ser.read(100) == str, 'CDC wrong data' # Block test - data = read_disk_file(id, 'README.TXT') + data = read_disk_file(uid, 'README.TXT') readme = \ b"This is tinyusb's MassStorage Class demo.\r\n\r\n\ If you find any bugs or get any questions, feel free to file an\r\n\ @@ -244,26 +247,28 @@ issue at github.com/hathach/tinyusb" assert data == readme, 'MSC wrong data' -def test_cdc_msc_freertos(id): - test_cdc_msc(id) +def test_cdc_msc_freertos(board): + test_cdc_msc(board) -def test_dfu(id): +def test_dfu(board): + uid = board['uid'] + # Wait device enum timeout = ENUM_TIMEOUT while timeout: ret = subprocess.run(f'dfu-util -l', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout = ret.stdout.decode() - if f'serial="{id}"' in stdout and 'Found DFU: [cafe:4000]' in stdout: + if f'serial="{uid}"' in stdout and 'Found DFU: [cafe:4000]' in stdout: break time.sleep(1) timeout = timeout - 1 assert timeout, 'Device not available' - f_dfu0 = f'dfu0_{id}' - f_dfu1 = f'dfu1_{id}' + f_dfu0 = f'dfu0_{uid}' + f_dfu1 = f'dfu1_{uid}' # Test upload try: @@ -272,10 +277,10 @@ def test_dfu(id): except OSError: pass - ret = run_cmd(f'dfu-util -S {id} -a 0 -U {f_dfu0}') + ret = run_cmd(f'dfu-util -S {uid} -a 0 -U {f_dfu0}') assert ret.returncode == 0, 'Upload failed' - ret = run_cmd(f'dfu-util -S {id} -a 1 -U {f_dfu1}') + ret = run_cmd(f'dfu-util -S {uid} -a 1 -U {f_dfu1}') assert ret.returncode == 0, 'Upload failed' with open(f_dfu0) as f: @@ -288,14 +293,16 @@ def test_dfu(id): os.remove(f_dfu1) -def test_dfu_runtime(id): +def test_dfu_runtime(board): + uid = board['uid'] + # Wait device enum timeout = ENUM_TIMEOUT while timeout: ret = subprocess.run(f'dfu-util -l', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) stdout = ret.stdout.decode() - if f'serial="{id}"' in stdout and 'Found Runtime: [cafe:4000]' in stdout: + if f'serial="{uid}"' in stdout and 'Found Runtime: [cafe:4000]' in stdout: break time.sleep(1) timeout = timeout - 1 @@ -303,10 +310,11 @@ def test_dfu_runtime(id): assert timeout, 'Device not available' -def test_hid_boot_interface(id): - kbd = get_hid_dev(id, 'TinyUSB', 'TinyUSB_Device', 'event-kbd') - mouse1 = get_hid_dev(id, 'TinyUSB', 'TinyUSB_Device', 'if01-event-mouse') - mouse2 = get_hid_dev(id, 'TinyUSB', 'TinyUSB_Device', 'if01-mouse') +def test_hid_boot_interface(board): + uid = board['uid'] + kbd = get_hid_dev(uid, 'TinyUSB', 'TinyUSB_Device', 'event-kbd') + mouse1 = get_hid_dev(uid, 'TinyUSB', 'TinyUSB_Device', 'if01-event-mouse') + mouse2 = get_hid_dev(uid, 'TinyUSB', 'TinyUSB_Device', 'if01-mouse') # Wait device enum timeout = ENUM_TIMEOUT while timeout: @@ -338,22 +346,23 @@ all_tests = [ ] -def test_board(item): - name = item['name'] - flasher = item['flasher'].lower() +def test_board(board): + name = board['name'] + flasher = board['flasher'].lower() # default to all tests - if 'tests' in item: - test_list = item['tests'] + ['board_test'] + if 'tests' in board: + test_list = board['tests'] + ['board_test'] else: test_list = list(all_tests) # remove skip_tests - if 'tests_skip' in item: - for skip in item['tests_skip']: + if 'tests_skip' in board: + for skip in board['tests_skip']: if skip in test_list: test_list.remove(skip) + err_count = 0 for test in test_list: fw_dir = f'cmake-build/cmake-build-{name}/device/{test}' if not os.path.exists(fw_dir): @@ -367,19 +376,26 @@ def test_board(item): # flash firmware. It may fail randomly, retry a few times for i in range(3): - ret = globals()[f'flash_{flasher}'](item, fw_name) + ret = globals()[f'flash_{flasher}'](board, fw_name) if ret.returncode == 0: break else: print(f'Flashing failed, retry {i+1}') time.sleep(1) - assert ret.returncode == 0, 'Flash failed\n' + ret.stdout.decode() - - # run test - globals()[f'test_{test}'](item['uid']) - print('OK') + if ret.returncode == 0: + try: + ret = globals()[f'test_{test}'](board) + print('OK') + except AssertionError as e: + err_count += 1 + print('Failed') + print(f' {e}') + else: + err_count += 1 + print('Flash failed') + return err_count def main(): """ @@ -404,8 +420,11 @@ def main(): else: config_boards = [e for e in config['boards'] if e['name'] in boards] + err_count_list = 0 with Pool(processes=os.cpu_count()) as pool: - pool.map(test_board, config_boards) + err_count_list = pool.map(test_board, config_boards) + + sys.exit(sum(err_count_list)) if __name__ == '__main__': -- cgit v1.3.1 From 5666aa196f99e323e025179559ef8ac1db390749 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 12 Aug 2024 15:38:22 +0200 Subject: Fix tusb_dir_t warning. --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 1e0e9c447..ed9036d19 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -155,7 +155,7 @@ static uint8_t remoteWakeCountdown; // When wake is requested // into the stack. static void handle_bus_reset(uint8_t rhport); static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix); -static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir); +static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, tusb_dir_t dir); // PMA allocation/access static uint16_t ep_buf_ptr; ///< Points to first free memory location @@ -578,7 +578,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { (void)rhport; uint8_t const ep_addr = desc_ep->bEndpointAddress; uint8_t const ep_num = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); const uint16_t packet_size = tu_edpt_packet_size(desc_ep); uint8_t const ep_idx = dcd_ep_alloc(ep_addr, desc_ep->bmAttributes.xfer); TU_ASSERT(ep_idx < FSDEV_EP_COUNT); @@ -671,7 +671,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) (void)rhport; uint8_t const ep_addr = desc_ep->bEndpointAddress; uint8_t const ep_num = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, dir); uint8_t const ep_idx = xfer->ep_idx; @@ -683,7 +683,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) ep_change_status(&ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED); ep_change_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED); ep_change_dtog(&ep_reg, dir, 0); - ep_change_dtog(&ep_reg, 1 - dir, 1); + ep_change_dtog(&ep_reg, (tusb_dir_t)(1 - dir), 1); ep_write(ep_idx, ep_reg, true); @@ -722,7 +722,7 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { ep_write(ep_ix, ep_reg, true); } -static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { +static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, tusb_dir_t dir) { (void) rhport; xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); @@ -752,7 +752,7 @@ static bool edpt_xfer(uint8_t rhport, uint8_t ep_num, uint8_t dir) { bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { uint8_t const ep_num = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); xfer->buffer = buffer; @@ -765,7 +765,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes) { uint8_t const ep_num = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); xfer->buffer = NULL; @@ -779,7 +779,7 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; uint8_t const ep_num = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); uint8_t const ep_idx = xfer->ep_idx; @@ -794,7 +794,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; uint8_t const ep_num = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + tusb_dir_t const dir = tu_edpt_dir(ep_addr); xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, dir); uint8_t const ep_idx = xfer->ep_idx; -- cgit v1.3.1 From 549f20d1793d1896a376a1ea978a4f02217de4ed Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 12 Aug 2024 15:39:02 +0200 Subject: Fix buf_id read for ISO transfer. --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index ed9036d19..0cdc3eef9 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -275,7 +275,6 @@ static void handle_bus_reset(uint8_t rhport) { // Handle CTR interrupt for the TX/IN direction static void handle_ctr_tx(uint32_t ep_id) { uint32_t ep_reg = ep_read(ep_id) | USB_EP_CTR_TX | USB_EP_CTR_RX; - ep_reg &= USB_EPREG_MASK; uint8_t const ep_num = ep_reg & USB_EPADDR_FIELD; xfer_ctl_t *xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_IN); @@ -694,7 +693,6 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { uint16_t len = tu_min16(xfer->total_len - xfer->queued_len, xfer->max_packet_size); uint32_t ep_reg = ep_read(ep_ix) | USB_EP_CTR_TX | USB_EP_CTR_RX; // reserve CTR - ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_IN); // only change TX Status, reserve other toggle bits bool const is_iso = ep_is_iso(ep_reg); @@ -719,6 +717,7 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { if (is_iso) { xfer->iso_in_sending = true; } + ep_reg &= USB_EPREG_MASK | EP_STAT_MASK(TUSB_DIR_IN); // only change TX Status, reserve other toggle bits ep_write(ep_ix, ep_reg, true); } -- cgit v1.3.1 From 96c5c72e971674ba3a4023aed02bf31cc8c994dc Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 12 Aug 2024 18:38:23 +0200 Subject: Fix double buffer not disabled for smaller devices. --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 0cdc3eef9..6eea1ab32 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -650,10 +650,11 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet /* Create a packet memory buffer area. Enable double buffering for devices with 2048 bytes PMA, for smaller devices double buffering occupy too much space. */ - uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, true); #if FSDEV_PMA_SIZE > 1024u + uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, true); uint16_t pma_addr2 = pma_addr >> 16; #else + uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, false); uint16_t pma_addr2 = pma_addr; #endif -- cgit v1.3.1 From f6b96f7ea9f0d0c4872e1e290bf59f65c68a7bf3 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 14 Aug 2024 22:56:59 +0700 Subject: fix spelling, add max32 to ci with arm-gcc build --- .github/workflows/ci_set_matrix.py | 1 + src/portable/mentor/musb/musb_ti.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'src/portable') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index a56bd4214..c9698c934 100644 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -22,6 +22,7 @@ family_list = { "lpc11 lpc13 lpc15": ["arm-gcc", "arm-clang"], "lpc17 lpc18 lpc40 lpc43": ["arm-gcc", "arm-clang"], "lpc51 lpc54 lpc55": ["arm-gcc", "arm-clang"], + "max32650 max32666 max32690 max78002": ["arm-gcc"], "mcx": ["arm-gcc"], "mm32": ["arm-gcc"], "msp430": ["msp430-gcc"], diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h index dbf82f391..4c9f00278 100644 --- a/src/portable/mentor/musb/musb_ti.h +++ b/src/portable/mentor/musb/musb_ti.h @@ -43,7 +43,7 @@ #endif -// Header supports both device and host modes. Only include whats necessary +// Header supports both device and host modes. Only include what's necessary #if CFG_TUD_ENABLED // Mapping of peripheral instances to port. Currently just 1. -- cgit v1.3.1 From 0be427bae95ef0fe94cb6f0b405eb5c3bbae160a Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 14 Aug 2024 23:59:35 +0700 Subject: use max32 cmsis, fix NVIC_GetEnableIRQ() not defined when using with CMISIS < 5 --- hw/bsp/max32650/family.c | 16 ++++++++++++++-- hw/bsp/max32650/family.cmake | 1 - hw/bsp/max32650/family.mk | 3 +-- hw/bsp/max32666/family.c | 15 +++++++++++++-- hw/bsp/max32666/family.cmake | 1 - hw/bsp/max32666/family.mk | 1 - hw/bsp/max32690/family.c | 16 ++++++++++++++-- hw/bsp/max32690/family.cmake | 1 - hw/bsp/max32690/family.mk | 1 - hw/bsp/max78002/family.c | 15 +++++++++++++-- hw/bsp/max78002/family.cmake | 1 - hw/bsp/max78002/family.mk | 1 - src/portable/mentor/musb/musb_max32.h | 33 ++++++++++++++------------------- tools/get_deps.py | 2 +- 14 files changed, 70 insertions(+), 37 deletions(-) (limited to 'src/portable') diff --git a/hw/bsp/max32650/family.c b/hw/bsp/max32650/family.c index 16b5233b9..89a5db160 100644 --- a/hw/bsp/max32650/family.c +++ b/hw/bsp/max32650/family.c @@ -24,12 +24,24 @@ * This file is part of the TinyUSB stack. */ -#include "board.h" -#include "bsp/board_api.h" +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" // _mxc_crit_get_state() +#endif + #include "gpio.h" +#include "mxc_sys.h" #include "mxc_device.h" #include "uart.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +#include "board.h" +#include "bsp/board_api.h" + + //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ diff --git a/hw/bsp/max32650/family.cmake b/hw/bsp/max32650/family.cmake index 92b68a1cd..8c4f286a2 100644 --- a/hw/bsp/max32650/family.cmake +++ b/hw/bsp/max32650/family.cmake @@ -74,7 +74,6 @@ function(add_board_target BOARD_TARGET) ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include ${MAX32_CMSIS}/Include ${MAX32_CMSIS}/Device/Maxim/MAX32650/Include ${MAX32_PERIPH}/Include/MAX32650 diff --git a/hw/bsp/max32650/family.mk b/hw/bsp/max32650/family.mk index 359261216..d2fc293e4 100644 --- a/hw/bsp/max32650/family.mk +++ b/hw/bsp/max32650/family.mk @@ -82,14 +82,13 @@ SRC_C += \ $(PERIPH_SRC)/ICC/icc_reva.c \ $(PERIPH_SRC)/ICC/icc_common.c \ $(PERIPH_SRC)/TPU/tpu_me10.c \ - $(PERIPH_SRC)/TPU/tpu_reva.c \ + $(PERIPH_SRC)/TPU/tpu_reva.c \ $(PERIPH_SRC)/UART/uart_common.c \ $(PERIPH_SRC)/UART/uart_me10.c \ $(PERIPH_SRC)/UART/uart_reva.c \ INC += \ $(TOP)/$(BOARD_PATH) \ - $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(MAX32_CMSIS)/Include \ $(TOP)/$(MAX32_CMSIS)/Device/Maxim/MAX32650/Include \ $(TOP)/$(MAX32_PERIPH)/Include/MAX32650 \ diff --git a/hw/bsp/max32666/family.c b/hw/bsp/max32666/family.c index 1398e09ff..8ee4b6762 100644 --- a/hw/bsp/max32666/family.c +++ b/hw/bsp/max32666/family.c @@ -24,13 +24,24 @@ * This file is part of the TinyUSB stack. */ -#include "board.h" -#include "bsp/board_api.h" +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" // _mxc_crit_get_state() +#endif + #include "gpio.h" +#include "mxc_sys.h" #include "mcr_regs.h" #include "mxc_device.h" #include "uart.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +#include "board.h" +#include "bsp/board_api.h" + //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ diff --git a/hw/bsp/max32666/family.cmake b/hw/bsp/max32666/family.cmake index eb9d2175f..4a3f1a428 100644 --- a/hw/bsp/max32666/family.cmake +++ b/hw/bsp/max32666/family.cmake @@ -70,7 +70,6 @@ function(add_board_target BOARD_TARGET) ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include ${MAX32_CMSIS}/Include ${MAX32_CMSIS}/Device/Maxim/MAX32665/Include ${MAX32_PERIPH}/Include/MAX32665 diff --git a/hw/bsp/max32666/family.mk b/hw/bsp/max32666/family.mk index 720d994ef..b4f7d1e57 100644 --- a/hw/bsp/max32666/family.mk +++ b/hw/bsp/max32666/family.mk @@ -82,7 +82,6 @@ SRC_C += \ INC += \ $(TOP)/$(BOARD_PATH) \ - $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(MAX32_CMSIS)/Include \ $(TOP)/$(MAX32_CMSIS)/Device/Maxim/MAX32665/Include \ $(TOP)/$(MAX32_PERIPH)/Include/MAX32665 \ diff --git a/hw/bsp/max32690/family.c b/hw/bsp/max32690/family.c index f4998bdbe..2418168d4 100644 --- a/hw/bsp/max32690/family.c +++ b/hw/bsp/max32690/family.c @@ -24,13 +24,25 @@ * This file is part of the TinyUSB stack. */ -#include "board.h" -#include "bsp/board_api.h" +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" // _mxc_crit_get_state() +#endif + #include "gpio.h" +#include "mxc_sys.h" #include "mcr_regs.h" #include "mxc_device.h" #include "uart.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +#include "board.h" +#include "bsp/board_api.h" + + //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ diff --git a/hw/bsp/max32690/family.cmake b/hw/bsp/max32690/family.cmake index 2a9422dbe..58647e432 100644 --- a/hw/bsp/max32690/family.cmake +++ b/hw/bsp/max32690/family.cmake @@ -75,7 +75,6 @@ function(add_board_target BOARD_TARGET) ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include ${MAX32_CMSIS}/Include ${MAX32_CMSIS}/Device/Maxim/MAX32690/Include ${MAX32_PERIPH}/Include/MAX32690 diff --git a/hw/bsp/max32690/family.mk b/hw/bsp/max32690/family.mk index c533cf4a4..d4df8ef2f 100644 --- a/hw/bsp/max32690/family.mk +++ b/hw/bsp/max32690/family.mk @@ -90,7 +90,6 @@ SRC_C += \ INC += \ $(TOP)/$(BOARD_PATH) \ - $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(MAX32_CMSIS)/Include \ $(TOP)/$(MAX32_CMSIS)/Device/Maxim/MAX32690/Include \ $(TOP)/$(MAX32_PERIPH)/Include/MAX32690 \ diff --git a/hw/bsp/max78002/family.c b/hw/bsp/max78002/family.c index 7758083a2..8d51f141c 100644 --- a/hw/bsp/max78002/family.c +++ b/hw/bsp/max78002/family.c @@ -24,13 +24,24 @@ * This file is part of the TinyUSB stack. */ -#include "board.h" -#include "bsp/board_api.h" +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" // _mxc_crit_get_state() +#endif + #include "gpio.h" +#include "mxc_sys.h" #include "mcr_regs.h" #include "mxc_device.h" #include "uart.h" +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + +#include "board.h" +#include "bsp/board_api.h" + //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler //--------------------------------------------------------------------+ diff --git a/hw/bsp/max78002/family.cmake b/hw/bsp/max78002/family.cmake index 090f1da43..446930bd8 100644 --- a/hw/bsp/max78002/family.cmake +++ b/hw/bsp/max78002/family.cmake @@ -72,7 +72,6 @@ function(add_board_target BOARD_TARGET) ) target_include_directories(${BOARD_TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMSIS_5}/CMSIS/Core/Include ${MAX32_CMSIS}/Include ${MAX32_CMSIS}/Device/Maxim/MAX78002/Include ${MAX32_PERIPH}/Include/MAX78002 diff --git a/hw/bsp/max78002/family.mk b/hw/bsp/max78002/family.mk index 5297815de..997816261 100644 --- a/hw/bsp/max78002/family.mk +++ b/hw/bsp/max78002/family.mk @@ -87,7 +87,6 @@ SRC_C += \ INC += \ $(TOP)/$(BOARD_PATH) \ - $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ $(TOP)/$(MAX32_CMSIS)/Include \ $(TOP)/$(MAX32_CMSIS)/Device/Maxim/MAX78002/Include \ $(TOP)/$(MAX32_PERIPH)/Include/MAX78002 \ diff --git a/src/portable/mentor/musb/musb_max32.h b/src/portable/mentor/musb/musb_max32.h index 297a695f8..bc6ce76dd 100644 --- a/src/portable/mentor/musb/musb_max32.h +++ b/src/portable/mentor/musb/musb_max32.h @@ -31,13 +31,8 @@ extern "C" { #endif -#if TU_CHECK_MCU(OPT_MCU_MAX32690, OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX78002) - #include "mxc_device.h" - #include "usbhs_regs.h" -#else - #error "Unsupported MCUs" -#endif - +#include "mxc_device.h" +#include "usbhs_regs.h" #if CFG_TUD_ENABLED #define USBHS_M31_CLOCK_RECOVERY @@ -48,39 +43,39 @@ static mxc_usbhs_regs_t* const musb_periph_inst[] = { }; // Mapping of IRQ numbers to port. Currently just 1. -static const IRQn_Type musb_irqs[] = { +static const IRQn_Type musb_irqs[] = { USB_IRQn }; TU_ATTR_ALWAYS_INLINE -static inline void musb_dcd_int_enable(uint8_t rhport) -{ +static inline void musb_dcd_int_enable(uint8_t rhport) { NVIC_EnableIRQ(musb_irqs[rhport]); } TU_ATTR_ALWAYS_INLINE -static inline void musb_dcd_int_disable(uint8_t rhport) -{ +static inline void musb_dcd_int_disable(uint8_t rhport) { NVIC_DisableIRQ(musb_irqs[rhport]); } TU_ATTR_ALWAYS_INLINE -static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) -{ +static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) { + #ifdef NVIC_GetEnableIRQ // only defined in CMSIS 5 return NVIC_GetEnableIRQ(musb_irqs[rhport]); + #else + uint32_t IRQn = (uint32_t) musb_irqs[rhport]; + return ((NVIC->ISER[IRQn >> 5UL] & (1UL << (IRQn & 0x1FUL))) != 0UL) ? 1UL : 0UL; + #endif } TU_ATTR_ALWAYS_INLINE -static inline void musb_dcd_int_clear(uint8_t rhport) -{ - NVIC_ClearPendingIRQ(musb_irqs[rhport]); +static inline void musb_dcd_int_clear(uint8_t rhport) { + NVIC_ClearPendingIRQ(musb_irqs[rhport]); } //Used to save and restore user's register map when interrupt occurs static volatile unsigned isr_saved_index = 0; -static inline void musb_dcd_int_handler_enter(uint8_t rhport) -{ +static inline void musb_dcd_int_handler_enter(uint8_t rhport) { uint32_t mxm_int, mxm_int_en, mxm_is; //save current register index diff --git a/tools/get_deps.py b/tools/get_deps.py index 51d6304ae..f141d3d41 100644 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -26,7 +26,7 @@ deps_optional = { 'fc100s'], 'hw/mcu/analog/max32' : ['https://github.com/analogdevicesinc/msdk.git', 'b20b398d3e5e2007594e54a74ba3d2a2e50ddd75', - 'max32690 max32650 max32666 max78002'], + 'max32650 max32666 max32690 max78002'], 'hw/mcu/bridgetek/ft9xx/ft90x-sdk': ['https://github.com/BRTSG-FOSS/ft90x-sdk.git', '91060164afe239fcb394122e8bf9eb24d3194eb1', 'brtmm90x'], -- cgit v1.3.1 From a9df933e0d35c1c198343464d49e69eff20dde4a Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 15 Aug 2024 15:24:04 +0700 Subject: add TUP_USBIP_MUSB macro, minor rename --- src/common/tusb_mcu.h | 6 ++--- src/portable/mentor/musb/dcd_musb.c | 50 +++++++++++++++++------------------ src/portable/mentor/musb/musb_max32.h | 18 ++++++------- src/portable/mentor/musb/musb_ti.h | 18 ++++++------- src/portable/mentor/musb/musb_type.h | 6 ++--- 5 files changed, 49 insertions(+), 49 deletions(-) (limited to 'src/portable') diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 259b9e002..7ec3c5842 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -308,6 +308,7 @@ #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) + #define TUP_USBIP_MUSB #define TUP_DCD_ENDPOINT_MAX 8 //--------------------------------------------------------------------+ @@ -471,12 +472,11 @@ //--------------------------------------------------------------------+ // Analog Devices //--------------------------------------------------------------------+ -#elif TU_CHECK_MCU(OPT_MCU_MAX32690, OPT_MCU_MAX32666, \ - OPT_MCU_MAX32650, OPT_MCU_MAX78002) +#elif TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002) + #define TUP_USBIP_MUSB #define TUP_DCD_ENDPOINT_MAX 12 #define TUP_RHPORT_HIGHSPEED 1 - #endif //--------------------------------------------------------------------+ diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index ee36656fd..80dfb9235 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -27,7 +27,7 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED +#if CFG_TUD_ENABLED && defined(TUP_USBIP_MUSB) #if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) /* GCC warns that an address may be unaligned, even though @@ -155,7 +155,7 @@ static void process_setup_packet(uint8_t rhport) { uint32_t *p = (void*)&_dcd.setup_packet; volatile uint32_t *fifo_ptr = musb_dcd_ep_get_fifo_ptr(rhport, 0); - volatile musb_dcd_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); + volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); p[0] = *fifo_ptr; p[1] = *fifo_ptr; @@ -183,7 +183,7 @@ static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr) return true; } - volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); + volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); const unsigned mps = regs->TXMAXP; const unsigned len = TU_MIN(mps, rem); void *buf = pipe->buf; @@ -208,7 +208,7 @@ static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr) unsigned epnum = tu_edpt_number(ep_addr); unsigned epnum_minus1 = epnum - 1; pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; - volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); + volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); // TU_LOG1(" RXCSRL%d = %x\r\n", epnum_minus1 + 1, regs->RXCSRL); TU_ASSERT(regs->RXCSRL & USB_RXCSRL1_RXRDY); @@ -250,7 +250,7 @@ static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16 if (dir_in) { handle_xfer_in(rhport, ep_addr); } else { - volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); + volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); if (regs->RXCSRL & USB_RXCSRL1_RXRDY) regs->RXCSRL = 0; } return true; @@ -260,7 +260,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ { (void)rhport; TU_ASSERT(total_bytes <= 64); /* Current implementation supports for only up to 64 bytes. */ - volatile musb_dcd_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); + volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); const unsigned req = _dcd.setup_packet.bmRequestType; TU_ASSERT(req != REQUEST_TYPE_INVALID || total_bytes == 0); @@ -325,7 +325,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ static void process_ep0(uint8_t rhport) { - volatile musb_dcd_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); + volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); uint_fast8_t csrl = ep0_regs->CSRL0; // TU_LOG1(" EP0 ep0_regs->CSRL0 = %x\r\n", csrl); @@ -381,7 +381,7 @@ static void process_ep0(uint8_t rhport) return; } - volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); /* When CSRL0 is zero, it means that completion of sending a any length packet * or receiving a zero length packet. */ @@ -415,7 +415,7 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) const unsigned epn = tu_edpt_number(ep_addr); const unsigned epn_minus1 = epn - 1; - volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); + volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); if (dir_in) { // TU_LOG1(" TXCSRL%d = %x\r\n", epn, regs->TXCSRL); if (regs->TXCSRL & USB_TXCSRL1_STALLED) { @@ -442,7 +442,7 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) static void process_bus_reset(uint8_t rhport) { - volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), * a control transfer state is SETUP or STATUS stage. */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; @@ -467,7 +467,7 @@ static void process_bus_reset(uint8_t rhport) void dcd_init(uint8_t rhport) { - volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); ctrl_regs->IE |= USB_IE_SUSPND; musb_dcd_int_clear(rhport); musb_dcd_phy_init(rhport); @@ -488,7 +488,7 @@ void dcd_int_disable(uint8_t rhport) void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void)dev_addr; - volatile musb_dcd_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); + volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; @@ -499,7 +499,7 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) // Wake up host void dcd_remote_wakeup(uint8_t rhport) { - volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); ctrl_regs->POWER |= USB_POWER_RESUME; unsigned cnt = SystemCoreClock / 1000; @@ -511,7 +511,7 @@ void dcd_remote_wakeup(uint8_t rhport) // Connect by enabling internal pull-up resistor on D+/D- void dcd_connect(uint8_t rhport) { - volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); ctrl_regs->POWER |= TUD_OPT_HIGH_SPEED ? USB_POWER_HSENAB : 0; ctrl_regs->POWER |= USB_POWER_SOFTCONN; } @@ -519,7 +519,7 @@ void dcd_connect(uint8_t rhport) // Disconnect by disabling internal pull-up resistor on D+/D- void dcd_disconnect(uint8_t rhport) { - volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); ctrl_regs->POWER &= ~USB_POWER_SOFTCONN; } @@ -551,8 +551,8 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) pipe->length = 0; pipe->remaining = 0; - volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); - volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); + volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); if (dir_in) { regs->TXMAXP = mps; regs->TXCSRH = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_TXCSRH1_ISO : 0; @@ -579,8 +579,8 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) void dcd_edpt_close_all(uint8_t rhport) { - volatile musb_dcd_epn_regs_t *regs; - volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + volatile musb_epn_regs_t *regs; + volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); ctrl_regs->TXIE = 1; /* Enable only EP0 */ @@ -613,8 +613,8 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) unsigned const epn = tu_edpt_number(ep_addr); unsigned const dir_in = tu_edpt_dir(ep_addr); - volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); - volatile musb_dcd_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); + volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); if (dir_in) { @@ -679,14 +679,14 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); if (0 == epn) { - volatile musb_dcd_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); + volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); if (!ep_addr) { /* Ignore EP80 */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; _dcd.pipe0.buf = NULL; ep0_regs->CSRL0 = USB_CSRL0_STALL; } } else { - volatile musb_dcd_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); + volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); if (tu_edpt_dir(ep_addr)) { /* IN */ regs->TXCSRL = USB_TXCSRL1_STALL; } else { /* OUT */ @@ -702,7 +702,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; unsigned const epn = tu_edpt_number(ep_addr); - musb_dcd_epn_regs_t volatile *regs = musb_dcd_epn_regs(rhport, epn); + musb_epn_regs_t volatile *regs = musb_dcd_epn_regs(rhport, epn); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); if (tu_edpt_dir(ep_addr)) { /* IN */ @@ -719,7 +719,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) void dcd_int_handler(uint8_t rhport) { uint_fast8_t is, txis, rxis; - volatile musb_dcd_ctl_regs_t *ctrl_regs; + volatile musb_ctl_regs_t *ctrl_regs; //Part specific ISR setup/entry musb_dcd_int_handler_enter(rhport); diff --git a/src/portable/mentor/musb/musb_max32.h b/src/portable/mentor/musb/musb_max32.h index bc6ce76dd..0712aeda4 100644 --- a/src/portable/mentor/musb/musb_max32.h +++ b/src/portable/mentor/musb/musb_max32.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_MUSB_MAX32_H_ -#define _TUSB_MUSB_MAX32_H_ +#ifndef TUSB_MUSB_MAX32_H_ +#define TUSB_MUSB_MAX32_H_ #ifdef __cplusplus extern "C" { @@ -136,25 +136,25 @@ static inline void musb_dcd_phy_init(uint8_t rhport) musb_periph_inst[rhport]->m31_phy_ponrst = 1; } -static inline volatile musb_dcd_ctl_regs_t* musb_dcd_ctl_regs(uint8_t rhport) +static inline volatile musb_ctl_regs_t* musb_dcd_ctl_regs(uint8_t rhport) { - volatile musb_dcd_ctl_regs_t *regs = (volatile musb_dcd_ctl_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->faddr)); + volatile musb_ctl_regs_t *regs = (volatile musb_ctl_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->faddr)); return regs; } -static inline volatile musb_dcd_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) +static inline volatile musb_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) { //Need to set index to map EP registers musb_periph_inst[rhport]->index = epnum; - volatile musb_dcd_epn_regs_t *regs = (volatile musb_dcd_epn_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->inmaxp)); + volatile musb_epn_regs_t *regs = (volatile musb_epn_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->inmaxp)); return regs; } -static inline volatile musb_dcd_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) +static inline volatile musb_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) { //Need to set index to map EP0 registers musb_periph_inst[rhport]->index = 0; - volatile musb_dcd_ep0_regs_t *regs = (volatile musb_dcd_ep0_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->csr0)); + volatile musb_ep0_regs_t *regs = (volatile musb_ep0_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->csr0)); return regs; } @@ -213,4 +213,4 @@ static inline void musb_dcd_reset_fifo(uint8_t rhport, unsigned epnum, unsigned } #endif -#endif // _TUSB_MUSB_MAX32_H_ +#endif // TUSB_MUSB_MAX32_H_ diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h index 4c9f00278..ec0a267b1 100644 --- a/src/portable/mentor/musb/musb_ti.h +++ b/src/portable/mentor/musb/musb_ti.h @@ -24,8 +24,8 @@ * This file is part of the TinyUSB stack. */ -#ifndef _TUSB_MUSB_TI_H_ -#define _TUSB_MUSB_TI_H_ +#ifndef TUSB_MUSB_TI_H_ +#define TUSB_MUSB_TI_H_ #ifdef __cplusplus extern "C" { @@ -95,25 +95,25 @@ static inline void musb_dcd_int_handler_exit(uint8_t rhport){ //Nothing to do for this part } -static inline volatile musb_dcd_ctl_regs_t* musb_dcd_ctl_regs(uint8_t rhport) +static inline volatile musb_ctl_regs_t* musb_dcd_ctl_regs(uint8_t rhport) { - volatile musb_dcd_ctl_regs_t *regs = (volatile musb_dcd_ctl_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->FADDR)); + volatile musb_ctl_regs_t *regs = (volatile musb_ctl_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->FADDR)); return regs; } -static inline volatile musb_dcd_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) +static inline volatile musb_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) { uintptr_t baseptr = (uintptr_t)&(musb_periph_inst[rhport]->TXMAXP1); //On the TI parts, the epn registers are 16-bytes apart. The core regs defined //by musb_dcd_epn_regs and 6 reserved/other use bytes - volatile musb_dcd_epn_regs_t *regs = (volatile musb_dcd_epn_regs_t*)(baseptr + ((epnum - 1)*16)); + volatile musb_epn_regs_t *regs = (volatile musb_epn_regs_t*)(baseptr + ((epnum - 1) * 16)); return regs; } -static inline volatile musb_dcd_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) +static inline volatile musb_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) { - volatile musb_dcd_ep0_regs_t *regs = (volatile musb_dcd_ep0_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->CSRL0)); + volatile musb_ep0_regs_t *regs = (volatile musb_ep0_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->CSRL0)); return regs; } @@ -282,4 +282,4 @@ static inline void musb_dcd_reset_fifo(uint8_t rhport, unsigned epnum, unsigned } #endif -#endif // _TUSB_MUSB_TI_H_ +#endif // TUSB_MUSB_TI_H_ diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index e8af8f19b..d21dcd6da 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -50,7 +50,7 @@ typedef struct TU_ATTR_PACKED { uint8_t RXCSRL; uint8_t RXCSRH; uint16_t RXCOUNT; -} musb_dcd_epn_regs_t; +} musb_epn_regs_t; // Endpoint 0 register mapping. typedef struct TU_ATTR_PACKED { @@ -58,7 +58,7 @@ typedef struct TU_ATTR_PACKED { uint8_t CSRH0; uint32_t RESERVED; uint8_t COUNT0; -} musb_dcd_ep0_regs_t; +} musb_ep0_regs_t; // Control register mapping typedef struct TU_ATTR_PACKED { @@ -70,7 +70,7 @@ typedef struct TU_ATTR_PACKED { uint16_t RXIE; uint8_t IS; uint8_t IE; -} musb_dcd_ctl_regs_t; +} musb_ctl_regs_t; //***************************************************************************** // -- cgit v1.3.1 From e339702a2a7977e4e62c2f3fea9aca55f71190ee Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 15 Aug 2024 16:41:20 +0700 Subject: adding universal register structs for musb --- src/portable/mentor/musb/dcd_musb.c | 99 +++++++++++---------- src/portable/mentor/musb/musb_max32.h | 47 ++++------ src/portable/mentor/musb/musb_ti.h | 8 +- src/portable/mentor/musb/musb_type.h | 156 +++++++++++++++++++++++++++++++--- 4 files changed, 216 insertions(+), 94 deletions(-) (limited to 'src/portable') diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 80dfb9235..78fc3d616 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -54,6 +54,8 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); #error "Unsupported MCU" #endif +#define MUSB_REGS(rhport) ((musb_regs_t*) MUSB_BASES[rhport]) + /*------------------------------------------------------------------ * MACRO TYPEDEF CONSTANT ENUM DECLARATION *------------------------------------------------------------------*/ @@ -381,7 +383,7 @@ static void process_ep0(uint8_t rhport) return; } - volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + musb_regs_t* musb_regs = MUSB_REGS(rhport); /* When CSRL0 is zero, it means that completion of sending a any length packet * or receiving a zero length packet. */ @@ -389,7 +391,7 @@ static void process_ep0(uint8_t rhport) /* STATUS IN */ if (*(const uint16_t*)(uintptr_t)&_dcd.setup_packet == 0x0500) { /* The address must be changed on completion of the control transfer. */ - ctrl_regs->FADDR = (uint8_t)_dcd.setup_packet.wValue; + musb_regs->faddr = (uint8_t)_dcd.setup_packet.wValue; } _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; dcd_event_xfer_complete(rhport, @@ -442,7 +444,7 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) static void process_bus_reset(uint8_t rhport) { - volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + musb_regs_t* musb_regs = MUSB_REGS(rhport); /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), * a control transfer state is SETUP or STATUS stage. */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; @@ -450,15 +452,15 @@ static void process_bus_reset(uint8_t rhport) /* When pipe0.buf has not NULL, DATA stage works in progress. */ _dcd.pipe0.buf = NULL; - ctrl_regs->TXIE = 1; /* Enable only EP0 */ - ctrl_regs->RXIE = 0; + musb_regs->intr_txen = 1; /* Enable only EP0 */ + musb_regs->intr_rxen = 0; /* Clear FIFO settings */ for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { musb_dcd_reset_fifo(rhport, i, 0); musb_dcd_reset_fifo(rhport, i, 1); } - dcd_event_bus_reset(rhport, (ctrl_regs->POWER & USB_POWER_HSMODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); + dcd_event_bus_reset(rhport, (musb_regs->power & USB_POWER_HSMODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); } /*------------------------------------------------------------------ @@ -467,8 +469,8 @@ static void process_bus_reset(uint8_t rhport) void dcd_init(uint8_t rhport) { - volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); - ctrl_regs->IE |= USB_IE_SUSPND; + musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_regs->intrusben |= USB_IE_SUSPND; musb_dcd_int_clear(rhport); musb_dcd_phy_init(rhport); dcd_connect(rhport); @@ -497,30 +499,29 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) } // Wake up host -void dcd_remote_wakeup(uint8_t rhport) -{ - volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); - ctrl_regs->POWER |= USB_POWER_RESUME; +void dcd_remote_wakeup(uint8_t rhport) { + musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_regs->power |= USB_POWER_RESUME; unsigned cnt = SystemCoreClock / 1000; while (cnt--) __NOP(); - ctrl_regs->POWER &= ~USB_POWER_RESUME; + musb_regs->power &= ~USB_POWER_RESUME; } // Connect by enabling internal pull-up resistor on D+/D- void dcd_connect(uint8_t rhport) { - volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); - ctrl_regs->POWER |= TUD_OPT_HIGH_SPEED ? USB_POWER_HSENAB : 0; - ctrl_regs->POWER |= USB_POWER_SOFTCONN; + musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_regs->power |= TUD_OPT_HIGH_SPEED ? USB_POWER_HSENAB : 0; + musb_regs->power |= USB_POWER_SOFTCONN; } // Disconnect by disabling internal pull-up resistor on D+/D- void dcd_disconnect(uint8_t rhport) { - volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); - ctrl_regs->POWER &= ~USB_POWER_SOFTCONN; + musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_regs->power &= ~USB_POWER_SOFTCONN; } void dcd_sof_enable(uint8_t rhport, bool en) @@ -552,23 +553,25 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) pipe->remaining = 0; volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); - volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + musb_regs_t* musb_regs = MUSB_REGS(rhport); if (dir_in) { regs->TXMAXP = mps; regs->TXCSRH = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_TXCSRH1_ISO : 0; - if (regs->TXCSRL & USB_TXCSRL1_TXRDY) + if (regs->TXCSRL & USB_TXCSRL1_TXRDY) { regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; - else + } else { regs->TXCSRL = USB_TXCSRL1_CLRDT; - ctrl_regs->TXIE |= TU_BIT(epn); + } + musb_regs->intr_txen |= TU_BIT(epn); } else { regs->RXMAXP = mps; regs->RXCSRH = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_RXCSRH1_ISO : 0; - if (regs->RXCSRL & USB_RXCSRL1_RXRDY) + if (regs->RXCSRL & USB_RXCSRL1_RXRDY) { regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; - else + } else { regs->RXCSRL = USB_RXCSRL1_CLRDT; - ctrl_regs->RXIE |= TU_BIT(epn); + } + musb_regs->intr_rxen |= TU_BIT(epn); } /* Setup FIFO */ @@ -580,11 +583,11 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) void dcd_edpt_close_all(uint8_t rhport) { volatile musb_epn_regs_t *regs; - volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + musb_regs_t* musb_regs = MUSB_REGS(rhport); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); - ctrl_regs->TXIE = 1; /* Enable only EP0 */ - ctrl_regs->RXIE = 0; + musb_regs->intr_txen = 1; /* Enable only EP0 */ + musb_regs->intr_rxen = 0; for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { regs = musb_dcd_epn_regs(rhport, i); regs->TXMAXP = 0; @@ -596,10 +599,11 @@ void dcd_edpt_close_all(uint8_t rhport) regs->RXMAXP = 0; regs->RXCSRH = 0; - if (regs->RXCSRL & USB_RXCSRL1_RXRDY) + if (regs->RXCSRL & USB_RXCSRL1_RXRDY) { regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; - else + } else { regs->RXCSRL = USB_RXCSRL1_CLRDT; + } musb_dcd_reset_fifo(rhport, i, 0); musb_dcd_reset_fifo(rhport, i, 1); @@ -614,25 +618,27 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) unsigned const dir_in = tu_edpt_dir(ep_addr); volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); - volatile musb_ctl_regs_t *ctrl_regs = musb_dcd_ctl_regs(rhport); + musb_regs_t* musb_regs = MUSB_REGS(rhport); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); if (dir_in) { - ctrl_regs->TXIE &= ~TU_BIT(epn); + musb_regs->intr_txen &= ~TU_BIT(epn); regs->TXMAXP = 0; regs->TXCSRH = 0; - if (regs->TXCSRL & USB_TXCSRL1_TXRDY) + if (regs->TXCSRL & USB_TXCSRL1_TXRDY) { regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; - else + } else { regs->TXCSRL = USB_TXCSRL1_CLRDT; + } } else { - ctrl_regs->RXIE &= ~TU_BIT(epn); + musb_regs->intr_rxen &= ~TU_BIT(epn); regs->RXMAXP = 0; regs->RXCSRH = 0; - if (regs->RXCSRL & USB_RXCSRL1_RXRDY) + if (regs->RXCSRL & USB_RXCSRL1_RXRDY) { regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; - else + } else { regs->RXCSRL = USB_RXCSRL1_CLRDT; + } } musb_dcd_reset_fifo(rhport, epn, dir_in); if (ie) musb_dcd_int_enable(rhport); @@ -650,8 +656,9 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t if (epnum) { _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] &= ~TU_BIT(epnum - 1); ret = edpt_n_xfer(rhport, ep_addr, buffer, total_bytes); - } else + } else { ret = edpt0_xfer(rhport, ep_addr, buffer, total_bytes); + } if (ie) musb_dcd_int_enable(rhport); return ret; } @@ -719,18 +726,18 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) void dcd_int_handler(uint8_t rhport) { uint_fast8_t is, txis, rxis; - volatile musb_ctl_regs_t *ctrl_regs; //Part specific ISR setup/entry musb_dcd_int_handler_enter(rhport); - ctrl_regs = musb_dcd_ctl_regs(rhport); - is = ctrl_regs->IS; /* read and clear interrupt status */ - txis = ctrl_regs->TXIS; /* read and clear interrupt status */ - rxis = ctrl_regs->RXIS; /* read and clear interrupt status */ + musb_regs_t* musb_regs = MUSB_REGS(rhport); + + is = musb_regs->intrusb; /* read and clear interrupt status */ + txis = musb_regs->intr_tx; /* read and clear interrupt status */ + rxis = musb_regs->intr_rx; /* read and clear interrupt status */ // TU_LOG1("D%2x T%2x R%2x\r\n", is, txis, rxis); - is &= ctrl_regs->IE; /* Clear disabled interrupts */ + is &= musb_regs->intrusben; /* Clear disabled interrupts */ if (is & USB_IS_DISCON) { } if (is & USB_IS_SOF) { @@ -746,7 +753,7 @@ void dcd_int_handler(uint8_t rhport) dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); } - txis &= ctrl_regs->TXIE; /* Clear disabled interrupts */ + txis &= musb_regs->intr_txen; /* Clear disabled interrupts */ if (txis & USB_TXIE_EP0) { process_ep0(rhport); txis &= ~TU_BIT(0); @@ -756,7 +763,7 @@ void dcd_int_handler(uint8_t rhport) process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_IN)); txis &= ~TU_BIT(num); } - rxis &= ctrl_regs->RXIE; /* Clear disabled interrupts */ + rxis &= musb_regs->intr_rxen; /* Clear disabled interrupts */ while (rxis) { unsigned const num = __builtin_ctz(rxis); process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_OUT)); diff --git a/src/portable/mentor/musb/musb_max32.h b/src/portable/mentor/musb/musb_max32.h index 0712aeda4..9c048513c 100644 --- a/src/portable/mentor/musb/musb_max32.h +++ b/src/portable/mentor/musb/musb_max32.h @@ -28,12 +28,14 @@ #define TUSB_MUSB_MAX32_H_ #ifdef __cplusplus - extern "C" { +extern "C" { #endif #include "mxc_device.h" #include "usbhs_regs.h" +const uintptr_t MUSB_BASES[] = { MXC_BASE_USBHS }; + #if CFG_TUD_ENABLED #define USBHS_M31_CLOCK_RECOVERY @@ -92,14 +94,12 @@ static inline void musb_dcd_int_handler_enter(uint8_t rhport) { } } -static inline void musb_dcd_int_handler_exit(uint8_t rhport) -{ +static inline void musb_dcd_int_handler_exit(uint8_t rhport) { //restore register index musb_periph_inst[rhport]->index = isr_saved_index; } -static inline void musb_dcd_phy_init(uint8_t rhport) -{ +static inline void musb_dcd_phy_init(uint8_t rhport) { //Interrupt for VBUS disconnect musb_periph_inst[rhport]->mxm_int_en |= MXC_F_USBHS_MXM_INT_EN_NOVBUS; @@ -136,42 +136,32 @@ static inline void musb_dcd_phy_init(uint8_t rhport) musb_periph_inst[rhport]->m31_phy_ponrst = 1; } -static inline volatile musb_ctl_regs_t* musb_dcd_ctl_regs(uint8_t rhport) -{ - volatile musb_ctl_regs_t *regs = (volatile musb_ctl_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->faddr)); - return regs; -} - -static inline volatile musb_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) -{ +static inline volatile musb_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) { //Need to set index to map EP registers musb_periph_inst[rhport]->index = epnum; - volatile musb_epn_regs_t *regs = (volatile musb_epn_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->inmaxp)); + volatile musb_epn_regs_t* regs = (volatile musb_epn_regs_t*) ((uintptr_t) &(musb_periph_inst[rhport]->inmaxp)); return regs; } -static inline volatile musb_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) -{ +static inline volatile musb_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) { //Need to set index to map EP0 registers musb_periph_inst[rhport]->index = 0; - volatile musb_ep0_regs_t *regs = (volatile musb_ep0_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->csr0)); + volatile musb_ep0_regs_t* regs = (volatile musb_ep0_regs_t*) ((uintptr_t) &(musb_periph_inst[rhport]->csr0)); return regs; } -static volatile void *musb_dcd_ep_get_fifo_ptr(uint8_t rhport, unsigned epnum) -{ - volatile uint32_t *ptr; +static volatile void* musb_dcd_ep_get_fifo_ptr(uint8_t rhport, unsigned epnum) { + volatile uint32_t* ptr; ptr = &(musb_periph_inst[rhport]->fifo0); ptr += epnum; - return (volatile void *) ptr; + return (volatile void*) ptr; } -static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) -{ - (void)mps; +static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) { + (void) mps; //Most likely the caller has already grabbed the right register block. But //as a precaution save and restore the register bank anyways @@ -180,7 +170,7 @@ static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned musb_periph_inst[rhport]->index = epnum; //Disable double buffering - if(dir_in) { + if (dir_in) { musb_periph_inst[rhport]->incsru |= (MXC_F_USBHS_INCSRU_DPKTBUFDIS | MXC_F_USBHS_INCSRU_MODE); } else { musb_periph_inst[rhport]->outcsru |= (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS); @@ -189,8 +179,7 @@ static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned musb_periph_inst[rhport]->index = saved_index; } -static inline void musb_dcd_reset_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in) -{ +static inline void musb_dcd_reset_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in) { //Most likely the caller has already grabbed the right register block. But //as a precaution save and restore the register bank anyways unsigned saved_index = musb_periph_inst[rhport]->index; @@ -198,7 +187,7 @@ static inline void musb_dcd_reset_fifo(uint8_t rhport, unsigned epnum, unsigned musb_periph_inst[rhport]->index = epnum; //Disable double buffering - if(dir_in) { + if (dir_in) { musb_periph_inst[rhport]->incsru |= (MXC_F_USBHS_INCSRU_DPKTBUFDIS); } else { musb_periph_inst[rhport]->outcsru |= (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS); @@ -210,7 +199,7 @@ static inline void musb_dcd_reset_fifo(uint8_t rhport, unsigned epnum, unsigned #endif // CFG_TUD_ENABLED #ifdef __cplusplus - } +} #endif #endif // TUSB_MUSB_MAX32_H_ diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h index ec0a267b1..df77303a0 100644 --- a/src/portable/mentor/musb/musb_ti.h +++ b/src/portable/mentor/musb/musb_ti.h @@ -42,6 +42,8 @@ #error "Unsupported MCUs" #endif +const uintptr_t MUSB_BASES[] = { USB0_BASE }; + // Header supports both device and host modes. Only include what's necessary #if CFG_TUD_ENABLED @@ -95,12 +97,6 @@ static inline void musb_dcd_int_handler_exit(uint8_t rhport){ //Nothing to do for this part } -static inline volatile musb_ctl_regs_t* musb_dcd_ctl_regs(uint8_t rhport) -{ - volatile musb_ctl_regs_t *regs = (volatile musb_ctl_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->FADDR)); - return regs; -} - static inline volatile musb_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) { uintptr_t baseptr = (uintptr_t)&(musb_periph_inst[rhport]->TXMAXP1); diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index d21dcd6da..9986a30e0 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -32,8 +32,8 @@ * *******************************************************************************/ -#ifndef _TUSB_MUSB_TYPE_H_ -#define _TUSB_MUSB_TYPE_H_ +#ifndef TUSB_MUSB_TYPE_H_ +#define TUSB_MUSB_TYPE_H_ #include "stdint.h" @@ -41,6 +41,22 @@ extern "C" { #endif +#ifndef __IO + #define __IO volatile +#endif + +#ifndef __I + #define __I volatile const +#endif + +#ifndef __O + #define __O volatile +#endif + +#ifndef __R + #define __R volatile const +#endif + // Endpoint register mapping. Non-zero end points. typedef struct TU_ATTR_PACKED { uint16_t TXMAXP; @@ -60,17 +76,131 @@ typedef struct TU_ATTR_PACKED { uint8_t COUNT0; } musb_ep0_regs_t; -// Control register mapping -typedef struct TU_ATTR_PACKED { - uint8_t FADDR; - uint8_t POWER; - uint16_t TXIS; - uint16_t RXIS; - uint16_t TXIE; - uint16_t RXIE; - uint8_t IS; - uint8_t IE; -} musb_ctl_regs_t; +typedef struct { + //------------- Common -------------// + __IO uint8_t faddr; // 0x00: FADDR + __IO uint8_t power; // 0x01: POWER + + __IO uint16_t intr_tx; // 0x02: INTR_TX + __IO uint16_t intr_rx; // 0x04: INTR_RX + + __IO uint16_t intr_txen; // 0x06: INTR_TXEN + __IO uint16_t intr_rxen; // 0x08: INTR_RXEN + + __IO uint8_t intrusb; // 0x0A: INTRUSB + __IO uint8_t intrusben; // 0x0B: INTRUSBEN + + __IO uint16_t frame; // 0x0C: FRAME + __IO uint8_t index; // 0x0E: INDEX + __IO uint8_t testmode; // 0x0F: TESTMODE + __IO uint16_t inmaxp; // 0x10: INMAXP + union { + __IO uint8_t csr0; // 0x12: CSR0 + __IO uint8_t incsrl; // 0x12: INCSRL + }; + __IO uint8_t incsru; // 0x13: INCSRU + __IO uint16_t outmaxp; // 0x14: OUTMAXP + __IO uint8_t outcsrl; // 0x16: OUTCSRL + __IO uint8_t outcsru; // 0x17: OUTCSRU + union { + __IO uint16_t count0; // 0x18: COUNT0 + __IO uint16_t outcount; // 0x18: OUTCOUNT + }; + __R uint16_t rsv_0x1a_0x1f[3]; + __IO uint32_t fifo0; // 0x20: FIFO0 + __IO uint32_t fifo1; // 0x24: FIFO1 + __IO uint32_t fifo2; // 0x28: FIFO2 + __IO uint32_t fifo3; // 0x2c: FIFO3 + __IO uint32_t fifo4; // 0x30: FIFO4 + __IO uint32_t fifo5; // 0x34: FIFO5 + __IO uint32_t fifo6; // 0x38: FIFO6 + __IO uint32_t fifo7; // 0x3c: FIFO7 + __IO uint32_t fifo8; // 0x40: FIFO8 + __IO uint32_t fifo9; // 0x44: FIFO9 + __IO uint32_t fifo10; // 0x48: FIFO10 + __IO uint32_t fifo11; // 0x4c: FIFO11 + __IO uint32_t fifo12; // 0x50: FIFO12 + __IO uint32_t fifo13; // 0x54: FIFO13 + __IO uint32_t fifo14; // 0x58: FIFO14 + __IO uint32_t fifo15; // 0x5c: FIFO15 + __IO uint8_t devctl; // 0x60: DEVCTL + __IO uint8_t misc; // 0x61: MISC + + //------------- Dynammic FIFO -------------// + __IO uint8_t txfifo_sz; // 0x62: TXFIFO_SZ + __IO uint8_t rxfifo_sz; // 0x63: RXFIFO_SZ + __IO uint16_t txfifo_addr; // 0x64: TXFIFO_ADDR + __IO uint16_t rxfifo_addr; // 0x66: RXFIFO_ADDR + + //------------- Additional Control/Status -------------// + union { + __O uint32_t vcontrol; // 0x68: VCONTROL + __IO uint32_t vstatus; // 0x68: VSTATUS + }; + __IO uint16_t hwvers; // 0x6c: HWVERS + __R uint16_t rsv_0x6e_0x77[5]; + + //------------- Additional Configuration -------------// + __IO uint8_t epinfo; // 0x78: EPINFO + __IO uint8_t raminfo; // 0x79: RAMINFO + __IO uint8_t softreset; // 0x7A: SOFTRESET (Analog), Link info + __IO uint8_t vplen; // 0x7B: VPLEN + __IO uint8_t hs_eof1; // 0x7C: HS_EOF1 + __IO uint8_t fs_eof1; // 0x7D: FS_EOF1 + __IO uint8_t ls_eof1; // 0x7E: LS_EOF1 + __IO uint8_t soft_rst; // 0x7F: SOFT_RST + + //------------- Extended -------------// + __IO uint16_t ctuch; // 0x80: CTUCH + __IO uint16_t cthsrtn; // 0x82: CTHSRTN + __R uint32_t rsv_0x84_0x3ff[223]; + + //------------- Analog PHY -------------// + __IO uint32_t mxm_usb_reg_00; // 0x400: MXM_USB_REG_00 + __IO uint32_t m31_phy_utmi_reset; // 0x404: M31_PHY_UTMI_RESET + __IO uint32_t m31_phy_utmi_vcontrol; // 0x408: M31_PHY_UTMI_VCONTROL + __IO uint32_t m31_phy_clk_en; // 0x40C: M31_PHY_CLK_EN + __IO uint32_t m31_phy_ponrst; // 0x410: M31_PHY_PONRST + __IO uint32_t m31_phy_noncry_rstb; // 0x414: M31_PHY_NONCRY_RSTB + __IO uint32_t m31_phy_noncry_en; // 0x418: M31_PHY_NONCRY_EN + __R uint32_t rsv_0x41c; + __IO uint32_t m31_phy_u2_compliance_en; // 0x420: M31_PHY_U2_COMPLIANCE_EN + __IO uint32_t m31_phy_u2_compliance_dac_adj; // 0x424: M31_PHY_U2_COMPLIANCE_DAC_ADJ + __IO uint32_t m31_phy_u2_compliance_dac_adj_en; // 0x428: M31_PHY_U2_COMPLIANCE_DAC_ADJ_EN + __IO uint32_t m31_phy_clk_rdy; // 0x42C: M31_PHY_CLK_RDY + __IO uint32_t m31_phy_pll_en; // 0x430: M31_PHY_PLL_EN + __IO uint32_t m31_phy_bist_ok; // 0x434: M31_PHY_BIST_OK + __IO uint32_t m31_phy_data_oe; // 0x438: M31_PHY_DATA_OE + __IO uint32_t m31_phy_oscouten; // 0x43C: M31_PHY_OSCOUTEN + __IO uint32_t m31_phy_lpm_alive; // 0x440: M31_PHY_LPM_ALIVE + __IO uint32_t m31_phy_hs_bist_mode; // 0x444: M31_PHY_HS_BIST_MODE + __IO uint32_t m31_phy_coreclkin; // 0x448: M31_PHY_CORECLKIN + __IO uint32_t m31_phy_xtlsel; // 0x44C: M31_PHY_XTLSEL + __IO uint32_t m31_phy_ls_en; // 0x450: M31_PHY_LS_EN + __IO uint32_t m31_phy_debug_sel; // 0x454: M31_PHY_DEBUG_SEL + __IO uint32_t m31_phy_debug_out; // 0x458: M31_PHY_DEBUG_OUT + __IO uint32_t m31_phy_outclksel; // 0x45C: M31_PHY_OUTCLKSEL + __IO uint32_t m31_phy_xcfgi_31_0; // 0x460: M31_PHY_XCFGI_31_0 + __IO uint32_t m31_phy_xcfgi_63_32; // 0x464: M31_PHY_XCFGI_63_32 + __IO uint32_t m31_phy_xcfgi_95_64; // 0x468: M31_PHY_XCFGI_95_64 + __IO uint32_t m31_phy_xcfgi_127_96; // 0x46C: M31_PHY_XCFGI_127_96 + __IO uint32_t m31_phy_xcfgi_137_128; // 0x470: M31_PHY_XCFGI_137_128 + __IO uint32_t m31_phy_xcfg_hs_coarse_tune_num; // 0x474: M31_PHY_XCFG_HS_COARSE_TUNE_NUM + __IO uint32_t m31_phy_xcfg_hs_fine_tune_num; // 0x478: M31_PHY_XCFG_HS_FINE_TUNE_NUM + __IO uint32_t m31_phy_xcfg_fs_coarse_tune_num; // 0x47C: M31_PHY_XCFG_FS_COARSE_TUNE_NUM + __IO uint32_t m31_phy_xcfg_fs_fine_tune_num; // 0x480: M31_PHY_XCFG_FS_FINE_TUNE_NUM + __IO uint32_t m31_phy_xcfg_lock_range_max; // 0x484: M31_PHY_XCFG_LOCK_RANGE_MAX + __IO uint32_t m31_phy_xcfgi_lock_range_min; // 0x488: M31_PHY_XCFGI_LOCK_RANGE_MIN + __IO uint32_t m31_phy_xcfg_ob_rsel; // 0x48C: M31_PHY_XCFG_OB_RSEL + __IO uint32_t m31_phy_xcfg_oc_rsel; // 0x490: M31_PHY_XCFG_OC_RSEL + __IO uint32_t m31_phy_xcfgo; // 0x494: M31_PHY_XCFGO + __IO uint32_t mxm_int; // 0x498: MXM_INT + __IO uint32_t mxm_int_en; // 0x49C: MXM_INT_EN + __IO uint32_t mxm_suspend; // 0x4A0: MXM_SUSPEND + __IO uint32_t mxm_reg_a4; // 0x4A4: MXM_REG_A4 +} musb_regs_t; + +TU_VERIFY_STATIC(sizeof(musb_regs_t) == 0x4A8, "size is not correct"); //***************************************************************************** // -- cgit v1.3.1 From 7d8d364332189f840cbd0265f2834c1b343c5e52 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 15 Aug 2024 16:52:50 +0700 Subject: update musb fifo usage --- src/portable/mentor/musb/dcd_musb.c | 20 +++++++++++--------- src/portable/mentor/musb/musb_max32.h | 10 ---------- src/portable/mentor/musb/musb_ti.h | 10 ---------- src/portable/mentor/musb/musb_type.h | 17 +---------------- 4 files changed, 12 insertions(+), 45 deletions(-) (limited to 'src/portable') diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 78fc3d616..114720a6a 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -153,10 +153,10 @@ static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigne ops[dir].tu_fifo_advance(f, total_len - rem); } -static void process_setup_packet(uint8_t rhport) -{ +static void process_setup_packet(uint8_t rhport) { + musb_regs_t* musb_regs = MUSB_REGS(rhport); uint32_t *p = (void*)&_dcd.setup_packet; - volatile uint32_t *fifo_ptr = musb_dcd_ep_get_fifo_ptr(rhport, 0); + volatile uint32_t *fifo_ptr = &musb_regs->fifo[0]; volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); p[0] = *fifo_ptr; p[1] = *fifo_ptr; @@ -185,11 +185,12 @@ static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr) return true; } + musb_regs_t* musb_regs = MUSB_REGS(rhport); volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); const unsigned mps = regs->TXMAXP; const unsigned len = TU_MIN(mps, rem); void *buf = pipe->buf; - volatile void *fifo_ptr = musb_dcd_ep_get_fifo_ptr(rhport, epnum); + volatile void *fifo_ptr = &musb_regs->fifo[epnum]; // 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)) { @@ -210,6 +211,7 @@ static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr) unsigned epnum = tu_edpt_number(ep_addr); unsigned epnum_minus1 = epnum - 1; pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; + musb_regs_t* musb_regs = MUSB_REGS(rhport); volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); // TU_LOG1(" RXCSRL%d = %x\r\n", epnum_minus1 + 1, regs->RXCSRL); @@ -220,7 +222,7 @@ static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr) const unsigned vld = regs->RXCOUNT; const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); void *buf = pipe->buf; - volatile void *fifo_ptr = musb_dcd_ep_get_fifo_ptr(rhport, epnum); + volatile void *fifo_ptr = &musb_regs->fifo[epnum]; if (len) { if (_dcd.pipe_buf_is_fifo[TUSB_DIR_OUT] & TU_BIT(epnum_minus1)) { pipe_read_write_packet_ff(buf, fifo_ptr, len, TUSB_DIR_OUT); @@ -262,6 +264,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ { (void)rhport; TU_ASSERT(total_bytes <= 64); /* Current implementation supports for only up to 64 bytes. */ + musb_regs_t* musb_regs = MUSB_REGS(rhport); volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); const unsigned req = _dcd.setup_packet.bmRequestType; TU_ASSERT(req != REQUEST_TYPE_INVALID || total_bytes == 0); @@ -289,7 +292,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ TU_ASSERT(total_bytes <= _dcd.remaining_ctrl); const unsigned rem = _dcd.remaining_ctrl; const unsigned len = TU_MIN(TU_MIN(rem, 64), total_bytes); - volatile void *fifo_ptr = musb_dcd_ep_get_fifo_ptr(rhport, 0); + volatile void *fifo_ptr = &musb_regs->fifo[0]; if (dir_in) { pipe_write_packet(buffer, fifo_ptr, len); @@ -327,6 +330,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ static void process_ep0(uint8_t rhport) { + musb_regs_t* musb_regs = MUSB_REGS(rhport); volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); uint_fast8_t csrl = ep0_regs->CSRL0; @@ -368,7 +372,7 @@ static void process_ep0(uint8_t rhport) const unsigned vld = ep0_regs->COUNT0; const unsigned rem = _dcd.pipe0.remaining; const unsigned len = TU_MIN(TU_MIN(rem, 64), vld); - volatile void *fifo_ptr = musb_dcd_ep_get_fifo_ptr(rhport, 0); + volatile void *fifo_ptr = &musb_regs->fifo[0]; pipe_read_packet(_dcd.pipe0.buf, fifo_ptr, len); _dcd.pipe0.remaining = rem - len; @@ -383,8 +387,6 @@ static void process_ep0(uint8_t rhport) return; } - musb_regs_t* musb_regs = MUSB_REGS(rhport); - /* When CSRL0 is zero, it means that completion of sending a any length packet * or receiving a zero length packet. */ if (req != REQUEST_TYPE_INVALID && !tu_edpt_dir(req)) { diff --git a/src/portable/mentor/musb/musb_max32.h b/src/portable/mentor/musb/musb_max32.h index 9c048513c..0a97f529a 100644 --- a/src/portable/mentor/musb/musb_max32.h +++ b/src/portable/mentor/musb/musb_max32.h @@ -150,16 +150,6 @@ static inline volatile musb_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) { return regs; } -static volatile void* musb_dcd_ep_get_fifo_ptr(uint8_t rhport, unsigned epnum) { - volatile uint32_t* ptr; - - ptr = &(musb_periph_inst[rhport]->fifo0); - ptr += epnum; - - return (volatile void*) ptr; -} - - static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) { (void) mps; diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h index df77303a0..499e01e63 100644 --- a/src/portable/mentor/musb/musb_ti.h +++ b/src/portable/mentor/musb/musb_ti.h @@ -113,16 +113,6 @@ static inline volatile musb_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) return regs; } -static volatile void *musb_dcd_ep_get_fifo_ptr(uint8_t rhport, unsigned epnum) -{ - if(epnum){ - return (volatile void *)(&(musb_periph_inst[rhport]->FIFO1_WORD) + (epnum - 1)); - } else { - return (volatile void *)&(musb_periph_inst[rhport]->FIFO0_WORD); - } -} - - typedef struct { uint_fast16_t beg; /* offset of including first element */ uint_fast16_t end; /* offset of excluding the last element */ diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index 9986a30e0..c31e0c984 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -107,22 +107,7 @@ typedef struct { __IO uint16_t outcount; // 0x18: OUTCOUNT }; __R uint16_t rsv_0x1a_0x1f[3]; - __IO uint32_t fifo0; // 0x20: FIFO0 - __IO uint32_t fifo1; // 0x24: FIFO1 - __IO uint32_t fifo2; // 0x28: FIFO2 - __IO uint32_t fifo3; // 0x2c: FIFO3 - __IO uint32_t fifo4; // 0x30: FIFO4 - __IO uint32_t fifo5; // 0x34: FIFO5 - __IO uint32_t fifo6; // 0x38: FIFO6 - __IO uint32_t fifo7; // 0x3c: FIFO7 - __IO uint32_t fifo8; // 0x40: FIFO8 - __IO uint32_t fifo9; // 0x44: FIFO9 - __IO uint32_t fifo10; // 0x48: FIFO10 - __IO uint32_t fifo11; // 0x4c: FIFO11 - __IO uint32_t fifo12; // 0x50: FIFO12 - __IO uint32_t fifo13; // 0x54: FIFO13 - __IO uint32_t fifo14; // 0x58: FIFO14 - __IO uint32_t fifo15; // 0x5c: FIFO15 + __IO uint32_t fifo[16]; // 0x20-0x5C: FIFO 0-15 __IO uint8_t devctl; // 0x60: DEVCTL __IO uint8_t misc; // 0x61: MISC -- cgit v1.3.1 From 6152adb17fd0e8d76c60f589d84eee0fec323fa5 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 15 Aug 2024 19:05:28 +0700 Subject: use musb_ep_csr_t for indexed CSR, also use indexed csr for TI access as well. Merge ep0 and epn together --- src/portable/mentor/musb/dcd_musb.c | 181 +++++++++++++++++----------------- src/portable/mentor/musb/musb_max32.h | 14 --- src/portable/mentor/musb/musb_ti.h | 16 --- src/portable/mentor/musb/musb_type.h | 104 +++++++++++++------ 4 files changed, 163 insertions(+), 152 deletions(-) (limited to 'src/portable') diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 114720a6a..48f6e9d97 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -41,10 +41,6 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); // Following symbols must be defined by port header // - musb_dcd_int_enable/disable/clear/get_enable // - musb_dcd_int_handler_enter/exit -// - musb_dcd_epn_regs: Get memory mapped struct of end point registers -// - musb_dcd_ep0_regs: Get memory mapped struct of EP0 registers -// - musb_dcd_ctl_regs: Get memory mapped struct of control registers -// - musb_dcd_ep_get_fifo_ptr: Gets the address of the provided EP's FIFO // - musb_dcd_setup_fifo/reset_fifo: Configuration of the EP's FIFO #if TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) #include "musb_ti.h" @@ -157,7 +153,7 @@ static void process_setup_packet(uint8_t rhport) { musb_regs_t* musb_regs = MUSB_REGS(rhport); uint32_t *p = (void*)&_dcd.setup_packet; volatile uint32_t *fifo_ptr = &musb_regs->fifo[0]; - volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); + p[0] = *fifo_ptr; p[1] = *fifo_ptr; @@ -170,7 +166,10 @@ static void process_setup_packet(uint8_t rhport) { _dcd.remaining_ctrl = len; const unsigned dir_in = tu_edpt_dir(_dcd.setup_packet.bmRequestType); /* Clear RX FIFO and reverse the transaction direction */ - if (len && dir_in) ep0_regs->CSRL0 = USB_CSRL0_RXRDYC; + if (len && dir_in) { + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, 0); + ep_csr->csr0l = USB_CSRL0_RXRDYC; + } } static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr) @@ -186,8 +185,8 @@ static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr) } musb_regs_t* musb_regs = MUSB_REGS(rhport); - volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); - const unsigned mps = regs->TXMAXP; + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epnum); + const unsigned mps = ep_csr->tx_maxp; const unsigned len = TU_MIN(mps, rem); void *buf = pipe->buf; volatile void *fifo_ptr = &musb_regs->fifo[epnum]; @@ -201,8 +200,8 @@ static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr) } pipe->remaining = rem - len; } - regs->TXCSRL = USB_TXCSRL1_TXRDY; - // TU_LOG1(" TXCSRL%d = %x %d\r\n", epnum, regs->TXCSRL, rem - len); + ep_csr->tx_csrl = USB_TXCSRL1_TXRDY; + // TU_LOG1(" TXCSRL%d = %x %d\r\n", epnum, ep_csr->tx_csrl, rem - len); return false; } @@ -212,14 +211,14 @@ static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr) unsigned epnum_minus1 = epnum - 1; pipe_state_t *pipe = &_dcd.pipe[tu_edpt_dir(ep_addr)][epnum_minus1]; musb_regs_t* musb_regs = MUSB_REGS(rhport); - volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); - // TU_LOG1(" RXCSRL%d = %x\r\n", epnum_minus1 + 1, regs->RXCSRL); + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epnum); + // TU_LOG1(" RXCSRL%d = %x\r\n", epnum_minus1 + 1, ep_csr->rx_csrl); - TU_ASSERT(regs->RXCSRL & USB_RXCSRL1_RXRDY); + TU_ASSERT(ep_csr->rx_csrl & USB_RXCSRL1_RXRDY); - const unsigned mps = regs->RXMAXP; + const unsigned mps = ep_csr->rx_maxp; const unsigned rem = pipe->remaining; - const unsigned vld = regs->RXCOUNT; + const unsigned vld = ep_csr->rx_count; const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); void *buf = pipe->buf; volatile void *fifo_ptr = &musb_regs->fifo[epnum]; @@ -236,7 +235,7 @@ static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr) pipe->buf = NULL; return NULL != buf; } - regs->RXCSRL = 0; /* Clear RXRDY bit */ + ep_csr->rx_csrl = 0; /* Clear RXRDY bit */ return false; } @@ -254,8 +253,9 @@ static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16 if (dir_in) { handle_xfer_in(rhport, ep_addr); } else { - volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epnum); - if (regs->RXCSRL & USB_RXCSRL1_RXRDY) regs->RXCSRL = 0; + musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epnum); + if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) ep_csr->rx_csrl = 0; } return true; } @@ -265,7 +265,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ (void)rhport; TU_ASSERT(total_bytes <= 64); /* Current implementation supports for only up to 64 bytes. */ musb_regs_t* musb_regs = MUSB_REGS(rhport); - volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, 0); const unsigned req = _dcd.setup_packet.bmRequestType; TU_ASSERT(req != REQUEST_TYPE_INVALID || total_bytes == 0); @@ -276,7 +276,7 @@ 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 ep0_regs->CSRL0 = %x\r\n", ep0_regs->CSRL0); + // TU_LOG1(" STATUS OUT ep_csr->csr0l = %x\r\n", ep_csr->csr0l); _dcd.status_out = 0; if (req == REQUEST_TYPE_INVALID) { dcd_event_xfer_complete(rhport, ep_addr, total_bytes, XFER_RESULT_SUCCESS, false); @@ -305,25 +305,25 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; /* Change to STATUS/SETUP stage */ _dcd.status_out = 1; /* Flush TX FIFO and reverse the transaction direction. */ - ep0_regs->CSRL0 = USB_CSRL0_TXRDY | USB_CSRL0_DATAEND; + ep_csr->csr0l = USB_CSRL0_TXRDY | USB_CSRL0_DATAEND; } else { - ep0_regs->CSRL0 = USB_CSRL0_TXRDY; /* Flush TX FIFO to return ACK. */ + ep_csr->csr0l = USB_CSRL0_TXRDY; /* Flush TX FIFO to return ACK. */ } - // TU_LOG1(" IN ep0_regs->CSRL0 = %x\r\n", ep0_regs->CSRL0); + // TU_LOG1(" IN ep_csr->csr0l = %x\r\n", ep_csr->csr0l); } else { - // TU_LOG1(" OUT ep0_regs->CSRL0 = %x\r\n", ep0_regs->CSRL0); + // TU_LOG1(" OUT ep_csr->csr0l = %x\r\n", ep_csr->csr0l); _dcd.pipe0.buf = buffer; _dcd.pipe0.length = len; _dcd.pipe0.remaining = len; - ep0_regs->CSRL0 = USB_CSRL0_RXRDYC; /* Clear RX FIFO to return ACK. */ + ep_csr->csr0l = USB_CSRL0_RXRDYC; /* Clear RX FIFO to return ACK. */ } } else if (dir_in) { - // TU_LOG1(" STATUS IN ep0_regs->CSRL0 = %x\r\n", ep0_regs->CSRL0); + // TU_LOG1(" STATUS IN ep_csr->csr0l = %x\r\n", ep_csr->csr0l); _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; /* Clear RX FIFO and reverse the transaction direction */ - ep0_regs->CSRL0 = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; + ep_csr->csr0l = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; } return true; } @@ -331,21 +331,21 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ static void process_ep0(uint8_t rhport) { musb_regs_t* musb_regs = MUSB_REGS(rhport); - volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); - uint_fast8_t csrl = ep0_regs->CSRL0; + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, 0); + uint_fast8_t csrl = ep_csr->csr0l; - // TU_LOG1(" EP0 ep0_regs->CSRL0 = %x\r\n", csrl); + // TU_LOG1(" EP0 ep_csr->csr0l = %x\r\n", csrl); if (csrl & USB_CSRL0_STALLED) { /* Returned STALL packet to HOST. */ - ep0_regs->CSRL0 = 0; /* Clear STALL */ + ep_csr->csr0l = 0; /* Clear STALL */ return; } unsigned req = _dcd.setup_packet.bmRequestType; if (csrl & USB_CSRL0_SETEND) { TU_LOG1(" ABORT by the next packets\r\n"); - ep0_regs->CSRL0 = USB_CSRL0_SETENDC; + ep_csr->csr0l = USB_CSRL0_SETENDC; if (req != REQUEST_TYPE_INVALID && _dcd.pipe0.buf) { /* DATA stage was aborted by receiving STATUS or SETUP packet. */ _dcd.pipe0.buf = NULL; @@ -363,13 +363,13 @@ static void process_ep0(uint8_t rhport) /* Received SETUP or DATA OUT packet */ if (req == REQUEST_TYPE_INVALID) { /* SETUP */ - TU_ASSERT(sizeof(tusb_control_request_t) == ep0_regs->COUNT0,); + TU_ASSERT(sizeof(tusb_control_request_t) == ep_csr->rx_count,); process_setup_packet(rhport); return; } if (_dcd.pipe0.buf) { /* DATA OUT */ - const unsigned vld = ep0_regs->COUNT0; + const unsigned vld = ep_csr->rx_count; const unsigned rem = _dcd.pipe0.remaining; const unsigned len = TU_MIN(TU_MIN(rem, 64), vld); volatile void *fifo_ptr = &musb_regs->fifo[0]; @@ -415,22 +415,23 @@ static void process_ep0(uint8_t rhport) static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) { bool completed; - const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned dir_in = tu_edpt_dir(ep_addr); const unsigned epn = tu_edpt_number(ep_addr); const unsigned epn_minus1 = epn - 1; - volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); + musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); if (dir_in) { - // TU_LOG1(" TXCSRL%d = %x\r\n", epn, regs->TXCSRL); - if (regs->TXCSRL & USB_TXCSRL1_STALLED) { - regs->TXCSRL &= ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_UNDRN); + // TU_LOG1(" TX CSRL%d = %x\r\n", epn, ep_csr->tx_csrl); + if (ep_csr->tx_csrl & USB_TXCSRL1_STALLED) { + ep_csr->tx_csrl &= ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_UNDRN); return; } completed = handle_xfer_in(rhport, ep_addr); } else { - // TU_LOG1(" RXCSRL%d = %x\r\n", epn, regs->RXCSRL); - if (regs->RXCSRL & USB_RXCSRL1_STALLED) { - regs->RXCSRL &= ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_OVER); + // TU_LOG1(" RX CSRL%d = %x\r\n", epn, ep_csr->rx_csrl); + if (ep_csr->rx_csrl & USB_RXCSRL1_STALLED) { + ep_csr->rx_csrl &= ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_OVER); return; } completed = handle_xfer_out(rhport, ep_addr); @@ -492,12 +493,14 @@ void dcd_int_disable(uint8_t rhport) void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { (void)dev_addr; - volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); + musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, 0); + _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; /* Clear RX FIFO to return ACK. */ - ep0_regs->CSRL0 = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; + ep_csr->csr0l = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; } // Wake up host @@ -554,24 +557,24 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) pipe->length = 0; pipe->remaining = 0; - volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); if (dir_in) { - regs->TXMAXP = mps; - regs->TXCSRH = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_TXCSRH1_ISO : 0; - if (regs->TXCSRL & USB_TXCSRL1_TXRDY) { - regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; + ep_csr->tx_maxp = mps; + ep_csr->tx_csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_TXCSRH1_ISO : 0; + if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY) { + ep_csr->tx_csrl = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; } else { - regs->TXCSRL = USB_TXCSRL1_CLRDT; + ep_csr->tx_csrl = USB_TXCSRL1_CLRDT; } musb_regs->intr_txen |= TU_BIT(epn); } else { - regs->RXMAXP = mps; - regs->RXCSRH = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_RXCSRH1_ISO : 0; - if (regs->RXCSRL & USB_RXCSRL1_RXRDY) { - regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; + ep_csr->rx_maxp = mps; + ep_csr->rx_csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_RXCSRH1_ISO : 0; + if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) { + ep_csr->rx_csrl = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; } else { - regs->RXCSRL = USB_RXCSRL1_CLRDT; + ep_csr->rx_csrl = USB_RXCSRL1_CLRDT; } musb_regs->intr_rxen |= TU_BIT(epn); } @@ -584,27 +587,26 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) void dcd_edpt_close_all(uint8_t rhport) { - volatile musb_epn_regs_t *regs; musb_regs_t* musb_regs = MUSB_REGS(rhport); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); musb_regs->intr_txen = 1; /* Enable only EP0 */ musb_regs->intr_rxen = 0; for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { - regs = musb_dcd_epn_regs(rhport, i); - regs->TXMAXP = 0; - regs->TXCSRH = 0; - if (regs->TXCSRL & USB_TXCSRL1_TXRDY) - regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, i); + ep_csr->tx_maxp = 0; + ep_csr->tx_csrh = 0; + if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY) + ep_csr->tx_csrl = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; else - regs->TXCSRL = USB_TXCSRL1_CLRDT; + ep_csr->tx_csrl = USB_TXCSRL1_CLRDT; - regs->RXMAXP = 0; - regs->RXCSRH = 0; - if (regs->RXCSRL & USB_RXCSRL1_RXRDY) { - regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; + ep_csr->rx_maxp = 0; + ep_csr->rx_csrh = 0; + if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) { + ep_csr->rx_csrl = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; } else { - regs->RXCSRL = USB_RXCSRL1_CLRDT; + ep_csr->rx_csrl = USB_RXCSRL1_CLRDT; } musb_dcd_reset_fifo(rhport, i, 0); @@ -618,28 +620,27 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { unsigned const epn = tu_edpt_number(ep_addr); unsigned const dir_in = tu_edpt_dir(ep_addr); - - volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); if (dir_in) { musb_regs->intr_txen &= ~TU_BIT(epn); - regs->TXMAXP = 0; - regs->TXCSRH = 0; - if (regs->TXCSRL & USB_TXCSRL1_TXRDY) { - regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; + ep_csr->tx_maxp = 0; + ep_csr->tx_csrh = 0; + if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY) { + ep_csr->tx_csrl = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; } else { - regs->TXCSRL = USB_TXCSRL1_CLRDT; + ep_csr->tx_csrl = USB_TXCSRL1_CLRDT; } } else { musb_regs->intr_rxen &= ~TU_BIT(epn); - regs->RXMAXP = 0; - regs->RXCSRH = 0; - if (regs->RXCSRL & USB_RXCSRL1_RXRDY) { - regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; + ep_csr->rx_maxp = 0; + ep_csr->rx_csrh = 0; + if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) { + ep_csr->rx_csrl = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; } else { - regs->RXCSRL = USB_RXCSRL1_CLRDT; + ep_csr->rx_csrl = USB_RXCSRL1_CLRDT; } } musb_dcd_reset_fifo(rhport, epn, dir_in); @@ -682,25 +683,24 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_ } // Stall endpoint -void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) -{ +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { unsigned const epn = tu_edpt_number(ep_addr); unsigned const ie = musb_dcd_get_int_enable(rhport); + musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); musb_dcd_int_disable(rhport); if (0 == epn) { - volatile musb_ep0_regs_t* ep0_regs = musb_dcd_ep0_regs(rhport); if (!ep_addr) { /* Ignore EP80 */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; _dcd.pipe0.buf = NULL; - ep0_regs->CSRL0 = USB_CSRL0_STALL; + ep_csr->csr0l = USB_CSRL0_STALL; } } else { - volatile musb_epn_regs_t *regs = musb_dcd_epn_regs(rhport, epn); if (tu_edpt_dir(ep_addr)) { /* IN */ - regs->TXCSRL = USB_TXCSRL1_STALL; + ep_csr->tx_csrl = USB_TXCSRL1_STALL; } else { /* OUT */ - TU_ASSERT(!(regs->RXCSRL & USB_RXCSRL1_RXRDY),); - regs->RXCSRL = USB_RXCSRL1_STALL; + TU_ASSERT(!(ep_csr->rx_csrl & USB_RXCSRL1_RXRDY),); + ep_csr->rx_csrl = USB_RXCSRL1_STALL; } } if (ie) musb_dcd_int_enable(rhport); @@ -711,13 +711,14 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; unsigned const epn = tu_edpt_number(ep_addr); - musb_epn_regs_t volatile *regs = musb_dcd_epn_regs(rhport, epn); + musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); if (tu_edpt_dir(ep_addr)) { /* IN */ - regs->TXCSRL = USB_TXCSRL1_CLRDT; + ep_csr->tx_csrl = USB_TXCSRL1_CLRDT; } else { /* OUT */ - regs->RXCSRL = USB_RXCSRL1_CLRDT; + ep_csr->rx_csrl = USB_RXCSRL1_CLRDT; } if (ie) musb_dcd_int_enable(rhport); } diff --git a/src/portable/mentor/musb/musb_max32.h b/src/portable/mentor/musb/musb_max32.h index 0a97f529a..43f56de3c 100644 --- a/src/portable/mentor/musb/musb_max32.h +++ b/src/portable/mentor/musb/musb_max32.h @@ -136,20 +136,6 @@ static inline void musb_dcd_phy_init(uint8_t rhport) { musb_periph_inst[rhport]->m31_phy_ponrst = 1; } -static inline volatile musb_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) { - //Need to set index to map EP registers - musb_periph_inst[rhport]->index = epnum; - volatile musb_epn_regs_t* regs = (volatile musb_epn_regs_t*) ((uintptr_t) &(musb_periph_inst[rhport]->inmaxp)); - return regs; -} - -static inline volatile musb_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) { - //Need to set index to map EP0 registers - musb_periph_inst[rhport]->index = 0; - volatile musb_ep0_regs_t* regs = (volatile musb_ep0_regs_t*) ((uintptr_t) &(musb_periph_inst[rhport]->csr0)); - return regs; -} - static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) { (void) mps; diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h index 499e01e63..d1a0aa4f9 100644 --- a/src/portable/mentor/musb/musb_ti.h +++ b/src/portable/mentor/musb/musb_ti.h @@ -97,22 +97,6 @@ static inline void musb_dcd_int_handler_exit(uint8_t rhport){ //Nothing to do for this part } -static inline volatile musb_epn_regs_t* musb_dcd_epn_regs(uint8_t rhport, unsigned epnum) -{ - uintptr_t baseptr = (uintptr_t)&(musb_periph_inst[rhport]->TXMAXP1); - - //On the TI parts, the epn registers are 16-bytes apart. The core regs defined - //by musb_dcd_epn_regs and 6 reserved/other use bytes - volatile musb_epn_regs_t *regs = (volatile musb_epn_regs_t*)(baseptr + ((epnum - 1) * 16)); - return regs; -} - -static inline volatile musb_ep0_regs_t* musb_dcd_ep0_regs(uint8_t rhport) -{ - volatile musb_ep0_regs_t *regs = (volatile musb_ep0_regs_t*)((uintptr_t)&(musb_periph_inst[rhport]->CSRL0)); - return regs; -} - typedef struct { uint_fast16_t beg; /* offset of including first element */ uint_fast16_t end; /* offset of excluding the last element */ diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index c31e0c984..670bc2ca1 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -1,3 +1,29 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 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. + */ + /****************************************************************************** * * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ @@ -57,24 +83,29 @@ #define __R volatile const #endif -// Endpoint register mapping. Non-zero end points. -typedef struct TU_ATTR_PACKED { - uint16_t TXMAXP; - uint8_t TXCSRL; - uint8_t TXCSRH; - uint16_t RXMAXP; - uint8_t RXCSRL; - uint8_t RXCSRH; - uint16_t RXCOUNT; -} musb_epn_regs_t; - -// Endpoint 0 register mapping. typedef struct TU_ATTR_PACKED { - uint8_t CSRL0; - uint8_t CSRH0; - uint32_t RESERVED; - uint8_t COUNT0; -} musb_ep0_regs_t; + __IO uint16_t tx_maxp; // 0x00: TXMAXP + union { + __IO uint8_t csr0l; // 0x02: CSR0 + __IO uint8_t tx_csrl; // 0x02: TX CSRL + }; + union { + __IO uint8_t csr0h; // 0x03: CSR0H + __IO uint8_t tx_csrh; // 0x03: TX CSRH + }; + __IO uint16_t rx_maxp; // 0x04: RX MAXP + __IO uint8_t rx_csrl; // 0x06: RX CSRL + __IO uint8_t rx_csrh; // 0x07: RX CSRH + __IO uint16_t rx_count; // 0x08: RX COUNT + __IO uint8_t tx_type; // 0x0A: TX TYPE + __IO uint8_t tx_interval; // 0x0B: TX INTERVAL + __IO uint8_t rx_type; // 0x0C: RX TYPE + __IO uint8_t rx_interval; // 0x0D: RX INTERVAL + __IO uint8_t reserved_0x0e; // 0x0E: Reserved + __IO uint8_t fifo_size; // 0x0F: FIFO_SIZE +} musb_ep_csr_t; + +TU_VERIFY_STATIC(sizeof(musb_ep_csr_t) == 16, "size is not correct"); typedef struct { //------------- Common -------------// @@ -93,21 +124,14 @@ typedef struct { __IO uint16_t frame; // 0x0C: FRAME __IO uint8_t index; // 0x0E: INDEX __IO uint8_t testmode; // 0x0F: TESTMODE - __IO uint16_t inmaxp; // 0x10: INMAXP - union { - __IO uint8_t csr0; // 0x12: CSR0 - __IO uint8_t incsrl; // 0x12: INCSRL - }; - __IO uint8_t incsru; // 0x13: INCSRU - __IO uint16_t outmaxp; // 0x14: OUTMAXP - __IO uint8_t outcsrl; // 0x16: OUTCSRL - __IO uint8_t outcsru; // 0x17: OUTCSRU - union { - __IO uint16_t count0; // 0x18: COUNT0 - __IO uint16_t outcount; // 0x18: OUTCOUNT - }; - __R uint16_t rsv_0x1a_0x1f[3]; + + //------------- Indexed CSR -------------// + musb_ep_csr_t indexed_csr; // 0x10-0x1F: Indexed CSR 0-15 + + //------------- FIFOs -------------// __IO uint32_t fifo[16]; // 0x20-0x5C: FIFO 0-15 + + // Common (2) __IO uint8_t devctl; // 0x60: DEVCTL __IO uint8_t misc; // 0x61: MISC @@ -138,7 +162,13 @@ typedef struct { //------------- Extended -------------// __IO uint16_t ctuch; // 0x80: CTUCH __IO uint16_t cthsrtn; // 0x82: CTHSRTN - __R uint32_t rsv_0x84_0x3ff[223]; + __R uint32_t rsv_0x84_0xff[31]; // 0x84-0xFF: Reserved + + //------------- Absolute CSR (used index to remap to Indexed above) -------------// + // TI tm4c can access this directly, but should use indexed_csr for portability + musb_ep_csr_t ep_csr[16]; // 0x100-0x1FF: EP0-15 CSR + + __R uint32_t rsv_0x200_0x3ff[128]; // 0x200-0x3FF: Reserved //------------- Analog PHY -------------// __IO uint32_t mxm_usb_reg_00; // 0x400: MXM_USB_REG_00 @@ -187,6 +217,16 @@ typedef struct { TU_VERIFY_STATIC(sizeof(musb_regs_t) == 0x4A8, "size is not correct"); +//--------------------------------------------------------------------+ +// Helper +//--------------------------------------------------------------------+ + +TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_regs, unsigned epnum) { + musb_regs->index = epnum; + return &musb_regs->indexed_csr; +} + + //***************************************************************************** // // The following are defines for the bit fields in the USB_O_FADDR register. -- cgit v1.3.1 From 33e3ea36450a30d76113e5e356ddf5f99cdda2c5 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 15 Aug 2024 23:46:33 +0700 Subject: remove analog PHY from musb_regs_t hil: remove ch32v203 since not reliable enough --- src/portable/mentor/musb/musb_type.h | 138 ++++++++++++----------------------- test/hil/rpi.json | 14 ++-- 2 files changed, 55 insertions(+), 97 deletions(-) (limited to 'src/portable') diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index 670bc2ca1..57ab2aefa 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -97,136 +97,94 @@ typedef struct TU_ATTR_PACKED { __IO uint8_t rx_csrl; // 0x06: RX CSRL __IO uint8_t rx_csrh; // 0x07: RX CSRH __IO uint16_t rx_count; // 0x08: RX COUNT - __IO uint8_t tx_type; // 0x0A: TX TYPE + union { + __IO uint8_t type0; // 0x0A: TYPE0 (host only) + __IO uint8_t tx_type; // 0x0A: TX TYPE + }; __IO uint8_t tx_interval; // 0x0B: TX INTERVAL __IO uint8_t rx_type; // 0x0C: RX TYPE __IO uint8_t rx_interval; // 0x0D: RX INTERVAL __IO uint8_t reserved_0x0e; // 0x0E: Reserved - __IO uint8_t fifo_size; // 0x0F: FIFO_SIZE + union { + __IO uint8_t config_data; // 0x0F: CONFIG DATA + __IO uint8_t fifo_size; // 0x0F: FIFO_SIZE + }; } musb_ep_csr_t; TU_VERIFY_STATIC(sizeof(musb_ep_csr_t) == 16, "size is not correct"); typedef struct { //------------- Common -------------// - __IO uint8_t faddr; // 0x00: FADDR - __IO uint8_t power; // 0x01: POWER + __IO uint8_t faddr; // 0x00: FADDR + __IO uint8_t power; // 0x01: POWER - __IO uint16_t intr_tx; // 0x02: INTR_TX - __IO uint16_t intr_rx; // 0x04: INTR_RX + __IO uint16_t intr_tx; // 0x02: INTR_TX + __IO uint16_t intr_rx; // 0x04: INTR_RX - __IO uint16_t intr_txen; // 0x06: INTR_TXEN - __IO uint16_t intr_rxen; // 0x08: INTR_RXEN + __IO uint16_t intr_txen; // 0x06: INTR_TXEN + __IO uint16_t intr_rxen; // 0x08: INTR_RXEN - __IO uint8_t intrusb; // 0x0A: INTRUSB - __IO uint8_t intrusben; // 0x0B: INTRUSBEN + __IO uint8_t intrusb; // 0x0A: INTRUSB + __IO uint8_t intrusben; // 0x0B: INTRUSBEN - __IO uint16_t frame; // 0x0C: FRAME - __IO uint8_t index; // 0x0E: INDEX - __IO uint8_t testmode; // 0x0F: TESTMODE + __IO uint16_t frame; // 0x0C: FRAME + __IO uint8_t index; // 0x0E: INDEX + __IO uint8_t testmode; // 0x0F: TESTMODE - //------------- Indexed CSR -------------// - musb_ep_csr_t indexed_csr; // 0x10-0x1F: Indexed CSR 0-15 + //------------- CSR (indexed) -------------// + musb_ep_csr_t indexed_csr; // 0x10-0x1F: Indexed CSR 0-15 //------------- FIFOs -------------// - __IO uint32_t fifo[16]; // 0x20-0x5C: FIFO 0-15 + __IO uint32_t fifo[16]; // 0x20-0x5C: FIFO 0-15 // Common (2) - __IO uint8_t devctl; // 0x60: DEVCTL - __IO uint8_t misc; // 0x61: MISC + __IO uint8_t devctl; // 0x60: DEVCTL + __IO uint8_t misc; // 0x61: MISC - //------------- Dynammic FIFO -------------// - __IO uint8_t txfifo_sz; // 0x62: TXFIFO_SZ - __IO uint8_t rxfifo_sz; // 0x63: RXFIFO_SZ - __IO uint16_t txfifo_addr; // 0x64: TXFIFO_ADDR - __IO uint16_t rxfifo_addr; // 0x66: RXFIFO_ADDR + //------------- Dynammic FIFO (indexed) -------------// + __IO uint8_t txfifo_sz; // 0x62: TXFIFO_SZ + __IO uint8_t rxfifo_sz; // 0x63: RXFIFO_SZ + __IO uint16_t txfifo_addr; // 0x64: TXFIFO_ADDR + __IO uint16_t rxfifo_addr; // 0x66: RXFIFO_ADDR //------------- Additional Control/Status -------------// union { - __O uint32_t vcontrol; // 0x68: VCONTROL - __IO uint32_t vstatus; // 0x68: VSTATUS + __O uint32_t vcontrol; // 0x68: VCONTROL + __IO uint32_t vstatus; // 0x68: VSTATUS }; - __IO uint16_t hwvers; // 0x6c: HWVERS - __R uint16_t rsv_0x6e_0x77[5]; - - //------------- Additional Configuration -------------// - __IO uint8_t epinfo; // 0x78: EPINFO - __IO uint8_t raminfo; // 0x79: RAMINFO - __IO uint8_t softreset; // 0x7A: SOFTRESET (Analog), Link info - __IO uint8_t vplen; // 0x7B: VPLEN - __IO uint8_t hs_eof1; // 0x7C: HS_EOF1 - __IO uint8_t fs_eof1; // 0x7D: FS_EOF1 - __IO uint8_t ls_eof1; // 0x7E: LS_EOF1 - __IO uint8_t soft_rst; // 0x7F: SOFT_RST + __IO uint16_t hwvers; // 0x6c: HWVERS + __R uint16_t rsv_0x6e_0x77[5]; // 0x6E-0x77: Reserved + + //------------- Additional Configuration -------------// + __IO uint8_t epinfo; // 0x78: EPINFO + __IO uint8_t raminfo; // 0x79: RAMINFO + __IO uint8_t softreset; // 0x7A: SOFTRESET (Analog), Link info + __IO uint8_t vplen; // 0x7B: VPLEN + __IO uint8_t hs_eof1; // 0x7C: HS_EOF1 + __IO uint8_t fs_eof1; // 0x7D: FS_EOF1 + __IO uint8_t ls_eof1; // 0x7E: LS_EOF1 + __IO uint8_t soft_rst; // 0x7F: SOFT_RST //------------- Extended -------------// - __IO uint16_t ctuch; // 0x80: CTUCH - __IO uint16_t cthsrtn; // 0x82: CTHSRTN - __R uint32_t rsv_0x84_0xff[31]; // 0x84-0xFF: Reserved + __IO uint16_t ctuch; // 0x80: CTUCH + __IO uint16_t cthsrtn; // 0x82: CTHSRTN + __R uint32_t rsv_0x84_0xff[31]; // 0x84-0xFF: Reserved //------------- Absolute CSR (used index to remap to Indexed above) -------------// // TI tm4c can access this directly, but should use indexed_csr for portability - musb_ep_csr_t ep_csr[16]; // 0x100-0x1FF: EP0-15 CSR - - __R uint32_t rsv_0x200_0x3ff[128]; // 0x200-0x3FF: Reserved - - //------------- Analog PHY -------------// - __IO uint32_t mxm_usb_reg_00; // 0x400: MXM_USB_REG_00 - __IO uint32_t m31_phy_utmi_reset; // 0x404: M31_PHY_UTMI_RESET - __IO uint32_t m31_phy_utmi_vcontrol; // 0x408: M31_PHY_UTMI_VCONTROL - __IO uint32_t m31_phy_clk_en; // 0x40C: M31_PHY_CLK_EN - __IO uint32_t m31_phy_ponrst; // 0x410: M31_PHY_PONRST - __IO uint32_t m31_phy_noncry_rstb; // 0x414: M31_PHY_NONCRY_RSTB - __IO uint32_t m31_phy_noncry_en; // 0x418: M31_PHY_NONCRY_EN - __R uint32_t rsv_0x41c; - __IO uint32_t m31_phy_u2_compliance_en; // 0x420: M31_PHY_U2_COMPLIANCE_EN - __IO uint32_t m31_phy_u2_compliance_dac_adj; // 0x424: M31_PHY_U2_COMPLIANCE_DAC_ADJ - __IO uint32_t m31_phy_u2_compliance_dac_adj_en; // 0x428: M31_PHY_U2_COMPLIANCE_DAC_ADJ_EN - __IO uint32_t m31_phy_clk_rdy; // 0x42C: M31_PHY_CLK_RDY - __IO uint32_t m31_phy_pll_en; // 0x430: M31_PHY_PLL_EN - __IO uint32_t m31_phy_bist_ok; // 0x434: M31_PHY_BIST_OK - __IO uint32_t m31_phy_data_oe; // 0x438: M31_PHY_DATA_OE - __IO uint32_t m31_phy_oscouten; // 0x43C: M31_PHY_OSCOUTEN - __IO uint32_t m31_phy_lpm_alive; // 0x440: M31_PHY_LPM_ALIVE - __IO uint32_t m31_phy_hs_bist_mode; // 0x444: M31_PHY_HS_BIST_MODE - __IO uint32_t m31_phy_coreclkin; // 0x448: M31_PHY_CORECLKIN - __IO uint32_t m31_phy_xtlsel; // 0x44C: M31_PHY_XTLSEL - __IO uint32_t m31_phy_ls_en; // 0x450: M31_PHY_LS_EN - __IO uint32_t m31_phy_debug_sel; // 0x454: M31_PHY_DEBUG_SEL - __IO uint32_t m31_phy_debug_out; // 0x458: M31_PHY_DEBUG_OUT - __IO uint32_t m31_phy_outclksel; // 0x45C: M31_PHY_OUTCLKSEL - __IO uint32_t m31_phy_xcfgi_31_0; // 0x460: M31_PHY_XCFGI_31_0 - __IO uint32_t m31_phy_xcfgi_63_32; // 0x464: M31_PHY_XCFGI_63_32 - __IO uint32_t m31_phy_xcfgi_95_64; // 0x468: M31_PHY_XCFGI_95_64 - __IO uint32_t m31_phy_xcfgi_127_96; // 0x46C: M31_PHY_XCFGI_127_96 - __IO uint32_t m31_phy_xcfgi_137_128; // 0x470: M31_PHY_XCFGI_137_128 - __IO uint32_t m31_phy_xcfg_hs_coarse_tune_num; // 0x474: M31_PHY_XCFG_HS_COARSE_TUNE_NUM - __IO uint32_t m31_phy_xcfg_hs_fine_tune_num; // 0x478: M31_PHY_XCFG_HS_FINE_TUNE_NUM - __IO uint32_t m31_phy_xcfg_fs_coarse_tune_num; // 0x47C: M31_PHY_XCFG_FS_COARSE_TUNE_NUM - __IO uint32_t m31_phy_xcfg_fs_fine_tune_num; // 0x480: M31_PHY_XCFG_FS_FINE_TUNE_NUM - __IO uint32_t m31_phy_xcfg_lock_range_max; // 0x484: M31_PHY_XCFG_LOCK_RANGE_MAX - __IO uint32_t m31_phy_xcfgi_lock_range_min; // 0x488: M31_PHY_XCFGI_LOCK_RANGE_MIN - __IO uint32_t m31_phy_xcfg_ob_rsel; // 0x48C: M31_PHY_XCFG_OB_RSEL - __IO uint32_t m31_phy_xcfg_oc_rsel; // 0x490: M31_PHY_XCFG_OC_RSEL - __IO uint32_t m31_phy_xcfgo; // 0x494: M31_PHY_XCFGO - __IO uint32_t mxm_int; // 0x498: MXM_INT - __IO uint32_t mxm_int_en; // 0x49C: MXM_INT_EN - __IO uint32_t mxm_suspend; // 0x4A0: MXM_SUSPEND - __IO uint32_t mxm_reg_a4; // 0x4A4: MXM_REG_A4 + musb_ep_csr_t ep_csr[16]; // 0x100-0x1FF: EP0-15 CSR } musb_regs_t; -TU_VERIFY_STATIC(sizeof(musb_regs_t) == 0x4A8, "size is not correct"); +TU_VERIFY_STATIC(sizeof(musb_regs_t) == 0x200, "size is not correct"); //--------------------------------------------------------------------+ // Helper //--------------------------------------------------------------------+ - TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_regs, unsigned epnum) { musb_regs->index = epnum; return &musb_regs->indexed_csr; } - //***************************************************************************** // // The following are defines for the bit fields in the USB_O_FADDR register. diff --git a/test/hil/rpi.json b/test/hil/rpi.json index 688ea3822..b7d36c543 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -50,13 +50,6 @@ "flasher": "openocd", "flasher_sn": "066FFF495087534867063844", "flasher_args": "-f interface/stlink.cfg -f target/stm32g0x.cfg" - }, - { - "name": "nanoch32v203", - "uid": "CDAB277B0FBC03E339E339E3", - "flasher": "openocd_wch", - "flasher_sn": "EBCA8F0670AF", - "flasher_args": "" } ], "boards-skip": [ @@ -68,6 +61,13 @@ "flasher_args": "-device MIMXRT1011xxx5A", "comment": "not running reliably in bulk with other boards, probably power, flashing etc .." }, + { + "name": "nanoch32v203", + "uid": "CDAB277B0FBC03E339E339E3", + "flasher": "openocd_wch", + "flasher_sn": "EBCA8F0670AF", + "flasher_args": "" + }, { "name": "espressif_s3_devkitm", "uid": "84F703C084E4", -- cgit v1.3.1 From eaf9cc1beb6f5e34683debe531c7fa4d012c47b2 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 17 Aug 2024 13:31:31 +0700 Subject: more refactor to simplify musb driver --- src/common/tusb_mcu.h | 2 + src/portable/mentor/musb/dcd_musb.c | 176 +-- src/portable/mentor/musb/musb_max32.h | 66 +- src/portable/mentor/musb/musb_ti.h | 47 +- src/portable/mentor/musb/musb_type.h | 2387 +++++++++++++-------------------- 5 files changed, 1090 insertions(+), 1588 deletions(-) (limited to 'src/portable') diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 7ec3c5842..0180fc466 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -309,6 +309,7 @@ #elif TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) #define TUP_USBIP_MUSB + #define TUP_USBIP_MUSB_TI #define TUP_DCD_ENDPOINT_MAX 8 //--------------------------------------------------------------------+ @@ -474,6 +475,7 @@ //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002) #define TUP_USBIP_MUSB + #define TUP_USBIP_MUSB_ADI #define TUP_DCD_ENDPOINT_MAX 12 #define TUP_RHPORT_HIGHSPEED 1 diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 48f6e9d97..36690c952 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -41,10 +41,10 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); // Following symbols must be defined by port header // - musb_dcd_int_enable/disable/clear/get_enable // - musb_dcd_int_handler_enter/exit -// - musb_dcd_setup_fifo/reset_fifo: Configuration of the EP's FIFO -#if TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) +// - musb_dcd_setup_fifo: Configuration of the EP's FIFO +#if defined(TUP_USBIP_MUSB_TI) #include "musb_ti.h" -#elif TU_CHECK_MCU(OPT_MCU_MAX32690, OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX78002) +#elif defined(TUP_USBIP_MUSB_ADI) #include "musb_max32.h" #else #error "Unsupported MCU" @@ -52,6 +52,8 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); #define MUSB_REGS(rhport) ((musb_regs_t*) MUSB_BASES[rhport]) +#define MUSB_DEBUG 2 + /*------------------------------------------------------------------ * MACRO TYPEDEF CONSTANT ENUM DECLARATION *------------------------------------------------------------------*/ @@ -86,6 +88,18 @@ typedef struct *------------------------------------------------------------------*/ static dcd_data_t _dcd; +TU_ATTR_ALWAYS_INLINE static inline void fifo_reset(musb_regs_t* musb, unsigned epnum, unsigned dir_in) { + musb->index = epnum; + const uint8_t is_rx = 1 - dir_in; + +#if MUSB_CFG_DYNAMIC_FIFO + musb->fifo_size[is_rx] = 0; + musb->fifo_addr[is_rx] = 0; +#elif defined(TUP_USBIP_MUSB_ADI) + // Analog have custom double buffered in csrh register, disable it + musb->indexed_csr.maxp_csr[is_rx].csrh |= MUSB_CSRH_DISABLE_DOUBLE_PACKET(is_rx); +#endif +} static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) { @@ -363,13 +377,13 @@ static void process_ep0(uint8_t rhport) /* Received SETUP or DATA OUT packet */ if (req == REQUEST_TYPE_INVALID) { /* SETUP */ - TU_ASSERT(sizeof(tusb_control_request_t) == ep_csr->rx_count,); + TU_ASSERT(sizeof(tusb_control_request_t) == ep_csr->count0,); process_setup_packet(rhport); return; } if (_dcd.pipe0.buf) { /* DATA OUT */ - const unsigned vld = ep_csr->rx_count; + const unsigned vld = ep_csr->count0; const unsigned rem = _dcd.pipe0.remaining; const unsigned len = TU_MIN(TU_MIN(rem, 64), vld); volatile void *fifo_ptr = &musb_regs->fifo[0]; @@ -445,47 +459,70 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) } } -static void process_bus_reset(uint8_t rhport) -{ - musb_regs_t* musb_regs = MUSB_REGS(rhport); - /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), - * a control transfer state is SETUP or STATUS stage. */ +// Upon BUS RESET is detected, hardware havs already done: +// faddr = 0, index = 0, flushes all ep fifos, clears all ep csr, enabled all ep interrupts +static void process_bus_reset(uint8_t rhport) { + musb_regs_t* musb = MUSB_REGS(rhport); + /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), a control transfer state is SETUP or STATUS stage. */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; _dcd.status_out = 0; /* When pipe0.buf has not NULL, DATA stage works in progress. */ _dcd.pipe0.buf = NULL; - musb_regs->intr_txen = 1; /* Enable only EP0 */ - musb_regs->intr_rxen = 0; + musb->intr_txen = 1; /* Enable only EP0 */ + musb->intr_rxen = 0; /* Clear FIFO settings */ for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { - musb_dcd_reset_fifo(rhport, i, 0); - musb_dcd_reset_fifo(rhport, i, 1); + fifo_reset(musb, i, 0); + fifo_reset(musb, i, 1); } - dcd_event_bus_reset(rhport, (musb_regs->power & USB_POWER_HSMODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); + dcd_event_bus_reset(rhport, (musb->power & USB_POWER_HSMODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); } /*------------------------------------------------------------------ * Device API *------------------------------------------------------------------*/ -void dcd_init(uint8_t rhport) -{ +#if CFG_TUSB_DEBUG >= MUSB_DEBUG +void print_musb_info(musb_regs_t* musb_regs) { + // print version, epinfo, raminfo, config_data0, fifo_size + TU_LOG1("musb version = %u.%u\r\n", musb_regs->hwvers_bit.major, musb_regs->hwvers_bit.minor); + TU_LOG1("Number of endpoints: %u TX, %u RX\r\n", musb_regs->epinfo_bit.tx_ep_num, musb_regs->epinfo_bit.rx_ep_num); + TU_LOG1("RAM Info: %u DMA Channel, %u RAM address width\r\n", musb_regs->raminfo_bit.dma_channel, musb_regs->raminfo_bit.ram_bits); + + musb_regs->index = 0; + TU_LOG1("config_data0 = 0x%x\r\n", musb_regs->indexed_csr.config_data0); + +#if MUSB_CFG_DYNAMIC_FIFO + TU_LOG1("Dynamic FIFO configuration\r\n"); +#else + for (uint8_t i=1; i <= musb_regs->epinfo_bit.tx_ep_num; i++) { + musb_regs->index = i; + TU_LOG1("FIFO %u Size: TX %u RX %u\r\n", i, musb_regs->indexed_csr.fifo_size_bit.tx, musb_regs->indexed_csr.fifo_size_bit.rx); + } +#endif +} +#endif + +void dcd_init(uint8_t rhport) { musb_regs_t* musb_regs = MUSB_REGS(rhport); - musb_regs->intrusben |= USB_IE_SUSPND; + +#if CFG_TUSB_DEBUG >= MUSB_DEBUG + print_musb_info(musb_regs); +#endif + + musb_regs->intr_usben |= USB_IE_SUSPND; musb_dcd_int_clear(rhport); musb_dcd_phy_init(rhport); dcd_connect(rhport); } -void dcd_int_enable(uint8_t rhport) -{ +void dcd_int_enable(uint8_t rhport) { musb_dcd_int_enable(rhport); } -void dcd_int_disable(uint8_t rhport) -{ +void dcd_int_disable(uint8_t rhport) { musb_dcd_int_disable(rhport); } @@ -559,25 +596,17 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); - if (dir_in) { - ep_csr->tx_maxp = mps; - ep_csr->tx_csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_TXCSRH1_ISO : 0; - if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY) { - ep_csr->tx_csrl = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; - } else { - ep_csr->tx_csrl = USB_TXCSRL1_CLRDT; - } - musb_regs->intr_txen |= TU_BIT(epn); - } else { - ep_csr->rx_maxp = mps; - ep_csr->rx_csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_RXCSRH1_ISO : 0; - if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) { - ep_csr->rx_csrl = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; - } else { - ep_csr->rx_csrl = USB_RXCSRL1_CLRDT; - } - musb_regs->intr_rxen |= TU_BIT(epn); + + const uint8_t is_rx = 1 - dir_in; + ep_csr->maxp_csr[is_rx].maxp = mps; + ep_csr->maxp_csr[is_rx].csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_RXCSRH1_ISO : 0; + + uint8_t csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(is_rx); + if (ep_csr->maxp_csr[is_rx].csrl & MUSB_CSRL_PACKET_READY(is_rx)) { + csrl |= MUSB_CSRL_FLUSH_FIFO(is_rx); } + ep_csr->maxp_csr[is_rx].csrl = csrl; + musb_regs->intren_ep[is_rx] |= TU_BIT(epn); /* Setup FIFO */ musb_dcd_setup_fifo(rhport, epn, dir_in, mps); @@ -587,13 +616,13 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) void dcd_edpt_close_all(uint8_t rhport) { - musb_regs_t* musb_regs = MUSB_REGS(rhport); + musb_regs_t* musb = MUSB_REGS(rhport); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); - musb_regs->intr_txen = 1; /* Enable only EP0 */ - musb_regs->intr_rxen = 0; + musb->intr_txen = 1; /* Enable only EP0 */ + musb->intr_rxen = 0; for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { - musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, i); + musb_ep_csr_t* ep_csr = get_ep_csr(musb, i); ep_csr->tx_maxp = 0; ep_csr->tx_csrh = 0; if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY) @@ -609,8 +638,8 @@ void dcd_edpt_close_all(uint8_t rhport) ep_csr->rx_csrl = USB_RXCSRL1_CLRDT; } - musb_dcd_reset_fifo(rhport, i, 0); - musb_dcd_reset_fifo(rhport, i, 1); + fifo_reset(musb, i, 0); + fifo_reset(musb, i, 1); } if (ie) musb_dcd_int_enable(rhport); @@ -620,12 +649,12 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { unsigned const epn = tu_edpt_number(ep_addr); unsigned const dir_in = tu_edpt_dir(ep_addr); - musb_regs_t* musb_regs = MUSB_REGS(rhport); - musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); + musb_regs_t* musb = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); if (dir_in) { - musb_regs->intr_txen &= ~TU_BIT(epn); + musb->intr_txen &= ~TU_BIT(epn); ep_csr->tx_maxp = 0; ep_csr->tx_csrh = 0; if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY) { @@ -634,7 +663,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) ep_csr->tx_csrl = USB_TXCSRL1_CLRDT; } } else { - musb_regs->intr_rxen &= ~TU_BIT(epn); + musb->intr_rxen &= ~TU_BIT(epn); ep_csr->rx_maxp = 0; ep_csr->rx_csrh = 0; if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) { @@ -643,7 +672,7 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) ep_csr->rx_csrl = USB_RXCSRL1_CLRDT; } } - musb_dcd_reset_fifo(rhport, epn, dir_in); + fifo_reset(musb, epn, dir_in); if (ie) musb_dcd_int_enable(rhport); } @@ -726,51 +755,48 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) /*------------------------------------------------------------------- * ISR *-------------------------------------------------------------------*/ -void dcd_int_handler(uint8_t rhport) -{ - uint_fast8_t is, txis, rxis; - +void dcd_int_handler(uint8_t rhport) { //Part specific ISR setup/entry musb_dcd_int_handler_enter(rhport); musb_regs_t* musb_regs = MUSB_REGS(rhport); - - is = musb_regs->intrusb; /* read and clear interrupt status */ - txis = musb_regs->intr_tx; /* read and clear interrupt status */ - rxis = musb_regs->intr_rx; /* read and clear interrupt status */ + uint_fast8_t intr_usb = musb_regs->intr_usb; // a read will clear this interrupt status + uint_fast8_t intr_tx = musb_regs->intr_tx; // a read will clear this interrupt status + uint_fast8_t intr_rx = musb_regs->intr_rx; // a read will clear this interrupt status // TU_LOG1("D%2x T%2x R%2x\r\n", is, txis, rxis); - is &= musb_regs->intrusben; /* Clear disabled interrupts */ - if (is & USB_IS_DISCON) { + intr_usb &= musb_regs->intr_usben; /* Clear disabled interrupts */ + if (intr_usb & USB_IS_DISCON) { } - if (is & USB_IS_SOF) { + if (intr_usb & USB_IS_SOF) { dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); } - if (is & USB_IS_RESET) { + if (intr_usb & USB_IS_RESET) { process_bus_reset(rhport); } - if (is & USB_IS_RESUME) { + if (intr_usb & USB_IS_RESUME) { dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); } - if (is & USB_IS_SUSPEND) { + if (intr_usb & USB_IS_SUSPEND) { dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); } - txis &= musb_regs->intr_txen; /* Clear disabled interrupts */ - if (txis & USB_TXIE_EP0) { + intr_tx &= musb_regs->intr_txen; /* Clear disabled interrupts */ + if (intr_tx & TU_BIT(0)) { process_ep0(rhport); - txis &= ~TU_BIT(0); + intr_tx &= ~TU_BIT(0); } - while (txis) { - unsigned const num = __builtin_ctz(txis); + while (intr_tx) { + unsigned const num = __builtin_ctz(intr_tx); process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_IN)); - txis &= ~TU_BIT(num); + intr_tx &= ~TU_BIT(num); } - rxis &= musb_regs->intr_rxen; /* Clear disabled interrupts */ - while (rxis) { - unsigned const num = __builtin_ctz(rxis); + + intr_rx &= musb_regs->intr_rxen; /* Clear disabled interrupts */ + while (intr_rx) { + unsigned const num = __builtin_ctz(intr_rx); process_edpt_n(rhport, tu_edpt_addr(num, TUSB_DIR_OUT)); - rxis &= ~TU_BIT(num); + intr_rx &= ~TU_BIT(num); } //Part specific ISR exit diff --git a/src/portable/mentor/musb/musb_max32.h b/src/portable/mentor/musb/musb_max32.h index 43f56de3c..73f63ee2e 100644 --- a/src/portable/mentor/musb/musb_max32.h +++ b/src/portable/mentor/musb/musb_max32.h @@ -34,6 +34,8 @@ extern "C" { #include "mxc_device.h" #include "usbhs_regs.h" +#define MUSB_CFG_DYNAMIC_FIFO 0 + const uintptr_t MUSB_BASES[] = { MXC_BASE_USBHS }; #if CFG_TUD_ENABLED @@ -100,40 +102,43 @@ static inline void musb_dcd_int_handler_exit(uint8_t rhport) { } static inline void musb_dcd_phy_init(uint8_t rhport) { - //Interrupt for VBUS disconnect - musb_periph_inst[rhport]->mxm_int_en |= MXC_F_USBHS_MXM_INT_EN_NOVBUS; + (void) rhport; + mxc_usbhs_regs_t* hs_phy = MXC_USBHS; + + // Interrupt for VBUS disconnect + hs_phy->mxm_int_en |= MXC_F_USBHS_MXM_INT_EN_NOVBUS; musb_dcd_int_clear(rhport); - //Unsuspend the MAC - musb_periph_inst[rhport]->mxm_suspend = 0; + // Unsuspend the MAC + hs_phy->mxm_suspend = 0; // Configure PHY - musb_periph_inst[rhport]->m31_phy_xcfgi_31_0 = (0x1 << 3) | (0x1 << 11); - musb_periph_inst[rhport]->m31_phy_xcfgi_63_32 = 0; - musb_periph_inst[rhport]->m31_phy_xcfgi_95_64 = 0x1 << (72 - 64); - musb_periph_inst[rhport]->m31_phy_xcfgi_127_96 = 0; + hs_phy->m31_phy_xcfgi_31_0 = (0x1 << 3) | (0x1 << 11); + hs_phy->m31_phy_xcfgi_63_32 = 0; + hs_phy->m31_phy_xcfgi_95_64 = 0x1 << (72 - 64); + hs_phy->m31_phy_xcfgi_127_96 = 0; #ifdef USBHS_M31_CLOCK_RECOVERY - musb_periph_inst[rhport]->m31_phy_noncry_rstb = 1; - musb_periph_inst[rhport]->m31_phy_noncry_en = 1; - musb_periph_inst[rhport]->m31_phy_outclksel = 0; - musb_periph_inst[rhport]->m31_phy_coreclkin = 0; - musb_periph_inst[rhport]->m31_phy_xtlsel = 2; /* Select 25 MHz clock */ + hs_phy->m31_phy_noncry_rstb = 1; + hs_phy->m31_phy_noncry_en = 1; + hs_phy->m31_phy_outclksel = 0; + hs_phy->m31_phy_coreclkin = 0; + hs_phy->m31_phy_xtlsel = 2; /* Select 25 MHz clock */ #else - musb_periph_inst[rhport]->m31_phy_noncry_rstb = 0; - musb_periph_inst[rhport]->m31_phy_noncry_en = 0; - musb_periph_inst[rhport]->m31_phy_outclksel = 1; - musb_periph_inst[rhport]->m31_phy_coreclkin = 1; - musb_periph_inst[rhport]->m31_phy_xtlsel = 3; /* Select 30 MHz clock */ + hs_phy->m31_phy_noncry_rstb = 0; + hs_phy->m31_phy_noncry_en = 0; + hs_phy->m31_phy_outclksel = 1; + hs_phy->m31_phy_coreclkin = 1; + hs_phy->m31_phy_xtlsel = 3; /* Select 30 MHz clock */ #endif - musb_periph_inst[rhport]->m31_phy_pll_en = 1; - musb_periph_inst[rhport]->m31_phy_oscouten = 1; + hs_phy->m31_phy_pll_en = 1; + hs_phy->m31_phy_oscouten = 1; /* Reset PHY */ - musb_periph_inst[rhport]->m31_phy_ponrst = 0; - musb_periph_inst[rhport]->m31_phy_ponrst = 1; + hs_phy->m31_phy_ponrst = 0; + hs_phy->m31_phy_ponrst = 1; } static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) { @@ -155,23 +160,6 @@ static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned musb_periph_inst[rhport]->index = saved_index; } -static inline void musb_dcd_reset_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in) { - //Most likely the caller has already grabbed the right register block. But - //as a precaution save and restore the register bank anyways - unsigned saved_index = musb_periph_inst[rhport]->index; - - musb_periph_inst[rhport]->index = epnum; - - //Disable double buffering - if (dir_in) { - musb_periph_inst[rhport]->incsru |= (MXC_F_USBHS_INCSRU_DPKTBUFDIS); - } else { - musb_periph_inst[rhport]->outcsru |= (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS); - } - - musb_periph_inst[rhport]->index = saved_index; -} - #endif // CFG_TUD_ENABLED #ifdef __cplusplus diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h index d1a0aa4f9..e43b3d3c0 100644 --- a/src/portable/mentor/musb/musb_ti.h +++ b/src/portable/mentor/musb/musb_ti.h @@ -42,8 +42,10 @@ #error "Unsupported MCUs" #endif -const uintptr_t MUSB_BASES[] = { USB0_BASE }; +#define MUSB_CFG_DYNAMIC_FIFO 1 +#define MUSB_CFG_DYNAMIC_FIFO_SIZE 4096 +const uintptr_t MUSB_BASES[] = { USB0_BASE }; // Header supports both device and host modes. Only include what's necessary #if CFG_TUD_ENABLED @@ -63,36 +65,28 @@ static inline void musb_dcd_phy_init(uint8_t rhport){ //Nothing to do for this part } -TU_ATTR_ALWAYS_INLINE -static inline void musb_dcd_int_enable(uint8_t rhport) -{ +TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_enable(uint8_t rhport) { NVIC_EnableIRQ(musb_irqs[rhport]); } -TU_ATTR_ALWAYS_INLINE -static inline void musb_dcd_int_disable(uint8_t rhport) -{ +TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_disable(uint8_t rhport) { NVIC_DisableIRQ(musb_irqs[rhport]); } -TU_ATTR_ALWAYS_INLINE -static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) -{ +TU_ATTR_ALWAYS_INLINE static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) { return NVIC_GetEnableIRQ(musb_irqs[rhport]); } -TU_ATTR_ALWAYS_INLINE -static inline void musb_dcd_int_clear(uint8_t rhport) -{ - NVIC_ClearPendingIRQ(musb_irqs[rhport]); +TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_clear(uint8_t rhport) { + NVIC_ClearPendingIRQ(musb_irqs[rhport]); } -static inline void musb_dcd_int_handler_enter(uint8_t rhport){ +static inline void musb_dcd_int_handler_enter(uint8_t rhport) { (void)rhport; //Nothing to do for this part } -static inline void musb_dcd_int_handler_exit(uint8_t rhport){ +static inline void musb_dcd_int_handler_exit(uint8_t rhport) { (void)rhport; //Nothing to do for this part } @@ -102,15 +96,13 @@ typedef struct { uint_fast16_t end; /* offset of excluding the last element */ } free_block_t; -static inline free_block_t *find_containing_block(free_block_t *beg, free_block_t *end, uint_fast16_t addr) -{ +static inline free_block_t *find_containing_block(free_block_t *beg, free_block_t *end, uint_fast16_t addr) { free_block_t *cur = beg; for (; cur < end && ((addr < cur->beg) || (cur->end <= addr)); ++cur) ; return cur; } -static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_fast16_t addr, uint_fast16_t size) -{ +static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_fast16_t addr, uint_fast16_t size) { free_block_t *p = find_containing_block(blks, blks + num, addr); TU_ASSERT(p != blks + num, -2); if (p->beg == addr) { @@ -150,8 +142,7 @@ static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_ } } -static inline unsigned free_block_size(free_block_t const *blk) -{ +static inline unsigned free_block_size(free_block_t const *blk) { return blk->end - blk->beg; } @@ -234,18 +225,6 @@ static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned } } -static inline void musb_dcd_reset_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in) -{ - musb_periph_inst[rhport]->EPIDX = epnum; - if (dir_in) { - musb_periph_inst[rhport]->TXFIFOADD = 0; - musb_periph_inst[rhport]->TXFIFOSZ = 0; - } else { - musb_periph_inst[rhport]->RXFIFOADD = 0; - musb_periph_inst[rhport]->RXFIFOSZ = 0; - } -} - #endif // CFG_TUD_ENABLED #ifdef __cplusplus diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index 57ab2aefa..ee0187270 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -83,20 +83,37 @@ #define __R volatile const #endif +// 0: TX (device IN, host OUT) +// 1: RX (device OUT, host IN) typedef struct TU_ATTR_PACKED { - __IO uint16_t tx_maxp; // 0x00: TXMAXP union { - __IO uint8_t csr0l; // 0x02: CSR0 - __IO uint8_t tx_csrl; // 0x02: TX CSRL + struct { + __IO uint16_t tx_maxp; // 0x00: TXMAXP + union { + __IO uint8_t csr0l; // 0x02: CSR0 + __IO uint8_t tx_csrl; // 0x02: TX CSRL + }; + union { + __IO uint8_t csr0h; // 0x03: CSR0H + __IO uint8_t tx_csrh; // 0x03: TX CSRH + }; + + __IO uint16_t rx_maxp; // 0x04: RX MAXP + __IO uint8_t rx_csrl; // 0x06: RX CSRL + __IO uint8_t rx_csrh; // 0x07: RX CSRH + }; + + struct { + __IO uint16_t maxp; // 0x00: MAXP + __IO uint8_t csrl; // 0x02: CSRL + __IO uint8_t csrh; // 0x03: CSRH + }maxp_csr[2]; }; + union { - __IO uint8_t csr0h; // 0x03: CSR0H - __IO uint8_t tx_csrh; // 0x03: TX CSRH + __IO uint16_t count0; // 0x08: COUNT0 + __IO uint16_t rx_count; // 0x08: RX COUNT }; - __IO uint16_t rx_maxp; // 0x04: RX MAXP - __IO uint8_t rx_csrl; // 0x06: RX CSRL - __IO uint8_t rx_csrh; // 0x07: RX CSRH - __IO uint16_t rx_count; // 0x08: RX COUNT union { __IO uint8_t type0; // 0x0A: TYPE0 (host only) __IO uint8_t tx_type; // 0x0A: TX TYPE @@ -106,32 +123,71 @@ typedef struct TU_ATTR_PACKED { __IO uint8_t rx_interval; // 0x0D: RX INTERVAL __IO uint8_t reserved_0x0e; // 0x0E: Reserved union { - __IO uint8_t config_data; // 0x0F: CONFIG DATA + __IO uint8_t config_data0; // 0x0F: CONFIG DATA + struct { + __IO uint8_t utmi_data_width : 1; // [0] UTMI Data Width + __IO uint8_t softconn_en : 1; // [1] Soft Connect Enable + __IO uint8_t dynamic_fifo : 1; // [2] Dynamic FIFO Sizing + __IO uint8_t hb_tx_en : 1; // [3] High Bandwidth TX ISO Enable + __IO uint8_t hb_rx_en : 1; // [4] High Bandwidth RX ISO Enable + __IO uint8_t big_endian : 1; // [5] Big Endian + __IO uint8_t mp_tx_en : 1; // [6] Auto splitting BULK TX Enable + __IO uint8_t mp_rx_en : 1; // [7] Auto amalgamation BULK RX Enable + } config_data0_bit; + __IO uint8_t fifo_size; // 0x0F: FIFO_SIZE + struct { + __IO uint8_t tx : 4; // [3:0] TX FIFO Size + __IO uint8_t rx : 4; // [7:4] RX FIFO Size + }fifo_size_bit; }; } musb_ep_csr_t; TU_VERIFY_STATIC(sizeof(musb_ep_csr_t) == 16, "size is not correct"); -typedef struct { +typedef struct TU_ATTR_PACKED { //------------- Common -------------// __IO uint8_t faddr; // 0x00: FADDR - __IO uint8_t power; // 0x01: POWER + union { + __IO uint8_t power; // 0x01: POWER + struct { + __IO uint8_t suspend_mode_en : 1; // [0] SUSPEND Mode Enable + __IO uint8_t suspend_mode : 1; // [1] SUSPEND Mode + __IO uint8_t resume_mode : 1; // [2] RESUME + __IO uint8_t reset : 1; // [3] RESET + __IO uint8_t highspeed_mode : 1; // [4] High Speed Mode + __IO uint8_t highspeed_en : 1; // [5] High Speed Enable + __IO uint8_t soft_conn : 1; // [6] Soft Connect/Disconnect + __IO uint8_t iso_update : 1; // [7] Isochronous Update + } power_bit; + }; + + union { + struct { + __IO uint16_t intr_tx; // 0x02: INTR_TX + __IO uint16_t intr_rx; // 0x04: INTR_RX + }; + + __IO uint16_t intr_ep[2]; // 0x02-0x05: INTR_EP0-1 + }; - __IO uint16_t intr_tx; // 0x02: INTR_TX - __IO uint16_t intr_rx; // 0x04: INTR_RX + union { + struct { + __IO uint16_t intr_txen; // 0x06: INTR_TXEN + __IO uint16_t intr_rxen; // 0x08: INTR_RXEN + }; - __IO uint16_t intr_txen; // 0x06: INTR_TXEN - __IO uint16_t intr_rxen; // 0x08: INTR_RXEN + __IO uint16_t intren_ep[2]; // 0x06-0x09: INTREN_EP0-1 + }; - __IO uint8_t intrusb; // 0x0A: INTRUSB - __IO uint8_t intrusben; // 0x0B: INTRUSBEN + __IO uint8_t intr_usb; // 0x0A: INTRUSB + __IO uint8_t intr_usben; // 0x0B: INTRUSBEN __IO uint16_t frame; // 0x0C: FRAME __IO uint8_t index; // 0x0E: INDEX __IO uint8_t testmode; // 0x0F: TESTMODE - //------------- CSR (indexed) -------------// + //------------- Endpoint CSR (indexed) -------------// musb_ep_csr_t indexed_csr; // 0x10-0x1F: Indexed CSR 0-15 //------------- FIFOs -------------// @@ -142,35 +198,68 @@ typedef struct { __IO uint8_t misc; // 0x61: MISC //------------- Dynammic FIFO (indexed) -------------// - __IO uint8_t txfifo_sz; // 0x62: TXFIFO_SZ - __IO uint8_t rxfifo_sz; // 0x63: RXFIFO_SZ - __IO uint16_t txfifo_addr; // 0x64: TXFIFO_ADDR - __IO uint16_t rxfifo_addr; // 0x66: RXFIFO_ADDR + union { + struct { + __IO uint8_t txfifo_sz; // 0x62: TXFIFO_SZ + __IO uint8_t rxfifo_sz; // 0x63: RXFIFO_SZ + }; + __IO uint8_t fifo_size[2]; + }; + + union { + struct { + __IO uint16_t txfifo_addr; // 0x64: TXFIFO_ADDR + __IO uint16_t rxfifo_addr; // 0x66: RXFIFO_ADDR + }; + __IO uint16_t fifo_addr[2]; + }; - //------------- Additional Control/Status -------------// + //------------- Additional Control and Configuration -------------// + union { + __O uint32_t vcontrol; // 0x68: PHY VCONTROL + __IO uint32_t vstatus; // 0x68: PHY VSTATUS + }; union { - __O uint32_t vcontrol; // 0x68: VCONTROL - __IO uint32_t vstatus; // 0x68: VSTATUS + __IO uint16_t hwvers; // 0x6C: HWVERS + struct { + __IO uint16_t minor : 10; // [9:0] Minor + __IO uint16_t major : 5; // [14:10] Major + __IO uint16_t rc : 1; // [15] Release Candidate + } hwvers_bit; }; - __IO uint16_t hwvers; // 0x6c: HWVERS __R uint16_t rsv_0x6e_0x77[5]; // 0x6E-0x77: Reserved //------------- Additional Configuration -------------// - __IO uint8_t epinfo; // 0x78: EPINFO - __IO uint8_t raminfo; // 0x79: RAMINFO - __IO uint8_t softreset; // 0x7A: SOFTRESET (Analog), Link info + union { + __IO uint8_t epinfo; // 0x78: EPINFO + struct { + __IO uint8_t tx_ep_num : 4; // [3:0] TX Endpoints + __IO uint8_t rx_ep_num : 4; // [7:4] RX Endpoints + } epinfo_bit; + }; + union { + __IO uint8_t raminfo; // 0x79: RAMINFO + struct { + __IO uint8_t ram_bits : 4; // [3:0] RAM Address Bus Width + __IO uint8_t dma_channel : 4; // [7:4] DMA Channels + }raminfo_bit; + }; + union { + __IO uint8_t link_info; // 0x7A: LINK_INFO + __IO uint8_t adi_softreset; // 0x7A: AnalogDevice SOFTRESET + }; __IO uint8_t vplen; // 0x7B: VPLEN __IO uint8_t hs_eof1; // 0x7C: HS_EOF1 __IO uint8_t fs_eof1; // 0x7D: FS_EOF1 __IO uint8_t ls_eof1; // 0x7E: LS_EOF1 __IO uint8_t soft_rst; // 0x7F: SOFT_RST - //------------- Extended -------------// + //------------- Target Endpoints (multipoint option) -------------// __IO uint16_t ctuch; // 0x80: CTUCH __IO uint16_t cthsrtn; // 0x82: CTHSRTN __R uint32_t rsv_0x84_0xff[31]; // 0x84-0xFF: Reserved - //------------- Absolute CSR (used index to remap to Indexed above) -------------// + //------------- Non-Indexed Endpoint CSRs -------------// // TI tm4c can access this directly, but should use indexed_csr for portability musb_ep_csr_t ep_csr[16]; // 0x100-0x1FF: EP0-15 CSR } musb_regs_t; @@ -185,267 +274,151 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ return &musb_regs->indexed_csr; } -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_FADDR register. -// -//***************************************************************************** -#define USB_FADDR_M 0x0000007F // Function Address -#define USB_FADDR_S 0 +//--------------------------------------------------------------------+ +// Register Bit Field +//--------------------------------------------------------------------+ -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_POWER register. -// -//***************************************************************************** -#define USB_POWER_ISOUP 0x00000080 // Isochronous Update -#define USB_POWER_SOFTCONN 0x00000040 // Soft Connect/Disconnect -#define USB_POWER_HSENAB 0x00000020 // High Speed Enable -#define USB_POWER_HSMODE 0x00000010 // High Speed Enable -#define USB_POWER_RESET 0x00000008 // RESET Signaling -#define USB_POWER_RESUME 0x00000004 // RESUME Signaling -#define USB_POWER_SUSPEND 0x00000002 // SUSPEND Mode -#define USB_POWER_PWRDNPHY 0x00000001 // Power Down PHY +// 0x01: Power +#define USB_POWER_ISOUP 0x0080 // Isochronous Update +#define USB_POWER_SOFTCONN 0x0040 // Soft Connect/Disconnect +#define USB_POWER_HSENAB 0x0020 // High Speed Enable +#define USB_POWER_HSMODE 0x0010 // High Speed Enable +#define USB_POWER_RESET 0x0008 // RESET Signaling +#define USB_POWER_RESUME 0x0004 // RESUME Signaling +#define USB_POWER_SUSPEND 0x0002 // SUSPEND Mode +#define USB_POWER_PWRDNPHY 0x0001 // Power Down PHY -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXIS register. -// -//***************************************************************************** -#define USB_TXIS_EP7 0x00000080 // TX Endpoint 7 Interrupt -#define USB_TXIS_EP6 0x00000040 // TX Endpoint 6 Interrupt -#define USB_TXIS_EP5 0x00000020 // TX Endpoint 5 Interrupt -#define USB_TXIS_EP4 0x00000010 // TX Endpoint 4 Interrupt -#define USB_TXIS_EP3 0x00000008 // TX Endpoint 3 Interrupt -#define USB_TXIS_EP2 0x00000004 // TX Endpoint 2 Interrupt -#define USB_TXIS_EP1 0x00000002 // TX Endpoint 1 Interrupt -#define USB_TXIS_EP0 0x00000001 // TX and RX Endpoint 0 Interrupt +// Interrupt TX/RX Status and Enable: each bit is for an endpoint -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXIS register. -// -//***************************************************************************** -#define USB_RXIS_EP7 0x00000080 // RX Endpoint 7 Interrupt -#define USB_RXIS_EP6 0x00000040 // RX Endpoint 6 Interrupt -#define USB_RXIS_EP5 0x00000020 // RX Endpoint 5 Interrupt -#define USB_RXIS_EP4 0x00000010 // RX Endpoint 4 Interrupt -#define USB_RXIS_EP3 0x00000008 // RX Endpoint 3 Interrupt -#define USB_RXIS_EP2 0x00000004 // RX Endpoint 2 Interrupt -#define USB_RXIS_EP1 0x00000002 // RX Endpoint 1 Interrupt +// 0x6c: HWVERS +#define MUSB_HWVERS_RC_SHIFT 15 +#define MUSB_HWVERS_RC_MASK 0x8000 +#define MUSB_HWVERS_MAJOR_SHIFT 10 +#define MUSB_HWVERS_MAJOR_MASK 0x7C00 +#define MUSB_HWVERS_MINOR_SHIFT 0 +#define MUSB_HWVERS_MINOR_MASK 0x03FF -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXIE register. -// -//***************************************************************************** -#define USB_TXIE_EP7 0x00000080 // TX Endpoint 7 Interrupt Enable -#define USB_TXIE_EP6 0x00000040 // TX Endpoint 6 Interrupt Enable -#define USB_TXIE_EP5 0x00000020 // TX Endpoint 5 Interrupt Enable -#define USB_TXIE_EP4 0x00000010 // TX Endpoint 4 Interrupt Enable -#define USB_TXIE_EP3 0x00000008 // TX Endpoint 3 Interrupt Enable -#define USB_TXIE_EP2 0x00000004 // TX Endpoint 2 Interrupt Enable -#define USB_TXIE_EP1 0x00000002 // TX Endpoint 1 Interrupt Enable -#define USB_TXIE_EP0 0x00000001 // TX and RX Endpoint 0 Interrupt - // Enable +// 0x12, 0x16: TX/RX CSRL +#define MUSB_CSRL_PACKET_READY(_rx) (1u << 0) +#define MUSB_CSRL_FLUSH_FIFO(_rx) (1u << ((_rx) ? 4 : 3)) +#define MUSB_CSRL_SEND_STALL(_rx) (1u << ((_rx) ? 5 : 4)) +#define MUSB_CSRL_SENT_STALL(_rx) (1u << ((_rx) ? 6 : 5)) +#define MUSB_CSRL_CLEAR_DATA_TOGGLE(_rx) (1u << ((_rx) ? 7 : 6)) + +// 0x13, 0x17: TX/RX CSRH +#define MUSB_CSRH_DISABLE_DOUBLE_PACKET(_rx) (1u << 1) -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXIE register. -// -//***************************************************************************** -#define USB_RXIE_EP7 0x00000080 // RX Endpoint 7 Interrupt Enable -#define USB_RXIE_EP6 0x00000040 // RX Endpoint 6 Interrupt Enable -#define USB_RXIE_EP5 0x00000020 // RX Endpoint 5 Interrupt Enable -#define USB_RXIE_EP4 0x00000010 // RX Endpoint 4 Interrupt Enable -#define USB_RXIE_EP3 0x00000008 // RX Endpoint 3 Interrupt Enable -#define USB_RXIE_EP2 0x00000004 // RX Endpoint 2 Interrupt Enable -#define USB_RXIE_EP1 0x00000002 // RX Endpoint 1 Interrupt Enable //***************************************************************************** // // The following are defines for the bit fields in the USB_O_IS register. // //***************************************************************************** -#define USB_IS_VBUSERR 0x00000080 // VBUS Error (OTG only) -#define USB_IS_SESREQ 0x00000040 // SESSION REQUEST (OTG only) -#define USB_IS_DISCON 0x00000020 // Session Disconnect (OTG only) -#define USB_IS_CONN 0x00000010 // Session Connect -#define USB_IS_SOF 0x00000008 // Start of Frame -#define USB_IS_BABBLE 0x00000004 // Babble Detected -#define USB_IS_RESET 0x00000004 // RESET Signaling Detected -#define USB_IS_RESUME 0x00000002 // RESUME Signaling Detected -#define USB_IS_SUSPEND 0x00000001 // SUSPEND Signaling Detected +#define USB_IS_VBUSERR 0x0080 // VBUS Error (OTG only) +#define USB_IS_SESREQ 0x0040 // SESSION REQUEST (OTG only) +#define USB_IS_DISCON 0x0020 // Session Disconnect (OTG only) +#define USB_IS_CONN 0x0010 // Session Connect +#define USB_IS_SOF 0x0008 // Start of Frame +#define USB_IS_BABBLE 0x0004 // Babble Detected +#define USB_IS_RESET 0x0004 // RESET Signaling Detected +#define USB_IS_RESUME 0x0002 // RESUME Signaling Detected +#define USB_IS_SUSPEND 0x0001 // SUSPEND Signaling Detected //***************************************************************************** // // The following are defines for the bit fields in the USB_O_IE register. // //***************************************************************************** -#define USB_IE_VBUSERR 0x00000080 // Enable VBUS Error Interrupt (OTG - // only) -#define USB_IE_SESREQ 0x00000040 // Enable Session Request (OTG - // only) -#define USB_IE_DISCON 0x00000020 // Enable Disconnect Interrupt -#define USB_IE_CONN 0x00000010 // Enable Connect Interrupt -#define USB_IE_SOF 0x00000008 // Enable Start-of-Frame Interrupt -#define USB_IE_BABBLE 0x00000004 // Enable Babble Interrupt -#define USB_IE_RESET 0x00000004 // Enable RESET Interrupt -#define USB_IE_RESUME 0x00000002 // Enable RESUME Interrupt -#define USB_IE_SUSPND 0x00000001 // Enable SUSPEND Interrupt +#define USB_IE_VBUSERR 0x0080 // Enable VBUS Error Interrupt (OTG only) +#define USB_IE_SESREQ 0x0040 // Enable Session Request (OTG only) +#define USB_IE_DISCON 0x0020 // Enable Disconnect Interrupt +#define USB_IE_CONN 0x0010 // Enable Connect Interrupt +#define USB_IE_SOF 0x0008 // Enable Start-of-Frame Interrupt +#define USB_IE_BABBLE 0x0004 // Enable Babble Interrupt +#define USB_IE_RESET 0x0004 // Enable RESET Interrupt +#define USB_IE_RESUME 0x0002 // Enable RESUME Interrupt +#define USB_IE_SUSPND 0x0001 // Enable SUSPEND Interrupt //***************************************************************************** // // The following are defines for the bit fields in the USB_O_FRAME register. // //***************************************************************************** -#define USB_FRAME_M 0x000007FF // Frame Number +#define USB_FRAME_M 0x07FF // Frame Number #define USB_FRAME_S 0 -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_EPIDX register. -// -//***************************************************************************** -#define USB_EPIDX_EPIDX_M 0x0000000F // Endpoint Index -#define USB_EPIDX_EPIDX_S 0 - //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TEST register. // //***************************************************************************** -#define USB_TEST_FORCEH 0x00000080 // Force Host Mode -#define USB_TEST_FIFOACC 0x00000040 // FIFO Access -#define USB_TEST_FORCEFS 0x00000020 // Force Full-Speed Mode -#define USB_TEST_FORCEHS 0x00000010 // Force High-Speed Mode -#define USB_TEST_TESTPKT 0x00000008 // Test Packet Mode Enable -#define USB_TEST_TESTK 0x00000004 // Test_K Mode Enable -#define USB_TEST_TESTJ 0x00000002 // Test_J Mode Enable -#define USB_TEST_TESTSE0NAK 0x00000001 // Test_SE0_NAK Test Mode Enable - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_FIFO0 register. -// -//***************************************************************************** -#define USB_FIFO0_EPDATA_M 0xFFFFFFFF // Endpoint Data -#define USB_FIFO0_EPDATA_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_FIFO1 register. -// -//***************************************************************************** -#define USB_FIFO1_EPDATA_M 0xFFFFFFFF // Endpoint Data -#define USB_FIFO1_EPDATA_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_FIFO2 register. -// -//***************************************************************************** -#define USB_FIFO2_EPDATA_M 0xFFFFFFFF // Endpoint Data -#define USB_FIFO2_EPDATA_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_FIFO3 register. -// -//***************************************************************************** -#define USB_FIFO3_EPDATA_M 0xFFFFFFFF // Endpoint Data -#define USB_FIFO3_EPDATA_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_FIFO4 register. -// -//***************************************************************************** -#define USB_FIFO4_EPDATA_M 0xFFFFFFFF // Endpoint Data -#define USB_FIFO4_EPDATA_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_FIFO5 register. -// -//***************************************************************************** -#define USB_FIFO5_EPDATA_M 0xFFFFFFFF // Endpoint Data -#define USB_FIFO5_EPDATA_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_FIFO6 register. -// -//***************************************************************************** -#define USB_FIFO6_EPDATA_M 0xFFFFFFFF // Endpoint Data -#define USB_FIFO6_EPDATA_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_FIFO7 register. -// -//***************************************************************************** -#define USB_FIFO7_EPDATA_M 0xFFFFFFFF // Endpoint Data -#define USB_FIFO7_EPDATA_S 0 +#define USB_TEST_FORCEH 0x0080 // Force Host Mode +#define USB_TEST_FIFOACC 0x0040 // FIFO Access +#define USB_TEST_FORCEFS 0x0020 // Force Full-Speed Mode +#define USB_TEST_FORCEHS 0x0010 // Force High-Speed Mode +#define USB_TEST_TESTPKT 0x0008 // Test Packet Mode Enable +#define USB_TEST_TESTK 0x0004 // Test_K Mode Enable +#define USB_TEST_TESTJ 0x0002 // Test_J Mode Enable +#define USB_TEST_TESTSE0NAK 0x0001 // Test_SE0_NAK Test Mode Enable //***************************************************************************** // // The following are defines for the bit fields in the USB_O_DEVCTL register. // //***************************************************************************** -#define USB_DEVCTL_DEV 0x00000080 // Device Mode (OTG only) -#define USB_DEVCTL_FSDEV 0x00000040 // Full-Speed Device Detected -#define USB_DEVCTL_LSDEV 0x00000020 // Low-Speed Device Detected -#define USB_DEVCTL_VBUS_M 0x00000018 // VBUS Level (OTG only) -#define USB_DEVCTL_VBUS_NONE 0x00000000 // Below SessionEnd -#define USB_DEVCTL_VBUS_SEND 0x00000008 // Above SessionEnd, below AValid -#define USB_DEVCTL_VBUS_AVALID 0x00000010 // Above AValid, below VBUSValid -#define USB_DEVCTL_VBUS_VALID 0x00000018 // Above VBUSValid -#define USB_DEVCTL_HOST 0x00000004 // Host Mode -#define USB_DEVCTL_HOSTREQ 0x00000002 // Host Request (OTG only) -#define USB_DEVCTL_SESSION 0x00000001 // Session Start/End (OTG only) +#define USB_DEVCTL_DEV 0x0080 // Device Mode (OTG only) +#define USB_DEVCTL_FSDEV 0x0040 // Full-Speed Device Detected +#define USB_DEVCTL_LSDEV 0x0020 // Low-Speed Device Detected +#define USB_DEVCTL_VBUS_M 0x0018 // VBUS Level (OTG only) +#define USB_DEVCTL_VBUS_NONE 0x0000 // Below SessionEnd +#define USB_DEVCTL_VBUS_SEND 0x0008 // Above SessionEnd, below AValid +#define USB_DEVCTL_VBUS_AVALID 0x0010 // Above AValid, below VBUSValid +#define USB_DEVCTL_VBUS_VALID 0x0018 // Above VBUSValid +#define USB_DEVCTL_HOST 0x0004 // Host Mode +#define USB_DEVCTL_HOSTREQ 0x0002 // Host Request (OTG only) +#define USB_DEVCTL_SESSION 0x0001 // Session Start/End (OTG only) //***************************************************************************** // // The following are defines for the bit fields in the USB_O_CCONF register. // //***************************************************************************** -#define USB_CCONF_TXEDMA 0x00000002 // TX Early DMA Enable -#define USB_CCONF_RXEDMA 0x00000001 // TX Early DMA Enable +#define USB_CCONF_TXEDMA 0x0002 // TX Early DMA Enable +#define USB_CCONF_RXEDMA 0x0001 // TX Early DMA Enable //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXFIFOSZ register. // //***************************************************************************** -#define USB_TXFIFOSZ_DPB 0x00000010 // Double Packet Buffer Support -#define USB_TXFIFOSZ_SIZE_M 0x0000000F // Max Packet Size -#define USB_TXFIFOSZ_SIZE_8 0x00000000 // 8 -#define USB_TXFIFOSZ_SIZE_16 0x00000001 // 16 -#define USB_TXFIFOSZ_SIZE_32 0x00000002 // 32 -#define USB_TXFIFOSZ_SIZE_64 0x00000003 // 64 -#define USB_TXFIFOSZ_SIZE_128 0x00000004 // 128 -#define USB_TXFIFOSZ_SIZE_256 0x00000005 // 256 -#define USB_TXFIFOSZ_SIZE_512 0x00000006 // 512 -#define USB_TXFIFOSZ_SIZE_1024 0x00000007 // 1024 -#define USB_TXFIFOSZ_SIZE_2048 0x00000008 // 2048 +#define USB_TXFIFOSZ_DPB 0x0010 // Double Packet Buffer Support +#define USB_TXFIFOSZ_SIZE_M 0x000F // Max Packet Size +#define USB_TXFIFOSZ_SIZE_8 0x0000 // 8 +#define USB_TXFIFOSZ_SIZE_16 0x0001 // 16 +#define USB_TXFIFOSZ_SIZE_32 0x0002 // 32 +#define USB_TXFIFOSZ_SIZE_64 0x0003 // 64 +#define USB_TXFIFOSZ_SIZE_128 0x0004 // 128 +#define USB_TXFIFOSZ_SIZE_256 0x0005 // 256 +#define USB_TXFIFOSZ_SIZE_512 0x0006 // 512 +#define USB_TXFIFOSZ_SIZE_1024 0x0007 // 1024 +#define USB_TXFIFOSZ_SIZE_2048 0x0008 // 2048 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXFIFOSZ register. // //***************************************************************************** -#define USB_RXFIFOSZ_DPB 0x00000010 // Double Packet Buffer Support -#define USB_RXFIFOSZ_SIZE_M 0x0000000F // Max Packet Size -#define USB_RXFIFOSZ_SIZE_8 0x00000000 // 8 -#define USB_RXFIFOSZ_SIZE_16 0x00000001 // 16 -#define USB_RXFIFOSZ_SIZE_32 0x00000002 // 32 -#define USB_RXFIFOSZ_SIZE_64 0x00000003 // 64 -#define USB_RXFIFOSZ_SIZE_128 0x00000004 // 128 -#define USB_RXFIFOSZ_SIZE_256 0x00000005 // 256 -#define USB_RXFIFOSZ_SIZE_512 0x00000006 // 512 -#define USB_RXFIFOSZ_SIZE_1024 0x00000007 // 1024 -#define USB_RXFIFOSZ_SIZE_2048 0x00000008 // 2048 +#define USB_RXFIFOSZ_DPB 0x0010 // Double Packet Buffer Support +#define USB_RXFIFOSZ_SIZE_M 0x000F // Max Packet Size +#define USB_RXFIFOSZ_SIZE_8 0x0000 // 8 +#define USB_RXFIFOSZ_SIZE_16 0x0001 // 16 +#define USB_RXFIFOSZ_SIZE_32 0x0002 // 32 +#define USB_RXFIFOSZ_SIZE_64 0x0003 // 64 +#define USB_RXFIFOSZ_SIZE_128 0x0004 // 128 +#define USB_RXFIFOSZ_SIZE_256 0x0005 // 256 +#define USB_RXFIFOSZ_SIZE_512 0x0006 // 512 +#define USB_RXFIFOSZ_SIZE_1024 0x0007 // 1024 +#define USB_RXFIFOSZ_SIZE_2048 0x0008 // 2048 //***************************************************************************** // @@ -453,7 +426,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_TXFIFOADD_ADDR_M 0x000001FF // Transmit/Receive Start Address +#define USB_TXFIFOADD_ADDR_M 0x01FF // Transmit/Receive Start Address #define USB_TXFIFOADD_ADDR_S 0 //***************************************************************************** @@ -462,7 +435,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RXFIFOADD_ADDR_M 0x000001FF // Transmit/Receive Start Address +#define USB_RXFIFOADD_ADDR_M 0x01FF // Transmit/Receive Start Address #define USB_RXFIFOADD_ADDR_S 0 //***************************************************************************** @@ -471,10 +444,8 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_ULPIVBUSCTL_USEEXTVBUSIND \ - 0x00000002 // Use External VBUS Indicator -#define USB_ULPIVBUSCTL_USEEXTVBUS \ - 0x00000001 // Use External VBUS +#define USB_ULPIVBUSCTL_USEEXTVBUSIND 0x0002 // Use External VBUS Indicator +#define USB_ULPIVBUSCTL_USEEXTVBUS 0x0001 // Use External VBUS //***************************************************************************** // @@ -482,18 +453,15 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_ULPIREGDATA_REGDATA_M \ - 0x000000FF // Register Data -#define USB_ULPIREGDATA_REGDATA_S \ - 0 - +#define USB_ULPIREGDATA_REGDATA_M 0x00FF // Register Data +#define USB_ULPIREGDATA_REGDATA_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_ULPIREGADDR // register. // //***************************************************************************** -#define USB_ULPIREGADDR_ADDR_M 0x000000FF // Register Address +#define USB_ULPIREGADDR_ADDR_M 0x00FF // Register Address #define USB_ULPIREGADDR_ADDR_S 0 //***************************************************************************** @@ -502,17 +470,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_ULPIREGCTL_RDWR 0x00000004 // Read/Write Control -#define USB_ULPIREGCTL_REGCMPLT 0x00000002 // Register Access Complete -#define USB_ULPIREGCTL_REGACC 0x00000001 // Initiate Register Access +#define USB_ULPIREGCTL_RDWR 0x0004 // Read/Write Control +#define USB_ULPIREGCTL_REGCMPLT 0x0002 // Register Access Complete +#define USB_ULPIREGCTL_REGACC 0x0001 // Initiate Register Access //***************************************************************************** // // The following are defines for the bit fields in the USB_O_EPINFO register. // //***************************************************************************** -#define USB_EPINFO_RXEP_M 0x000000F0 // RX Endpoints -#define USB_EPINFO_TXEP_M 0x0000000F // TX Endpoints +#define USB_EPINFO_RXEP_M 0x00F0 // RX Endpoints +#define USB_EPINFO_TXEP_M 0x000F // TX Endpoints #define USB_EPINFO_RXEP_S 4 #define USB_EPINFO_TXEP_S 0 @@ -521,8 +489,8 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RAMINFO register. // //***************************************************************************** -#define USB_RAMINFO_DMACHAN_M 0x000000F0 // DMA Channels -#define USB_RAMINFO_RAMBITS_M 0x0000000F // RAM Address Bus Width +#define USB_RAMINFO_DMACHAN_M 0x00F0 // DMA Channels +#define USB_RAMINFO_RAMBITS_M 0x000F // RAM Address Bus Width #define USB_RAMINFO_DMACHAN_S 4 #define USB_RAMINFO_RAMBITS_S 0 @@ -531,8 +499,8 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_CONTIM register. // //***************************************************************************** -#define USB_CONTIM_WTCON_M 0x000000F0 // Connect Wait -#define USB_CONTIM_WTID_M 0x0000000F // Wait ID +#define USB_CONTIM_WTCON_M 0x00F0 // Connect Wait +#define USB_CONTIM_WTID_M 0x000F // Wait ID #define USB_CONTIM_WTCON_S 4 #define USB_CONTIM_WTID_S 0 @@ -541,7 +509,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_VPLEN register. // //***************************************************************************** -#define USB_VPLEN_VPLEN_M 0x000000FF // VBUS Pulse Length +#define USB_VPLEN_VPLEN_M 0x00FF // VBUS Pulse Length #define USB_VPLEN_VPLEN_S 0 //***************************************************************************** @@ -549,7 +517,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_HSEOF register. // //***************************************************************************** -#define USB_HSEOF_HSEOFG_M 0x000000FF // HIgh-Speed End-of-Frame Gap +#define USB_HSEOF_HSEOFG_M 0x00FF // HIgh-Speed End-of-Frame Gap #define USB_HSEOF_HSEOFG_S 0 //***************************************************************************** @@ -557,7 +525,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_FSEOF register. // //***************************************************************************** -#define USB_FSEOF_FSEOFG_M 0x000000FF // Full-Speed End-of-Frame Gap +#define USB_FSEOF_FSEOFG_M 0x00FF // Full-Speed End-of-Frame Gap #define USB_FSEOF_FSEOFG_S 0 //***************************************************************************** @@ -565,449 +533,44 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_LSEOF register. // //***************************************************************************** -#define USB_LSEOF_LSEOFG_M 0x000000FF // Low-Speed End-of-Frame Gap +#define USB_LSEOF_LSEOFG_M 0x00FF // Low-Speed End-of-Frame Gap #define USB_LSEOF_LSEOFG_S 0 -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXFUNCADDR0 -// register. -// -//***************************************************************************** -#define USB_TXFUNCADDR0_ADDR_M 0x0000007F // Device Address -#define USB_TXFUNCADDR0_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBADDR0 -// register. -// -//***************************************************************************** -#define USB_TXHUBADDR0_ADDR_M 0x0000007F // Hub Address -#define USB_TXHUBADDR0_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBPORT0 -// register. -// -//***************************************************************************** -#define USB_TXHUBPORT0_PORT_M 0x0000007F // Hub Port -#define USB_TXHUBPORT0_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXFUNCADDR1 -// register. -// -//***************************************************************************** -#define USB_TXFUNCADDR1_ADDR_M 0x0000007F // Device Address -#define USB_TXFUNCADDR1_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBADDR1 -// register. -// -//***************************************************************************** -#define USB_TXHUBADDR1_ADDR_M 0x0000007F // Hub Address -#define USB_TXHUBADDR1_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBPORT1 -// register. -// -//***************************************************************************** -#define USB_TXHUBPORT1_PORT_M 0x0000007F // Hub Port -#define USB_TXHUBPORT1_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXFUNCADDR1 -// register. -// -//***************************************************************************** -#define USB_RXFUNCADDR1_ADDR_M 0x0000007F // Device Address -#define USB_RXFUNCADDR1_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBADDR1 -// register. -// -//***************************************************************************** -#define USB_RXHUBADDR1_ADDR_M 0x0000007F // Hub Address -#define USB_RXHUBADDR1_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBPORT1 -// register. -// -//***************************************************************************** -#define USB_RXHUBPORT1_PORT_M 0x0000007F // Hub Port -#define USB_RXHUBPORT1_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXFUNCADDR2 -// register. -// -//***************************************************************************** -#define USB_TXFUNCADDR2_ADDR_M 0x0000007F // Device Address -#define USB_TXFUNCADDR2_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBADDR2 -// register. -// -//***************************************************************************** -#define USB_TXHUBADDR2_ADDR_M 0x0000007F // Hub Address -#define USB_TXHUBADDR2_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBPORT2 -// register. -// -//***************************************************************************** -#define USB_TXHUBPORT2_PORT_M 0x0000007F // Hub Port -#define USB_TXHUBPORT2_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXFUNCADDR2 -// register. -// -//***************************************************************************** -#define USB_RXFUNCADDR2_ADDR_M 0x0000007F // Device Address -#define USB_RXFUNCADDR2_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBADDR2 -// register. -// -//***************************************************************************** -#define USB_RXHUBADDR2_ADDR_M 0x0000007F // Hub Address -#define USB_RXHUBADDR2_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBPORT2 -// register. -// -//***************************************************************************** -#define USB_RXHUBPORT2_PORT_M 0x0000007F // Hub Port -#define USB_RXHUBPORT2_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXFUNCADDR3 -// register. -// -//***************************************************************************** -#define USB_TXFUNCADDR3_ADDR_M 0x0000007F // Device Address -#define USB_TXFUNCADDR3_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBADDR3 -// register. -// -//***************************************************************************** -#define USB_TXHUBADDR3_ADDR_M 0x0000007F // Hub Address -#define USB_TXHUBADDR3_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBPORT3 -// register. -// -//***************************************************************************** -#define USB_TXHUBPORT3_PORT_M 0x0000007F // Hub Port -#define USB_TXHUBPORT3_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXFUNCADDR3 -// register. -// -//***************************************************************************** -#define USB_RXFUNCADDR3_ADDR_M 0x0000007F // Device Address -#define USB_RXFUNCADDR3_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBADDR3 -// register. -// -//***************************************************************************** -#define USB_RXHUBADDR3_ADDR_M 0x0000007F // Hub Address -#define USB_RXHUBADDR3_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBPORT3 -// register. -// -//***************************************************************************** -#define USB_RXHUBPORT3_PORT_M 0x0000007F // Hub Port -#define USB_RXHUBPORT3_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXFUNCADDR4 -// register. -// -//***************************************************************************** -#define USB_TXFUNCADDR4_ADDR_M 0x0000007F // Device Address -#define USB_TXFUNCADDR4_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBADDR4 -// register. -// -//***************************************************************************** -#define USB_TXHUBADDR4_ADDR_M 0x0000007F // Hub Address -#define USB_TXHUBADDR4_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBPORT4 -// register. -// -//***************************************************************************** -#define USB_TXHUBPORT4_PORT_M 0x0000007F // Hub Port -#define USB_TXHUBPORT4_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXFUNCADDR4 -// register. -// -//***************************************************************************** -#define USB_RXFUNCADDR4_ADDR_M 0x0000007F // Device Address -#define USB_RXFUNCADDR4_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBADDR4 -// register. -// -//***************************************************************************** -#define USB_RXHUBADDR4_ADDR_M 0x0000007F // Hub Address -#define USB_RXHUBADDR4_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBPORT4 -// register. -// -//***************************************************************************** -#define USB_RXHUBPORT4_PORT_M 0x0000007F // Hub Port -#define USB_RXHUBPORT4_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXFUNCADDR5 -// register. -// -//***************************************************************************** -#define USB_TXFUNCADDR5_ADDR_M 0x0000007F // Device Address -#define USB_TXFUNCADDR5_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBADDR5 -// register. -// -//***************************************************************************** -#define USB_TXHUBADDR5_ADDR_M 0x0000007F // Hub Address -#define USB_TXHUBADDR5_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBPORT5 -// register. -// -//***************************************************************************** -#define USB_TXHUBPORT5_PORT_M 0x0000007F // Hub Port -#define USB_TXHUBPORT5_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXFUNCADDR5 -// register. -// -//***************************************************************************** -#define USB_RXFUNCADDR5_ADDR_M 0x0000007F // Device Address -#define USB_RXFUNCADDR5_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBADDR5 -// register. -// -//***************************************************************************** -#define USB_RXHUBADDR5_ADDR_M 0x0000007F // Hub Address -#define USB_RXHUBADDR5_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBPORT5 -// register. -// -//***************************************************************************** -#define USB_RXHUBPORT5_PORT_M 0x0000007F // Hub Port -#define USB_RXHUBPORT5_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXFUNCADDR6 -// register. -// -//***************************************************************************** -#define USB_TXFUNCADDR6_ADDR_M 0x0000007F // Device Address -#define USB_TXFUNCADDR6_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBADDR6 -// register. -// -//***************************************************************************** -#define USB_TXHUBADDR6_ADDR_M 0x0000007F // Hub Address -#define USB_TXHUBADDR6_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBPORT6 -// register. -// -//***************************************************************************** -#define USB_TXHUBPORT6_PORT_M 0x0000007F // Hub Port -#define USB_TXHUBPORT6_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXFUNCADDR6 -// register. -// -//***************************************************************************** -#define USB_RXFUNCADDR6_ADDR_M 0x0000007F // Device Address -#define USB_RXFUNCADDR6_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBADDR6 -// register. -// -//***************************************************************************** -#define USB_RXHUBADDR6_ADDR_M 0x0000007F // Hub Address -#define USB_RXHUBADDR6_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBPORT6 -// register. -// -//***************************************************************************** -#define USB_RXHUBPORT6_PORT_M 0x0000007F // Hub Port -#define USB_RXHUBPORT6_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXFUNCADDR7 -// register. -// -//***************************************************************************** -#define USB_TXFUNCADDR7_ADDR_M 0x0000007F // Device Address -#define USB_TXFUNCADDR7_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBADDR7 -// register. -// -//***************************************************************************** -#define USB_TXHUBADDR7_ADDR_M 0x0000007F // Hub Address -#define USB_TXHUBADDR7_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXHUBPORT7 -// register. -// -//***************************************************************************** -#define USB_TXHUBPORT7_PORT_M 0x0000007F // Hub Port -#define USB_TXHUBPORT7_PORT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXFUNCADDR7 -// register. -// -//***************************************************************************** -#define USB_RXFUNCADDR7_ADDR_M 0x0000007F // Device Address -#define USB_RXFUNCADDR7_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBADDR7 -// register. -// -//***************************************************************************** -#define USB_RXHUBADDR7_ADDR_M 0x0000007F // Hub Address -#define USB_RXHUBADDR7_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXHUBPORT7 -// register. -// -//***************************************************************************** -#define USB_RXHUBPORT7_PORT_M 0x0000007F // Hub Port -#define USB_RXHUBPORT7_PORT_S 0 - //***************************************************************************** // // The following are defines for the bit fields in the USB_O_CSRL0 register. // //***************************************************************************** -#define USB_CSRL0_NAKTO 0x00000080 // NAK Timeout -#define USB_CSRL0_SETENDC 0x00000080 // Setup End Clear -#define USB_CSRL0_STATUS 0x00000040 // STATUS Packet -#define USB_CSRL0_RXRDYC 0x00000040 // RXRDY Clear -#define USB_CSRL0_REQPKT 0x00000020 // Request Packet -#define USB_CSRL0_STALL 0x00000020 // Send Stall -#define USB_CSRL0_SETEND 0x00000010 // Setup End -#define USB_CSRL0_ERROR 0x00000010 // Error -#define USB_CSRL0_DATAEND 0x00000008 // Data End -#define USB_CSRL0_SETUP 0x00000008 // Setup Packet -#define USB_CSRL0_STALLED 0x00000004 // Endpoint Stalled -#define USB_CSRL0_TXRDY 0x00000002 // Transmit Packet Ready -#define USB_CSRL0_RXRDY 0x00000001 // Receive Packet Ready +#define USB_CSRL0_NAKTO 0x0080 // NAK Timeout +#define USB_CSRL0_SETENDC 0x0080 // Setup End Clear +#define USB_CSRL0_STATUS 0x0040 // STATUS Packet +#define USB_CSRL0_RXRDYC 0x0040 // RXRDY Clear +#define USB_CSRL0_REQPKT 0x0020 // Request Packet +#define USB_CSRL0_STALL 0x0020 // Send Stall +#define USB_CSRL0_SETEND 0x0010 // Setup End +#define USB_CSRL0_ERROR 0x0010 // Error +#define USB_CSRL0_DATAEND 0x0008 // Data End +#define USB_CSRL0_SETUP 0x0008 // Setup Packet +#define USB_CSRL0_STALLED 0x0004 // Endpoint Stalled +#define USB_CSRL0_TXRDY 0x0002 // Transmit Packet Ready +#define USB_CSRL0_RXRDY 0x0001 // Receive Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_CSRH0 register. // //***************************************************************************** -#define USB_CSRH0_DISPING 0x00000008 // PING Disable -#define USB_CSRH0_DTWE 0x00000004 // Data Toggle Write Enable -#define USB_CSRH0_DT 0x00000002 // Data Toggle -#define USB_CSRH0_FLUSH 0x00000001 // Flush FIFO +#define USB_CSRH0_DISPING 0x0008 // PING Disable +#define USB_CSRH0_DTWE 0x0004 // Data Toggle Write Enable +#define USB_CSRH0_DT 0x0002 // Data Toggle +#define USB_CSRH0_FLUSH 0x0001 // Flush FIFO //***************************************************************************** // // The following are defines for the bit fields in the USB_O_COUNT0 register. // //***************************************************************************** -#define USB_COUNT0_COUNT_M 0x0000007F // FIFO Count +#define USB_COUNT0_COUNT_M 0x007F // FIFO Count #define USB_COUNT0_COUNT_S 0 //***************************************************************************** @@ -1015,17 +578,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TYPE0 register. // //***************************************************************************** -#define USB_TYPE0_SPEED_M 0x000000C0 // Operating Speed -#define USB_TYPE0_SPEED_HIGH 0x00000040 // High -#define USB_TYPE0_SPEED_FULL 0x00000080 // Full -#define USB_TYPE0_SPEED_LOW 0x000000C0 // Low +#define USB_TYPE0_SPEED_M 0x00C0 // Operating Speed +#define USB_TYPE0_SPEED_HIGH 0x0040 // High +#define USB_TYPE0_SPEED_FULL 0x0080 // Full +#define USB_TYPE0_SPEED_LOW 0x00C0 // Low //***************************************************************************** // // The following are defines for the bit fields in the USB_O_NAKLMT register. // //***************************************************************************** -#define USB_NAKLMT_NAKLMT_M 0x0000001F // EP0 NAK Limit +#define USB_NAKLMT_NAKLMT_M 0x001F // EP0 NAK Limit #define USB_NAKLMT_NAKLMT_S 0 //***************************************************************************** @@ -1033,7 +596,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXMAXP1 register. // //***************************************************************************** -#define USB_TXMAXP1_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_TXMAXP1_MAXLOAD_M 0x07FF // Maximum Payload #define USB_TXMAXP1_MAXLOAD_S 0 //***************************************************************************** @@ -1041,37 +604,37 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXCSRL1 register. // //***************************************************************************** -#define USB_TXCSRL1_NAKTO 0x00000080 // NAK Timeout -#define USB_TXCSRL1_CLRDT 0x00000040 // Clear Data Toggle -#define USB_TXCSRL1_STALLED 0x00000020 // Endpoint Stalled -#define USB_TXCSRL1_STALL 0x00000010 // Send STALL -#define USB_TXCSRL1_SETUP 0x00000010 // Setup Packet -#define USB_TXCSRL1_FLUSH 0x00000008 // Flush FIFO -#define USB_TXCSRL1_ERROR 0x00000004 // Error -#define USB_TXCSRL1_UNDRN 0x00000004 // Underrun -#define USB_TXCSRL1_FIFONE 0x00000002 // FIFO Not Empty -#define USB_TXCSRL1_TXRDY 0x00000001 // Transmit Packet Ready +#define USB_TXCSRL1_NAKTO 0x0080 // NAK Timeout +#define USB_TXCSRL1_CLRDT 0x0040 // Clear Data Toggle +#define USB_TXCSRL1_STALLED 0x0020 // Endpoint Stalled +#define USB_TXCSRL1_STALL 0x0010 // Send STALL +#define USB_TXCSRL1_SETUP 0x0010 // Setup Packet +#define USB_TXCSRL1_FLUSH 0x0008 // Flush FIFO +#define USB_TXCSRL1_ERROR 0x0004 // Error +#define USB_TXCSRL1_UNDRN 0x0004 // Underrun +#define USB_TXCSRL1_FIFONE 0x0002 // FIFO Not Empty +#define USB_TXCSRL1_TXRDY 0x0001 // Transmit Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXCSRH1 register. // //***************************************************************************** -#define USB_TXCSRH1_AUTOSET 0x00000080 // Auto Set -#define USB_TXCSRH1_ISO 0x00000040 // Isochronous Transfers -#define USB_TXCSRH1_MODE 0x00000020 // Mode -#define USB_TXCSRH1_DMAEN 0x00000010 // DMA Request Enable -#define USB_TXCSRH1_FDT 0x00000008 // Force Data Toggle -#define USB_TXCSRH1_DMAMOD 0x00000004 // DMA Request Mode -#define USB_TXCSRH1_DTWE 0x00000002 // Data Toggle Write Enable -#define USB_TXCSRH1_DT 0x00000001 // Data Toggle +#define USB_TXCSRH1_AUTOSET 0x0080 // Auto Set +#define USB_TXCSRH1_ISO 0x0040 // Isochronous Transfers +#define USB_TXCSRH1_MODE 0x0020 // Mode +#define USB_TXCSRH1_DMAEN 0x0010 // DMA Request Enable +#define USB_TXCSRH1_FDT 0x0008 // Force Data Toggle +#define USB_TXCSRH1_DMAMOD 0x0004 // DMA Request Mode +#define USB_TXCSRH1_DTWE 0x0002 // Data Toggle Write Enable +#define USB_TXCSRH1_DT 0x0001 // Data Toggle //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXMAXP1 register. // //***************************************************************************** -#define USB_RXMAXP1_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_RXMAXP1_MAXLOAD_M 0x07FF // Maximum Payload #define USB_RXMAXP1_MAXLOAD_S 0 //***************************************************************************** @@ -1079,33 +642,33 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCSRL1 register. // //***************************************************************************** -#define USB_RXCSRL1_CLRDT 0x00000080 // Clear Data Toggle -#define USB_RXCSRL1_STALLED 0x00000040 // Endpoint Stalled -#define USB_RXCSRL1_STALL 0x00000020 // Send STALL -#define USB_RXCSRL1_REQPKT 0x00000020 // Request Packet -#define USB_RXCSRL1_FLUSH 0x00000010 // Flush FIFO -#define USB_RXCSRL1_DATAERR 0x00000008 // Data Error -#define USB_RXCSRL1_NAKTO 0x00000008 // NAK Timeout -#define USB_RXCSRL1_OVER 0x00000004 // Overrun -#define USB_RXCSRL1_ERROR 0x00000004 // Error -#define USB_RXCSRL1_FULL 0x00000002 // FIFO Full -#define USB_RXCSRL1_RXRDY 0x00000001 // Receive Packet Ready +#define USB_RXCSRL1_CLRDT 0x0080 // Clear Data Toggle +#define USB_RXCSRL1_STALLED 0x0040 // Endpoint Stalled +#define USB_RXCSRL1_STALL 0x0020 // Send STALL +#define USB_RXCSRL1_REQPKT 0x0020 // Request Packet +#define USB_RXCSRL1_FLUSH 0x0010 // Flush FIFO +#define USB_RXCSRL1_DATAERR 0x0008 // Data Error +#define USB_RXCSRL1_NAKTO 0x0008 // NAK Timeout +#define USB_RXCSRL1_OVER 0x0004 // Overrun +#define USB_RXCSRL1_ERROR 0x0004 // Error +#define USB_RXCSRL1_FULL 0x0002 // FIFO Full +#define USB_RXCSRL1_RXRDY 0x0001 // Receive Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXCSRH1 register. // //***************************************************************************** -#define USB_RXCSRH1_AUTOCL 0x00000080 // Auto Clear -#define USB_RXCSRH1_AUTORQ 0x00000040 // Auto Request -#define USB_RXCSRH1_ISO 0x00000040 // Isochronous Transfers -#define USB_RXCSRH1_DMAEN 0x00000020 // DMA Request Enable -#define USB_RXCSRH1_DISNYET 0x00000010 // Disable NYET -#define USB_RXCSRH1_PIDERR 0x00000010 // PID Error -#define USB_RXCSRH1_DMAMOD 0x00000008 // DMA Request Mode -#define USB_RXCSRH1_DTWE 0x00000004 // Data Toggle Write Enable -#define USB_RXCSRH1_DT 0x00000002 // Data Toggle -#define USB_RXCSRH1_INCOMPRX 0x00000001 // Incomplete RX Transmission +#define USB_RXCSRH1_AUTOCL 0x0080 // Auto Clear +#define USB_RXCSRH1_AUTORQ 0x0040 // Auto Request +#define USB_RXCSRH1_ISO 0x0040 // Isochronous Transfers +#define USB_RXCSRH1_DMAEN 0x0020 // DMA Request Enable +#define USB_RXCSRH1_DISNYET 0x0010 // Disable NYET +#define USB_RXCSRH1_PIDERR 0x0010 // PID Error +#define USB_RXCSRH1_DMAMOD 0x0008 // DMA Request Mode +#define USB_RXCSRH1_DTWE 0x0004 // Data Toggle Write Enable +#define USB_RXCSRH1_DT 0x0002 // Data Toggle +#define USB_RXCSRH1_INCOMPRX 0x0001 // Incomplete RX Transmission // Status //***************************************************************************** @@ -1113,7 +676,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCOUNT1 register. // //***************************************************************************** -#define USB_RXCOUNT1_COUNT_M 0x00001FFF // Receive Packet Count +#define USB_RXCOUNT1_COUNT_M 0x1FFF // Receive Packet Count #define USB_RXCOUNT1_COUNT_S 0 //***************************************************************************** @@ -1121,17 +684,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXTYPE1 register. // //***************************************************************************** -#define USB_TXTYPE1_SPEED_M 0x000000C0 // Operating Speed -#define USB_TXTYPE1_SPEED_DFLT 0x00000000 // Default -#define USB_TXTYPE1_SPEED_HIGH 0x00000040 // High -#define USB_TXTYPE1_SPEED_FULL 0x00000080 // Full -#define USB_TXTYPE1_SPEED_LOW 0x000000C0 // Low -#define USB_TXTYPE1_PROTO_M 0x00000030 // Protocol -#define USB_TXTYPE1_PROTO_CTRL 0x00000000 // Control -#define USB_TXTYPE1_PROTO_ISOC 0x00000010 // Isochronous -#define USB_TXTYPE1_PROTO_BULK 0x00000020 // Bulk -#define USB_TXTYPE1_PROTO_INT 0x00000030 // Interrupt -#define USB_TXTYPE1_TEP_M 0x0000000F // Target Endpoint Number +#define USB_TXTYPE1_SPEED_M 0x00C0 // Operating Speed +#define USB_TXTYPE1_SPEED_DFLT 0x0000 // Default +#define USB_TXTYPE1_SPEED_HIGH 0x0040 // High +#define USB_TXTYPE1_SPEED_FULL 0x0080 // Full +#define USB_TXTYPE1_SPEED_LOW 0x00C0 // Low +#define USB_TXTYPE1_PROTO_M 0x0030 // Protocol +#define USB_TXTYPE1_PROTO_CTRL 0x0000 // Control +#define USB_TXTYPE1_PROTO_ISOC 0x0010 // Isochronous +#define USB_TXTYPE1_PROTO_BULK 0x0020 // Bulk +#define USB_TXTYPE1_PROTO_INT 0x0030 // Interrupt +#define USB_TXTYPE1_TEP_M 0x000F // Target Endpoint Number #define USB_TXTYPE1_TEP_S 0 //***************************************************************************** @@ -1140,31 +703,27 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_TXINTERVAL1_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_TXINTERVAL1_TXPOLL_M \ - 0x000000FF // TX Polling -#define USB_TXINTERVAL1_TXPOLL_S \ - 0 -#define USB_TXINTERVAL1_NAKLMT_S \ - 0 +#define USB_TXINTERVAL1_NAKLMT_M 0x00FF // NAK Limit +#define USB_TXINTERVAL1_TXPOLL_M 0x00FF // TX Polling +#define USB_TXINTERVAL1_TXPOLL_S 0 +#define USB_TXINTERVAL1_NAKLMT_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXTYPE1 register. // //***************************************************************************** -#define USB_RXTYPE1_SPEED_M 0x000000C0 // Operating Speed -#define USB_RXTYPE1_SPEED_DFLT 0x00000000 // Default -#define USB_RXTYPE1_SPEED_HIGH 0x00000040 // High -#define USB_RXTYPE1_SPEED_FULL 0x00000080 // Full -#define USB_RXTYPE1_SPEED_LOW 0x000000C0 // Low -#define USB_RXTYPE1_PROTO_M 0x00000030 // Protocol -#define USB_RXTYPE1_PROTO_CTRL 0x00000000 // Control -#define USB_RXTYPE1_PROTO_ISOC 0x00000010 // Isochronous -#define USB_RXTYPE1_PROTO_BULK 0x00000020 // Bulk -#define USB_RXTYPE1_PROTO_INT 0x00000030 // Interrupt -#define USB_RXTYPE1_TEP_M 0x0000000F // Target Endpoint Number +#define USB_RXTYPE1_SPEED_M 0x00C0 // Operating Speed +#define USB_RXTYPE1_SPEED_DFLT 0x0000 // Default +#define USB_RXTYPE1_SPEED_HIGH 0x0040 // High +#define USB_RXTYPE1_SPEED_FULL 0x0080 // Full +#define USB_RXTYPE1_SPEED_LOW 0x00C0 // Low +#define USB_RXTYPE1_PROTO_M 0x0030 // Protocol +#define USB_RXTYPE1_PROTO_CTRL 0x0000 // Control +#define USB_RXTYPE1_PROTO_ISOC 0x0010 // Isochronous +#define USB_RXTYPE1_PROTO_BULK 0x0020 // Bulk +#define USB_RXTYPE1_PROTO_INT 0x0030 // Interrupt +#define USB_RXTYPE1_TEP_M 0x000F // Target Endpoint Number #define USB_RXTYPE1_TEP_S 0 //***************************************************************************** @@ -1173,21 +732,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RXINTERVAL1_TXPOLL_M \ - 0x000000FF // RX Polling -#define USB_RXINTERVAL1_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_RXINTERVAL1_TXPOLL_S \ - 0 -#define USB_RXINTERVAL1_NAKLMT_S \ - 0 +#define USB_RXINTERVAL1_TXPOLL_M 0x00FF // RX Polling +#define USB_RXINTERVAL1_NAKLMT_M 0x00FF // NAK Limit +#define USB_RXINTERVAL1_TXPOLL_S 0 +#define USB_RXINTERVAL1_NAKLMT_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXMAXP2 register. // //***************************************************************************** -#define USB_TXMAXP2_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_TXMAXP2_MAXLOAD_M 0x07FF // Maximum Payload #define USB_TXMAXP2_MAXLOAD_S 0 //***************************************************************************** @@ -1195,37 +750,37 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXCSRL2 register. // //***************************************************************************** -#define USB_TXCSRL2_NAKTO 0x00000080 // NAK Timeout -#define USB_TXCSRL2_CLRDT 0x00000040 // Clear Data Toggle -#define USB_TXCSRL2_STALLED 0x00000020 // Endpoint Stalled -#define USB_TXCSRL2_SETUP 0x00000010 // Setup Packet -#define USB_TXCSRL2_STALL 0x00000010 // Send STALL -#define USB_TXCSRL2_FLUSH 0x00000008 // Flush FIFO -#define USB_TXCSRL2_ERROR 0x00000004 // Error -#define USB_TXCSRL2_UNDRN 0x00000004 // Underrun -#define USB_TXCSRL2_FIFONE 0x00000002 // FIFO Not Empty -#define USB_TXCSRL2_TXRDY 0x00000001 // Transmit Packet Ready +#define USB_TXCSRL2_NAKTO 0x0080 // NAK Timeout +#define USB_TXCSRL2_CLRDT 0x0040 // Clear Data Toggle +#define USB_TXCSRL2_STALLED 0x0020 // Endpoint Stalled +#define USB_TXCSRL2_SETUP 0x0010 // Setup Packet +#define USB_TXCSRL2_STALL 0x0010 // Send STALL +#define USB_TXCSRL2_FLUSH 0x0008 // Flush FIFO +#define USB_TXCSRL2_ERROR 0x0004 // Error +#define USB_TXCSRL2_UNDRN 0x0004 // Underrun +#define USB_TXCSRL2_FIFONE 0x0002 // FIFO Not Empty +#define USB_TXCSRL2_TXRDY 0x0001 // Transmit Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXCSRH2 register. // //***************************************************************************** -#define USB_TXCSRH2_AUTOSET 0x00000080 // Auto Set -#define USB_TXCSRH2_ISO 0x00000040 // Isochronous Transfers -#define USB_TXCSRH2_MODE 0x00000020 // Mode -#define USB_TXCSRH2_DMAEN 0x00000010 // DMA Request Enable -#define USB_TXCSRH2_FDT 0x00000008 // Force Data Toggle -#define USB_TXCSRH2_DMAMOD 0x00000004 // DMA Request Mode -#define USB_TXCSRH2_DTWE 0x00000002 // Data Toggle Write Enable -#define USB_TXCSRH2_DT 0x00000001 // Data Toggle +#define USB_TXCSRH2_AUTOSET 0x0080 // Auto Set +#define USB_TXCSRH2_ISO 0x0040 // Isochronous Transfers +#define USB_TXCSRH2_MODE 0x0020 // Mode +#define USB_TXCSRH2_DMAEN 0x0010 // DMA Request Enable +#define USB_TXCSRH2_FDT 0x0008 // Force Data Toggle +#define USB_TXCSRH2_DMAMOD 0x0004 // DMA Request Mode +#define USB_TXCSRH2_DTWE 0x0002 // Data Toggle Write Enable +#define USB_TXCSRH2_DT 0x0001 // Data Toggle //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXMAXP2 register. // //***************************************************************************** -#define USB_RXMAXP2_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_RXMAXP2_MAXLOAD_M 0x07FF // Maximum Payload #define USB_RXMAXP2_MAXLOAD_S 0 //***************************************************************************** @@ -1233,33 +788,33 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCSRL2 register. // //***************************************************************************** -#define USB_RXCSRL2_CLRDT 0x00000080 // Clear Data Toggle -#define USB_RXCSRL2_STALLED 0x00000040 // Endpoint Stalled -#define USB_RXCSRL2_REQPKT 0x00000020 // Request Packet -#define USB_RXCSRL2_STALL 0x00000020 // Send STALL -#define USB_RXCSRL2_FLUSH 0x00000010 // Flush FIFO -#define USB_RXCSRL2_DATAERR 0x00000008 // Data Error -#define USB_RXCSRL2_NAKTO 0x00000008 // NAK Timeout -#define USB_RXCSRL2_ERROR 0x00000004 // Error -#define USB_RXCSRL2_OVER 0x00000004 // Overrun -#define USB_RXCSRL2_FULL 0x00000002 // FIFO Full -#define USB_RXCSRL2_RXRDY 0x00000001 // Receive Packet Ready +#define USB_RXCSRL2_CLRDT 0x0080 // Clear Data Toggle +#define USB_RXCSRL2_STALLED 0x0040 // Endpoint Stalled +#define USB_RXCSRL2_REQPKT 0x0020 // Request Packet +#define USB_RXCSRL2_STALL 0x0020 // Send STALL +#define USB_RXCSRL2_FLUSH 0x0010 // Flush FIFO +#define USB_RXCSRL2_DATAERR 0x0008 // Data Error +#define USB_RXCSRL2_NAKTO 0x0008 // NAK Timeout +#define USB_RXCSRL2_ERROR 0x0004 // Error +#define USB_RXCSRL2_OVER 0x0004 // Overrun +#define USB_RXCSRL2_FULL 0x0002 // FIFO Full +#define USB_RXCSRL2_RXRDY 0x0001 // Receive Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXCSRH2 register. // //***************************************************************************** -#define USB_RXCSRH2_AUTOCL 0x00000080 // Auto Clear -#define USB_RXCSRH2_AUTORQ 0x00000040 // Auto Request -#define USB_RXCSRH2_ISO 0x00000040 // Isochronous Transfers -#define USB_RXCSRH2_DMAEN 0x00000020 // DMA Request Enable -#define USB_RXCSRH2_DISNYET 0x00000010 // Disable NYET -#define USB_RXCSRH2_PIDERR 0x00000010 // PID Error -#define USB_RXCSRH2_DMAMOD 0x00000008 // DMA Request Mode -#define USB_RXCSRH2_DTWE 0x00000004 // Data Toggle Write Enable -#define USB_RXCSRH2_DT 0x00000002 // Data Toggle -#define USB_RXCSRH2_INCOMPRX 0x00000001 // Incomplete RX Transmission +#define USB_RXCSRH2_AUTOCL 0x0080 // Auto Clear +#define USB_RXCSRH2_AUTORQ 0x0040 // Auto Request +#define USB_RXCSRH2_ISO 0x0040 // Isochronous Transfers +#define USB_RXCSRH2_DMAEN 0x0020 // DMA Request Enable +#define USB_RXCSRH2_DISNYET 0x0010 // Disable NYET +#define USB_RXCSRH2_PIDERR 0x0010 // PID Error +#define USB_RXCSRH2_DMAMOD 0x0008 // DMA Request Mode +#define USB_RXCSRH2_DTWE 0x0004 // Data Toggle Write Enable +#define USB_RXCSRH2_DT 0x0002 // Data Toggle +#define USB_RXCSRH2_INCOMPRX 0x0001 // Incomplete RX Transmission // Status //***************************************************************************** @@ -1267,7 +822,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCOUNT2 register. // //***************************************************************************** -#define USB_RXCOUNT2_COUNT_M 0x00001FFF // Receive Packet Count +#define USB_RXCOUNT2_COUNT_M 0x1FFF // Receive Packet Count #define USB_RXCOUNT2_COUNT_S 0 //***************************************************************************** @@ -1275,17 +830,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXTYPE2 register. // //***************************************************************************** -#define USB_TXTYPE2_SPEED_M 0x000000C0 // Operating Speed -#define USB_TXTYPE2_SPEED_DFLT 0x00000000 // Default -#define USB_TXTYPE2_SPEED_HIGH 0x00000040 // High -#define USB_TXTYPE2_SPEED_FULL 0x00000080 // Full -#define USB_TXTYPE2_SPEED_LOW 0x000000C0 // Low -#define USB_TXTYPE2_PROTO_M 0x00000030 // Protocol -#define USB_TXTYPE2_PROTO_CTRL 0x00000000 // Control -#define USB_TXTYPE2_PROTO_ISOC 0x00000010 // Isochronous -#define USB_TXTYPE2_PROTO_BULK 0x00000020 // Bulk -#define USB_TXTYPE2_PROTO_INT 0x00000030 // Interrupt -#define USB_TXTYPE2_TEP_M 0x0000000F // Target Endpoint Number +#define USB_TXTYPE2_SPEED_M 0x00C0 // Operating Speed +#define USB_TXTYPE2_SPEED_DFLT 0x0000 // Default +#define USB_TXTYPE2_SPEED_HIGH 0x0040 // High +#define USB_TXTYPE2_SPEED_FULL 0x0080 // Full +#define USB_TXTYPE2_SPEED_LOW 0x00C0 // Low +#define USB_TXTYPE2_PROTO_M 0x0030 // Protocol +#define USB_TXTYPE2_PROTO_CTRL 0x0000 // Control +#define USB_TXTYPE2_PROTO_ISOC 0x0010 // Isochronous +#define USB_TXTYPE2_PROTO_BULK 0x0020 // Bulk +#define USB_TXTYPE2_PROTO_INT 0x0030 // Interrupt +#define USB_TXTYPE2_TEP_M 0x000F // Target Endpoint Number #define USB_TXTYPE2_TEP_S 0 //***************************************************************************** @@ -1294,31 +849,27 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_TXINTERVAL2_TXPOLL_M \ - 0x000000FF // TX Polling -#define USB_TXINTERVAL2_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_TXINTERVAL2_NAKLMT_S \ - 0 -#define USB_TXINTERVAL2_TXPOLL_S \ - 0 +#define USB_TXINTERVAL2_TXPOLL_M 0x00FF // TX Polling +#define USB_TXINTERVAL2_NAKLMT_M 0x00FF // NAK Limit +#define USB_TXINTERVAL2_NAKLMT_S 0 +#define USB_TXINTERVAL2_TXPOLL_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXTYPE2 register. // //***************************************************************************** -#define USB_RXTYPE2_SPEED_M 0x000000C0 // Operating Speed -#define USB_RXTYPE2_SPEED_DFLT 0x00000000 // Default -#define USB_RXTYPE2_SPEED_HIGH 0x00000040 // High -#define USB_RXTYPE2_SPEED_FULL 0x00000080 // Full -#define USB_RXTYPE2_SPEED_LOW 0x000000C0 // Low -#define USB_RXTYPE2_PROTO_M 0x00000030 // Protocol -#define USB_RXTYPE2_PROTO_CTRL 0x00000000 // Control -#define USB_RXTYPE2_PROTO_ISOC 0x00000010 // Isochronous -#define USB_RXTYPE2_PROTO_BULK 0x00000020 // Bulk -#define USB_RXTYPE2_PROTO_INT 0x00000030 // Interrupt -#define USB_RXTYPE2_TEP_M 0x0000000F // Target Endpoint Number +#define USB_RXTYPE2_SPEED_M 0x00C0 // Operating Speed +#define USB_RXTYPE2_SPEED_DFLT 0x0000 // Default +#define USB_RXTYPE2_SPEED_HIGH 0x0040 // High +#define USB_RXTYPE2_SPEED_FULL 0x0080 // Full +#define USB_RXTYPE2_SPEED_LOW 0x00C0 // Low +#define USB_RXTYPE2_PROTO_M 0x0030 // Protocol +#define USB_RXTYPE2_PROTO_CTRL 0x0000 // Control +#define USB_RXTYPE2_PROTO_ISOC 0x0010 // Isochronous +#define USB_RXTYPE2_PROTO_BULK 0x0020 // Bulk +#define USB_RXTYPE2_PROTO_INT 0x0030 // Interrupt +#define USB_RXTYPE2_TEP_M 0x000F // Target Endpoint Number #define USB_RXTYPE2_TEP_S 0 //***************************************************************************** @@ -1327,21 +878,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RXINTERVAL2_TXPOLL_M \ - 0x000000FF // RX Polling -#define USB_RXINTERVAL2_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_RXINTERVAL2_TXPOLL_S \ - 0 -#define USB_RXINTERVAL2_NAKLMT_S \ - 0 +#define USB_RXINTERVAL2_TXPOLL_M 0x00FF // RX Polling +#define USB_RXINTERVAL2_NAKLMT_M 0x00FF // NAK Limit +#define USB_RXINTERVAL2_TXPOLL_S 0 +#define USB_RXINTERVAL2_NAKLMT_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXMAXP3 register. // //***************************************************************************** -#define USB_TXMAXP3_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_TXMAXP3_MAXLOAD_M 0x07FF // Maximum Payload #define USB_TXMAXP3_MAXLOAD_S 0 //***************************************************************************** @@ -1349,37 +896,37 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXCSRL3 register. // //***************************************************************************** -#define USB_TXCSRL3_NAKTO 0x00000080 // NAK Timeout -#define USB_TXCSRL3_CLRDT 0x00000040 // Clear Data Toggle -#define USB_TXCSRL3_STALLED 0x00000020 // Endpoint Stalled -#define USB_TXCSRL3_SETUP 0x00000010 // Setup Packet -#define USB_TXCSRL3_STALL 0x00000010 // Send STALL -#define USB_TXCSRL3_FLUSH 0x00000008 // Flush FIFO -#define USB_TXCSRL3_ERROR 0x00000004 // Error -#define USB_TXCSRL3_UNDRN 0x00000004 // Underrun -#define USB_TXCSRL3_FIFONE 0x00000002 // FIFO Not Empty -#define USB_TXCSRL3_TXRDY 0x00000001 // Transmit Packet Ready +#define USB_TXCSRL3_NAKTO 0x0080 // NAK Timeout +#define USB_TXCSRL3_CLRDT 0x0040 // Clear Data Toggle +#define USB_TXCSRL3_STALLED 0x0020 // Endpoint Stalled +#define USB_TXCSRL3_SETUP 0x0010 // Setup Packet +#define USB_TXCSRL3_STALL 0x0010 // Send STALL +#define USB_TXCSRL3_FLUSH 0x0008 // Flush FIFO +#define USB_TXCSRL3_ERROR 0x0004 // Error +#define USB_TXCSRL3_UNDRN 0x0004 // Underrun +#define USB_TXCSRL3_FIFONE 0x0002 // FIFO Not Empty +#define USB_TXCSRL3_TXRDY 0x0001 // Transmit Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXCSRH3 register. // //***************************************************************************** -#define USB_TXCSRH3_AUTOSET 0x00000080 // Auto Set -#define USB_TXCSRH3_ISO 0x00000040 // Isochronous Transfers -#define USB_TXCSRH3_MODE 0x00000020 // Mode -#define USB_TXCSRH3_DMAEN 0x00000010 // DMA Request Enable -#define USB_TXCSRH3_FDT 0x00000008 // Force Data Toggle -#define USB_TXCSRH3_DMAMOD 0x00000004 // DMA Request Mode -#define USB_TXCSRH3_DTWE 0x00000002 // Data Toggle Write Enable -#define USB_TXCSRH3_DT 0x00000001 // Data Toggle +#define USB_TXCSRH3_AUTOSET 0x0080 // Auto Set +#define USB_TXCSRH3_ISO 0x0040 // Isochronous Transfers +#define USB_TXCSRH3_MODE 0x0020 // Mode +#define USB_TXCSRH3_DMAEN 0x0010 // DMA Request Enable +#define USB_TXCSRH3_FDT 0x0008 // Force Data Toggle +#define USB_TXCSRH3_DMAMOD 0x0004 // DMA Request Mode +#define USB_TXCSRH3_DTWE 0x0002 // Data Toggle Write Enable +#define USB_TXCSRH3_DT 0x0001 // Data Toggle //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXMAXP3 register. // //***************************************************************************** -#define USB_RXMAXP3_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_RXMAXP3_MAXLOAD_M 0x07FF // Maximum Payload #define USB_RXMAXP3_MAXLOAD_S 0 //***************************************************************************** @@ -1387,33 +934,33 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCSRL3 register. // //***************************************************************************** -#define USB_RXCSRL3_CLRDT 0x00000080 // Clear Data Toggle -#define USB_RXCSRL3_STALLED 0x00000040 // Endpoint Stalled -#define USB_RXCSRL3_STALL 0x00000020 // Send STALL -#define USB_RXCSRL3_REQPKT 0x00000020 // Request Packet -#define USB_RXCSRL3_FLUSH 0x00000010 // Flush FIFO -#define USB_RXCSRL3_DATAERR 0x00000008 // Data Error -#define USB_RXCSRL3_NAKTO 0x00000008 // NAK Timeout -#define USB_RXCSRL3_ERROR 0x00000004 // Error -#define USB_RXCSRL3_OVER 0x00000004 // Overrun -#define USB_RXCSRL3_FULL 0x00000002 // FIFO Full -#define USB_RXCSRL3_RXRDY 0x00000001 // Receive Packet Ready +#define USB_RXCSRL3_CLRDT 0x0080 // Clear Data Toggle +#define USB_RXCSRL3_STALLED 0x0040 // Endpoint Stalled +#define USB_RXCSRL3_STALL 0x0020 // Send STALL +#define USB_RXCSRL3_REQPKT 0x0020 // Request Packet +#define USB_RXCSRL3_FLUSH 0x0010 // Flush FIFO +#define USB_RXCSRL3_DATAERR 0x0008 // Data Error +#define USB_RXCSRL3_NAKTO 0x0008 // NAK Timeout +#define USB_RXCSRL3_ERROR 0x0004 // Error +#define USB_RXCSRL3_OVER 0x0004 // Overrun +#define USB_RXCSRL3_FULL 0x0002 // FIFO Full +#define USB_RXCSRL3_RXRDY 0x0001 // Receive Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXCSRH3 register. // //***************************************************************************** -#define USB_RXCSRH3_AUTOCL 0x00000080 // Auto Clear -#define USB_RXCSRH3_AUTORQ 0x00000040 // Auto Request -#define USB_RXCSRH3_ISO 0x00000040 // Isochronous Transfers -#define USB_RXCSRH3_DMAEN 0x00000020 // DMA Request Enable -#define USB_RXCSRH3_DISNYET 0x00000010 // Disable NYET -#define USB_RXCSRH3_PIDERR 0x00000010 // PID Error -#define USB_RXCSRH3_DMAMOD 0x00000008 // DMA Request Mode -#define USB_RXCSRH3_DTWE 0x00000004 // Data Toggle Write Enable -#define USB_RXCSRH3_DT 0x00000002 // Data Toggle -#define USB_RXCSRH3_INCOMPRX 0x00000001 // Incomplete RX Transmission +#define USB_RXCSRH3_AUTOCL 0x0080 // Auto Clear +#define USB_RXCSRH3_AUTORQ 0x0040 // Auto Request +#define USB_RXCSRH3_ISO 0x0040 // Isochronous Transfers +#define USB_RXCSRH3_DMAEN 0x0020 // DMA Request Enable +#define USB_RXCSRH3_DISNYET 0x0010 // Disable NYET +#define USB_RXCSRH3_PIDERR 0x0010 // PID Error +#define USB_RXCSRH3_DMAMOD 0x0008 // DMA Request Mode +#define USB_RXCSRH3_DTWE 0x0004 // Data Toggle Write Enable +#define USB_RXCSRH3_DT 0x0002 // Data Toggle +#define USB_RXCSRH3_INCOMPRX 0x0001 // Incomplete RX Transmission // Status //***************************************************************************** @@ -1421,7 +968,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCOUNT3 register. // //***************************************************************************** -#define USB_RXCOUNT3_COUNT_M 0x00001FFF // Receive Packet Count +#define USB_RXCOUNT3_COUNT_M 0x1FFF // Receive Packet Count #define USB_RXCOUNT3_COUNT_S 0 //***************************************************************************** @@ -1429,17 +976,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXTYPE3 register. // //***************************************************************************** -#define USB_TXTYPE3_SPEED_M 0x000000C0 // Operating Speed -#define USB_TXTYPE3_SPEED_DFLT 0x00000000 // Default -#define USB_TXTYPE3_SPEED_HIGH 0x00000040 // High -#define USB_TXTYPE3_SPEED_FULL 0x00000080 // Full -#define USB_TXTYPE3_SPEED_LOW 0x000000C0 // Low -#define USB_TXTYPE3_PROTO_M 0x00000030 // Protocol -#define USB_TXTYPE3_PROTO_CTRL 0x00000000 // Control -#define USB_TXTYPE3_PROTO_ISOC 0x00000010 // Isochronous -#define USB_TXTYPE3_PROTO_BULK 0x00000020 // Bulk -#define USB_TXTYPE3_PROTO_INT 0x00000030 // Interrupt -#define USB_TXTYPE3_TEP_M 0x0000000F // Target Endpoint Number +#define USB_TXTYPE3_SPEED_M 0x00C0 // Operating Speed +#define USB_TXTYPE3_SPEED_DFLT 0x0000 // Default +#define USB_TXTYPE3_SPEED_HIGH 0x0040 // High +#define USB_TXTYPE3_SPEED_FULL 0x0080 // Full +#define USB_TXTYPE3_SPEED_LOW 0x00C0 // Low +#define USB_TXTYPE3_PROTO_M 0x0030 // Protocol +#define USB_TXTYPE3_PROTO_CTRL 0x0000 // Control +#define USB_TXTYPE3_PROTO_ISOC 0x0010 // Isochronous +#define USB_TXTYPE3_PROTO_BULK 0x0020 // Bulk +#define USB_TXTYPE3_PROTO_INT 0x0030 // Interrupt +#define USB_TXTYPE3_TEP_M 0x000F // Target Endpoint Number #define USB_TXTYPE3_TEP_S 0 //***************************************************************************** @@ -1448,31 +995,27 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_TXINTERVAL3_TXPOLL_M \ - 0x000000FF // TX Polling -#define USB_TXINTERVAL3_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_TXINTERVAL3_TXPOLL_S \ - 0 -#define USB_TXINTERVAL3_NAKLMT_S \ - 0 +#define USB_TXINTERVAL3_TXPOLL_M 0x00FF // TX Polling +#define USB_TXINTERVAL3_NAKLMT_M 0x00FF // NAK Limit +#define USB_TXINTERVAL3_TXPOLL_S 0 +#define USB_TXINTERVAL3_NAKLMT_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXTYPE3 register. // //***************************************************************************** -#define USB_RXTYPE3_SPEED_M 0x000000C0 // Operating Speed -#define USB_RXTYPE3_SPEED_DFLT 0x00000000 // Default -#define USB_RXTYPE3_SPEED_HIGH 0x00000040 // High -#define USB_RXTYPE3_SPEED_FULL 0x00000080 // Full -#define USB_RXTYPE3_SPEED_LOW 0x000000C0 // Low -#define USB_RXTYPE3_PROTO_M 0x00000030 // Protocol -#define USB_RXTYPE3_PROTO_CTRL 0x00000000 // Control -#define USB_RXTYPE3_PROTO_ISOC 0x00000010 // Isochronous -#define USB_RXTYPE3_PROTO_BULK 0x00000020 // Bulk -#define USB_RXTYPE3_PROTO_INT 0x00000030 // Interrupt -#define USB_RXTYPE3_TEP_M 0x0000000F // Target Endpoint Number +#define USB_RXTYPE3_SPEED_M 0x00C0 // Operating Speed +#define USB_RXTYPE3_SPEED_DFLT 0x0000 // Default +#define USB_RXTYPE3_SPEED_HIGH 0x0040 // High +#define USB_RXTYPE3_SPEED_FULL 0x0080 // Full +#define USB_RXTYPE3_SPEED_LOW 0x00C0 // Low +#define USB_RXTYPE3_PROTO_M 0x0030 // Protocol +#define USB_RXTYPE3_PROTO_CTRL 0x0000 // Control +#define USB_RXTYPE3_PROTO_ISOC 0x0010 // Isochronous +#define USB_RXTYPE3_PROTO_BULK 0x0020 // Bulk +#define USB_RXTYPE3_PROTO_INT 0x0030 // Interrupt +#define USB_RXTYPE3_TEP_M 0x000F // Target Endpoint Number #define USB_RXTYPE3_TEP_S 0 //***************************************************************************** @@ -1481,21 +1024,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RXINTERVAL3_TXPOLL_M \ - 0x000000FF // RX Polling -#define USB_RXINTERVAL3_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_RXINTERVAL3_TXPOLL_S \ - 0 -#define USB_RXINTERVAL3_NAKLMT_S \ - 0 +#define USB_RXINTERVAL3_TXPOLL_M 0x00FF // RX Polling +#define USB_RXINTERVAL3_NAKLMT_M 0x00FF // NAK Limit +#define USB_RXINTERVAL3_TXPOLL_S 0 +#define USB_RXINTERVAL3_NAKLMT_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXMAXP4 register. // //***************************************************************************** -#define USB_TXMAXP4_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_TXMAXP4_MAXLOAD_M 0x07FF // Maximum Payload #define USB_TXMAXP4_MAXLOAD_S 0 //***************************************************************************** @@ -1503,37 +1042,37 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXCSRL4 register. // //***************************************************************************** -#define USB_TXCSRL4_NAKTO 0x00000080 // NAK Timeout -#define USB_TXCSRL4_CLRDT 0x00000040 // Clear Data Toggle -#define USB_TXCSRL4_STALLED 0x00000020 // Endpoint Stalled -#define USB_TXCSRL4_SETUP 0x00000010 // Setup Packet -#define USB_TXCSRL4_STALL 0x00000010 // Send STALL -#define USB_TXCSRL4_FLUSH 0x00000008 // Flush FIFO -#define USB_TXCSRL4_ERROR 0x00000004 // Error -#define USB_TXCSRL4_UNDRN 0x00000004 // Underrun -#define USB_TXCSRL4_FIFONE 0x00000002 // FIFO Not Empty -#define USB_TXCSRL4_TXRDY 0x00000001 // Transmit Packet Ready +#define USB_TXCSRL4_NAKTO 0x0080 // NAK Timeout +#define USB_TXCSRL4_CLRDT 0x0040 // Clear Data Toggle +#define USB_TXCSRL4_STALLED 0x0020 // Endpoint Stalled +#define USB_TXCSRL4_SETUP 0x0010 // Setup Packet +#define USB_TXCSRL4_STALL 0x0010 // Send STALL +#define USB_TXCSRL4_FLUSH 0x0008 // Flush FIFO +#define USB_TXCSRL4_ERROR 0x0004 // Error +#define USB_TXCSRL4_UNDRN 0x0004 // Underrun +#define USB_TXCSRL4_FIFONE 0x0002 // FIFO Not Empty +#define USB_TXCSRL4_TXRDY 0x0001 // Transmit Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXCSRH4 register. // //***************************************************************************** -#define USB_TXCSRH4_AUTOSET 0x00000080 // Auto Set -#define USB_TXCSRH4_ISO 0x00000040 // Isochronous Transfers -#define USB_TXCSRH4_MODE 0x00000020 // Mode -#define USB_TXCSRH4_DMAEN 0x00000010 // DMA Request Enable -#define USB_TXCSRH4_FDT 0x00000008 // Force Data Toggle -#define USB_TXCSRH4_DMAMOD 0x00000004 // DMA Request Mode -#define USB_TXCSRH4_DTWE 0x00000002 // Data Toggle Write Enable -#define USB_TXCSRH4_DT 0x00000001 // Data Toggle +#define USB_TXCSRH4_AUTOSET 0x0080 // Auto Set +#define USB_TXCSRH4_ISO 0x0040 // Isochronous Transfers +#define USB_TXCSRH4_MODE 0x0020 // Mode +#define USB_TXCSRH4_DMAEN 0x0010 // DMA Request Enable +#define USB_TXCSRH4_FDT 0x0008 // Force Data Toggle +#define USB_TXCSRH4_DMAMOD 0x0004 // DMA Request Mode +#define USB_TXCSRH4_DTWE 0x0002 // Data Toggle Write Enable +#define USB_TXCSRH4_DT 0x0001 // Data Toggle //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXMAXP4 register. // //***************************************************************************** -#define USB_RXMAXP4_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_RXMAXP4_MAXLOAD_M 0x07FF // Maximum Payload #define USB_RXMAXP4_MAXLOAD_S 0 //***************************************************************************** @@ -1541,33 +1080,33 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCSRL4 register. // //***************************************************************************** -#define USB_RXCSRL4_CLRDT 0x00000080 // Clear Data Toggle -#define USB_RXCSRL4_STALLED 0x00000040 // Endpoint Stalled -#define USB_RXCSRL4_STALL 0x00000020 // Send STALL -#define USB_RXCSRL4_REQPKT 0x00000020 // Request Packet -#define USB_RXCSRL4_FLUSH 0x00000010 // Flush FIFO -#define USB_RXCSRL4_NAKTO 0x00000008 // NAK Timeout -#define USB_RXCSRL4_DATAERR 0x00000008 // Data Error -#define USB_RXCSRL4_OVER 0x00000004 // Overrun -#define USB_RXCSRL4_ERROR 0x00000004 // Error -#define USB_RXCSRL4_FULL 0x00000002 // FIFO Full -#define USB_RXCSRL4_RXRDY 0x00000001 // Receive Packet Ready +#define USB_RXCSRL4_CLRDT 0x0080 // Clear Data Toggle +#define USB_RXCSRL4_STALLED 0x0040 // Endpoint Stalled +#define USB_RXCSRL4_STALL 0x0020 // Send STALL +#define USB_RXCSRL4_REQPKT 0x0020 // Request Packet +#define USB_RXCSRL4_FLUSH 0x0010 // Flush FIFO +#define USB_RXCSRL4_NAKTO 0x0008 // NAK Timeout +#define USB_RXCSRL4_DATAERR 0x0008 // Data Error +#define USB_RXCSRL4_OVER 0x0004 // Overrun +#define USB_RXCSRL4_ERROR 0x0004 // Error +#define USB_RXCSRL4_FULL 0x0002 // FIFO Full +#define USB_RXCSRL4_RXRDY 0x0001 // Receive Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXCSRH4 register. // //***************************************************************************** -#define USB_RXCSRH4_AUTOCL 0x00000080 // Auto Clear -#define USB_RXCSRH4_AUTORQ 0x00000040 // Auto Request -#define USB_RXCSRH4_ISO 0x00000040 // Isochronous Transfers -#define USB_RXCSRH4_DMAEN 0x00000020 // DMA Request Enable -#define USB_RXCSRH4_DISNYET 0x00000010 // Disable NYET -#define USB_RXCSRH4_PIDERR 0x00000010 // PID Error -#define USB_RXCSRH4_DMAMOD 0x00000008 // DMA Request Mode -#define USB_RXCSRH4_DTWE 0x00000004 // Data Toggle Write Enable -#define USB_RXCSRH4_DT 0x00000002 // Data Toggle -#define USB_RXCSRH4_INCOMPRX 0x00000001 // Incomplete RX Transmission +#define USB_RXCSRH4_AUTOCL 0x0080 // Auto Clear +#define USB_RXCSRH4_AUTORQ 0x0040 // Auto Request +#define USB_RXCSRH4_ISO 0x0040 // Isochronous Transfers +#define USB_RXCSRH4_DMAEN 0x0020 // DMA Request Enable +#define USB_RXCSRH4_DISNYET 0x0010 // Disable NYET +#define USB_RXCSRH4_PIDERR 0x0010 // PID Error +#define USB_RXCSRH4_DMAMOD 0x0008 // DMA Request Mode +#define USB_RXCSRH4_DTWE 0x0004 // Data Toggle Write Enable +#define USB_RXCSRH4_DT 0x0002 // Data Toggle +#define USB_RXCSRH4_INCOMPRX 0x0001 // Incomplete RX Transmission // Status //***************************************************************************** @@ -1575,7 +1114,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCOUNT4 register. // //***************************************************************************** -#define USB_RXCOUNT4_COUNT_M 0x00001FFF // Receive Packet Count +#define USB_RXCOUNT4_COUNT_M 0x1FFF // Receive Packet Count #define USB_RXCOUNT4_COUNT_S 0 //***************************************************************************** @@ -1583,17 +1122,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXTYPE4 register. // //***************************************************************************** -#define USB_TXTYPE4_SPEED_M 0x000000C0 // Operating Speed -#define USB_TXTYPE4_SPEED_DFLT 0x00000000 // Default -#define USB_TXTYPE4_SPEED_HIGH 0x00000040 // High -#define USB_TXTYPE4_SPEED_FULL 0x00000080 // Full -#define USB_TXTYPE4_SPEED_LOW 0x000000C0 // Low -#define USB_TXTYPE4_PROTO_M 0x00000030 // Protocol -#define USB_TXTYPE4_PROTO_CTRL 0x00000000 // Control -#define USB_TXTYPE4_PROTO_ISOC 0x00000010 // Isochronous -#define USB_TXTYPE4_PROTO_BULK 0x00000020 // Bulk -#define USB_TXTYPE4_PROTO_INT 0x00000030 // Interrupt -#define USB_TXTYPE4_TEP_M 0x0000000F // Target Endpoint Number +#define USB_TXTYPE4_SPEED_M 0x00C0 // Operating Speed +#define USB_TXTYPE4_SPEED_DFLT 0x0000 // Default +#define USB_TXTYPE4_SPEED_HIGH 0x0040 // High +#define USB_TXTYPE4_SPEED_FULL 0x0080 // Full +#define USB_TXTYPE4_SPEED_LOW 0x00C0 // Low +#define USB_TXTYPE4_PROTO_M 0x0030 // Protocol +#define USB_TXTYPE4_PROTO_CTRL 0x0000 // Control +#define USB_TXTYPE4_PROTO_ISOC 0x0010 // Isochronous +#define USB_TXTYPE4_PROTO_BULK 0x0020 // Bulk +#define USB_TXTYPE4_PROTO_INT 0x0030 // Interrupt +#define USB_TXTYPE4_TEP_M 0x000F // Target Endpoint Number #define USB_TXTYPE4_TEP_S 0 //***************************************************************************** @@ -1602,31 +1141,27 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_TXINTERVAL4_TXPOLL_M \ - 0x000000FF // TX Polling -#define USB_TXINTERVAL4_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_TXINTERVAL4_NAKLMT_S \ - 0 -#define USB_TXINTERVAL4_TXPOLL_S \ - 0 +#define USB_TXINTERVAL4_TXPOLL_M 0x00FF // TX Polling +#define USB_TXINTERVAL4_NAKLMT_M 0x00FF // NAK Limit +#define USB_TXINTERVAL4_NAKLMT_S 0 +#define USB_TXINTERVAL4_TXPOLL_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXTYPE4 register. // //***************************************************************************** -#define USB_RXTYPE4_SPEED_M 0x000000C0 // Operating Speed -#define USB_RXTYPE4_SPEED_DFLT 0x00000000 // Default -#define USB_RXTYPE4_SPEED_HIGH 0x00000040 // High -#define USB_RXTYPE4_SPEED_FULL 0x00000080 // Full -#define USB_RXTYPE4_SPEED_LOW 0x000000C0 // Low -#define USB_RXTYPE4_PROTO_M 0x00000030 // Protocol -#define USB_RXTYPE4_PROTO_CTRL 0x00000000 // Control -#define USB_RXTYPE4_PROTO_ISOC 0x00000010 // Isochronous -#define USB_RXTYPE4_PROTO_BULK 0x00000020 // Bulk -#define USB_RXTYPE4_PROTO_INT 0x00000030 // Interrupt -#define USB_RXTYPE4_TEP_M 0x0000000F // Target Endpoint Number +#define USB_RXTYPE4_SPEED_M 0x00C0 // Operating Speed +#define USB_RXTYPE4_SPEED_DFLT 0x0000 // Default +#define USB_RXTYPE4_SPEED_HIGH 0x0040 // High +#define USB_RXTYPE4_SPEED_FULL 0x0080 // Full +#define USB_RXTYPE4_SPEED_LOW 0x00C0 // Low +#define USB_RXTYPE4_PROTO_M 0x0030 // Protocol +#define USB_RXTYPE4_PROTO_CTRL 0x0000 // Control +#define USB_RXTYPE4_PROTO_ISOC 0x0010 // Isochronous +#define USB_RXTYPE4_PROTO_BULK 0x0020 // Bulk +#define USB_RXTYPE4_PROTO_INT 0x0030 // Interrupt +#define USB_RXTYPE4_TEP_M 0x000F // Target Endpoint Number #define USB_RXTYPE4_TEP_S 0 //***************************************************************************** @@ -1635,21 +1170,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RXINTERVAL4_TXPOLL_M \ - 0x000000FF // RX Polling -#define USB_RXINTERVAL4_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_RXINTERVAL4_NAKLMT_S \ - 0 -#define USB_RXINTERVAL4_TXPOLL_S \ - 0 +#define USB_RXINTERVAL4_TXPOLL_M 0x00FF // RX Polling +#define USB_RXINTERVAL4_NAKLMT_M 0x00FF // NAK Limit +#define USB_RXINTERVAL4_NAKLMT_S 0 +#define USB_RXINTERVAL4_TXPOLL_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXMAXP5 register. // //***************************************************************************** -#define USB_TXMAXP5_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_TXMAXP5_MAXLOAD_M 0x07FF // Maximum Payload #define USB_TXMAXP5_MAXLOAD_S 0 //***************************************************************************** @@ -1657,37 +1188,37 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXCSRL5 register. // //***************************************************************************** -#define USB_TXCSRL5_NAKTO 0x00000080 // NAK Timeout -#define USB_TXCSRL5_CLRDT 0x00000040 // Clear Data Toggle -#define USB_TXCSRL5_STALLED 0x00000020 // Endpoint Stalled -#define USB_TXCSRL5_SETUP 0x00000010 // Setup Packet -#define USB_TXCSRL5_STALL 0x00000010 // Send STALL -#define USB_TXCSRL5_FLUSH 0x00000008 // Flush FIFO -#define USB_TXCSRL5_ERROR 0x00000004 // Error -#define USB_TXCSRL5_UNDRN 0x00000004 // Underrun -#define USB_TXCSRL5_FIFONE 0x00000002 // FIFO Not Empty -#define USB_TXCSRL5_TXRDY 0x00000001 // Transmit Packet Ready +#define USB_TXCSRL5_NAKTO 0x0080 // NAK Timeout +#define USB_TXCSRL5_CLRDT 0x0040 // Clear Data Toggle +#define USB_TXCSRL5_STALLED 0x0020 // Endpoint Stalled +#define USB_TXCSRL5_SETUP 0x0010 // Setup Packet +#define USB_TXCSRL5_STALL 0x0010 // Send STALL +#define USB_TXCSRL5_FLUSH 0x0008 // Flush FIFO +#define USB_TXCSRL5_ERROR 0x0004 // Error +#define USB_TXCSRL5_UNDRN 0x0004 // Underrun +#define USB_TXCSRL5_FIFONE 0x0002 // FIFO Not Empty +#define USB_TXCSRL5_TXRDY 0x0001 // Transmit Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXCSRH5 register. // //***************************************************************************** -#define USB_TXCSRH5_AUTOSET 0x00000080 // Auto Set -#define USB_TXCSRH5_ISO 0x00000040 // Isochronous Transfers -#define USB_TXCSRH5_MODE 0x00000020 // Mode -#define USB_TXCSRH5_DMAEN 0x00000010 // DMA Request Enable -#define USB_TXCSRH5_FDT 0x00000008 // Force Data Toggle -#define USB_TXCSRH5_DMAMOD 0x00000004 // DMA Request Mode -#define USB_TXCSRH5_DTWE 0x00000002 // Data Toggle Write Enable -#define USB_TXCSRH5_DT 0x00000001 // Data Toggle +#define USB_TXCSRH5_AUTOSET 0x0080 // Auto Set +#define USB_TXCSRH5_ISO 0x0040 // Isochronous Transfers +#define USB_TXCSRH5_MODE 0x0020 // Mode +#define USB_TXCSRH5_DMAEN 0x0010 // DMA Request Enable +#define USB_TXCSRH5_FDT 0x0008 // Force Data Toggle +#define USB_TXCSRH5_DMAMOD 0x0004 // DMA Request Mode +#define USB_TXCSRH5_DTWE 0x0002 // Data Toggle Write Enable +#define USB_TXCSRH5_DT 0x0001 // Data Toggle //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXMAXP5 register. // //***************************************************************************** -#define USB_RXMAXP5_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_RXMAXP5_MAXLOAD_M 0x07FF // Maximum Payload #define USB_RXMAXP5_MAXLOAD_S 0 //***************************************************************************** @@ -1695,33 +1226,33 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCSRL5 register. // //***************************************************************************** -#define USB_RXCSRL5_CLRDT 0x00000080 // Clear Data Toggle -#define USB_RXCSRL5_STALLED 0x00000040 // Endpoint Stalled -#define USB_RXCSRL5_STALL 0x00000020 // Send STALL -#define USB_RXCSRL5_REQPKT 0x00000020 // Request Packet -#define USB_RXCSRL5_FLUSH 0x00000010 // Flush FIFO -#define USB_RXCSRL5_NAKTO 0x00000008 // NAK Timeout -#define USB_RXCSRL5_DATAERR 0x00000008 // Data Error -#define USB_RXCSRL5_ERROR 0x00000004 // Error -#define USB_RXCSRL5_OVER 0x00000004 // Overrun -#define USB_RXCSRL5_FULL 0x00000002 // FIFO Full -#define USB_RXCSRL5_RXRDY 0x00000001 // Receive Packet Ready +#define USB_RXCSRL5_CLRDT 0x0080 // Clear Data Toggle +#define USB_RXCSRL5_STALLED 0x0040 // Endpoint Stalled +#define USB_RXCSRL5_STALL 0x0020 // Send STALL +#define USB_RXCSRL5_REQPKT 0x0020 // Request Packet +#define USB_RXCSRL5_FLUSH 0x0010 // Flush FIFO +#define USB_RXCSRL5_NAKTO 0x0008 // NAK Timeout +#define USB_RXCSRL5_DATAERR 0x0008 // Data Error +#define USB_RXCSRL5_ERROR 0x0004 // Error +#define USB_RXCSRL5_OVER 0x0004 // Overrun +#define USB_RXCSRL5_FULL 0x0002 // FIFO Full +#define USB_RXCSRL5_RXRDY 0x0001 // Receive Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXCSRH5 register. // //***************************************************************************** -#define USB_RXCSRH5_AUTOCL 0x00000080 // Auto Clear -#define USB_RXCSRH5_AUTORQ 0x00000040 // Auto Request -#define USB_RXCSRH5_ISO 0x00000040 // Isochronous Transfers -#define USB_RXCSRH5_DMAEN 0x00000020 // DMA Request Enable -#define USB_RXCSRH5_DISNYET 0x00000010 // Disable NYET -#define USB_RXCSRH5_PIDERR 0x00000010 // PID Error -#define USB_RXCSRH5_DMAMOD 0x00000008 // DMA Request Mode -#define USB_RXCSRH5_DTWE 0x00000004 // Data Toggle Write Enable -#define USB_RXCSRH5_DT 0x00000002 // Data Toggle -#define USB_RXCSRH5_INCOMPRX 0x00000001 // Incomplete RX Transmission +#define USB_RXCSRH5_AUTOCL 0x0080 // Auto Clear +#define USB_RXCSRH5_AUTORQ 0x0040 // Auto Request +#define USB_RXCSRH5_ISO 0x0040 // Isochronous Transfers +#define USB_RXCSRH5_DMAEN 0x0020 // DMA Request Enable +#define USB_RXCSRH5_DISNYET 0x0010 // Disable NYET +#define USB_RXCSRH5_PIDERR 0x0010 // PID Error +#define USB_RXCSRH5_DMAMOD 0x0008 // DMA Request Mode +#define USB_RXCSRH5_DTWE 0x0004 // Data Toggle Write Enable +#define USB_RXCSRH5_DT 0x0002 // Data Toggle +#define USB_RXCSRH5_INCOMPRX 0x0001 // Incomplete RX Transmission // Status //***************************************************************************** @@ -1729,7 +1260,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCOUNT5 register. // //***************************************************************************** -#define USB_RXCOUNT5_COUNT_M 0x00001FFF // Receive Packet Count +#define USB_RXCOUNT5_COUNT_M 0x1FFF // Receive Packet Count #define USB_RXCOUNT5_COUNT_S 0 //***************************************************************************** @@ -1737,17 +1268,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXTYPE5 register. // //***************************************************************************** -#define USB_TXTYPE5_SPEED_M 0x000000C0 // Operating Speed -#define USB_TXTYPE5_SPEED_DFLT 0x00000000 // Default -#define USB_TXTYPE5_SPEED_HIGH 0x00000040 // High -#define USB_TXTYPE5_SPEED_FULL 0x00000080 // Full -#define USB_TXTYPE5_SPEED_LOW 0x000000C0 // Low -#define USB_TXTYPE5_PROTO_M 0x00000030 // Protocol -#define USB_TXTYPE5_PROTO_CTRL 0x00000000 // Control -#define USB_TXTYPE5_PROTO_ISOC 0x00000010 // Isochronous -#define USB_TXTYPE5_PROTO_BULK 0x00000020 // Bulk -#define USB_TXTYPE5_PROTO_INT 0x00000030 // Interrupt -#define USB_TXTYPE5_TEP_M 0x0000000F // Target Endpoint Number +#define USB_TXTYPE5_SPEED_M 0x00C0 // Operating Speed +#define USB_TXTYPE5_SPEED_DFLT 0x0000 // Default +#define USB_TXTYPE5_SPEED_HIGH 0x0040 // High +#define USB_TXTYPE5_SPEED_FULL 0x0080 // Full +#define USB_TXTYPE5_SPEED_LOW 0x00C0 // Low +#define USB_TXTYPE5_PROTO_M 0x0030 // Protocol +#define USB_TXTYPE5_PROTO_CTRL 0x0000 // Control +#define USB_TXTYPE5_PROTO_ISOC 0x0010 // Isochronous +#define USB_TXTYPE5_PROTO_BULK 0x0020 // Bulk +#define USB_TXTYPE5_PROTO_INT 0x0030 // Interrupt +#define USB_TXTYPE5_TEP_M 0x000F // Target Endpoint Number #define USB_TXTYPE5_TEP_S 0 //***************************************************************************** @@ -1756,31 +1287,27 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_TXINTERVAL5_TXPOLL_M \ - 0x000000FF // TX Polling -#define USB_TXINTERVAL5_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_TXINTERVAL5_NAKLMT_S \ - 0 -#define USB_TXINTERVAL5_TXPOLL_S \ - 0 +#define USB_TXINTERVAL5_TXPOLL_M 0x00FF // TX Polling +#define USB_TXINTERVAL5_NAKLMT_M 0x00FF // NAK Limit +#define USB_TXINTERVAL5_NAKLMT_S 0 +#define USB_TXINTERVAL5_TXPOLL_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXTYPE5 register. // //***************************************************************************** -#define USB_RXTYPE5_SPEED_M 0x000000C0 // Operating Speed -#define USB_RXTYPE5_SPEED_DFLT 0x00000000 // Default -#define USB_RXTYPE5_SPEED_HIGH 0x00000040 // High -#define USB_RXTYPE5_SPEED_FULL 0x00000080 // Full -#define USB_RXTYPE5_SPEED_LOW 0x000000C0 // Low -#define USB_RXTYPE5_PROTO_M 0x00000030 // Protocol -#define USB_RXTYPE5_PROTO_CTRL 0x00000000 // Control -#define USB_RXTYPE5_PROTO_ISOC 0x00000010 // Isochronous -#define USB_RXTYPE5_PROTO_BULK 0x00000020 // Bulk -#define USB_RXTYPE5_PROTO_INT 0x00000030 // Interrupt -#define USB_RXTYPE5_TEP_M 0x0000000F // Target Endpoint Number +#define USB_RXTYPE5_SPEED_M 0x00C0 // Operating Speed +#define USB_RXTYPE5_SPEED_DFLT 0x0000 // Default +#define USB_RXTYPE5_SPEED_HIGH 0x0040 // High +#define USB_RXTYPE5_SPEED_FULL 0x0080 // Full +#define USB_RXTYPE5_SPEED_LOW 0x00C0 // Low +#define USB_RXTYPE5_PROTO_M 0x0030 // Protocol +#define USB_RXTYPE5_PROTO_CTRL 0x0000 // Control +#define USB_RXTYPE5_PROTO_ISOC 0x0010 // Isochronous +#define USB_RXTYPE5_PROTO_BULK 0x0020 // Bulk +#define USB_RXTYPE5_PROTO_INT 0x0030 // Interrupt +#define USB_RXTYPE5_TEP_M 0x000F // Target Endpoint Number #define USB_RXTYPE5_TEP_S 0 //***************************************************************************** @@ -1789,21 +1316,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RXINTERVAL5_TXPOLL_M \ - 0x000000FF // RX Polling -#define USB_RXINTERVAL5_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_RXINTERVAL5_TXPOLL_S \ - 0 -#define USB_RXINTERVAL5_NAKLMT_S \ - 0 +#define USB_RXINTERVAL5_TXPOLL_M 0x00FF // RX Polling +#define USB_RXINTERVAL5_NAKLMT_M 0x00FF // NAK Limit +#define USB_RXINTERVAL5_TXPOLL_S 0 +#define USB_RXINTERVAL5_NAKLMT_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXMAXP6 register. // //***************************************************************************** -#define USB_TXMAXP6_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_TXMAXP6_MAXLOAD_M 0x07FF // Maximum Payload #define USB_TXMAXP6_MAXLOAD_S 0 //***************************************************************************** @@ -1811,37 +1334,37 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXCSRL6 register. // //***************************************************************************** -#define USB_TXCSRL6_NAKTO 0x00000080 // NAK Timeout -#define USB_TXCSRL6_CLRDT 0x00000040 // Clear Data Toggle -#define USB_TXCSRL6_STALLED 0x00000020 // Endpoint Stalled -#define USB_TXCSRL6_STALL 0x00000010 // Send STALL -#define USB_TXCSRL6_SETUP 0x00000010 // Setup Packet -#define USB_TXCSRL6_FLUSH 0x00000008 // Flush FIFO -#define USB_TXCSRL6_ERROR 0x00000004 // Error -#define USB_TXCSRL6_UNDRN 0x00000004 // Underrun -#define USB_TXCSRL6_FIFONE 0x00000002 // FIFO Not Empty -#define USB_TXCSRL6_TXRDY 0x00000001 // Transmit Packet Ready +#define USB_TXCSRL6_NAKTO 0x0080 // NAK Timeout +#define USB_TXCSRL6_CLRDT 0x0040 // Clear Data Toggle +#define USB_TXCSRL6_STALLED 0x0020 // Endpoint Stalled +#define USB_TXCSRL6_STALL 0x0010 // Send STALL +#define USB_TXCSRL6_SETUP 0x0010 // Setup Packet +#define USB_TXCSRL6_FLUSH 0x0008 // Flush FIFO +#define USB_TXCSRL6_ERROR 0x0004 // Error +#define USB_TXCSRL6_UNDRN 0x0004 // Underrun +#define USB_TXCSRL6_FIFONE 0x0002 // FIFO Not Empty +#define USB_TXCSRL6_TXRDY 0x0001 // Transmit Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXCSRH6 register. // //***************************************************************************** -#define USB_TXCSRH6_AUTOSET 0x00000080 // Auto Set -#define USB_TXCSRH6_ISO 0x00000040 // Isochronous Transfers -#define USB_TXCSRH6_MODE 0x00000020 // Mode -#define USB_TXCSRH6_DMAEN 0x00000010 // DMA Request Enable -#define USB_TXCSRH6_FDT 0x00000008 // Force Data Toggle -#define USB_TXCSRH6_DMAMOD 0x00000004 // DMA Request Mode -#define USB_TXCSRH6_DTWE 0x00000002 // Data Toggle Write Enable -#define USB_TXCSRH6_DT 0x00000001 // Data Toggle +#define USB_TXCSRH6_AUTOSET 0x0080 // Auto Set +#define USB_TXCSRH6_ISO 0x0040 // Isochronous Transfers +#define USB_TXCSRH6_MODE 0x0020 // Mode +#define USB_TXCSRH6_DMAEN 0x0010 // DMA Request Enable +#define USB_TXCSRH6_FDT 0x0008 // Force Data Toggle +#define USB_TXCSRH6_DMAMOD 0x0004 // DMA Request Mode +#define USB_TXCSRH6_DTWE 0x0002 // Data Toggle Write Enable +#define USB_TXCSRH6_DT 0x0001 // Data Toggle //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXMAXP6 register. // //***************************************************************************** -#define USB_RXMAXP6_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_RXMAXP6_MAXLOAD_M 0x07FF // Maximum Payload #define USB_RXMAXP6_MAXLOAD_S 0 //***************************************************************************** @@ -1849,33 +1372,33 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCSRL6 register. // //***************************************************************************** -#define USB_RXCSRL6_CLRDT 0x00000080 // Clear Data Toggle -#define USB_RXCSRL6_STALLED 0x00000040 // Endpoint Stalled -#define USB_RXCSRL6_REQPKT 0x00000020 // Request Packet -#define USB_RXCSRL6_STALL 0x00000020 // Send STALL -#define USB_RXCSRL6_FLUSH 0x00000010 // Flush FIFO -#define USB_RXCSRL6_NAKTO 0x00000008 // NAK Timeout -#define USB_RXCSRL6_DATAERR 0x00000008 // Data Error -#define USB_RXCSRL6_ERROR 0x00000004 // Error -#define USB_RXCSRL6_OVER 0x00000004 // Overrun -#define USB_RXCSRL6_FULL 0x00000002 // FIFO Full -#define USB_RXCSRL6_RXRDY 0x00000001 // Receive Packet Ready +#define USB_RXCSRL6_CLRDT 0x0080 // Clear Data Toggle +#define USB_RXCSRL6_STALLED 0x0040 // Endpoint Stalled +#define USB_RXCSRL6_REQPKT 0x0020 // Request Packet +#define USB_RXCSRL6_STALL 0x0020 // Send STALL +#define USB_RXCSRL6_FLUSH 0x0010 // Flush FIFO +#define USB_RXCSRL6_NAKTO 0x0008 // NAK Timeout +#define USB_RXCSRL6_DATAERR 0x0008 // Data Error +#define USB_RXCSRL6_ERROR 0x0004 // Error +#define USB_RXCSRL6_OVER 0x0004 // Overrun +#define USB_RXCSRL6_FULL 0x0002 // FIFO Full +#define USB_RXCSRL6_RXRDY 0x0001 // Receive Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXCSRH6 register. // //***************************************************************************** -#define USB_RXCSRH6_AUTOCL 0x00000080 // Auto Clear -#define USB_RXCSRH6_AUTORQ 0x00000040 // Auto Request -#define USB_RXCSRH6_ISO 0x00000040 // Isochronous Transfers -#define USB_RXCSRH6_DMAEN 0x00000020 // DMA Request Enable -#define USB_RXCSRH6_DISNYET 0x00000010 // Disable NYET -#define USB_RXCSRH6_PIDERR 0x00000010 // PID Error -#define USB_RXCSRH6_DMAMOD 0x00000008 // DMA Request Mode -#define USB_RXCSRH6_DTWE 0x00000004 // Data Toggle Write Enable -#define USB_RXCSRH6_DT 0x00000002 // Data Toggle -#define USB_RXCSRH6_INCOMPRX 0x00000001 // Incomplete RX Transmission +#define USB_RXCSRH6_AUTOCL 0x0080 // Auto Clear +#define USB_RXCSRH6_AUTORQ 0x0040 // Auto Request +#define USB_RXCSRH6_ISO 0x0040 // Isochronous Transfers +#define USB_RXCSRH6_DMAEN 0x0020 // DMA Request Enable +#define USB_RXCSRH6_DISNYET 0x0010 // Disable NYET +#define USB_RXCSRH6_PIDERR 0x0010 // PID Error +#define USB_RXCSRH6_DMAMOD 0x0008 // DMA Request Mode +#define USB_RXCSRH6_DTWE 0x0004 // Data Toggle Write Enable +#define USB_RXCSRH6_DT 0x0002 // Data Toggle +#define USB_RXCSRH6_INCOMPRX 0x0001 // Incomplete RX Transmission // Status //***************************************************************************** @@ -1883,7 +1406,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCOUNT6 register. // //***************************************************************************** -#define USB_RXCOUNT6_COUNT_M 0x00001FFF // Receive Packet Count +#define USB_RXCOUNT6_COUNT_M 0x1FFF // Receive Packet Count #define USB_RXCOUNT6_COUNT_S 0 //***************************************************************************** @@ -1891,17 +1414,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXTYPE6 register. // //***************************************************************************** -#define USB_TXTYPE6_SPEED_M 0x000000C0 // Operating Speed -#define USB_TXTYPE6_SPEED_DFLT 0x00000000 // Default -#define USB_TXTYPE6_SPEED_HIGH 0x00000040 // High -#define USB_TXTYPE6_SPEED_FULL 0x00000080 // Full -#define USB_TXTYPE6_SPEED_LOW 0x000000C0 // Low -#define USB_TXTYPE6_PROTO_M 0x00000030 // Protocol -#define USB_TXTYPE6_PROTO_CTRL 0x00000000 // Control -#define USB_TXTYPE6_PROTO_ISOC 0x00000010 // Isochronous -#define USB_TXTYPE6_PROTO_BULK 0x00000020 // Bulk -#define USB_TXTYPE6_PROTO_INT 0x00000030 // Interrupt -#define USB_TXTYPE6_TEP_M 0x0000000F // Target Endpoint Number +#define USB_TXTYPE6_SPEED_M 0x00C0 // Operating Speed +#define USB_TXTYPE6_SPEED_DFLT 0x0000 // Default +#define USB_TXTYPE6_SPEED_HIGH 0x0040 // High +#define USB_TXTYPE6_SPEED_FULL 0x0080 // Full +#define USB_TXTYPE6_SPEED_LOW 0x00C0 // Low +#define USB_TXTYPE6_PROTO_M 0x0030 // Protocol +#define USB_TXTYPE6_PROTO_CTRL 0x0000 // Control +#define USB_TXTYPE6_PROTO_ISOC 0x0010 // Isochronous +#define USB_TXTYPE6_PROTO_BULK 0x0020 // Bulk +#define USB_TXTYPE6_PROTO_INT 0x0030 // Interrupt +#define USB_TXTYPE6_TEP_M 0x000F // Target Endpoint Number #define USB_TXTYPE6_TEP_S 0 //***************************************************************************** @@ -1910,31 +1433,27 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_TXINTERVAL6_TXPOLL_M \ - 0x000000FF // TX Polling -#define USB_TXINTERVAL6_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_TXINTERVAL6_TXPOLL_S \ - 0 -#define USB_TXINTERVAL6_NAKLMT_S \ - 0 +#define USB_TXINTERVAL6_TXPOLL_M 0x00FF // TX Polling +#define USB_TXINTERVAL6_NAKLMT_M 0x00FF // NAK Limit +#define USB_TXINTERVAL6_TXPOLL_S 0 +#define USB_TXINTERVAL6_NAKLMT_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXTYPE6 register. // //***************************************************************************** -#define USB_RXTYPE6_SPEED_M 0x000000C0 // Operating Speed -#define USB_RXTYPE6_SPEED_DFLT 0x00000000 // Default -#define USB_RXTYPE6_SPEED_HIGH 0x00000040 // High -#define USB_RXTYPE6_SPEED_FULL 0x00000080 // Full -#define USB_RXTYPE6_SPEED_LOW 0x000000C0 // Low -#define USB_RXTYPE6_PROTO_M 0x00000030 // Protocol -#define USB_RXTYPE6_PROTO_CTRL 0x00000000 // Control -#define USB_RXTYPE6_PROTO_ISOC 0x00000010 // Isochronous -#define USB_RXTYPE6_PROTO_BULK 0x00000020 // Bulk -#define USB_RXTYPE6_PROTO_INT 0x00000030 // Interrupt -#define USB_RXTYPE6_TEP_M 0x0000000F // Target Endpoint Number +#define USB_RXTYPE6_SPEED_M 0x00C0 // Operating Speed +#define USB_RXTYPE6_SPEED_DFLT 0x0000 // Default +#define USB_RXTYPE6_SPEED_HIGH 0x0040 // High +#define USB_RXTYPE6_SPEED_FULL 0x0080 // Full +#define USB_RXTYPE6_SPEED_LOW 0x00C0 // Low +#define USB_RXTYPE6_PROTO_M 0x0030 // Protocol +#define USB_RXTYPE6_PROTO_CTRL 0x0000 // Control +#define USB_RXTYPE6_PROTO_ISOC 0x0010 // Isochronous +#define USB_RXTYPE6_PROTO_BULK 0x0020 // Bulk +#define USB_RXTYPE6_PROTO_INT 0x0030 // Interrupt +#define USB_RXTYPE6_TEP_M 0x000F // Target Endpoint Number #define USB_RXTYPE6_TEP_S 0 //***************************************************************************** @@ -1943,21 +1462,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RXINTERVAL6_TXPOLL_M \ - 0x000000FF // RX Polling -#define USB_RXINTERVAL6_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_RXINTERVAL6_NAKLMT_S \ - 0 -#define USB_RXINTERVAL6_TXPOLL_S \ - 0 +#define USB_RXINTERVAL6_TXPOLL_M 0x00FF // RX Polling +#define USB_RXINTERVAL6_NAKLMT_M 0x00FF // NAK Limit +#define USB_RXINTERVAL6_NAKLMT_S 0 +#define USB_RXINTERVAL6_TXPOLL_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXMAXP7 register. // //***************************************************************************** -#define USB_TXMAXP7_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_TXMAXP7_MAXLOAD_M 0x07FF // Maximum Payload #define USB_TXMAXP7_MAXLOAD_S 0 //***************************************************************************** @@ -1965,37 +1480,37 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXCSRL7 register. // //***************************************************************************** -#define USB_TXCSRL7_NAKTO 0x00000080 // NAK Timeout -#define USB_TXCSRL7_CLRDT 0x00000040 // Clear Data Toggle -#define USB_TXCSRL7_STALLED 0x00000020 // Endpoint Stalled -#define USB_TXCSRL7_STALL 0x00000010 // Send STALL -#define USB_TXCSRL7_SETUP 0x00000010 // Setup Packet -#define USB_TXCSRL7_FLUSH 0x00000008 // Flush FIFO -#define USB_TXCSRL7_ERROR 0x00000004 // Error -#define USB_TXCSRL7_UNDRN 0x00000004 // Underrun -#define USB_TXCSRL7_FIFONE 0x00000002 // FIFO Not Empty -#define USB_TXCSRL7_TXRDY 0x00000001 // Transmit Packet Ready +#define USB_TXCSRL7_NAKTO 0x0080 // NAK Timeout +#define USB_TXCSRL7_CLRDT 0x0040 // Clear Data Toggle +#define USB_TXCSRL7_STALLED 0x0020 // Endpoint Stalled +#define USB_TXCSRL7_STALL 0x0010 // Send STALL +#define USB_TXCSRL7_SETUP 0x0010 // Setup Packet +#define USB_TXCSRL7_FLUSH 0x0008 // Flush FIFO +#define USB_TXCSRL7_ERROR 0x0004 // Error +#define USB_TXCSRL7_UNDRN 0x0004 // Underrun +#define USB_TXCSRL7_FIFONE 0x0002 // FIFO Not Empty +#define USB_TXCSRL7_TXRDY 0x0001 // Transmit Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXCSRH7 register. // //***************************************************************************** -#define USB_TXCSRH7_AUTOSET 0x00000080 // Auto Set -#define USB_TXCSRH7_ISO 0x00000040 // Isochronous Transfers -#define USB_TXCSRH7_MODE 0x00000020 // Mode -#define USB_TXCSRH7_DMAEN 0x00000010 // DMA Request Enable -#define USB_TXCSRH7_FDT 0x00000008 // Force Data Toggle -#define USB_TXCSRH7_DMAMOD 0x00000004 // DMA Request Mode -#define USB_TXCSRH7_DTWE 0x00000002 // Data Toggle Write Enable -#define USB_TXCSRH7_DT 0x00000001 // Data Toggle +#define USB_TXCSRH7_AUTOSET 0x0080 // Auto Set +#define USB_TXCSRH7_ISO 0x0040 // Isochronous Transfers +#define USB_TXCSRH7_MODE 0x0020 // Mode +#define USB_TXCSRH7_DMAEN 0x0010 // DMA Request Enable +#define USB_TXCSRH7_FDT 0x0008 // Force Data Toggle +#define USB_TXCSRH7_DMAMOD 0x0004 // DMA Request Mode +#define USB_TXCSRH7_DTWE 0x0002 // Data Toggle Write Enable +#define USB_TXCSRH7_DT 0x0001 // Data Toggle //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXMAXP7 register. // //***************************************************************************** -#define USB_RXMAXP7_MAXLOAD_M 0x000007FF // Maximum Payload +#define USB_RXMAXP7_MAXLOAD_M 0x07FF // Maximum Payload #define USB_RXMAXP7_MAXLOAD_S 0 //***************************************************************************** @@ -2003,33 +1518,33 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCSRL7 register. // //***************************************************************************** -#define USB_RXCSRL7_CLRDT 0x00000080 // Clear Data Toggle -#define USB_RXCSRL7_STALLED 0x00000040 // Endpoint Stalled -#define USB_RXCSRL7_REQPKT 0x00000020 // Request Packet -#define USB_RXCSRL7_STALL 0x00000020 // Send STALL -#define USB_RXCSRL7_FLUSH 0x00000010 // Flush FIFO -#define USB_RXCSRL7_DATAERR 0x00000008 // Data Error -#define USB_RXCSRL7_NAKTO 0x00000008 // NAK Timeout -#define USB_RXCSRL7_ERROR 0x00000004 // Error -#define USB_RXCSRL7_OVER 0x00000004 // Overrun -#define USB_RXCSRL7_FULL 0x00000002 // FIFO Full -#define USB_RXCSRL7_RXRDY 0x00000001 // Receive Packet Ready +#define USB_RXCSRL7_CLRDT 0x0080 // Clear Data Toggle +#define USB_RXCSRL7_STALLED 0x0040 // Endpoint Stalled +#define USB_RXCSRL7_REQPKT 0x0020 // Request Packet +#define USB_RXCSRL7_STALL 0x0020 // Send STALL +#define USB_RXCSRL7_FLUSH 0x0010 // Flush FIFO +#define USB_RXCSRL7_DATAERR 0x0008 // Data Error +#define USB_RXCSRL7_NAKTO 0x0008 // NAK Timeout +#define USB_RXCSRL7_ERROR 0x0004 // Error +#define USB_RXCSRL7_OVER 0x0004 // Overrun +#define USB_RXCSRL7_FULL 0x0002 // FIFO Full +#define USB_RXCSRL7_RXRDY 0x0001 // Receive Packet Ready //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXCSRH7 register. // //***************************************************************************** -#define USB_RXCSRH7_AUTOCL 0x00000080 // Auto Clear -#define USB_RXCSRH7_ISO 0x00000040 // Isochronous Transfers -#define USB_RXCSRH7_AUTORQ 0x00000040 // Auto Request -#define USB_RXCSRH7_DMAEN 0x00000020 // DMA Request Enable -#define USB_RXCSRH7_PIDERR 0x00000010 // PID Error -#define USB_RXCSRH7_DISNYET 0x00000010 // Disable NYET -#define USB_RXCSRH7_DMAMOD 0x00000008 // DMA Request Mode -#define USB_RXCSRH7_DTWE 0x00000004 // Data Toggle Write Enable -#define USB_RXCSRH7_DT 0x00000002 // Data Toggle -#define USB_RXCSRH7_INCOMPRX 0x00000001 // Incomplete RX Transmission +#define USB_RXCSRH7_AUTOCL 0x0080 // Auto Clear +#define USB_RXCSRH7_ISO 0x0040 // Isochronous Transfers +#define USB_RXCSRH7_AUTORQ 0x0040 // Auto Request +#define USB_RXCSRH7_DMAEN 0x0020 // DMA Request Enable +#define USB_RXCSRH7_PIDERR 0x0010 // PID Error +#define USB_RXCSRH7_DISNYET 0x0010 // Disable NYET +#define USB_RXCSRH7_DMAMOD 0x0008 // DMA Request Mode +#define USB_RXCSRH7_DTWE 0x0004 // Data Toggle Write Enable +#define USB_RXCSRH7_DT 0x0002 // Data Toggle +#define USB_RXCSRH7_INCOMPRX 0x0001 // Incomplete RX Transmission // Status //***************************************************************************** @@ -2037,7 +1552,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_RXCOUNT7 register. // //***************************************************************************** -#define USB_RXCOUNT7_COUNT_M 0x00001FFF // Receive Packet Count +#define USB_RXCOUNT7_COUNT_M 0x1FFF // Receive Packet Count #define USB_RXCOUNT7_COUNT_S 0 //***************************************************************************** @@ -2045,17 +1560,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_TXTYPE7 register. // //***************************************************************************** -#define USB_TXTYPE7_SPEED_M 0x000000C0 // Operating Speed -#define USB_TXTYPE7_SPEED_DFLT 0x00000000 // Default -#define USB_TXTYPE7_SPEED_HIGH 0x00000040 // High -#define USB_TXTYPE7_SPEED_FULL 0x00000080 // Full -#define USB_TXTYPE7_SPEED_LOW 0x000000C0 // Low -#define USB_TXTYPE7_PROTO_M 0x00000030 // Protocol -#define USB_TXTYPE7_PROTO_CTRL 0x00000000 // Control -#define USB_TXTYPE7_PROTO_ISOC 0x00000010 // Isochronous -#define USB_TXTYPE7_PROTO_BULK 0x00000020 // Bulk -#define USB_TXTYPE7_PROTO_INT 0x00000030 // Interrupt -#define USB_TXTYPE7_TEP_M 0x0000000F // Target Endpoint Number +#define USB_TXTYPE7_SPEED_M 0x00C0 // Operating Speed +#define USB_TXTYPE7_SPEED_DFLT 0x0000 // Default +#define USB_TXTYPE7_SPEED_HIGH 0x0040 // High +#define USB_TXTYPE7_SPEED_FULL 0x0080 // Full +#define USB_TXTYPE7_SPEED_LOW 0x00C0 // Low +#define USB_TXTYPE7_PROTO_M 0x0030 // Protocol +#define USB_TXTYPE7_PROTO_CTRL 0x0000 // Control +#define USB_TXTYPE7_PROTO_ISOC 0x0010 // Isochronous +#define USB_TXTYPE7_PROTO_BULK 0x0020 // Bulk +#define USB_TXTYPE7_PROTO_INT 0x0030 // Interrupt +#define USB_TXTYPE7_TEP_M 0x000F // Target Endpoint Number #define USB_TXTYPE7_TEP_S 0 //***************************************************************************** @@ -2064,31 +1579,27 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_TXINTERVAL7_TXPOLL_M \ - 0x000000FF // TX Polling -#define USB_TXINTERVAL7_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_TXINTERVAL7_NAKLMT_S \ - 0 -#define USB_TXINTERVAL7_TXPOLL_S \ - 0 +#define USB_TXINTERVAL7_TXPOLL_M 0x00FF // TX Polling +#define USB_TXINTERVAL7_NAKLMT_M 0x00FF // NAK Limit +#define USB_TXINTERVAL7_NAKLMT_S 0 +#define USB_TXINTERVAL7_TXPOLL_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXTYPE7 register. // //***************************************************************************** -#define USB_RXTYPE7_SPEED_M 0x000000C0 // Operating Speed -#define USB_RXTYPE7_SPEED_DFLT 0x00000000 // Default -#define USB_RXTYPE7_SPEED_HIGH 0x00000040 // High -#define USB_RXTYPE7_SPEED_FULL 0x00000080 // Full -#define USB_RXTYPE7_SPEED_LOW 0x000000C0 // Low -#define USB_RXTYPE7_PROTO_M 0x00000030 // Protocol -#define USB_RXTYPE7_PROTO_CTRL 0x00000000 // Control -#define USB_RXTYPE7_PROTO_ISOC 0x00000010 // Isochronous -#define USB_RXTYPE7_PROTO_BULK 0x00000020 // Bulk -#define USB_RXTYPE7_PROTO_INT 0x00000030 // Interrupt -#define USB_RXTYPE7_TEP_M 0x0000000F // Target Endpoint Number +#define USB_RXTYPE7_SPEED_M 0x00C0 // Operating Speed +#define USB_RXTYPE7_SPEED_DFLT 0x0000 // Default +#define USB_RXTYPE7_SPEED_HIGH 0x0040 // High +#define USB_RXTYPE7_SPEED_FULL 0x0080 // Full +#define USB_RXTYPE7_SPEED_LOW 0x00C0 // Low +#define USB_RXTYPE7_PROTO_M 0x0030 // Protocol +#define USB_RXTYPE7_PROTO_CTRL 0x0000 // Control +#define USB_RXTYPE7_PROTO_ISOC 0x0010 // Isochronous +#define USB_RXTYPE7_PROTO_BULK 0x0020 // Bulk +#define USB_RXTYPE7_PROTO_INT 0x0030 // Interrupt +#define USB_RXTYPE7_TEP_M 0x000F // Target Endpoint Number #define USB_RXTYPE7_TEP_S 0 //***************************************************************************** @@ -2097,47 +1608,43 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RXINTERVAL7_TXPOLL_M \ - 0x000000FF // RX Polling -#define USB_RXINTERVAL7_NAKLMT_M \ - 0x000000FF // NAK Limit -#define USB_RXINTERVAL7_NAKLMT_S \ - 0 -#define USB_RXINTERVAL7_TXPOLL_S \ - 0 +#define USB_RXINTERVAL7_TXPOLL_M 0x00FF // RX Polling +#define USB_RXINTERVAL7_NAKLMT_M 0x00FF // NAK Limit +#define USB_RXINTERVAL7_NAKLMT_S 0 +#define USB_RXINTERVAL7_TXPOLL_S 0 //***************************************************************************** // // The following are defines for the bit fields in the USB_O_DMAINTR register. // //***************************************************************************** -#define USB_DMAINTR_CH7 0x00000080 // Channel 7 DMA Interrupt -#define USB_DMAINTR_CH6 0x00000040 // Channel 6 DMA Interrupt -#define USB_DMAINTR_CH5 0x00000020 // Channel 5 DMA Interrupt -#define USB_DMAINTR_CH4 0x00000010 // Channel 4 DMA Interrupt -#define USB_DMAINTR_CH3 0x00000008 // Channel 3 DMA Interrupt -#define USB_DMAINTR_CH2 0x00000004 // Channel 2 DMA Interrupt -#define USB_DMAINTR_CH1 0x00000002 // Channel 1 DMA Interrupt -#define USB_DMAINTR_CH0 0x00000001 // Channel 0 DMA Interrupt +#define USB_DMAINTR_CH7 0x0080 // Channel 7 DMA Interrupt +#define USB_DMAINTR_CH6 0x0040 // Channel 6 DMA Interrupt +#define USB_DMAINTR_CH5 0x0020 // Channel 5 DMA Interrupt +#define USB_DMAINTR_CH4 0x0010 // Channel 4 DMA Interrupt +#define USB_DMAINTR_CH3 0x0008 // Channel 3 DMA Interrupt +#define USB_DMAINTR_CH2 0x0004 // Channel 2 DMA Interrupt +#define USB_DMAINTR_CH1 0x0002 // Channel 1 DMA Interrupt +#define USB_DMAINTR_CH0 0x0001 // Channel 0 DMA Interrupt //***************************************************************************** // // The following are defines for the bit fields in the USB_O_DMACTL0 register. // //***************************************************************************** -#define USB_DMACTL0_BRSTM_M 0x00000600 // Burst Mode -#define USB_DMACTL0_BRSTM_ANY 0x00000000 // Bursts of unspecified length -#define USB_DMACTL0_BRSTM_INC4 0x00000200 // INCR4 or unspecified length -#define USB_DMACTL0_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified +#define USB_DMACTL0_BRSTM_M 0x0600 // Burst Mode +#define USB_DMACTL0_BRSTM_ANY 0x0000 // Bursts of unspecified length +#define USB_DMACTL0_BRSTM_INC4 0x0200 // INCR4 or unspecified length +#define USB_DMACTL0_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified // length -#define USB_DMACTL0_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or +#define USB_DMACTL0_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or // unspecified length -#define USB_DMACTL0_ERR 0x00000100 // Bus Error Bit -#define USB_DMACTL0_EP_M 0x000000F0 // Endpoint number -#define USB_DMACTL0_IE 0x00000008 // DMA Interrupt Enable -#define USB_DMACTL0_MODE 0x00000004 // DMA Transfer Mode -#define USB_DMACTL0_DIR 0x00000002 // DMA Direction -#define USB_DMACTL0_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL0_ERR 0x0100 // Bus Error Bit +#define USB_DMACTL0_EP_M 0x00F0 // Endpoint number +#define USB_DMACTL0_IE 0x0008 // DMA Interrupt Enable +#define USB_DMACTL0_MODE 0x0004 // DMA Transfer Mode +#define USB_DMACTL0_DIR 0x0002 // DMA Direction +#define USB_DMACTL0_ENABLE 0x0001 // DMA Transfer Enable #define USB_DMACTL0_EP_S 4 //***************************************************************************** @@ -2162,19 +1669,19 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_DMACTL1 register. // //***************************************************************************** -#define USB_DMACTL1_BRSTM_M 0x00000600 // Burst Mode -#define USB_DMACTL1_BRSTM_ANY 0x00000000 // Bursts of unspecified length -#define USB_DMACTL1_BRSTM_INC4 0x00000200 // INCR4 or unspecified length -#define USB_DMACTL1_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified +#define USB_DMACTL1_BRSTM_M 0x0600 // Burst Mode +#define USB_DMACTL1_BRSTM_ANY 0x0000 // Bursts of unspecified length +#define USB_DMACTL1_BRSTM_INC4 0x0200 // INCR4 or unspecified length +#define USB_DMACTL1_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified // length -#define USB_DMACTL1_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or +#define USB_DMACTL1_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or // unspecified length -#define USB_DMACTL1_ERR 0x00000100 // Bus Error Bit -#define USB_DMACTL1_EP_M 0x000000F0 // Endpoint number -#define USB_DMACTL1_IE 0x00000008 // DMA Interrupt Enable -#define USB_DMACTL1_MODE 0x00000004 // DMA Transfer Mode -#define USB_DMACTL1_DIR 0x00000002 // DMA Direction -#define USB_DMACTL1_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL1_ERR 0x0100 // Bus Error Bit +#define USB_DMACTL1_EP_M 0x00F0 // Endpoint number +#define USB_DMACTL1_IE 0x0008 // DMA Interrupt Enable +#define USB_DMACTL1_MODE 0x0004 // DMA Transfer Mode +#define USB_DMACTL1_DIR 0x0002 // DMA Direction +#define USB_DMACTL1_ENABLE 0x0001 // DMA Transfer Enable #define USB_DMACTL1_EP_S 4 //***************************************************************************** @@ -2199,19 +1706,19 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_DMACTL2 register. // //***************************************************************************** -#define USB_DMACTL2_BRSTM_M 0x00000600 // Burst Mode -#define USB_DMACTL2_BRSTM_ANY 0x00000000 // Bursts of unspecified length -#define USB_DMACTL2_BRSTM_INC4 0x00000200 // INCR4 or unspecified length -#define USB_DMACTL2_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified +#define USB_DMACTL2_BRSTM_M 0x0600 // Burst Mode +#define USB_DMACTL2_BRSTM_ANY 0x0000 // Bursts of unspecified length +#define USB_DMACTL2_BRSTM_INC4 0x0200 // INCR4 or unspecified length +#define USB_DMACTL2_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified // length -#define USB_DMACTL2_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or +#define USB_DMACTL2_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or // unspecified length -#define USB_DMACTL2_ERR 0x00000100 // Bus Error Bit -#define USB_DMACTL2_EP_M 0x000000F0 // Endpoint number -#define USB_DMACTL2_IE 0x00000008 // DMA Interrupt Enable -#define USB_DMACTL2_MODE 0x00000004 // DMA Transfer Mode -#define USB_DMACTL2_DIR 0x00000002 // DMA Direction -#define USB_DMACTL2_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL2_ERR 0x0100 // Bus Error Bit +#define USB_DMACTL2_EP_M 0x00F0 // Endpoint number +#define USB_DMACTL2_IE 0x0008 // DMA Interrupt Enable +#define USB_DMACTL2_MODE 0x0004 // DMA Transfer Mode +#define USB_DMACTL2_DIR 0x0002 // DMA Direction +#define USB_DMACTL2_ENABLE 0x0001 // DMA Transfer Enable #define USB_DMACTL2_EP_S 4 //***************************************************************************** @@ -2236,19 +1743,19 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_DMACTL3 register. // //***************************************************************************** -#define USB_DMACTL3_BRSTM_M 0x00000600 // Burst Mode -#define USB_DMACTL3_BRSTM_ANY 0x00000000 // Bursts of unspecified length -#define USB_DMACTL3_BRSTM_INC4 0x00000200 // INCR4 or unspecified length -#define USB_DMACTL3_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified +#define USB_DMACTL3_BRSTM_M 0x0600 // Burst Mode +#define USB_DMACTL3_BRSTM_ANY 0x0000 // Bursts of unspecified length +#define USB_DMACTL3_BRSTM_INC4 0x0200 // INCR4 or unspecified length +#define USB_DMACTL3_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified // length -#define USB_DMACTL3_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or +#define USB_DMACTL3_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or // unspecified length -#define USB_DMACTL3_ERR 0x00000100 // Bus Error Bit -#define USB_DMACTL3_EP_M 0x000000F0 // Endpoint number -#define USB_DMACTL3_IE 0x00000008 // DMA Interrupt Enable -#define USB_DMACTL3_MODE 0x00000004 // DMA Transfer Mode -#define USB_DMACTL3_DIR 0x00000002 // DMA Direction -#define USB_DMACTL3_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL3_ERR 0x0100 // Bus Error Bit +#define USB_DMACTL3_EP_M 0x00F0 // Endpoint number +#define USB_DMACTL3_IE 0x0008 // DMA Interrupt Enable +#define USB_DMACTL3_MODE 0x0004 // DMA Transfer Mode +#define USB_DMACTL3_DIR 0x0002 // DMA Direction +#define USB_DMACTL3_ENABLE 0x0001 // DMA Transfer Enable #define USB_DMACTL3_EP_S 4 //***************************************************************************** @@ -2273,19 +1780,19 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_DMACTL4 register. // //***************************************************************************** -#define USB_DMACTL4_BRSTM_M 0x00000600 // Burst Mode -#define USB_DMACTL4_BRSTM_ANY 0x00000000 // Bursts of unspecified length -#define USB_DMACTL4_BRSTM_INC4 0x00000200 // INCR4 or unspecified length -#define USB_DMACTL4_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified +#define USB_DMACTL4_BRSTM_M 0x0600 // Burst Mode +#define USB_DMACTL4_BRSTM_ANY 0x0000 // Bursts of unspecified length +#define USB_DMACTL4_BRSTM_INC4 0x0200 // INCR4 or unspecified length +#define USB_DMACTL4_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified // length -#define USB_DMACTL4_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or +#define USB_DMACTL4_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or // unspecified length -#define USB_DMACTL4_ERR 0x00000100 // Bus Error Bit -#define USB_DMACTL4_EP_M 0x000000F0 // Endpoint number -#define USB_DMACTL4_IE 0x00000008 // DMA Interrupt Enable -#define USB_DMACTL4_MODE 0x00000004 // DMA Transfer Mode -#define USB_DMACTL4_DIR 0x00000002 // DMA Direction -#define USB_DMACTL4_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL4_ERR 0x0100 // Bus Error Bit +#define USB_DMACTL4_EP_M 0x00F0 // Endpoint number +#define USB_DMACTL4_IE 0x0008 // DMA Interrupt Enable +#define USB_DMACTL4_MODE 0x0004 // DMA Transfer Mode +#define USB_DMACTL4_DIR 0x0002 // DMA Direction +#define USB_DMACTL4_ENABLE 0x0001 // DMA Transfer Enable #define USB_DMACTL4_EP_S 4 //***************************************************************************** @@ -2310,19 +1817,19 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_DMACTL5 register. // //***************************************************************************** -#define USB_DMACTL5_BRSTM_M 0x00000600 // Burst Mode -#define USB_DMACTL5_BRSTM_ANY 0x00000000 // Bursts of unspecified length -#define USB_DMACTL5_BRSTM_INC4 0x00000200 // INCR4 or unspecified length -#define USB_DMACTL5_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified +#define USB_DMACTL5_BRSTM_M 0x0600 // Burst Mode +#define USB_DMACTL5_BRSTM_ANY 0x0000 // Bursts of unspecified length +#define USB_DMACTL5_BRSTM_INC4 0x0200 // INCR4 or unspecified length +#define USB_DMACTL5_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified // length -#define USB_DMACTL5_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or +#define USB_DMACTL5_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or // unspecified length -#define USB_DMACTL5_ERR 0x00000100 // Bus Error Bit -#define USB_DMACTL5_EP_M 0x000000F0 // Endpoint number -#define USB_DMACTL5_IE 0x00000008 // DMA Interrupt Enable -#define USB_DMACTL5_MODE 0x00000004 // DMA Transfer Mode -#define USB_DMACTL5_DIR 0x00000002 // DMA Direction -#define USB_DMACTL5_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL5_ERR 0x0100 // Bus Error Bit +#define USB_DMACTL5_EP_M 0x00F0 // Endpoint number +#define USB_DMACTL5_IE 0x0008 // DMA Interrupt Enable +#define USB_DMACTL5_MODE 0x0004 // DMA Transfer Mode +#define USB_DMACTL5_DIR 0x0002 // DMA Direction +#define USB_DMACTL5_ENABLE 0x0001 // DMA Transfer Enable #define USB_DMACTL5_EP_S 4 //***************************************************************************** @@ -2347,19 +1854,19 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_DMACTL6 register. // //***************************************************************************** -#define USB_DMACTL6_BRSTM_M 0x00000600 // Burst Mode -#define USB_DMACTL6_BRSTM_ANY 0x00000000 // Bursts of unspecified length -#define USB_DMACTL6_BRSTM_INC4 0x00000200 // INCR4 or unspecified length -#define USB_DMACTL6_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified +#define USB_DMACTL6_BRSTM_M 0x0600 // Burst Mode +#define USB_DMACTL6_BRSTM_ANY 0x0000 // Bursts of unspecified length +#define USB_DMACTL6_BRSTM_INC4 0x0200 // INCR4 or unspecified length +#define USB_DMACTL6_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified // length -#define USB_DMACTL6_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or +#define USB_DMACTL6_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or // unspecified length -#define USB_DMACTL6_ERR 0x00000100 // Bus Error Bit -#define USB_DMACTL6_EP_M 0x000000F0 // Endpoint number -#define USB_DMACTL6_IE 0x00000008 // DMA Interrupt Enable -#define USB_DMACTL6_MODE 0x00000004 // DMA Transfer Mode -#define USB_DMACTL6_DIR 0x00000002 // DMA Direction -#define USB_DMACTL6_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL6_ERR 0x0100 // Bus Error Bit +#define USB_DMACTL6_EP_M 0x00F0 // Endpoint number +#define USB_DMACTL6_IE 0x0008 // DMA Interrupt Enable +#define USB_DMACTL6_MODE 0x0004 // DMA Transfer Mode +#define USB_DMACTL6_DIR 0x0002 // DMA Direction +#define USB_DMACTL6_ENABLE 0x0001 // DMA Transfer Enable #define USB_DMACTL6_EP_S 4 //***************************************************************************** @@ -2384,19 +1891,19 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_DMACTL7 register. // //***************************************************************************** -#define USB_DMACTL7_BRSTM_M 0x00000600 // Burst Mode -#define USB_DMACTL7_BRSTM_ANY 0x00000000 // Bursts of unspecified length -#define USB_DMACTL7_BRSTM_INC4 0x00000200 // INCR4 or unspecified length -#define USB_DMACTL7_BRSTM_INC8 0x00000400 // INCR8, INCR4 or unspecified +#define USB_DMACTL7_BRSTM_M 0x0600 // Burst Mode +#define USB_DMACTL7_BRSTM_ANY 0x0000 // Bursts of unspecified length +#define USB_DMACTL7_BRSTM_INC4 0x0200 // INCR4 or unspecified length +#define USB_DMACTL7_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified // length -#define USB_DMACTL7_BRSTM_INC16 0x00000600 // INCR16, INCR8, INCR4 or +#define USB_DMACTL7_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or // unspecified length -#define USB_DMACTL7_ERR 0x00000100 // Bus Error Bit -#define USB_DMACTL7_EP_M 0x000000F0 // Endpoint number -#define USB_DMACTL7_IE 0x00000008 // DMA Interrupt Enable -#define USB_DMACTL7_MODE 0x00000004 // DMA Transfer Mode -#define USB_DMACTL7_DIR 0x00000002 // DMA Direction -#define USB_DMACTL7_ENABLE 0x00000001 // DMA Transfer Enable +#define USB_DMACTL7_ERR 0x0100 // Bus Error Bit +#define USB_DMACTL7_EP_M 0x00F0 // Endpoint number +#define USB_DMACTL7_IE 0x0008 // DMA Interrupt Enable +#define USB_DMACTL7_MODE 0x0004 // DMA Transfer Mode +#define USB_DMACTL7_DIR 0x0002 // DMA Direction +#define USB_DMACTL7_ENABLE 0x0001 // DMA Transfer Enable #define USB_DMACTL7_EP_S 4 //***************************************************************************** @@ -2422,7 +1929,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RQPKTCOUNT1_M 0x0000FFFF // Block Transfer Packet Count +#define USB_RQPKTCOUNT1_M 0xFFFF // Block Transfer Packet Count #define USB_RQPKTCOUNT1_S 0 //***************************************************************************** @@ -2431,7 +1938,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RQPKTCOUNT2_M 0x0000FFFF // Block Transfer Packet Count +#define USB_RQPKTCOUNT2_M 0xFFFF // Block Transfer Packet Count #define USB_RQPKTCOUNT2_S 0 //***************************************************************************** @@ -2440,7 +1947,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RQPKTCOUNT3_M 0x0000FFFF // Block Transfer Packet Count +#define USB_RQPKTCOUNT3_M 0xFFFF // Block Transfer Packet Count #define USB_RQPKTCOUNT3_S 0 //***************************************************************************** @@ -2449,7 +1956,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RQPKTCOUNT4_COUNT_M 0x0000FFFF // Block Transfer Packet Count +#define USB_RQPKTCOUNT4_COUNT_M 0xFFFF // Block Transfer Packet Count #define USB_RQPKTCOUNT4_COUNT_S 0 //***************************************************************************** @@ -2458,7 +1965,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RQPKTCOUNT5_COUNT_M 0x0000FFFF // Block Transfer Packet Count +#define USB_RQPKTCOUNT5_COUNT_M 0xFFFF // Block Transfer Packet Count #define USB_RQPKTCOUNT5_COUNT_S 0 //***************************************************************************** @@ -2467,7 +1974,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RQPKTCOUNT6_COUNT_M 0x0000FFFF // Block Transfer Packet Count +#define USB_RQPKTCOUNT6_COUNT_M 0xFFFF // Block Transfer Packet Count #define USB_RQPKTCOUNT6_COUNT_S 0 //***************************************************************************** @@ -2476,7 +1983,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RQPKTCOUNT7_COUNT_M 0x0000FFFF // Block Transfer Packet Count +#define USB_RQPKTCOUNT7_COUNT_M 0xFFFF // Block Transfer Packet Count #define USB_RQPKTCOUNT7_COUNT_S 0 //***************************************************************************** @@ -2485,19 +1992,19 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_RXDPKTBUFDIS_EP7 0x00000080 // EP7 RX Double-Packet Buffer +#define USB_RXDPKTBUFDIS_EP7 0x0080 // EP7 RX Double-Packet Buffer // Disable -#define USB_RXDPKTBUFDIS_EP6 0x00000040 // EP6 RX Double-Packet Buffer +#define USB_RXDPKTBUFDIS_EP6 0x0040 // EP6 RX Double-Packet Buffer // Disable -#define USB_RXDPKTBUFDIS_EP5 0x00000020 // EP5 RX Double-Packet Buffer +#define USB_RXDPKTBUFDIS_EP5 0x0020 // EP5 RX Double-Packet Buffer // Disable -#define USB_RXDPKTBUFDIS_EP4 0x00000010 // EP4 RX Double-Packet Buffer +#define USB_RXDPKTBUFDIS_EP4 0x0010 // EP4 RX Double-Packet Buffer // Disable -#define USB_RXDPKTBUFDIS_EP3 0x00000008 // EP3 RX Double-Packet Buffer +#define USB_RXDPKTBUFDIS_EP3 0x0008 // EP3 RX Double-Packet Buffer // Disable -#define USB_RXDPKTBUFDIS_EP2 0x00000004 // EP2 RX Double-Packet Buffer +#define USB_RXDPKTBUFDIS_EP2 0x0004 // EP2 RX Double-Packet Buffer // Disable -#define USB_RXDPKTBUFDIS_EP1 0x00000002 // EP1 RX Double-Packet Buffer +#define USB_RXDPKTBUFDIS_EP1 0x0002 // EP1 RX Double-Packet Buffer // Disable //***************************************************************************** @@ -2506,19 +2013,19 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // register. // //***************************************************************************** -#define USB_TXDPKTBUFDIS_EP7 0x00000080 // EP7 TX Double-Packet Buffer +#define USB_TXDPKTBUFDIS_EP7 0x0080 // EP7 TX Double-Packet Buffer // Disable -#define USB_TXDPKTBUFDIS_EP6 0x00000040 // EP6 TX Double-Packet Buffer +#define USB_TXDPKTBUFDIS_EP6 0x0040 // EP6 TX Double-Packet Buffer // Disable -#define USB_TXDPKTBUFDIS_EP5 0x00000020 // EP5 TX Double-Packet Buffer +#define USB_TXDPKTBUFDIS_EP5 0x0020 // EP5 TX Double-Packet Buffer // Disable -#define USB_TXDPKTBUFDIS_EP4 0x00000010 // EP4 TX Double-Packet Buffer +#define USB_TXDPKTBUFDIS_EP4 0x0010 // EP4 TX Double-Packet Buffer // Disable -#define USB_TXDPKTBUFDIS_EP3 0x00000008 // EP3 TX Double-Packet Buffer +#define USB_TXDPKTBUFDIS_EP3 0x0008 // EP3 TX Double-Packet Buffer // Disable -#define USB_TXDPKTBUFDIS_EP2 0x00000004 // EP2 TX Double-Packet Buffer +#define USB_TXDPKTBUFDIS_EP2 0x0004 // EP2 TX Double-Packet Buffer // Disable -#define USB_TXDPKTBUFDIS_EP1 0x00000002 // EP1 TX Double-Packet Buffer +#define USB_TXDPKTBUFDIS_EP1 0x0002 // EP1 TX Double-Packet Buffer // Disable //***************************************************************************** @@ -2526,7 +2033,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_CTO register. // //***************************************************************************** -#define USB_CTO_CCTV_M 0x0000FFFF // Configurable Chirp Timeout Value +#define USB_CTO_CCTV_M 0xFFFF // Configurable Chirp Timeout Value #define USB_CTO_CCTV_S 0 //***************************************************************************** @@ -2534,7 +2041,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_HHSRTN register. // //***************************************************************************** -#define USB_HHSRTN_HHSRTN_M 0x0000FFFF // HIgh Speed to UTM Operating +#define USB_HHSRTN_HHSRTN_M 0xFFFF // HIgh Speed to UTM Operating // Delay #define USB_HHSRTN_HHSRTN_S 0 @@ -2543,7 +2050,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_HSBT register. // //***************************************************************************** -#define USB_HSBT_HSBT_M 0x0000000F // High Speed Timeout Adder +#define USB_HSBT_HSBT_M 0x000F // High Speed Timeout Adder #define USB_HSBT_HSBT_S 0 //***************************************************************************** @@ -2551,11 +2058,11 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_LPMATTR register. // //***************************************************************************** -#define USB_LPMATTR_ENDPT_M 0x0000F000 // Endpoint -#define USB_LPMATTR_RMTWAK 0x00000100 // Remote Wake -#define USB_LPMATTR_HIRD_M 0x000000F0 // Host Initiated Resume Duration -#define USB_LPMATTR_LS_M 0x0000000F // Link State -#define USB_LPMATTR_LS_L1 0x00000001 // Sleep State (L1) +#define USB_LPMATTR_ENDPT_M 0xF000 // Endpoint +#define USB_LPMATTR_RMTWAK 0x0100 // Remote Wake +#define USB_LPMATTR_HIRD_M 0x00F0 // Host Initiated Resume Duration +#define USB_LPMATTR_LS_M 0x000F // Link State +#define USB_LPMATTR_LS_L1 0x0001 // Sleep State (L1) #define USB_LPMATTR_ENDPT_S 12 #define USB_LPMATTR_HIRD_S 4 @@ -2564,56 +2071,56 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_LPMCNTRL register. // //***************************************************************************** -#define USB_LPMCNTRL_NAK 0x00000010 // LPM NAK -#define USB_LPMCNTRL_EN_M 0x0000000C // LPM Enable -#define USB_LPMCNTRL_EN_NONE 0x00000000 // LPM and Extended transactions +#define USB_LPMCNTRL_NAK 0x0010 // LPM NAK +#define USB_LPMCNTRL_EN_M 0x000C // LPM Enable +#define USB_LPMCNTRL_EN_NONE 0x0000 // LPM and Extended transactions // are not supported. In this case, // the USB does not respond to LPM // transactions and LPM // transactions cause a timeout -#define USB_LPMCNTRL_EN_EXT 0x00000004 // LPM is not supported but +#define USB_LPMCNTRL_EN_EXT 0x0004 // LPM is not supported but // extended transactions are // supported. In this case, the USB // does respond to an LPM // transaction with a STALL -#define USB_LPMCNTRL_EN_LPMEXT 0x0000000C // The USB supports LPM extended +#define USB_LPMCNTRL_EN_LPMEXT 0x000C // The USB supports LPM extended // transactions. In this case, the // USB responds with a NYET or an // ACK as determined by the value // of TXLPM and other conditions -#define USB_LPMCNTRL_RES 0x00000002 // LPM Resume -#define USB_LPMCNTRL_TXLPM 0x00000001 // Transmit LPM Transaction Enable +#define USB_LPMCNTRL_RES 0x0002 // LPM Resume +#define USB_LPMCNTRL_TXLPM 0x0001 // Transmit LPM Transaction Enable //***************************************************************************** // // The following are defines for the bit fields in the USB_O_LPMIM register. // //***************************************************************************** -#define USB_LPMIM_ERR 0x00000020 // LPM Error Interrupt Mask -#define USB_LPMIM_RES 0x00000010 // LPM Resume Interrupt Mask -#define USB_LPMIM_NC 0x00000008 // LPM NC Interrupt Mask -#define USB_LPMIM_ACK 0x00000004 // LPM ACK Interrupt Mask -#define USB_LPMIM_NY 0x00000002 // LPM NY Interrupt Mask -#define USB_LPMIM_STALL 0x00000001 // LPM STALL Interrupt Mask +#define USB_LPMIM_ERR 0x0020 // LPM Error Interrupt Mask +#define USB_LPMIM_RES 0x0010 // LPM Resume Interrupt Mask +#define USB_LPMIM_NC 0x0008 // LPM NC Interrupt Mask +#define USB_LPMIM_ACK 0x0004 // LPM ACK Interrupt Mask +#define USB_LPMIM_NY 0x0002 // LPM NY Interrupt Mask +#define USB_LPMIM_STALL 0x0001 // LPM STALL Interrupt Mask //***************************************************************************** // // The following are defines for the bit fields in the USB_O_LPMRIS register. // //***************************************************************************** -#define USB_LPMRIS_ERR 0x00000020 // LPM Interrupt Status -#define USB_LPMRIS_RES 0x00000010 // LPM Resume Interrupt Status -#define USB_LPMRIS_NC 0x00000008 // LPM NC Interrupt Status -#define USB_LPMRIS_ACK 0x00000004 // LPM ACK Interrupt Status -#define USB_LPMRIS_NY 0x00000002 // LPM NY Interrupt Status -#define USB_LPMRIS_LPMST 0x00000001 // LPM STALL Interrupt Status +#define USB_LPMRIS_ERR 0x0020 // LPM Interrupt Status +#define USB_LPMRIS_RES 0x0010 // LPM Resume Interrupt Status +#define USB_LPMRIS_NC 0x0008 // LPM NC Interrupt Status +#define USB_LPMRIS_ACK 0x0004 // LPM ACK Interrupt Status +#define USB_LPMRIS_NY 0x0002 // LPM NY Interrupt Status +#define USB_LPMRIS_LPMST 0x0001 // LPM STALL Interrupt Status //***************************************************************************** // // The following are defines for the bit fields in the USB_O_LPMFADDR register. // //***************************************************************************** -#define USB_LPMFADDR_ADDR_M 0x0000007F // LPM Function Address +#define USB_LPMFADDR_ADDR_M 0x007F // LPM Function Address #define USB_LPMFADDR_ADDR_S 0 //***************************************************************************** @@ -2621,22 +2128,22 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_EPC register. // //***************************************************************************** -#define USB_EPC_PFLTACT_M 0x00000300 // Power Fault Action -#define USB_EPC_PFLTACT_UNCHG 0x00000000 // Unchanged -#define USB_EPC_PFLTACT_TRIS 0x00000100 // Tristate -#define USB_EPC_PFLTACT_LOW 0x00000200 // Low -#define USB_EPC_PFLTACT_HIGH 0x00000300 // High -#define USB_EPC_PFLTAEN 0x00000040 // Power Fault Action Enable -#define USB_EPC_PFLTSEN_HIGH 0x00000020 // Power Fault Sense -#define USB_EPC_PFLTEN 0x00000010 // Power Fault Input Enable -#define USB_EPC_EPENDE 0x00000004 // EPEN Drive Enable -#define USB_EPC_EPEN_M 0x00000003 // External Power Supply Enable +#define USB_EPC_PFLTACT_M 0x0300 // Power Fault Action +#define USB_EPC_PFLTACT_UNCHG 0x0000 // Unchanged +#define USB_EPC_PFLTACT_TRIS 0x0100 // Tristate +#define USB_EPC_PFLTACT_LOW 0x0200 // Low +#define USB_EPC_PFLTACT_HIGH 0x0300 // High +#define USB_EPC_PFLTAEN 0x0040 // Power Fault Action Enable +#define USB_EPC_PFLTSEN_HIGH 0x0020 // Power Fault Sense +#define USB_EPC_PFLTEN 0x0010 // Power Fault Input Enable +#define USB_EPC_EPENDE 0x0004 // EPEN Drive Enable +#define USB_EPC_EPEN_M 0x0003 // External Power Supply Enable // Configuration -#define USB_EPC_EPEN_LOW 0x00000000 // Power Enable Active Low -#define USB_EPC_EPEN_HIGH 0x00000001 // Power Enable Active High -#define USB_EPC_EPEN_VBLOW 0x00000002 // Power Enable High if VBUS Low +#define USB_EPC_EPEN_LOW 0x0000 // Power Enable Active Low +#define USB_EPC_EPEN_HIGH 0x0001 // Power Enable Active High +#define USB_EPC_EPEN_VBLOW 0x0002 // Power Enable High if VBUS Low // (OTG only) -#define USB_EPC_EPEN_VBHIGH 0x00000003 // Power Enable High if VBUS High +#define USB_EPC_EPEN_VBHIGH 0x0003 // Power Enable High if VBUS High // (OTG only) //***************************************************************************** @@ -2644,21 +2151,21 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_EPCRIS register. // //***************************************************************************** -#define USB_EPCRIS_PF 0x00000001 // USB Power Fault Interrupt Status +#define USB_EPCRIS_PF 0x0001 // USB Power Fault Interrupt Status //***************************************************************************** // // The following are defines for the bit fields in the USB_O_EPCIM register. // //***************************************************************************** -#define USB_EPCIM_PF 0x00000001 // USB Power Fault Interrupt Mask +#define USB_EPCIM_PF 0x0001 // USB Power Fault Interrupt Mask //***************************************************************************** // // The following are defines for the bit fields in the USB_O_EPCISC register. // //***************************************************************************** -#define USB_EPCISC_PF 0x00000001 // USB Power Fault Interrupt Status +#define USB_EPCISC_PF 0x0001 // USB Power Fault Interrupt Status // and Clear //***************************************************************************** @@ -2666,21 +2173,21 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_DRRIS register. // //***************************************************************************** -#define USB_DRRIS_RESUME 0x00000001 // RESUME Interrupt Status +#define USB_DRRIS_RESUME 0x0001 // RESUME Interrupt Status //***************************************************************************** // // The following are defines for the bit fields in the USB_O_DRIM register. // //***************************************************************************** -#define USB_DRIM_RESUME 0x00000001 // RESUME Interrupt Mask +#define USB_DRIM_RESUME 0x0001 // RESUME Interrupt Mask //***************************************************************************** // // The following are defines for the bit fields in the USB_O_DRISC register. // //***************************************************************************** -#define USB_DRISC_RESUME 0x00000001 // RESUME Interrupt Status and +#define USB_DRISC_RESUME 0x0001 // RESUME Interrupt Status and // Clear //***************************************************************************** @@ -2688,14 +2195,14 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_GPCS register. // //***************************************************************************** -#define USB_GPCS_DEVMOD_M 0x00000007 // Device Mode -#define USB_GPCS_DEVMOD_OTG 0x00000000 // Use USB0VBUS and USB0ID pin -#define USB_GPCS_DEVMOD_HOST 0x00000002 // Force USB0VBUS and USB0ID low -#define USB_GPCS_DEVMOD_DEV 0x00000003 // Force USB0VBUS and USB0ID high +#define USB_GPCS_DEVMOD_M 0x0007 // Device Mode +#define USB_GPCS_DEVMOD_OTG 0x0000 // Use USB0VBUS and USB0ID pin +#define USB_GPCS_DEVMOD_HOST 0x0002 // Force USB0VBUS and USB0ID low +#define USB_GPCS_DEVMOD_DEV 0x0003 // Force USB0VBUS and USB0ID high #define USB_GPCS_DEVMOD_HOSTVBUS \ - 0x00000004 // Use USB0VBUS and force USB0ID + 0x0004 // Use USB0VBUS and force USB0ID // low -#define USB_GPCS_DEVMOD_DEVVBUS 0x00000005 // Use USB0VBUS and force USB0ID +#define USB_GPCS_DEVMOD_DEVVBUS 0x0005 // Use USB0VBUS and force USB0ID // high //***************************************************************************** @@ -2703,28 +2210,28 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_VDC register. // //***************************************************************************** -#define USB_VDC_VBDEN 0x00000001 // VBUS Droop Enable +#define USB_VDC_VBDEN 0x0001 // VBUS Droop Enable //***************************************************************************** // // The following are defines for the bit fields in the USB_O_VDCRIS register. // //***************************************************************************** -#define USB_VDCRIS_VD 0x00000001 // VBUS Droop Raw Interrupt Status +#define USB_VDCRIS_VD 0x0001 // VBUS Droop Raw Interrupt Status //***************************************************************************** // // The following are defines for the bit fields in the USB_O_VDCIM register. // //***************************************************************************** -#define USB_VDCIM_VD 0x00000001 // VBUS Droop Interrupt Mask +#define USB_VDCIM_VD 0x0001 // VBUS Droop Interrupt Mask //***************************************************************************** // // The following are defines for the bit fields in the USB_O_VDCISC register. // //***************************************************************************** -#define USB_VDCISC_VD 0x00000001 // VBUS Droop Interrupt Status and +#define USB_VDCISC_VD 0x0001 // VBUS Droop Interrupt Status and // Clear //***************************************************************************** @@ -2732,17 +2239,17 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_PP register. // //***************************************************************************** -#define USB_PP_ECNT_M 0x0000FF00 // Endpoint Count -#define USB_PP_USB_M 0x000000C0 // USB Capability -#define USB_PP_USB_DEVICE 0x00000040 // DEVICE -#define USB_PP_USB_HOSTDEVICE 0x00000080 // HOST -#define USB_PP_USB_OTG 0x000000C0 // OTG -#define USB_PP_ULPI 0x00000020 // ULPI Present -#define USB_PP_PHY 0x00000010 // PHY Present -#define USB_PP_TYPE_M 0x0000000F // Controller Type -#define USB_PP_TYPE_0 0x00000000 // The first-generation USB +#define USB_PP_ECNT_M 0xFF00 // Endpoint Count +#define USB_PP_USB_M 0x00C0 // USB Capability +#define USB_PP_USB_DEVICE 0x0040 // DEVICE +#define USB_PP_USB_HOSTDEVICE 0x0080 // HOST +#define USB_PP_USB_OTG 0x00C0 // OTG +#define USB_PP_ULPI 0x0020 // ULPI Present +#define USB_PP_PHY 0x0010 // PHY Present +#define USB_PP_TYPE_M 0x000F // Controller Type +#define USB_PP_TYPE_0 0x0000 // The first-generation USB // controller -#define USB_PP_TYPE_1 0x00000001 // The second-generation USB +#define USB_PP_TYPE_1 0x0001 // The second-generation USB // controller revision #define USB_PP_ECNT_S 8 @@ -2758,9 +2265,9 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // The following are defines for the bit fields in the USB_O_CC register. // //***************************************************************************** -#define USB_CC_CLKEN 0x00000200 // USB Clock Enable -#define USB_CC_CSD 0x00000100 // Clock Source/Direction -#define USB_CC_CLKDIV_M 0x0000000F // PLL Clock Divisor +#define USB_CC_CLKEN 0x0200 // USB Clock Enable +#define USB_CC_CSD 0x0100 // Clock Source/Direction +#define USB_CC_CLKDIV_M 0x000F // PLL Clock Divisor #define USB_CC_CLKDIV_S 0 #ifdef __cplusplus -- cgit v1.3.1 From e9109f36ba873062812b37f2c40fc88bbf48af67 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 17 Aug 2024 16:34:24 +0700 Subject: refactor fifo configure/setup for dynamic and static fifo --- src/portable/mentor/musb/dcd_musb.c | 86 +++++++++++++++++++++++++++++++---- src/portable/mentor/musb/musb_max32.h | 39 ++++++++-------- src/portable/mentor/musb/musb_ti.h | 3 ++ src/portable/mentor/musb/musb_type.h | 3 +- 4 files changed, 101 insertions(+), 30 deletions(-) (limited to 'src/portable') diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 36690c952..e9d907828 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -41,7 +41,6 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); // Following symbols must be defined by port header // - musb_dcd_int_enable/disable/clear/get_enable // - musb_dcd_int_handler_enter/exit -// - musb_dcd_setup_fifo: Configuration of the EP's FIFO #if defined(TUP_USBIP_MUSB_TI) #include "musb_ti.h" #elif defined(TUP_USBIP_MUSB_ADI) @@ -88,19 +87,78 @@ typedef struct *------------------------------------------------------------------*/ static dcd_data_t _dcd; +#if MUSB_CFG_DYNAMIC_FIFO + +// musb is configured to use dynamic FIFO sizing. +// FF Size is encodded: 1 << (fifo_size[3:0] + 3) = 8 << fifo_size[3:0] +// FF Address is 8*ff_addr[12:0] +// First 64 bytes are reserved for EP0 +static uint32_t alloced_fifo_bytes; + TU_ATTR_ALWAYS_INLINE static inline void fifo_reset(musb_regs_t* musb, unsigned epnum, unsigned dir_in) { - musb->index = epnum; const uint8_t is_rx = 1 - dir_in; - -#if MUSB_CFG_DYNAMIC_FIFO + musb->index = epnum; musb->fifo_size[is_rx] = 0; musb->fifo_addr[is_rx] = 0; -#elif defined(TUP_USBIP_MUSB_ADI) +} + +TU_ATTR_ALWAYS_INLINE static inline bool fifo_configure(musb_regs_t* musb, unsigned epnum, unsigned dir_in, unsigned mps) { + // ffsize is log2(mps) - 3 (round up) + uint8_t ffsize = 28 - tu_min8(28, __builtin_clz(mps)); + // round up to the next power of 2 + if ((8u << ffsize) < mps) { + ++ffsize; + mps = 8 << ffsize; + } + + TU_ASSERT(alloced_fifo_bytes + mps <= MUSB_CFG_DYNAMIC_FIFO_SIZE); + const uint8_t is_rx = 1 - dir_in; + musb->index = epnum; + musb->fifo_addr[is_rx] = alloced_fifo_bytes / 8; + musb->fifo_size[is_rx] = ffsize; + + alloced_fifo_bytes += mps; + + return true; +} + +#else +TU_ATTR_ALWAYS_INLINE static inline void fifo_reset(musb_regs_t* musb, unsigned epnum, unsigned dir_in) { + const uint8_t is_rx = 1 - dir_in; + musb->index = epnum; + + #if defined(TUP_USBIP_MUSB_ADI) // Analog have custom double buffered in csrh register, disable it musb->indexed_csr.maxp_csr[is_rx].csrh |= MUSB_CSRH_DISABLE_DOUBLE_PACKET(is_rx); + #else + // disable double bufeffered in extended register + #endif +} + +TU_ATTR_ALWAYS_INLINE static inline bool fifo_configure(musb_regs_t* musb, unsigned epnum, unsigned dir_in, unsigned mps) { + (void) mps; + const uint8_t is_rx = 1 - dir_in; + musb->index = epnum; + + uint8_t csrh = 0; + +#if defined(TUP_USBIP_MUSB_ADI) + csrh = MUSB_CSRH_DISABLE_DOUBLE_PACKET(is_rx); #endif + +#if MUSB_CFG_SHARED_FIFO + if (dir_in) { + csrh |= MUSB_CSRH_TX_MODE; + } +#endif + + musb->indexed_csr.maxp_csr[is_rx].csrh |= csrh; + + return true; } +#endif + static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) { volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; @@ -463,6 +521,11 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) // faddr = 0, index = 0, flushes all ep fifos, clears all ep csr, enabled all ep interrupts static void process_bus_reset(uint8_t rhport) { musb_regs_t* musb = MUSB_REGS(rhport); + +#if MUSB_CFG_DYNAMIC_FIFO + alloced_fifo_bytes = CFG_TUD_ENDPOINT0_SIZE; +#endif + /* When bmRequestType is REQUEST_TYPE_INVALID(0xFF), a control transfer state is SETUP or STATUS stage. */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; _dcd.status_out = 0; @@ -594,8 +657,8 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) pipe->length = 0; pipe->remaining = 0; - musb_regs_t* musb_regs = MUSB_REGS(rhport); - musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); + musb_regs_t* musb = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn); const uint8_t is_rx = 1 - dir_in; ep_csr->maxp_csr[is_rx].maxp = mps; @@ -606,10 +669,10 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) csrl |= MUSB_CSRL_FLUSH_FIFO(is_rx); } ep_csr->maxp_csr[is_rx].csrl = csrl; - musb_regs->intren_ep[is_rx] |= TU_BIT(epn); + musb->intren_ep[is_rx] |= TU_BIT(epn); /* Setup FIFO */ - musb_dcd_setup_fifo(rhport, epn, dir_in, mps); + fifo_configure(musb, epn, dir_in, mps); return true; } @@ -619,6 +682,7 @@ void dcd_edpt_close_all(uint8_t rhport) musb_regs_t* musb = MUSB_REGS(rhport); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); + musb->intr_txen = 1; /* Enable only EP0 */ musb->intr_rxen = 0; for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { @@ -640,13 +704,15 @@ void dcd_edpt_close_all(uint8_t rhport) fifo_reset(musb, i, 0); fifo_reset(musb, i, 1); - } + alloced_fifo_bytes = CFG_TUD_ENDPOINT0_SIZE; + if (ie) musb_dcd_int_enable(rhport); } void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + // FIXME: we should implement iso_alloc() and iso_activate() unsigned const epn = tu_edpt_number(ep_addr); unsigned const dir_in = tu_edpt_dir(ep_addr); musb_regs_t* musb = MUSB_REGS(rhport); diff --git a/src/portable/mentor/musb/musb_max32.h b/src/portable/mentor/musb/musb_max32.h index 73f63ee2e..1320239c9 100644 --- a/src/portable/mentor/musb/musb_max32.h +++ b/src/portable/mentor/musb/musb_max32.h @@ -34,7 +34,8 @@ extern "C" { #include "mxc_device.h" #include "usbhs_regs.h" -#define MUSB_CFG_DYNAMIC_FIFO 0 +#define MUSB_CFG_SHARED_FIFO 1 // shared FIFO for TX and RX endpoints +#define MUSB_CFG_DYNAMIC_FIFO 0 // dynamic EP FIFO sizing const uintptr_t MUSB_BASES[] = { MXC_BASE_USBHS }; @@ -141,24 +142,24 @@ static inline void musb_dcd_phy_init(uint8_t rhport) { hs_phy->m31_phy_ponrst = 1; } -static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) { - (void) mps; - - //Most likely the caller has already grabbed the right register block. But - //as a precaution save and restore the register bank anyways - unsigned saved_index = musb_periph_inst[rhport]->index; - - musb_periph_inst[rhport]->index = epnum; - - //Disable double buffering - if (dir_in) { - musb_periph_inst[rhport]->incsru |= (MXC_F_USBHS_INCSRU_DPKTBUFDIS | MXC_F_USBHS_INCSRU_MODE); - } else { - musb_periph_inst[rhport]->outcsru |= (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS); - } - - musb_periph_inst[rhport]->index = saved_index; -} +// static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) { +// (void) mps; +// +// //Most likely the caller has already grabbed the right register block. But +// //as a precaution save and restore the register bank anyways +// unsigned saved_index = musb_periph_inst[rhport]->index; +// +// musb_periph_inst[rhport]->index = epnum; +// +// //Disable double buffering +// if (dir_in) { +// musb_periph_inst[rhport]->incsru |= (MXC_F_USBHS_INCSRU_DPKTBUFDIS | MXC_F_USBHS_INCSRU_MODE); +// } else { +// musb_periph_inst[rhport]->outcsru |= (MXC_F_USBHS_OUTCSRU_DPKTBUFDIS); +// } +// +// musb_periph_inst[rhport]->index = saved_index; +// } #endif // CFG_TUD_ENABLED diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h index e43b3d3c0..7c15b61ad 100644 --- a/src/portable/mentor/musb/musb_ti.h +++ b/src/portable/mentor/musb/musb_ti.h @@ -42,6 +42,7 @@ #error "Unsupported MCUs" #endif +#define MUSB_CFG_SHARED_FIFO 0 #define MUSB_CFG_DYNAMIC_FIFO 1 #define MUSB_CFG_DYNAMIC_FIFO_SIZE 4096 @@ -91,6 +92,7 @@ static inline void musb_dcd_int_handler_exit(uint8_t rhport) { //Nothing to do for this part } +#if 0 typedef struct { uint_fast16_t beg; /* offset of including first element */ uint_fast16_t end; /* offset of excluding the last element */ @@ -224,6 +226,7 @@ static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned musb_periph_inst[rhport]->RXFIFOSZ = size_in_log2_minus3; } } +#endif #endif // CFG_TUD_ENABLED diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index ee0187270..08f26edbd 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -261,7 +261,7 @@ typedef struct TU_ATTR_PACKED { //------------- Non-Indexed Endpoint CSRs -------------// // TI tm4c can access this directly, but should use indexed_csr for portability - musb_ep_csr_t ep_csr[16]; // 0x100-0x1FF: EP0-15 CSR + musb_ep_csr_t abs_csr[16]; // 0x100-0x1FF: EP0-15 CSR } musb_regs_t; TU_VERIFY_STATIC(sizeof(musb_regs_t) == 0x200, "size is not correct"); @@ -307,6 +307,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // 0x13, 0x17: TX/RX CSRH #define MUSB_CSRH_DISABLE_DOUBLE_PACKET(_rx) (1u << 1) +#define MUSB_CSRH_TX_MODE (1u << 5) // 1 = TX, 0 = RX. only relevant for SHARED FIFO //***************************************************************************** -- cgit v1.3.1 From 993473312b390b722d8693c23310b306997f8c2b Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 17 Aug 2024 17:09:38 +0700 Subject: minor update --- src/portable/mentor/musb/dcd_musb.c | 31 ++++++++++++++++++------------- src/portable/mentor/musb/musb_max32.h | 24 ++++-------------------- src/portable/mentor/musb/musb_ti.h | 5 ----- 3 files changed, 22 insertions(+), 38 deletions(-) (limited to 'src/portable') diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index e9d907828..3dcb9cdf1 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -29,6 +29,9 @@ #if CFG_TUD_ENABLED && defined(TUP_USBIP_MUSB) +#define MUSB_DEBUG 2 +#define MUSB_REGS(rhport) ((musb_regs_t*) MUSB_BASES[rhport]) + #if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) /* GCC warns that an address may be unaligned, even though * the target CPU has the capability for unaligned memory access. */ @@ -49,10 +52,6 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); #error "Unsupported MCU" #endif -#define MUSB_REGS(rhport) ((musb_regs_t*) MUSB_BASES[rhport]) - -#define MUSB_DEBUG 2 - /*------------------------------------------------------------------ * MACRO TYPEDEF CONSTANT ENUM DECLARATION *------------------------------------------------------------------*/ @@ -60,9 +59,9 @@ _Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); #define REQUEST_TYPE_INVALID (0xFFu) typedef union { - uint8_t u8; - uint16_t u16; - uint32_t u32; + volatile uint8_t u8; + volatile uint16_t u16; + volatile uint32_t u32; } hw_fifo_t; typedef struct TU_ATTR_PACKED @@ -223,11 +222,12 @@ static void pipe_read_write_packet_ff(tu_fifo_t *f, volatile void *fifo, unsigne static void process_setup_packet(uint8_t rhport) { musb_regs_t* musb_regs = MUSB_REGS(rhport); + + // Read setup packet uint32_t *p = (void*)&_dcd.setup_packet; volatile uint32_t *fifo_ptr = &musb_regs->fifo[0]; - - p[0] = *fifo_ptr; - p[1] = *fifo_ptr; + p[0] = *fifo_ptr; + p[1] = *fifo_ptr; _dcd.pipe0.buf = NULL; _dcd.pipe0.length = 0; @@ -407,6 +407,7 @@ static void process_ep0(uint8_t rhport) uint_fast8_t csrl = ep_csr->csr0l; // TU_LOG1(" EP0 ep_csr->csr0l = %x\r\n", csrl); + // 21.1.5: endpoint 0 service routine as peripheral if (csrl & USB_CSRL0_STALLED) { /* Returned STALL packet to HOST. */ @@ -705,7 +706,10 @@ void dcd_edpt_close_all(uint8_t rhport) fifo_reset(musb, i, 0); fifo_reset(musb, i, 1); } + +#if MUSB_CFG_DYNAMIC_FIFO alloced_fifo_bytes = CFG_TUD_ENDPOINT0_SIZE; +#endif if (ie) musb_dcd_int_enable(rhport); } @@ -822,10 +826,12 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) * ISR *-------------------------------------------------------------------*/ void dcd_int_handler(uint8_t rhport) { + musb_regs_t* musb_regs = MUSB_REGS(rhport); + const uint8_t saved_index = musb_regs->index; // save endpoint index + //Part specific ISR setup/entry musb_dcd_int_handler_enter(rhport); - musb_regs_t* musb_regs = MUSB_REGS(rhport); uint_fast8_t intr_usb = musb_regs->intr_usb; // a read will clear this interrupt status uint_fast8_t intr_tx = musb_regs->intr_tx; // a read will clear this interrupt status uint_fast8_t intr_rx = musb_regs->intr_rx; // a read will clear this interrupt status @@ -865,8 +871,7 @@ void dcd_int_handler(uint8_t rhport) { intr_rx &= ~TU_BIT(num); } - //Part specific ISR exit - musb_dcd_int_handler_exit(rhport); + musb_regs->index = saved_index; // restore endpoint index } #endif diff --git a/src/portable/mentor/musb/musb_max32.h b/src/portable/mentor/musb/musb_max32.h index 1320239c9..38e80f680 100644 --- a/src/portable/mentor/musb/musb_max32.h +++ b/src/portable/mentor/musb/musb_max32.h @@ -42,11 +42,6 @@ const uintptr_t MUSB_BASES[] = { MXC_BASE_USBHS }; #if CFG_TUD_ENABLED #define USBHS_M31_CLOCK_RECOVERY -// Mapping of peripheral instances to port. Currently just 1. -static mxc_usbhs_regs_t* const musb_periph_inst[] = { - MXC_USBHS -}; - // Mapping of IRQ numbers to port. Currently just 1. static const IRQn_Type musb_irqs[] = { USB_IRQn @@ -77,31 +72,21 @@ static inline void musb_dcd_int_clear(uint8_t rhport) { NVIC_ClearPendingIRQ(musb_irqs[rhport]); } -//Used to save and restore user's register map when interrupt occurs -static volatile unsigned isr_saved_index = 0; - static inline void musb_dcd_int_handler_enter(uint8_t rhport) { + mxc_usbhs_regs_t* hs_phy = MXC_USBHS; uint32_t mxm_int, mxm_int_en, mxm_is; - //save current register index - isr_saved_index = musb_periph_inst[rhport]->index; - //Handle PHY specific events - mxm_int = musb_periph_inst[rhport]->mxm_int; - mxm_int_en = musb_periph_inst[rhport]->mxm_int_en; + mxm_int = hs_phy->mxm_int; + mxm_int_en = hs_phy->mxm_int_en; mxm_is = mxm_int & mxm_int_en; - musb_periph_inst[rhport]->mxm_int = mxm_is; + hs_phy->mxm_int = mxm_is; if (mxm_is & MXC_F_USBHS_MXM_INT_NOVBUS) { dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); } } -static inline void musb_dcd_int_handler_exit(uint8_t rhport) { - //restore register index - musb_periph_inst[rhport]->index = isr_saved_index; -} - static inline void musb_dcd_phy_init(uint8_t rhport) { (void) rhport; mxc_usbhs_regs_t* hs_phy = MXC_USBHS; @@ -120,7 +105,6 @@ static inline void musb_dcd_phy_init(uint8_t rhport) { hs_phy->m31_phy_xcfgi_95_64 = 0x1 << (72 - 64); hs_phy->m31_phy_xcfgi_127_96 = 0; - #ifdef USBHS_M31_CLOCK_RECOVERY hs_phy->m31_phy_noncry_rstb = 1; hs_phy->m31_phy_noncry_en = 1; diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h index 7c15b61ad..680bebde7 100644 --- a/src/portable/mentor/musb/musb_ti.h +++ b/src/portable/mentor/musb/musb_ti.h @@ -87,11 +87,6 @@ static inline void musb_dcd_int_handler_enter(uint8_t rhport) { //Nothing to do for this part } -static inline void musb_dcd_int_handler_exit(uint8_t rhport) { - (void)rhport; - //Nothing to do for this part -} - #if 0 typedef struct { uint_fast16_t beg; /* offset of including first element */ -- cgit v1.3.1 From 123830c1f00813d86d0405dc7a5624ccb1220a31 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 17 Aug 2024 19:06:19 +0700 Subject: remove unused register def --- src/portable/mentor/musb/musb_type.h | 1594 ++-------------------------------- 1 file changed, 59 insertions(+), 1535 deletions(-) (limited to 'src/portable') diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index 08f26edbd..619eb0108 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -262,9 +262,37 @@ typedef struct TU_ATTR_PACKED { //------------- Non-Indexed Endpoint CSRs -------------// // TI tm4c can access this directly, but should use indexed_csr for portability musb_ep_csr_t abs_csr[16]; // 0x100-0x1FF: EP0-15 CSR + + //------------- DMA -------------// + __IO uint8_t dma_intr; // 0x200: DMA_INTR + __R uint8_t rsv_0x201_0x203[3]; // 0x201-0x203: Reserved + struct { + __IO uint16_t cntl; // 0x204: DMA_CNTL + __IO uint16_t rsv_0x206; // 0x206: Reserved + __IO uint32_t addr; // 0x208: DMA_ADDR + __IO uint32_t count; // 0x20C: DMA_COUNT + __IO uint32_t rsv_0x210; // 0x210: Reserved + }dma[8]; + __R uint32_t rsv_0x284_0x2FF[31]; // 0x284-0x2FF: Reserved + + //------------- Extended -------------// + __R uint32_t rsv_0x300; // 0x300: Reserved + struct { + __IO uint16_t count; // 0x304: REQ_PACKET_COUNT + __R uint16_t rsv_0x306; // 0x306: Reserved + }req_packet[15]; + + __IO uint16_t rx_doulbe_packet_disable; // 0x340: RX_DOUBLE_PACKET_DISABLE + __IO uint16_t tx_double_packet_disable; // 0x342: TX_DOUBLE_PACKET_DISABLE + + __IO uint16_t chirp_timeout; // 0x344: CHIRP_TIMEOUT + __IO uint16_t hs_to_utm; // 0x346: HS_TO_UTM delay + __IO uint16_t hs_timeout_adder; // 0x348: HS_TIMEOUT_ADDER + + __R uint8_t rsv_34A_34f[6]; // 0x34A-0x34F: Reserved } musb_regs_t; -TU_VERIFY_STATIC(sizeof(musb_regs_t) == 0x200, "size is not correct"); +TU_VERIFY_STATIC(sizeof(musb_regs_t) == 0x350, "size is not correct"); //--------------------------------------------------------------------+ // Helper @@ -566,14 +594,6 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ #define USB_CSRH0_DT 0x0002 // Data Toggle #define USB_CSRH0_FLUSH 0x0001 // Flush FIFO -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_COUNT0 register. -// -//***************************************************************************** -#define USB_COUNT0_COUNT_M 0x007F // FIFO Count -#define USB_COUNT0_COUNT_S 0 - //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TYPE0 register. @@ -592,14 +612,6 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ #define USB_NAKLMT_NAKLMT_M 0x001F // EP0 NAK Limit #define USB_NAKLMT_NAKLMT_S 0 -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXMAXP1 register. -// -//***************************************************************************** -#define USB_TXMAXP1_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_TXMAXP1_MAXLOAD_S 0 - //***************************************************************************** // // The following are defines for the bit fields in the USB_O_TXCSRL1 register. @@ -630,14 +642,6 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ #define USB_TXCSRH1_DTWE 0x0002 // Data Toggle Write Enable #define USB_TXCSRH1_DT 0x0001 // Data Toggle -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXMAXP1 register. -// -//***************************************************************************** -#define USB_RXMAXP1_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_RXMAXP1_MAXLOAD_S 0 - //***************************************************************************** // // The following are defines for the bit fields in the USB_O_RXCSRL1 register. @@ -669,16 +673,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ #define USB_RXCSRH1_DMAMOD 0x0008 // DMA Request Mode #define USB_RXCSRH1_DTWE 0x0004 // Data Toggle Write Enable #define USB_RXCSRH1_DT 0x0002 // Data Toggle -#define USB_RXCSRH1_INCOMPRX 0x0001 // Incomplete RX Transmission - // Status - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCOUNT1 register. -// -//***************************************************************************** -#define USB_RXCOUNT1_COUNT_M 0x1FFF // Receive Packet Count -#define USB_RXCOUNT1_COUNT_S 0 +#define USB_RXCSRH1_INCOMPRX 0x0001 // Incomplete RX Transmission Status //***************************************************************************** // @@ -740,1537 +735,66 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TXMAXP2 register. -// -//***************************************************************************** -#define USB_TXMAXP2_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_TXMAXP2_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRL2 register. -// -//***************************************************************************** -#define USB_TXCSRL2_NAKTO 0x0080 // NAK Timeout -#define USB_TXCSRL2_CLRDT 0x0040 // Clear Data Toggle -#define USB_TXCSRL2_STALLED 0x0020 // Endpoint Stalled -#define USB_TXCSRL2_SETUP 0x0010 // Setup Packet -#define USB_TXCSRL2_STALL 0x0010 // Send STALL -#define USB_TXCSRL2_FLUSH 0x0008 // Flush FIFO -#define USB_TXCSRL2_ERROR 0x0004 // Error -#define USB_TXCSRL2_UNDRN 0x0004 // Underrun -#define USB_TXCSRL2_FIFONE 0x0002 // FIFO Not Empty -#define USB_TXCSRL2_TXRDY 0x0001 // Transmit Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRH2 register. -// -//***************************************************************************** -#define USB_TXCSRH2_AUTOSET 0x0080 // Auto Set -#define USB_TXCSRH2_ISO 0x0040 // Isochronous Transfers -#define USB_TXCSRH2_MODE 0x0020 // Mode -#define USB_TXCSRH2_DMAEN 0x0010 // DMA Request Enable -#define USB_TXCSRH2_FDT 0x0008 // Force Data Toggle -#define USB_TXCSRH2_DMAMOD 0x0004 // DMA Request Mode -#define USB_TXCSRH2_DTWE 0x0002 // Data Toggle Write Enable -#define USB_TXCSRH2_DT 0x0001 // Data Toggle - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXMAXP2 register. -// -//***************************************************************************** -#define USB_RXMAXP2_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_RXMAXP2_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRL2 register. -// -//***************************************************************************** -#define USB_RXCSRL2_CLRDT 0x0080 // Clear Data Toggle -#define USB_RXCSRL2_STALLED 0x0040 // Endpoint Stalled -#define USB_RXCSRL2_REQPKT 0x0020 // Request Packet -#define USB_RXCSRL2_STALL 0x0020 // Send STALL -#define USB_RXCSRL2_FLUSH 0x0010 // Flush FIFO -#define USB_RXCSRL2_DATAERR 0x0008 // Data Error -#define USB_RXCSRL2_NAKTO 0x0008 // NAK Timeout -#define USB_RXCSRL2_ERROR 0x0004 // Error -#define USB_RXCSRL2_OVER 0x0004 // Overrun -#define USB_RXCSRL2_FULL 0x0002 // FIFO Full -#define USB_RXCSRL2_RXRDY 0x0001 // Receive Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRH2 register. -// -//***************************************************************************** -#define USB_RXCSRH2_AUTOCL 0x0080 // Auto Clear -#define USB_RXCSRH2_AUTORQ 0x0040 // Auto Request -#define USB_RXCSRH2_ISO 0x0040 // Isochronous Transfers -#define USB_RXCSRH2_DMAEN 0x0020 // DMA Request Enable -#define USB_RXCSRH2_DISNYET 0x0010 // Disable NYET -#define USB_RXCSRH2_PIDERR 0x0010 // PID Error -#define USB_RXCSRH2_DMAMOD 0x0008 // DMA Request Mode -#define USB_RXCSRH2_DTWE 0x0004 // Data Toggle Write Enable -#define USB_RXCSRH2_DT 0x0002 // Data Toggle -#define USB_RXCSRH2_INCOMPRX 0x0001 // Incomplete RX Transmission - // Status - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCOUNT2 register. -// -//***************************************************************************** -#define USB_RXCOUNT2_COUNT_M 0x1FFF // Receive Packet Count -#define USB_RXCOUNT2_COUNT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXTYPE2 register. -// -//***************************************************************************** -#define USB_TXTYPE2_SPEED_M 0x00C0 // Operating Speed -#define USB_TXTYPE2_SPEED_DFLT 0x0000 // Default -#define USB_TXTYPE2_SPEED_HIGH 0x0040 // High -#define USB_TXTYPE2_SPEED_FULL 0x0080 // Full -#define USB_TXTYPE2_SPEED_LOW 0x00C0 // Low -#define USB_TXTYPE2_PROTO_M 0x0030 // Protocol -#define USB_TXTYPE2_PROTO_CTRL 0x0000 // Control -#define USB_TXTYPE2_PROTO_ISOC 0x0010 // Isochronous -#define USB_TXTYPE2_PROTO_BULK 0x0020 // Bulk -#define USB_TXTYPE2_PROTO_INT 0x0030 // Interrupt -#define USB_TXTYPE2_TEP_M 0x000F // Target Endpoint Number -#define USB_TXTYPE2_TEP_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXINTERVAL2 -// register. -// -//***************************************************************************** -#define USB_TXINTERVAL2_TXPOLL_M 0x00FF // TX Polling -#define USB_TXINTERVAL2_NAKLMT_M 0x00FF // NAK Limit -#define USB_TXINTERVAL2_NAKLMT_S 0 -#define USB_TXINTERVAL2_TXPOLL_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXTYPE2 register. -// -//***************************************************************************** -#define USB_RXTYPE2_SPEED_M 0x00C0 // Operating Speed -#define USB_RXTYPE2_SPEED_DFLT 0x0000 // Default -#define USB_RXTYPE2_SPEED_HIGH 0x0040 // High -#define USB_RXTYPE2_SPEED_FULL 0x0080 // Full -#define USB_RXTYPE2_SPEED_LOW 0x00C0 // Low -#define USB_RXTYPE2_PROTO_M 0x0030 // Protocol -#define USB_RXTYPE2_PROTO_CTRL 0x0000 // Control -#define USB_RXTYPE2_PROTO_ISOC 0x0010 // Isochronous -#define USB_RXTYPE2_PROTO_BULK 0x0020 // Bulk -#define USB_RXTYPE2_PROTO_INT 0x0030 // Interrupt -#define USB_RXTYPE2_TEP_M 0x000F // Target Endpoint Number -#define USB_RXTYPE2_TEP_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXINTERVAL2 -// register. -// -//***************************************************************************** -#define USB_RXINTERVAL2_TXPOLL_M 0x00FF // RX Polling -#define USB_RXINTERVAL2_NAKLMT_M 0x00FF // NAK Limit -#define USB_RXINTERVAL2_TXPOLL_S 0 -#define USB_RXINTERVAL2_NAKLMT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXMAXP3 register. -// -//***************************************************************************** -#define USB_TXMAXP3_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_TXMAXP3_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRL3 register. -// -//***************************************************************************** -#define USB_TXCSRL3_NAKTO 0x0080 // NAK Timeout -#define USB_TXCSRL3_CLRDT 0x0040 // Clear Data Toggle -#define USB_TXCSRL3_STALLED 0x0020 // Endpoint Stalled -#define USB_TXCSRL3_SETUP 0x0010 // Setup Packet -#define USB_TXCSRL3_STALL 0x0010 // Send STALL -#define USB_TXCSRL3_FLUSH 0x0008 // Flush FIFO -#define USB_TXCSRL3_ERROR 0x0004 // Error -#define USB_TXCSRL3_UNDRN 0x0004 // Underrun -#define USB_TXCSRL3_FIFONE 0x0002 // FIFO Not Empty -#define USB_TXCSRL3_TXRDY 0x0001 // Transmit Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRH3 register. -// -//***************************************************************************** -#define USB_TXCSRH3_AUTOSET 0x0080 // Auto Set -#define USB_TXCSRH3_ISO 0x0040 // Isochronous Transfers -#define USB_TXCSRH3_MODE 0x0020 // Mode -#define USB_TXCSRH3_DMAEN 0x0010 // DMA Request Enable -#define USB_TXCSRH3_FDT 0x0008 // Force Data Toggle -#define USB_TXCSRH3_DMAMOD 0x0004 // DMA Request Mode -#define USB_TXCSRH3_DTWE 0x0002 // Data Toggle Write Enable -#define USB_TXCSRH3_DT 0x0001 // Data Toggle - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXMAXP3 register. -// -//***************************************************************************** -#define USB_RXMAXP3_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_RXMAXP3_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRL3 register. -// -//***************************************************************************** -#define USB_RXCSRL3_CLRDT 0x0080 // Clear Data Toggle -#define USB_RXCSRL3_STALLED 0x0040 // Endpoint Stalled -#define USB_RXCSRL3_STALL 0x0020 // Send STALL -#define USB_RXCSRL3_REQPKT 0x0020 // Request Packet -#define USB_RXCSRL3_FLUSH 0x0010 // Flush FIFO -#define USB_RXCSRL3_DATAERR 0x0008 // Data Error -#define USB_RXCSRL3_NAKTO 0x0008 // NAK Timeout -#define USB_RXCSRL3_ERROR 0x0004 // Error -#define USB_RXCSRL3_OVER 0x0004 // Overrun -#define USB_RXCSRL3_FULL 0x0002 // FIFO Full -#define USB_RXCSRL3_RXRDY 0x0001 // Receive Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRH3 register. -// -//***************************************************************************** -#define USB_RXCSRH3_AUTOCL 0x0080 // Auto Clear -#define USB_RXCSRH3_AUTORQ 0x0040 // Auto Request -#define USB_RXCSRH3_ISO 0x0040 // Isochronous Transfers -#define USB_RXCSRH3_DMAEN 0x0020 // DMA Request Enable -#define USB_RXCSRH3_DISNYET 0x0010 // Disable NYET -#define USB_RXCSRH3_PIDERR 0x0010 // PID Error -#define USB_RXCSRH3_DMAMOD 0x0008 // DMA Request Mode -#define USB_RXCSRH3_DTWE 0x0004 // Data Toggle Write Enable -#define USB_RXCSRH3_DT 0x0002 // Data Toggle -#define USB_RXCSRH3_INCOMPRX 0x0001 // Incomplete RX Transmission - // Status - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCOUNT3 register. -// -//***************************************************************************** -#define USB_RXCOUNT3_COUNT_M 0x1FFF // Receive Packet Count -#define USB_RXCOUNT3_COUNT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXTYPE3 register. -// -//***************************************************************************** -#define USB_TXTYPE3_SPEED_M 0x00C0 // Operating Speed -#define USB_TXTYPE3_SPEED_DFLT 0x0000 // Default -#define USB_TXTYPE3_SPEED_HIGH 0x0040 // High -#define USB_TXTYPE3_SPEED_FULL 0x0080 // Full -#define USB_TXTYPE3_SPEED_LOW 0x00C0 // Low -#define USB_TXTYPE3_PROTO_M 0x0030 // Protocol -#define USB_TXTYPE3_PROTO_CTRL 0x0000 // Control -#define USB_TXTYPE3_PROTO_ISOC 0x0010 // Isochronous -#define USB_TXTYPE3_PROTO_BULK 0x0020 // Bulk -#define USB_TXTYPE3_PROTO_INT 0x0030 // Interrupt -#define USB_TXTYPE3_TEP_M 0x000F // Target Endpoint Number -#define USB_TXTYPE3_TEP_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXINTERVAL3 -// register. -// -//***************************************************************************** -#define USB_TXINTERVAL3_TXPOLL_M 0x00FF // TX Polling -#define USB_TXINTERVAL3_NAKLMT_M 0x00FF // NAK Limit -#define USB_TXINTERVAL3_TXPOLL_S 0 -#define USB_TXINTERVAL3_NAKLMT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXTYPE3 register. -// -//***************************************************************************** -#define USB_RXTYPE3_SPEED_M 0x00C0 // Operating Speed -#define USB_RXTYPE3_SPEED_DFLT 0x0000 // Default -#define USB_RXTYPE3_SPEED_HIGH 0x0040 // High -#define USB_RXTYPE3_SPEED_FULL 0x0080 // Full -#define USB_RXTYPE3_SPEED_LOW 0x00C0 // Low -#define USB_RXTYPE3_PROTO_M 0x0030 // Protocol -#define USB_RXTYPE3_PROTO_CTRL 0x0000 // Control -#define USB_RXTYPE3_PROTO_ISOC 0x0010 // Isochronous -#define USB_RXTYPE3_PROTO_BULK 0x0020 // Bulk -#define USB_RXTYPE3_PROTO_INT 0x0030 // Interrupt -#define USB_RXTYPE3_TEP_M 0x000F // Target Endpoint Number -#define USB_RXTYPE3_TEP_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXINTERVAL3 -// register. -// -//***************************************************************************** -#define USB_RXINTERVAL3_TXPOLL_M 0x00FF // RX Polling -#define USB_RXINTERVAL3_NAKLMT_M 0x00FF // NAK Limit -#define USB_RXINTERVAL3_TXPOLL_S 0 -#define USB_RXINTERVAL3_NAKLMT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXMAXP4 register. -// -//***************************************************************************** -#define USB_TXMAXP4_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_TXMAXP4_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRL4 register. -// -//***************************************************************************** -#define USB_TXCSRL4_NAKTO 0x0080 // NAK Timeout -#define USB_TXCSRL4_CLRDT 0x0040 // Clear Data Toggle -#define USB_TXCSRL4_STALLED 0x0020 // Endpoint Stalled -#define USB_TXCSRL4_SETUP 0x0010 // Setup Packet -#define USB_TXCSRL4_STALL 0x0010 // Send STALL -#define USB_TXCSRL4_FLUSH 0x0008 // Flush FIFO -#define USB_TXCSRL4_ERROR 0x0004 // Error -#define USB_TXCSRL4_UNDRN 0x0004 // Underrun -#define USB_TXCSRL4_FIFONE 0x0002 // FIFO Not Empty -#define USB_TXCSRL4_TXRDY 0x0001 // Transmit Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRH4 register. -// -//***************************************************************************** -#define USB_TXCSRH4_AUTOSET 0x0080 // Auto Set -#define USB_TXCSRH4_ISO 0x0040 // Isochronous Transfers -#define USB_TXCSRH4_MODE 0x0020 // Mode -#define USB_TXCSRH4_DMAEN 0x0010 // DMA Request Enable -#define USB_TXCSRH4_FDT 0x0008 // Force Data Toggle -#define USB_TXCSRH4_DMAMOD 0x0004 // DMA Request Mode -#define USB_TXCSRH4_DTWE 0x0002 // Data Toggle Write Enable -#define USB_TXCSRH4_DT 0x0001 // Data Toggle - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXMAXP4 register. -// -//***************************************************************************** -#define USB_RXMAXP4_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_RXMAXP4_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRL4 register. -// -//***************************************************************************** -#define USB_RXCSRL4_CLRDT 0x0080 // Clear Data Toggle -#define USB_RXCSRL4_STALLED 0x0040 // Endpoint Stalled -#define USB_RXCSRL4_STALL 0x0020 // Send STALL -#define USB_RXCSRL4_REQPKT 0x0020 // Request Packet -#define USB_RXCSRL4_FLUSH 0x0010 // Flush FIFO -#define USB_RXCSRL4_NAKTO 0x0008 // NAK Timeout -#define USB_RXCSRL4_DATAERR 0x0008 // Data Error -#define USB_RXCSRL4_OVER 0x0004 // Overrun -#define USB_RXCSRL4_ERROR 0x0004 // Error -#define USB_RXCSRL4_FULL 0x0002 // FIFO Full -#define USB_RXCSRL4_RXRDY 0x0001 // Receive Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRH4 register. -// -//***************************************************************************** -#define USB_RXCSRH4_AUTOCL 0x0080 // Auto Clear -#define USB_RXCSRH4_AUTORQ 0x0040 // Auto Request -#define USB_RXCSRH4_ISO 0x0040 // Isochronous Transfers -#define USB_RXCSRH4_DMAEN 0x0020 // DMA Request Enable -#define USB_RXCSRH4_DISNYET 0x0010 // Disable NYET -#define USB_RXCSRH4_PIDERR 0x0010 // PID Error -#define USB_RXCSRH4_DMAMOD 0x0008 // DMA Request Mode -#define USB_RXCSRH4_DTWE 0x0004 // Data Toggle Write Enable -#define USB_RXCSRH4_DT 0x0002 // Data Toggle -#define USB_RXCSRH4_INCOMPRX 0x0001 // Incomplete RX Transmission - // Status - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCOUNT4 register. -// -//***************************************************************************** -#define USB_RXCOUNT4_COUNT_M 0x1FFF // Receive Packet Count -#define USB_RXCOUNT4_COUNT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXTYPE4 register. -// -//***************************************************************************** -#define USB_TXTYPE4_SPEED_M 0x00C0 // Operating Speed -#define USB_TXTYPE4_SPEED_DFLT 0x0000 // Default -#define USB_TXTYPE4_SPEED_HIGH 0x0040 // High -#define USB_TXTYPE4_SPEED_FULL 0x0080 // Full -#define USB_TXTYPE4_SPEED_LOW 0x00C0 // Low -#define USB_TXTYPE4_PROTO_M 0x0030 // Protocol -#define USB_TXTYPE4_PROTO_CTRL 0x0000 // Control -#define USB_TXTYPE4_PROTO_ISOC 0x0010 // Isochronous -#define USB_TXTYPE4_PROTO_BULK 0x0020 // Bulk -#define USB_TXTYPE4_PROTO_INT 0x0030 // Interrupt -#define USB_TXTYPE4_TEP_M 0x000F // Target Endpoint Number -#define USB_TXTYPE4_TEP_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXINTERVAL4 -// register. -// -//***************************************************************************** -#define USB_TXINTERVAL4_TXPOLL_M 0x00FF // TX Polling -#define USB_TXINTERVAL4_NAKLMT_M 0x00FF // NAK Limit -#define USB_TXINTERVAL4_NAKLMT_S 0 -#define USB_TXINTERVAL4_TXPOLL_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXTYPE4 register. -// -//***************************************************************************** -#define USB_RXTYPE4_SPEED_M 0x00C0 // Operating Speed -#define USB_RXTYPE4_SPEED_DFLT 0x0000 // Default -#define USB_RXTYPE4_SPEED_HIGH 0x0040 // High -#define USB_RXTYPE4_SPEED_FULL 0x0080 // Full -#define USB_RXTYPE4_SPEED_LOW 0x00C0 // Low -#define USB_RXTYPE4_PROTO_M 0x0030 // Protocol -#define USB_RXTYPE4_PROTO_CTRL 0x0000 // Control -#define USB_RXTYPE4_PROTO_ISOC 0x0010 // Isochronous -#define USB_RXTYPE4_PROTO_BULK 0x0020 // Bulk -#define USB_RXTYPE4_PROTO_INT 0x0030 // Interrupt -#define USB_RXTYPE4_TEP_M 0x000F // Target Endpoint Number -#define USB_RXTYPE4_TEP_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXINTERVAL4 -// register. -// -//***************************************************************************** -#define USB_RXINTERVAL4_TXPOLL_M 0x00FF // RX Polling -#define USB_RXINTERVAL4_NAKLMT_M 0x00FF // NAK Limit -#define USB_RXINTERVAL4_NAKLMT_S 0 -#define USB_RXINTERVAL4_TXPOLL_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXMAXP5 register. -// -//***************************************************************************** -#define USB_TXMAXP5_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_TXMAXP5_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRL5 register. -// -//***************************************************************************** -#define USB_TXCSRL5_NAKTO 0x0080 // NAK Timeout -#define USB_TXCSRL5_CLRDT 0x0040 // Clear Data Toggle -#define USB_TXCSRL5_STALLED 0x0020 // Endpoint Stalled -#define USB_TXCSRL5_SETUP 0x0010 // Setup Packet -#define USB_TXCSRL5_STALL 0x0010 // Send STALL -#define USB_TXCSRL5_FLUSH 0x0008 // Flush FIFO -#define USB_TXCSRL5_ERROR 0x0004 // Error -#define USB_TXCSRL5_UNDRN 0x0004 // Underrun -#define USB_TXCSRL5_FIFONE 0x0002 // FIFO Not Empty -#define USB_TXCSRL5_TXRDY 0x0001 // Transmit Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRH5 register. -// -//***************************************************************************** -#define USB_TXCSRH5_AUTOSET 0x0080 // Auto Set -#define USB_TXCSRH5_ISO 0x0040 // Isochronous Transfers -#define USB_TXCSRH5_MODE 0x0020 // Mode -#define USB_TXCSRH5_DMAEN 0x0010 // DMA Request Enable -#define USB_TXCSRH5_FDT 0x0008 // Force Data Toggle -#define USB_TXCSRH5_DMAMOD 0x0004 // DMA Request Mode -#define USB_TXCSRH5_DTWE 0x0002 // Data Toggle Write Enable -#define USB_TXCSRH5_DT 0x0001 // Data Toggle - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXMAXP5 register. -// -//***************************************************************************** -#define USB_RXMAXP5_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_RXMAXP5_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRL5 register. -// -//***************************************************************************** -#define USB_RXCSRL5_CLRDT 0x0080 // Clear Data Toggle -#define USB_RXCSRL5_STALLED 0x0040 // Endpoint Stalled -#define USB_RXCSRL5_STALL 0x0020 // Send STALL -#define USB_RXCSRL5_REQPKT 0x0020 // Request Packet -#define USB_RXCSRL5_FLUSH 0x0010 // Flush FIFO -#define USB_RXCSRL5_NAKTO 0x0008 // NAK Timeout -#define USB_RXCSRL5_DATAERR 0x0008 // Data Error -#define USB_RXCSRL5_ERROR 0x0004 // Error -#define USB_RXCSRL5_OVER 0x0004 // Overrun -#define USB_RXCSRL5_FULL 0x0002 // FIFO Full -#define USB_RXCSRL5_RXRDY 0x0001 // Receive Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRH5 register. -// -//***************************************************************************** -#define USB_RXCSRH5_AUTOCL 0x0080 // Auto Clear -#define USB_RXCSRH5_AUTORQ 0x0040 // Auto Request -#define USB_RXCSRH5_ISO 0x0040 // Isochronous Transfers -#define USB_RXCSRH5_DMAEN 0x0020 // DMA Request Enable -#define USB_RXCSRH5_DISNYET 0x0010 // Disable NYET -#define USB_RXCSRH5_PIDERR 0x0010 // PID Error -#define USB_RXCSRH5_DMAMOD 0x0008 // DMA Request Mode -#define USB_RXCSRH5_DTWE 0x0004 // Data Toggle Write Enable -#define USB_RXCSRH5_DT 0x0002 // Data Toggle -#define USB_RXCSRH5_INCOMPRX 0x0001 // Incomplete RX Transmission - // Status - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCOUNT5 register. +// The following are defines for the bit fields in the USB_O_DMACTL0 register. // //***************************************************************************** -#define USB_RXCOUNT5_COUNT_M 0x1FFF // Receive Packet Count -#define USB_RXCOUNT5_COUNT_S 0 +#define USB_DMACTL0_BRSTM_M 0x0600 // Burst Mode +#define USB_DMACTL0_BRSTM_ANY 0x0000 // Bursts of unspecified length +#define USB_DMACTL0_BRSTM_INC4 0x0200 // INCR4 or unspecified length +#define USB_DMACTL0_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified + // length +#define USB_DMACTL0_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or + // unspecified length +#define USB_DMACTL0_ERR 0x0100 // Bus Error Bit +#define USB_DMACTL0_EP_M 0x00F0 // Endpoint number +#define USB_DMACTL0_IE 0x0008 // DMA Interrupt Enable +#define USB_DMACTL0_MODE 0x0004 // DMA Transfer Mode +#define USB_DMACTL0_DIR 0x0002 // DMA Direction +#define USB_DMACTL0_ENABLE 0x0001 // DMA Transfer Enable +#define USB_DMACTL0_EP_S 4 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TXTYPE5 register. +// The following are defines for the bit fields in the USB_O_DMAADDR0 register. // //***************************************************************************** -#define USB_TXTYPE5_SPEED_M 0x00C0 // Operating Speed -#define USB_TXTYPE5_SPEED_DFLT 0x0000 // Default -#define USB_TXTYPE5_SPEED_HIGH 0x0040 // High -#define USB_TXTYPE5_SPEED_FULL 0x0080 // Full -#define USB_TXTYPE5_SPEED_LOW 0x00C0 // Low -#define USB_TXTYPE5_PROTO_M 0x0030 // Protocol -#define USB_TXTYPE5_PROTO_CTRL 0x0000 // Control -#define USB_TXTYPE5_PROTO_ISOC 0x0010 // Isochronous -#define USB_TXTYPE5_PROTO_BULK 0x0020 // Bulk -#define USB_TXTYPE5_PROTO_INT 0x0030 // Interrupt -#define USB_TXTYPE5_TEP_M 0x000F // Target Endpoint Number -#define USB_TXTYPE5_TEP_S 0 +#define USB_DMAADDR0_ADDR_M 0xFFFFFFFC // DMA Address +#define USB_DMAADDR0_ADDR_S 2 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TXINTERVAL5 +// The following are defines for the bit fields in the USB_O_DMACOUNT0 // register. // //***************************************************************************** -#define USB_TXINTERVAL5_TXPOLL_M 0x00FF // TX Polling -#define USB_TXINTERVAL5_NAKLMT_M 0x00FF // NAK Limit -#define USB_TXINTERVAL5_NAKLMT_S 0 -#define USB_TXINTERVAL5_TXPOLL_S 0 +#define USB_DMACOUNT0_COUNT_M 0xFFFFFFFC // DMA Count +#define USB_DMACOUNT0_COUNT_S 2 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_RXTYPE5 register. +// The following are defines for the bit fields in the USB_O_CTO register. // //***************************************************************************** -#define USB_RXTYPE5_SPEED_M 0x00C0 // Operating Speed -#define USB_RXTYPE5_SPEED_DFLT 0x0000 // Default -#define USB_RXTYPE5_SPEED_HIGH 0x0040 // High -#define USB_RXTYPE5_SPEED_FULL 0x0080 // Full -#define USB_RXTYPE5_SPEED_LOW 0x00C0 // Low -#define USB_RXTYPE5_PROTO_M 0x0030 // Protocol -#define USB_RXTYPE5_PROTO_CTRL 0x0000 // Control -#define USB_RXTYPE5_PROTO_ISOC 0x0010 // Isochronous -#define USB_RXTYPE5_PROTO_BULK 0x0020 // Bulk -#define USB_RXTYPE5_PROTO_INT 0x0030 // Interrupt -#define USB_RXTYPE5_TEP_M 0x000F // Target Endpoint Number -#define USB_RXTYPE5_TEP_S 0 +#define USB_CTO_CCTV_M 0xFFFF // Configurable Chirp Timeout Value +#define USB_CTO_CCTV_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_RXINTERVAL5 -// register. +// The following are defines for the bit fields in the USB_O_HHSRTN register. // //***************************************************************************** -#define USB_RXINTERVAL5_TXPOLL_M 0x00FF // RX Polling -#define USB_RXINTERVAL5_NAKLMT_M 0x00FF // NAK Limit -#define USB_RXINTERVAL5_TXPOLL_S 0 -#define USB_RXINTERVAL5_NAKLMT_S 0 +#define USB_HHSRTN_HHSRTN_M 0xFFFF // HIgh Speed to UTM Operating + // Delay +#define USB_HHSRTN_HHSRTN_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TXMAXP6 register. -// -//***************************************************************************** -#define USB_TXMAXP6_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_TXMAXP6_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRL6 register. -// -//***************************************************************************** -#define USB_TXCSRL6_NAKTO 0x0080 // NAK Timeout -#define USB_TXCSRL6_CLRDT 0x0040 // Clear Data Toggle -#define USB_TXCSRL6_STALLED 0x0020 // Endpoint Stalled -#define USB_TXCSRL6_STALL 0x0010 // Send STALL -#define USB_TXCSRL6_SETUP 0x0010 // Setup Packet -#define USB_TXCSRL6_FLUSH 0x0008 // Flush FIFO -#define USB_TXCSRL6_ERROR 0x0004 // Error -#define USB_TXCSRL6_UNDRN 0x0004 // Underrun -#define USB_TXCSRL6_FIFONE 0x0002 // FIFO Not Empty -#define USB_TXCSRL6_TXRDY 0x0001 // Transmit Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRH6 register. -// -//***************************************************************************** -#define USB_TXCSRH6_AUTOSET 0x0080 // Auto Set -#define USB_TXCSRH6_ISO 0x0040 // Isochronous Transfers -#define USB_TXCSRH6_MODE 0x0020 // Mode -#define USB_TXCSRH6_DMAEN 0x0010 // DMA Request Enable -#define USB_TXCSRH6_FDT 0x0008 // Force Data Toggle -#define USB_TXCSRH6_DMAMOD 0x0004 // DMA Request Mode -#define USB_TXCSRH6_DTWE 0x0002 // Data Toggle Write Enable -#define USB_TXCSRH6_DT 0x0001 // Data Toggle - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXMAXP6 register. -// -//***************************************************************************** -#define USB_RXMAXP6_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_RXMAXP6_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRL6 register. -// -//***************************************************************************** -#define USB_RXCSRL6_CLRDT 0x0080 // Clear Data Toggle -#define USB_RXCSRL6_STALLED 0x0040 // Endpoint Stalled -#define USB_RXCSRL6_REQPKT 0x0020 // Request Packet -#define USB_RXCSRL6_STALL 0x0020 // Send STALL -#define USB_RXCSRL6_FLUSH 0x0010 // Flush FIFO -#define USB_RXCSRL6_NAKTO 0x0008 // NAK Timeout -#define USB_RXCSRL6_DATAERR 0x0008 // Data Error -#define USB_RXCSRL6_ERROR 0x0004 // Error -#define USB_RXCSRL6_OVER 0x0004 // Overrun -#define USB_RXCSRL6_FULL 0x0002 // FIFO Full -#define USB_RXCSRL6_RXRDY 0x0001 // Receive Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRH6 register. -// -//***************************************************************************** -#define USB_RXCSRH6_AUTOCL 0x0080 // Auto Clear -#define USB_RXCSRH6_AUTORQ 0x0040 // Auto Request -#define USB_RXCSRH6_ISO 0x0040 // Isochronous Transfers -#define USB_RXCSRH6_DMAEN 0x0020 // DMA Request Enable -#define USB_RXCSRH6_DISNYET 0x0010 // Disable NYET -#define USB_RXCSRH6_PIDERR 0x0010 // PID Error -#define USB_RXCSRH6_DMAMOD 0x0008 // DMA Request Mode -#define USB_RXCSRH6_DTWE 0x0004 // Data Toggle Write Enable -#define USB_RXCSRH6_DT 0x0002 // Data Toggle -#define USB_RXCSRH6_INCOMPRX 0x0001 // Incomplete RX Transmission - // Status - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCOUNT6 register. -// -//***************************************************************************** -#define USB_RXCOUNT6_COUNT_M 0x1FFF // Receive Packet Count -#define USB_RXCOUNT6_COUNT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXTYPE6 register. -// -//***************************************************************************** -#define USB_TXTYPE6_SPEED_M 0x00C0 // Operating Speed -#define USB_TXTYPE6_SPEED_DFLT 0x0000 // Default -#define USB_TXTYPE6_SPEED_HIGH 0x0040 // High -#define USB_TXTYPE6_SPEED_FULL 0x0080 // Full -#define USB_TXTYPE6_SPEED_LOW 0x00C0 // Low -#define USB_TXTYPE6_PROTO_M 0x0030 // Protocol -#define USB_TXTYPE6_PROTO_CTRL 0x0000 // Control -#define USB_TXTYPE6_PROTO_ISOC 0x0010 // Isochronous -#define USB_TXTYPE6_PROTO_BULK 0x0020 // Bulk -#define USB_TXTYPE6_PROTO_INT 0x0030 // Interrupt -#define USB_TXTYPE6_TEP_M 0x000F // Target Endpoint Number -#define USB_TXTYPE6_TEP_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXINTERVAL6 -// register. -// -//***************************************************************************** -#define USB_TXINTERVAL6_TXPOLL_M 0x00FF // TX Polling -#define USB_TXINTERVAL6_NAKLMT_M 0x00FF // NAK Limit -#define USB_TXINTERVAL6_TXPOLL_S 0 -#define USB_TXINTERVAL6_NAKLMT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXTYPE6 register. -// -//***************************************************************************** -#define USB_RXTYPE6_SPEED_M 0x00C0 // Operating Speed -#define USB_RXTYPE6_SPEED_DFLT 0x0000 // Default -#define USB_RXTYPE6_SPEED_HIGH 0x0040 // High -#define USB_RXTYPE6_SPEED_FULL 0x0080 // Full -#define USB_RXTYPE6_SPEED_LOW 0x00C0 // Low -#define USB_RXTYPE6_PROTO_M 0x0030 // Protocol -#define USB_RXTYPE6_PROTO_CTRL 0x0000 // Control -#define USB_RXTYPE6_PROTO_ISOC 0x0010 // Isochronous -#define USB_RXTYPE6_PROTO_BULK 0x0020 // Bulk -#define USB_RXTYPE6_PROTO_INT 0x0030 // Interrupt -#define USB_RXTYPE6_TEP_M 0x000F // Target Endpoint Number -#define USB_RXTYPE6_TEP_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXINTERVAL6 -// register. -// -//***************************************************************************** -#define USB_RXINTERVAL6_TXPOLL_M 0x00FF // RX Polling -#define USB_RXINTERVAL6_NAKLMT_M 0x00FF // NAK Limit -#define USB_RXINTERVAL6_NAKLMT_S 0 -#define USB_RXINTERVAL6_TXPOLL_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXMAXP7 register. -// -//***************************************************************************** -#define USB_TXMAXP7_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_TXMAXP7_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRL7 register. -// -//***************************************************************************** -#define USB_TXCSRL7_NAKTO 0x0080 // NAK Timeout -#define USB_TXCSRL7_CLRDT 0x0040 // Clear Data Toggle -#define USB_TXCSRL7_STALLED 0x0020 // Endpoint Stalled -#define USB_TXCSRL7_STALL 0x0010 // Send STALL -#define USB_TXCSRL7_SETUP 0x0010 // Setup Packet -#define USB_TXCSRL7_FLUSH 0x0008 // Flush FIFO -#define USB_TXCSRL7_ERROR 0x0004 // Error -#define USB_TXCSRL7_UNDRN 0x0004 // Underrun -#define USB_TXCSRL7_FIFONE 0x0002 // FIFO Not Empty -#define USB_TXCSRL7_TXRDY 0x0001 // Transmit Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXCSRH7 register. -// -//***************************************************************************** -#define USB_TXCSRH7_AUTOSET 0x0080 // Auto Set -#define USB_TXCSRH7_ISO 0x0040 // Isochronous Transfers -#define USB_TXCSRH7_MODE 0x0020 // Mode -#define USB_TXCSRH7_DMAEN 0x0010 // DMA Request Enable -#define USB_TXCSRH7_FDT 0x0008 // Force Data Toggle -#define USB_TXCSRH7_DMAMOD 0x0004 // DMA Request Mode -#define USB_TXCSRH7_DTWE 0x0002 // Data Toggle Write Enable -#define USB_TXCSRH7_DT 0x0001 // Data Toggle - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXMAXP7 register. -// -//***************************************************************************** -#define USB_RXMAXP7_MAXLOAD_M 0x07FF // Maximum Payload -#define USB_RXMAXP7_MAXLOAD_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRL7 register. -// -//***************************************************************************** -#define USB_RXCSRL7_CLRDT 0x0080 // Clear Data Toggle -#define USB_RXCSRL7_STALLED 0x0040 // Endpoint Stalled -#define USB_RXCSRL7_REQPKT 0x0020 // Request Packet -#define USB_RXCSRL7_STALL 0x0020 // Send STALL -#define USB_RXCSRL7_FLUSH 0x0010 // Flush FIFO -#define USB_RXCSRL7_DATAERR 0x0008 // Data Error -#define USB_RXCSRL7_NAKTO 0x0008 // NAK Timeout -#define USB_RXCSRL7_ERROR 0x0004 // Error -#define USB_RXCSRL7_OVER 0x0004 // Overrun -#define USB_RXCSRL7_FULL 0x0002 // FIFO Full -#define USB_RXCSRL7_RXRDY 0x0001 // Receive Packet Ready - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCSRH7 register. -// -//***************************************************************************** -#define USB_RXCSRH7_AUTOCL 0x0080 // Auto Clear -#define USB_RXCSRH7_ISO 0x0040 // Isochronous Transfers -#define USB_RXCSRH7_AUTORQ 0x0040 // Auto Request -#define USB_RXCSRH7_DMAEN 0x0020 // DMA Request Enable -#define USB_RXCSRH7_PIDERR 0x0010 // PID Error -#define USB_RXCSRH7_DISNYET 0x0010 // Disable NYET -#define USB_RXCSRH7_DMAMOD 0x0008 // DMA Request Mode -#define USB_RXCSRH7_DTWE 0x0004 // Data Toggle Write Enable -#define USB_RXCSRH7_DT 0x0002 // Data Toggle -#define USB_RXCSRH7_INCOMPRX 0x0001 // Incomplete RX Transmission - // Status - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXCOUNT7 register. -// -//***************************************************************************** -#define USB_RXCOUNT7_COUNT_M 0x1FFF // Receive Packet Count -#define USB_RXCOUNT7_COUNT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXTYPE7 register. -// -//***************************************************************************** -#define USB_TXTYPE7_SPEED_M 0x00C0 // Operating Speed -#define USB_TXTYPE7_SPEED_DFLT 0x0000 // Default -#define USB_TXTYPE7_SPEED_HIGH 0x0040 // High -#define USB_TXTYPE7_SPEED_FULL 0x0080 // Full -#define USB_TXTYPE7_SPEED_LOW 0x00C0 // Low -#define USB_TXTYPE7_PROTO_M 0x0030 // Protocol -#define USB_TXTYPE7_PROTO_CTRL 0x0000 // Control -#define USB_TXTYPE7_PROTO_ISOC 0x0010 // Isochronous -#define USB_TXTYPE7_PROTO_BULK 0x0020 // Bulk -#define USB_TXTYPE7_PROTO_INT 0x0030 // Interrupt -#define USB_TXTYPE7_TEP_M 0x000F // Target Endpoint Number -#define USB_TXTYPE7_TEP_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXINTERVAL7 -// register. -// -//***************************************************************************** -#define USB_TXINTERVAL7_TXPOLL_M 0x00FF // TX Polling -#define USB_TXINTERVAL7_NAKLMT_M 0x00FF // NAK Limit -#define USB_TXINTERVAL7_NAKLMT_S 0 -#define USB_TXINTERVAL7_TXPOLL_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXTYPE7 register. -// -//***************************************************************************** -#define USB_RXTYPE7_SPEED_M 0x00C0 // Operating Speed -#define USB_RXTYPE7_SPEED_DFLT 0x0000 // Default -#define USB_RXTYPE7_SPEED_HIGH 0x0040 // High -#define USB_RXTYPE7_SPEED_FULL 0x0080 // Full -#define USB_RXTYPE7_SPEED_LOW 0x00C0 // Low -#define USB_RXTYPE7_PROTO_M 0x0030 // Protocol -#define USB_RXTYPE7_PROTO_CTRL 0x0000 // Control -#define USB_RXTYPE7_PROTO_ISOC 0x0010 // Isochronous -#define USB_RXTYPE7_PROTO_BULK 0x0020 // Bulk -#define USB_RXTYPE7_PROTO_INT 0x0030 // Interrupt -#define USB_RXTYPE7_TEP_M 0x000F // Target Endpoint Number -#define USB_RXTYPE7_TEP_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXINTERVAL7 -// register. -// -//***************************************************************************** -#define USB_RXINTERVAL7_TXPOLL_M 0x00FF // RX Polling -#define USB_RXINTERVAL7_NAKLMT_M 0x00FF // NAK Limit -#define USB_RXINTERVAL7_NAKLMT_S 0 -#define USB_RXINTERVAL7_TXPOLL_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMAINTR register. -// -//***************************************************************************** -#define USB_DMAINTR_CH7 0x0080 // Channel 7 DMA Interrupt -#define USB_DMAINTR_CH6 0x0040 // Channel 6 DMA Interrupt -#define USB_DMAINTR_CH5 0x0020 // Channel 5 DMA Interrupt -#define USB_DMAINTR_CH4 0x0010 // Channel 4 DMA Interrupt -#define USB_DMAINTR_CH3 0x0008 // Channel 3 DMA Interrupt -#define USB_DMAINTR_CH2 0x0004 // Channel 2 DMA Interrupt -#define USB_DMAINTR_CH1 0x0002 // Channel 1 DMA Interrupt -#define USB_DMAINTR_CH0 0x0001 // Channel 0 DMA Interrupt - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACTL0 register. -// -//***************************************************************************** -#define USB_DMACTL0_BRSTM_M 0x0600 // Burst Mode -#define USB_DMACTL0_BRSTM_ANY 0x0000 // Bursts of unspecified length -#define USB_DMACTL0_BRSTM_INC4 0x0200 // INCR4 or unspecified length -#define USB_DMACTL0_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified - // length -#define USB_DMACTL0_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or - // unspecified length -#define USB_DMACTL0_ERR 0x0100 // Bus Error Bit -#define USB_DMACTL0_EP_M 0x00F0 // Endpoint number -#define USB_DMACTL0_IE 0x0008 // DMA Interrupt Enable -#define USB_DMACTL0_MODE 0x0004 // DMA Transfer Mode -#define USB_DMACTL0_DIR 0x0002 // DMA Direction -#define USB_DMACTL0_ENABLE 0x0001 // DMA Transfer Enable -#define USB_DMACTL0_EP_S 4 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMAADDR0 register. -// -//***************************************************************************** -#define USB_DMAADDR0_ADDR_M 0xFFFFFFFC // DMA Address -#define USB_DMAADDR0_ADDR_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACOUNT0 -// register. -// -//***************************************************************************** -#define USB_DMACOUNT0_COUNT_M 0xFFFFFFFC // DMA Count -#define USB_DMACOUNT0_COUNT_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACTL1 register. -// -//***************************************************************************** -#define USB_DMACTL1_BRSTM_M 0x0600 // Burst Mode -#define USB_DMACTL1_BRSTM_ANY 0x0000 // Bursts of unspecified length -#define USB_DMACTL1_BRSTM_INC4 0x0200 // INCR4 or unspecified length -#define USB_DMACTL1_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified - // length -#define USB_DMACTL1_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or - // unspecified length -#define USB_DMACTL1_ERR 0x0100 // Bus Error Bit -#define USB_DMACTL1_EP_M 0x00F0 // Endpoint number -#define USB_DMACTL1_IE 0x0008 // DMA Interrupt Enable -#define USB_DMACTL1_MODE 0x0004 // DMA Transfer Mode -#define USB_DMACTL1_DIR 0x0002 // DMA Direction -#define USB_DMACTL1_ENABLE 0x0001 // DMA Transfer Enable -#define USB_DMACTL1_EP_S 4 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMAADDR1 register. -// -//***************************************************************************** -#define USB_DMAADDR1_ADDR_M 0xFFFFFFFC // DMA Address -#define USB_DMAADDR1_ADDR_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACOUNT1 -// register. -// -//***************************************************************************** -#define USB_DMACOUNT1_COUNT_M 0xFFFFFFFC // DMA Count -#define USB_DMACOUNT1_COUNT_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACTL2 register. -// -//***************************************************************************** -#define USB_DMACTL2_BRSTM_M 0x0600 // Burst Mode -#define USB_DMACTL2_BRSTM_ANY 0x0000 // Bursts of unspecified length -#define USB_DMACTL2_BRSTM_INC4 0x0200 // INCR4 or unspecified length -#define USB_DMACTL2_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified - // length -#define USB_DMACTL2_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or - // unspecified length -#define USB_DMACTL2_ERR 0x0100 // Bus Error Bit -#define USB_DMACTL2_EP_M 0x00F0 // Endpoint number -#define USB_DMACTL2_IE 0x0008 // DMA Interrupt Enable -#define USB_DMACTL2_MODE 0x0004 // DMA Transfer Mode -#define USB_DMACTL2_DIR 0x0002 // DMA Direction -#define USB_DMACTL2_ENABLE 0x0001 // DMA Transfer Enable -#define USB_DMACTL2_EP_S 4 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMAADDR2 register. -// -//***************************************************************************** -#define USB_DMAADDR2_ADDR_M 0xFFFFFFFC // DMA Address -#define USB_DMAADDR2_ADDR_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACOUNT2 -// register. -// -//***************************************************************************** -#define USB_DMACOUNT2_COUNT_M 0xFFFFFFFC // DMA Count -#define USB_DMACOUNT2_COUNT_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACTL3 register. -// -//***************************************************************************** -#define USB_DMACTL3_BRSTM_M 0x0600 // Burst Mode -#define USB_DMACTL3_BRSTM_ANY 0x0000 // Bursts of unspecified length -#define USB_DMACTL3_BRSTM_INC4 0x0200 // INCR4 or unspecified length -#define USB_DMACTL3_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified - // length -#define USB_DMACTL3_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or - // unspecified length -#define USB_DMACTL3_ERR 0x0100 // Bus Error Bit -#define USB_DMACTL3_EP_M 0x00F0 // Endpoint number -#define USB_DMACTL3_IE 0x0008 // DMA Interrupt Enable -#define USB_DMACTL3_MODE 0x0004 // DMA Transfer Mode -#define USB_DMACTL3_DIR 0x0002 // DMA Direction -#define USB_DMACTL3_ENABLE 0x0001 // DMA Transfer Enable -#define USB_DMACTL3_EP_S 4 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMAADDR3 register. -// -//***************************************************************************** -#define USB_DMAADDR3_ADDR_M 0xFFFFFFFC // DMA Address -#define USB_DMAADDR3_ADDR_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACOUNT3 -// register. -// -//***************************************************************************** -#define USB_DMACOUNT3_COUNT_M 0xFFFFFFFC // DMA Count -#define USB_DMACOUNT3_COUNT_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACTL4 register. -// -//***************************************************************************** -#define USB_DMACTL4_BRSTM_M 0x0600 // Burst Mode -#define USB_DMACTL4_BRSTM_ANY 0x0000 // Bursts of unspecified length -#define USB_DMACTL4_BRSTM_INC4 0x0200 // INCR4 or unspecified length -#define USB_DMACTL4_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified - // length -#define USB_DMACTL4_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or - // unspecified length -#define USB_DMACTL4_ERR 0x0100 // Bus Error Bit -#define USB_DMACTL4_EP_M 0x00F0 // Endpoint number -#define USB_DMACTL4_IE 0x0008 // DMA Interrupt Enable -#define USB_DMACTL4_MODE 0x0004 // DMA Transfer Mode -#define USB_DMACTL4_DIR 0x0002 // DMA Direction -#define USB_DMACTL4_ENABLE 0x0001 // DMA Transfer Enable -#define USB_DMACTL4_EP_S 4 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMAADDR4 register. -// -//***************************************************************************** -#define USB_DMAADDR4_ADDR_M 0xFFFFFFFC // DMA Address -#define USB_DMAADDR4_ADDR_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACOUNT4 -// register. -// -//***************************************************************************** -#define USB_DMACOUNT4_COUNT_M 0xFFFFFFFC // DMA Count -#define USB_DMACOUNT4_COUNT_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACTL5 register. -// -//***************************************************************************** -#define USB_DMACTL5_BRSTM_M 0x0600 // Burst Mode -#define USB_DMACTL5_BRSTM_ANY 0x0000 // Bursts of unspecified length -#define USB_DMACTL5_BRSTM_INC4 0x0200 // INCR4 or unspecified length -#define USB_DMACTL5_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified - // length -#define USB_DMACTL5_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or - // unspecified length -#define USB_DMACTL5_ERR 0x0100 // Bus Error Bit -#define USB_DMACTL5_EP_M 0x00F0 // Endpoint number -#define USB_DMACTL5_IE 0x0008 // DMA Interrupt Enable -#define USB_DMACTL5_MODE 0x0004 // DMA Transfer Mode -#define USB_DMACTL5_DIR 0x0002 // DMA Direction -#define USB_DMACTL5_ENABLE 0x0001 // DMA Transfer Enable -#define USB_DMACTL5_EP_S 4 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMAADDR5 register. -// -//***************************************************************************** -#define USB_DMAADDR5_ADDR_M 0xFFFFFFFC // DMA Address -#define USB_DMAADDR5_ADDR_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACOUNT5 -// register. -// -//***************************************************************************** -#define USB_DMACOUNT5_COUNT_M 0xFFFFFFFC // DMA Count -#define USB_DMACOUNT5_COUNT_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACTL6 register. -// -//***************************************************************************** -#define USB_DMACTL6_BRSTM_M 0x0600 // Burst Mode -#define USB_DMACTL6_BRSTM_ANY 0x0000 // Bursts of unspecified length -#define USB_DMACTL6_BRSTM_INC4 0x0200 // INCR4 or unspecified length -#define USB_DMACTL6_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified - // length -#define USB_DMACTL6_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or - // unspecified length -#define USB_DMACTL6_ERR 0x0100 // Bus Error Bit -#define USB_DMACTL6_EP_M 0x00F0 // Endpoint number -#define USB_DMACTL6_IE 0x0008 // DMA Interrupt Enable -#define USB_DMACTL6_MODE 0x0004 // DMA Transfer Mode -#define USB_DMACTL6_DIR 0x0002 // DMA Direction -#define USB_DMACTL6_ENABLE 0x0001 // DMA Transfer Enable -#define USB_DMACTL6_EP_S 4 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMAADDR6 register. -// -//***************************************************************************** -#define USB_DMAADDR6_ADDR_M 0xFFFFFFFC // DMA Address -#define USB_DMAADDR6_ADDR_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACOUNT6 -// register. -// -//***************************************************************************** -#define USB_DMACOUNT6_COUNT_M 0xFFFFFFFC // DMA Count -#define USB_DMACOUNT6_COUNT_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACTL7 register. -// -//***************************************************************************** -#define USB_DMACTL7_BRSTM_M 0x0600 // Burst Mode -#define USB_DMACTL7_BRSTM_ANY 0x0000 // Bursts of unspecified length -#define USB_DMACTL7_BRSTM_INC4 0x0200 // INCR4 or unspecified length -#define USB_DMACTL7_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified - // length -#define USB_DMACTL7_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or - // unspecified length -#define USB_DMACTL7_ERR 0x0100 // Bus Error Bit -#define USB_DMACTL7_EP_M 0x00F0 // Endpoint number -#define USB_DMACTL7_IE 0x0008 // DMA Interrupt Enable -#define USB_DMACTL7_MODE 0x0004 // DMA Transfer Mode -#define USB_DMACTL7_DIR 0x0002 // DMA Direction -#define USB_DMACTL7_ENABLE 0x0001 // DMA Transfer Enable -#define USB_DMACTL7_EP_S 4 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMAADDR7 register. -// -//***************************************************************************** -#define USB_DMAADDR7_ADDR_M 0xFFFFFFFC // DMA Address -#define USB_DMAADDR7_ADDR_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DMACOUNT7 -// register. -// -//***************************************************************************** -#define USB_DMACOUNT7_COUNT_M 0xFFFFFFFC // DMA Count -#define USB_DMACOUNT7_COUNT_S 2 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RQPKTCOUNT1 -// register. -// -//***************************************************************************** -#define USB_RQPKTCOUNT1_M 0xFFFF // Block Transfer Packet Count -#define USB_RQPKTCOUNT1_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RQPKTCOUNT2 -// register. -// -//***************************************************************************** -#define USB_RQPKTCOUNT2_M 0xFFFF // Block Transfer Packet Count -#define USB_RQPKTCOUNT2_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RQPKTCOUNT3 -// register. -// -//***************************************************************************** -#define USB_RQPKTCOUNT3_M 0xFFFF // Block Transfer Packet Count -#define USB_RQPKTCOUNT3_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RQPKTCOUNT4 -// register. -// -//***************************************************************************** -#define USB_RQPKTCOUNT4_COUNT_M 0xFFFF // Block Transfer Packet Count -#define USB_RQPKTCOUNT4_COUNT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RQPKTCOUNT5 -// register. -// -//***************************************************************************** -#define USB_RQPKTCOUNT5_COUNT_M 0xFFFF // Block Transfer Packet Count -#define USB_RQPKTCOUNT5_COUNT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RQPKTCOUNT6 -// register. -// -//***************************************************************************** -#define USB_RQPKTCOUNT6_COUNT_M 0xFFFF // Block Transfer Packet Count -#define USB_RQPKTCOUNT6_COUNT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RQPKTCOUNT7 -// register. -// -//***************************************************************************** -#define USB_RQPKTCOUNT7_COUNT_M 0xFFFF // Block Transfer Packet Count -#define USB_RQPKTCOUNT7_COUNT_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_RXDPKTBUFDIS -// register. -// -//***************************************************************************** -#define USB_RXDPKTBUFDIS_EP7 0x0080 // EP7 RX Double-Packet Buffer - // Disable -#define USB_RXDPKTBUFDIS_EP6 0x0040 // EP6 RX Double-Packet Buffer - // Disable -#define USB_RXDPKTBUFDIS_EP5 0x0020 // EP5 RX Double-Packet Buffer - // Disable -#define USB_RXDPKTBUFDIS_EP4 0x0010 // EP4 RX Double-Packet Buffer - // Disable -#define USB_RXDPKTBUFDIS_EP3 0x0008 // EP3 RX Double-Packet Buffer - // Disable -#define USB_RXDPKTBUFDIS_EP2 0x0004 // EP2 RX Double-Packet Buffer - // Disable -#define USB_RXDPKTBUFDIS_EP1 0x0002 // EP1 RX Double-Packet Buffer - // Disable - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_TXDPKTBUFDIS -// register. -// -//***************************************************************************** -#define USB_TXDPKTBUFDIS_EP7 0x0080 // EP7 TX Double-Packet Buffer - // Disable -#define USB_TXDPKTBUFDIS_EP6 0x0040 // EP6 TX Double-Packet Buffer - // Disable -#define USB_TXDPKTBUFDIS_EP5 0x0020 // EP5 TX Double-Packet Buffer - // Disable -#define USB_TXDPKTBUFDIS_EP4 0x0010 // EP4 TX Double-Packet Buffer - // Disable -#define USB_TXDPKTBUFDIS_EP3 0x0008 // EP3 TX Double-Packet Buffer - // Disable -#define USB_TXDPKTBUFDIS_EP2 0x0004 // EP2 TX Double-Packet Buffer - // Disable -#define USB_TXDPKTBUFDIS_EP1 0x0002 // EP1 TX Double-Packet Buffer - // Disable - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_CTO register. -// -//***************************************************************************** -#define USB_CTO_CCTV_M 0xFFFF // Configurable Chirp Timeout Value -#define USB_CTO_CCTV_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_HHSRTN register. -// -//***************************************************************************** -#define USB_HHSRTN_HHSRTN_M 0xFFFF // HIgh Speed to UTM Operating - // Delay -#define USB_HHSRTN_HHSRTN_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_HSBT register. +// The following are defines for the bit fields in the USB_O_HSBT register. // //***************************************************************************** #define USB_HSBT_HSBT_M 0x000F // High Speed Timeout Adder #define USB_HSBT_HSBT_S 0 -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_LPMATTR register. -// -//***************************************************************************** -#define USB_LPMATTR_ENDPT_M 0xF000 // Endpoint -#define USB_LPMATTR_RMTWAK 0x0100 // Remote Wake -#define USB_LPMATTR_HIRD_M 0x00F0 // Host Initiated Resume Duration -#define USB_LPMATTR_LS_M 0x000F // Link State -#define USB_LPMATTR_LS_L1 0x0001 // Sleep State (L1) -#define USB_LPMATTR_ENDPT_S 12 -#define USB_LPMATTR_HIRD_S 4 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_LPMCNTRL register. -// -//***************************************************************************** -#define USB_LPMCNTRL_NAK 0x0010 // LPM NAK -#define USB_LPMCNTRL_EN_M 0x000C // LPM Enable -#define USB_LPMCNTRL_EN_NONE 0x0000 // LPM and Extended transactions - // are not supported. In this case, - // the USB does not respond to LPM - // transactions and LPM - // transactions cause a timeout -#define USB_LPMCNTRL_EN_EXT 0x0004 // LPM is not supported but - // extended transactions are - // supported. In this case, the USB - // does respond to an LPM - // transaction with a STALL -#define USB_LPMCNTRL_EN_LPMEXT 0x000C // The USB supports LPM extended - // transactions. In this case, the - // USB responds with a NYET or an - // ACK as determined by the value - // of TXLPM and other conditions -#define USB_LPMCNTRL_RES 0x0002 // LPM Resume -#define USB_LPMCNTRL_TXLPM 0x0001 // Transmit LPM Transaction Enable - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_LPMIM register. -// -//***************************************************************************** -#define USB_LPMIM_ERR 0x0020 // LPM Error Interrupt Mask -#define USB_LPMIM_RES 0x0010 // LPM Resume Interrupt Mask -#define USB_LPMIM_NC 0x0008 // LPM NC Interrupt Mask -#define USB_LPMIM_ACK 0x0004 // LPM ACK Interrupt Mask -#define USB_LPMIM_NY 0x0002 // LPM NY Interrupt Mask -#define USB_LPMIM_STALL 0x0001 // LPM STALL Interrupt Mask - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_LPMRIS register. -// -//***************************************************************************** -#define USB_LPMRIS_ERR 0x0020 // LPM Interrupt Status -#define USB_LPMRIS_RES 0x0010 // LPM Resume Interrupt Status -#define USB_LPMRIS_NC 0x0008 // LPM NC Interrupt Status -#define USB_LPMRIS_ACK 0x0004 // LPM ACK Interrupt Status -#define USB_LPMRIS_NY 0x0002 // LPM NY Interrupt Status -#define USB_LPMRIS_LPMST 0x0001 // LPM STALL Interrupt Status - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_LPMFADDR register. -// -//***************************************************************************** -#define USB_LPMFADDR_ADDR_M 0x007F // LPM Function Address -#define USB_LPMFADDR_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_EPC register. -// -//***************************************************************************** -#define USB_EPC_PFLTACT_M 0x0300 // Power Fault Action -#define USB_EPC_PFLTACT_UNCHG 0x0000 // Unchanged -#define USB_EPC_PFLTACT_TRIS 0x0100 // Tristate -#define USB_EPC_PFLTACT_LOW 0x0200 // Low -#define USB_EPC_PFLTACT_HIGH 0x0300 // High -#define USB_EPC_PFLTAEN 0x0040 // Power Fault Action Enable -#define USB_EPC_PFLTSEN_HIGH 0x0020 // Power Fault Sense -#define USB_EPC_PFLTEN 0x0010 // Power Fault Input Enable -#define USB_EPC_EPENDE 0x0004 // EPEN Drive Enable -#define USB_EPC_EPEN_M 0x0003 // External Power Supply Enable - // Configuration -#define USB_EPC_EPEN_LOW 0x0000 // Power Enable Active Low -#define USB_EPC_EPEN_HIGH 0x0001 // Power Enable Active High -#define USB_EPC_EPEN_VBLOW 0x0002 // Power Enable High if VBUS Low - // (OTG only) -#define USB_EPC_EPEN_VBHIGH 0x0003 // Power Enable High if VBUS High - // (OTG only) - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_EPCRIS register. -// -//***************************************************************************** -#define USB_EPCRIS_PF 0x0001 // USB Power Fault Interrupt Status - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_EPCIM register. -// -//***************************************************************************** -#define USB_EPCIM_PF 0x0001 // USB Power Fault Interrupt Mask - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_EPCISC register. -// -//***************************************************************************** -#define USB_EPCISC_PF 0x0001 // USB Power Fault Interrupt Status - // and Clear - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DRRIS register. -// -//***************************************************************************** -#define USB_DRRIS_RESUME 0x0001 // RESUME Interrupt Status - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DRIM register. -// -//***************************************************************************** -#define USB_DRIM_RESUME 0x0001 // RESUME Interrupt Mask - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_DRISC register. -// -//***************************************************************************** -#define USB_DRISC_RESUME 0x0001 // RESUME Interrupt Status and - // Clear - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_GPCS register. -// -//***************************************************************************** -#define USB_GPCS_DEVMOD_M 0x0007 // Device Mode -#define USB_GPCS_DEVMOD_OTG 0x0000 // Use USB0VBUS and USB0ID pin -#define USB_GPCS_DEVMOD_HOST 0x0002 // Force USB0VBUS and USB0ID low -#define USB_GPCS_DEVMOD_DEV 0x0003 // Force USB0VBUS and USB0ID high -#define USB_GPCS_DEVMOD_HOSTVBUS \ - 0x0004 // Use USB0VBUS and force USB0ID - // low -#define USB_GPCS_DEVMOD_DEVVBUS 0x0005 // Use USB0VBUS and force USB0ID - // high - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_VDC register. -// -//***************************************************************************** -#define USB_VDC_VBDEN 0x0001 // VBUS Droop Enable - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_VDCRIS register. -// -//***************************************************************************** -#define USB_VDCRIS_VD 0x0001 // VBUS Droop Raw Interrupt Status - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_VDCIM register. -// -//***************************************************************************** -#define USB_VDCIM_VD 0x0001 // VBUS Droop Interrupt Mask - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_VDCISC register. -// -//***************************************************************************** -#define USB_VDCISC_VD 0x0001 // VBUS Droop Interrupt Status and - // Clear - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_PP register. -// -//***************************************************************************** -#define USB_PP_ECNT_M 0xFF00 // Endpoint Count -#define USB_PP_USB_M 0x00C0 // USB Capability -#define USB_PP_USB_DEVICE 0x0040 // DEVICE -#define USB_PP_USB_HOSTDEVICE 0x0080 // HOST -#define USB_PP_USB_OTG 0x00C0 // OTG -#define USB_PP_ULPI 0x0020 // ULPI Present -#define USB_PP_PHY 0x0010 // PHY Present -#define USB_PP_TYPE_M 0x000F // Controller Type -#define USB_PP_TYPE_0 0x0000 // The first-generation USB - // controller -#define USB_PP_TYPE_1 0x0001 // The second-generation USB - // controller revision -#define USB_PP_ECNT_S 8 - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_PC register. -// -//***************************************************************************** -#define USB_PC_ULPIEN 0x00010000 // ULPI Enable - -//***************************************************************************** -// -// The following are defines for the bit fields in the USB_O_CC register. -// -//***************************************************************************** -#define USB_CC_CLKEN 0x0200 // USB Clock Enable -#define USB_CC_CSD 0x0100 // Clock Source/Direction -#define USB_CC_CLKDIV_M 0x000F // PLL Clock Divisor -#define USB_CC_CLKDIV_S 0 - #ifdef __cplusplus } #endif -- cgit v1.3.1 From fe7ffc8edaad069955d6ededb3fc77084338256c Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 17 Aug 2024 19:08:48 +0700 Subject: rename register bit definition to prevent conflict --- src/portable/mentor/musb/dcd_musb.c | 98 +++---- src/portable/mentor/musb/musb_type.h | 518 +++++++++++++++++------------------ 2 files changed, 308 insertions(+), 308 deletions(-) (limited to 'src/portable') diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 3dcb9cdf1..3fd4d953a 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -240,7 +240,7 @@ static void process_setup_packet(uint8_t rhport) { /* Clear RX FIFO and reverse the transaction direction */ if (len && dir_in) { musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, 0); - ep_csr->csr0l = USB_CSRL0_RXRDYC; + ep_csr->csr0l = MUSB_CSRL0_RXRDYC; } } @@ -272,7 +272,7 @@ static bool handle_xfer_in(uint8_t rhport, uint_fast8_t ep_addr) } pipe->remaining = rem - len; } - ep_csr->tx_csrl = USB_TXCSRL1_TXRDY; + ep_csr->tx_csrl = MUSB_TXCSRL1_TXRDY; // TU_LOG1(" TXCSRL%d = %x %d\r\n", epnum, ep_csr->tx_csrl, rem - len); return false; } @@ -286,7 +286,7 @@ static bool handle_xfer_out(uint8_t rhport, uint_fast8_t ep_addr) musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epnum); // TU_LOG1(" RXCSRL%d = %x\r\n", epnum_minus1 + 1, ep_csr->rx_csrl); - TU_ASSERT(ep_csr->rx_csrl & USB_RXCSRL1_RXRDY); + TU_ASSERT(ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY); const unsigned mps = ep_csr->rx_maxp; const unsigned rem = pipe->remaining; @@ -327,7 +327,7 @@ static bool edpt_n_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16 } else { musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epnum); - if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) ep_csr->rx_csrl = 0; + if (ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY) ep_csr->rx_csrl = 0; } return true; } @@ -377,9 +377,9 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; /* Change to STATUS/SETUP stage */ _dcd.status_out = 1; /* Flush TX FIFO and reverse the transaction direction. */ - ep_csr->csr0l = USB_CSRL0_TXRDY | USB_CSRL0_DATAEND; + ep_csr->csr0l = MUSB_CSRL0_TXRDY | MUSB_CSRL0_DATAEND; } else { - ep_csr->csr0l = USB_CSRL0_TXRDY; /* Flush TX FIFO to return ACK. */ + ep_csr->csr0l = MUSB_CSRL0_TXRDY; /* Flush TX FIFO to return ACK. */ } // TU_LOG1(" IN ep_csr->csr0l = %x\r\n", ep_csr->csr0l); } else { @@ -387,7 +387,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ _dcd.pipe0.buf = buffer; _dcd.pipe0.length = len; _dcd.pipe0.remaining = len; - ep_csr->csr0l = USB_CSRL0_RXRDYC; /* Clear RX FIFO to return ACK. */ + ep_csr->csr0l = MUSB_CSRL0_RXRDYC; /* Clear RX FIFO to return ACK. */ } } else if (dir_in) { // TU_LOG1(" STATUS IN ep_csr->csr0l = %x\r\n", ep_csr->csr0l); @@ -395,7 +395,7 @@ static bool edpt0_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_ _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; /* Clear RX FIFO and reverse the transaction direction */ - ep_csr->csr0l = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; + ep_csr->csr0l = MUSB_CSRL0_RXRDYC | MUSB_CSRL0_DATAEND; } return true; } @@ -409,16 +409,16 @@ static void process_ep0(uint8_t rhport) // TU_LOG1(" EP0 ep_csr->csr0l = %x\r\n", csrl); // 21.1.5: endpoint 0 service routine as peripheral - if (csrl & USB_CSRL0_STALLED) { + if (csrl & MUSB_CSRL0_STALLED) { /* Returned STALL packet to HOST. */ ep_csr->csr0l = 0; /* Clear STALL */ return; } unsigned req = _dcd.setup_packet.bmRequestType; - if (csrl & USB_CSRL0_SETEND) { + if (csrl & MUSB_CSRL0_SETEND) { TU_LOG1(" ABORT by the next packets\r\n"); - ep_csr->csr0l = USB_CSRL0_SETENDC; + ep_csr->csr0l = MUSB_CSRL0_SETENDC; if (req != REQUEST_TYPE_INVALID && _dcd.pipe0.buf) { /* DATA stage was aborted by receiving STATUS or SETUP packet. */ _dcd.pipe0.buf = NULL; @@ -429,10 +429,10 @@ static void process_ep0(uint8_t rhport) XFER_RESULT_SUCCESS, true); } req = REQUEST_TYPE_INVALID; - if (!(csrl & USB_CSRL0_RXRDY)) return; /* Received SETUP packet */ + if (!(csrl & MUSB_CSRL0_RXRDY)) return; /* Received SETUP packet */ } - if (csrl & USB_CSRL0_RXRDY) { + if (csrl & MUSB_CSRL0_RXRDY) { /* Received SETUP or DATA OUT packet */ if (req == REQUEST_TYPE_INVALID) { /* SETUP */ @@ -496,15 +496,15 @@ static void process_edpt_n(uint8_t rhport, uint_fast8_t ep_addr) musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); if (dir_in) { // TU_LOG1(" TX CSRL%d = %x\r\n", epn, ep_csr->tx_csrl); - if (ep_csr->tx_csrl & USB_TXCSRL1_STALLED) { - ep_csr->tx_csrl &= ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_UNDRN); + if (ep_csr->tx_csrl & MUSB_TXCSRL1_STALLED) { + ep_csr->tx_csrl &= ~(MUSB_TXCSRL1_STALLED | MUSB_TXCSRL1_UNDRN); return; } completed = handle_xfer_in(rhport, ep_addr); } else { // TU_LOG1(" RX CSRL%d = %x\r\n", epn, ep_csr->rx_csrl); - if (ep_csr->rx_csrl & USB_RXCSRL1_STALLED) { - ep_csr->rx_csrl &= ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_OVER); + if (ep_csr->rx_csrl & MUSB_RXCSRL1_STALLED) { + ep_csr->rx_csrl &= ~(MUSB_RXCSRL1_STALLED | MUSB_RXCSRL1_OVER); return; } completed = handle_xfer_out(rhport, ep_addr); @@ -541,7 +541,7 @@ static void process_bus_reset(uint8_t rhport) { fifo_reset(musb, i, 0); fifo_reset(musb, i, 1); } - dcd_event_bus_reset(rhport, (musb->power & USB_POWER_HSMODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); + dcd_event_bus_reset(rhport, (musb->power & MUSB_POWER_HSMODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); } /*------------------------------------------------------------------ @@ -576,7 +576,7 @@ void dcd_init(uint8_t rhport) { print_musb_info(musb_regs); #endif - musb_regs->intr_usben |= USB_IE_SUSPND; + musb_regs->intr_usben |= MUSB_IE_SUSPND; musb_dcd_int_clear(rhport); musb_dcd_phy_init(rhport); dcd_connect(rhport); @@ -601,33 +601,33 @@ void dcd_set_address(uint8_t rhport, uint8_t dev_addr) _dcd.pipe0.length = 0; _dcd.pipe0.remaining = 0; /* Clear RX FIFO to return ACK. */ - ep_csr->csr0l = USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND; + ep_csr->csr0l = MUSB_CSRL0_RXRDYC | MUSB_CSRL0_DATAEND; } // Wake up host void dcd_remote_wakeup(uint8_t rhport) { musb_regs_t* musb_regs = MUSB_REGS(rhport); - musb_regs->power |= USB_POWER_RESUME; + musb_regs->power |= MUSB_POWER_RESUME; unsigned cnt = SystemCoreClock / 1000; while (cnt--) __NOP(); - musb_regs->power &= ~USB_POWER_RESUME; + musb_regs->power &= ~MUSB_POWER_RESUME; } // Connect by enabling internal pull-up resistor on D+/D- void dcd_connect(uint8_t rhport) { musb_regs_t* musb_regs = MUSB_REGS(rhport); - musb_regs->power |= TUD_OPT_HIGH_SPEED ? USB_POWER_HSENAB : 0; - musb_regs->power |= USB_POWER_SOFTCONN; + musb_regs->power |= TUD_OPT_HIGH_SPEED ? MUSB_POWER_HSENAB : 0; + musb_regs->power |= MUSB_POWER_SOFTCONN; } // Disconnect by disabling internal pull-up resistor on D+/D- void dcd_disconnect(uint8_t rhport) { musb_regs_t* musb_regs = MUSB_REGS(rhport); - musb_regs->power &= ~USB_POWER_SOFTCONN; + musb_regs->power &= ~MUSB_POWER_SOFTCONN; } void dcd_sof_enable(uint8_t rhport, bool en) @@ -663,7 +663,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) const uint8_t is_rx = 1 - dir_in; ep_csr->maxp_csr[is_rx].maxp = mps; - ep_csr->maxp_csr[is_rx].csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? USB_RXCSRH1_ISO : 0; + ep_csr->maxp_csr[is_rx].csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? MUSB_RXCSRH1_ISO : 0; uint8_t csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(is_rx); if (ep_csr->maxp_csr[is_rx].csrl & MUSB_CSRL_PACKET_READY(is_rx)) { @@ -690,17 +690,17 @@ void dcd_edpt_close_all(uint8_t rhport) musb_ep_csr_t* ep_csr = get_ep_csr(musb, i); ep_csr->tx_maxp = 0; ep_csr->tx_csrh = 0; - if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY) - ep_csr->tx_csrl = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; + if (ep_csr->tx_csrl & MUSB_TXCSRL1_TXRDY) + ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT | MUSB_TXCSRL1_FLUSH; else - ep_csr->tx_csrl = USB_TXCSRL1_CLRDT; + ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT; ep_csr->rx_maxp = 0; ep_csr->rx_csrh = 0; - if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) { - ep_csr->rx_csrl = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; + if (ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY) { + ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT | MUSB_RXCSRL1_FLUSH; } else { - ep_csr->rx_csrl = USB_RXCSRL1_CLRDT; + ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT; } fifo_reset(musb, i, 0); @@ -727,19 +727,19 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) musb->intr_txen &= ~TU_BIT(epn); ep_csr->tx_maxp = 0; ep_csr->tx_csrh = 0; - if (ep_csr->tx_csrl & USB_TXCSRL1_TXRDY) { - ep_csr->tx_csrl = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; + if (ep_csr->tx_csrl & MUSB_TXCSRL1_TXRDY) { + ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT | MUSB_TXCSRL1_FLUSH; } else { - ep_csr->tx_csrl = USB_TXCSRL1_CLRDT; + ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT; } } else { musb->intr_rxen &= ~TU_BIT(epn); ep_csr->rx_maxp = 0; ep_csr->rx_csrh = 0; - if (ep_csr->rx_csrl & USB_RXCSRL1_RXRDY) { - ep_csr->rx_csrl = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; + if (ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY) { + ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT | MUSB_RXCSRL1_FLUSH; } else { - ep_csr->rx_csrl = USB_RXCSRL1_CLRDT; + ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT; } } fifo_reset(musb, epn, dir_in); @@ -792,14 +792,14 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { if (!ep_addr) { /* Ignore EP80 */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; _dcd.pipe0.buf = NULL; - ep_csr->csr0l = USB_CSRL0_STALL; + ep_csr->csr0l = MUSB_CSRL0_STALL; } } else { if (tu_edpt_dir(ep_addr)) { /* IN */ - ep_csr->tx_csrl = USB_TXCSRL1_STALL; + ep_csr->tx_csrl = MUSB_TXCSRL1_STALL; } else { /* OUT */ - TU_ASSERT(!(ep_csr->rx_csrl & USB_RXCSRL1_RXRDY),); - ep_csr->rx_csrl = USB_RXCSRL1_STALL; + TU_ASSERT(!(ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY),); + ep_csr->rx_csrl = MUSB_RXCSRL1_STALL; } } if (ie) musb_dcd_int_enable(rhport); @@ -815,9 +815,9 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); if (tu_edpt_dir(ep_addr)) { /* IN */ - ep_csr->tx_csrl = USB_TXCSRL1_CLRDT; + ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT; } else { /* OUT */ - ep_csr->rx_csrl = USB_RXCSRL1_CLRDT; + ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT; } if (ie) musb_dcd_int_enable(rhport); } @@ -838,18 +838,18 @@ void dcd_int_handler(uint8_t rhport) { // TU_LOG1("D%2x T%2x R%2x\r\n", is, txis, rxis); intr_usb &= musb_regs->intr_usben; /* Clear disabled interrupts */ - if (intr_usb & USB_IS_DISCON) { + if (intr_usb & MUSB_IS_DISCON) { } - if (intr_usb & USB_IS_SOF) { + if (intr_usb & MUSB_IS_SOF) { dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); } - if (intr_usb & USB_IS_RESET) { + if (intr_usb & MUSB_IS_RESET) { process_bus_reset(rhport); } - if (intr_usb & USB_IS_RESUME) { + if (intr_usb & MUSB_IS_RESUME) { dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); } - if (intr_usb & USB_IS_SUSPEND) { + if (intr_usb & MUSB_IS_SUSPEND) { dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); } diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index 619eb0108..3415f74b5 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -307,14 +307,14 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ //--------------------------------------------------------------------+ // 0x01: Power -#define USB_POWER_ISOUP 0x0080 // Isochronous Update -#define USB_POWER_SOFTCONN 0x0040 // Soft Connect/Disconnect -#define USB_POWER_HSENAB 0x0020 // High Speed Enable -#define USB_POWER_HSMODE 0x0010 // High Speed Enable -#define USB_POWER_RESET 0x0008 // RESET Signaling -#define USB_POWER_RESUME 0x0004 // RESUME Signaling -#define USB_POWER_SUSPEND 0x0002 // SUSPEND Mode -#define USB_POWER_PWRDNPHY 0x0001 // Power Down PHY +#define MUSB_POWER_ISOUP 0x0080 // Isochronous Update +#define MUSB_POWER_SOFTCONN 0x0040 // Soft Connect/Disconnect +#define MUSB_POWER_HSENAB 0x0020 // High Speed Enable +#define MUSB_POWER_HSMODE 0x0010 // High Speed Enable +#define MUSB_POWER_RESET 0x0008 // RESET Signaling +#define MUSB_POWER_RESUME 0x0004 // RESUME Signaling +#define MUSB_POWER_SUSPEND 0x0002 // SUSPEND Mode +#define MUSB_POWER_PWRDNPHY 0x0001 // Power Down PHY // Interrupt TX/RX Status and Enable: each bit is for an endpoint @@ -340,460 +340,460 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_IS register. +// The following are defines for the bit fields in the MUSB_O_IS register. // //***************************************************************************** -#define USB_IS_VBUSERR 0x0080 // VBUS Error (OTG only) -#define USB_IS_SESREQ 0x0040 // SESSION REQUEST (OTG only) -#define USB_IS_DISCON 0x0020 // Session Disconnect (OTG only) -#define USB_IS_CONN 0x0010 // Session Connect -#define USB_IS_SOF 0x0008 // Start of Frame -#define USB_IS_BABBLE 0x0004 // Babble Detected -#define USB_IS_RESET 0x0004 // RESET Signaling Detected -#define USB_IS_RESUME 0x0002 // RESUME Signaling Detected -#define USB_IS_SUSPEND 0x0001 // SUSPEND Signaling Detected +#define MUSB_IS_VBUSERR 0x0080 // VBUS Error (OTG only) +#define MUSB_IS_SESREQ 0x0040 // SESSION REQUEST (OTG only) +#define MUSB_IS_DISCON 0x0020 // Session Disconnect (OTG only) +#define MUSB_IS_CONN 0x0010 // Session Connect +#define MUSB_IS_SOF 0x0008 // Start of Frame +#define MUSB_IS_BABBLE 0x0004 // Babble Detected +#define MUSB_IS_RESET 0x0004 // RESET Signaling Detected +#define MUSB_IS_RESUME 0x0002 // RESUME Signaling Detected +#define MUSB_IS_SUSPEND 0x0001 // SUSPEND Signaling Detected //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_IE register. +// The following are defines for the bit fields in the MUSB_O_IE register. // //***************************************************************************** -#define USB_IE_VBUSERR 0x0080 // Enable VBUS Error Interrupt (OTG only) -#define USB_IE_SESREQ 0x0040 // Enable Session Request (OTG only) -#define USB_IE_DISCON 0x0020 // Enable Disconnect Interrupt -#define USB_IE_CONN 0x0010 // Enable Connect Interrupt -#define USB_IE_SOF 0x0008 // Enable Start-of-Frame Interrupt -#define USB_IE_BABBLE 0x0004 // Enable Babble Interrupt -#define USB_IE_RESET 0x0004 // Enable RESET Interrupt -#define USB_IE_RESUME 0x0002 // Enable RESUME Interrupt -#define USB_IE_SUSPND 0x0001 // Enable SUSPEND Interrupt +#define MUSB_IE_VBUSERR 0x0080 // Enable VBUS Error Interrupt (OTG only) +#define MUSB_IE_SESREQ 0x0040 // Enable Session Request (OTG only) +#define MUSB_IE_DISCON 0x0020 // Enable Disconnect Interrupt +#define MUSB_IE_CONN 0x0010 // Enable Connect Interrupt +#define MUSB_IE_SOF 0x0008 // Enable Start-of-Frame Interrupt +#define MUSB_IE_BABBLE 0x0004 // Enable Babble Interrupt +#define MUSB_IE_RESET 0x0004 // Enable RESET Interrupt +#define MUSB_IE_RESUME 0x0002 // Enable RESUME Interrupt +#define MUSB_IE_SUSPND 0x0001 // Enable SUSPEND Interrupt //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_FRAME register. +// The following are defines for the bit fields in the MUSB_O_FRAME register. // //***************************************************************************** -#define USB_FRAME_M 0x07FF // Frame Number -#define USB_FRAME_S 0 +#define MUSB_FRAME_M 0x07FF // Frame Number +#define MUSB_FRAME_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TEST register. +// The following are defines for the bit fields in the MUSB_O_TEST register. // //***************************************************************************** -#define USB_TEST_FORCEH 0x0080 // Force Host Mode -#define USB_TEST_FIFOACC 0x0040 // FIFO Access -#define USB_TEST_FORCEFS 0x0020 // Force Full-Speed Mode -#define USB_TEST_FORCEHS 0x0010 // Force High-Speed Mode -#define USB_TEST_TESTPKT 0x0008 // Test Packet Mode Enable -#define USB_TEST_TESTK 0x0004 // Test_K Mode Enable -#define USB_TEST_TESTJ 0x0002 // Test_J Mode Enable -#define USB_TEST_TESTSE0NAK 0x0001 // Test_SE0_NAK Test Mode Enable +#define MUSB_TEST_FORCEH 0x0080 // Force Host Mode +#define MUSB_TEST_FIFOACC 0x0040 // FIFO Access +#define MUSB_TEST_FORCEFS 0x0020 // Force Full-Speed Mode +#define MUSB_TEST_FORCEHS 0x0010 // Force High-Speed Mode +#define MUSB_TEST_TESTPKT 0x0008 // Test Packet Mode Enable +#define MUSB_TEST_TESTK 0x0004 // Test_K Mode Enable +#define MUSB_TEST_TESTJ 0x0002 // Test_J Mode Enable +#define MUSB_TEST_TESTSE0NAK 0x0001 // Test_SE0_NAK Test Mode Enable //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_DEVCTL register. +// The following are defines for the bit fields in the MUSB_O_DEVCTL register. // //***************************************************************************** -#define USB_DEVCTL_DEV 0x0080 // Device Mode (OTG only) -#define USB_DEVCTL_FSDEV 0x0040 // Full-Speed Device Detected -#define USB_DEVCTL_LSDEV 0x0020 // Low-Speed Device Detected -#define USB_DEVCTL_VBUS_M 0x0018 // VBUS Level (OTG only) -#define USB_DEVCTL_VBUS_NONE 0x0000 // Below SessionEnd -#define USB_DEVCTL_VBUS_SEND 0x0008 // Above SessionEnd, below AValid -#define USB_DEVCTL_VBUS_AVALID 0x0010 // Above AValid, below VBUSValid -#define USB_DEVCTL_VBUS_VALID 0x0018 // Above VBUSValid -#define USB_DEVCTL_HOST 0x0004 // Host Mode -#define USB_DEVCTL_HOSTREQ 0x0002 // Host Request (OTG only) -#define USB_DEVCTL_SESSION 0x0001 // Session Start/End (OTG only) +#define MUSB_DEVCTL_DEV 0x0080 // Device Mode (OTG only) +#define MUSB_DEVCTL_FSDEV 0x0040 // Full-Speed Device Detected +#define MUSB_DEVCTL_LSDEV 0x0020 // Low-Speed Device Detected +#define MUSB_DEVCTL_VBUS_M 0x0018 // VBUS Level (OTG only) +#define MUSB_DEVCTL_VBUS_NONE 0x0000 // Below SessionEnd +#define MUSB_DEVCTL_VBUS_SEND 0x0008 // Above SessionEnd, below AValid +#define MUSB_DEVCTL_VBUS_AVALID 0x0010 // Above AValid, below VBUSValid +#define MUSB_DEVCTL_VBUS_VALID 0x0018 // Above VBUSValid +#define MUSB_DEVCTL_HOST 0x0004 // Host Mode +#define MUSB_DEVCTL_HOSTREQ 0x0002 // Host Request (OTG only) +#define MUSB_DEVCTL_SESSION 0x0001 // Session Start/End (OTG only) //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_CCONF register. +// The following are defines for the bit fields in the MUSB_O_CCONF register. // //***************************************************************************** -#define USB_CCONF_TXEDMA 0x0002 // TX Early DMA Enable -#define USB_CCONF_RXEDMA 0x0001 // TX Early DMA Enable +#define MUSB_CCONF_TXEDMA 0x0002 // TX Early DMA Enable +#define MUSB_CCONF_RXEDMA 0x0001 // TX Early DMA Enable //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TXFIFOSZ register. +// The following are defines for the bit fields in the MUSB_O_TXFIFOSZ register. // //***************************************************************************** -#define USB_TXFIFOSZ_DPB 0x0010 // Double Packet Buffer Support -#define USB_TXFIFOSZ_SIZE_M 0x000F // Max Packet Size -#define USB_TXFIFOSZ_SIZE_8 0x0000 // 8 -#define USB_TXFIFOSZ_SIZE_16 0x0001 // 16 -#define USB_TXFIFOSZ_SIZE_32 0x0002 // 32 -#define USB_TXFIFOSZ_SIZE_64 0x0003 // 64 -#define USB_TXFIFOSZ_SIZE_128 0x0004 // 128 -#define USB_TXFIFOSZ_SIZE_256 0x0005 // 256 -#define USB_TXFIFOSZ_SIZE_512 0x0006 // 512 -#define USB_TXFIFOSZ_SIZE_1024 0x0007 // 1024 -#define USB_TXFIFOSZ_SIZE_2048 0x0008 // 2048 +#define MUSB_TXFIFOSZ_DPB 0x0010 // Double Packet Buffer Support +#define MUSB_TXFIFOSZ_SIZE_M 0x000F // Max Packet Size +#define MUSB_TXFIFOSZ_SIZE_8 0x0000 // 8 +#define MUSB_TXFIFOSZ_SIZE_16 0x0001 // 16 +#define MUSB_TXFIFOSZ_SIZE_32 0x0002 // 32 +#define MUSB_TXFIFOSZ_SIZE_64 0x0003 // 64 +#define MUSB_TXFIFOSZ_SIZE_128 0x0004 // 128 +#define MUSB_TXFIFOSZ_SIZE_256 0x0005 // 256 +#define MUSB_TXFIFOSZ_SIZE_512 0x0006 // 512 +#define MUSB_TXFIFOSZ_SIZE_1024 0x0007 // 1024 +#define MUSB_TXFIFOSZ_SIZE_2048 0x0008 // 2048 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_RXFIFOSZ register. +// The following are defines for the bit fields in the MUSB_O_RXFIFOSZ register. // //***************************************************************************** -#define USB_RXFIFOSZ_DPB 0x0010 // Double Packet Buffer Support -#define USB_RXFIFOSZ_SIZE_M 0x000F // Max Packet Size -#define USB_RXFIFOSZ_SIZE_8 0x0000 // 8 -#define USB_RXFIFOSZ_SIZE_16 0x0001 // 16 -#define USB_RXFIFOSZ_SIZE_32 0x0002 // 32 -#define USB_RXFIFOSZ_SIZE_64 0x0003 // 64 -#define USB_RXFIFOSZ_SIZE_128 0x0004 // 128 -#define USB_RXFIFOSZ_SIZE_256 0x0005 // 256 -#define USB_RXFIFOSZ_SIZE_512 0x0006 // 512 -#define USB_RXFIFOSZ_SIZE_1024 0x0007 // 1024 -#define USB_RXFIFOSZ_SIZE_2048 0x0008 // 2048 +#define MUSB_RXFIFOSZ_DPB 0x0010 // Double Packet Buffer Support +#define MUSB_RXFIFOSZ_SIZE_M 0x000F // Max Packet Size +#define MUSB_RXFIFOSZ_SIZE_8 0x0000 // 8 +#define MUSB_RXFIFOSZ_SIZE_16 0x0001 // 16 +#define MUSB_RXFIFOSZ_SIZE_32 0x0002 // 32 +#define MUSB_RXFIFOSZ_SIZE_64 0x0003 // 64 +#define MUSB_RXFIFOSZ_SIZE_128 0x0004 // 128 +#define MUSB_RXFIFOSZ_SIZE_256 0x0005 // 256 +#define MUSB_RXFIFOSZ_SIZE_512 0x0006 // 512 +#define MUSB_RXFIFOSZ_SIZE_1024 0x0007 // 1024 +#define MUSB_RXFIFOSZ_SIZE_2048 0x0008 // 2048 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TXFIFOADD +// The following are defines for the bit fields in the MUSB_O_TXFIFOADD // register. // //***************************************************************************** -#define USB_TXFIFOADD_ADDR_M 0x01FF // Transmit/Receive Start Address -#define USB_TXFIFOADD_ADDR_S 0 +#define MUSB_TXFIFOADD_ADDR_M 0x01FF // Transmit/Receive Start Address +#define MUSB_TXFIFOADD_ADDR_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_RXFIFOADD +// The following are defines for the bit fields in the MUSB_O_RXFIFOADD // register. // //***************************************************************************** -#define USB_RXFIFOADD_ADDR_M 0x01FF // Transmit/Receive Start Address -#define USB_RXFIFOADD_ADDR_S 0 +#define MUSB_RXFIFOADD_ADDR_M 0x01FF // Transmit/Receive Start Address +#define MUSB_RXFIFOADD_ADDR_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_ULPIVBUSCTL +// The following are defines for the bit fields in the MUSB_O_ULPIVBUSCTL // register. // //***************************************************************************** -#define USB_ULPIVBUSCTL_USEEXTVBUSIND 0x0002 // Use External VBUS Indicator -#define USB_ULPIVBUSCTL_USEEXTVBUS 0x0001 // Use External VBUS +#define MUSB_ULPIVBUSCTL_USEEXTVBUSIND 0x0002 // Use External VBUS Indicator +#define MUSB_ULPIVBUSCTL_USEEXTVBUS 0x0001 // Use External VBUS //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_ULPIREGDATA +// The following are defines for the bit fields in the MUSB_O_ULPIREGDATA // register. // //***************************************************************************** -#define USB_ULPIREGDATA_REGDATA_M 0x00FF // Register Data -#define USB_ULPIREGDATA_REGDATA_S 0 +#define MUSB_ULPIREGDATA_REGDATA_M 0x00FF // Register Data +#define MUSB_ULPIREGDATA_REGDATA_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_ULPIREGADDR +// The following are defines for the bit fields in the MUSB_O_ULPIREGADDR // register. // //***************************************************************************** -#define USB_ULPIREGADDR_ADDR_M 0x00FF // Register Address -#define USB_ULPIREGADDR_ADDR_S 0 +#define MUSB_ULPIREGADDR_ADDR_M 0x00FF // Register Address +#define MUSB_ULPIREGADDR_ADDR_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_ULPIREGCTL +// The following are defines for the bit fields in the MUSB_O_ULPIREGCTL // register. // //***************************************************************************** -#define USB_ULPIREGCTL_RDWR 0x0004 // Read/Write Control -#define USB_ULPIREGCTL_REGCMPLT 0x0002 // Register Access Complete -#define USB_ULPIREGCTL_REGACC 0x0001 // Initiate Register Access +#define MUSB_ULPIREGCTL_RDWR 0x0004 // Read/Write Control +#define MUSB_ULPIREGCTL_REGCMPLT 0x0002 // Register Access Complete +#define MUSB_ULPIREGCTL_REGACC 0x0001 // Initiate Register Access //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_EPINFO register. +// The following are defines for the bit fields in the MUSB_O_EPINFO register. // //***************************************************************************** -#define USB_EPINFO_RXEP_M 0x00F0 // RX Endpoints -#define USB_EPINFO_TXEP_M 0x000F // TX Endpoints -#define USB_EPINFO_RXEP_S 4 -#define USB_EPINFO_TXEP_S 0 +#define MUSB_EPINFO_RXEP_M 0x00F0 // RX Endpoints +#define MUSB_EPINFO_TXEP_M 0x000F // TX Endpoints +#define MUSB_EPINFO_RXEP_S 4 +#define MUSB_EPINFO_TXEP_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_RAMINFO register. +// The following are defines for the bit fields in the MUSB_O_RAMINFO register. // //***************************************************************************** -#define USB_RAMINFO_DMACHAN_M 0x00F0 // DMA Channels -#define USB_RAMINFO_RAMBITS_M 0x000F // RAM Address Bus Width -#define USB_RAMINFO_DMACHAN_S 4 -#define USB_RAMINFO_RAMBITS_S 0 +#define MUSB_RAMINFO_DMACHAN_M 0x00F0 // DMA Channels +#define MUSB_RAMINFO_RAMBITS_M 0x000F // RAM Address Bus Width +#define MUSB_RAMINFO_DMACHAN_S 4 +#define MUSB_RAMINFO_RAMBITS_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_CONTIM register. +// The following are defines for the bit fields in the MUSB_O_CONTIM register. // //***************************************************************************** -#define USB_CONTIM_WTCON_M 0x00F0 // Connect Wait -#define USB_CONTIM_WTID_M 0x000F // Wait ID -#define USB_CONTIM_WTCON_S 4 -#define USB_CONTIM_WTID_S 0 +#define MUSB_CONTIM_WTCON_M 0x00F0 // Connect Wait +#define MUSB_CONTIM_WTID_M 0x000F // Wait ID +#define MUSB_CONTIM_WTCON_S 4 +#define MUSB_CONTIM_WTID_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_VPLEN register. +// The following are defines for the bit fields in the MUSB_O_VPLEN register. // //***************************************************************************** -#define USB_VPLEN_VPLEN_M 0x00FF // VBUS Pulse Length -#define USB_VPLEN_VPLEN_S 0 +#define MUSB_VPLEN_VPLEN_M 0x00FF // VBUS Pulse Length +#define MUSB_VPLEN_VPLEN_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_HSEOF register. +// The following are defines for the bit fields in the MUSB_O_HSEOF register. // //***************************************************************************** -#define USB_HSEOF_HSEOFG_M 0x00FF // HIgh-Speed End-of-Frame Gap -#define USB_HSEOF_HSEOFG_S 0 +#define MUSB_HSEOF_HSEOFG_M 0x00FF // HIgh-Speed End-of-Frame Gap +#define MUSB_HSEOF_HSEOFG_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_FSEOF register. +// The following are defines for the bit fields in the MUSB_O_FSEOF register. // //***************************************************************************** -#define USB_FSEOF_FSEOFG_M 0x00FF // Full-Speed End-of-Frame Gap -#define USB_FSEOF_FSEOFG_S 0 +#define MUSB_FSEOF_FSEOFG_M 0x00FF // Full-Speed End-of-Frame Gap +#define MUSB_FSEOF_FSEOFG_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_LSEOF register. +// The following are defines for the bit fields in the MUSB_O_LSEOF register. // //***************************************************************************** -#define USB_LSEOF_LSEOFG_M 0x00FF // Low-Speed End-of-Frame Gap -#define USB_LSEOF_LSEOFG_S 0 +#define MUSB_LSEOF_LSEOFG_M 0x00FF // Low-Speed End-of-Frame Gap +#define MUSB_LSEOF_LSEOFG_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_CSRL0 register. +// The following are defines for the bit fields in the MUSB_O_CSRL0 register. // //***************************************************************************** -#define USB_CSRL0_NAKTO 0x0080 // NAK Timeout -#define USB_CSRL0_SETENDC 0x0080 // Setup End Clear -#define USB_CSRL0_STATUS 0x0040 // STATUS Packet -#define USB_CSRL0_RXRDYC 0x0040 // RXRDY Clear -#define USB_CSRL0_REQPKT 0x0020 // Request Packet -#define USB_CSRL0_STALL 0x0020 // Send Stall -#define USB_CSRL0_SETEND 0x0010 // Setup End -#define USB_CSRL0_ERROR 0x0010 // Error -#define USB_CSRL0_DATAEND 0x0008 // Data End -#define USB_CSRL0_SETUP 0x0008 // Setup Packet -#define USB_CSRL0_STALLED 0x0004 // Endpoint Stalled -#define USB_CSRL0_TXRDY 0x0002 // Transmit Packet Ready -#define USB_CSRL0_RXRDY 0x0001 // Receive Packet Ready +#define MUSB_CSRL0_NAKTO 0x0080 // NAK Timeout +#define MUSB_CSRL0_SETENDC 0x0080 // Setup End Clear +#define MUSB_CSRL0_STATUS 0x0040 // STATUS Packet +#define MUSB_CSRL0_RXRDYC 0x0040 // RXRDY Clear +#define MUSB_CSRL0_REQPKT 0x0020 // Request Packet +#define MUSB_CSRL0_STALL 0x0020 // Send Stall +#define MUSB_CSRL0_SETEND 0x0010 // Setup End +#define MUSB_CSRL0_ERROR 0x0010 // Error +#define MUSB_CSRL0_DATAEND 0x0008 // Data End +#define MUSB_CSRL0_SETUP 0x0008 // Setup Packet +#define MUSB_CSRL0_STALLED 0x0004 // Endpoint Stalled +#define MUSB_CSRL0_TXRDY 0x0002 // Transmit Packet Ready +#define MUSB_CSRL0_RXRDY 0x0001 // Receive Packet Ready //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_CSRH0 register. +// The following are defines for the bit fields in the MUSB_O_CSRH0 register. // //***************************************************************************** -#define USB_CSRH0_DISPING 0x0008 // PING Disable -#define USB_CSRH0_DTWE 0x0004 // Data Toggle Write Enable -#define USB_CSRH0_DT 0x0002 // Data Toggle -#define USB_CSRH0_FLUSH 0x0001 // Flush FIFO +#define MUSB_CSRH0_DISPING 0x0008 // PING Disable +#define MUSB_CSRH0_DTWE 0x0004 // Data Toggle Write Enable +#define MUSB_CSRH0_DT 0x0002 // Data Toggle +#define MUSB_CSRH0_FLUSH 0x0001 // Flush FIFO //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TYPE0 register. +// The following are defines for the bit fields in the MUSB_O_TYPE0 register. // //***************************************************************************** -#define USB_TYPE0_SPEED_M 0x00C0 // Operating Speed -#define USB_TYPE0_SPEED_HIGH 0x0040 // High -#define USB_TYPE0_SPEED_FULL 0x0080 // Full -#define USB_TYPE0_SPEED_LOW 0x00C0 // Low +#define MUSB_TYPE0_SPEED_M 0x00C0 // Operating Speed +#define MUSB_TYPE0_SPEED_HIGH 0x0040 // High +#define MUSB_TYPE0_SPEED_FULL 0x0080 // Full +#define MUSB_TYPE0_SPEED_LOW 0x00C0 // Low //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_NAKLMT register. +// The following are defines for the bit fields in the MUSB_O_NAKLMT register. // //***************************************************************************** -#define USB_NAKLMT_NAKLMT_M 0x001F // EP0 NAK Limit -#define USB_NAKLMT_NAKLMT_S 0 +#define MUSB_NAKLMT_NAKLMT_M 0x001F // EP0 NAK Limit +#define MUSB_NAKLMT_NAKLMT_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TXCSRL1 register. +// The following are defines for the bit fields in the MUSB_O_TXCSRL1 register. // //***************************************************************************** -#define USB_TXCSRL1_NAKTO 0x0080 // NAK Timeout -#define USB_TXCSRL1_CLRDT 0x0040 // Clear Data Toggle -#define USB_TXCSRL1_STALLED 0x0020 // Endpoint Stalled -#define USB_TXCSRL1_STALL 0x0010 // Send STALL -#define USB_TXCSRL1_SETUP 0x0010 // Setup Packet -#define USB_TXCSRL1_FLUSH 0x0008 // Flush FIFO -#define USB_TXCSRL1_ERROR 0x0004 // Error -#define USB_TXCSRL1_UNDRN 0x0004 // Underrun -#define USB_TXCSRL1_FIFONE 0x0002 // FIFO Not Empty -#define USB_TXCSRL1_TXRDY 0x0001 // Transmit Packet Ready +#define MUSB_TXCSRL1_NAKTO 0x0080 // NAK Timeout +#define MUSB_TXCSRL1_CLRDT 0x0040 // Clear Data Toggle +#define MUSB_TXCSRL1_STALLED 0x0020 // Endpoint Stalled +#define MUSB_TXCSRL1_STALL 0x0010 // Send STALL +#define MUSB_TXCSRL1_SETUP 0x0010 // Setup Packet +#define MUSB_TXCSRL1_FLUSH 0x0008 // Flush FIFO +#define MUSB_TXCSRL1_ERROR 0x0004 // Error +#define MUSB_TXCSRL1_UNDRN 0x0004 // Underrun +#define MUSB_TXCSRL1_FIFONE 0x0002 // FIFO Not Empty +#define MUSB_TXCSRL1_TXRDY 0x0001 // Transmit Packet Ready //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TXCSRH1 register. +// The following are defines for the bit fields in the MUSB_O_TXCSRH1 register. // //***************************************************************************** -#define USB_TXCSRH1_AUTOSET 0x0080 // Auto Set -#define USB_TXCSRH1_ISO 0x0040 // Isochronous Transfers -#define USB_TXCSRH1_MODE 0x0020 // Mode -#define USB_TXCSRH1_DMAEN 0x0010 // DMA Request Enable -#define USB_TXCSRH1_FDT 0x0008 // Force Data Toggle -#define USB_TXCSRH1_DMAMOD 0x0004 // DMA Request Mode -#define USB_TXCSRH1_DTWE 0x0002 // Data Toggle Write Enable -#define USB_TXCSRH1_DT 0x0001 // Data Toggle +#define MUSB_TXCSRH1_AUTOSET 0x0080 // Auto Set +#define MUSB_TXCSRH1_ISO 0x0040 // Isochronous Transfers +#define MUSB_TXCSRH1_MODE 0x0020 // Mode +#define MUSB_TXCSRH1_DMAEN 0x0010 // DMA Request Enable +#define MUSB_TXCSRH1_FDT 0x0008 // Force Data Toggle +#define MUSB_TXCSRH1_DMAMOD 0x0004 // DMA Request Mode +#define MUSB_TXCSRH1_DTWE 0x0002 // Data Toggle Write Enable +#define MUSB_TXCSRH1_DT 0x0001 // Data Toggle //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_RXCSRL1 register. +// The following are defines for the bit fields in the MUSB_O_RXCSRL1 register. // //***************************************************************************** -#define USB_RXCSRL1_CLRDT 0x0080 // Clear Data Toggle -#define USB_RXCSRL1_STALLED 0x0040 // Endpoint Stalled -#define USB_RXCSRL1_STALL 0x0020 // Send STALL -#define USB_RXCSRL1_REQPKT 0x0020 // Request Packet -#define USB_RXCSRL1_FLUSH 0x0010 // Flush FIFO -#define USB_RXCSRL1_DATAERR 0x0008 // Data Error -#define USB_RXCSRL1_NAKTO 0x0008 // NAK Timeout -#define USB_RXCSRL1_OVER 0x0004 // Overrun -#define USB_RXCSRL1_ERROR 0x0004 // Error -#define USB_RXCSRL1_FULL 0x0002 // FIFO Full -#define USB_RXCSRL1_RXRDY 0x0001 // Receive Packet Ready +#define MUSB_RXCSRL1_CLRDT 0x0080 // Clear Data Toggle +#define MUSB_RXCSRL1_STALLED 0x0040 // Endpoint Stalled +#define MUSB_RXCSRL1_STALL 0x0020 // Send STALL +#define MUSB_RXCSRL1_REQPKT 0x0020 // Request Packet +#define MUSB_RXCSRL1_FLUSH 0x0010 // Flush FIFO +#define MUSB_RXCSRL1_DATAERR 0x0008 // Data Error +#define MUSB_RXCSRL1_NAKTO 0x0008 // NAK Timeout +#define MUSB_RXCSRL1_OVER 0x0004 // Overrun +#define MUSB_RXCSRL1_ERROR 0x0004 // Error +#define MUSB_RXCSRL1_FULL 0x0002 // FIFO Full +#define MUSB_RXCSRL1_RXRDY 0x0001 // Receive Packet Ready //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_RXCSRH1 register. +// The following are defines for the bit fields in the MUSB_O_RXCSRH1 register. // //***************************************************************************** -#define USB_RXCSRH1_AUTOCL 0x0080 // Auto Clear -#define USB_RXCSRH1_AUTORQ 0x0040 // Auto Request -#define USB_RXCSRH1_ISO 0x0040 // Isochronous Transfers -#define USB_RXCSRH1_DMAEN 0x0020 // DMA Request Enable -#define USB_RXCSRH1_DISNYET 0x0010 // Disable NYET -#define USB_RXCSRH1_PIDERR 0x0010 // PID Error -#define USB_RXCSRH1_DMAMOD 0x0008 // DMA Request Mode -#define USB_RXCSRH1_DTWE 0x0004 // Data Toggle Write Enable -#define USB_RXCSRH1_DT 0x0002 // Data Toggle -#define USB_RXCSRH1_INCOMPRX 0x0001 // Incomplete RX Transmission Status +#define MUSB_RXCSRH1_AUTOCL 0x0080 // Auto Clear +#define MUSB_RXCSRH1_AUTORQ 0x0040 // Auto Request +#define MUSB_RXCSRH1_ISO 0x0040 // Isochronous Transfers +#define MUSB_RXCSRH1_DMAEN 0x0020 // DMA Request Enable +#define MUSB_RXCSRH1_DISNYET 0x0010 // Disable NYET +#define MUSB_RXCSRH1_PIDERR 0x0010 // PID Error +#define MUSB_RXCSRH1_DMAMOD 0x0008 // DMA Request Mode +#define MUSB_RXCSRH1_DTWE 0x0004 // Data Toggle Write Enable +#define MUSB_RXCSRH1_DT 0x0002 // Data Toggle +#define MUSB_RXCSRH1_INCOMPRX 0x0001 // Incomplete RX Transmission Status //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TXTYPE1 register. +// The following are defines for the bit fields in the MUSB_O_TXTYPE1 register. // //***************************************************************************** -#define USB_TXTYPE1_SPEED_M 0x00C0 // Operating Speed -#define USB_TXTYPE1_SPEED_DFLT 0x0000 // Default -#define USB_TXTYPE1_SPEED_HIGH 0x0040 // High -#define USB_TXTYPE1_SPEED_FULL 0x0080 // Full -#define USB_TXTYPE1_SPEED_LOW 0x00C0 // Low -#define USB_TXTYPE1_PROTO_M 0x0030 // Protocol -#define USB_TXTYPE1_PROTO_CTRL 0x0000 // Control -#define USB_TXTYPE1_PROTO_ISOC 0x0010 // Isochronous -#define USB_TXTYPE1_PROTO_BULK 0x0020 // Bulk -#define USB_TXTYPE1_PROTO_INT 0x0030 // Interrupt -#define USB_TXTYPE1_TEP_M 0x000F // Target Endpoint Number -#define USB_TXTYPE1_TEP_S 0 +#define MUSB_TXTYPE1_SPEED_M 0x00C0 // Operating Speed +#define MUSB_TXTYPE1_SPEED_DFLT 0x0000 // Default +#define MUSB_TXTYPE1_SPEED_HIGH 0x0040 // High +#define MUSB_TXTYPE1_SPEED_FULL 0x0080 // Full +#define MUSB_TXTYPE1_SPEED_LOW 0x00C0 // Low +#define MUSB_TXTYPE1_PROTO_M 0x0030 // Protocol +#define MUSB_TXTYPE1_PROTO_CTRL 0x0000 // Control +#define MUSB_TXTYPE1_PROTO_ISOC 0x0010 // Isochronous +#define MUSB_TXTYPE1_PROTO_BULK 0x0020 // Bulk +#define MUSB_TXTYPE1_PROTO_INT 0x0030 // Interrupt +#define MUSB_TXTYPE1_TEP_M 0x000F // Target Endpoint Number +#define MUSB_TXTYPE1_TEP_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_TXINTERVAL1 +// The following are defines for the bit fields in the MUSB_O_TXINTERVAL1 // register. // //***************************************************************************** -#define USB_TXINTERVAL1_NAKLMT_M 0x00FF // NAK Limit -#define USB_TXINTERVAL1_TXPOLL_M 0x00FF // TX Polling -#define USB_TXINTERVAL1_TXPOLL_S 0 -#define USB_TXINTERVAL1_NAKLMT_S 0 +#define MUSB_TXINTERVAL1_NAKLMT_M 0x00FF // NAK Limit +#define MUSB_TXINTERVAL1_TXPOLL_M 0x00FF // TX Polling +#define MUSB_TXINTERVAL1_TXPOLL_S 0 +#define MUSB_TXINTERVAL1_NAKLMT_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_RXTYPE1 register. +// The following are defines for the bit fields in the MUSB_O_RXTYPE1 register. // //***************************************************************************** -#define USB_RXTYPE1_SPEED_M 0x00C0 // Operating Speed -#define USB_RXTYPE1_SPEED_DFLT 0x0000 // Default -#define USB_RXTYPE1_SPEED_HIGH 0x0040 // High -#define USB_RXTYPE1_SPEED_FULL 0x0080 // Full -#define USB_RXTYPE1_SPEED_LOW 0x00C0 // Low -#define USB_RXTYPE1_PROTO_M 0x0030 // Protocol -#define USB_RXTYPE1_PROTO_CTRL 0x0000 // Control -#define USB_RXTYPE1_PROTO_ISOC 0x0010 // Isochronous -#define USB_RXTYPE1_PROTO_BULK 0x0020 // Bulk -#define USB_RXTYPE1_PROTO_INT 0x0030 // Interrupt -#define USB_RXTYPE1_TEP_M 0x000F // Target Endpoint Number -#define USB_RXTYPE1_TEP_S 0 +#define MUSB_RXTYPE1_SPEED_M 0x00C0 // Operating Speed +#define MUSB_RXTYPE1_SPEED_DFLT 0x0000 // Default +#define MUSB_RXTYPE1_SPEED_HIGH 0x0040 // High +#define MUSB_RXTYPE1_SPEED_FULL 0x0080 // Full +#define MUSB_RXTYPE1_SPEED_LOW 0x00C0 // Low +#define MUSB_RXTYPE1_PROTO_M 0x0030 // Protocol +#define MUSB_RXTYPE1_PROTO_CTRL 0x0000 // Control +#define MUSB_RXTYPE1_PROTO_ISOC 0x0010 // Isochronous +#define MUSB_RXTYPE1_PROTO_BULK 0x0020 // Bulk +#define MUSB_RXTYPE1_PROTO_INT 0x0030 // Interrupt +#define MUSB_RXTYPE1_TEP_M 0x000F // Target Endpoint Number +#define MUSB_RXTYPE1_TEP_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_RXINTERVAL1 +// The following are defines for the bit fields in the MUSB_O_RXINTERVAL1 // register. // //***************************************************************************** -#define USB_RXINTERVAL1_TXPOLL_M 0x00FF // RX Polling -#define USB_RXINTERVAL1_NAKLMT_M 0x00FF // NAK Limit -#define USB_RXINTERVAL1_TXPOLL_S 0 -#define USB_RXINTERVAL1_NAKLMT_S 0 +#define MUSB_RXINTERVAL1_TXPOLL_M 0x00FF // RX Polling +#define MUSB_RXINTERVAL1_NAKLMT_M 0x00FF // NAK Limit +#define MUSB_RXINTERVAL1_TXPOLL_S 0 +#define MUSB_RXINTERVAL1_NAKLMT_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_DMACTL0 register. +// The following are defines for the bit fields in the MUSB_O_DMACTL0 register. // //***************************************************************************** -#define USB_DMACTL0_BRSTM_M 0x0600 // Burst Mode -#define USB_DMACTL0_BRSTM_ANY 0x0000 // Bursts of unspecified length -#define USB_DMACTL0_BRSTM_INC4 0x0200 // INCR4 or unspecified length -#define USB_DMACTL0_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified +#define MUSB_DMACTL0_BRSTM_M 0x0600 // Burst Mode +#define MUSB_DMACTL0_BRSTM_ANY 0x0000 // Bursts of unspecified length +#define MUSB_DMACTL0_BRSTM_INC4 0x0200 // INCR4 or unspecified length +#define MUSB_DMACTL0_BRSTM_INC8 0x0400 // INCR8, INCR4 or unspecified // length -#define USB_DMACTL0_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or +#define MUSB_DMACTL0_BRSTM_INC16 0x0600 // INCR16, INCR8, INCR4 or // unspecified length -#define USB_DMACTL0_ERR 0x0100 // Bus Error Bit -#define USB_DMACTL0_EP_M 0x00F0 // Endpoint number -#define USB_DMACTL0_IE 0x0008 // DMA Interrupt Enable -#define USB_DMACTL0_MODE 0x0004 // DMA Transfer Mode -#define USB_DMACTL0_DIR 0x0002 // DMA Direction -#define USB_DMACTL0_ENABLE 0x0001 // DMA Transfer Enable -#define USB_DMACTL0_EP_S 4 +#define MUSB_DMACTL0_ERR 0x0100 // Bus Error Bit +#define MUSB_DMACTL0_EP_M 0x00F0 // Endpoint number +#define MUSB_DMACTL0_IE 0x0008 // DMA Interrupt Enable +#define MUSB_DMACTL0_MODE 0x0004 // DMA Transfer Mode +#define MUSB_DMACTL0_DIR 0x0002 // DMA Direction +#define MUSB_DMACTL0_ENABLE 0x0001 // DMA Transfer Enable +#define MUSB_DMACTL0_EP_S 4 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_DMAADDR0 register. +// The following are defines for the bit fields in the MUSB_O_DMAADDR0 register. // //***************************************************************************** -#define USB_DMAADDR0_ADDR_M 0xFFFFFFFC // DMA Address -#define USB_DMAADDR0_ADDR_S 2 +#define MUSB_DMAADDR0_ADDR_M 0xFFFFFFFC // DMA Address +#define MUSB_DMAADDR0_ADDR_S 2 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_DMACOUNT0 +// The following are defines for the bit fields in the MUSB_O_DMACOUNT0 // register. // //***************************************************************************** -#define USB_DMACOUNT0_COUNT_M 0xFFFFFFFC // DMA Count -#define USB_DMACOUNT0_COUNT_S 2 +#define MUSB_DMACOUNT0_COUNT_M 0xFFFFFFFC // DMA Count +#define MUSB_DMACOUNT0_COUNT_S 2 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_CTO register. +// The following are defines for the bit fields in the MUSB_O_CTO register. // //***************************************************************************** -#define USB_CTO_CCTV_M 0xFFFF // Configurable Chirp Timeout Value -#define USB_CTO_CCTV_S 0 +#define MUSB_CTO_CCTV_M 0xFFFF // Configurable Chirp Timeout Value +#define MUSB_CTO_CCTV_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_HHSRTN register. +// The following are defines for the bit fields in the MUSB_O_HHSRTN register. // //***************************************************************************** -#define USB_HHSRTN_HHSRTN_M 0xFFFF // HIgh Speed to UTM Operating +#define MUSB_HHSRTN_HHSRTN_M 0xFFFF // HIgh Speed to UTM Operating // Delay -#define USB_HHSRTN_HHSRTN_S 0 +#define MUSB_HHSRTN_HHSRTN_S 0 //***************************************************************************** // -// The following are defines for the bit fields in the USB_O_HSBT register. +// The following are defines for the bit fields in the MUSB_O_HSBT register. // //***************************************************************************** -#define USB_HSBT_HSBT_M 0x000F // High Speed Timeout Adder -#define USB_HSBT_HSBT_S 0 +#define MUSB_HSBT_HSBT_M 0x000F // High Speed Timeout Adder +#define MUSB_HSBT_HSBT_S 0 #ifdef __cplusplus } -- cgit v1.3.1 From 76eb2f506642968b2b0079326483905e79d20d2f Mon Sep 17 00:00:00 2001 From: hathach Date: Sun, 18 Aug 2024 16:34:58 +0700 Subject: more musb update --- src/portable/mentor/musb/dcd_musb.c | 79 +++++++++++++++++++---------------- src/portable/mentor/musb/musb_max32.h | 12 ++---- src/portable/mentor/musb/musb_type.h | 14 ++++--- 3 files changed, 54 insertions(+), 51 deletions(-) (limited to 'src/portable') diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 3fd4d953a..585480772 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -643,8 +643,7 @@ void dcd_sof_enable(uint8_t rhport, bool en) //--------------------------------------------------------------------+ // Configure endpoint's registers according to descriptor -bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) -{ +bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { const unsigned ep_addr = ep_desc->bEndpointAddress; const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir_in = tu_edpt_dir(ep_addr); @@ -662,22 +661,30 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn); const uint8_t is_rx = 1 - dir_in; - ep_csr->maxp_csr[is_rx].maxp = mps; - ep_csr->maxp_csr[is_rx].csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? MUSB_RXCSRH1_ISO : 0; + musb_ep_maxp_csr_t* maxp_csr = &ep_csr->maxp_csr[is_rx]; + maxp_csr->maxp = mps; + maxp_csr->csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? MUSB_RXCSRH1_ISO : 0; + // flush and reset data toggle uint8_t csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(is_rx); - if (ep_csr->maxp_csr[is_rx].csrl & MUSB_CSRL_PACKET_READY(is_rx)) { + if (maxp_csr->csrl & MUSB_CSRL_PACKET_READY(is_rx)) { csrl |= MUSB_CSRL_FLUSH_FIFO(is_rx); } - ep_csr->maxp_csr[is_rx].csrl = csrl; + maxp_csr->csrl = csrl; + musb->intren_ep[is_rx] |= TU_BIT(epn); - /* Setup FIFO */ fifo_configure(musb, epn, dir_in, mps); return true; } +// bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { +// } +// +// bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { +// } + void dcd_edpt_close_all(uint8_t rhport) { musb_regs_t* musb = MUSB_REGS(rhport); @@ -688,23 +695,20 @@ void dcd_edpt_close_all(uint8_t rhport) musb->intr_rxen = 0; for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { musb_ep_csr_t* ep_csr = get_ep_csr(musb, i); - ep_csr->tx_maxp = 0; - ep_csr->tx_csrh = 0; - if (ep_csr->tx_csrl & MUSB_TXCSRL1_TXRDY) - ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT | MUSB_TXCSRL1_FLUSH; - else - ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT; + for (unsigned d = 0; d < 2; d++) { + musb_ep_maxp_csr_t* maxp_csr = &ep_csr->maxp_csr[d]; + maxp_csr->maxp = 0; + maxp_csr->csrh = 0; + + // flush and reset data toggle + uint8_t csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(d); + if (maxp_csr->csrl & MUSB_CSRL_PACKET_READY(is_rx)) { + csrl |= MUSB_CSRL_FLUSH_FIFO(d); + } + maxp_csr->csrl = csrl; - ep_csr->rx_maxp = 0; - ep_csr->rx_csrh = 0; - if (ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY) { - ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT | MUSB_RXCSRL1_FLUSH; - } else { - ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT; + fifo_reset(musb, i, 1-d); } - - fifo_reset(musb, i, 0); - fifo_reset(musb, i, 1); } #if MUSB_CFG_DYNAMIC_FIFO @@ -755,12 +759,14 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t unsigned const epnum = tu_edpt_number(ep_addr); unsigned const ie = musb_dcd_get_int_enable(rhport); musb_dcd_int_disable(rhport); + if (epnum) { _dcd.pipe_buf_is_fifo[tu_edpt_dir(ep_addr)] &= ~TU_BIT(epnum - 1); ret = edpt_n_xfer(rhport, ep_addr, buffer, total_bytes); } else { ret = edpt0_xfer(rhport, ep_addr, buffer, total_bytes); } + if (ie) musb_dcd_int_enable(rhport); return ret; } @@ -783,11 +789,13 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_ // Stall endpoint void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { - unsigned const epn = tu_edpt_number(ep_addr); unsigned const ie = musb_dcd_get_int_enable(rhport); + musb_dcd_int_disable(rhport); + + unsigned const epn = tu_edpt_number(ep_addr); musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); - musb_dcd_int_disable(rhport); + if (0 == epn) { if (!ep_addr) { /* Ignore EP80 */ _dcd.setup_packet.bmRequestType = REQUEST_TYPE_INVALID; @@ -795,13 +803,10 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { ep_csr->csr0l = MUSB_CSRL0_STALL; } } else { - if (tu_edpt_dir(ep_addr)) { /* IN */ - ep_csr->tx_csrl = MUSB_TXCSRL1_STALL; - } else { /* OUT */ - TU_ASSERT(!(ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY),); - ep_csr->rx_csrl = MUSB_RXCSRL1_STALL; - } + const uint8_t is_rx = 1 - tu_edpt_dir(ep_addr); + ep_csr->maxp_csr[is_rx].csrl = MUSB_CSRL_SEND_STALL(is_rx); } + if (ie) musb_dcd_int_enable(rhport); } @@ -809,16 +814,16 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { (void)rhport; + unsigned const ie = musb_dcd_get_int_enable(rhport); + musb_dcd_int_disable(rhport); + unsigned const epn = tu_edpt_number(ep_addr); musb_regs_t* musb_regs = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb_regs, epn); - unsigned const ie = musb_dcd_get_int_enable(rhport); - musb_dcd_int_disable(rhport); - if (tu_edpt_dir(ep_addr)) { /* IN */ - ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT; - } else { /* OUT */ - ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT; - } + const uint8_t is_rx = 1 - tu_edpt_dir(ep_addr); + + ep_csr->maxp_csr[is_rx].csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(is_rx); + if (ie) musb_dcd_int_enable(rhport); } diff --git a/src/portable/mentor/musb/musb_max32.h b/src/portable/mentor/musb/musb_max32.h index 38e80f680..35849b5f8 100644 --- a/src/portable/mentor/musb/musb_max32.h +++ b/src/portable/mentor/musb/musb_max32.h @@ -47,18 +47,15 @@ static const IRQn_Type musb_irqs[] = { USB_IRQn }; -TU_ATTR_ALWAYS_INLINE -static inline void musb_dcd_int_enable(uint8_t rhport) { +TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_enable(uint8_t rhport) { NVIC_EnableIRQ(musb_irqs[rhport]); } -TU_ATTR_ALWAYS_INLINE -static inline void musb_dcd_int_disable(uint8_t rhport) { +TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_disable(uint8_t rhport) { NVIC_DisableIRQ(musb_irqs[rhport]); } -TU_ATTR_ALWAYS_INLINE -static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) { +TU_ATTR_ALWAYS_INLINE static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) { #ifdef NVIC_GetEnableIRQ // only defined in CMSIS 5 return NVIC_GetEnableIRQ(musb_irqs[rhport]); #else @@ -67,8 +64,7 @@ static inline unsigned musb_dcd_get_int_enable(uint8_t rhport) { #endif } -TU_ATTR_ALWAYS_INLINE -static inline void musb_dcd_int_clear(uint8_t rhport) { +TU_ATTR_ALWAYS_INLINE static inline void musb_dcd_int_clear(uint8_t rhport) { NVIC_ClearPendingIRQ(musb_irqs[rhport]); } diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index 3415f74b5..f8a66acce 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -83,6 +83,12 @@ #define __R volatile const #endif +typedef struct TU_ATTR_PACKED { + __IO uint16_t maxp; // 0x00, 0x04: MAXP + __IO uint8_t csrl; // 0x02, 0x06: CSRL + __IO uint8_t csrh; // 0x03, 0x07: CSRH +}musb_ep_maxp_csr_t; + // 0: TX (device IN, host OUT) // 1: RX (device OUT, host IN) typedef struct TU_ATTR_PACKED { @@ -103,11 +109,7 @@ typedef struct TU_ATTR_PACKED { __IO uint8_t rx_csrh; // 0x07: RX CSRH }; - struct { - __IO uint16_t maxp; // 0x00: MAXP - __IO uint8_t csrl; // 0x02: CSRL - __IO uint8_t csrh; // 0x03: CSRH - }maxp_csr[2]; + musb_ep_maxp_csr_t maxp_csr[2]; }; union { @@ -330,7 +332,7 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ #define MUSB_CSRL_PACKET_READY(_rx) (1u << 0) #define MUSB_CSRL_FLUSH_FIFO(_rx) (1u << ((_rx) ? 4 : 3)) #define MUSB_CSRL_SEND_STALL(_rx) (1u << ((_rx) ? 5 : 4)) -#define MUSB_CSRL_SENT_STALL(_rx) (1u << ((_rx) ? 6 : 5)) +#define MUSB_CSRL_STALLED(_rx) (1u << ((_rx) ? 6 : 5)) #define MUSB_CSRL_CLEAR_DATA_TOGGLE(_rx) (1u << ((_rx) ? 7 : 6)) // 0x13, 0x17: TX/RX CSRH -- cgit v1.3.1 From 8fdd8d9a7b83bfb79ac9a02142592d7ee4948b83 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 19 Aug 2024 11:59:41 +0700 Subject: implement dcd_edpt_iso_alloc/dcd_edpt_iso_activate for musb. video_capture example with iso kind of work but not smoothly. audio example does not seems to work as expected --- hw/bsp/max32690/family.cmake | 1 + src/common/tusb_mcu.h | 3 +- src/device/dcd.h | 15 +-- src/device/usbd.c | 18 +++- src/portable/mentor/musb/dcd_musb.c | 198 ++++++++++++++++++++--------------- src/portable/mentor/musb/musb_ti.h | 145 +------------------------ src/portable/mentor/musb/musb_type.h | 56 +--------- 7 files changed, 147 insertions(+), 289 deletions(-) (limited to 'src/portable') diff --git a/hw/bsp/max32690/family.cmake b/hw/bsp/max32690/family.cmake index 58647e432..736ca8eac 100644 --- a/hw/bsp/max32690/family.cmake +++ b/hw/bsp/max32690/family.cmake @@ -15,6 +15,7 @@ set(LD_FILE_Clang ${LD_FILE_GNU}) set(CMAKE_SYSTEM_PROCESSOR cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) set(JLINK_DEVICE max32690) +set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -f target/max32690.cfg") set(FAMILY_MCUS MAX32690 CACHE INTERNAL "") diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index b7cbd83df..e86f55c1d 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -518,7 +518,8 @@ #define TU_ATTR_FAST_FUNC #endif -#if defined(TUP_USBIP_DWC2) || defined(TUP_USBIP_FSDEV) +// USBIP that support ISO alloc & activate API +#if defined(TUP_USBIP_DWC2) || defined(TUP_USBIP_FSDEV) || defined(TUP_USBIP_MUSB) #define TUP_DCD_EDPT_ISO_ALLOC #endif diff --git a/src/device/dcd.h b/src/device/dcd.h index 41e0fbee3..66fae0802 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -157,10 +157,6 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc // required for multiple configuration support. void dcd_edpt_close_all (uint8_t rhport); -// Close an endpoint. -// Since it is weak, caller must TU_ASSERT this function's existence before calling it. -void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) TU_ATTR_WEAK; - // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes); @@ -175,12 +171,19 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr); // This API never calls with control endpoints, since it is auto cleared when receiving setup packet void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr); +#ifdef TUP_DCD_EDPT_ISO_ALLOC // Allocate packet buffer used by ISO endpoints // Some MCU need manual packet buffer allocation, we allocate the largest size to avoid clustering -TU_ATTR_WEAK bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size); +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size); // Configure and enable an ISO endpoint according to descriptor -TU_ATTR_WEAK bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep); +bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep); + +#else +// Close an endpoint. +void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr); + +#endif //--------------------------------------------------------------------+ // Event API (implemented by stack) diff --git a/src/device/usbd.c b/src/device/usbd.c index 7089e9cf1..d6f69fc24 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1418,6 +1418,10 @@ bool usbd_edpt_stalled(uint8_t rhport, uint8_t ep_addr) { * In progress transfers on this EP may be delivered after this call. */ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) { +#ifdef TUP_DCD_EDPT_ISO_ALLOC + (void) rhport; (void) ep_addr; + // ISO alloc/activate Should be used instead +#else rhport = _usbd_rhport; TU_ASSERT(dcd_edpt_close, /**/); @@ -1430,6 +1434,7 @@ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr) { _usbd_dev.ep_status[epnum][dir].stalled = 0; _usbd_dev.ep_status[epnum][dir].busy = 0; _usbd_dev.ep_status[epnum][dir].claimed = 0; +#endif return; } @@ -1452,21 +1457,24 @@ void usbd_sof_enable(uint8_t rhport, sof_consumer_t consumer, bool en) { } bool usbd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { +#ifdef TUP_DCD_EDPT_ISO_ALLOC rhport = _usbd_rhport; - TU_ASSERT(dcd_edpt_iso_alloc); TU_ASSERT(tu_edpt_number(ep_addr) < CFG_TUD_ENDPPOINT_MAX); - return dcd_edpt_iso_alloc(rhport, ep_addr, largest_packet_size); +#else + (void) rhport; (void) ep_addr; (void) largest_packet_size; + return false; +#endif } bool usbd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const* desc_ep) { +#ifdef TUP_DCD_EDPT_ISO_ALLOC rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(desc_ep->bEndpointAddress); uint8_t const dir = tu_edpt_dir(desc_ep->bEndpointAddress); - TU_ASSERT(dcd_edpt_iso_activate); TU_ASSERT(epnum < CFG_TUD_ENDPPOINT_MAX); TU_ASSERT(tu_edpt_validate(desc_ep, (tusb_speed_t) _usbd_dev.speed)); @@ -1474,6 +1482,10 @@ bool usbd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const* desc_ep) _usbd_dev.ep_status[epnum][dir].busy = 0; _usbd_dev.ep_status[epnum][dir].claimed = 0; return dcd_edpt_iso_activate(rhport, desc_ep); +#else + (void) rhport; (void) desc_ep; + return false; +#endif } #endif diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 585480772..dc2753ea6 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -94,64 +94,71 @@ static dcd_data_t _dcd; // First 64 bytes are reserved for EP0 static uint32_t alloced_fifo_bytes; -TU_ATTR_ALWAYS_INLINE static inline void fifo_reset(musb_regs_t* musb, unsigned epnum, unsigned dir_in) { +// ffsize is log2(mps) - 3 (round up) +TU_ATTR_ALWAYS_INLINE static inline uint8_t hwfifo_byte2size(uint16_t nbytes) { + uint8_t ffsize = 28 - tu_min8(28, __builtin_clz(nbytes)); + // round up to the next power of 2 + if ((8u << ffsize) < nbytes) { + ++ffsize; + } + + return ffsize; +} + +// index register is already set +TU_ATTR_ALWAYS_INLINE static inline void hwfifo_reset(musb_regs_t* musb, unsigned epnum, unsigned dir_in) { + (void) epnum; const uint8_t is_rx = 1 - dir_in; - musb->index = epnum; musb->fifo_size[is_rx] = 0; musb->fifo_addr[is_rx] = 0; } -TU_ATTR_ALWAYS_INLINE static inline bool fifo_configure(musb_regs_t* musb, unsigned epnum, unsigned dir_in, unsigned mps) { - // ffsize is log2(mps) - 3 (round up) - uint8_t ffsize = 28 - tu_min8(28, __builtin_clz(mps)); - // round up to the next power of 2 - if ((8u << ffsize) < mps) { - ++ffsize; - mps = 8 << ffsize; +// index register is already set +TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsigned epnum, unsigned dir_in, unsigned mps, bool double_packet) { + (void) epnum; + uint8_t ffsize = hwfifo_byte2size(mps); + mps = 8 << ffsize; // round up to the next power of 2 + + if (double_packet) { + ffsize |= MUSB_FIFOSZ_DOUBLE_PACKET; + mps <<= 1; } TU_ASSERT(alloced_fifo_bytes + mps <= MUSB_CFG_DYNAMIC_FIFO_SIZE); const uint8_t is_rx = 1 - dir_in; - musb->index = epnum; + musb->fifo_addr[is_rx] = alloced_fifo_bytes / 8; musb->fifo_size[is_rx] = ffsize; alloced_fifo_bytes += mps; - return true; } #else -TU_ATTR_ALWAYS_INLINE static inline void fifo_reset(musb_regs_t* musb, unsigned epnum, unsigned dir_in) { - const uint8_t is_rx = 1 - dir_in; - musb->index = epnum; - #if defined(TUP_USBIP_MUSB_ADI) - // Analog have custom double buffered in csrh register, disable it - musb->indexed_csr.maxp_csr[is_rx].csrh |= MUSB_CSRH_DISABLE_DOUBLE_PACKET(is_rx); - #else - // disable double bufeffered in extended register - #endif +// index register is already set +TU_ATTR_ALWAYS_INLINE static inline void hwfifo_reset(musb_regs_t* musb, unsigned epnum, unsigned dir_in) { + (void) musb; (void) epnum; (void) dir_in; + // nothing to do for static FIFO } -TU_ATTR_ALWAYS_INLINE static inline bool fifo_configure(musb_regs_t* musb, unsigned epnum, unsigned dir_in, unsigned mps) { - (void) mps; - const uint8_t is_rx = 1 - dir_in; - musb->index = epnum; - - uint8_t csrh = 0; - -#if defined(TUP_USBIP_MUSB_ADI) - csrh = MUSB_CSRH_DISABLE_DOUBLE_PACKET(is_rx); -#endif +// index register is already set +TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsigned epnum, unsigned dir_in, unsigned mps, + bool double_packet) { + (void) epnum; (void) dir_in; (void) mps; -#if MUSB_CFG_SHARED_FIFO - if (dir_in) { - csrh |= MUSB_CSRH_TX_MODE; + if (!double_packet) { + #if defined(TUP_USBIP_MUSB_ADI) + const uint8_t is_rx = 1 - dir_in; + musb->indexed_csr.maxp_csr[is_rx].csrh |= MUSB_CSRH_DISABLE_DOUBLE_PACKET(is_rx); + #else + if (is_rx) { + musb->rx_doulbe_packet_disable |= 1u << epnum; + } else { + musb->tx_double_packet_disable |= 1u << epnum; + } + #endif } -#endif - - musb->indexed_csr.maxp_csr[is_rx].csrh |= csrh; return true; } @@ -538,8 +545,9 @@ static void process_bus_reset(uint8_t rhport) { /* Clear FIFO settings */ for (unsigned i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { - fifo_reset(musb, i, 0); - fifo_reset(musb, i, 1); + musb->index = i; + hwfifo_reset(musb, i, 0); + hwfifo_reset(musb, i, 1); } dcd_event_bus_reset(rhport, (musb->power & MUSB_POWER_HSMODE) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true); } @@ -641,17 +649,18 @@ void dcd_sof_enable(uint8_t rhport, bool en) //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ +// static void edpt_setup(musb_regs_t* musb, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_size){ +// const unsigned epn = tu_edpt_number(ep_addr); +// const unsigned dir_in = tu_edpt_dir(ep_addr); +// } // Configure endpoint's registers according to descriptor bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { const unsigned ep_addr = ep_desc->bEndpointAddress; const unsigned epn = tu_edpt_number(ep_addr); const unsigned dir_in = tu_edpt_dir(ep_addr); - const unsigned xfer = ep_desc->bmAttributes.xfer; const unsigned mps = tu_edpt_packet_size(ep_desc); - TU_ASSERT(epn < TUP_DCD_ENDPOINT_MAX); - pipe_state_t *pipe = &_dcd.pipe[dir_in][epn - 1]; pipe->buf = NULL; pipe->length = 0; @@ -659,11 +668,16 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { musb_regs_t* musb = MUSB_REGS(rhport); musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn); - const uint8_t is_rx = 1 - dir_in; musb_ep_maxp_csr_t* maxp_csr = &ep_csr->maxp_csr[is_rx]; + maxp_csr->maxp = mps; - maxp_csr->csrh = (xfer == TUSB_XFER_ISOCHRONOUS) ? MUSB_RXCSRH1_ISO : 0; + maxp_csr->csrh = 0; +#if MUSB_CFG_SHARED_FIFO + if (dir_in) { + maxp_csr->csrh |= MUSB_CSRH_TX_MODE; + } +#endif // flush and reset data toggle uint8_t csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(is_rx); @@ -672,18 +686,65 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { } maxp_csr->csrl = csrl; + TU_ASSERT(hwfifo_config(musb, epn, dir_in, mps, false)); musb->intren_ep[is_rx] |= TU_BIT(epn); - fifo_configure(musb, epn, dir_in, mps); - return true; } -// bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { -// } -// -// bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) { -// } +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned dir_in = tu_edpt_dir(ep_addr); + musb_regs_t* musb = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn); + const uint8_t is_rx = 1 - dir_in; + ep_csr->maxp_csr[is_rx].csrh = 0; + return hwfifo_config(musb, epn, dir_in, largest_packet_size, true); +} + +bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc ) { + const unsigned ep_addr = ep_desc->bEndpointAddress; + const unsigned epn = tu_edpt_number(ep_addr); + const unsigned dir_in = tu_edpt_dir(ep_addr); + const unsigned mps = tu_edpt_packet_size(ep_desc); + + unsigned const ie = musb_dcd_get_int_enable(rhport); + musb_dcd_int_disable(rhport); + + pipe_state_t *pipe = &_dcd.pipe[dir_in][epn - 1]; + pipe->buf = NULL; + pipe->length = 0; + pipe->remaining = 0; + + musb_regs_t* musb = MUSB_REGS(rhport); + musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn); + const uint8_t is_rx = 1 - dir_in; + musb_ep_maxp_csr_t* maxp_csr = &ep_csr->maxp_csr[is_rx]; + + maxp_csr->maxp = mps; + maxp_csr->csrh |= MUSB_CSRH_ISO; +#if MUSB_CFG_SHARED_FIFO + if (dir_in) { + maxp_csr->csrh |= MUSB_CSRH_TX_MODE; + } +#endif + + // flush fifo + if (maxp_csr->csrl & MUSB_CSRL_PACKET_READY(is_rx)) { + maxp_csr->csrl = MUSB_CSRL_FLUSH_FIFO(is_rx); + } + +#if MUSB_CFG_DYNAMIC_FIFO + // fifo space is already allocated, keep the address and just change packet size + musb->fifo_size[is_rx] = hwfifo_byte2size(mps) | MUSB_FIFOSZ_DOUBLE_PACKET; +#endif + + musb->intren_ep[is_rx] |= TU_BIT(epn); + + if (ie) musb_dcd_int_enable(rhport); + + return true; +} void dcd_edpt_close_all(uint8_t rhport) { @@ -707,7 +768,7 @@ void dcd_edpt_close_all(uint8_t rhport) } maxp_csr->csrl = csrl; - fifo_reset(musb, i, 1-d); + hwfifo_reset(musb, i, 1-d); } } @@ -718,38 +779,6 @@ void dcd_edpt_close_all(uint8_t rhport) if (ie) musb_dcd_int_enable(rhport); } -void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) -{ - // FIXME: we should implement iso_alloc() and iso_activate() - unsigned const epn = tu_edpt_number(ep_addr); - unsigned const dir_in = tu_edpt_dir(ep_addr); - musb_regs_t* musb = MUSB_REGS(rhport); - musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn); - unsigned const ie = musb_dcd_get_int_enable(rhport); - musb_dcd_int_disable(rhport); - if (dir_in) { - musb->intr_txen &= ~TU_BIT(epn); - ep_csr->tx_maxp = 0; - ep_csr->tx_csrh = 0; - if (ep_csr->tx_csrl & MUSB_TXCSRL1_TXRDY) { - ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT | MUSB_TXCSRL1_FLUSH; - } else { - ep_csr->tx_csrl = MUSB_TXCSRL1_CLRDT; - } - } else { - musb->intr_rxen &= ~TU_BIT(epn); - ep_csr->rx_maxp = 0; - ep_csr->rx_csrh = 0; - if (ep_csr->rx_csrl & MUSB_RXCSRL1_RXRDY) { - ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT | MUSB_RXCSRL1_FLUSH; - } else { - ep_csr->rx_csrl = MUSB_RXCSRL1_CLRDT; - } - } - fifo_reset(musb, epn, dir_in); - if (ie) musb_dcd_int_enable(rhport); -} - // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) { @@ -771,7 +800,8 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t t return ret; } -// Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c +// Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack +// - optional, however, must be listed in usbd.c bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) { (void)rhport; diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h index 680bebde7..d17e836ee 100644 --- a/src/portable/mentor/musb/musb_ti.h +++ b/src/portable/mentor/musb/musb_ti.h @@ -42,8 +42,8 @@ #error "Unsupported MCUs" #endif -#define MUSB_CFG_SHARED_FIFO 0 -#define MUSB_CFG_DYNAMIC_FIFO 1 +#define MUSB_CFG_SHARED_FIFO 0 +#define MUSB_CFG_DYNAMIC_FIFO 1 #define MUSB_CFG_DYNAMIC_FIFO_SIZE 4096 const uintptr_t MUSB_BASES[] = { USB0_BASE }; @@ -51,11 +51,6 @@ const uintptr_t MUSB_BASES[] = { USB0_BASE }; // Header supports both device and host modes. Only include what's necessary #if CFG_TUD_ENABLED -// Mapping of peripheral instances to port. Currently just 1. -static USB0_Type* const musb_periph_inst[] = { - USB0 -}; - // Mapping of IRQ numbers to port. Currently just 1. static const IRQn_Type musb_irqs[] = { USB0_IRQn @@ -87,142 +82,6 @@ static inline void musb_dcd_int_handler_enter(uint8_t rhport) { //Nothing to do for this part } -#if 0 -typedef struct { - uint_fast16_t beg; /* offset of including first element */ - uint_fast16_t end; /* offset of excluding the last element */ -} free_block_t; - -static inline free_block_t *find_containing_block(free_block_t *beg, free_block_t *end, uint_fast16_t addr) { - free_block_t *cur = beg; - for (; cur < end && ((addr < cur->beg) || (cur->end <= addr)); ++cur) ; - return cur; -} - -static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_fast16_t addr, uint_fast16_t size) { - free_block_t *p = find_containing_block(blks, blks + num, addr); - TU_ASSERT(p != blks + num, -2); - if (p->beg == addr) { - /* Shrink block */ - p->beg = addr + size; - if (p->beg != p->end) return 0; - /* remove block */ - free_block_t *end = blks + num; - while (p + 1 < end) { - *p = *(p + 1); - ++p; - } - return -1; - } else { - /* Split into 2 blocks */ - free_block_t tmp = { - .beg = addr + size, - .end = p->end - }; - p->end = addr; - if (p->beg == p->end) { - if (tmp.beg != tmp.end) { - *p = tmp; - return 0; - } - /* remove block */ - free_block_t *end = blks + num; - while (p + 1 < end) { - *p = *(p + 1); - ++p; - } - return -1; - } - if (tmp.beg == tmp.end) return 0; - blks[num] = tmp; - return 1; - } -} - -static inline unsigned free_block_size(free_block_t const *blk) { - return blk->end - blk->beg; -} - -#if 0 -static inline void print_block_list(free_block_t const *blk, unsigned num) -{ - TU_LOG1("*************\r\n"); - for (unsigned i = 0; i < num; ++i) { - TU_LOG1(" Blk%u %u %u\r\n", i, blk->beg, blk->end); - ++blk; - } -} -#else -#define print_block_list(a,b) -#endif - -static unsigned find_free_memory(uint8_t rhport, uint_fast16_t size_in_log2_minus3) -{ - free_block_t free_blocks[2 * (TUP_DCD_ENDPOINT_MAX - 1)]; - unsigned num_blocks = 1; - - /* Initialize free memory block list */ - free_blocks[0].beg = 64 / 8; - free_blocks[0].end = (4 << 10) / 8; /* 4KiB / 8 bytes */ - for (int i = 1; i < TUP_DCD_ENDPOINT_MAX; ++i) { - uint_fast16_t addr; - int num; - musb_periph_inst[rhport]->EPIDX = i; - addr = musb_periph_inst[rhport]->TXFIFOADD; - if (addr) { - unsigned sz = musb_periph_inst[rhport]->TXFIFOSZ; - unsigned sft = (sz & USB_TXFIFOSZ_SIZE_M) + ((sz & USB_TXFIFOSZ_DPB) ? 1: 0); - num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); - TU_ASSERT(-2 < num, 0); - num_blocks += num; - print_block_list(free_blocks, num_blocks); - } - addr = musb_periph_inst[rhport]->RXFIFOADD; - if (addr) { - unsigned sz = musb_periph_inst[rhport]->RXFIFOSZ; - unsigned sft = (sz & USB_RXFIFOSZ_SIZE_M) + ((sz & USB_RXFIFOSZ_DPB) ? 1: 0); - num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); - TU_ASSERT(-2 < num, 0); - num_blocks += num; - print_block_list(free_blocks, num_blocks); - } - } - print_block_list(free_blocks, num_blocks); - - /* Find the best fit memory block */ - uint_fast16_t size_in_8byte_unit = 1 << size_in_log2_minus3; - free_block_t const *min = NULL; - uint_fast16_t min_sz = 0xFFFFu; - free_block_t const *end = &free_blocks[num_blocks]; - for (free_block_t const *cur = &free_blocks[0]; cur < end; ++cur) { - uint_fast16_t sz = free_block_size(cur); - if (sz < size_in_8byte_unit) continue; - if (size_in_8byte_unit == sz) return cur->beg; - if (sz < min_sz) min = cur; - } - TU_ASSERT(min, 0); - return min->beg; -} - - -static inline void musb_dcd_setup_fifo(uint8_t rhport, unsigned epnum, unsigned dir_in, unsigned mps) -{ - int size_in_log2_minus3 = 28 - TU_MIN(28, __CLZ((uint32_t)mps)); - if ((8u << size_in_log2_minus3) < mps) ++size_in_log2_minus3; - unsigned addr = find_free_memory(rhport, size_in_log2_minus3); - TU_ASSERT(addr,); - - musb_periph_inst[rhport]->EPIDX = epnum; - if (dir_in) { - musb_periph_inst[rhport]->TXFIFOADD = addr; - musb_periph_inst[rhport]->TXFIFOSZ = size_in_log2_minus3; - } else { - musb_periph_inst[rhport]->RXFIFOADD = addr; - musb_periph_inst[rhport]->RXFIFOSZ = size_in_log2_minus3; - } -} -#endif - #endif // CFG_TUD_ENABLED #ifdef __cplusplus diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index f8a66acce..4e448c0ed 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -338,6 +338,10 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ // 0x13, 0x17: TX/RX CSRH #define MUSB_CSRH_DISABLE_DOUBLE_PACKET(_rx) (1u << 1) #define MUSB_CSRH_TX_MODE (1u << 5) // 1 = TX, 0 = RX. only relevant for SHARED FIFO +#define MUSB_CSRH_ISO (1u << 6) + +// 0x62, 0x63: TXFIFO_SZ, RXFIFO_SZ +#define MUSB_FIFOSZ_DOUBLE_PACKET (1u << 4) //***************************************************************************** @@ -417,58 +421,6 @@ TU_ATTR_ALWAYS_INLINE static inline musb_ep_csr_t* get_ep_csr(musb_regs_t* musb_ #define MUSB_CCONF_TXEDMA 0x0002 // TX Early DMA Enable #define MUSB_CCONF_RXEDMA 0x0001 // TX Early DMA Enable -//***************************************************************************** -// -// The following are defines for the bit fields in the MUSB_O_TXFIFOSZ register. -// -//***************************************************************************** -#define MUSB_TXFIFOSZ_DPB 0x0010 // Double Packet Buffer Support -#define MUSB_TXFIFOSZ_SIZE_M 0x000F // Max Packet Size -#define MUSB_TXFIFOSZ_SIZE_8 0x0000 // 8 -#define MUSB_TXFIFOSZ_SIZE_16 0x0001 // 16 -#define MUSB_TXFIFOSZ_SIZE_32 0x0002 // 32 -#define MUSB_TXFIFOSZ_SIZE_64 0x0003 // 64 -#define MUSB_TXFIFOSZ_SIZE_128 0x0004 // 128 -#define MUSB_TXFIFOSZ_SIZE_256 0x0005 // 256 -#define MUSB_TXFIFOSZ_SIZE_512 0x0006 // 512 -#define MUSB_TXFIFOSZ_SIZE_1024 0x0007 // 1024 -#define MUSB_TXFIFOSZ_SIZE_2048 0x0008 // 2048 - -//***************************************************************************** -// -// The following are defines for the bit fields in the MUSB_O_RXFIFOSZ register. -// -//***************************************************************************** -#define MUSB_RXFIFOSZ_DPB 0x0010 // Double Packet Buffer Support -#define MUSB_RXFIFOSZ_SIZE_M 0x000F // Max Packet Size -#define MUSB_RXFIFOSZ_SIZE_8 0x0000 // 8 -#define MUSB_RXFIFOSZ_SIZE_16 0x0001 // 16 -#define MUSB_RXFIFOSZ_SIZE_32 0x0002 // 32 -#define MUSB_RXFIFOSZ_SIZE_64 0x0003 // 64 -#define MUSB_RXFIFOSZ_SIZE_128 0x0004 // 128 -#define MUSB_RXFIFOSZ_SIZE_256 0x0005 // 256 -#define MUSB_RXFIFOSZ_SIZE_512 0x0006 // 512 -#define MUSB_RXFIFOSZ_SIZE_1024 0x0007 // 1024 -#define MUSB_RXFIFOSZ_SIZE_2048 0x0008 // 2048 - -//***************************************************************************** -// -// The following are defines for the bit fields in the MUSB_O_TXFIFOADD -// register. -// -//***************************************************************************** -#define MUSB_TXFIFOADD_ADDR_M 0x01FF // Transmit/Receive Start Address -#define MUSB_TXFIFOADD_ADDR_S 0 - -//***************************************************************************** -// -// The following are defines for the bit fields in the MUSB_O_RXFIFOADD -// register. -// -//***************************************************************************** -#define MUSB_RXFIFOADD_ADDR_M 0x01FF // Transmit/Receive Start Address -#define MUSB_RXFIFOADD_ADDR_S 0 - //***************************************************************************** // // The following are defines for the bit fields in the MUSB_O_ULPIVBUSCTL -- cgit v1.3.1 From 0c9d7a21858d246dfaadb78122c27c6e4099109c Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 19 Aug 2024 12:38:45 +0700 Subject: add hwfifo_flush() --- src/portable/mentor/musb/dcd_musb.c | 72 ++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 41 deletions(-) (limited to 'src/portable') diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index dc2753ea6..a40b3dc07 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -81,11 +81,13 @@ typedef struct uint16_t pipe_buf_is_fifo[2]; /* Bitmap. Each bit means whether 1:TU_FIFO or 0:POD. */ } dcd_data_t; -/*------------------------------------------------------------------ - * INTERNAL OBJECT & FUNCTION DECLARATION - *------------------------------------------------------------------*/ static dcd_data_t _dcd; +//-------------------------------------------------------------------- +// HW FIFO Helper +// Note: Index register is already set by caller +//-------------------------------------------------------------------- + #if MUSB_CFG_DYNAMIC_FIFO // musb is configured to use dynamic FIFO sizing. @@ -97,24 +99,20 @@ static uint32_t alloced_fifo_bytes; // ffsize is log2(mps) - 3 (round up) TU_ATTR_ALWAYS_INLINE static inline uint8_t hwfifo_byte2size(uint16_t nbytes) { uint8_t ffsize = 28 - tu_min8(28, __builtin_clz(nbytes)); - // round up to the next power of 2 if ((8u << ffsize) < nbytes) { ++ffsize; } - return ffsize; } -// index register is already set -TU_ATTR_ALWAYS_INLINE static inline void hwfifo_reset(musb_regs_t* musb, unsigned epnum, unsigned dir_in) { +TU_ATTR_ALWAYS_INLINE static inline void hwfifo_reset(musb_regs_t* musb, unsigned epnum, unsigned is_rx) { (void) epnum; - const uint8_t is_rx = 1 - dir_in; musb->fifo_size[is_rx] = 0; musb->fifo_addr[is_rx] = 0; } -// index register is already set -TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsigned epnum, unsigned dir_in, unsigned mps, bool double_packet) { +TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsigned epnum, unsigned is_rx, unsigned mps, + bool double_packet) { (void) epnum; uint8_t ffsize = hwfifo_byte2size(mps); mps = 8 << ffsize; // round up to the next power of 2 @@ -125,8 +123,6 @@ TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsign } TU_ASSERT(alloced_fifo_bytes + mps <= MUSB_CFG_DYNAMIC_FIFO_SIZE); - const uint8_t is_rx = 1 - dir_in; - musb->fifo_addr[is_rx] = alloced_fifo_bytes / 8; musb->fifo_size[is_rx] = ffsize; @@ -136,20 +132,16 @@ TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsign #else -// index register is already set -TU_ATTR_ALWAYS_INLINE static inline void hwfifo_reset(musb_regs_t* musb, unsigned epnum, unsigned dir_in) { - (void) musb; (void) epnum; (void) dir_in; +TU_ATTR_ALWAYS_INLINE static inline void hwfifo_reset(musb_regs_t* musb, unsigned epnum, unsigned is_rx) { + (void) musb; (void) epnum; (void) is_rx; // nothing to do for static FIFO } -// index register is already set -TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsigned epnum, unsigned dir_in, unsigned mps, +TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsigned epnum, unsigned is_rx, unsigned mps, bool double_packet) { - (void) epnum; (void) dir_in; (void) mps; - + (void) epnum; (void) mps; if (!double_packet) { #if defined(TUP_USBIP_MUSB_ADI) - const uint8_t is_rx = 1 - dir_in; musb->indexed_csr.maxp_csr[is_rx].csrh |= MUSB_CSRH_DISABLE_DOUBLE_PACKET(is_rx); #else if (is_rx) { @@ -165,6 +157,19 @@ TU_ATTR_ALWAYS_INLINE static inline bool hwfifo_config(musb_regs_t* musb, unsign #endif +// Flush FIFO and clear data toggle +TU_ATTR_ALWAYS_INLINE static inline void hwfifo_flush(musb_regs_t* musb, unsigned epnum, unsigned is_rx, bool clear_dtog) { + (void) epnum; + const uint8_t csrl_dtog = clear_dtog ? MUSB_CSRL_CLEAR_DATA_TOGGLE(is_rx) : 0; + musb_ep_maxp_csr_t* maxp_csr = &musb->indexed_csr.maxp_csr[is_rx]; + // may need to flush twice for double packet + for (unsigned i=0; i<2; i++) { + if (maxp_csr->csrl & MUSB_CSRL_PACKET_READY(is_rx)) { + maxp_csr->csrl = MUSB_CSRL_FLUSH_FIFO(is_rx) | csrl_dtog; + } + } +} + static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) { volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; @@ -679,14 +684,9 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { } #endif - // flush and reset data toggle - uint8_t csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(is_rx); - if (maxp_csr->csrl & MUSB_CSRL_PACKET_READY(is_rx)) { - csrl |= MUSB_CSRL_FLUSH_FIFO(is_rx); - } - maxp_csr->csrl = csrl; + hwfifo_flush(musb, epn, is_rx, true); - TU_ASSERT(hwfifo_config(musb, epn, dir_in, mps, false)); + TU_ASSERT(hwfifo_config(musb, epn, is_rx, mps, false)); musb->intren_ep[is_rx] |= TU_BIT(epn); return true; @@ -699,7 +699,7 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet musb_ep_csr_t* ep_csr = get_ep_csr(musb, epn); const uint8_t is_rx = 1 - dir_in; ep_csr->maxp_csr[is_rx].csrh = 0; - return hwfifo_config(musb, epn, dir_in, largest_packet_size, true); + return hwfifo_config(musb, epn, is_rx, largest_packet_size, true); } bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc ) { @@ -729,10 +729,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc ) } #endif - // flush fifo - if (maxp_csr->csrl & MUSB_CSRL_PACKET_READY(is_rx)) { - maxp_csr->csrl = MUSB_CSRL_FLUSH_FIFO(is_rx); - } + hwfifo_flush(musb, epn, is_rx, true); #if MUSB_CFG_DYNAMIC_FIFO // fifo space is already allocated, keep the address and just change packet size @@ -758,17 +755,10 @@ void dcd_edpt_close_all(uint8_t rhport) musb_ep_csr_t* ep_csr = get_ep_csr(musb, i); for (unsigned d = 0; d < 2; d++) { musb_ep_maxp_csr_t* maxp_csr = &ep_csr->maxp_csr[d]; + hwfifo_flush(musb, i, d, true); + hwfifo_reset(musb, i, d); maxp_csr->maxp = 0; maxp_csr->csrh = 0; - - // flush and reset data toggle - uint8_t csrl = MUSB_CSRL_CLEAR_DATA_TOGGLE(d); - if (maxp_csr->csrl & MUSB_CSRL_PACKET_READY(is_rx)) { - csrl |= MUSB_CSRL_FLUSH_FIFO(d); - } - maxp_csr->csrl = csrl; - - hwfifo_reset(musb, i, 1-d); } } -- cgit v1.3.1 From ea4f9ceb58f0aa6acc86bbe3083596a98b5355fd Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 19 Aug 2024 20:08:55 +0700 Subject: remove weak from dcd_edpt_close() for port without TUP_DCD_EDPT_ISO_ALLOC --- src/device/dcd.h | 2 +- src/portable/microchip/samg/dcd_samg.c | 5 +++++ src/portable/nxp/lpc17_40/dcd_lpc17_40.c | 5 +++++ src/portable/template/dcd_template.c | 16 ++++++++++++++++ src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 5 +++++ src/portable/valentyusb/eptri/dcd_eptri.c | 5 +++++ 6 files changed, 37 insertions(+), 1 deletion(-) (limited to 'src/portable') diff --git a/src/device/dcd.h b/src/device/dcd.h index d1d4e4897..3ef5188fc 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -181,7 +181,7 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) #else // Close an endpoint. -void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) TU_ATTR_WEAK; +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr); #endif diff --git a/src/portable/microchip/samg/dcd_samg.c b/src/portable/microchip/samg/dcd_samg.c index e3fa51e31..a15431937 100644 --- a/src/portable/microchip/samg/dcd_samg.c +++ b/src/portable/microchip/samg/dcd_samg.c @@ -277,6 +277,11 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) return true; } +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; (void) ep_addr; + // TODO implement dcd_edpt_close() +} + void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; diff --git a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c index b880c2870..75b29faf3 100644 --- a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c +++ b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c @@ -335,6 +335,11 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) return true; } +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; (void) ep_addr; + // TODO implement dcd_edpt_close() +} + void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; diff --git a/src/portable/template/dcd_template.c b/src/portable/template/dcd_template.c index 12d610bd6..25ee507c1 100644 --- a/src/portable/template/dcd_template.c +++ b/src/portable/template/dcd_template.c @@ -102,6 +102,22 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) return false; } +// Allocate packet buffer used by ISO endpoints +// Some MCU need manual packet buffer allocation, we allocate the largest size to avoid clustering +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { + (void) rhport; + (void) ep_addr; + (void) largest_packet_size; + return false; +} + +// Configure and enable an ISO endpoint according to descriptor +bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) { + (void) rhport; + (void) desc_ep; + return false; +} + void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 8005f5f7b..6b60bc657 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -332,6 +332,11 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) return true; } +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; (void) ep_addr; + // TODO implement dcd_edpt_close() +} + void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; diff --git a/src/portable/valentyusb/eptri/dcd_eptri.c b/src/portable/valentyusb/eptri/dcd_eptri.c index 58628a8bb..8f40e3349 100644 --- a/src/portable/valentyusb/eptri/dcd_eptri.c +++ b/src/portable/valentyusb/eptri/dcd_eptri.c @@ -436,6 +436,11 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) return true; } +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + (void) rhport; (void) ep_addr; + // TODO implement dcd_edpt_close() +} + void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; -- cgit v1.3.1 From 5bb2e66ce774fe174742f0893d82cb7895285983 Mon Sep 17 00:00:00 2001 From: Cumhur Onat Date: Sun, 21 Jul 2024 21:22:19 -0400 Subject: fix for out retry attempts with nak response --- src/portable/analog/max3421/hcd_max3421.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'src/portable') diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index d9b8e1fc3..342edef89 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -203,12 +203,13 @@ typedef struct { uint16_t packet_size : 11; }; + bool received_nak; uint16_t total_len; uint16_t xferred_len; uint8_t* buf; } max3421_ep_t; -TU_VERIFY_STATIC(sizeof(max3421_ep_t) == 12, "size is not correct"); +TU_VERIFY_STATIC(sizeof(max3421_ep_t) == 16, "size is not correct"); typedef struct { volatile uint16_t frame_count; @@ -625,12 +626,17 @@ static void xact_out(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_i reg_write(rhport, HCTL_ADDR, hctl, in_isr); } - uint8_t const xact_len = (uint8_t) tu_min16(ep->total_len - ep->xferred_len, ep->packet_size); - TU_ASSERT(_hcd_data.hirq & HIRQ_SNDBAV_IRQ,); - if (xact_len) { - fifo_write(rhport, SNDFIFO_ADDR, ep->buf, xact_len, in_isr); + if (!ep->received_nak){ + // do not write to fifo or sdnbc register again if previous attempt got NAK + uint8_t const xact_len = (uint8_t) tu_min16(ep->total_len - ep->xferred_len, ep->packet_size); + TU_ASSERT(_hcd_data.hirq & HIRQ_SNDBAV_IRQ,); + if (xact_len) { + fifo_write(rhport, SNDFIFO_ADDR, ep->buf, xact_len, in_isr); + } + + sndbc_write(rhport, xact_len, in_isr); } - sndbc_write(rhport, xact_len, in_isr); + hxfr_write(rhport, ep->hxfr, in_isr); } @@ -844,6 +850,7 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { return; } else if (EP_STATE_ATTEMPT_1 <= ep->state && ep->state < EP_STATE_ATTEMPT_MAX) { ep->state++; + ep->received_nak = true; } } @@ -867,6 +874,7 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { case HRSL_SUCCESS: xfer_result = XFER_RESULT_SUCCESS; + ep->received_nak = false; break; case HRSL_STALL: -- cgit v1.3.1 From c7851e8dcbdac8f895cfe81f2479bc6fcfcc524a Mon Sep 17 00:00:00 2001 From: Cumhur Onat Date: Sun, 21 Jul 2024 23:32:48 -0400 Subject: only check SNDBAV IRQ if there is data to send --- src/portable/analog/max3421/hcd_max3421.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/portable') diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 342edef89..3d054b66e 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -629,8 +629,9 @@ static void xact_out(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_i if (!ep->received_nak){ // do not write to fifo or sdnbc register again if previous attempt got NAK uint8_t const xact_len = (uint8_t) tu_min16(ep->total_len - ep->xferred_len, ep->packet_size); - TU_ASSERT(_hcd_data.hirq & HIRQ_SNDBAV_IRQ,); if (xact_len) { + // only check SNDBAV IRQ if there is data to send + TU_ASSERT(_hcd_data.hirq & HIRQ_SNDBAV_IRQ,); fifo_write(rhport, SNDFIFO_ADDR, ep->buf, xact_len, in_isr); } -- cgit v1.3.1 From 27ddf19631d135df15f3388686f59e379e146dbb Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 26 Aug 2024 12:24:29 +0700 Subject: add sndfifo owner info to skip rewriting data for retrying NAKed --- README.rst | 2 +- hw/bsp/family_support.cmake | 6 + src/host/usbh.h | 2 +- src/portable/analog/max3421/hcd_max3421.c | 191 +++++++++++++++++++----------- 4 files changed, 127 insertions(+), 74 deletions(-) (limited to 'src/portable') diff --git a/README.rst b/README.rst index 6dd0e2714..2ffe3823a 100644 --- a/README.rst +++ b/README.rst @@ -197,7 +197,7 @@ Docs - `Structure`_ - `Porting`_ -.. |Build Status| image:: https://github.com/hathach/tinyusb/actions/workflows/cmake_arm.yml/badge.svg +.. |Build Status| image:: https://github.com/hathach/tinyusb/actions/workflows/build.yml/badge.svg :target: https://github.com/hathach/tinyusb/actions .. |CircleCI Status| image:: https://dl.circleci.com/status-badge/img/circleci/4AYHvUhFxdnY4rA7LEsdqW/QmrpoL2AjGqetvFQNqtWyq/tree/master.svg?style=svg :target: https://dl.circleci.com/status-badge/redirect/circleci/4AYHvUhFxdnY4rA7LEsdqW/QmrpoL2AjGqetvFQNqtWyq/tree/master diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index b457fcfac..aa5e037d1 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -418,6 +418,12 @@ exit" COMMAND ${JLINKEXE} -device ${JLINK_DEVICE} ${OPTION_LIST} -if ${JLINK_IF} -JTAGConf -1,-1 -speed auto -CommandFile $/${TARGET}.jlink VERBATIM ) + + # optional flash post build +# add_custom_command(TARGET ${TARGET} POST_BUILD +# COMMAND ${JLINKEXE} -device ${JLINK_DEVICE} ${OPTION_LIST} -if ${JLINK_IF} -JTAGConf -1,-1 -speed auto -CommandFile $/${TARGET}.jlink +# VERBATIM +# ) endfunction() diff --git a/src/host/usbh.h b/src/host/usbh.h index 359684169..d0a5732e5 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -81,7 +81,7 @@ enum { }; typedef struct { - uint8_t max_nak; // max NAK per endpoint per frame + uint8_t max_nak; // max NAK per endpoint per frame to save CPU/SPI bus usage uint8_t cpuctl; // R16: CPU Control Register uint8_t pinctl; // R17: Pin Control Register. FDUPSPI bit is ignored } tuh_configure_max3421_t; diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 3d054b66e..215feb481 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -168,14 +168,14 @@ enum { }; enum { - MAX_NAK_DEFAULT = 1 // Number of NAK per endpoint per usb frame + MAX_NAK_DEFAULT = 1 // Number of NAK per endpoint per usb frame to save CPU/SPI bus usage }; enum { EP_STATE_IDLE = 0, EP_STATE_COMPLETE = 1, EP_STATE_ABORTING = 2, - EP_STATE_ATTEMPT_1 = 3, // pending 1st attempt + EP_STATE_ATTEMPT_1 = 3, // Number of attempts to transfer in a frame. Incremented after each NAK EP_STATE_ATTEMPT_MAX = 15 }; @@ -183,17 +183,20 @@ enum { // //--------------------------------------------------------------------+ +typedef struct TU_ATTR_PACKED { + uint8_t ep_num : 4; + uint8_t is_setup : 1; + uint8_t is_out : 1; + uint8_t is_iso : 1; +} hxfr_bm_t; + +TU_VERIFY_STATIC(sizeof(hxfr_bm_t) == 1, "size is not correct"); + typedef struct { uint8_t daddr; - union { ; - struct TU_ATTR_PACKED { - uint8_t ep_num : 4; - uint8_t is_setup : 1; - uint8_t is_out : 1; - uint8_t is_iso : 1; - }hxfr_bm; - + union { + hxfr_bm_t hxfr_bm; uint8_t hxfr; }; @@ -203,13 +206,12 @@ typedef struct { uint16_t packet_size : 11; }; - bool received_nak; uint16_t total_len; uint16_t xferred_len; uint8_t* buf; } max3421_ep_t; -TU_VERIFY_STATIC(sizeof(max3421_ep_t) == 16, "size is not correct"); +TU_VERIFY_STATIC(sizeof(max3421_ep_t) == 12, "size is not correct"); typedef struct { volatile uint16_t frame_count; @@ -220,7 +222,16 @@ typedef struct { uint8_t hien; uint8_t mode; uint8_t peraddr; - uint8_t hxfr; + union { + hxfr_bm_t hxfr_bm; + uint8_t hxfr; + }; + + // owner of data in SNDFIFO, for retrying NAKed without re-writing to FIFO + struct { + uint8_t daddr; + uint8_t hxfr; + }sndfifo_owner; atomic_flag busy; // busy transferring @@ -318,33 +329,9 @@ bool tuh_max3421_reg_write(uint8_t rhport, uint8_t reg, uint8_t data, bool in_is return ret; } -static void fifo_write(uint8_t rhport, uint8_t reg, uint8_t const * buffer, uint16_t len, bool in_isr) { - uint8_t hirq; - reg |= CMDBYTE_WRITE; - - max3421_spi_lock(rhport, in_isr); - - tuh_max3421_spi_xfer_api(rhport, ®, &hirq, 1); - _hcd_data.hirq = hirq; - tuh_max3421_spi_xfer_api(rhport, buffer, NULL, len); - - max3421_spi_unlock(rhport, in_isr); -} - -static void fifo_read(uint8_t rhport, uint8_t * buffer, uint16_t len, bool in_isr) { - uint8_t hirq; - uint8_t const reg = RCVVFIFO_ADDR; - - max3421_spi_lock(rhport, in_isr); - - tuh_max3421_spi_xfer_api(rhport, ®, &hirq, 1); - _hcd_data.hirq = hirq; - tuh_max3421_spi_xfer_api(rhport, NULL, buffer, len); - - max3421_spi_unlock(rhport, in_isr); -} - -//------------- register write helper -------------// +//-------------------------------------------------------------------- +// Register helper +//-------------------------------------------------------------------- TU_ATTR_ALWAYS_INLINE static inline void hirq_write(uint8_t rhport, uint8_t data, bool in_isr) { reg_write(rhport, HIRQ_ADDR, data, in_isr); // HIRQ write 1 is clear @@ -378,6 +365,47 @@ TU_ATTR_ALWAYS_INLINE static inline void sndbc_write(uint8_t rhport, uint8_t dat reg_write(rhport, SNDBC_ADDR, data, in_isr); } +//-------------------------------------------------------------------- +// FIFO access (receive, send, setup) +//-------------------------------------------------------------------- +static void hwfifo_write(uint8_t rhport, uint8_t reg, const uint8_t* buffer, uint8_t len, bool in_isr) { + uint8_t hirq; + reg |= CMDBYTE_WRITE; + + max3421_spi_lock(rhport, in_isr); + + tuh_max3421_spi_xfer_api(rhport, ®, &hirq, 1); + _hcd_data.hirq = hirq; + tuh_max3421_spi_xfer_api(rhport, buffer, NULL, len); + + max3421_spi_unlock(rhport, in_isr); +} + +// Write to SNDFIFO if len > 0 and update SNDBC +TU_ATTR_ALWAYS_INLINE static inline void hwfifo_send(uint8_t rhport, const uint8_t* buffer, uint8_t len, bool in_isr) { + if (len) { + hwfifo_write(rhport, SNDFIFO_ADDR, buffer, len, in_isr); + } + sndbc_write(rhport, len, in_isr); +} + +TU_ATTR_ALWAYS_INLINE static inline void hwfifo_setup(uint8_t rhport, const uint8_t* buffer, bool in_isr) { + hwfifo_write(rhport, SUDFIFO_ADDR, buffer, 8, in_isr); +} + +static void hwfifo_receive(uint8_t rhport, uint8_t * buffer, uint16_t len, bool in_isr) { + uint8_t hirq; + uint8_t const reg = RCVVFIFO_ADDR; + + max3421_spi_lock(rhport, in_isr); + + tuh_max3421_spi_xfer_api(rhport, ®, &hirq, 1); + _hcd_data.hirq = hirq; + tuh_max3421_spi_xfer_api(rhport, NULL, buffer, len); + + max3421_spi_unlock(rhport, in_isr); +} + //--------------------------------------------------------------------+ // Endpoint helper //--------------------------------------------------------------------+ @@ -418,7 +446,7 @@ static void free_ep(uint8_t daddr) { } } -// Check if endpoint has an queued transfer and not reach max NAK +// Check if endpoint has a queued transfer and not reach max NAK in this frame TU_ATTR_ALWAYS_INLINE static inline bool is_ep_pending(max3421_ep_t const * ep) { uint8_t const state = ep->state; return ep->packet_size && (state >= EP_STATE_ATTEMPT_1) && @@ -488,6 +516,7 @@ bool hcd_init(uint8_t rhport) { reg_write(rhport, PINCTL_ADDR, _tuh_cfg.pinctl | PINCTL_FDUPSPI, false); // v1 is 0x01, v2 is 0x12, v3 is 0x13 + // Note: v1 and v2 has host OUT errata whose workaround is not implemented in this driver uint8_t const revision = reg_read(rhport, REVISION_ADDR, false); TU_LOG2_HEX(revision); TU_ASSERT(revision == 0x01 || revision == 0x12 || revision == 0x13, false); @@ -616,27 +645,44 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t daddr, tusb_desc_endpoint_t const * e return true; } +/* The microcontroller repeatedly writes the SNDFIFO register R2 to load the FIFO with up to 64 data bytes. + * Then the microcontroller writes the SNDBC register, which this does three things: + * 1. Tells the MAX3421E SIE (Serial Interface Engine) how many bytes in the FIFO to send. + * 2. Connects the SNDFIFO and SNDBC register to the USB logic for USB transmission. + * 3. Clears the SNDBAVIRQ interrupt flag. If the second FIFO is available for µC loading, the SNDBAVIRQ immediately re-asserts. + + +-----------+ + --->| SNDBC-A | + / | SNDFIFO-A | + / +-----------+ + +------+ +-------------+ / +----------+ + | MCU |------>| R2: SNDFIFO |---- << Write R7 Flip >> ---| MAX3241E | + |(hcd) | | R7: SNDBC | / | SIE | + +------+ +-------------+ / +----------+ + +-----------+ / + | SNDBC-B | / + | SNDFIFO-B |<--- + +-----------+ + Note: xact_out() is called when starting a new transfer, continue a transfer (isr) or retry a transfer (NAK) + For NAK retry, we do not need to write to FIFO or SNDBC register again. +*/ static void xact_out(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_isr) { // Page 12: Programming BULK-OUT Transfers - // TODO double buffered + // TODO: double buffering for ISO transfer if (switch_ep) { peraddr_write(rhport, ep->daddr, in_isr); - - uint8_t const hctl = (ep->data_toggle ? HCTL_SNDTOG1 : HCTL_SNDTOG0); + const uint8_t hctl = (ep->data_toggle ? HCTL_SNDTOG1 : HCTL_SNDTOG0); reg_write(rhport, HCTL_ADDR, hctl, in_isr); } - if (!ep->received_nak){ - // do not write to fifo or sdnbc register again if previous attempt got NAK - uint8_t const xact_len = (uint8_t) tu_min16(ep->total_len - ep->xferred_len, ep->packet_size); - if (xact_len) { - // only check SNDBAV IRQ if there is data to send - TU_ASSERT(_hcd_data.hirq & HIRQ_SNDBAV_IRQ,); - fifo_write(rhport, SNDFIFO_ADDR, ep->buf, xact_len, in_isr); - } - - sndbc_write(rhport, xact_len, in_isr); + // Only write to sndfifo and sdnbc register if it is not a NAKed retry + if (!(ep->daddr == _hcd_data.sndfifo_owner.daddr && ep->hxfr == _hcd_data.sndfifo_owner.hxfr)) { + // skip SNDBAV IRQ check, overwrite sndfifo if needed + const uint8_t xact_len = (uint8_t) tu_min16(ep->total_len - ep->xferred_len, ep->packet_size); + hwfifo_send(rhport, ep->buf, xact_len, in_isr); } + _hcd_data.sndfifo_owner.daddr = ep->daddr; + _hcd_data.sndfifo_owner.hxfr = ep->hxfr; hxfr_write(rhport, ep->hxfr, in_isr); } @@ -655,7 +701,7 @@ static void xact_in(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool in_is static void xact_setup(uint8_t rhport, max3421_ep_t *ep, bool in_isr) { peraddr_write(rhport, ep->daddr, in_isr); - fifo_write(rhport, SUDFIFO_ADDR, ep->buf, 8, in_isr); + hwfifo_setup(rhport, ep->buf, in_isr); hxfr_write(rhport, HXFR_SETUP, in_isr); } @@ -669,7 +715,7 @@ static void xact_generic(uint8_t rhport, max3421_ep_t *ep, bool switch_ep, bool // status if (ep->buf == NULL || ep->total_len == 0) { - uint8_t const hxfr = (uint8_t) (HXFR_HS | (ep->hxfr & HXFR_OUT_NIN)); + const uint8_t hxfr = (uint8_t) (HXFR_HS | (ep->hxfr & HXFR_OUT_NIN)); peraddr_write(rhport, ep->daddr, in_isr); hxfr_write(rhport, hxfr, in_isr); return; @@ -830,11 +876,11 @@ static void xfer_complete_isr(uint8_t rhport, max3421_ep_t *ep, xfer_result_t re } static void handle_xfer_done(uint8_t rhport, bool in_isr) { - uint8_t const hrsl = reg_read(rhport, HRSL_ADDR, in_isr); - uint8_t const hresult = hrsl & HRSL_RESULT_MASK; - uint8_t const ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK; - uint8_t const hxfr_type = _hcd_data.hxfr & 0xf0; - uint8_t const ep_dir = ((hxfr_type & HXFR_SETUP) || (hxfr_type & HXFR_OUT_NIN)) ? 0 : 1; + const uint8_t hrsl = reg_read(rhport, HRSL_ADDR, in_isr); + const uint8_t hresult = hrsl & HRSL_RESULT_MASK; + const uint8_t ep_num = _hcd_data.hxfr_bm.ep_num; + const uint8_t hxfr_type = _hcd_data.hxfr & 0xf0; + const uint8_t ep_dir = ((hxfr_type & HXFR_SETUP) || (hxfr_type & HXFR_OUT_NIN)) ? 0 : 1; max3421_ep_t *ep = find_opened_ep(_hcd_data.peraddr, ep_num, ep_dir); TU_VERIFY(ep, ); @@ -849,9 +895,9 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { // control endpoint -> retry immediately and return hxfr_write(rhport, _hcd_data.hxfr, in_isr); return; - } else if (EP_STATE_ATTEMPT_1 <= ep->state && ep->state < EP_STATE_ATTEMPT_MAX) { + } + if (EP_STATE_ATTEMPT_1 <= ep->state && ep->state < EP_STATE_ATTEMPT_MAX) { ep->state++; - ep->received_nak = true; } } @@ -861,7 +907,6 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { hxfr_write(rhport, _hcd_data.hxfr, in_isr); } else if (next_ep) { // switch to next pending endpoint - // TODO could have issue with double buffered if not clear previously out data xact_generic(rhport, next_ep, true, in_isr); } else { // no more pending in this frame -> clear busy @@ -875,7 +920,6 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { case HRSL_SUCCESS: xfer_result = XFER_RESULT_SUCCESS; - ep->received_nak = false; break; case HRSL_STALL: @@ -905,11 +949,15 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { if (ep->state == EP_STATE_COMPLETE) { xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr); }else { - // more to transfer - hxfr_write(rhport, _hcd_data.hxfr, in_isr); + hxfr_write(rhport, _hcd_data.hxfr, in_isr); // more to transfer } } else { // SETUP or OUT transfer + + // clear sndfifo owner since data is sent + _hcd_data.sndfifo_owner.daddr = 0xff; + _hcd_data.sndfifo_owner.hxfr = 0xff; + uint8_t xact_len; if (hxfr_type & HXFR_SETUP) { @@ -926,8 +974,7 @@ static void handle_xfer_done(uint8_t rhport, bool in_isr) { if (xact_len < ep->packet_size || ep->xferred_len >= ep->total_len) { xfer_complete_isr(rhport, ep, xfer_result, hrsl, in_isr); } else { - // more to transfer - xact_out(rhport, ep, false, in_isr); + xact_out(rhport, ep, false, in_isr); // more to transfer } } } @@ -987,16 +1034,16 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { // not call this handler again. So we need to loop until all IRQ are cleared while (hirq & (HIRQ_RCVDAV_IRQ | HIRQ_HXFRDN_IRQ)) { if (hirq & HIRQ_RCVDAV_IRQ) { - uint8_t const ep_num = _hcd_data.hxfr & HXFR_EPNUM_MASK; + const uint8_t ep_num = _hcd_data.hxfr_bm.ep_num; max3421_ep_t* ep = find_opened_ep(_hcd_data.peraddr, ep_num, 1); uint8_t xact_len = 0; // RCVDAV_IRQ can trigger 2 times (dual buffered) while (hirq & HIRQ_RCVDAV_IRQ) { - uint8_t rcvbc = reg_read(rhport, RCVBC_ADDR, in_isr); + const uint8_t rcvbc = reg_read(rhport, RCVBC_ADDR, in_isr); xact_len = (uint8_t) tu_min16(rcvbc, ep->total_len - ep->xferred_len); if (xact_len) { - fifo_read(rhport, ep->buf, xact_len, in_isr); + hwfifo_receive(rhport, ep->buf, xact_len, in_isr); ep->buf += xact_len; ep->xferred_len += xact_len; } -- cgit v1.3.1 From 1d2c9f929dd3bfaf82741da30e8dbf97b0ff385c Mon Sep 17 00:00:00 2001 From: Reinhard Griech Date: Thu, 29 Aug 2024 15:31:29 +0200 Subject: change order, fixes #2778 --- src/portable/nordic/nrf5x/dcd_nrf5x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/portable') diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 1cc5c1836..a63e442f3 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -441,11 +441,11 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to bool const control_status = (epnum == 0 && total_bytes == 0 && dir != tu_edpt_dir(NRF_USBD->BMREQUESTTYPE)); if (control_status) { - // Status Phase also requires EasyDMA has to be available as well !!!! - edpt_dma_start(&NRF_USBD->TASKS_EP0STATUS); - // The nRF doesn't interrupt on status transmit so we queue up a success response. dcd_event_xfer_complete(0, ep_addr, 0, XFER_RESULT_SUCCESS, is_in_isr()); + + // Status Phase also requires EasyDMA has to be available as well !!!! + edpt_dma_start(&NRF_USBD->TASKS_EP0STATUS); } else if (dir == TUSB_DIR_OUT) { xfer->started = true; if (epnum == 0) { -- cgit v1.3.1 From 6890975f80bb541ba4f229cc1c3bc165745e21ac Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Thu, 29 Aug 2024 14:04:49 -0700 Subject: Fix ESP32-SX resume The interrupt handler pipes through the resume event but the interrupt wasn't enabled in the first place. --- src/portable/espressif/esp32sx/dcd_esp32sx.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/portable') diff --git a/src/portable/espressif/esp32sx/dcd_esp32sx.c b/src/portable/espressif/esp32sx/dcd_esp32sx.c index f912bef89..61911ab4c 100644 --- a/src/portable/espressif/esp32sx/dcd_esp32sx.c +++ b/src/portable/espressif/esp32sx/dcd_esp32sx.c @@ -207,6 +207,7 @@ void dcd_init(uint8_t rhport) USB_USBRSTMSK_M | USB_ENUMDONEMSK_M | USB_RESETDETMSK_M | + USB_WKUPINT_M | USB_DISCONNINTMSK_M; // host most only dcd_connect(rhport); -- cgit v1.3.1 From 0bb7b992d8383e30a84d0114537ce777fb9d678e Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 4 Sep 2024 20:56:04 +0700 Subject: dwc2: for esp32 force disconnect/connect using USB_WRAP otg pad override (DM=DP=0) in addition to dwc2's dctrl --- .github/actions/setup_toolchain/action.yml | 2 - .../actions/setup_toolchain/espressif/action.yml | 2 +- src/common/tusb_mcu.h | 1 + src/portable/synopsys/dwc2/dcd_dwc2.c | 24 +++++++++++- src/portable/synopsys/dwc2/dwc2_esp32.h | 44 +++++++++------------- 5 files changed, 43 insertions(+), 30 deletions(-) (limited to 'src/portable') diff --git a/.github/actions/setup_toolchain/action.yml b/.github/actions/setup_toolchain/action.yml index d173d6903..5b9bc95ce 100644 --- a/.github/actions/setup_toolchain/action.yml +++ b/.github/actions/setup_toolchain/action.yml @@ -39,8 +39,6 @@ runs: TOOLCHAIN_JSON='{ "aarch64-gcc": "https://developer.arm.com/-/media/Files/downloads/gnu-a/10.3-2021.07/binrel/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz", "arm-clang": "https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/download/release-17.0.1/LLVMEmbeddedToolchainForArm-17.0.1-Linux-x86_64.tar.xz", - "arm-iar": "", - "arm-gcc": "", "msp430-gcc": "http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSPGCC/9_2_0_0/export/msp430-gcc-9.2.0.50_linux64.tar.bz2", "riscv-gcc": "https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack/releases/download/v13.2.0-2/xpack-riscv-none-elf-gcc-13.2.0-2-linux-x64.tar.gz", "rx-gcc": "http://gcc-renesas.com/downloads/get.php?f=rx/8.3.0.202004-gnurx/gcc-8.3.0.202004-GNURX-ELF.run" diff --git a/.github/actions/setup_toolchain/espressif/action.yml b/.github/actions/setup_toolchain/espressif/action.yml index 3129329dd..1e3ce18f1 100644 --- a/.github/actions/setup_toolchain/espressif/action.yml +++ b/.github/actions/setup_toolchain/espressif/action.yml @@ -5,7 +5,7 @@ inputs: description: 'Toolchain name' required: true toolchain_version: - description: 'Toolchain URL or version' + description: 'Toolchain version' required: true runs: diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 52debf079..0a4462a0a 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -336,6 +336,7 @@ //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) #define TUP_USBIP_DWC2 + #define TUP_USBIP_DWC2_ESP32 #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_ESP32, OPT_MCU_ESP32C2, OPT_MCU_ESP32C3, OPT_MCU_ESP32C6, OPT_MCU_ESP32H2) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 9a38b46dc..daed76105 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -43,7 +43,7 @@ #if defined(TUP_USBIP_DWC2_STM32) #include "dwc2_stm32.h" -#elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#elif defined(TUP_USBIP_DWC2_ESP32) #include "dwc2_esp32.h" #elif TU_CHECK_MCU(OPT_MCU_GD32VF103) #include "dwc2_gd32.h" @@ -667,12 +667,34 @@ void dcd_remote_wakeup(uint8_t rhport) { void dcd_connect(uint8_t rhport) { (void) rhport; dwc2_regs_t* dwc2 = DWC2_REG(rhport); + +#ifdef TUP_USBIP_DWC2_ESP32 + usb_wrap_otg_conf_reg_t conf = USB_WRAP.otg_conf; + conf.pad_pull_override = 0; + conf.dp_pullup = 0; + conf.dp_pulldown = 0; + conf.dm_pullup = 0; + conf.dm_pulldown = 0; + USB_WRAP.otg_conf = conf; +#endif + dwc2->dctl &= ~DCTL_SDIS; } void dcd_disconnect(uint8_t rhport) { (void) rhport; dwc2_regs_t* dwc2 = DWC2_REG(rhport); + +#ifdef TUP_USBIP_DWC2_ESP32 + usb_wrap_otg_conf_reg_t conf = USB_WRAP.otg_conf; + conf.pad_pull_override = 1; + conf.dp_pullup = 0; + conf.dp_pulldown = 1; + conf.dm_pullup = 0; + conf.dm_pulldown = 1; + USB_WRAP.otg_conf = conf; +#endif + dwc2->dctl |= DCTL_SDIS; } diff --git a/src/portable/synopsys/dwc2/dwc2_esp32.h b/src/portable/synopsys/dwc2/dwc2_esp32.h index 932f52f40..1a938ea46 100644 --- a/src/portable/synopsys/dwc2/dwc2_esp32.h +++ b/src/portable/synopsys/dwc2/dwc2_esp32.h @@ -32,60 +32,52 @@ extern "C" { #endif +#include "freertos/task.h" + #include "esp_intr_alloc.h" #include "soc/periph_defs.h" -//#include "soc/usb_periph.h" -#include "freertos/task.h" +#include "soc/usb_wrap_struct.h" #define DWC2_REG_BASE 0x60080000UL #define DWC2_EP_MAX 6 // USB_OUT_EP_NUM. TODO ESP32Sx only has 5 tx fifo (5 endpoint IN) -static const dwc2_controller_t _dwc2_controller[] = -{ +static const dwc2_controller_t _dwc2_controller[] = { { .reg_base = DWC2_REG_BASE, .irqnum = 0, .ep_count = DWC2_EP_MAX, .ep_fifo_size = 1024 } }; static intr_handle_t usb_ih; -static void dcd_int_handler_wrap(void* arg) -{ - (void) arg; +static void dcd_int_handler_wrap(void* arg) { + (void)arg; dcd_int_handler(0); } -TU_ATTR_ALWAYS_INLINE -static inline void dwc2_dcd_int_enable (uint8_t rhport) -{ - (void) rhport; +TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_enable(uint8_t rhport) { + (void)rhport; esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, dcd_int_handler_wrap, NULL, &usb_ih); } -TU_ATTR_ALWAYS_INLINE -static inline void dwc2_dcd_int_disable (uint8_t rhport) -{ - (void) rhport; +TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_disable(uint8_t rhport) { + (void)rhport; esp_intr_free(usb_ih); } -static inline void dwc2_remote_wakeup_delay(void) -{ +TU_ATTR_ALWAYS_INLINE static inline void dwc2_remote_wakeup_delay(void) { vTaskDelay(pdMS_TO_TICKS(1)); } // MCU specific PHY init, called BEFORE core reset -static inline void dwc2_phy_init(dwc2_regs_t * dwc2, uint8_t hs_phy_type) -{ - (void) dwc2; - (void) hs_phy_type; +TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { + (void)dwc2; + (void)hs_phy_type; // nothing to do } // MCU specific PHY update, it is called AFTER init() and core reset -static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) -{ - (void) dwc2; - (void) hs_phy_type; +TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { + (void)dwc2; + (void)hs_phy_type; // nothing to do } @@ -94,4 +86,4 @@ static inline void dwc2_phy_update(dwc2_regs_t * dwc2, uint8_t hs_phy_type) } #endif -#endif /* _DWC2_ESP32_H_ */ +#endif -- cgit v1.3.1 From 616532892d913b7224806ed1e881b72ed66bb3e1 Mon Sep 17 00:00:00 2001 From: Shawn Hoffman Date: Tue, 17 Sep 2024 12:17:12 -0700 Subject: make all python files executable and standardize interpreter --- .github/workflows/ci_set_matrix.py | 1 + docs/conf.py | 1 + examples/device/audio_4_channel_mic/src/plot_audio_samples.py | 1 + examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py | 1 + examples/device/audio_test/src/plot_audio_samples.py | 1 + examples/device/audio_test_freertos/src/plot_audio_samples.py | 1 + examples/device/audio_test_multi_rate/src/plot_audio_samples.py | 1 + examples/device/hid_generic_inout/hid_test.py | 1 + examples/device/uac2_speaker_fb/src/audio_debug.py | 1 + examples/device/usbtmc/visaQuery.py | 0 hw/bsp/fomu/dfu.py | 2 +- hw/mcu/sony/cxd56/tools/flash_writer.py | 2 +- hw/mcu/sony/cxd56/tools/xmodem.py | 1 + src/portable/synopsys/dwc2/dwc2_info.py | 1 + test/hil/hil_test.py | 1 + test/unit-test/vendor/ceedling/vendor/unity/auto/unity_test_summary.py | 2 +- test/unit-test/vendor/ceedling/vendor/unity/auto/unity_to_junit.py | 1 + tools/build.py | 1 + tools/build_utils.py | 1 + tools/gen_doc.py | 1 + tools/get_deps.py | 1 + tools/iar_gen.py | 2 +- tools/make_release.py | 1 + tools/mksunxi.py | 0 tools/pcapng_to_corpus.py | 2 +- 25 files changed, 23 insertions(+), 5 deletions(-) mode change 100644 => 100755 .github/workflows/ci_set_matrix.py mode change 100644 => 100755 docs/conf.py mode change 100644 => 100755 examples/device/audio_4_channel_mic/src/plot_audio_samples.py mode change 100644 => 100755 examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py mode change 100644 => 100755 examples/device/audio_test/src/plot_audio_samples.py mode change 100644 => 100755 examples/device/audio_test_freertos/src/plot_audio_samples.py mode change 100644 => 100755 examples/device/audio_test_multi_rate/src/plot_audio_samples.py mode change 100644 => 100755 examples/device/hid_generic_inout/hid_test.py mode change 100644 => 100755 examples/device/uac2_speaker_fb/src/audio_debug.py mode change 100644 => 100755 examples/device/usbtmc/visaQuery.py mode change 100644 => 100755 hw/bsp/fomu/dfu.py mode change 100644 => 100755 hw/mcu/sony/cxd56/tools/xmodem.py mode change 100644 => 100755 src/portable/synopsys/dwc2/dwc2_info.py mode change 100644 => 100755 test/hil/hil_test.py mode change 100644 => 100755 test/unit-test/vendor/ceedling/vendor/unity/auto/unity_test_summary.py mode change 100644 => 100755 test/unit-test/vendor/ceedling/vendor/unity/auto/unity_to_junit.py mode change 100644 => 100755 tools/build.py mode change 100644 => 100755 tools/build_utils.py mode change 100644 => 100755 tools/gen_doc.py mode change 100644 => 100755 tools/get_deps.py mode change 100644 => 100755 tools/iar_gen.py mode change 100644 => 100755 tools/make_release.py mode change 100644 => 100755 tools/mksunxi.py (limited to 'src/portable') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py old mode 100644 new mode 100755 index 4da26bfea..fde6e81d6 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import json # toolchain, url diff --git a/docs/conf.py b/docs/conf.py old mode 100644 new mode 100755 index 878b29645..af44b7339 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # Configuration file for the Sphinx documentation builder. # # This file only contains a selection of the most common options. For a full diff --git a/examples/device/audio_4_channel_mic/src/plot_audio_samples.py b/examples/device/audio_4_channel_mic/src/plot_audio_samples.py old mode 100644 new mode 100755 index d17a908b6..4d61e7f5e --- a/examples/device/audio_4_channel_mic/src/plot_audio_samples.py +++ b/examples/device/audio_4_channel_mic/src/plot_audio_samples.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import sounddevice as sd import matplotlib.pyplot as plt import numpy as np diff --git a/examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py b/examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py old mode 100644 new mode 100755 index 8312b4e28..4d5ca28d6 --- a/examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py +++ b/examples/device/audio_4_channel_mic_freertos/src/plot_audio_samples.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import sounddevice as sd import matplotlib.pyplot as plt import numpy as np diff --git a/examples/device/audio_test/src/plot_audio_samples.py b/examples/device/audio_test/src/plot_audio_samples.py old mode 100644 new mode 100755 index 1504684a6..ea6aa661e --- a/examples/device/audio_test/src/plot_audio_samples.py +++ b/examples/device/audio_test/src/plot_audio_samples.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import sounddevice as sd import matplotlib.pyplot as plt import numpy as np diff --git a/examples/device/audio_test_freertos/src/plot_audio_samples.py b/examples/device/audio_test_freertos/src/plot_audio_samples.py old mode 100644 new mode 100755 index 304b2d5de..46738eb3f --- a/examples/device/audio_test_freertos/src/plot_audio_samples.py +++ b/examples/device/audio_test_freertos/src/plot_audio_samples.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import sounddevice as sd import matplotlib.pyplot as plt import numpy as np diff --git a/examples/device/audio_test_multi_rate/src/plot_audio_samples.py b/examples/device/audio_test_multi_rate/src/plot_audio_samples.py old mode 100644 new mode 100755 index c92e49957..1f33a003e --- a/examples/device/audio_test_multi_rate/src/plot_audio_samples.py +++ b/examples/device/audio_test_multi_rate/src/plot_audio_samples.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import sounddevice as sd import matplotlib.pyplot as plt import numpy as np diff --git a/examples/device/hid_generic_inout/hid_test.py b/examples/device/hid_generic_inout/hid_test.py old mode 100644 new mode 100755 index 5bdba9db0..3aaca9d2c --- a/examples/device/hid_generic_inout/hid_test.py +++ b/examples/device/hid_generic_inout/hid_test.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # Install python3 HID package https://pypi.org/project/hid/ import hid diff --git a/examples/device/uac2_speaker_fb/src/audio_debug.py b/examples/device/uac2_speaker_fb/src/audio_debug.py old mode 100644 new mode 100755 index 336c46c01..05b49baf6 --- a/examples/device/uac2_speaker_fb/src/audio_debug.py +++ b/examples/device/uac2_speaker_fb/src/audio_debug.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # Install python3 HID package https://pypi.org/project/hid/ # Install python3 matplotlib package https://pypi.org/project/matplotlib/ diff --git a/examples/device/usbtmc/visaQuery.py b/examples/device/usbtmc/visaQuery.py old mode 100644 new mode 100755 diff --git a/hw/bsp/fomu/dfu.py b/hw/bsp/fomu/dfu.py old mode 100644 new mode 100755 index 32479350c..8383852e3 --- a/hw/bsp/fomu/dfu.py +++ b/hw/bsp/fomu/dfu.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python3 # Written by Antonio Galea - 2010/11/18 # Updated for DFU 1.1 by Sean Cross - 2020/03/31 diff --git a/hw/mcu/sony/cxd56/tools/flash_writer.py b/hw/mcu/sony/cxd56/tools/flash_writer.py index bf630547a..387e679da 100755 --- a/hw/mcu/sony/cxd56/tools/flash_writer.py +++ b/hw/mcu/sony/cxd56/tools/flash_writer.py @@ -1,4 +1,4 @@ -#! /usr/bin/env python3 +#!/usr/bin/env python3 # Copyright (C) 2018 Sony Semiconductor Solutions Corp. # diff --git a/hw/mcu/sony/cxd56/tools/xmodem.py b/hw/mcu/sony/cxd56/tools/xmodem.py old mode 100644 new mode 100755 index 60fcc952c..3ee2698f7 --- a/hw/mcu/sony/cxd56/tools/xmodem.py +++ b/hw/mcu/sony/cxd56/tools/xmodem.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 ''' =============================== XMODEM file transfer protocol diff --git a/src/portable/synopsys/dwc2/dwc2_info.py b/src/portable/synopsys/dwc2/dwc2_info.py old mode 100644 new mode 100755 index 55bec3d23..9bbc18850 --- a/src/portable/synopsys/dwc2/dwc2_info.py +++ b/src/portable/synopsys/dwc2/dwc2_info.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import click import ctypes import pandas as pd diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py old mode 100644 new mode 100755 index a569e7666..b2e17c8e3 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 # # The MIT License (MIT) # diff --git a/test/unit-test/vendor/ceedling/vendor/unity/auto/unity_test_summary.py b/test/unit-test/vendor/ceedling/vendor/unity/auto/unity_test_summary.py old mode 100644 new mode 100755 index 00c0da8cc..a8e5b2726 --- a/test/unit-test/vendor/ceedling/vendor/unity/auto/unity_test_summary.py +++ b/test/unit-test/vendor/ceedling/vendor/unity/auto/unity_test_summary.py @@ -1,4 +1,4 @@ -#! python3 +#!/usr/bin/env python3 # ========================================== # Unity Project - A Test Framework for C # Copyright (c) 2015 Alexander Mueller / XelaRellum@web.de diff --git a/test/unit-test/vendor/ceedling/vendor/unity/auto/unity_to_junit.py b/test/unit-test/vendor/ceedling/vendor/unity/auto/unity_to_junit.py old mode 100644 new mode 100755 index 71dd56888..2379ad49a --- a/test/unit-test/vendor/ceedling/vendor/unity/auto/unity_to_junit.py +++ b/test/unit-test/vendor/ceedling/vendor/unity/auto/unity_to_junit.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import sys import os from glob import glob diff --git a/tools/build.py b/tools/build.py old mode 100644 new mode 100755 index f9ae68231..1f3a7e0af --- a/tools/build.py +++ b/tools/build.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import argparse import random import os diff --git a/tools/build_utils.py b/tools/build_utils.py old mode 100644 new mode 100755 index 5f88db8a2..357a95c93 --- a/tools/build_utils.py +++ b/tools/build_utils.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import subprocess import pathlib import time diff --git a/tools/gen_doc.py b/tools/gen_doc.py old mode 100644 new mode 100755 index 668c77ef6..c69f3ff29 --- a/tools/gen_doc.py +++ b/tools/gen_doc.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import pandas as pd from tabulate import tabulate from pathlib import Path diff --git a/tools/get_deps.py b/tools/get_deps.py old mode 100644 new mode 100755 index 06da54b41..84c6a9e61 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import argparse import sys import subprocess diff --git a/tools/iar_gen.py b/tools/iar_gen.py old mode 100644 new mode 100755 index ebcfa1423..8d45659db --- a/tools/iar_gen.py +++ b/tools/iar_gen.py @@ -1,4 +1,4 @@ -#!/usr/bin/python3 +#!/usr/bin/env python3 import os import sys diff --git a/tools/make_release.py b/tools/make_release.py old mode 100644 new mode 100755 index 3e653c12d..92c75baf9 --- a/tools/make_release.py +++ b/tools/make_release.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import re import gen_doc diff --git a/tools/mksunxi.py b/tools/mksunxi.py old mode 100644 new mode 100755 diff --git a/tools/pcapng_to_corpus.py b/tools/pcapng_to_corpus.py index 9c31365eb..3089f0bb6 100755 --- a/tools/pcapng_to_corpus.py +++ b/tools/pcapng_to_corpus.py @@ -1,4 +1,4 @@ -#!/bin/python3 +#!/usr/bin/env python3 import argparse import pcapng import zipfile -- cgit v1.3.1 From 86b4608365e66ba250cf4fb52226b0ed02488cc1 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 24 Sep 2024 17:38:31 +0700 Subject: update dfifo allocation scheme to use top pointer, update document and explanation for EPInfo address and GDFIFO. some function rename update h743 linker to use SRAM1 since USB DMA cannot access DTCM ram update xmc4500 to use uuid for testing --- hw/bsp/stm32h7/linker/stm32h743xx_flash.ld | 35 +-- hw/bsp/xmc4000/family.c | 6 + src/portable/synopsys/dwc2/dcd_dwc2.c | 361 ++++++++++++++--------------- src/portable/synopsys/dwc2/dwc2_type.h | 14 +- 4 files changed, 206 insertions(+), 210 deletions(-) (limited to 'src/portable') diff --git a/hw/bsp/stm32h7/linker/stm32h743xx_flash.ld b/hw/bsp/stm32h7/linker/stm32h743xx_flash.ld index 336afc01f..ba18c8cd1 100644 --- a/hw/bsp/stm32h7/linker/stm32h743xx_flash.ld +++ b/hw/bsp/stm32h7/linker/stm32h743xx_flash.ld @@ -32,23 +32,24 @@ /* Entry Point */ ENTRY(Reset_Handler) -/* Highest address of the user mode stack */ -_estack = 0x20020000; /* end of RAM */ -/* Generate a link error if heap and stack don't fit into RAM */ -_Min_Heap_Size = 0x200; /* required amount of heap */ -_Min_Stack_Size = 0x400; /* required amount of stack */ - /* Specify the memory areas */ MEMORY { -DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K -RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K -RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K -RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K -ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K -FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K + DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K + RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K + RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K + RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K + ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K + } +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM_D1) + LENGTH(RAM_D1); /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + /* Define output sections */ SECTIONS { @@ -127,7 +128,7 @@ SECTIONS . = ALIGN(4); _edata = .; /* define a global symbol at data end */ - } >DTCMRAM AT> FLASH + } >RAM_D1 AT> FLASH /* Uninitialized data section */ @@ -144,7 +145,9 @@ SECTIONS . = ALIGN(4); _ebss = .; /* define a global symbol at bss end */ __bss_end__ = _ebss; - } >DTCMRAM + } >RAM_D1 + + /* User_heap_stack section, used to check that there is enough RAM left */ ._user_heap_stack : @@ -155,9 +158,7 @@ SECTIONS . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(8); - } >DTCMRAM - - + } >RAM_D1 /* Remove information from the standard libraries */ /DISCARD/ : diff --git a/hw/bsp/xmc4000/family.c b/hw/bsp/xmc4000/family.c index 88810de7a..c776cb58a 100644 --- a/hw/bsp/xmc4000/family.c +++ b/hw/bsp/xmc4000/family.c @@ -103,6 +103,12 @@ uint32_t board_button_read(void) { return BUTTON_STATE_ACTIVE == XMC_GPIO_GetInput(BUTTON_PIN); } +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + uint8_t const len = tu_min8(16, max_len); + memcpy(id, g_chipid, len); + return len; +} + int board_uart_read(uint8_t* buf, int len) { #ifdef UART_DEV for(int i=0;igrxfsiz -static uint16_t _allocated_fifo_words_tx; // TX FIFO size in words (IN EPs) +static uint16_t ep0_pending[2]; // Index determines direction as tusb_dir_t type +static uint16_t _dfifo_top; // top free location in FIFO RAM // Number of IN endpoints active static uint8_t _allocated_ep_in_count; @@ -92,68 +90,125 @@ static uint8_t _allocated_ep_in_count; // SOF enabling flag - required for SOF to not get disabled in ISR when SOF was enabled by static bool _sof_en; -// Calculate the RX FIFO size according to minimum recommendations from reference manual -// RxFIFO = (5 * number of control endpoints + 8) + -// ((largest USB packet used / 4) + 1 for status information) + -// (2 * number of OUT endpoints) + 1 for Global NAK -// with number of control endpoints = 1 we have -// RxFIFO = 15 + (largest USB packet used / 4) + 2 * number of OUT endpoints -// we double the largest USB packet size to be able to hold up to 2 packets -static inline uint16_t calc_grxfsiz(uint16_t max_ep_size, uint8_t ep_count) { - return 15 + 2 * (max_ep_size / 4) + 2 * ep_count; +//-------------------------------------------------------------------- +// DMA +//-------------------------------------------------------------------- + +TU_ATTR_ALWAYS_INLINE static inline bool dma_enabled(const dwc2_regs_t* dwc2) { + (void) dwc2; + // DMA doesn't support fifo transfer +#ifdef TUD_AUDIO_PREFER_RING_BUFFER +#if TUD_AUDIO_PREFER_RING_BUFFER + return false; +#endif +#endif + // Internal DMA only + return (dwc2->ghwcfg2_bm.arch == GHWCFG2_ARCH_INTERNAL_DMA); + // return false; +} + +TU_ATTR_ALWAYS_INLINE static inline uint16_t dma_cal_epfifo_base(uint8_t rhport) { + // Scatter/Gather DMA mode is not yet supported. Buffer DMA only need 1 words per endpoint direction + const dwc2_controller_t* dwc2_controller = &_dwc2_controller[rhport]; + return dwc2_controller->ep_fifo_size/4 - 2*dwc2_controller->ep_count; } -TU_ATTR_ALWAYS_INLINE static inline void fifo_flush_tx(dwc2_regs_t* dwc2, uint8_t epnum) { +static void dma_setup_prepare(uint8_t rhport) { + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + + if (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a) { + if(dwc2->epout[0].doepctl & DOEPCTL_EPENA) { + return; + } + } + + // Receive only 1 packet + dwc2->epout[0].doeptsiz = (1 << DOEPTSIZ_STUPCNT_Pos) | (1 << DOEPTSIZ_PKTCNT_Pos) | (8 << DOEPTSIZ_XFRSIZ_Pos); + dwc2->epout[0].doepdma = (uintptr_t)_setup_packet; + dwc2->epout[0].doepctl |= DOEPCTL_EPENA | DOEPCTL_USBAEP; +} + +//--------------------------------------------------------------------+ +// Data FIFO +//--------------------------------------------------------------------+ + +TU_ATTR_ALWAYS_INLINE static inline void dfifo_flush_tx(dwc2_regs_t* dwc2, uint8_t epnum) { // flush TX fifo and wait for it cleared dwc2->grstctl = GRSTCTL_TXFFLSH | (epnum << GRSTCTL_TXFNUM_Pos); while (dwc2->grstctl & GRSTCTL_TXFFLSH_Msk) {} } -TU_ATTR_ALWAYS_INLINE static inline void fifo_flush_rx(dwc2_regs_t* dwc2) { +TU_ATTR_ALWAYS_INLINE static inline void dfifo_flush_rx(dwc2_regs_t* dwc2) { // flush RX fifo and wait for it cleared dwc2->grstctl = GRSTCTL_RXFFLSH; while (dwc2->grstctl & GRSTCTL_RXFFLSH_Msk) {} } -static bool fifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) { +/* USB Data FIFO Layout + + The FIFO is split up into + - EPInfo: for storing DMA metadata, only required when use DMA. Maximum size is called + EP_LOC_CNT = ep_fifo_size - ghwcfg3.dfifo_depth. For value less than EP_LOC_CNT, gdfifocfg must be configured before + gahbcfg.dmaen is set + - Buffer mode: 1 word per endpoint direction + - Scatter/Gather DMA: 4 words per endpoint direction + - TX FIFO: one fifo for each IN endpoint. Size is dynamic depending on packet size, starting from top with EP0 IN. + - Shared RX FIFO: a shared fifo for all OUT endpoints. Typically, can hold up to 2 packets of the largest EP size. + + We allocated TX FIFO from top to bottom (using top pointer), this to allow the RX FIFO to grow dynamically which is + possible since the free space is located between the RX and TX FIFOs. + + ---------------- ep_fifo_size + | EPInfo | + | for DMA | + |-------------|-- gdfifocfg.EPINFOBASE (max is ghwcfg3.dfifo_depth) + | IN FIFO 0 | + | control | + |-------------| + | IN FIFO 1 | + |-------------| + | . . . . | + |-------------| + | IN FIFO n | + |-------------| + | FREE | + |-------------|-- GRXFSIZ (expandable) + | OUT FIFO | + | ( Shared ) | + --------------- 0 + + According to "FIFO RAM allocation" section in RM, FIFO RAM are allocated as follows (each word 32-bits): + - Each EP IN needs at least max packet size + - All EP OUT shared a unique OUT FIFO which uses (for Slave or Buffer DMA, Scatt/Gather DMA use different formula): + - 13 for setup packets + control words (up to 3 setup packets). + - 1 for global NAK (not required/used here). + - Largest-EPsize / 4 + 1. ( FS: 64 bytes, HS: 512 bytes). Recommended is "2 x (Largest-EPsize/4) + 1" + - 2 for each used OUT endpoint + + Therefore GRXFSIZ = 13 + 1 + 2 x (Largest-EPsize/4 + 1) + 2 x EPOUTnum +*/ + +TU_ATTR_ALWAYS_INLINE static inline uint16_t calc_grxfsiz(uint16_t largest_ep_size, uint8_t ep_count) { + return 13 + 1 + 2 * ((largest_ep_size / 4) + 1) + 2 * ep_count; +} + +static bool dfifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); - uint8_t const ep_count = _dwc2_controller[rhport].ep_count; + const dwc2_controller_t* dwc2_controller = &_dwc2_controller[rhport]; + uint8_t const ep_count = dwc2_controller->ep_count; uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); TU_ASSERT(epnum < ep_count); uint16_t fifo_size = tu_div_ceil(packet_size, 4); - - // "USB Data FIFOs" section in reference manual - // Peripheral FIFO architecture - // - // --------------- 320 or 1024 ( 1280 or 4096 bytes ) - // | IN FIFO 0 | - // --------------- (320 or 1024) - 16 - // | IN FIFO 1 | - // --------------- (320 or 1024) - 16 - x - // | . . . . | - // --------------- (320 or 1024) - 16 - x - y - ... - z - // | IN FIFO MAX | - // --------------- - // | FREE | - // --------------- GRXFSIZ - // | OUT FIFO | - // | ( Shared ) | - // --------------- 0 - // - // In FIFO is allocated by following rules: - // - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n". if (dir == TUSB_DIR_OUT) { // Calculate required size of RX FIFO - uint16_t const sz = calc_grxfsiz(4 * fifo_size, ep_count); + uint16_t const new_sz = calc_grxfsiz(4 * fifo_size, ep_count); - // If size_rx needs to be extended check if possible and if so enlarge it - if (dwc2->grxfsiz < sz) { - TU_ASSERT(sz + _allocated_fifo_words_tx <= _dwc2_controller[rhport].ep_fifo_size / 4); - - // Enlarge RX FIFO - dwc2->grxfsiz = sz; + // If size_rx needs to be extended check if there is enough free space + if (dwc2->grxfsiz < new_sz) { + TU_ASSERT(new_sz <= _dfifo_top); + dwc2->grxfsiz = new_sz; // Enlarge RX FIFO } } else { // Check IN endpoints concurrently active limit @@ -162,59 +217,48 @@ static bool fifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) { _allocated_ep_in_count++; } - // Note if The TXFELVL is configured as half empty. In order - // to be able to write a packet at that point, the fifo must be twice the max_size. + // If The TXFELVL is configured as half empty, the fifo must be twice the max_size. if ((dwc2->gahbcfg & GAHBCFG_TXFELVL) == 0) { fifo_size *= 2; } // Check if free space is available - TU_ASSERT(_allocated_fifo_words_tx + fifo_size + dwc2->grxfsiz <= _dwc2_controller[rhport].ep_fifo_size / 4); - _allocated_fifo_words_tx += fifo_size; - TU_LOG(DWC2_DEBUG, " Allocated %u bytes at offset %" PRIu32, fifo_size * 4, - _dwc2_controller[rhport].ep_fifo_size - _allocated_fifo_words_tx * 4); + TU_ASSERT(_dfifo_top >= fifo_size + dwc2->grxfsiz); + _dfifo_top -= fifo_size; + TU_LOG(DWC2_DEBUG, " TX FIFO %u: allocated %u words at offset %u\r\n", epnum, fifo_size, _dfifo_top); - // DIEPTXF starts at FIFO #1. // Both TXFD and TXSA are in unit of 32-bit words. - dwc2->dieptxf[epnum - 1] = (fifo_size << DIEPTXF_INEPTXFD_Pos) | - (_dwc2_controller[rhport].ep_fifo_size / 4 - _allocated_fifo_words_tx); + if (epnum == 0) { + dwc2->dieptxf0 = (fifo_size << DIEPTXF0_TX0FD_Pos) | _dfifo_top; + } else { + // DIEPTXF starts at FIFO #1. + dwc2->dieptxf[epnum - 1] = (fifo_size << DIEPTXF_INEPTXFD_Pos) | _dfifo_top; + } } return true; } -static inline bool dma_enabled(uint8_t rhport) -{ - // DMA doesn't support fifo transfer -#ifdef TUD_AUDIO_PREFER_RING_BUFFER -#if TUD_AUDIO_PREFER_RING_BUFFER - return false; -#endif -#endif - dwc2_regs_t* dwc2 = DWC2_REG(rhport); - // Internal DMA only - return (dwc2->ghwcfg2_bm.arch == 2); -} - -static void dma_stpkt_rx(uint8_t rhport) -{ +static void dfifo_init(uint8_t rhport) { + const dwc2_controller_t* dwc2_controller = &_dwc2_controller[rhport]; dwc2_regs_t* dwc2 = DWC2_REG(rhport); + dwc2->grxfsiz = calc_grxfsiz(CFG_TUD_ENDPOINT0_SIZE, dwc2_controller->ep_count); - if (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a) { - if(dwc2->epout[0].doepctl & DOEPCTL_EPENA) - return; + if(dma_enabled(dwc2)) { + // DMA use last DFIFO to store metadata + _dfifo_top = dma_cal_epfifo_base(rhport); + }else { + _dfifo_top = dwc2_controller->ep_fifo_size / 4; } - // Receive only 1 packet - dwc2->epout[0].doeptsiz = 0; - dwc2->epout[0].doeptsiz |= (1 << DOEPTSIZ_STUPCNT_Pos); - dwc2->epout[0].doeptsiz |= 8; - dwc2->epout[0].doeptsiz |= (1 << DOEPTSIZ_PKTCNT_Pos); - dwc2->epout[0].doepdma = (uintptr_t)_setup_packet; - - dwc2->epout[0].doepctl |= DOEPCTL_EPENA | DOEPCTL_USBAEP; + // Allocate FIFO for EP0 IN + dfifo_alloc(rhport, 0x80, CFG_TUD_ENDPOINT0_SIZE); } +//-------------------------------------------------------------------- +// Endpoint +//-------------------------------------------------------------------- + static void edpt_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); @@ -235,7 +279,7 @@ static void edpt_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoin dwc2->daintmsk |= TU_BIT(DAINTMSK_OEPM_Pos + epnum); } else { dwc2->epin[epnum].diepctl = dxepctl | (epnum << DIEPCTL_TXFNUM_Pos); - dwc2->daintmsk |= (1 << (DAINTMSK_IEPM_Pos + epnum)); + dwc2->daintmsk |= TU_BIT(DAINTMSK_IEPM_Pos + epnum); } } @@ -265,7 +309,7 @@ static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) { } // Flush the FIFO, and wait until we have confirmed it cleared. - fifo_flush_tx(dwc2, epnum); + dfifo_flush_tx(dwc2, epnum); } else { dwc2_epout_t* epout = dwc2->epout; @@ -318,88 +362,27 @@ static void bus_reset(uint8_t rhport) { } } - fifo_flush_tx(dwc2, 0x10); // all tx fifo - fifo_flush_rx(dwc2); + dfifo_flush_tx(dwc2, 0x10); // all tx fifo + dfifo_flush_rx(dwc2); // 3. Set up interrupt mask dwc2->daintmsk = TU_BIT(DAINTMSK_OEPM_Pos) | TU_BIT(DAINTMSK_IEPM_Pos); dwc2->doepmsk = DOEPMSK_STUPM | DOEPMSK_XFRCM; dwc2->diepmsk = DIEPMSK_TOM | DIEPMSK_XFRCM; - // "USB Data FIFOs" section in reference manual - // Peripheral FIFO architecture - // - // The FIFO is split up in a lower part where the RX FIFO is located and an upper part where the TX FIFOs start. - // We do this to allow the RX FIFO to grow dynamically which is possible since the free space is located - // between the RX and TX FIFOs. This is required by ISO OUT EPs which need a bigger FIFO than the standard - // configuration done below. - // - // Dynamically FIFO sizes are of interest only for ISO EPs since all others are usually not opened and closed. - // All EPs other than ISO are opened as soon as the driver starts up i.e. when the host sends a - // configure interface command. Hence, all IN EPs other the ISO will be located at the top. IN ISO EPs are usually - // opened when the host sends an additional command: setInterface. At this point in time - // the ISO EP will be located next to the free space and can change its size. In case more IN EPs change its size - // an additional memory - // - // --------------- 320 or 1024 ( 1280 or 4096 bytes ) - // | IN FIFO 0 | - // --------------- (320 or 1024) - 16 - // | IN FIFO 1 | - // --------------- (320 or 1024) - 16 - x - // | . . . . | - // --------------- (320 or 1024) - 16 - x - y - ... - z - // | IN FIFO MAX | - // --------------- - // | FREE | - // --------------- GRXFSIZ - // | OUT FIFO | - // | ( Shared ) | - // --------------- 0 - // - // According to "FIFO RAM allocation" section in RM, FIFO RAM are allocated as follows (each word 32-bits): - // - Each EP IN needs at least max packet size, 16 words is sufficient for EP0 IN - // - // - All EP OUT shared a unique OUT FIFO which uses - // - 13 for setup packets + control words (up to 3 setup packets). - // - 1 for global NAK (not required/used here). - // - Largest-EPsize / 4 + 1. ( FS: 64 bytes, HS: 512 bytes). Recommended is "2 x (Largest-EPsize/4) + 1" - // - 2 for each used OUT endpoint - // - // Therefore GRXFSIZ = 13 + 1 + 1 + 2 x (Largest-EPsize/4) + 2 x EPOUTnum - // - FullSpeed (64 Bytes ): GRXFSIZ = 15 + 2 x 16 + 2 x ep_count = 47 + 2 x ep_count - // - Highspeed (512 bytes): GRXFSIZ = 15 + 2 x 128 + 2 x ep_count = 271 + 2 x ep_count - // - // NOTE: Largest-EPsize & EPOUTnum is actual used endpoints in configuration. Since DCD has no knowledge - // of the overall picture yet. We will use the worst scenario: largest possible + ep_count - // - // For Isochronous, largest EP size can be 1023/1024 for FS/HS respectively. In addition if multiple ISO - // are enabled at least "2 x (Largest-EPsize/4) + 1" are recommended. Maybe provide a macro for application to - // overwrite this. - - // EP0 out max is 64 - dwc2->grxfsiz = calc_grxfsiz(64, ep_count); - - // Setup the control endpoint 0 - _allocated_fifo_words_tx = 16; - - // DMA needs extra space for processing - if(dma_enabled(rhport)) { - uint16_t reserved = _dwc2_controller[rhport].ep_fifo_size / 4- dwc2->ghwcfg3_bm.total_fifo_size; - _allocated_fifo_words_tx += reserved; - } - - // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word ) - dwc2->dieptxf0 = (16 << DIEPTXF0_TX0FD_Pos) | (_dwc2_controller[rhport].ep_fifo_size / 4 - _allocated_fifo_words_tx); + dfifo_init(rhport); // Fixed control EP0 size to 64 bytes dwc2->epin[0].diepctl &= ~(0x03 << DIEPCTL_MPSIZ_Pos); + dwc2->epout[0].doepctl &= ~(0x03 << DOEPCTL_MPSIZ_Pos); + xfer_status[0][TUSB_DIR_OUT].max_size = 64; xfer_status[0][TUSB_DIR_IN].max_size = 64; - dwc2->epout[0].doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos); - - if(dma_enabled(rhport)) { - dma_stpkt_rx(rhport); + if(dma_enabled(dwc2)) { + dma_setup_prepare(rhport); + } else { + dwc2->epout[0].doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos); } dwc2->gintmsk |= GINTMSK_OEPINT | GINTMSK_IEPINT; @@ -427,7 +410,7 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c epin[epnum].dieptsiz = (num_packets << DIEPTSIZ_PKTCNT_Pos) | ((total_bytes << DIEPTSIZ_XFRSIZ_Pos) & DIEPTSIZ_XFRSIZ_Msk); - if(dma_enabled(rhport)) { + if(dma_enabled(dwc2)) { epin[epnum].diepdma = (uintptr_t)xfer->buffer; // For ISO endpoint set correct odd/even bit for next frame. @@ -468,7 +451,7 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c epout[epnum].doepctl |= (odd_frame_now ? DOEPCTL_SD0PID_SEVNFRM_Msk : DOEPCTL_SODDFRM_Msk); } - if(dma_enabled(rhport)) { + if(dma_enabled(dwc2)) { epout[epnum].doepdma = (uintptr_t)xfer->buffer; } @@ -599,7 +582,9 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { // XCVRDLY: transceiver delay between xcvr_sel and txvalid during device chirp is required // when using with some PHYs such as USB334x (USB3341, USB3343, USB3346, USB3347) - if (dwc2->ghwcfg2_bm.hs_phy_type == HS_PHY_TYPE_ULPI) dcfg |= DCFG_XCVRDLY; + if (dwc2->ghwcfg2_bm.hs_phy_type == HS_PHY_TYPE_ULPI) { + dcfg |= DCFG_XCVRDLY; + } dwc2->dcfg = dcfg; } @@ -625,12 +610,9 @@ void dcd_init(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); // Check Synopsys ID register, failed if controller clock/power is not enabled - if (!check_dwc2(dwc2)) return; + TU_ASSERT(check_dwc2(dwc2), ); dcd_disconnect(rhport); - // max number of endpoints & total_fifo_size are: - // hw_cfg2->num_dev_ep, hw_cfg2->total_fifo_size - if (phy_hs_supported(dwc2)) { phy_hs_init(dwc2); // Highspeed } else { @@ -660,8 +642,8 @@ void dcd_init(uint8_t rhport) { // (non zero-length packet), send STALL back and discard. dwc2->dcfg |= DCFG_NZLSOHSK; - fifo_flush_tx(dwc2, 0x10); // all tx fifo - fifo_flush_rx(dwc2); + dfifo_flush_tx(dwc2, 0x10); // all tx fifo + dfifo_flush_rx(dwc2); // Clear all interrupts uint32_t int_mask = dwc2->gintsts; @@ -670,20 +652,24 @@ void dcd_init(uint8_t rhport) { dwc2->gotgint |= int_mask; // Required as part of core initialization. - dwc2->gintmsk = GINTMSK_OTGINT | GINTMSK_RXFLVLM | - GINTMSK_USBSUSPM | GINTMSK_USBRST | GINTMSK_ENUMDNEM | GINTMSK_WUIM; + dwc2->gintmsk = GINTMSK_OTGINT | GINTMSK_USBSUSPM | GINTMSK_USBRST | GINTMSK_ENUMDNEM | GINTMSK_WUIM; // Configure TX FIFO empty level for interrupt. Default is complete empty dwc2->gahbcfg |= GAHBCFG_TXFELVL; - // Enable global interrupt - dwc2->gahbcfg |= GAHBCFG_GINT; + if (dma_enabled(dwc2)) { + const uint16_t epinfo_base = dma_cal_epfifo_base(rhport); + dwc2->gdfifocfg = (epinfo_base << GDFIFOCFG_EPINFOBASE_SHIFT) | epinfo_base; - if (dma_enabled(rhport)) { + // DMA seems to be only settable after a core reset dwc2->gahbcfg |= GAHBCFG_DMAEN | GAHBCFG_HBSTLEN_2; - dwc2->gintmsk &=~GINTMSK_RXFLVLM; + }else { + dwc2->gintmsk |= GINTMSK_RXFLVLM; } + // Enable global interrupt + dwc2->gahbcfg |= GAHBCFG_GINT; + // make sure we are in device mode // TU_ASSERT(!(dwc2->gintsts & GINTSTS_CMOD), ); @@ -783,7 +769,7 @@ void dcd_sof_enable(uint8_t rhport, bool en) { *------------------------------------------------------------------*/ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const* desc_edpt) { - TU_ASSERT(fifo_alloc(rhport, desc_edpt->bEndpointAddress, tu_edpt_packet_size(desc_edpt))); + TU_ASSERT(dfifo_alloc(rhport, desc_edpt->bEndpointAddress, tu_edpt_packet_size(desc_edpt))); edpt_activate(rhport, desc_edpt); return true; } @@ -812,32 +798,21 @@ void dcd_edpt_close_all(uint8_t rhport) { xfer_status[n][TUSB_DIR_IN].max_size = 0; } - // reset allocated fifo OUT - dwc2->grxfsiz = calc_grxfsiz(64, ep_count); - // reset allocated fifo IN - _allocated_fifo_words_tx = 16; - - fifo_flush_tx(dwc2, 0x10); // all tx fifo - fifo_flush_rx(dwc2); + dfifo_flush_tx(dwc2, 0x10); // all tx fifo + dfifo_flush_rx(dwc2); - // DMA needs extra space for processing - if(dma_enabled(rhport)) { - uint16_t reserved = _dwc2_controller[rhport].ep_fifo_size / 4- dwc2->ghwcfg3_bm.total_fifo_size; - _allocated_fifo_words_tx += reserved; - } + dfifo_init(rhport); // re-init dfifo } bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { - TU_ASSERT(fifo_alloc(rhport, ep_addr, largest_packet_size)); + TU_ASSERT(dfifo_alloc(rhport, ep_addr, largest_packet_size)); return true; } bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) { // Disable EP to clear potential incomplete transfers edpt_disable(rhport, p_endpoint_desc->bEndpointAddress, false); - edpt_activate(rhport, p_endpoint_desc); - return true; } @@ -904,8 +879,8 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { edpt_disable(rhport, ep_addr, true); - if((tu_edpt_number(ep_addr) == 0) && dma_enabled(rhport)) { - dma_stpkt_rx(rhport); + if((tu_edpt_number(ep_addr) == 0) && dma_enabled(DWC2_REG(rhport))) { + dma_setup_prepare(rhport); } } @@ -1075,13 +1050,15 @@ static void handle_epout_irq(uint8_t rhport) { uint32_t const doepint = epout->doepint; + TU_ASSERT((epout->doepint & DOEPINT_AHBERR) == 0, ); + // OUT XFER complete if (epout->doepint & DOEPINT_XFRC) { epout->doepint = DOEPINT_XFRC; xfer_ctl_t* xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT); - if(dma_enabled(rhport)) { + if(dma_enabled(dwc2)) { if (doepint & DOEPINT_STUP) { // STPKTRX is only available for version from 3_00a if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { @@ -1103,7 +1080,7 @@ static void handle_epout_irq(uint8_t rhport) { xfer->total_len -= remain; // this is ZLP, so prepare EP0 for next setup if(n == 0 && xfer->total_len == 0) { - dma_stpkt_rx(rhport); + dma_setup_prepare(rhport); } dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); @@ -1135,8 +1112,8 @@ static void handle_epout_irq(uint8_t rhport) { if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { epout->doepint = DOEPINT_STPKTRX; } - if(dma_enabled(rhport) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { - dma_stpkt_rx(rhport); + if(dma_enabled(dwc2) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { + dma_setup_prepare(rhport); } dcd_event_setup_received(rhport, (uint8_t*) _setup_packet, true); @@ -1165,8 +1142,8 @@ static void handle_epin_irq(uint8_t rhport) { // Schedule another packet to be transmitted. edpt_schedule_packets(rhport, n, TUSB_DIR_IN, 1, ep0_pending[TUSB_DIR_IN]); } else { - if((n == 0) && dma_enabled(rhport)) { - dma_stpkt_rx(rhport); + if((n == 0) && dma_enabled(dwc2)) { + dma_setup_prepare(rhport); } dcd_event_xfer_complete(rhport, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); } diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index 244323b51..c21bf9e94 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -100,6 +100,12 @@ enum { FS_PHY_TYPE_ULPI, }; +enum { + GHWCFG2_ARCH_SLAVE_ONLY = 0, + GHWCFG2_ARCH_EXTERNAL_DMA, // 1 + GHWCFG2_ARCH_INTERNAL_DMA, // 2 +}; + typedef struct TU_ATTR_PACKED { uint32_t op_mode : 3; // 0: HNP and SRP | 1: SRP | 2: non-HNP, non-SRP @@ -134,7 +140,7 @@ typedef struct TU_ATTR_PACKED uint32_t otg_enable_hsic : 1; // 1: HSIC-capable with shared UTMI PHY interface | 0: non-HSIC uint32_t battery_charger_support : 1; // support battery charger uint32_t lpm_mode : 1; // LPC mode - uint32_t total_fifo_size : 16; // DFIFO depth value in terms of 32-bit words + uint32_t dfifo_depth : 16; // DFIFO depth - EP_LOC_CNT in terms of 32-bit words }dwc2_ghwcfg3_t; TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg3_t) == 4, "incorrect size"); @@ -1240,6 +1246,12 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define GLPMCFG_ENBESL_Msk (0x1UL << GLPMCFG_ENBESL_Pos) // 0x10000000 #define GLPMCFG_ENBESL GLPMCFG_ENBESL_Msk // Enable best effort service latency +// GDFIFOCFG +#define GDFIFOCFG_EPINFOBASE_MASK (0xffff << 16) +#define GDFIFOCFG_EPINFOBASE_SHIFT 16 +#define GDFIFOCFG_GDFIFOCFG_MASK (0xffff << 0) +#define GDFIFOCFG_GDFIFOCFG_SHIFT 0 + /******************** Bit definition for DIEPEACHMSK1 register ********************/ #define DIEPEACHMSK1_XFRCM_Pos (0U) #define DIEPEACHMSK1_XFRCM_Msk (0x1UL << DIEPEACHMSK1_XFRCM_Pos) // 0x00000001 -- cgit v1.3.1 From a1244381b3e68959f99bc0ba8057eea5ca35bac6 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 24 Sep 2024 17:55:15 +0700 Subject: add CFG_TUD_DWC2_DMA, make it compile time option --- src/common/tusb_mcu.h | 2 +- src/portable/synopsys/dwc2/dcd_dwc2.c | 9 +++----- src/tusb_option.h | 39 +++++++++++++++++++++-------------- 3 files changed, 28 insertions(+), 22 deletions(-) (limited to 'src/portable') diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 0a4462a0a..6ead1ea0b 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -524,7 +524,7 @@ #define TUP_DCD_EDPT_ISO_ALLOC #endif -#if defined(TUP_USBIP_DWC2) +#if defined(TUP_USBIP_DWC2) // && CFG_TUD_DWC2_DMA == 0 #define TUP_MEM_CONST_ADDR #endif diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 897f81a42..2c5e82778 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -95,16 +95,13 @@ static bool _sof_en; //-------------------------------------------------------------------- TU_ATTR_ALWAYS_INLINE static inline bool dma_enabled(const dwc2_regs_t* dwc2) { + #if !CFG_TUD_DWC2_DMA (void) dwc2; - // DMA doesn't support fifo transfer -#ifdef TUD_AUDIO_PREFER_RING_BUFFER -#if TUD_AUDIO_PREFER_RING_BUFFER return false; -#endif -#endif + #else // Internal DMA only return (dwc2->ghwcfg2_bm.arch == GHWCFG2_ARCH_INTERNAL_DMA); - // return false; + #endif } TU_ATTR_ALWAYS_INLINE static inline uint16_t dma_cal_epfifo_base(uint8_t rhport) { diff --git a/src/tusb_option.h b/src/tusb_option.h index fb0209023..e61b3bb9e 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -228,7 +228,7 @@ #define OPT_MODE_SPEED_MASK 0xff00 //--------------------------------------------------------------------+ -// Include tusb_config.h and tusb_mcu.h +// Include tusb_config.h //--------------------------------------------------------------------+ // Allow to use command line to change the config name/location @@ -238,6 +238,29 @@ #include "tusb_config.h" #endif +//--------------------------------------------------------------------+ +// USBIP +//--------------------------------------------------------------------+ + +// DWC2 controller: use DMA for data transfer +#ifndef CFG_TUD_DWC2_DMA + #define CFG_TUD_DWC2_DMA 1 +#endif + +// Enable PIO-USB software host controller +#ifndef CFG_TUH_RPI_PIO_USB + #define CFG_TUH_RPI_PIO_USB 0 +#endif + +#ifndef CFG_TUD_RPI_PIO_USB + #define CFG_TUD_RPI_PIO_USB 0 +#endif + +// MAX3421 Host controller option +#ifndef CFG_TUH_MAX3421 + #define CFG_TUH_MAX3421 0 +#endif + #include "common/tusb_mcu.h" //-------------------------------------------------------------------- @@ -548,20 +571,6 @@ #define CFG_TUH_API_EDPT_XFER 0 #endif -// Enable PIO-USB software host controller -#ifndef CFG_TUH_RPI_PIO_USB - #define CFG_TUH_RPI_PIO_USB 0 -#endif - -#ifndef CFG_TUD_RPI_PIO_USB - #define CFG_TUD_RPI_PIO_USB 0 -#endif - -// MAX3421 Host controller option -#ifndef CFG_TUH_MAX3421 - #define CFG_TUH_MAX3421 0 -#endif - //--------------------------------------------------------------------+ // TypeC Options (Default) //--------------------------------------------------------------------+ -- cgit v1.3.1 From 6a15e7875c6bc42247210fdcebdea1a4353c51ea Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 24 Sep 2024 18:01:09 +0700 Subject: more rename --- src/portable/synopsys/dwc2/dcd_dwc2.c | 106 +++++++++++++++++----------------- src/tusb_option.h | 2 +- 2 files changed, 55 insertions(+), 53 deletions(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 2c5e82778..eb5b145e8 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -252,6 +252,55 @@ static void dfifo_init(uint8_t rhport) { dfifo_alloc(rhport, 0x80, CFG_TUD_ENDPOINT0_SIZE); } +// Read a single data packet from receive FIFO +static void dfifo_read_packet(uint8_t rhport, uint8_t* dst, uint16_t len) { + (void) rhport; + + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + volatile const uint32_t* rx_fifo = dwc2->fifo[0]; + + // Reading full available 32 bit words from fifo + uint16_t full_words = len >> 2; + while (full_words--) { + tu_unaligned_write32(dst, *rx_fifo); + dst += 4; + } + + // Read the remaining 1-3 bytes from fifo + uint8_t const bytes_rem = len & 0x03; + if (bytes_rem != 0) { + uint32_t const tmp = *rx_fifo; + dst[0] = tu_u32_byte0(tmp); + if (bytes_rem > 1) dst[1] = tu_u32_byte1(tmp); + if (bytes_rem > 2) dst[2] = tu_u32_byte2(tmp); + } +} + +// Write a single data packet to EPIN FIFO +static void dfifo_write_packet(uint8_t rhport, uint8_t fifo_num, uint8_t const* src, uint16_t len) { + (void) rhport; + + dwc2_regs_t* dwc2 = DWC2_REG(rhport); + volatile uint32_t* tx_fifo = dwc2->fifo[fifo_num]; + + // Pushing full available 32 bit words to fifo + uint16_t full_words = len >> 2; + while (full_words--) { + *tx_fifo = tu_unaligned_read32(src); + src += 4; + } + + // Write the remaining 1-3 bytes into fifo + uint8_t const bytes_rem = len & 0x03; + if (bytes_rem) { + uint32_t tmp_word = src[0]; + if (bytes_rem > 1) tmp_word |= (src[1] << 8); + if (bytes_rem > 2) tmp_word |= (src[2] << 16); + + *tx_fifo = tmp_word; + } +} + //-------------------------------------------------------------------- // Endpoint //-------------------------------------------------------------------- @@ -899,56 +948,9 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { } } -/*------------------------------------------------------------------*/ - -// Read a single data packet from receive FIFO -static void read_fifo_packet(uint8_t rhport, uint8_t* dst, uint16_t len) { - (void) rhport; - - dwc2_regs_t* dwc2 = DWC2_REG(rhport); - volatile const uint32_t* rx_fifo = dwc2->fifo[0]; - - // Reading full available 32 bit words from fifo - uint16_t full_words = len >> 2; - while (full_words--) { - tu_unaligned_write32(dst, *rx_fifo); - dst += 4; - } - - // Read the remaining 1-3 bytes from fifo - uint8_t const bytes_rem = len & 0x03; - if (bytes_rem != 0) { - uint32_t const tmp = *rx_fifo; - dst[0] = tu_u32_byte0(tmp); - if (bytes_rem > 1) dst[1] = tu_u32_byte1(tmp); - if (bytes_rem > 2) dst[2] = tu_u32_byte2(tmp); - } -} - -// Write a single data packet to EPIN FIFO -static void write_fifo_packet(uint8_t rhport, uint8_t fifo_num, uint8_t const* src, uint16_t len) { - (void) rhport; - - dwc2_regs_t* dwc2 = DWC2_REG(rhport); - volatile uint32_t* tx_fifo = dwc2->fifo[fifo_num]; - - // Pushing full available 32 bit words to fifo - uint16_t full_words = len >> 2; - while (full_words--) { - *tx_fifo = tu_unaligned_read32(src); - src += 4; - } - - // Write the remaining 1-3 bytes into fifo - uint8_t const bytes_rem = len & 0x03; - if (bytes_rem) { - uint32_t tmp_word = src[0]; - if (bytes_rem > 1) tmp_word |= (src[1] << 8); - if (bytes_rem > 2) tmp_word |= (src[2] << 16); - - *tx_fifo = tmp_word; - } -} +//-------------------------------------------------------------------- +// Interrupt Handler +//-------------------------------------------------------------------- static void handle_rxflvl_irq(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); @@ -1002,7 +1004,7 @@ static void handle_rxflvl_irq(uint8_t rhport) { tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void*) (uintptr_t) rx_fifo, bcnt); } else { // Linear buffer - read_fifo_packet(rhport, xfer->buffer, bcnt); + dfifo_read_packet(rhport, xfer->buffer, bcnt); // Increment pointer to xfer data xfer->buffer += bcnt; @@ -1171,7 +1173,7 @@ static void handle_epin_irq(uint8_t rhport) { volatile uint32_t* tx_fifo = dwc2->fifo[n]; tu_fifo_read_n_const_addr_full_words(xfer->ff, (void*) (uintptr_t) tx_fifo, packet_size); } else { - write_fifo_packet(rhport, n, xfer->buffer, packet_size); + dfifo_write_packet(rhport, n, xfer->buffer, packet_size); // Increment pointer to xfer data xfer->buffer += packet_size; diff --git a/src/tusb_option.h b/src/tusb_option.h index e61b3bb9e..0d118eef9 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -244,7 +244,7 @@ // DWC2 controller: use DMA for data transfer #ifndef CFG_TUD_DWC2_DMA - #define CFG_TUD_DWC2_DMA 1 + #define CFG_TUD_DWC2_DMA 0 #endif // Enable PIO-USB software host controller -- cgit v1.3.1 From 47233f863a5fa5255461514fada9af7771cf2146 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 18 Sep 2024 17:59:04 +0700 Subject: update to dwc2 register struct --- src/portable/synopsys/dwc2/dwc2_info.md | 110 +++++++++++++------------- src/portable/synopsys/dwc2/dwc2_info.py | 27 +++---- src/portable/synopsys/dwc2/dwc2_type.h | 136 +++++++++++++++++++++++++++----- test/hil/hil_test.py | 5 +- 4 files changed, 187 insertions(+), 91 deletions(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dwc2_info.md b/src/portable/synopsys/dwc2/dwc2_info.md index 8690a0755..a11b79671 100644 --- a/src/portable/synopsys/dwc2/dwc2_info.md +++ b/src/portable/synopsys/dwc2/dwc2_info.md @@ -1,55 +1,55 @@ -| | BCM2711 (Pi4) | EFM32GG FullSpeed | ESP32-S2 | STM32F407 Fullspeed | STM32F407 Highspeed | STM32F411 Fullspeed | STM32F412 Fullspeed | STM32F429 Fullspeed | STM32F429 Highspeed | STM32F723 Fullspeed | STM32F723 HighSpeed | STM32F767 Fullspeed | STM32H743 Highspeed | STM32L476 Fullspeed | STM32U5A5 Highspeed | GD32VF103 Fullspeed | XMC4500 | -|:----------------------------|:----------------|:--------------------|:-----------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:----------------------|:-----------| -| guid | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00001200 | 0x00002000 | 0x00001200 | 0x00001100 | 0x00003000 | 0x00003100 | 0x00002000 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 | -| gsnpsid | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54281A | 0x4F54281A | 0x4F54330A | 0x4F54330A | 0x4F54320A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A | -| - specs version | 2.80a | 3.30a | 4.00a | 2.81a | 2.81a | 2.81a | 3.20a | 2.81a | 2.81a | 3.30a | 3.30a | 3.20a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a | -| ghwcfg1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | -| ghwcfg2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x229DCD20 | 0x229ED590 | 0x229DCD20 | 0x229ED520 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229FE1D0 | 0x229ED520 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 | -| - op_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | -| - arch | 2 | 2 | 2 | 0 | 2 | 0 | 0 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | -| - point2point | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | -| - hs_phy_type | 1 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | 2 | 0 | 3 | 0 | 2 | 0 | 1 | 0 | 0 | -| - fs_phy_type | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - num_dev_ep | 7 | 6 | 6 | 3 | 5 | 3 | 5 | 3 | 5 | 5 | 8 | 5 | 8 | 5 | 8 | 0 | 6 | -| - num_host_ch | 7 | 13 | 7 | 7 | 11 | 7 | 11 | 7 | 11 | 11 | 15 | 11 | 15 | 11 | 15 | 0 | 13 | -| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - mul_cpu_int | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - nperiod_tx_q_depth | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | -| - host_period_tx_q_depth | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | -| - dev_token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 | -| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| ghwcfg3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x020001E8 | 0x03F403E8 | 0x020001E8 | 0x0200D1E8 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x03EED2E8 | 0x0200D1E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 | -| - xfer_size_width | 8 | 8 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 | -| - packet_size_width | 6 | 6 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 | -| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - i2c_enable | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | -| - vendor_ctrl_itf | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | -| - optional_feature_removed | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - synch_reset | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - otg_adp_support | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - battery_charger_support | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | -| - total_fifo_size | 4080 | 498 | 200 | 512 | 1012 | 512 | 512 | 512 | 1012 | 512 | 1006 | 512 | 952 | 512 | 952 | 0 | 634 | -| ghwcfg4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0x0FF08030 | 0x17F00030 | 0x0FF08030 | 0x17F08030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x23F00030 | 0x17F08030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 | -| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - power_optimized | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - reserved7 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 4 | 0 | 0 | -| - service_interval_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - ipg_isoc_en | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - acg_enable | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - reserved13 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - utmi_phy_data_width | 0 | 2 | 2 | 2 | 0 | 2 | 2 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 0 | 2 | -| - dev_ctrl_ep_num | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - iddg_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - vbus_valid_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - a_valid_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - b_valid_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - num_dev_in_eps | 15 | 13 | 9 | 7 | 11 | 7 | 11 | 7 | 11 | 11 | 1 | 11 | 1 | 11 | 1 | 0 | 13 | -| - dma_desc_enable | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | -| - dma_dynamic | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | +| | BCM2711 (Pi4) | EFM32GG FS | ESP32-S2/S3 | STM32F 407/411/429 FS | STM32F407 HS | STM32F412 FS | STM32F429 HS | STM32F723 FS | STM32F723 HS | STM32F767 FS | STM32H743 HS | STM32L476 FS | STM32U5A5 HS | GD32VF103 FS | XMC4500 | +|:----------------------------|:----------------|:-------------|:--------------|:------------------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:-----------| +| guid | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00001100 | 0x00003000 | 0x00003100 | 0x00002000 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 | +| gsnpsid | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54281A | 0x4F54330A | 0x4F54330A | 0x4F54320A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A | +| - specs version | 2.80a | 3.30a | 4.00a | 2.81a | 2.81a | 3.20a | 2.81a | 3.30a | 3.30a | 3.20a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a | +| ghwcfg1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | +| ghwcfg2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED590 | 0x229ED520 | 0x229FE1D0 | 0x229ED520 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 | +| - op_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | +| - arch | 2 | 2 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | +| - point2point | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | +| - hs_phy_type | 1 | 0 | 0 | 0 | 2 | 0 | 2 | 0 | 3 | 0 | 2 | 0 | 1 | 0 | 0 | +| - fs_phy_type | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - num_dev_ep | 7 | 6 | 6 | 3 | 5 | 5 | 5 | 5 | 8 | 5 | 8 | 5 | 8 | 0 | 6 | +| - num_host_ch | 7 | 13 | 7 | 7 | 11 | 11 | 11 | 11 | 15 | 11 | 15 | 11 | 15 | 0 | 13 | +| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - mul_cpu_int | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - nperiod_tx_q_depth | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | +| - host_period_tx_q_depth | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | +| - dev_token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 | +| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| ghwcfg3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x03F403E8 | 0x0200D1E8 | 0x03EED2E8 | 0x0200D1E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 | +| - xfer_size_width | 8 | 8 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 | +| - packet_size_width | 6 | 6 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 | +| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - i2c_enable | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | +| - vendor_ctrl_itf | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | +| - optional_feature_removed | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - synch_reset | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - otg_adp_support | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - battery_charger_support | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | +| - total_fifo_size | 4080 | 498 | 200 | 512 | 1012 | 512 | 1012 | 512 | 1006 | 512 | 952 | 512 | 952 | 0 | 634 | +| ghwcfg4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F00030 | 0x17F08030 | 0x23F00030 | 0x17F08030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 | +| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - power_optimized | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - reserved7 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 4 | 0 | 0 | +| - service_interval_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - ipg_isoc_en | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - acg_enable | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - reserved13 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - utmi_phy_data_width | 0 | 2 | 2 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 0 | 2 | +| - dev_ctrl_ep_num | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - iddg_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - vbus_valid_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - a_valid_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - b_valid_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - num_dev_in_eps | 15 | 13 | 9 | 7 | 11 | 11 | 11 | 11 | 1 | 11 | 1 | 11 | 1 | 0 | 13 | +| - dma_desc_enable | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | +| - dma_dynamic | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | diff --git a/src/portable/synopsys/dwc2/dwc2_info.py b/src/portable/synopsys/dwc2/dwc2_info.py index 55bec3d23..6f3f195f0 100644 --- a/src/portable/synopsys/dwc2/dwc2_info.py +++ b/src/portable/synopsys/dwc2/dwc2_info.py @@ -3,24 +3,21 @@ import ctypes import pandas as pd # hex value for register: guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4 +# Note: FS is FullSpeed, HS is HighSpeed dwc2_reg_list = ['guid', 'gsnpsid', 'ghwcfg1', 'ghwcfg2', 'ghwcfg3', 'ghwcfg4'] dwc2_reg_value = { 'BCM2711 (Pi4)': [0x2708A000, 0x4F54280A, 0, 0x228DDD50, 0xFF000E8, 0x1FF00020], - 'EFM32GG FullSpeed': [0, 0x4F54330A, 0, 0x228F5910, 0x1F204E8, 0x1BF08030], - 'ESP32-S2': [0, 0x4F54400A, 0, 0x224DD930, 0xC804B5, 0xD3F0A030], - 'STM32F407 Fullspeed': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x20001E8, 0xFF08030], - 'STM32F407 Highspeed': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x3F403E8, 0x17F00030], - 'STM32F411 Fullspeed': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x20001E8, 0xFF08030], - 'STM32F412 Fullspeed': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], - 'STM32F429 Fullspeed': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x20001E8, 0xFF08030], - 'STM32F429 Highspeed': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x3F403E8, 0x17F00030], - 'STM32F723 Fullspeed': [0x3000, 0x4F54330A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], - 'STM32F723 HighSpeed': [0x3100, 0x4F54330A, 0, 0x229FE1D0, 0x3EED2E8, 0x23F00030], - 'STM32F767 Fullspeed': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], - 'STM32H743 Highspeed': [0x2300, 0x4F54330A, 0, 0x229FE190, 0x3B8D2E8, 0xE3F00030], # both HS cores - 'STM32L476 Fullspeed': [0x2000, 0x4F54310A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], - 'STM32U5A5 Highspeed': [0x00005000, 0x4F54411A, 0x00000000, 0x228FE052, 0x03B882E8, 0xE2103E30], - 'GD32VF103 Fullspeed': [0x1000, 0, 0, 0, 0, 0], + 'EFM32GG FS': [0, 0x4F54330A, 0, 0x228F5910, 0x1F204E8, 0x1BF08030], + 'ESP32-S2/S3': [0, 0x4F54400A, 0, 0x224DD930, 0xC804B5, 0xD3F0A030], + 'STM32F 407/411/429 FS': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x20001E8, 0xFF08030], + 'STM32F 407/429 HS': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x3F403E8, 0x17F00030], + 'STM32F 412/767 FS': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], + 'STM32F723 FS': [0x3000, 0x4F54330A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], + 'STM32F723 HS': [0x3100, 0x4F54330A, 0, 0x229FE1D0, 0x3EED2E8, 0x23F00030], + 'STM32H743 HS': [0x2300, 0x4F54330A, 0, 0x229FE190, 0x3B8D2E8, 0xE3F00030], # both HS cores + 'STM32L476 FS': [0x2000, 0x4F54310A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], + 'STM32U5A5 HS': [0x5000, 0x4F54411A, 0, 0x228FE052, 0x03B882E8, 0xE2103E30], + 'GD32VF103 FS': [0x1000, 0, 0, 0, 0, 0], 'XMC4500': [0xAEC000, 0x4F54292A, 0, 0x228F5930, 0x27A01E5, 0xDBF08030] } diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index c21bf9e94..97b9d1d8c 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -101,13 +101,15 @@ enum { }; enum { - GHWCFG2_ARCH_SLAVE_ONLY = 0, - GHWCFG2_ARCH_EXTERNAL_DMA, // 1 - GHWCFG2_ARCH_INTERNAL_DMA, // 2 + GHWCFG2_ARCH_SLAVE_ONLY = 0, + GHWCFG2_ARCH_EXTERNAL_DMA, // 1 + GHWCFG2_ARCH_INTERNAL_DMA, // 2 }; -typedef struct TU_ATTR_PACKED -{ +//-------------------------------------------------------------------- +// Register bitfield definitions +//-------------------------------------------------------------------- +typedef struct TU_ATTR_PACKED { uint32_t op_mode : 3; // 0: HNP and SRP | 1: SRP | 2: non-HNP, non-SRP uint32_t arch : 2; // 0: slave-only | 1: External DMA | 2: Internal DMA | 3: others uint32_t point2point : 1; // 0: support hub and split | 1: no hub, no split @@ -124,11 +126,9 @@ typedef struct TU_ATTR_PACKED uint32_t dev_token_q_depth : 5; // Device IN token sequence learning queue depth: 0-30 uint32_t otg_enable_ic_usb : 1; // IC_USB mode specified for mode of operation } dwc2_ghwcfg2_t; - TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg2_t) == 4, "incorrect size"); -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint32_t xfer_size_width : 4; // Transfer size counter in bits = 11 + n (max 19 bits) uint32_t packet_size_width : 3; // Packet size counter in bits = 4 + n (max 10 bits) uint32_t otg_enable : 1; // 1 is OTG capable @@ -142,11 +142,9 @@ typedef struct TU_ATTR_PACKED uint32_t lpm_mode : 1; // LPC mode uint32_t dfifo_depth : 16; // DFIFO depth - EP_LOC_CNT in terms of 32-bit words }dwc2_ghwcfg3_t; - TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg3_t) == 4, "incorrect size"); -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { uint32_t num_dev_period_in_ep : 4; // Number of Device Periodic IN Endpoints uint32_t power_optimized : 1; // Partial Power Down Enabled uint32_t ahb_freq_min : 1; // 1: minimum of AHB frequency is less than 60 MHz @@ -167,12 +165,110 @@ typedef struct TU_ATTR_PACKED uint32_t dma_desc_enable : 1; // scatter/gather DMA configuration uint32_t dma_dynamic : 1; // Dynamic scatter/gather DMA }dwc2_ghwcfg4_t; - TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg4_t) == 4, "incorrect size"); +typedef struct TU_ATTR_PACKED { + uint32_t ses_req_scs : 1; // 0: Session request success + uint32_t ses_req : 1; // 1: Session request + uint32_t vbval_ov_en : 1; // 2: VBUS valid override enable + uint32_t vbval_ov_val : 1; // 3: VBUS valid override value + uint32_t aval_ov_en : 1; // 4: A-peripheral session valid override enable + uint32_t aval_ov_al : 1; // 5: A-peripheral session valid override value + uint32_t bval_ov_en : 1; // 6: B-peripheral session valid override enable + uint32_t bval_ov_val : 1; // 7: B-peripheral session valid override value + uint32_t hng_scs : 1; // 8: Host negotiation success + uint32_t hnp_rq : 1; // 9: HNP (host negotiation protocol) request + uint32_t host_set_hnp_en : 1; // 10: Host set HNP enable + uint32_t dev_hnp_en : 1; // 11: Device HNP enabled + uint32_t embedded_host_en : 1; // 12: Embedded host enable + uint32_t rsv13_14 : 2; // 13..14: Reserved + uint32_t dbnc_filter_bypass : 1; // 15: Debounce filter bypass + uint32_t cid_status : 1; // 16: Connector ID status + uint32_t dbnc_done : 1; // 17: Debounce done + uint32_t ases_valid : 1; // 18: A-session valid + uint32_t bses_valid : 1; // 19: B-session valid + uint32_t otg_ver : 1; // 20: OTG version 0: v1.3, 1: v2.0 + uint32_t current_mode : 1; // 21: Current mode of operation 0: device, 1: host + uint32_t mult_val_id_bc : 5; // 22..26: Multi-valued input pin ID battery charger + uint32_t chirp_en : 1; // 27: Chirp detection enable + uint32_t rsv28_30 : 3; // 28..30: Reserved + uint32_t test_mode_corr_eusb2 : 1; // 31: Test mode control for eUSB2 PHY +} dwc2_gotgctl_t; +TU_VERIFY_STATIC(sizeof(dwc2_gotgctl_t) == 4, "incorrect size"); + +typedef struct TU_ATTR_PACKED { + uint32_t rsv0_1 : 2; // 0..1 : Reserved + uint32_t ses_end_det : 1; // 2 : Session end detected + uint32_t rsv3_7 : 5; // 3..7 : Reserved + uint32_t srs_status_change : 1; // 8 : Session request success status change + uint32_t hns_status_change : 1; // 9 : Host negotiation success status change + uint32_t rsv10_16 : 7; // 10..16 : Reserved + uint32_t hng_det : 1; // 17 : Host negotiation detected + uint32_t adev_timeout_change : 1; // 18 : A-device timeout change + uint32_t dbnc_done : 1; // 19 : Debounce done + uint32_t mult_val_lp_change : 1; // 20 : Multi-valued input pin change + uint32_t rsv21_31 :11; // 21..31 : Reserved +} dwc2_gotgint_t; +TU_VERIFY_STATIC(sizeof(dwc2_gotgint_t) == 4, "incorrect size"); + +typedef struct TU_ATTR_PACKED { + uint32_t gintmask : 1; // 0: Global interrupt mask + uint32_t hbst_len : 4; // 1..4: Burst length/type + uint32_t dma_en : 1; // 5: DMA enable + uint32_t rsv6 : 1; // 6: Reserved + uint32_t nptxf_empty_lvl : 1; // 7: Non-periodic Tx FIFO empty level + uint32_t ptxf_empty_lvl : 1; // 8: Periodic Tx FIFO empty level + uint32_t rsv9_20 : 12; // 9..20: Reserved + uint32_t remote_mem_support : 1; // 21: Remote memory support + uint32_t notify_all_dma_write : 1; // 22: Notify all DMA writes + uint32_t ahb_single : 1; // 23: AHB single + uint32_t inv_desc_endian : 1; // 24: Inverse descriptor endian + uint32_t rsv25_31 : 7; // 25..31: Reserved +} dwc2_gahbcfg_t; +TU_VERIFY_STATIC(sizeof(dwc2_gahbcfg_t) == 4, "incorrect size"); + +typedef struct TU_ATTR_PACKED { + uint32_t timeout_cal : 3; /* 0..2: Timeout calibration. + The USB standard timeout value for high-speed operation is 736 to 816 (inclusive) bit times. The USB standard + timeout value for full- speed operation is 16 to 18 (inclusive) bit times. The application must program this field + based on the speed of enumeration. The number of bit times added per PHY clock are as follows: + - High-speed: PHY clock One 30-MHz = 16 bit times, One 60-MHz = 8 bit times + - Full-speed: PHY clock One 30-MHz = 0.4 bit times, One 60-MHz = 0.2 bit times, One 48-MHz = 0.25 bit times */ + uint32_t phy_if : 1; // 3: PHY interface. 0: 8 bits, 1: 16 bits + uint32_t ulpi_utmi_sel : 1; // 4: ULPI/UTMI select. 0: UTMI+, 1: ULPI + uint32_t fs_intf_sel : 1; // 5: Fullspeed serial interface select. 0: 6-pin, 1: 3-pin + uint32_t phy_sel : 1; // 6: HS/FS PHY selection. 0: HS UTMI+ or ULPI, 1: FS serial transceiver + uint32_t ddr_sel : 1; // 7 ULPI DDR select. 0: Single data rate 8-bit, 1: Double data rate 4-bit + uint32_t srp_capable : 1; // 8: SRP-capable + uint32_t hnp_capable : 1; // 9: HNP-capable + uint32_t turnaround_time : 4; // 10..13 Turnaround time. 9: 8-bit UTMI+, 5: 16-bit UTMI+ + uint32_t rsv14 : 1; // 14: Reserved + uint32_t phy_low_power_clk_sel : 1; /* 15: PHY low-power clock select either 480-MHz or 48-MHz (low-power) PHY mode. + In FS/LS modes, the PHY can usually operate on a 48-MHz clock to save power. This bit is valid only for UTMI+ PHYs. + - 0: 480 Mhz internal PLL: the UTMI interface operates at either 60 MHz (8 bit) or 30 MHz (16-bit) + - 1 48 Mhz external clock: the UTMI interface operates at 48 MHz in FS mode and at either 48 or 6 MHz in LS mode */ + uint32_t otg_i2c_sel : 1; // 16: OTG I2C interface select. 0: UTMI-FS, 1: I2C for OTG signals + uint32_t ulpi_fsls : 1; /* 17: ULPI FS/LS select. 0: ULPI, 1: ULPI FS/LS. + valid only when the FS serial transceiver is selected on the ULPI PHY. */ + uint32_t ulpi_auto_resume : 1; // 18: ULPI Auto-resume + uint32_t ulpi_clk_sus_m : 1; // 19: ULPI Clock SuspendM + uint32_t ulpi_ext_vbus_drv : 1; // 20: ULPI External VBUS Drive + uint32_t ulpi_int_vbus_indicator : 1; // 21: ULPI Internal VBUS Indicator + uint32_t term_sel_dl_pulse : 1; // 22: TermSel DLine pulsing + uint32_t indicator_complement : 1; // 23: Indicator complement + uint32_t indicator_pass_through : 1; // 24: Indicator pass through + uint32_t ulpi_if_protect_disable : 1; // 25: ULPI interface protect disable + uint32_t ic_usb_capable : 1; // 26: IC_USB Capable + uint32_t ic_usb_traf_ctl : 1; // 27: IC_USB Traffic Control + uint32_t tx_end_delay : 1; // 28: TX end delay + uint32_t force_host_mode : 1; // 29: Force host mode + uint32_t force_dev_mode : 1; // 30: Force device mode + uint32_t corrupt_tx_pkt : 1; // 31: Corrupt Tx packet. 0: normal, 1: debug +} dwc2_gusbcfg_t; +TU_VERIFY_STATIC(sizeof(dwc2_gusbcfg_t) == 4, "incorrect size"); + // Host Channel -typedef struct -{ +typedef struct { volatile uint32_t hcchar; // 500 + 20*ch Host Channel Characteristics volatile uint32_t hcsplt; // 504 + 20*ch Host Channel Split Control volatile uint32_t hcint; // 508 + 20*ch Host Channel Interrupt @@ -184,8 +280,7 @@ typedef struct } dwc2_channel_t; // Endpoint IN -typedef struct -{ +typedef struct { volatile uint32_t diepctl; // 900 + 20*ep Device IN Endpoint Control uint32_t reserved04; // 904 volatile uint32_t diepint; // 908 + 20*ep Device IN Endpoint Interrupt @@ -197,8 +292,7 @@ typedef struct } dwc2_epin_t; // Endpoint OUT -typedef struct -{ +typedef struct { volatile uint32_t doepctl; // B00 + 20*ep Device OUT Endpoint Control uint32_t reserved04; // B04 volatile uint32_t doepint; // B08 + 20*ep Device OUT Endpoint Interrupt @@ -208,8 +302,10 @@ typedef struct uint32_t reserved18[2]; // B18..B1C } dwc2_epout_t; -typedef struct -{ +//-------------------------------------------------------------------- +// CSR Register Map +//-------------------------------------------------------------------- +typedef struct { //------------- Core Global -------------// volatile uint32_t gotgctl; // 000 OTG Control and Status volatile uint32_t gotgint; // 004 OTG Interrupt diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 2d14220c5..fc2e6c777 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -459,6 +459,8 @@ def main(): """ global verbose + duration = time.time() + parser = argparse.ArgumentParser() parser.add_argument('config_file', help='Configuration JSON file') parser.add_argument('-b', '--board', action='append', default=[], help='Boards to test, all if not specified') @@ -483,9 +485,10 @@ def main(): with Pool(processes=os.cpu_count()) as pool: err_count = sum(pool.map(test_board, config_boards)) + duration = time.time() - duration print() print("-" * 30) - print(f'Total failed: {err_count}') + print(f'Total failed: {err_count} in {duration:.1f}s') print("-" * 30) sys.exit(err_count) -- cgit v1.3.1 From bb2d1dd0c1bef04d495b05d609311e3b7ba870a7 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 24 Sep 2024 22:35:07 +0700 Subject: update/rename ghwcfg registers --- src/portable/synopsys/dwc2/dcd_dwc2.c | 21 +- src/portable/synopsys/dwc2/dwc2_info.md | 113 +++---- src/portable/synopsys/dwc2/dwc2_info.py | 37 +-- src/portable/synopsys/dwc2/dwc2_stm32.h | 6 +- src/portable/synopsys/dwc2/dwc2_type.h | 518 +++++++++++++++++--------------- 5 files changed, 366 insertions(+), 329 deletions(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index eb5b145e8..13143073d 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -538,13 +538,10 @@ static void reset_core(dwc2_regs_t* dwc2) { static bool phy_hs_supported(dwc2_regs_t* dwc2) { (void) dwc2; -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) - // note: esp32 incorrect report its hs_phy_type as utmi - return false; -#elif !TUD_OPT_HIGH_SPEED +#if !TUD_OPT_HIGH_SPEED return false; #else - return dwc2->ghwcfg2_bm.hs_phy_type != HS_PHY_TYPE_NONE; + return dwc2->ghwcfg2_bm.hs_phy_type != GHWCFG2_HSPHY_NOT_SUPPORTED; #endif } @@ -555,7 +552,7 @@ static void phy_fs_init(dwc2_regs_t* dwc2) { dwc2->gusbcfg |= GUSBCFG_PHYSEL; // MCU specific PHY init before reset - dwc2_phy_init(dwc2, HS_PHY_TYPE_NONE); + dwc2_phy_init(dwc2, GHWCFG2_HSPHY_NOT_SUPPORTED); // Reset core after selecting PHY reset_core(dwc2); @@ -566,7 +563,7 @@ static void phy_fs_init(dwc2_regs_t* dwc2) { dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_TRDT_Msk) | (5u << GUSBCFG_TRDT_Pos); // MCU specific PHY update post reset - dwc2_phy_update(dwc2, HS_PHY_TYPE_NONE); + dwc2_phy_update(dwc2, GHWCFG2_HSPHY_NOT_SUPPORTED); // set max speed dwc2->dcfg = (dwc2->dcfg & ~DCFG_DSPD_Msk) | (DCFG_DSPD_FS << DCFG_DSPD_Pos); @@ -578,7 +575,7 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { // De-select FS PHY gusbcfg &= ~GUSBCFG_PHYSEL; - if (dwc2->ghwcfg2_bm.hs_phy_type == HS_PHY_TYPE_ULPI) { + if (dwc2->ghwcfg2_bm.hs_phy_type == GHWCFG2_HSPHY_ULPI) { TU_LOG(DWC2_DEBUG, "Highspeed ULPI PHY init\r\n"); // Select ULPI @@ -599,7 +596,7 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { gusbcfg &= ~(GUSBCFG_ULPI_UTMI_SEL | GUSBCFG_PHYIF16); // Set 16-bit interface if supported - if (dwc2->ghwcfg4_bm.utmi_phy_data_width) gusbcfg |= GUSBCFG_PHYIF16; + if (dwc2->ghwcfg4_bm.phy_data_width) gusbcfg |= GUSBCFG_PHYIF16; } // Apply config @@ -615,7 +612,7 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { // - 9 if using 8-bit PHY interface // - 5 if using 16-bit PHY interface gusbcfg &= ~GUSBCFG_TRDT_Msk; - gusbcfg |= (dwc2->ghwcfg4_bm.utmi_phy_data_width ? 5u : 9u) << GUSBCFG_TRDT_Pos; + gusbcfg |= (dwc2->ghwcfg4_bm.phy_data_width ? 5u : 9u) << GUSBCFG_TRDT_Pos; dwc2->gusbcfg = gusbcfg; // MCU specific PHY update post reset @@ -628,7 +625,7 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { // XCVRDLY: transceiver delay between xcvr_sel and txvalid during device chirp is required // when using with some PHYs such as USB334x (USB3341, USB3343, USB3346, USB3347) - if (dwc2->ghwcfg2_bm.hs_phy_type == HS_PHY_TYPE_ULPI) { + if (dwc2->ghwcfg2_bm.hs_phy_type == GHWCFG2_HSPHY_ULPI) { dcfg |= DCFG_XCVRDLY; } @@ -640,7 +637,7 @@ static bool check_dwc2(dwc2_regs_t* dwc2) { print_dwc2_info(dwc2); #endif - // For some reasons: GD32VF103 snpsid and all hwcfg register are always zero (skip it) + // For some reason: GD32VF103 snpsid and all hwcfg register are always zero (skip it) (void) dwc2; #if !TU_CHECK_MCU(OPT_MCU_GD32VF103) uint32_t const gsnpsid = dwc2->gsnpsid & GSNPSID_ID_MASK; diff --git a/src/portable/synopsys/dwc2/dwc2_info.md b/src/portable/synopsys/dwc2/dwc2_info.md index a11b79671..9798fb0de 100644 --- a/src/portable/synopsys/dwc2/dwc2_info.md +++ b/src/portable/synopsys/dwc2/dwc2_info.md @@ -1,55 +1,58 @@ -| | BCM2711 (Pi4) | EFM32GG FS | ESP32-S2/S3 | STM32F 407/411/429 FS | STM32F407 HS | STM32F412 FS | STM32F429 HS | STM32F723 FS | STM32F723 HS | STM32F767 FS | STM32H743 HS | STM32L476 FS | STM32U5A5 HS | GD32VF103 FS | XMC4500 | -|:----------------------------|:----------------|:-------------|:--------------|:------------------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:-----------| -| guid | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00001100 | 0x00003000 | 0x00003100 | 0x00002000 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 | -| gsnpsid | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54281A | 0x4F54330A | 0x4F54330A | 0x4F54320A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A | -| - specs version | 2.80a | 3.30a | 4.00a | 2.81a | 2.81a | 3.20a | 2.81a | 3.30a | 3.30a | 3.20a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a | -| ghwcfg1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | -| ghwcfg2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED590 | 0x229ED520 | 0x229FE1D0 | 0x229ED520 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 | -| - op_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | -| - arch | 2 | 2 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | -| - point2point | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | -| - hs_phy_type | 1 | 0 | 0 | 0 | 2 | 0 | 2 | 0 | 3 | 0 | 2 | 0 | 1 | 0 | 0 | -| - fs_phy_type | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - num_dev_ep | 7 | 6 | 6 | 3 | 5 | 5 | 5 | 5 | 8 | 5 | 8 | 5 | 8 | 0 | 6 | -| - num_host_ch | 7 | 13 | 7 | 7 | 11 | 11 | 11 | 11 | 15 | 11 | 15 | 11 | 15 | 0 | 13 | -| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - mul_cpu_int | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - nperiod_tx_q_depth | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | -| - host_period_tx_q_depth | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | -| - dev_token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 | -| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| ghwcfg3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x03F403E8 | 0x0200D1E8 | 0x03EED2E8 | 0x0200D1E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 | -| - xfer_size_width | 8 | 8 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 | -| - packet_size_width | 6 | 6 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 | -| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - i2c_enable | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | -| - vendor_ctrl_itf | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | -| - optional_feature_removed | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - synch_reset | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - otg_adp_support | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - battery_charger_support | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | -| - total_fifo_size | 4080 | 498 | 200 | 512 | 1012 | 512 | 1012 | 512 | 1006 | 512 | 952 | 512 | 952 | 0 | 634 | -| ghwcfg4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F00030 | 0x17F08030 | 0x23F00030 | 0x17F08030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 | -| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - power_optimized | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - reserved7 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 4 | 0 | 0 | -| - service_interval_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - ipg_isoc_en | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - acg_enable | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - reserved13 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - utmi_phy_data_width | 0 | 2 | 2 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 2 | 0 | 0 | 2 | -| - dev_ctrl_ep_num | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - iddg_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - vbus_valid_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - a_valid_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - b_valid_filter_enabled | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - num_dev_in_eps | 15 | 13 | 9 | 7 | 11 | 11 | 11 | 11 | 1 | 11 | 1 | 11 | 1 | 0 | 13 | -| - dma_desc_enable | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | -| - dma_dynamic | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | +| | BCM2711 (Pi4) | EFM32GG FS | ESP32-S2/S3 | STM32F 407/411/429 FS | STM32F 407/429 HS | STM32F 412/767 FS | STM32F723 FS | STM32F723 HS | STM32H743 HS | STM32L476 FS | STM32U5A5 HS | GD32VF103 FS | XMC4500 | +|:---------------------------|:----------------|:-------------|:--------------|:------------------------|:--------------------|:--------------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:-----------| +| guid | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 | +| gsnpsid | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A | +| - specs version | 2.80a | 3.30a | 4.00a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a | +| ghwcfg1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | +| ghwcfg2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 | +| - op_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | +| - arch | 2 | 2 | 2 | 0 | 2 | 0 | 0 | 2 | 2 | 0 | 2 | 0 | 2 | +| - point2point | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | +| - hs_phy_type | 1 | 0 | 0 | 0 | 2 | 0 | 0 | 3 | 2 | 0 | 1 | 0 | 0 | +| - fs_phy_type | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - num_dev_ep | 7 | 6 | 6 | 3 | 5 | 5 | 5 | 8 | 8 | 5 | 8 | 0 | 6 | +| - num_host_ch | 7 | 13 | 7 | 7 | 11 | 11 | 11 | 15 | 15 | 11 | 15 | 0 | 13 | +| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - mul_cpu_int | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - nptx_q_depth | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | +| - ptx_q_depth | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | +| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 | +| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| ghwcfg3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 | +| - xfer_size_width | 8 | 8 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 | +| - packet_size_width | 6 | 6 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 | +| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - i2c_enable | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | +| - vendor_ctrl_itf | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | +| - optional_feature_removed | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - synch_reset | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - otg_adp_support | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - battery_charger_support | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | +| - dfifo_depth | 4080 | 498 | 200 | 512 | 1012 | 512 | 512 | 1006 | 952 | 512 | 952 | 0 | 634 | +| ghwcfg4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 | +| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - partial_powerdown | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - enhanced_lpm_support | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - phy_data_width | 0 | 2 | 2 | 2 | 0 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 2 | +| - ctrl_ep_num | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - iddg_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - vbus_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - a_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - b_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - session_end_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - num_dev_in_eps | 7 | 6 | 4 | 3 | 5 | 5 | 5 | 8 | 8 | 5 | 8 | 0 | 6 | +| - dma_desc_enable | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | +| - dma_desc_dynamic | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | diff --git a/src/portable/synopsys/dwc2/dwc2_info.py b/src/portable/synopsys/dwc2/dwc2_info.py index 6f3f195f0..871ac112d 100644 --- a/src/portable/synopsys/dwc2/dwc2_info.py +++ b/src/portable/synopsys/dwc2/dwc2_info.py @@ -47,9 +47,9 @@ class GHWCFG2(ctypes.LittleEndianStructure): ("enable_dynamic_fifo", ctypes.c_uint32, 1), ("mul_cpu_int", ctypes.c_uint32, 1), ("reserved21", ctypes.c_uint32, 1), - ("nperiod_tx_q_depth", ctypes.c_uint32, 2), - ("host_period_tx_q_depth", ctypes.c_uint32, 2), - ("dev_token_q_depth", ctypes.c_uint32, 5), + ("nptx_q_depth", ctypes.c_uint32, 2), + ("ptx_q_depth", ctypes.c_uint32, 2), + ("token_q_depth", ctypes.c_uint32, 5), ("otg_enable_ic_usb", ctypes.c_uint32, 1) ] @@ -67,31 +67,34 @@ class GHWCFG3(ctypes.LittleEndianStructure): ("otg_enable_hsic", ctypes.c_uint32, 1), ("battery_charger_support", ctypes.c_uint32, 1), ("lpm_mode", ctypes.c_uint32, 1), - ("total_fifo_size", ctypes.c_uint32, 16) + ("dfifo_depth", ctypes.c_uint32, 16) ] class GHWCFG4(ctypes.LittleEndianStructure): _fields_ = [ ("num_dev_period_in_ep", ctypes.c_uint32, 4), - ("power_optimized", ctypes.c_uint32, 1), + ("partial_powerdown", ctypes.c_uint32, 1), ("ahb_freq_min", ctypes.c_uint32, 1), ("hibernation", ctypes.c_uint32, 1), - ("reserved7", ctypes.c_uint32, 3), - ("service_interval_mode", ctypes.c_uint32, 1), - ("ipg_isoc_en", ctypes.c_uint32, 1), - ("acg_enable", ctypes.c_uint32, 1), - ("reserved13", ctypes.c_uint32, 1), - ("utmi_phy_data_width", ctypes.c_uint32, 2), - ("dev_ctrl_ep_num", ctypes.c_uint32, 4), - ("iddg_filter_enabled", ctypes.c_uint32, 1), - ("vbus_valid_filter_enabled", ctypes.c_uint32, 1), - ("a_valid_filter_enabled", ctypes.c_uint32, 1), - ("b_valid_filter_enabled", ctypes.c_uint32, 1), + ("extended_hibernation", ctypes.c_uint32, 1), + ("reserved8", ctypes.c_uint32, 1), + ("enhanced_lpm_support1", ctypes.c_uint32, 1), + ("service_interval_flow", ctypes.c_uint32, 1), + ("ipg_isoc_support", ctypes.c_uint32, 1), + ("acg_support", ctypes.c_uint32, 1), + ("enhanced_lpm_support", ctypes.c_uint32, 1), + ("phy_data_width", ctypes.c_uint32, 2), + ("ctrl_ep_num", ctypes.c_uint32, 4), + ("iddg_filter", ctypes.c_uint32, 1), + ("vbus_valid_filter", ctypes.c_uint32, 1), + ("a_valid_filter", ctypes.c_uint32, 1), + ("b_valid_filter", ctypes.c_uint32, 1), + ("session_end_filter", ctypes.c_uint32, 1), ("dedicated_fifos", ctypes.c_uint32, 1), ("num_dev_in_eps", ctypes.c_uint32, 4), ("dma_desc_enable", ctypes.c_uint32, 1), - ("dma_dynamic", ctypes.c_uint32, 1) + ("dma_desc_dynamic", ctypes.c_uint32, 1) ] diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 3237a50f6..395b6d870 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -142,7 +142,7 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_remote_wakeup_delay(void) { // - dwc2 3.30a (H5) use USB_HS_PHYC // - dwc2 4.11a (U5) use femtoPHY static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { - if (hs_phy_type == HS_PHY_TYPE_NONE) { + if (hs_phy_type == GHWCFG2_HSPHY_NOT_SUPPORTED) { // Enable on-chip FS PHY dwc2->stm32_gccfg |= STM32_GCCFG_PWRDWN; @@ -175,7 +175,7 @@ static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { #endif // Enable on-chip HS PHY - if (hs_phy_type == HS_PHY_TYPE_UTMI || hs_phy_type == HS_PHY_TYPE_UTMI_ULPI) { + if (hs_phy_type == GHWCFG2_HSPHY_UTMI || hs_phy_type == GHWCFG2_HSPHY_UTMI_ULPI) { #ifdef USB_HS_PHYC // Enable UTMI HS PHY dwc2->stm32_gccfg |= STM32_GCCFG_PHYHSEN; @@ -218,7 +218,7 @@ static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { // MCU specific PHY update, it is called AFTER init() and core reset static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { // used to set turnaround time for fullspeed, nothing to do in highspeed mode - if (hs_phy_type == HS_PHY_TYPE_NONE) { + if (hs_phy_type == GHWCFG2_HSPHY_NOT_SUPPORTED) { // Turnaround timeout depends on the AHB clock dictated by STM32 Reference Manual uint32_t turnaround; diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index 97b9d1d8c..ac88dd24d 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -87,186 +87,220 @@ typedef struct #endif enum { - HS_PHY_TYPE_NONE = 0 , // not supported - HS_PHY_TYPE_UTMI , // internal PHY (mostly) - HS_PHY_TYPE_ULPI , // external PHY - HS_PHY_TYPE_UTMI_ULPI , + GHWCFG2_OPMODE_HNP_SRP = 0, + GHWCFG2_OPMODE_SRP = 1, + GHWCFG2_OPMODE_NON_HNP_NON_SRP = 2, + GHWCFG2_OPMODE_SRP_DEVICE = 3, + GHWCFFG2_OPMODE_NON_OTG_DEVICE = 4, + GHWCFG2_OPMODE_SRP_HOST = 5, + GHWCFG2_OPMODE_NON_OTG_HOST = 6, +}; +enum { + GHWCFG2_ARCH_SLAVE_ONLY = 0, + GHWCFG2_ARCH_EXTERNAL_DMA = 1, + GHWCFG2_ARCH_INTERNAL_DMA = 2, +}; + +enum { + GHWCFG2_HSPHY_NOT_SUPPORTED = 0, + GHWCFG2_HSPHY_UTMI = 1, // internal PHY (mostly) + GHWCFG2_HSPHY_ULPI = 2, // external PHY (mostly) + GHWCFG2_HSPHY_UTMI_ULPI = 3, // both + }; enum { - FS_PHY_TYPE_NONE = 0, // not supported - FS_PHY_TYPE_DEDICATED, - FS_PHY_TYPE_UTMI, - FS_PHY_TYPE_ULPI, + GHWCFG2_FSPHY_NOT_SUPPORTED = 0, + GHWCFG2_FSPHY_DEDICATED = 1, // have dedicated FS PHY + GHWCFG2_FSPHY_UTMI = 2, // shared with UTMI+ + GHWCFG2_FSPHY_ULPI = 3, // shared with ULPI }; enum { - GHWCFG2_ARCH_SLAVE_ONLY = 0, - GHWCFG2_ARCH_EXTERNAL_DMA, // 1 - GHWCFG2_ARCH_INTERNAL_DMA, // 2 + GHWCFFG4_PHY_DATA_WIDTH_8 = 0, + GHWCFFG4_PHY_DATA_WIDTH_16 = 1, + GHWCFFG4_PHY_DATA_WIDTH_8_16 = 2, // software selectable }; //-------------------------------------------------------------------- // Register bitfield definitions //-------------------------------------------------------------------- typedef struct TU_ATTR_PACKED { - uint32_t op_mode : 3; // 0: HNP and SRP | 1: SRP | 2: non-HNP, non-SRP - uint32_t arch : 2; // 0: slave-only | 1: External DMA | 2: Internal DMA | 3: others - uint32_t point2point : 1; // 0: support hub and split | 1: no hub, no split - uint32_t hs_phy_type : 2; // 0: not supported | 1: UTMI+ | 2: ULPI | 3: UTMI+ and ULPI - uint32_t fs_phy_type : 2; // 0: not supported | 1: dedicated | 2: UTMI+ | 3: ULPI - uint32_t num_dev_ep : 4; // Number of device endpoints (not including EP0) - uint32_t num_host_ch : 4; // Number of host channel - uint32_t period_channel_support : 1; // Support Periodic OUT Host Channel - uint32_t enable_dynamic_fifo : 1; // Dynamic FIFO Sizing Enabled - uint32_t mul_cpu_int : 1; // Multi-Processor Interrupt Enabled - uint32_t reserved21 : 1; - uint32_t nperiod_tx_q_depth : 2; // Non-periodic request queue depth: 0 = 2. 1 = 4, 2 = 8 - uint32_t host_period_tx_q_depth : 2; // Host periodic request queue depth: 0 = 2. 1 = 4, 2 = 8 - uint32_t dev_token_q_depth : 5; // Device IN token sequence learning queue depth: 0-30 - uint32_t otg_enable_ic_usb : 1; // IC_USB mode specified for mode of operation -} dwc2_ghwcfg2_t; -TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg2_t) == 4, "incorrect size"); - -typedef struct TU_ATTR_PACKED { - uint32_t xfer_size_width : 4; // Transfer size counter in bits = 11 + n (max 19 bits) - uint32_t packet_size_width : 3; // Packet size counter in bits = 4 + n (max 10 bits) - uint32_t otg_enable : 1; // 1 is OTG capable - uint32_t i2c_enable : 1; // I2C interface is available - uint32_t vendor_ctrl_itf : 1; // Vendor control interface is available - uint32_t optional_feature_removed : 1; // remove User ID, GPIO, SOF toggle & counter - uint32_t synch_reset : 1; // 0: async reset | 1: synch reset - uint32_t otg_adp_support : 1; // ADP logic is present along with HSOTG controller - uint32_t otg_enable_hsic : 1; // 1: HSIC-capable with shared UTMI PHY interface | 0: non-HSIC - uint32_t battery_charger_support : 1; // support battery charger - uint32_t lpm_mode : 1; // LPC mode - uint32_t dfifo_depth : 16; // DFIFO depth - EP_LOC_CNT in terms of 32-bit words -}dwc2_ghwcfg3_t; -TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg3_t) == 4, "incorrect size"); - -typedef struct TU_ATTR_PACKED { - uint32_t num_dev_period_in_ep : 4; // Number of Device Periodic IN Endpoints - uint32_t power_optimized : 1; // Partial Power Down Enabled - uint32_t ahb_freq_min : 1; // 1: minimum of AHB frequency is less than 60 MHz - uint32_t hibernation : 1; // Hibernation feature is enabled - uint32_t reserved7 : 3; - uint32_t service_interval_mode : 1; // Service Interval supported - uint32_t ipg_isoc_en : 1; // IPG ISOC supported - uint32_t acg_enable : 1; // ACG enabled - uint32_t reserved13 : 1; - uint32_t utmi_phy_data_width : 2; // 0: 8 bits | 1: 16 bits | 2: 8/16 software selectable - uint32_t dev_ctrl_ep_num : 4; // Number of Device control endpoints in addition to EP0 - uint32_t iddg_filter_enabled : 1; - uint32_t vbus_valid_filter_enabled : 1; - uint32_t a_valid_filter_enabled : 1; - uint32_t b_valid_filter_enabled : 1; - uint32_t dedicated_fifos : 1; // Dedicated tx fifo for device IN Endpoint is enabled - uint32_t num_dev_in_eps : 4; // Number of Device IN Endpoints including EP0 - uint32_t dma_desc_enable : 1; // scatter/gather DMA configuration - uint32_t dma_dynamic : 1; // Dynamic scatter/gather DMA -}dwc2_ghwcfg4_t; -TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg4_t) == 4, "incorrect size"); - -typedef struct TU_ATTR_PACKED { - uint32_t ses_req_scs : 1; // 0: Session request success - uint32_t ses_req : 1; // 1: Session request - uint32_t vbval_ov_en : 1; // 2: VBUS valid override enable - uint32_t vbval_ov_val : 1; // 3: VBUS valid override value - uint32_t aval_ov_en : 1; // 4: A-peripheral session valid override enable - uint32_t aval_ov_al : 1; // 5: A-peripheral session valid override value - uint32_t bval_ov_en : 1; // 6: B-peripheral session valid override enable - uint32_t bval_ov_val : 1; // 7: B-peripheral session valid override value - uint32_t hng_scs : 1; // 8: Host negotiation success - uint32_t hnp_rq : 1; // 9: HNP (host negotiation protocol) request - uint32_t host_set_hnp_en : 1; // 10: Host set HNP enable - uint32_t dev_hnp_en : 1; // 11: Device HNP enabled - uint32_t embedded_host_en : 1; // 12: Embedded host enable - uint32_t rsv13_14 : 2; // 13..14: Reserved - uint32_t dbnc_filter_bypass : 1; // 15: Debounce filter bypass - uint32_t cid_status : 1; // 16: Connector ID status - uint32_t dbnc_done : 1; // 17: Debounce done - uint32_t ases_valid : 1; // 18: A-session valid - uint32_t bses_valid : 1; // 19: B-session valid - uint32_t otg_ver : 1; // 20: OTG version 0: v1.3, 1: v2.0 - uint32_t current_mode : 1; // 21: Current mode of operation 0: device, 1: host - uint32_t mult_val_id_bc : 5; // 22..26: Multi-valued input pin ID battery charger - uint32_t chirp_en : 1; // 27: Chirp detection enable - uint32_t rsv28_30 : 3; // 28..30: Reserved - uint32_t test_mode_corr_eusb2 : 1; // 31: Test mode control for eUSB2 PHY + uint32_t ses_req_scs : 1; // 0 Session request success + uint32_t ses_req : 1; // 1 Session request + uint32_t vbval_ov_en : 1; // 2 VBUS valid override enable + uint32_t vbval_ov_val : 1; // 3 VBUS valid override value + uint32_t aval_ov_en : 1; // 4 A-peripheral session valid override enable + uint32_t aval_ov_al : 1; // 5 A-peripheral session valid override value + uint32_t bval_ov_en : 1; // 6 B-peripheral session valid override enable + uint32_t bval_ov_val : 1; // 7 B-peripheral session valid override value + uint32_t hng_scs : 1; // 8 Host negotiation success + uint32_t hnp_rq : 1; // 9 HNP (host negotiation protocol) request + uint32_t host_set_hnp_en : 1; // 10 Host set HNP enable + uint32_t dev_hnp_en : 1; // 11 Device HNP enabled + uint32_t embedded_host_en : 1; // 12 Embedded host enable + uint32_t rsv13_14 : 2; // 13.14 Reserved + uint32_t dbnc_filter_bypass : 1; // 15 Debounce filter bypass + uint32_t cid_status : 1; // 16 Connector ID status + uint32_t dbnc_done : 1; // 17 Debounce done + uint32_t ases_valid : 1; // 18 A-session valid + uint32_t bses_valid : 1; // 19 B-session valid + uint32_t otg_ver : 1; // 20 OTG version 0: v1.3, 1: v2.0 + uint32_t current_mode : 1; // 21 Current mode of operation 0: device, 1: host + uint32_t mult_val_id_bc : 5; // 22..26 Multi-valued input pin ID battery charger + uint32_t chirp_en : 1; // 27 Chirp detection enable + uint32_t rsv28_30 : 3; // 28.30: Reserved + uint32_t test_mode_corr_eusb2 : 1; // 31 Test mode control for eUSB2 PHY } dwc2_gotgctl_t; TU_VERIFY_STATIC(sizeof(dwc2_gotgctl_t) == 4, "incorrect size"); typedef struct TU_ATTR_PACKED { - uint32_t rsv0_1 : 2; // 0..1 : Reserved - uint32_t ses_end_det : 1; // 2 : Session end detected - uint32_t rsv3_7 : 5; // 3..7 : Reserved - uint32_t srs_status_change : 1; // 8 : Session request success status change - uint32_t hns_status_change : 1; // 9 : Host negotiation success status change - uint32_t rsv10_16 : 7; // 10..16 : Reserved - uint32_t hng_det : 1; // 17 : Host negotiation detected - uint32_t adev_timeout_change : 1; // 18 : A-device timeout change - uint32_t dbnc_done : 1; // 19 : Debounce done - uint32_t mult_val_lp_change : 1; // 20 : Multi-valued input pin change - uint32_t rsv21_31 :11; // 21..31 : Reserved + uint32_t rsv0_1 : 2; // 0..1 Reserved + uint32_t ses_end_det : 1; // 2 Session end detected + uint32_t rsv3_7 : 5; // 3..7 Reserved + uint32_t srs_status_change : 1; // 8 Session request success status change + uint32_t hns_status_change : 1; // 9 Host negotiation success status change + uint32_t rsv10_16 : 7; // 10..16 Reserved + uint32_t hng_det : 1; // 17 Host negotiation detected + uint32_t adev_timeout_change : 1; // 18 A-device timeout change + uint32_t dbnc_done : 1; // 19 Debounce done + uint32_t mult_val_lp_change : 1; // 20 Multi-valued input pin change + uint32_t rsv21_31 :11; // 21..31 Reserved } dwc2_gotgint_t; TU_VERIFY_STATIC(sizeof(dwc2_gotgint_t) == 4, "incorrect size"); typedef struct TU_ATTR_PACKED { - uint32_t gintmask : 1; // 0: Global interrupt mask - uint32_t hbst_len : 4; // 1..4: Burst length/type - uint32_t dma_en : 1; // 5: DMA enable - uint32_t rsv6 : 1; // 6: Reserved - uint32_t nptxf_empty_lvl : 1; // 7: Non-periodic Tx FIFO empty level - uint32_t ptxf_empty_lvl : 1; // 8: Periodic Tx FIFO empty level - uint32_t rsv9_20 : 12; // 9..20: Reserved - uint32_t remote_mem_support : 1; // 21: Remote memory support - uint32_t notify_all_dma_write : 1; // 22: Notify all DMA writes - uint32_t ahb_single : 1; // 23: AHB single - uint32_t inv_desc_endian : 1; // 24: Inverse descriptor endian - uint32_t rsv25_31 : 7; // 25..31: Reserved + uint32_t gintmask : 1; // 0 Global interrupt mask + uint32_t hbst_len : 4; // 1..4 Burst length/type + uint32_t dma_en : 1; // 5 DMA enable + uint32_t rsv6 : 1; // 6 Reserved + uint32_t nptxf_empty_lvl : 1; // 7 Non-periodic Tx FIFO empty level + uint32_t ptxf_empty_lvl : 1; // 8 Periodic Tx FIFO empty level + uint32_t rsv9_20 : 12; // 9.20: Reserved + uint32_t remote_mem_support : 1; // 21 Remote memory support + uint32_t notify_all_dma_write : 1; // 22 Notify all DMA writes + uint32_t ahb_single : 1; // 23 AHB single + uint32_t inv_desc_endian : 1; // 24 Inverse descriptor endian + uint32_t rsv25_31 : 7; // 25..31 Reserved } dwc2_gahbcfg_t; TU_VERIFY_STATIC(sizeof(dwc2_gahbcfg_t) == 4, "incorrect size"); typedef struct TU_ATTR_PACKED { - uint32_t timeout_cal : 3; /* 0..2: Timeout calibration. + uint32_t timeout_cal : 3; /* 0..2 Timeout calibration. The USB standard timeout value for high-speed operation is 736 to 816 (inclusive) bit times. The USB standard timeout value for full- speed operation is 16 to 18 (inclusive) bit times. The application must program this field based on the speed of enumeration. The number of bit times added per PHY clock are as follows: - High-speed: PHY clock One 30-MHz = 16 bit times, One 60-MHz = 8 bit times - Full-speed: PHY clock One 30-MHz = 0.4 bit times, One 60-MHz = 0.2 bit times, One 48-MHz = 0.25 bit times */ - uint32_t phy_if : 1; // 3: PHY interface. 0: 8 bits, 1: 16 bits - uint32_t ulpi_utmi_sel : 1; // 4: ULPI/UTMI select. 0: UTMI+, 1: ULPI - uint32_t fs_intf_sel : 1; // 5: Fullspeed serial interface select. 0: 6-pin, 1: 3-pin - uint32_t phy_sel : 1; // 6: HS/FS PHY selection. 0: HS UTMI+ or ULPI, 1: FS serial transceiver - uint32_t ddr_sel : 1; // 7 ULPI DDR select. 0: Single data rate 8-bit, 1: Double data rate 4-bit - uint32_t srp_capable : 1; // 8: SRP-capable - uint32_t hnp_capable : 1; // 9: HNP-capable - uint32_t turnaround_time : 4; // 10..13 Turnaround time. 9: 8-bit UTMI+, 5: 16-bit UTMI+ - uint32_t rsv14 : 1; // 14: Reserved - uint32_t phy_low_power_clk_sel : 1; /* 15: PHY low-power clock select either 480-MHz or 48-MHz (low-power) PHY mode. + uint32_t phy_if : 1; // 3 PHY interface. 0: 8 bits, 1: 16 bits + uint32_t ulpi_utmi_sel : 1; // 4 ULPI/UTMI select. 0: UTMI+, 1: ULPI + uint32_t fs_intf_sel : 1; // 5 Fullspeed serial interface select. 0: 6-pin, 1: 3-pin + uint32_t phy_sel : 1; // 6 HS/FS PHY selection. 0: HS UTMI+ or ULPI, 1: FS serial transceiver + uint32_t ddr_sel : 1; // 7 ULPI DDR select. 0: Single data rate 8-bit, 1: Double data rate 4-bit + uint32_t srp_capable : 1; // 8 SRP-capable + uint32_t hnp_capable : 1; // 9 HNP-capable + uint32_t turnaround_time : 4; // 10..13 Turnaround time. 9: 8-bit UTMI+, 5: 16-bit UTMI+ + uint32_t rsv14 : 1; // 14 Reserved + uint32_t phy_low_power_clk_sel : 1; /* 15 PHY low-power clock select either 480-MHz or 48-MHz (low-power) PHY mode. In FS/LS modes, the PHY can usually operate on a 48-MHz clock to save power. This bit is valid only for UTMI+ PHYs. - 0: 480 Mhz internal PLL: the UTMI interface operates at either 60 MHz (8 bit) or 30 MHz (16-bit) - 1 48 Mhz external clock: the UTMI interface operates at 48 MHz in FS mode and at either 48 or 6 MHz in LS mode */ - uint32_t otg_i2c_sel : 1; // 16: OTG I2C interface select. 0: UTMI-FS, 1: I2C for OTG signals - uint32_t ulpi_fsls : 1; /* 17: ULPI FS/LS select. 0: ULPI, 1: ULPI FS/LS. - valid only when the FS serial transceiver is selected on the ULPI PHY. */ - uint32_t ulpi_auto_resume : 1; // 18: ULPI Auto-resume - uint32_t ulpi_clk_sus_m : 1; // 19: ULPI Clock SuspendM - uint32_t ulpi_ext_vbus_drv : 1; // 20: ULPI External VBUS Drive - uint32_t ulpi_int_vbus_indicator : 1; // 21: ULPI Internal VBUS Indicator - uint32_t term_sel_dl_pulse : 1; // 22: TermSel DLine pulsing - uint32_t indicator_complement : 1; // 23: Indicator complement - uint32_t indicator_pass_through : 1; // 24: Indicator pass through - uint32_t ulpi_if_protect_disable : 1; // 25: ULPI interface protect disable - uint32_t ic_usb_capable : 1; // 26: IC_USB Capable - uint32_t ic_usb_traf_ctl : 1; // 27: IC_USB Traffic Control - uint32_t tx_end_delay : 1; // 28: TX end delay - uint32_t force_host_mode : 1; // 29: Force host mode - uint32_t force_dev_mode : 1; // 30: Force device mode - uint32_t corrupt_tx_pkt : 1; // 31: Corrupt Tx packet. 0: normal, 1: debug + uint32_t otg_i2c_sel : 1; // 16 OTG I2C interface select. 0: UTMI-FS, 1: I2C for OTG signals + uint32_t ulpi_fsls : 1; /* 17 ULPI FS/LS select. 0: ULPI, 1: ULPI FS/LS. + valid only when the FS serial transceiver is selected on the ULPI PHY. */ + uint32_t ulpi_auto_resume : 1; // 18 ULPI Auto-resume + uint32_t ulpi_clk_sus_m : 1; // 19 ULPI Clock SuspendM + uint32_t ulpi_ext_vbus_drv : 1; // 20 ULPI External VBUS Drive + uint32_t ulpi_int_vbus_indicator : 1; // 21 ULPI Internal VBUS Indicator + uint32_t term_sel_dl_pulse : 1; // 22 TermSel DLine pulsing + uint32_t indicator_complement : 1; // 23 Indicator complement + uint32_t indicator_pass_through : 1; // 24 Indicator pass through + uint32_t ulpi_if_protect_disable : 1; // 25 ULPI interface protect disable + uint32_t ic_usb_capable : 1; // 26 IC_USB Capable + uint32_t ic_usb_traf_ctl : 1; // 27 IC_USB Traffic Control + uint32_t tx_end_delay : 1; // 28 TX end delay + uint32_t force_host_mode : 1; // 29 Force host mode + uint32_t force_dev_mode : 1; // 30 Force device mode + uint32_t corrupt_tx_pkt : 1; // 31 Corrupt Tx packet. 0: normal, 1: debug } dwc2_gusbcfg_t; TU_VERIFY_STATIC(sizeof(dwc2_gusbcfg_t) == 4, "incorrect size"); +typedef struct TU_ATTR_PACKED { + uint32_t core_soft_rst : 1; // 0 Core Soft Reset + uint32_t piufs_soft_rst : 1; // 1 PIU FS Dedicated Controller Soft Reset + uint32_t frame_counter_rst : 1; // 2 Frame Counter Reset (host) + uint32_t intoken_q_flush : 1; // 3 IN Token Queue Flush + uint32_t rx_fifo_flush : 1; // 4 RX FIFO Flush + uint32_t tx_fifo_flush : 1; // 5 TX FIFO Flush + uint32_t tx_fifo_num : 5; // 6..10 TX FIFO Number + uint32_t rsv11_28 :18; // 11..28 Reserved + uint32_t core_soft_rst_done : 1; // 29 Core Soft Reset Done, from v4.20a + uint32_t dma_req : 1; // 30 DMA Request + uint32_t ahb_idle : 1; // 31 AHB Idle +} dwc2_grstctl_t; +TU_VERIFY_STATIC(sizeof(dwc2_grstctl_t) == 4, "incorrect size"); + +typedef struct TU_ATTR_PACKED { + uint32_t op_mode : 3; // 0..2 HNP/SRP Host/Device/OTG mode + uint32_t arch : 2; // 3..4 Slave/External/Internal DMA + uint32_t point2point : 1; // 5 0: support hub and split | 1: no hub, no split + uint32_t hs_phy_type : 2; // 6..7 0: not supported | 1: UTMI+ | 2: ULPI | 3: UTMI+ and ULPI + uint32_t fs_phy_type : 2; // 8..9 0: not supported | 1: dedicated | 2: UTMI+ | 3: ULPI + uint32_t num_dev_ep : 4; // 10..13 Number of device endpoints (excluding EP0) + uint32_t num_host_ch : 4; // 14..17 Number of host channel (excluding control) + uint32_t period_channel_support : 1; // 18 Support Periodic OUT Host Channel + uint32_t enable_dynamic_fifo : 1; // 19 Dynamic FIFO Sizing Enabled + uint32_t mul_cpu_int : 1; // 20 Multi-Processor Interrupt Enabled + uint32_t reserved21 : 1; // 21 reserved + uint32_t nptx_q_depth : 2; // 22..23 Non-periodic request queue depth: 0 = 2. 1 = 4, 2 = 8 + uint32_t ptx_q_depth : 2; // 24..25 Host periodic request queue depth: 0 = 2. 1 = 4, 2 = 8 + uint32_t token_q_depth : 5; // 26..30 Device IN token sequence learning queue depth: 0-30 + uint32_t otg_enable_ic_usb : 1; // 31 IC_USB mode specified for mode of operation +} dwc2_ghwcfg2_t; +TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg2_t) == 4, "incorrect size"); + +typedef struct TU_ATTR_PACKED { + uint32_t xfer_size_width : 4; // 0..3 Transfer size counter in bits = 11 + n (max 19 bits) + uint32_t packet_size_width : 3; // 4..6 Packet size counter in bits = 4 + n (max 10 bits) + uint32_t otg_enable : 1; // 7 OTG capable + uint32_t i2c_enable : 1; // 8 I2C interface is available + uint32_t vendor_ctrl_itf : 1; // 9 Vendor control interface is available + uint32_t optional_feature_removed : 1; // 10 remove User ID, GPIO, SOF toggle & counter to save gate count + uint32_t synch_reset : 1; // 11 0: async reset | 1: synch reset + uint32_t otg_adp_support : 1; // 12 ADP logic is present along with HSOTG controller + uint32_t otg_enable_hsic : 1; // 13 1: HSIC-capable with shared UTMI PHY interface | 0: non-HSIC + uint32_t battery_charger_support : 1; // s14 upport battery charger + uint32_t lpm_mode : 1; // 15 LPM mode + uint32_t dfifo_depth : 16; // DFIFO depth - EP_LOC_CNT in terms of 32-bit words +}dwc2_ghwcfg3_t; +TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg3_t) == 4, "incorrect size"); + +typedef struct TU_ATTR_PACKED { + uint32_t num_dev_period_in_ep : 4; // 0..3 Number of Device Periodic IN Endpoints + uint32_t partial_powerdown : 1; // 4 Partial Power Down Enabled + uint32_t ahb_freq_min : 1; // 5 1: minimum of AHB frequency is less than 60 MHz + uint32_t hibernation : 1; // 6 Hibernation feature is enabled + uint32_t extended_hibernation : 1; // 7 Extended Hibernation feature is enabled + uint32_t reserved8 : 1; // 8 Reserved + uint32_t enhanced_lpm_support1 : 1; // 9 Enhanced LPM Support1 + uint32_t service_interval_flow : 1; // 10 Service Interval flow is supported + uint32_t ipg_isoc_support : 1; // 11 Interpacket GAP ISO OUT worst-case is supported + uint32_t acg_support : 1; // 12 Active clock gating is supported + uint32_t enhanced_lpm_support : 1; // 13 Enhanced LPM Support + uint32_t phy_data_width : 2; // 14..15 0: 8 bits | 1: 16 bits | 2: 8/16 software selectable + uint32_t ctrl_ep_num : 4; // 16..19 Number of Device control endpoints in addition to EP0 + uint32_t iddg_filter : 1; // 20 IDDG Filter Enabled + uint32_t vbus_valid_filter : 1; // 21 VBUS Valid Filter Enabled + uint32_t a_valid_filter : 1; // 22 A Valid Filter Enabled + uint32_t b_valid_filter : 1; // 23 B Valid Filter Enabled + uint32_t session_end_filter : 1; // 24 Session End Filter Enabled + uint32_t dedicated_fifos : 1; // 25 Dedicated tx fifo for device IN Endpoint + uint32_t num_dev_in_eps : 4; // 26..29 Number of Device IN Endpoints including EP0 + uint32_t dma_desc_enabled : 1; // scatter/gather DMA configuration enabled + uint32_t dma_desc_dynamic : 1; // Dynamic scatter/gather DMA +}dwc2_ghwcfg4_t; +TU_VERIFY_STATIC(sizeof(dwc2_ghwcfg4_t) == 4, "incorrect size"); + // Host Channel typedef struct { volatile uint32_t hcchar; // 500 + 20*ch Host Channel Characteristics @@ -306,103 +340,103 @@ typedef struct { // CSR Register Map //-------------------------------------------------------------------- typedef struct { - //------------- Core Global -------------// - volatile uint32_t gotgctl; // 000 OTG Control and Status - volatile uint32_t gotgint; // 004 OTG Interrupt - volatile uint32_t gahbcfg; // 008 AHB Configuration - volatile uint32_t gusbcfg; // 00c USB Configuration - volatile uint32_t grstctl; // 010 Reset - volatile uint32_t gintsts; // 014 Interrupt - volatile uint32_t gintmsk; // 018 Interrupt Mask - volatile uint32_t grxstsr; // 01c Receive Status Debug Read - volatile uint32_t grxstsp; // 020 Receive Status Read/Pop - volatile uint32_t grxfsiz; // 024 Receive FIFO Size -union { - volatile uint32_t dieptxf0; // 028 EP0 Tx FIFO Size - volatile uint32_t gnptxfsiz; // 028 Non-periodic Transmit FIFO Size -}; - volatile uint32_t gnptxsts; // 02c Non-periodic Transmit FIFO/Queue Status - volatile uint32_t gi2cctl; // 030 I2C Address - volatile uint32_t gpvndctl; // 034 PHY Vendor Control -union { - volatile uint32_t ggpio; // 038 General Purpose IO - volatile uint32_t stm32_gccfg; // 038 STM32 General Core Configuration -}; - volatile uint32_t guid; // 03C User (Application programmable) ID - volatile uint32_t gsnpsid; // 040 Synopsys ID + Release version - volatile uint32_t ghwcfg1; // 044 User Hardware Configuration1: endpoint dir (2 bit per ep) -union { - volatile uint32_t ghwcfg2; // 048 User Hardware Configuration2 - volatile dwc2_ghwcfg2_t ghwcfg2_bm; -}; -union { - volatile uint32_t ghwcfg3; // 04C User Hardware Configuration3 - volatile dwc2_ghwcfg3_t ghwcfg3_bm; -}; -union { - volatile uint32_t ghwcfg4; // 050 User Hardware Configuration4 - volatile dwc2_ghwcfg4_t ghwcfg4_bm; -}; - volatile uint32_t glpmcfg; // 054 Core LPM Configuration - volatile uint32_t gpwrdn; // 058 Power Down - volatile uint32_t gdfifocfg; // 05C DFIFO Software Configuration - volatile uint32_t gadpctl; // 060 ADP Timer, Control and Status - uint32_t reserved64[39]; // 064..0FF - volatile uint32_t hptxfsiz; // 100 Host Periodic Tx FIFO Size - volatile uint32_t dieptxf[15]; // 104..13C Device Periodic Transmit FIFO Size - uint32_t reserved140[176]; // 140..3FF - - //------------- Host -------------// - volatile uint32_t hcfg; // 400 Host Configuration - volatile uint32_t hfir; // 404 Host Frame Interval - volatile uint32_t hfnum; // 408 Host Frame Number / Frame Remaining - uint32_t reserved40c; // 40C - volatile uint32_t hptxsts; // 410 Host Periodic TX FIFO / Queue Status - volatile uint32_t haint; // 414 Host All Channels Interrupt - volatile uint32_t haintmsk; // 418 Host All Channels Interrupt Mask - volatile uint32_t hflbaddr; // 41C Host Frame List Base Address - uint32_t reserved420[8]; // 420..43F - volatile uint32_t hprt; // 440 Host Port Control and Status - uint32_t reserved444[47]; // 444..4FF - - //------------- Host Channel -------------// - dwc2_channel_t channel[16]; // 500..6FF Host Channels 0-15 - uint32_t reserved700[64]; // 700..7FF - - //------------- Device -------------// - volatile uint32_t dcfg; // 800 Device Configuration - volatile uint32_t dctl; // 804 Device Control - volatile uint32_t dsts; // 808 Device Status (RO) - uint32_t reserved80c; // 80C - volatile uint32_t diepmsk; // 810 Device IN Endpoint Interrupt Mask - volatile uint32_t doepmsk; // 814 Device OUT Endpoint Interrupt Mask - volatile uint32_t daint; // 818 Device All Endpoints Interrupt - volatile uint32_t daintmsk; // 81C Device All Endpoints Interrupt Mask - volatile uint32_t dtknqr1; // 820 Device IN token sequence learning queue read1 - volatile uint32_t dtknqr2; // 824 Device IN token sequence learning queue read2 - volatile uint32_t dvbusdis; // 828 Device VBUS Discharge Time - volatile uint32_t dvbuspulse; // 82C Device VBUS Pulsing Time - volatile uint32_t dthrctl; // 830 Device threshold Control - volatile uint32_t diepempmsk; // 834 Device IN Endpoint FIFO Empty Interrupt Mask - volatile uint32_t deachint; // 838 Device Each Endpoint Interrupt - volatile uint32_t deachmsk; // 83C Device Each Endpoint Interrupt msk - volatile uint32_t diepeachmsk[16]; // 840..87C Device Each IN Endpoint mask - volatile uint32_t doepeachmsk[16]; // 880..8BF Device Each OUT Endpoint mask - uint32_t reserved8c0[16]; // 8C0..8FF - - //------------- Device Endpoint -------------// - dwc2_epin_t epin[16]; // 900..AFF IN Endpoints - dwc2_epout_t epout[16]; // B00..CFF OUT Endpoints - uint32_t reservedd00[64]; // D00..DFF - - //------------- Power Clock -------------// - volatile uint32_t pcgctl; // E00 Power and Clock Gating Control - volatile uint32_t pcgctl1; // E04 - uint32_t reservede08[126]; // E08..FFF - - //------------- FIFOs -------------// - // Word-accessed only using first pointer since it auto shift - volatile uint32_t fifo[16][0x400]; // 1000..FFFF Endpoint FIFO + //------------- Core Global -------------// + volatile uint32_t gotgctl; // 000 OTG Control and Status + volatile uint32_t gotgint; // 004 OTG Interrupt + volatile uint32_t gahbcfg; // 008 AHB Configuration + volatile uint32_t gusbcfg; // 00c USB Configuration + volatile uint32_t grstctl; // 010 Reset + volatile uint32_t gintsts; // 014 Interrupt + volatile uint32_t gintmsk; // 018 Interrupt Mask + volatile uint32_t grxstsr; // 01c Receive Status Debug Read + volatile uint32_t grxstsp; // 020 Receive Status Read/Pop + volatile uint32_t grxfsiz; // 024 Receive FIFO Size + union { + volatile uint32_t dieptxf0; // 028 EP0 Tx FIFO Size + volatile uint32_t gnptxfsiz; // 028 Non-periodic Transmit FIFO Size + }; + volatile uint32_t gnptxsts; // 02c Non-periodic Transmit FIFO/Queue Status + volatile uint32_t gi2cctl; // 030 I2C Address + volatile uint32_t gpvndctl; // 034 PHY Vendor Control + union { + volatile uint32_t ggpio; // 038 General Purpose IO + volatile uint32_t stm32_gccfg; // 038 STM32 General Core Configuration + }; + volatile uint32_t guid; // 03C User (Application programmable) ID + volatile uint32_t gsnpsid; // 040 Synopsys ID + Release version + volatile uint32_t ghwcfg1; // 044 User Hardware Configuration1: endpoint dir (2 bit per ep) + union { + volatile uint32_t ghwcfg2; // 048 User Hardware Configuration2 + volatile dwc2_ghwcfg2_t ghwcfg2_bm; + }; + union { + volatile uint32_t ghwcfg3; // 04C User Hardware Configuration3 + volatile dwc2_ghwcfg3_t ghwcfg3_bm; + }; + union { + volatile uint32_t ghwcfg4; // 050 User Hardware Configuration4 + volatile dwc2_ghwcfg4_t ghwcfg4_bm; + }; + volatile uint32_t glpmcfg; // 054 Core LPM Configuration + volatile uint32_t gpwrdn; // 058 Power Down + volatile uint32_t gdfifocfg; // 05C DFIFO Software Configuration + volatile uint32_t gadpctl; // 060 ADP Timer, Control and Status + uint32_t reserved64[39]; // 064..0FF + volatile uint32_t hptxfsiz; // 100 Host Periodic Tx FIFO Size + volatile uint32_t dieptxf[15]; // 104..13C Device Periodic Transmit FIFO Size + uint32_t reserved140[176]; // 140..3FF + + //------------ Host -------------// + volatile uint32_t hcfg; // 400 Host Configuration + volatile uint32_t hfir; // 404 Host Frame Interval + volatile uint32_t hfnum; // 408 Host Frame Number / Frame Remaining + uint32_t reserved40c; // 40C + volatile uint32_t hptxsts; // 410 Host Periodic TX FIFO / Queue Status + volatile uint32_t haint; // 414 Host All Channels Interrupt + volatile uint32_t haintmsk; // 418 Host All Channels Interrupt Mask + volatile uint32_t hflbaddr; // 41C Host Frame List Base Address + uint32_t reserved420[8]; // 420..43F + volatile uint32_t hprt; // 440 Host Port Control and Status + uint32_t reserved444[47]; // 444..4FF + + //------------- Host Channel -------------// + dwc2_channel_t channel[16]; // 500..6FF Host Channels 0-15 + uint32_t reserved700[64]; // 700..7FF + + //------------- Device -----------// + volatile uint32_t dcfg; // 800 Device Configuration + volatile uint32_t dctl; // 804 Device Control + volatile uint32_t dsts; // 808 Device Status (RO) + uint32_t reserved80c; // 80C + volatile uint32_t diepmsk; // 810 Device IN Endpoint Interrupt Mask + volatile uint32_t doepmsk; // 814 Device OUT Endpoint Interrupt Mask + volatile uint32_t daint; // 818 Device All Endpoints Interrupt + volatile uint32_t daintmsk; // 81C Device All Endpoints Interrupt Mask + volatile uint32_t dtknqr1; // 820 Device IN token sequence learning queue read1 + volatile uint32_t dtknqr2; // 824 Device IN token sequence learning queue read2 + volatile uint32_t dvbusdis; // 828 Device VBUS Discharge Time + volatile uint32_t dvbuspulse; // 82C Device VBUS Pulsing Time + volatile uint32_t dthrctl; // 830 Device threshold Control + volatile uint32_t diepempmsk; // 834 Device IN Endpoint FIFO Empty Interrupt Mask + volatile uint32_t deachint; // 838 Device Each Endpoint Interrupt + volatile uint32_t deachmsk; // 83C Device Each Endpoint Interrupt msk + volatile uint32_t diepeachmsk[16]; // 840..87C Device Each IN Endpoint mask + volatile uint32_t doepeachmsk[16]; // 880..8BF Device Each OUT Endpoint mask + uint32_t reserved8c0[16]; // 8C0..8FF + + //------------- Device Endpoint -------------// + dwc2_epin_t epin[16]; // 900..AFF IN Endpoints + dwc2_epout_t epout[16]; // B00..CFF OUT Endpoints + uint32_t reservedd00[64]; // D00..DFF + + //------------- Power Clock -------------// + volatile uint32_t pcgctl; // E00 Power and Clock Gating Control + volatile uint32_t pcgctl1; // E04 + uint32_t reservede08[126]; // E08..FFF + + //------------- FIFOs -------------// + // Word-accessed only using first pointer since it auto shift + volatile uint32_t fifo[16][0x400]; // 1000..FFFF Endpoint FIFO } dwc2_regs_t; TU_VERIFY_STATIC(offsetof(dwc2_regs_t, hcfg ) == 0x0400, "incorrect size"); -- cgit v1.3.1 From 67e5577b428e70878d99c4f83039cef020a272cb Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 25 Sep 2024 20:36:16 +0700 Subject: added p4, seems to work well and enumerated --- .idea/cmake.xml | 9 +- .../boards/espressif_p4_function_ev/board.cmake | 2 + .../boards/espressif_p4_function_ev/board.h | 43 ++++++++ hw/bsp/espressif/family.cmake | 3 + src/common/tusb_mcu.h | 6 +- src/portable/synopsys/dwc2/dcd_dwc2.c | 23 ++-- src/portable/synopsys/dwc2/dwc2_esp32.h | 48 +++++++-- src/portable/synopsys/dwc2/dwc2_info.md | 116 ++++++++++----------- src/portable/synopsys/dwc2/dwc2_info.py | 1 + 9 files changed, 164 insertions(+), 87 deletions(-) create mode 100644 hw/bsp/espressif/boards/espressif_p4_function_ev/board.cmake create mode 100644 hw/bsp/espressif/boards/espressif_p4_function_ev/board.h (limited to 'src/portable') diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 96ff19c89..b6a237a1d 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -37,7 +37,7 @@ - + @@ -145,6 +145,13 @@ + + + + + + + \ No newline at end of file diff --git a/hw/bsp/espressif/boards/espressif_p4_function_ev/board.cmake b/hw/bsp/espressif/boards/espressif_p4_function_ev/board.cmake new file mode 100644 index 000000000..fe4db4fc1 --- /dev/null +++ b/hw/bsp/espressif/boards/espressif_p4_function_ev/board.cmake @@ -0,0 +1,2 @@ +# Apply board specific content here +set(IDF_TARGET "esp32p4") diff --git a/hw/bsp/espressif/boards/espressif_p4_function_ev/board.h b/hw/bsp/espressif/boards/espressif_p4_function_ev/board.h new file mode 100644 index 000000000..9c8aa409f --- /dev/null +++ b/hw/bsp/espressif/boards/espressif_p4_function_ev/board.h @@ -0,0 +1,43 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, 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. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// #define NEOPIXEL_PIN 48 + +#define BUTTON_PIN 0 +#define BUTTON_STATE_ACTIVE 0 + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/espressif/family.cmake b/hw/bsp/espressif/family.cmake index eb97401c3..b0786f1cc 100644 --- a/hw/bsp/espressif/family.cmake +++ b/hw/bsp/espressif/family.cmake @@ -8,4 +8,7 @@ string(TOUPPER ${IDF_TARGET} FAMILY_MCUS) # Add example src and bsp directories set(EXTRA_COMPONENT_DIRS "src" "${CMAKE_CURRENT_LIST_DIR}/boards" "${CMAKE_CURRENT_LIST_DIR}/components") +# set SDKCONFIG for each IDF Target +set(SDKCONFIG ${CMAKE_SOURCE_DIR}/sdkconfig.${IDF_TARGET}) + include($ENV{IDF_PATH}/tools/cmake/project.cmake) diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 26a8ee26b..6b19ac9fe 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -337,13 +337,13 @@ #elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_ESP32 - #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_DCD_ENDPOINT_MAX 7 // only 5 TX FIFO for endpoint IN #elif TU_CHECK_MCU(OPT_MCU_ESP32P4) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_ESP32 - #define TUP_RHPORT_HIGHSPEED 1 // 1 port FS, 1 port HS - #define TUP_DCD_ENDPOINT_MAX 8 // FS 6 ep, HS 8 ep + #define TUP_RHPORT_HIGHSPEED 1 // port0 FS, port1 HS + #define TUP_DCD_ENDPOINT_MAX 16 // FS 7 ep, HS 16 ep #elif TU_CHECK_MCU(OPT_MCU_ESP32, OPT_MCU_ESP32C2, OPT_MCU_ESP32C3, OPT_MCU_ESP32C6, OPT_MCU_ESP32H2) #if (CFG_TUD_ENABLED || !(defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421)) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 13143073d..d1eb22ed7 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -508,18 +508,6 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ -#if CFG_TUSB_DEBUG >= DWC2_DEBUG -void print_dwc2_info(dwc2_regs_t* dwc2) { - // print guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4 - // use dwc2_info.py/md for bit-field value and comparison with other ports - volatile uint32_t const* p = (volatile uint32_t const*) &dwc2->guid; - TU_LOG(DWC2_DEBUG, "guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4\r\n"); - for (size_t i = 0; i < 5; i++) { - TU_LOG(DWC2_DEBUG, "0x%08" PRIX32 ", ", p[i]); - } - TU_LOG(DWC2_DEBUG, "0x%08" PRIX32 "\r\n", p[5]); -} -#endif static void reset_core(dwc2_regs_t* dwc2) { // reset core @@ -633,8 +621,15 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { } static bool check_dwc2(dwc2_regs_t* dwc2) { -#if CFG_TUSB_DEBUG >= DWC2_DEBUG - print_dwc2_info(dwc2); +#if CFG_TUSB_DEBUG >= DWC2_DEBUG || 1 + // print guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4 + // Run 'dwc2_info.py render-md' and check dwc2_info.md for bit-field value and comparison with other ports + volatile uint32_t const* p = (volatile uint32_t const*) &dwc2->guid; + TU_LOG1("guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4\r\n"); + for (size_t i = 0; i < 5; i++) { + TU_LOG1("0x%08" PRIX32 ", ", p[i]); + } + TU_LOG1("0x%08" PRIX32 "\r\n", p[5]); #endif // For some reason: GD32VF103 snpsid and all hwcfg register are always zero (skip it) diff --git a/src/portable/synopsys/dwc2/dwc2_esp32.h b/src/portable/synopsys/dwc2/dwc2_esp32.h index 921cee29e..af04347d1 100644 --- a/src/portable/synopsys/dwc2/dwc2_esp32.h +++ b/src/portable/synopsys/dwc2/dwc2_esp32.h @@ -38,29 +38,55 @@ #include "soc/periph_defs.h" #include "soc/usb_wrap_struct.h" -#define DWC2_REG_BASE 0x60080000UL -#define DWC2_EP_MAX 7 -#define DWC2_EP_IN_MAX 5 +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#define DWC2_PERIPH_COUNT 1 +#define DWC2_FS_REG_BASE 0x60080000UL +#define DWC2_EP_MAX 7 static const dwc2_controller_t _dwc2_controller[] = { - { .reg_base = DWC2_REG_BASE, .irqnum = 0, .ep_count = DWC2_EP_MAX, .ep_in_count = DWC2_EP_IN_MAX, .ep_fifo_size = 1024 } + { .reg_base = DWC2_FS_REG_BASE, .irqnum = ETS_USB_INTR_SOURCE, .ep_count = 7, .ep_in_count = 5, .ep_fifo_size = 1024 } }; -static intr_handle_t usb_ih; +#elif TU_CHECK_MCU(OPT_MCU_ESP32P4) + +#define DWC2_PERIPH_COUNT 2 +#define DWC2_FS_REG_BASE 0x50040000UL +#define DWC2_HS_REG_BASE 0x50000000UL +#define DWC2_EP_MAX 16 + +// On ESP32 for consistency we associate +// - Port0 to OTG_FS, and Port1 to OTG_HS +static const dwc2_controller_t _dwc2_controller[] = { + { + .reg_base = DWC2_HS_REG_BASE, .irqnum = ETS_USB_OTG_INTR_SOURCE, .ep_count = 16, .ep_in_count = 8, + .ep_fifo_size = 4096 + }, +{ + .reg_base = DWC2_FS_REG_BASE, .irqnum = ETS_USB_OTG11_CH0_INTR_SOURCE, .ep_count = 7, .ep_in_count = 5, + .ep_fifo_size = 1024 +} + +}; +#endif + +enum { + DWC2_CONTROLLER_COUNT = TU_ARRAY_SIZE(_dwc2_controller) +}; + +static intr_handle_t usb_ih[DWC2_CONTROLLER_COUNT]; static void dcd_int_handler_wrap(void* arg) { - (void)arg; - dcd_int_handler(0); + const uint8_t rhport = (uint8_t) arg; + dcd_int_handler(rhport); } TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_enable(uint8_t rhport) { - (void)rhport; - esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, dcd_int_handler_wrap, NULL, &usb_ih); + esp_intr_alloc(_dwc2_controller[rhport].irqnum, ESP_INTR_FLAG_LOWMED, + dcd_int_handler_wrap, (void*) rhport, &usb_ih[rhport]); } TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_disable(uint8_t rhport) { - (void)rhport; - esp_intr_free(usb_ih); + esp_intr_free(usb_ih[rhport]); } TU_ATTR_ALWAYS_INLINE static inline void dwc2_remote_wakeup_delay(void) { diff --git a/src/portable/synopsys/dwc2/dwc2_info.md b/src/portable/synopsys/dwc2/dwc2_info.md index 9798fb0de..462b5856a 100644 --- a/src/portable/synopsys/dwc2/dwc2_info.md +++ b/src/portable/synopsys/dwc2/dwc2_info.md @@ -1,58 +1,58 @@ -| | BCM2711 (Pi4) | EFM32GG FS | ESP32-S2/S3 | STM32F 407/411/429 FS | STM32F 407/429 HS | STM32F 412/767 FS | STM32F723 FS | STM32F723 HS | STM32H743 HS | STM32L476 FS | STM32U5A5 HS | GD32VF103 FS | XMC4500 | -|:---------------------------|:----------------|:-------------|:--------------|:------------------------|:--------------------|:--------------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:-----------| -| guid | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 | -| gsnpsid | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A | -| - specs version | 2.80a | 3.30a | 4.00a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a | -| ghwcfg1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | -| ghwcfg2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 | -| - op_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | -| - arch | 2 | 2 | 2 | 0 | 2 | 0 | 0 | 2 | 2 | 0 | 2 | 0 | 2 | -| - point2point | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | -| - hs_phy_type | 1 | 0 | 0 | 0 | 2 | 0 | 0 | 3 | 2 | 0 | 1 | 0 | 0 | -| - fs_phy_type | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - num_dev_ep | 7 | 6 | 6 | 3 | 5 | 5 | 5 | 8 | 8 | 5 | 8 | 0 | 6 | -| - num_host_ch | 7 | 13 | 7 | 7 | 11 | 11 | 11 | 15 | 15 | 11 | 15 | 0 | 13 | -| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - mul_cpu_int | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - nptx_q_depth | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | -| - ptx_q_depth | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | -| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 | -| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| ghwcfg3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 | -| - xfer_size_width | 8 | 8 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 | -| - packet_size_width | 6 | 6 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 | -| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - i2c_enable | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | -| - vendor_ctrl_itf | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | -| - optional_feature_removed | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - synch_reset | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - otg_adp_support | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - battery_charger_support | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | -| - dfifo_depth | 4080 | 498 | 200 | 512 | 1012 | 512 | 512 | 1006 | 952 | 512 | 952 | 0 | 634 | -| ghwcfg4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 | -| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - partial_powerdown | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - enhanced_lpm_support | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - phy_data_width | 0 | 2 | 2 | 2 | 0 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 2 | -| - ctrl_ep_num | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - iddg_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - vbus_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - a_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - b_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - session_end_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - num_dev_in_eps | 7 | 6 | 4 | 3 | 5 | 5 | 5 | 8 | 8 | 5 | 8 | 0 | 6 | -| - dma_desc_enable | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | -| - dma_desc_dynamic | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | +| | BCM2711 (Pi4) | EFM32GG FS | ESP32-S2/S3 | ESP32-P4 | STM32F 407/411/429 FS | STM32F 407/429 HS | STM32F 412/767 FS | STM32F723 FS | STM32F723 HS | STM32H743 HS | STM32L476 FS | STM32U5A5 HS | GD32VF103 FS | XMC4500 | +|:---------------------------|:----------------|:-------------|:--------------|:-----------|:------------------------|:--------------------|:--------------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:-----------| +| guid | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 | +| gsnpsid | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A | +| - specs version | 2.80a | 3.30a | 4.00a | 4.00a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a | +| ghwcfg1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | +| ghwcfg2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x215FFFD0 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 | +| - op_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | +| - arch | 2 | 2 | 2 | 2 | 0 | 2 | 0 | 0 | 2 | 2 | 0 | 2 | 0 | 2 | +| - point2point | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | +| - hs_phy_type | 1 | 0 | 0 | 3 | 0 | 2 | 0 | 0 | 3 | 2 | 0 | 1 | 0 | 0 | +| - fs_phy_type | 1 | 1 | 1 | 3 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - num_dev_ep | 7 | 6 | 6 | 15 | 3 | 5 | 5 | 5 | 8 | 8 | 5 | 8 | 0 | 6 | +| - num_host_ch | 7 | 13 | 7 | 15 | 7 | 11 | 11 | 11 | 15 | 15 | 11 | 15 | 0 | 13 | +| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - mul_cpu_int | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - nptx_q_depth | 2 | 2 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | +| - ptx_q_depth | 2 | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | +| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 | +| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| ghwcfg3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x03805EB5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 | +| - xfer_size_width | 8 | 8 | 5 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 | +| - packet_size_width | 6 | 6 | 3 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 | +| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - i2c_enable | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | +| - vendor_ctrl_itf | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | +| - optional_feature_removed | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - synch_reset | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - otg_adp_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - battery_charger_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | +| - dfifo_depth | 4080 | 498 | 200 | 896 | 512 | 1012 | 512 | 512 | 1006 | 952 | 512 | 952 | 0 | 634 | +| ghwcfg4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0xDFF1A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 | +| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - partial_powerdown | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - enhanced_lpm_support | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - phy_data_width | 0 | 2 | 2 | 2 | 2 | 0 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 2 | +| - ctrl_ep_num | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - iddg_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - vbus_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - a_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - b_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - session_end_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - num_dev_in_eps | 7 | 6 | 4 | 7 | 3 | 5 | 5 | 5 | 8 | 8 | 5 | 8 | 0 | 6 | +| - dma_desc_enable | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | +| - dma_desc_dynamic | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | diff --git a/src/portable/synopsys/dwc2/dwc2_info.py b/src/portable/synopsys/dwc2/dwc2_info.py index 871ac112d..e382ba011 100644 --- a/src/portable/synopsys/dwc2/dwc2_info.py +++ b/src/portable/synopsys/dwc2/dwc2_info.py @@ -9,6 +9,7 @@ dwc2_reg_value = { 'BCM2711 (Pi4)': [0x2708A000, 0x4F54280A, 0, 0x228DDD50, 0xFF000E8, 0x1FF00020], 'EFM32GG FS': [0, 0x4F54330A, 0, 0x228F5910, 0x1F204E8, 0x1BF08030], 'ESP32-S2/S3': [0, 0x4F54400A, 0, 0x224DD930, 0xC804B5, 0xD3F0A030], + 'ESP32-P4': [0, 0x4F54400A, 0, 0x215FFFD0, 0x03805EB5, 0xDFF1A030], 'STM32F 407/411/429 FS': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x20001E8, 0xFF08030], 'STM32F 407/429 HS': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x3F403E8, 0x17F00030], 'STM32F 412/767 FS': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], -- cgit v1.3.1 From 87f199330405f0a51f8ad4b3b8b2d69c9a21ac3e Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 27 Sep 2024 15:32:47 +0700 Subject: esp32p4 use port0 as fs, port1 as highspeed --- .idea/cmake.xml | 16 +++++----- hw/bsp/espressif/boards/CMakeLists.txt | 2 -- .../components/tinyusb_src/CMakeLists.txt | 3 ++ hw/bsp/espressif/family.cmake | 10 +++++- src/portable/synopsys/dwc2/dcd_dwc2.c | 30 +++++++++++++----- src/portable/synopsys/dwc2/dwc2_esp32.h | 36 ++++++---------------- 6 files changed, 52 insertions(+), 45 deletions(-) (limited to 'src/portable') diff --git a/.idea/cmake.xml b/.idea/cmake.xml index b6a237a1d..37cd73c65 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -37,7 +37,7 @@ - + @@ -65,6 +65,13 @@ + + + + + + + @@ -145,13 +152,6 @@ - - - - - - - \ No newline at end of file diff --git a/hw/bsp/espressif/boards/CMakeLists.txt b/hw/bsp/espressif/boards/CMakeLists.txt index fe1273d4c..434f77704 100644 --- a/hw/bsp/espressif/boards/CMakeLists.txt +++ b/hw/bsp/espressif/boards/CMakeLists.txt @@ -4,5 +4,3 @@ idf_component_register(SRCS family.c INCLUDE_DIRS "." ${BOARD} ${hw_dir} PRIV_REQUIRES driver usb REQUIRES led_strip src tinyusb_src) - -target_compile_options(${COMPONENT_LIB} PRIVATE -Wno-error=format) diff --git a/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt b/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt index 8bdb3802e..26c7e4030 100644 --- a/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt +++ b/hw/bsp/espressif/components/tinyusb_src/CMakeLists.txt @@ -9,6 +9,9 @@ string(TOUPPER OPT_MCU_${target} tusb_mcu) list(APPEND compile_definitions CFG_TUSB_MCU=${tusb_mcu} CFG_TUSB_OS=OPT_OS_FREERTOS + # EXAMPLE port selection: port0 is fullspeed, port1 is highspeed + BOARD_TUD_RHPORT=${TUD_PORT} + BOARD_TUD_MAX_SPEED=$ ) list(APPEND srcs diff --git a/hw/bsp/espressif/family.cmake b/hw/bsp/espressif/family.cmake index b0786f1cc..ada082c76 100644 --- a/hw/bsp/espressif/family.cmake +++ b/hw/bsp/espressif/family.cmake @@ -2,9 +2,17 @@ cmake_minimum_required(VERSION 3.5) # Apply board specific content i.e IDF_TARGET must be set before project.cmake is included include("${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake") - string(TOUPPER ${IDF_TARGET} FAMILY_MCUS) +# Device port default to Port1 for P4 (highspeed), Port0 for others (fullspeed) +if (NOT DEFINED TUD_PORT) + if (IDF_TARGET STREQUAL "esp32p4") + set(TUD_PORT 1) + else () + set(TUD_PORT 0) + endif () +endif() + # Add example src and bsp directories set(EXTRA_COMPONENT_DIRS "src" "${CMAKE_CURRENT_LIST_DIR}/boards" "${CMAKE_CURRENT_LIST_DIR}/components") diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index d1eb22ed7..4fa869241 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -31,6 +31,9 @@ #if CFG_TUD_ENABLED && defined(TUP_USBIP_DWC2) +// Debug level for DWC2 +#define DWC2_DEBUG 2 + #include "device/dcd.h" #include "dwc2_type.h" @@ -57,15 +60,24 @@ #error "Unsupported MCUs" #endif -//--------------------------------------------------------------------+ -// MACRO TYPEDEF CONSTANT ENUM -//--------------------------------------------------------------------+ +enum { + DWC2_CONTROLLER_COUNT = TU_ARRAY_SIZE(_dwc2_controller) +}; // DWC2 registers -#define DWC2_REG(_port) ((dwc2_regs_t*) _dwc2_controller[_port].reg_base) +//#define DWC2_REG(_port) ((dwc2_regs_t*) _dwc2_controller[_port].reg_base) -// Debug level for DWC2 -#define DWC2_DEBUG 2 +TU_ATTR_ALWAYS_INLINE static inline dwc2_regs_t* DWC2_REG(uint8_t rhport) { + if (rhport >= DWC2_CONTROLLER_COUNT) { + // user mis-configured, ignore and use first controller + rhport = 0; + } + return (dwc2_regs_t*) _dwc2_controller[rhport].reg_base; +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ static CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2]; @@ -584,7 +596,9 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { gusbcfg &= ~(GUSBCFG_ULPI_UTMI_SEL | GUSBCFG_PHYIF16); // Set 16-bit interface if supported - if (dwc2->ghwcfg4_bm.phy_data_width) gusbcfg |= GUSBCFG_PHYIF16; + if (dwc2->ghwcfg4_bm.phy_data_width) { + gusbcfg |= GUSBCFG_PHYIF16; + } } // Apply config @@ -621,7 +635,7 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { } static bool check_dwc2(dwc2_regs_t* dwc2) { -#if CFG_TUSB_DEBUG >= DWC2_DEBUG || 1 +#if CFG_TUSB_DEBUG >= DWC2_DEBUG // print guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4 // Run 'dwc2_info.py render-md' and check dwc2_info.md for bit-field value and comparison with other ports volatile uint32_t const* p = (volatile uint32_t const*) &dwc2->guid; diff --git a/src/portable/synopsys/dwc2/dwc2_esp32.h b/src/portable/synopsys/dwc2/dwc2_esp32.h index af04347d1..4cdbcdb7a 100644 --- a/src/portable/synopsys/dwc2/dwc2_esp32.h +++ b/src/portable/synopsys/dwc2/dwc2_esp32.h @@ -39,50 +39,36 @@ #include "soc/usb_wrap_struct.h" #if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) -#define DWC2_PERIPH_COUNT 1 -#define DWC2_FS_REG_BASE 0x60080000UL -#define DWC2_EP_MAX 7 +#define DWC2_FS_REG_BASE 0x60080000UL +#define DWC2_EP_MAX 7 static const dwc2_controller_t _dwc2_controller[] = { { .reg_base = DWC2_FS_REG_BASE, .irqnum = ETS_USB_INTR_SOURCE, .ep_count = 7, .ep_in_count = 5, .ep_fifo_size = 1024 } }; #elif TU_CHECK_MCU(OPT_MCU_ESP32P4) - -#define DWC2_PERIPH_COUNT 2 -#define DWC2_FS_REG_BASE 0x50040000UL -#define DWC2_HS_REG_BASE 0x50000000UL -#define DWC2_EP_MAX 16 +#define DWC2_FS_REG_BASE 0x50040000UL +#define DWC2_HS_REG_BASE 0x50000000UL +#define DWC2_EP_MAX 16 // On ESP32 for consistency we associate // - Port0 to OTG_FS, and Port1 to OTG_HS static const dwc2_controller_t _dwc2_controller[] = { - { - .reg_base = DWC2_HS_REG_BASE, .irqnum = ETS_USB_OTG_INTR_SOURCE, .ep_count = 16, .ep_in_count = 8, - .ep_fifo_size = 4096 - }, -{ - .reg_base = DWC2_FS_REG_BASE, .irqnum = ETS_USB_OTG11_CH0_INTR_SOURCE, .ep_count = 7, .ep_in_count = 5, - .ep_fifo_size = 1024 -} - +{ .reg_base = DWC2_FS_REG_BASE, .irqnum = ETS_USB_OTG11_CH0_INTR_SOURCE, .ep_count = 7, .ep_in_count = 5, .ep_fifo_size = 1024 }, +{ .reg_base = DWC2_HS_REG_BASE, .irqnum = ETS_USB_OTG_INTR_SOURCE, .ep_count = 16, .ep_in_count = 8, .ep_fifo_size = 4096 } }; #endif -enum { - DWC2_CONTROLLER_COUNT = TU_ARRAY_SIZE(_dwc2_controller) -}; - -static intr_handle_t usb_ih[DWC2_CONTROLLER_COUNT]; +static intr_handle_t usb_ih[TU_ARRAY_SIZE(_dwc2_controller)]; static void dcd_int_handler_wrap(void* arg) { - const uint8_t rhport = (uint8_t) arg; + const uint8_t rhport = (uint8_t)(uintptr_t) arg; dcd_int_handler(rhport); } TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_enable(uint8_t rhport) { esp_intr_alloc(_dwc2_controller[rhport].irqnum, ESP_INTR_FLAG_LOWMED, - dcd_int_handler_wrap, (void*) rhport, &usb_ih[rhport]); + dcd_int_handler_wrap, (void*)(uintptr_t) rhport, &usb_ih[rhport]); } TU_ATTR_ALWAYS_INLINE static inline void dwc2_dcd_int_disable(uint8_t rhport) { @@ -97,7 +83,6 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_remote_wakeup_delay(void) { TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { (void)dwc2; (void)hs_phy_type; - // nothing to do } @@ -105,7 +90,6 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_ TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { (void)dwc2; (void)hs_phy_type; - // nothing to do } -- cgit v1.3.1 From 3fa7da95bd2a7189020ba6fe2d6aa17577f83abd Mon Sep 17 00:00:00 2001 From: "Haefner, Martin" Date: Tue, 1 Oct 2024 15:24:11 +0200 Subject: support stm32U0 device --- src/common/tusb_mcu.h | 5 +++++ src/portable/st/stm32_fsdev/fsdev_stm32.h | 26 ++++++++++++++++++++++++++ src/portable/synopsys/dwc2/dwc2_stm32.h | 7 +++++++ src/tusb_option.h | 1 + 4 files changed, 39 insertions(+) (limited to 'src/portable') diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 0a4462a0a..87f47e732 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -293,6 +293,11 @@ #define TUP_USBIP_FSDEV_STM32 #define TUP_DCD_ENDPOINT_MAX 8 +#elif TU_CHECK_MCU(OPT_MCU_STM32U0) + #define TUP_USBIP_FSDEV + #define TUP_USBIP_FSDEV_STM32 + #define TUP_DCD_ENDPOINT_MAX 8 + //--------------------------------------------------------------------+ // Sony //--------------------------------------------------------------------+ diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index 99fe8d55f..03ea4c67e 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -170,6 +170,30 @@ #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY #define USB_CNTR_FSUSP USB_CNTR_SUSPEN +#elif CFG_TUSB_MCU == OPT_MCU_STM32U0 + #include "stm32u0xx.h" + #define FSDEV_PMA_SIZE (2048u) + #define USB USB_DRD_FS + + #define USB_EP_CTR_RX USB_EP_VTRX + #define USB_EP_CTR_TX USB_EP_VTTX + #define USB_EP_T_FIELD USB_CHEP_UTYPE + #define USB_EPREG_MASK USB_CHEP_REG_MASK + #define USB_EPTX_DTOGMASK USB_CHEP_TX_DTOGMASK + #define USB_EPRX_DTOGMASK USB_CHEP_RX_DTOGMASK + #define USB_EPTX_DTOG1 USB_CHEP_TX_DTOG1 + #define USB_EPTX_DTOG2 USB_CHEP_TX_DTOG2 + #define USB_EPRX_DTOG1 USB_CHEP_RX_DTOG1 + #define USB_EPRX_DTOG2 USB_CHEP_RX_DTOG2 + #define USB_EPRX_STAT USB_CH_RX_VALID + #define USB_EPKIND_MASK USB_EP_KIND_MASK + #define USB_CNTR_FRES USB_CNTR_USBRST + #define USB_CNTR_RESUME USB_CNTR_L2RES + #define USB_ISTR_EP_ID USB_ISTR_IDN + #define USB_EPADDR_FIELD USB_CHEP_ADDR + #define USB_CNTR_LPMODE USB_CNTR_SUSPRDY + #define USB_CNTR_FSUSP USB_CNTR_SUSPEN + #else #error You are using an untested or unimplemented STM32 variant. Please update the driver. // This includes U0 @@ -249,6 +273,8 @@ static const IRQn_Type fsdev_irq[] = { USB_LP_IRQn, #elif CFG_TUSB_MCU == OPT_MCU_STM32U5 USB_IRQn, + #elif CFG_TUSB_MCU == OPT_MCU_STM32U0 + USB_DRD_FS_IRQn, #else #error Unknown arch in USB driver #endif diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 3237a50f6..906538779 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -94,6 +94,13 @@ extern "C" { #define EP_MAX_HS 9 #define EP_FIFO_SIZE_HS 4096 #endif + +#elif CFG_TUSB_MCU == OPT_MCU_STM32U0 + #include "stm32u0xx.h" + #define USB_OTG_FS_PERIPH_BASE USB_OTG_FS_BASE + #define EP_MAX_FS 6 + #define EP_FIFO_SIZE_FS 1280 + #else #error "Unsupported MCUs" #endif diff --git a/src/tusb_option.h b/src/tusb_option.h index fb0209023..690859120 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -91,6 +91,7 @@ #define OPT_MCU_STM32U5 313 ///< ST U5 #define OPT_MCU_STM32L5 314 ///< ST L5 #define OPT_MCU_STM32H5 315 ///< ST H5 +#define OPT_MCU_STM32U0 316 ///< ST U0 // Sony #define OPT_MCU_CXD56 400 ///< SONY CXD56 -- cgit v1.3.1 From 73f7ce7103c0d002d787abfc1ae73d1f9e087f0b Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Oct 2024 17:26:14 +0700 Subject: U0 does not have dwc2 controller --- src/portable/synopsys/dwc2/dwc2_stm32.h | 7 ------- 1 file changed, 7 deletions(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index e9f6bdd91..395b6d870 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -94,13 +94,6 @@ extern "C" { #define EP_MAX_HS 9 #define EP_FIFO_SIZE_HS 4096 #endif - -#elif CFG_TUSB_MCU == OPT_MCU_STM32U0 - #include "stm32u0xx.h" - #define USB_OTG_FS_PERIPH_BASE USB_OTG_FS_BASE - #define EP_MAX_FS 6 - #define EP_FIFO_SIZE_FS 1280 - #else #error "Unsupported MCUs" #endif -- cgit v1.3.1 From cb5e273e9a9bde61970101191366b3845007eff9 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Oct 2024 22:12:38 +0700 Subject: enhance dwc2 markdown with field mapping --- src/portable/synopsys/dwc2/dwc2_info.md | 116 +++++++++++++------------- src/portable/synopsys/dwc2/dwc2_info.py | 140 +++++++++++++++++++------------- 2 files changed, 140 insertions(+), 116 deletions(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dwc2_info.md b/src/portable/synopsys/dwc2/dwc2_info.md index 462b5856a..cd8a57ec3 100644 --- a/src/portable/synopsys/dwc2/dwc2_info.md +++ b/src/portable/synopsys/dwc2/dwc2_info.md @@ -1,58 +1,58 @@ -| | BCM2711 (Pi4) | EFM32GG FS | ESP32-S2/S3 | ESP32-P4 | STM32F 407/411/429 FS | STM32F 407/429 HS | STM32F 412/767 FS | STM32F723 FS | STM32F723 HS | STM32H743 HS | STM32L476 FS | STM32U5A5 HS | GD32VF103 FS | XMC4500 | -|:---------------------------|:----------------|:-------------|:--------------|:-----------|:------------------------|:--------------------|:--------------------|:---------------|:---------------|:---------------|:---------------|:---------------|:---------------|:-----------| -| guid | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 | -| gsnpsid | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A | -| - specs version | 2.80a | 3.30a | 4.00a | 4.00a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a | -| ghwcfg1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | -| ghwcfg2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x215FFFD0 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 | -| - op_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | -| - arch | 2 | 2 | 2 | 2 | 0 | 2 | 0 | 0 | 2 | 2 | 0 | 2 | 0 | 2 | -| - point2point | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | -| - hs_phy_type | 1 | 0 | 0 | 3 | 0 | 2 | 0 | 0 | 3 | 2 | 0 | 1 | 0 | 0 | -| - fs_phy_type | 1 | 1 | 1 | 3 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - num_dev_ep | 7 | 6 | 6 | 15 | 3 | 5 | 5 | 5 | 8 | 8 | 5 | 8 | 0 | 6 | -| - num_host_ch | 7 | 13 | 7 | 15 | 7 | 11 | 11 | 11 | 15 | 15 | 11 | 15 | 0 | 13 | -| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - mul_cpu_int | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - nptx_q_depth | 2 | 2 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | -| - ptx_q_depth | 2 | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | -| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 | -| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| ghwcfg3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x03805EB5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 | -| - xfer_size_width | 8 | 8 | 5 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 | -| - packet_size_width | 6 | 6 | 3 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 | -| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - i2c_enable | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | -| - vendor_ctrl_itf | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | -| - optional_feature_removed | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - synch_reset | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - otg_adp_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - battery_charger_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | -| - dfifo_depth | 4080 | 498 | 200 | 896 | 512 | 1012 | 512 | 512 | 1006 | 952 | 512 | 952 | 0 | 634 | -| ghwcfg4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0xDFF1A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 | -| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - partial_powerdown | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - enhanced_lpm_support | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - phy_data_width | 0 | 2 | 2 | 2 | 2 | 0 | 2 | 2 | 0 | 0 | 2 | 0 | 0 | 2 | -| - ctrl_ep_num | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - iddg_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - vbus_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - a_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - b_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - session_end_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - num_dev_in_eps | 7 | 6 | 4 | 7 | 3 | 5 | 5 | 5 | 8 | 8 | 5 | 8 | 0 | 6 | -| - dma_desc_enable | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | -| - dma_desc_dynamic | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | +| | BCM2711 (Pi4) | EFM32GG FS | ESP32-S2/S3 | ESP32-P4 | ST F407/411/429 FS | ST F407/429 HS | ST F412/767 FS | ST F723 FS | ST F723 HS | ST F769 | ST H743 HS | ST L476 FS | ST U5A5 HS | GD32VF103 FS | XMC4500 | +|:---------------------------|:----------------|:-------------|:--------------|:-------------|:---------------------|:-----------------|:-----------------|:-------------|:-------------|:-------------|:-------------|:-------------|:-------------|:---------------|:-------------| +| GUID | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 | +| GSNPSID | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54320A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A | +| - specs version | 2.80a | 3.30a | 4.00a | 4.00a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.20a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a | +| GHWCFG1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | +| GHWCFG2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x215FFFD0 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 | +| - op_mode | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | noHNP noSRP | HNP SRP | HNP SRP | +| - arch | DMA internal | DMA internal | DMA internal | DMA internal | Slave only | DMA internal | Slave only | Slave only | DMA internal | DMA internal | DMA internal | Slave only | DMA internal | Slave only | DMA internal | +| - p2p (hub support) | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | +| - hs_phy_type | UTMI+ | N/A | N/A | UTMI+/ULPI | N/A | ULPI | N/A | N/A | UTMI+/ULPI | ULPI | ULPI | N/A | UTMI+ | N/A | N/A | +| - fs_phy_type | Dedicated | Dedicated | Dedicated | Shared ULPI | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | N/A | N/A | Dedicated | +| - num_dev_ep | 7 | 6 | 6 | 15 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 0 | 6 | +| - num_host_ch | 7 | 13 | 7 | 15 | 7 | 11 | 11 | 11 | 15 | 15 | 15 | 11 | 15 | 0 | 13 | +| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - mul_cpu_int | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - nptx_q_depth | 2 | 2 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | +| - ptx_q_depth | 2 | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | +| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 | +| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| GHWCFG3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x03805EB5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 | +| - xfer_size_width | 8 | 8 | 5 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 | +| - packet_size_width | 6 | 6 | 3 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 | +| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - i2c_enable | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | +| - vendor_ctrl_itf | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | +| - optional_feature_removed | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - synch_reset | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - otg_adp_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - battery_charger_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | +| - dfifo_depth | 4080 | 498 | 200 | 896 | 512 | 1012 | 512 | 512 | 1006 | 1006 | 952 | 512 | 952 | 0 | 634 | +| GHWCFG4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0xDFF1A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 | +| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - partial_powerdown | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - enhanced_lpm_support | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - phy_data_width | 8 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8 bit | 8/16 bit | 8/16 bit | 8 bit | 8 bit | 8 bit | 8/16 bit | 8 bit | 8 bit | 8/16 bit | +| - ctrl_ep_num | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - iddg_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - vbus_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - a_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - b_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - session_end_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - num_dev_in_eps | 7 | 6 | 4 | 7 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 0 | 6 | +| - dma_desc_enable | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | +| - dma_desc_dynamic | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | diff --git a/src/portable/synopsys/dwc2/dwc2_info.py b/src/portable/synopsys/dwc2/dwc2_info.py index 33997ca19..62437cfde 100755 --- a/src/portable/synopsys/dwc2/dwc2_info.py +++ b/src/portable/synopsys/dwc2/dwc2_info.py @@ -1,24 +1,27 @@ #!/usr/bin/env python3 -import click + import ctypes +import argparse +import click import pandas as pd # hex value for register: guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4 # Note: FS is FullSpeed, HS is HighSpeed -dwc2_reg_list = ['guid', 'gsnpsid', 'ghwcfg1', 'ghwcfg2', 'ghwcfg3', 'ghwcfg4'] +dwc2_reg_list = ['GUID', 'GSNPSID', 'GHWCFG1', 'GHWCFG2', 'GHWCFG3', 'GHWCFG4'] dwc2_reg_value = { 'BCM2711 (Pi4)': [0x2708A000, 0x4F54280A, 0, 0x228DDD50, 0xFF000E8, 0x1FF00020], 'EFM32GG FS': [0, 0x4F54330A, 0, 0x228F5910, 0x1F204E8, 0x1BF08030], 'ESP32-S2/S3': [0, 0x4F54400A, 0, 0x224DD930, 0xC804B5, 0xD3F0A030], 'ESP32-P4': [0, 0x4F54400A, 0, 0x215FFFD0, 0x03805EB5, 0xDFF1A030], - 'STM32F 407/411/429 FS': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x20001E8, 0xFF08030], - 'STM32F 407/429 HS': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x3F403E8, 0x17F00030], - 'STM32F 412/767 FS': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], - 'STM32F723 FS': [0x3000, 0x4F54330A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], - 'STM32F723 HS': [0x3100, 0x4F54330A, 0, 0x229FE1D0, 0x3EED2E8, 0x23F00030], - 'STM32H743 HS': [0x2300, 0x4F54330A, 0, 0x229FE190, 0x3B8D2E8, 0xE3F00030], # both HS cores - 'STM32L476 FS': [0x2000, 0x4F54310A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], - 'STM32U5A5 HS': [0x5000, 0x4F54411A, 0, 0x228FE052, 0x03B882E8, 0xE2103E30], + 'ST F407/411/429 FS': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x20001E8, 0xFF08030], + 'ST F407/429 HS': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x3F403E8, 0x17F00030], + 'ST F412/767 FS': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], + 'ST F723 FS': [0x3000, 0x4F54330A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], + 'ST F723 HS': [0x3100, 0x4F54330A, 0, 0x229FE1D0, 0x3EED2E8, 0x23F00030], + 'ST F769': [0x2100, 0x4F54320A, 0, 0x229FE190, 0x03EED2E8, 0x23F00030], + 'ST H743 HS': [0x2300, 0x4F54330A, 0, 0x229FE190, 0x3B8D2E8, 0xE3F00030], # both HS cores + 'ST L476 FS': [0x2000, 0x4F54310A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], + 'ST U5A5 HS': [0x5000, 0x4F54411A, 0, 0x228FE052, 0x03B882E8, 0xE2103E30], 'GD32VF103 FS': [0x1000, 0, 0, 0, 0, 0], 'XMC4500': [0xAEC000, 0x4F54292A, 0, 0x228F5930, 0x27A01E5, 0xDBF08030] } @@ -26,12 +29,12 @@ dwc2_reg_value = { # Combine dwc2_info with dwc2_reg_list # dwc2_info = { # 'BCM2711 (Pi4)': { -# 'guid': 0x2708A000, -# 'gsnpsid': 0x4F54280A, -# 'ghwcfg1': 0, -# 'ghwcfg2': 0x228DDD50, -# 'ghwcfg3': 0xFF000E8, -# 'ghwcfg4': 0x1FF00020 +# 'GUID': 0x2708A000, +# 'GSNPSID': 0x4F54280A, +# 'GHWCFG1': 0, +# 'GHWCFG2': 0x228DDD50, +# 'GHWCFG3': 0xFF000E8, +# 'GHWCFG4': 0x1FF00020 # }, dwc2_info = {key: {field: value for field, value in zip(dwc2_reg_list, values)} for key, values in dwc2_reg_value.items()} @@ -40,7 +43,7 @@ class GHWCFG2(ctypes.LittleEndianStructure): _fields_ = [ ("op_mode", ctypes.c_uint32, 3), ("arch", ctypes.c_uint32, 2), - ("point2point", ctypes.c_uint32, 1), + ("p2p (hub support)", ctypes.c_uint32, 1), ("hs_phy_type", ctypes.c_uint32, 2), ("fs_phy_type", ctypes.c_uint32, 2), ("num_dev_ep", ctypes.c_uint32, 4), @@ -99,63 +102,84 @@ class GHWCFG4(ctypes.LittleEndianStructure): ("dma_desc_dynamic", ctypes.c_uint32, 1) ] +# mapping for specific fields in GHWCFG2 +GHWCFG2_field = { + 'op_mode': { + 0: "HNP SRP", + 1: "SRP", + 2: "noHNP noSRP", + 3: "SRP Device", + 4: "noOTG Device", + 5: "SRP Host", + 6: "noOTG Host" + }, + 'arch': { + 0: "Slave only", + 1: "DMA external", + 2: "DMA internal" + }, + 'hs_phy_type': { + 0: "N/A", + 1: "UTMI+", + 2: "ULPI", + 3: "UTMI+/ULPI" + }, + 'fs_phy_type': { + 0: "N/A", + 1: "Dedicated", + 2: "Shared UTMI+", + 3: "Shared ULPI" + } +} -@click.group() -def cli(): - pass - - -@cli.command() -@click.argument('mcus', nargs=-1) -@click.option('-a', '--all', is_flag=True, help='Print all bit-field values') -def info(mcus, all): - """Print DWC2 register values for given MCU(s)""" - if len(mcus) == 0: - mcus = dwc2_info - - for mcu in mcus: - for entry in dwc2_info: - if mcu.lower() in entry.lower(): - print(f"## {entry}") - for r_name, r_value in dwc2_info[entry].items(): - print(f"{r_name} = 0x{r_value:08X}") - # Print bit-field values - if all and r_name.upper() in globals(): - class_name = globals()[r_name.upper()] - ghwcfg = class_name.from_buffer_copy(r_value.to_bytes(4, byteorder='little')) - for field_name, field_type, _ in class_name._fields_: - print(f" {field_name} = {getattr(ghwcfg, field_name)}") +# mapping for specific fields in GHWCFG4 +GHWCFG4_field = { + 'phy_data_width': { + 0: "8 bit", + 1: "16 bit", + 2: "8/16 bit", + 3: "Reserved" + }, + } + +def main(): + """Render dwc2_info to Markdown table""" + parser = argparse.ArgumentParser() + args = parser.parse_args() -@cli.command() -def render_md(): - """Render dwc2_info to Markdown table""" # Create an empty list to hold the dictionaries - dwc2_info_list = [] + md_table = [] # Iterate over the dwc2_info dictionary and extract fields for device, reg_values in dwc2_info.items(): - entry_dict = {"Device": device} + md_item = {"Device": device} for r_name, r_value in reg_values.items(): - entry_dict[r_name] = f"0x{r_value:08X}" + md_item[r_name] = f"0x{r_value:08X}" - if r_name == 'gsnpsid': + if r_name == 'GSNPSID': # Get dwc2 specs version major = ((r_value >> 8) >> 4) & 0x0F minor = (r_value >> 4) & 0xFF patch = chr((r_value & 0x0F) + ord('a') - 0xA) - entry_dict[f' - specs version'] = f"{major:X}.{minor:02X}{patch}" - elif r_name.upper() in globals(): + md_item[f' - specs version'] = f"{major:X}.{minor:02X}{patch}" + elif r_name in globals(): # Get bit-field values which exist as ctypes structures - class_name = globals()[r_name.upper()] - ghwcfg = class_name.from_buffer_copy(r_value.to_bytes(4, byteorder='little')) - for field_name, field_type, _ in class_name._fields_: - entry_dict[f' - {field_name}'] = getattr(ghwcfg, field_name) + class_hdl = globals()[r_name] + ghwcfg = class_hdl.from_buffer_copy(r_value.to_bytes(4, byteorder='little')) + for field_name, field_type, _ in class_hdl._fields_: + field_value = getattr(ghwcfg, field_name) + if class_hdl == GHWCFG2 and field_name in GHWCFG2_field: + field_value = GHWCFG2_field[field_name].get(field_value, f"Unknown ({field_value})") + if class_hdl == GHWCFG4 and field_name in GHWCFG4_field: + field_value = GHWCFG4_field[field_name].get(field_value, f"Unknown ({field_value})") + + md_item[f' - {field_name}'] = field_value - dwc2_info_list.append(entry_dict) + md_table.append(md_item) # Create a Pandas DataFrame from the list of dictionaries - df = pd.DataFrame(dwc2_info_list).set_index('Device') + df = pd.DataFrame(md_table).set_index('Device') # Transpose the DataFrame to switch rows and columns df = df.T @@ -168,4 +192,4 @@ def render_md(): if __name__ == '__main__': - cli() + main() -- cgit v1.3.1 From b2a98eadabf3b48f3d9316b32444f0b9cfbc2d1f Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Oct 2024 22:21:08 +0700 Subject: add stm32f769disco to hil pool --- src/portable/synopsys/dwc2/dcd_dwc2.c | 2 +- test/hil/tinyusb.json | 36 ++++++++++++++++++++++------------- 2 files changed, 24 insertions(+), 14 deletions(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 4fa869241..210ce1bba 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -637,7 +637,7 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { static bool check_dwc2(dwc2_regs_t* dwc2) { #if CFG_TUSB_DEBUG >= DWC2_DEBUG // print guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4 - // Run 'dwc2_info.py render-md' and check dwc2_info.md for bit-field value and comparison with other ports + // Run 'python dwc2_info.py' and check dwc2_info.md for bit-field value and comparison with other ports volatile uint32_t const* p = (volatile uint32_t const*) &dwc2->guid; TU_LOG1("guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4\r\n"); for (size_t i = 0; i < 5; i++) { diff --git a/test/hil/tinyusb.json b/test/hil/tinyusb.json index 1eaa08207..2358c3c4f 100644 --- a/test/hil/tinyusb.json +++ b/test/hil/tinyusb.json @@ -1,5 +1,18 @@ { "boards": [ + { + "name": "espressif_s3_devkitm", + "uid": "84F703C084E4", + "build" : { + "flags_on": ["", "CFG_TUD_DWC2_DMA"] + }, + "tests": { + "only": ["device/cdc_msc_freertos", "device/hid_composite_freertos"] + }, + "flasher": "esptool", + "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", + "flasher_args": "-b 1500000" + }, { "name": "feather_nrf52840_express", "uid": "1F0479CD0F764471", @@ -69,25 +82,22 @@ "flasher_sn": "779541626", "flasher_args": "-device stm32f072rb" }, + { + "name": "stm32f769disco", + "uid": "21002F000F51363531383437", + "build" : { + "flags_on": ["", "CFG_TUD_DWC2_DMA"] + }, + "flasher": "jlink", + "flasher_sn": "000778170924", + "flasher_args": "-device stm32f769ni" + }, { "name": "stm32g0b1nucleo", "uid": "4D0038000450434E37343120", "flasher": "openocd", "flasher_sn": "066FFF495087534867063844", "flasher_args": "-f interface/stlink.cfg -f target/stm32g0x.cfg" - }, - { - "name": "espressif_s3_devkitm", - "uid": "84F703C084E4", - "build" : { - "flags_on": ["", "CFG_TUD_DWC2_DMA"] - }, - "tests": { - "only": ["device/cdc_msc_freertos", "device/hid_composite_freertos"] - }, - "flasher": "esptool", - "flasher_sn": "3ea619acd1cdeb11a0a0b806e93fd3f1", - "flasher_args": "-b 921600" } ], "boards-skip": [ -- cgit v1.3.1 From 599bb0c8227f659b15302dac6a04706c7d3b2a4e Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 4 Oct 2024 22:26:40 +0700 Subject: improving dwc2, merging diep and doep if possible --- .idea/cmake.xml | 62 +++--- hw/bsp/stm32h7/boards/stm32h743eval/board.cmake | 1 + hw/bsp/stm32l4/boards/stm32l476disco/board.cmake | 2 +- src/portable/synopsys/dwc2/dcd_dwc2.c | 230 ++++++++++++----------- src/portable/synopsys/dwc2/dwc2_info.md | 6 +- src/portable/synopsys/dwc2/dwc2_info.py | 6 +- src/portable/synopsys/dwc2/dwc2_type.h | 108 +++++++++-- 7 files changed, 246 insertions(+), 169 deletions(-) (limited to 'src/portable') diff --git a/.idea/cmake.xml b/.idea/cmake.xml index 37cd73c65..d4ad3a748 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -9,49 +9,49 @@ - + - + - + - + - + - + - + @@ -65,19 +65,15 @@ - - - - - - - + + + @@ -86,33 +82,22 @@ - - - - - - - - - - - - - - + + + - + - + @@ -124,22 +109,31 @@ - + + + + + - - + + + + + + + + - diff --git a/hw/bsp/stm32h7/boards/stm32h743eval/board.cmake b/hw/bsp/stm32h7/boards/stm32h743eval/board.cmake index a28aa87bd..6d7a97741 100644 --- a/hw/bsp/stm32h7/boards/stm32h743eval/board.cmake +++ b/hw/bsp/stm32h7/boards/stm32h743eval/board.cmake @@ -1,5 +1,6 @@ set(MCU_VARIANT stm32h743xx) set(JLINK_DEVICE stm32h743xi) +# set(JLINK_OPTION "-USB jtrace") set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/${MCU_VARIANT}_flash.ld) diff --git a/hw/bsp/stm32l4/boards/stm32l476disco/board.cmake b/hw/bsp/stm32l4/boards/stm32l476disco/board.cmake index 4ade0a5c9..fd1c931c2 100644 --- a/hw/bsp/stm32l4/boards/stm32l476disco/board.cmake +++ b/hw/bsp/stm32l4/boards/stm32l476disco/board.cmake @@ -1,6 +1,6 @@ set(MCU_VARIANT stm32l476xx) set(JLINK_DEVICE stm32l476vg) - +# set(JLINK_OPTION "-USB 000777632258") set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32L476VGTx_FLASH.ld) function(update_board TARGET) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 210ce1bba..99cf3fdaa 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -327,53 +327,49 @@ static void edpt_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoin xfer->interval = p_endpoint_desc->bInterval; // USBAEP, EPTYP, SD0PID_SEVNFRM, MPSIZ are the same for IN and OUT endpoints. - uint32_t const dxepctl = (1 << DOEPCTL_USBAEP_Pos) | - (p_endpoint_desc->bmAttributes.xfer << DOEPCTL_EPTYP_Pos) | - (p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DOEPCTL_SD0PID_SEVNFRM : 0) | - (xfer->max_size << DOEPCTL_MPSIZ_Pos); - - if (dir == TUSB_DIR_OUT) { - dwc2->epout[epnum].doepctl = dxepctl; - dwc2->daintmsk |= TU_BIT(DAINTMSK_OEPM_Pos + epnum); - } else { - dwc2->epin[epnum].diepctl = dxepctl | (epnum << DIEPCTL_TXFNUM_Pos); - dwc2->daintmsk |= TU_BIT(DAINTMSK_IEPM_Pos + epnum); + uint32_t epctl = (1 << DOEPCTL_USBAEP_Pos) | + (p_endpoint_desc->bmAttributes.xfer << DOEPCTL_EPTYP_Pos) | + (p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DOEPCTL_SD0PID_SEVNFRM : 0) | + (xfer->max_size << DOEPCTL_MPSIZ_Pos); + if (dir == TUSB_DIR_IN) { + epctl |= (epnum << DIEPCTL_TXFNUM_Pos); } + + dwc2_dep_t* dep = &dwc2->ep[1 - dir][epnum]; + dep->ctl = epctl; + dwc2->daintmsk |= TU_BIT(epnum + DAINT_SHIFT(dir)); } static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) { (void) rhport; dwc2_regs_t* dwc2 = DWC2_REG(rhport); - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); + const uint8_t epnum = tu_edpt_number(ep_addr); + const uint8_t dir = tu_edpt_dir(ep_addr); + dwc2_dep_t* dep = &dwc2->ep[1 - dir][epnum]; if (dir == TUSB_DIR_IN) { - dwc2_epin_t* epin = dwc2->epin; - // Only disable currently enabled non-control endpoint - if ((epnum == 0) || !(epin[epnum].diepctl & DIEPCTL_EPENA)) { - epin[epnum].diepctl |= DIEPCTL_SNAK | (stall ? DIEPCTL_STALL : 0); + if ((epnum == 0) || !(dep->diepctl & DIEPCTL_EPENA)) { + dep->diepctl |= DIEPCTL_SNAK | (stall ? DIEPCTL_STALL : 0); } else { // Stop transmitting packets and NAK IN xfers. - epin[epnum].diepctl |= DIEPCTL_SNAK; - while ((epin[epnum].diepint & DIEPINT_INEPNE) == 0) {} + dep->diepctl |= DIEPCTL_SNAK; + while ((dep->diepint & DIEPINT_INEPNE) == 0) {} // Disable the endpoint. - epin[epnum].diepctl |= DIEPCTL_EPDIS | (stall ? DIEPCTL_STALL : 0); - while ((epin[epnum].diepint & DIEPINT_EPDISD_Msk) == 0) {} + dep->diepctl |= DIEPCTL_EPDIS | (stall ? DIEPCTL_STALL : 0); + while ((dep->diepint & DIEPINT_EPDISD_Msk) == 0) {} - epin[epnum].diepint = DIEPINT_EPDISD; + dep->diepint = DIEPINT_EPDISD; } // Flush the FIFO, and wait until we have confirmed it cleared. dfifo_flush_tx(dwc2, epnum); } else { - dwc2_epout_t* epout = dwc2->epout; - // Only disable currently enabled non-control endpoint - if ((epnum == 0) || !(epout[epnum].doepctl & DOEPCTL_EPENA)) { - epout[epnum].doepctl |= stall ? DOEPCTL_STALL : 0; + if ((epnum == 0) || !(dep->doepctl & DOEPCTL_EPENA)) { + dep->doepctl |= stall ? DOEPCTL_STALL : 0; } else { // Asserting GONAK is required to STALL an OUT endpoint. // Simpler to use polling here, we don't use the "B"OUTNAKEFF interrupt @@ -382,11 +378,11 @@ static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) { dwc2->dctl |= DCTL_SGONAK; while ((dwc2->gintsts & GINTSTS_BOUTNAKEFF_Msk) == 0) {} - // Ditto here- disable the endpoint. - epout[epnum].doepctl |= DOEPCTL_EPDIS | (stall ? DOEPCTL_STALL : 0); - while ((epout[epnum].doepint & DOEPINT_EPDISD_Msk) == 0) {} + // Ditto here disable the endpoint. + dep->doepctl |= DOEPCTL_EPDIS | (stall ? DOEPCTL_STALL : 0); + while ((dep->doepint & DOEPINT_EPDISD_Msk) == 0) {} - epout[epnum].doepint = DOEPINT_EPDISD; + dep->doepint = DOEPINT_EPDISD; // Allow other OUT endpoints to keep receiving. dwc2->dctl |= DCTL_CGONAK; @@ -430,7 +426,7 @@ static void bus_reset(uint8_t rhport) { dfifo_init(rhport); - // Fixed control EP0 size to 64 bytes + // Fixed both control EP0 size to 64 bytes dwc2->epin[0].diepctl &= ~(0x03 << DIEPCTL_MPSIZ_Pos); dwc2->epout[0].doepctl &= ~(0x03 << DOEPCTL_MPSIZ_Pos); @@ -461,33 +457,33 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c } // IN and OUT endpoint xfers are interrupt-driven, we just schedule them here. - if (dir == TUSB_DIR_IN) { - dwc2_epin_t* epin = dwc2->epin; + const uint8_t is_epout = 1 - dir; + dwc2_dep_t* dep = &dwc2->ep[is_epout][epnum]; + if (dir == TUSB_DIR_IN) { // A full IN transfer (multiple packets, possibly) triggers XFRC. - epin[epnum].dieptsiz = (num_packets << DIEPTSIZ_PKTCNT_Pos) | + dep->dieptsiz = (num_packets << DIEPTSIZ_PKTCNT_Pos) | ((total_bytes << DIEPTSIZ_XFRSIZ_Pos) & DIEPTSIZ_XFRSIZ_Msk); if(dma_enabled(dwc2)) { - epin[epnum].diepdma = (uintptr_t)xfer->buffer; + dep->diepdma = (uintptr_t)xfer->buffer; // For ISO endpoint set correct odd/even bit for next frame. - if ((epin[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) { + if ((dep->diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) { // Take odd/even bit from frame counter. uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); - epin[epnum].diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk); + dep->diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk); } - epin[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK; + dep->diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK; } else { - - epin[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK; + dep->diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK; // For ISO endpoint set correct odd/even bit for next frame. - if ((epin[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) { + if ((dep->diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) { // Take odd/even bit from frame counter. uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); - epin[epnum].diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk); + dep->diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk); } // Enable fifo empty interrupt only if there are something to put in the fifo. if (total_bytes != 0) { @@ -495,25 +491,23 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c } } } else { - dwc2_epout_t* epout = dwc2->epout; - // A full OUT transfer (multiple packets, possibly) triggers XFRC. - epout[epnum].doeptsiz &= ~(DOEPTSIZ_PKTCNT_Msk | DOEPTSIZ_XFRSIZ); - epout[epnum].doeptsiz |= (num_packets << DOEPTSIZ_PKTCNT_Pos) | + dep->doeptsiz &= ~(DOEPTSIZ_PKTCNT_Msk | DOEPTSIZ_XFRSIZ); + dep->doeptsiz |= (num_packets << DOEPTSIZ_PKTCNT_Pos) | ((total_bytes << DOEPTSIZ_XFRSIZ_Pos) & DOEPTSIZ_XFRSIZ_Msk); - if ((epout[epnum].doepctl & DOEPCTL_EPTYP) == DOEPCTL_EPTYP_0 && + if ((dep->doepctl & DOEPCTL_EPTYP) == DOEPCTL_EPTYP_0 && XFER_CTL_BASE(epnum, dir)->interval == 1) { // Take odd/even bit from frame counter. uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos)); - epout[epnum].doepctl |= (odd_frame_now ? DOEPCTL_SD0PID_SEVNFRM_Msk : DOEPCTL_SODDFRM_Msk); + dep->doepctl |= (odd_frame_now ? DOEPCTL_SD0PID_SEVNFRM_Msk : DOEPCTL_SODDFRM_Msk); } if(dma_enabled(dwc2)) { - epout[epnum].doepdma = (uintptr_t)xfer->buffer; + dep->doepdma = (uintptr_t)xfer->buffer; } - epout[epnum].doepctl |= DOEPCTL_EPENA | DOEPCTL_CNAK; + dep->doepctl |= DOEPCTL_EPENA | DOEPCTL_CNAK; } } @@ -837,17 +831,13 @@ void dcd_edpt_close_all(uint8_t rhport) { dwc2->daintmsk = (1 << DAINTMSK_OEPM_Pos) | (1 << DAINTMSK_IEPM_Pos); for (uint8_t n = 1; n < ep_count; n++) { - // disable OUT endpoint - if (dwc2->epout[n].doepctl & DOEPCTL_EPENA) { - dwc2->epout[n].doepctl |= DOEPCTL_SNAK | DOEPCTL_EPDIS; - } - xfer_status[n][TUSB_DIR_OUT].max_size = 0; - - // disable IN endpoint - if (dwc2->epin[n].diepctl & DIEPCTL_EPENA) { - dwc2->epin[n].diepctl |= DIEPCTL_SNAK | DIEPCTL_EPDIS; + for (uint8_t d = 0; d < 2; d++) { + dwc2_dep_t* dep = &dwc2->ep[d][n]; + if (dep->ctl & EPCTL_EPENA) { + dep->ctl |= EPCTL_SNAK | EPCTL_EPDIS; + } + xfer_status[n][1-d].max_size = 0; } - xfer_status[n][TUSB_DIR_IN].max_size = 0; } dfifo_flush_tx(dwc2, 0x10); // all tx fifo @@ -937,21 +927,14 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { } void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; - dwc2_regs_t* dwc2 = DWC2_REG(rhport); - uint8_t const epnum = tu_edpt_number(ep_addr); uint8_t const dir = tu_edpt_dir(ep_addr); + dwc2_dep_t* dep = &dwc2->ep[1 - dir][epnum]; // Clear stall and reset data toggle - if (dir == TUSB_DIR_IN) { - dwc2->epin[epnum].diepctl &= ~DIEPCTL_STALL; - dwc2->epin[epnum].diepctl |= DIEPCTL_SD0PID_SEVNFRM; - } else { - dwc2->epout[epnum].doepctl &= ~DOEPCTL_STALL; - dwc2->epout[epnum].doepctl |= DOEPCTL_SD0PID_SEVNFRM; - } + dep->ctl &= ~EPCTL_STALL;; + dep->ctl |= EPCTL_SD0PID_SEVNFRM; } //-------------------------------------------------------------------- @@ -963,10 +946,10 @@ static void handle_rxflvl_irq(uint8_t rhport) { volatile uint32_t const* rx_fifo = dwc2->fifo[0]; // Pop control word off FIFO - uint32_t const ctl_word = dwc2->grxstsp; - uint8_t const pktsts = (ctl_word & GRXSTSP_PKTSTS_Msk) >> GRXSTSP_PKTSTS_Pos; - uint8_t const epnum = (ctl_word & GRXSTSP_EPNUM_Msk) >> GRXSTSP_EPNUM_Pos; - uint16_t const bcnt = (ctl_word & GRXSTSP_BCNT_Msk) >> GRXSTSP_BCNT_Pos; + uint32_t const grxstsp = dwc2->grxstsp; + uint8_t const pktsts = (grxstsp & GRXSTSP_PKTSTS_Msk) >> GRXSTSP_PKTSTS_Pos; + uint8_t const epnum = (grxstsp & GRXSTSP_EPNUM_Msk) >> GRXSTSP_EPNUM_Pos; + uint16_t const bcnt = (grxstsp & GRXSTSP_BCNT_Msk) >> GRXSTSP_BCNT_Pos; dwc2_epout_t* epout = &dwc2->epout[epnum]; @@ -1024,20 +1007,16 @@ static void handle_rxflvl_irq(uint8_t rhport) { ep0_pending[TUSB_DIR_OUT] = 0; } } - } break; + } - // Out packet done (Interrupt) case GRXSTS_PKTSTS_OUTDONE: - // Occurred on STM32L47 with dwc2 version 3.10a but not found on other version like 2.80a or 3.30a - // May (or not) be 3.10a specific feature/bug or depending on MCU configuration - // XFRC complete is additionally generated when - // - setup packet is received - // - complete the data stage of control write is complete - // It will be handled in handle_epout_irq() + /* Out packet done (Interrupt) + After this entry is popped from the receive FIFO, the controller asserts a Transfer Completed interrupt on + the specified OUT endpoint which will be handled by handle_epout_irq() */ break; - default: // Invalid + default: TU_BREAKPOINT(); break; } @@ -1049,73 +1028,73 @@ static void handle_epout_irq(uint8_t rhport) { // DAINT for a given EP clears when DOEPINTx is cleared. // OEPINT will be cleared when DAINT's out bits are cleared. - for (uint8_t n = 0; n < ep_count; n++) { - if (dwc2->daint & TU_BIT(DAINT_OEPINT_Pos + n)) { - dwc2_epout_t* epout = &dwc2->epout[n]; - - uint32_t const doepint = epout->doepint; - + for (uint8_t epnum = 0; epnum < ep_count; epnum++) { + if (dwc2->daint & TU_BIT(DAINT_OEPINT_Pos + epnum)) { + dwc2_epout_t* epout = &dwc2->epout[epnum]; + const uint32_t doepint = epout->doepint; TU_ASSERT((epout->doepint & DOEPINT_AHBERR) == 0, ); // OUT XFER complete - if (epout->doepint & DOEPINT_XFRC) { + if (doepint & DOEPINT_XFRC) { epout->doepint = DOEPINT_XFRC; - xfer_ctl_t* xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT); + xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); if(dma_enabled(dwc2)) { - if (doepint & DOEPINT_STUP) { + if (doepint & DOEPINT_SETUP) { // STPKTRX is only available for version from 3_00a - if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { - epout->doepint = DOEPINT_STPKTRX; + if ((doepint & DOEPINT_DMA_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { + epout->doepint = DOEPINT_DMA_STPKTRX; } - } else if (doepint & DOEPINT_OTEPSPR) { - epout->doepint = DOEPINT_OTEPSPR; + } else if (doepint & DOEPINT_STSPHSRX) { + epout->doepint = DOEPINT_STSPHSRX; } else { - if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { - epout->doepint = DOEPINT_STPKTRX; + if ((doepint & DOEPINT_DMA_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { + epout->doepint = DOEPINT_DMA_STPKTRX; } else { // EP0 can only handle one packet - if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { + if ((epnum == 0) && ep0_pending[TUSB_DIR_OUT]) { // Schedule another packet to be received. - edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + edpt_schedule_packets(rhport, epnum, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); } else { // Fix packet length uint16_t remain = (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos; xfer->total_len -= remain; // this is ZLP, so prepare EP0 for next setup - if(n == 0 && xfer->total_len == 0) { + if(epnum == 0 && xfer->total_len == 0) { dma_setup_prepare(rhport); } - dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); + dcd_event_xfer_complete(rhport, epnum, xfer->total_len, XFER_RESULT_SUCCESS, true); } } } } else { - if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) { - epout->doepint = DOEPINT_STPKTRX; + // DMA_STPKTRX should only be set in Buffer DMA Mode. However, STM32L476 (slave-only) with v3.10a + // incorrectly set this along with SETUP bit. This may (or not) be STM32L476 or 3.10a specific bug + if ((doepint & DOEPINT_DMA_STPKTRX) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) { + epout->doepint = DOEPINT_DMA_STPKTRX; } else { - if ((doepint & DOEPINT_OTEPSPR) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) { - epout->doepint = DOEPINT_OTEPSPR; + if ((doepint & DOEPINT_STSPHSRX) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) { + epout->doepint = DOEPINT_STSPHSRX; } // EP0 can only handle one packet - if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) { + if ((epnum == 0) && ep0_pending[TUSB_DIR_OUT]) { // Schedule another packet to be received. - edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); + edpt_schedule_packets(rhport, epnum, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); } else { - dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true); + dcd_event_xfer_complete(rhport, epnum, xfer->total_len, XFER_RESULT_SUCCESS, true); } } } } // SETUP packet Setup Phase done. - if (doepint & DOEPINT_STUP) { - epout->doepint = DOEPINT_STUP; - if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { - epout->doepint = DOEPINT_STPKTRX; + if (doepint & DOEPINT_SETUP) { + epout->doepint = DOEPINT_SETUP; + if ((doepint & DOEPINT_DMA_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { + epout->doepint = DOEPINT_DMA_STPKTRX; } if(dma_enabled(dwc2) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { dma_setup_prepare(rhport); @@ -1195,6 +1174,29 @@ static void handle_epin_irq(uint8_t rhport) { } } +/* Interrupt Hierarchy + + DxEPMSK.XferComplMsk DxEPINTn.XferCompl + | | + +---------- AND --------+ + | + DAINT.xEPnInt DAINTMSK.xEPnMsk + | | + +---------- AND --------+ + | + GINTSTS.xEPInt GINTMSK.xEPIntMsk + | | + +---------- AND --------+ + | + GAHBCFG.GblIntrMsk + | + IRQn + + Note: when OTG_MULTI_PROC_INTRPT = 1, Device Each endpoint interrupt deachint/deachmsk/diepeachmsk/doepeachmsk + are combined to generate dedicated interrupt line for each endpoint. + */ + + void dcd_int_handler(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); @@ -1276,8 +1278,8 @@ void dcd_int_handler(uint8_t rhport) { // Mask out RXFLVL while reading data from FIFO dwc2->gintmsk &= ~GINTMSK_RXFLVLM; - // Loop until all available packets were handled do { + // Loop until all available packets were handled handle_rxflvl_irq(rhport); } while(dwc2->gintsts & GINTSTS_RXFLVL); diff --git a/src/portable/synopsys/dwc2/dwc2_info.md b/src/portable/synopsys/dwc2/dwc2_info.md index cd8a57ec3..5c7e5e688 100644 --- a/src/portable/synopsys/dwc2/dwc2_info.md +++ b/src/portable/synopsys/dwc2/dwc2_info.md @@ -8,13 +8,13 @@ | - op_mode | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | noHNP noSRP | HNP SRP | HNP SRP | | - arch | DMA internal | DMA internal | DMA internal | DMA internal | Slave only | DMA internal | Slave only | Slave only | DMA internal | DMA internal | DMA internal | Slave only | DMA internal | Slave only | DMA internal | | - p2p (hub support) | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | -| - hs_phy_type | UTMI+ | N/A | N/A | UTMI+/ULPI | N/A | ULPI | N/A | N/A | UTMI+/ULPI | ULPI | ULPI | N/A | UTMI+ | N/A | N/A | -| - fs_phy_type | Dedicated | Dedicated | Dedicated | Shared ULPI | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | N/A | N/A | Dedicated | +| - hs_phy_type | UTMI+ | n/a | n/a | UTMI+/ULPI | n/a | ULPI | n/a | n/a | UTMI+/ULPI | ULPI | ULPI | n/a | UTMI+ | n/a | n/a | +| - fs_phy_type | Dedicated | Dedicated | Dedicated | Shared ULPI | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | n/a | n/a | Dedicated | | - num_dev_ep | 7 | 6 | 6 | 15 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 0 | 6 | | - num_host_ch | 7 | 13 | 7 | 15 | 7 | 11 | 11 | 11 | 15 | 15 | 15 | 11 | 15 | 0 | 13 | | - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | | - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - mul_cpu_int | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - mul_proc_intrpt | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | | - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | - nptx_q_depth | 2 | 2 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | | - ptx_q_depth | 2 | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | diff --git a/src/portable/synopsys/dwc2/dwc2_info.py b/src/portable/synopsys/dwc2/dwc2_info.py index 62437cfde..ac32eb585 100755 --- a/src/portable/synopsys/dwc2/dwc2_info.py +++ b/src/portable/synopsys/dwc2/dwc2_info.py @@ -50,7 +50,7 @@ class GHWCFG2(ctypes.LittleEndianStructure): ("num_host_ch", ctypes.c_uint32, 4), ("period_channel_support", ctypes.c_uint32, 1), ("enable_dynamic_fifo", ctypes.c_uint32, 1), - ("mul_cpu_int", ctypes.c_uint32, 1), + ("mul_proc_intrpt", ctypes.c_uint32, 1), ("reserved21", ctypes.c_uint32, 1), ("nptx_q_depth", ctypes.c_uint32, 2), ("ptx_q_depth", ctypes.c_uint32, 2), @@ -119,13 +119,13 @@ GHWCFG2_field = { 2: "DMA internal" }, 'hs_phy_type': { - 0: "N/A", + 0: "n/a", 1: "UTMI+", 2: "ULPI", 3: "UTMI+/ULPI" }, 'fs_phy_type': { - 0: "N/A", + 0: "n/a", 1: "Dedicated", 2: "Shared UTMI+", 3: "Shared ULPI" diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index ac88dd24d..d5a51fb09 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -250,7 +250,7 @@ typedef struct TU_ATTR_PACKED { uint32_t num_host_ch : 4; // 14..17 Number of host channel (excluding control) uint32_t period_channel_support : 1; // 18 Support Periodic OUT Host Channel uint32_t enable_dynamic_fifo : 1; // 19 Dynamic FIFO Sizing Enabled - uint32_t mul_cpu_int : 1; // 20 Multi-Processor Interrupt Enabled + uint32_t mul_proc_intrpt : 1; // 20 Multi-Processor Interrupt enabled (OTG_MULTI_PROC_INTRPT) uint32_t reserved21 : 1; // 21 reserved uint32_t nptx_q_depth : 2; // 22..23 Non-periodic request queue depth: 0 = 2. 1 = 4, 2 = 8 uint32_t ptx_q_depth : 2; // 24..25 Host periodic request queue depth: 0 = 2. 1 = 4, 2 = 8 @@ -336,6 +336,32 @@ typedef struct { uint32_t reserved18[2]; // B18..B1C } dwc2_epout_t; +typedef struct { + union { + volatile uint32_t diepctl; + volatile uint32_t doepctl; + volatile uint32_t ctl; + }; + uint32_t rsv04; + union { + volatile uint32_t diepint; + volatile uint32_t doepint; + }; + uint32_t rsv0c; + union { + volatile uint32_t dieptsiz; + volatile uint32_t doeptsiz; + }; + union { + volatile uint32_t diepdma; + volatile uint32_t doepdma; + }; + volatile uint32_t dtxfsts; + uint32_t rsv1c; +}dwc2_dep_t; + +TU_VERIFY_STATIC(sizeof(dwc2_dep_t) == 0x20, "incorrect size"); + //-------------------------------------------------------------------- // CSR Register Map //-------------------------------------------------------------------- @@ -418,16 +444,24 @@ typedef struct { volatile uint32_t dvbuspulse; // 82C Device VBUS Pulsing Time volatile uint32_t dthrctl; // 830 Device threshold Control volatile uint32_t diepempmsk; // 834 Device IN Endpoint FIFO Empty Interrupt Mask + + // Device Each Endpoint (IN/OUT) Interrupt/Mask for generating dedicated EP interrupt line + // require OTG_MULTI_PROC_INTRPT=1 volatile uint32_t deachint; // 838 Device Each Endpoint Interrupt - volatile uint32_t deachmsk; // 83C Device Each Endpoint Interrupt msk + volatile uint32_t deachmsk; // 83C Device Each Endpoint Interrupt mask volatile uint32_t diepeachmsk[16]; // 840..87C Device Each IN Endpoint mask volatile uint32_t doepeachmsk[16]; // 880..8BF Device Each OUT Endpoint mask uint32_t reserved8c0[16]; // 8C0..8FF //------------- Device Endpoint -------------// - dwc2_epin_t epin[16]; // 900..AFF IN Endpoints - dwc2_epout_t epout[16]; // B00..CFF OUT Endpoints - uint32_t reservedd00[64]; // D00..DFF + union { + dwc2_dep_t ep[2][16]; // 0: IN, 1 OUT + struct { + dwc2_epin_t epin[16]; // 900..AFF IN Endpoints + dwc2_epout_t epout[16]; // B00..CFF OUT Endpoints + }; + }; + uint32_t reservedd00[64]; // D00..DFF //------------- Power Clock -------------// volatile uint32_t pcgctl; // E00 Power and Clock Gating Control @@ -1094,6 +1128,8 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define DAINTMSK_OEPM_Msk (0xFFFFUL << DAINTMSK_OEPM_Pos) // 0xFFFF0000 #define DAINTMSK_OEPM DAINTMSK_OEPM_Msk // OUT EP interrupt mask bits +#define DAINT_SHIFT(_dir) ((_dir == TUSB_DIR_IN) ? 0 : 16) + #if 0 /******************** Bit definition for OTG register ********************/ #define CHNUM_Pos (0U) @@ -1803,6 +1839,45 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define DIEPTXF_INEPTXFD_Msk (0xFFFFUL << DIEPTXF_INEPTXFD_Pos) // 0xFFFF0000 #define DIEPTXF_INEPTXFD DIEPTXF_INEPTXFD_Msk // IN endpoint TxFIFO depth + +/******************** Bit definition for Common EPCTL register ********************/ +#define EPCTL_MPSIZ_Pos (0U) +#define EPCTL_MPSIZ_Msk (0x7FFUL << EPCTL_MPSIZ_Pos) // 0x000007FF +#define EPCTL_MPSIZ EPCTL_MPSIZ_Msk // Maximum packet size //Bit 1 +#define EPCTL_USBAEP_Pos (15U) +#define EPCTL_USBAEP_Msk (0x1UL << EPCTL_USBAEP_Pos) // 0x00008000 +#define EPCTL_USBAEP EPCTL_USBAEP_Msk // USB active endpoint +#define EPCTL_NAKSTS_Pos (17U) +#define EPCTL_NAKSTS_Msk (0x1UL << EPCTL_NAKSTS_Pos) // 0x00020000 +#define EPCTL_NAKSTS EPCTL_NAKSTS_Msk // NAK status +#define EPCTL_EPTYP_Pos (18U) +#define EPCTL_EPTYP_Msk (0x3UL << EPCTL_EPTYP_Pos) // 0x000C0000 +#define EPCTL_EPTYP EPCTL_EPTYP_Msk // Endpoint type +#define EPCTL_EPTYP_0 (0x1UL << EPCTL_EPTYP_Pos) // 0x00040000 +#define EPCTL_EPTYP_1 (0x2UL << EPCTL_EPTYP_Pos) // 0x00080000 +#define EPCTL_SNPM EPCTL_SNPM_Msk // Snoop mode +#define EPCTL_STALL_Pos (21U) +#define EPCTL_STALL_Msk (0x1UL << EPCTL_STALL_Pos) // 0x00200000 +#define EPCTL_STALL EPCTL_STALL_Msk // STALL handshake +#define EPCTL_CNAK_Pos (26U) +#define EPCTL_CNAK_Msk (0x1UL << EPCTL_CNAK_Pos) // 0x04000000 +#define EPCTL_CNAK EPCTL_CNAK_Msk // Clear NAK +#define EPCTL_SNAK_Pos (27U) +#define EPCTL_SNAK_Msk (0x1UL << EPCTL_SNAK_Pos) // 0x08000000 +#define EPCTL_SNAK EPCTL_SNAK_Msk // Set NAK +#define EPCTL_SD0PID_SEVNFRM_Pos (28U) +#define EPCTL_SD0PID_SEVNFRM_Msk (0x1UL << EPCTL_SD0PID_SEVNFRM_Pos) // 0x10000000 +#define EPCTL_SD0PID_SEVNFRM EPCTL_SD0PID_SEVNFRM_Msk // Set DATA0 PID +#define EPCTL_SODDFRM_Pos (29U) +#define EPCTL_SODDFRM_Msk (0x1UL << EPCTL_SODDFRM_Pos) // 0x20000000 +#define EPCTL_SODDFRM EPCTL_SODDFRM_Msk // Set odd frame +#define EPCTL_EPDIS_Pos (30U) +#define EPCTL_EPDIS_Msk (0x1UL << EPCTL_EPDIS_Pos) // 0x40000000 +#define EPCTL_EPDIS EPCTL_EPDIS_Msk // Endpoint disable +#define EPCTL_EPENA_Pos (31U) +#define EPCTL_EPENA_Msk (0x1UL << EPCTL_EPENA_Pos) // 0x80000000 +#define EPCTL_EPENA EPCTL_EPENA_Msk // Endpoint enable + /******************** Bit definition for DOEPCTL register ********************/ #define DOEPCTL_MPSIZ_Pos (0U) #define DOEPCTL_MPSIZ_Msk (0x7FFUL << DOEPCTL_MPSIZ_Pos) // 0x000007FF @@ -1853,15 +1928,19 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define DOEPINT_AHBERR_Pos (2U) #define DOEPINT_AHBERR_Msk (0x1UL << DOEPINT_AHBERR_Pos) // 0x00000004 #define DOEPINT_AHBERR DOEPINT_AHBERR_Msk // AHB Error (AHBErr) during an OUT transaction -#define DOEPINT_STUP_Pos (3U) -#define DOEPINT_STUP_Msk (0x1UL << DOEPINT_STUP_Pos) // 0x00000008 -#define DOEPINT_STUP DOEPINT_STUP_Msk // SETUP phase done + +#define DOEPINT_SETUP_Pos (3U) +#define DOEPINT_SETUP_Msk (0x1UL << DOEPINT_SETUP_Pos) // 0x00000008 +#define DOEPINT_SETUP DOEPINT_SETUP_Msk // SETUP phase done + #define DOEPINT_OTEPDIS_Pos (4U) #define DOEPINT_OTEPDIS_Msk (0x1UL << DOEPINT_OTEPDIS_Pos) // 0x00000010 #define DOEPINT_OTEPDIS DOEPINT_OTEPDIS_Msk // OUT token received when endpoint disabled -#define DOEPINT_OTEPSPR_Pos (5U) -#define DOEPINT_OTEPSPR_Msk (0x1UL << DOEPINT_OTEPSPR_Pos) // 0x00000020 -#define DOEPINT_OTEPSPR DOEPINT_OTEPSPR_Msk // Status Phase Received For Control Write + +#define DOEPINT_STSPHSRX_Pos (5U) +#define DOEPINT_STSPHSRX_Msk (0x1UL << DOEPINT_STSPHSRX_Pos) // 0x00000020 +#define DOEPINT_STSPHSRX DOEPINT_STSPHSRX_Msk // Status Phase Received For Control Write + #define DOEPINT_B2BSTUP_Pos (6U) #define DOEPINT_B2BSTUP_Msk (0x1UL << DOEPINT_B2BSTUP_Pos) // 0x00000040 #define DOEPINT_B2BSTUP DOEPINT_B2BSTUP_Msk // Back-to-back SETUP packets received @@ -1874,9 +1953,10 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define DOEPINT_NYET_Pos (14U) #define DOEPINT_NYET_Msk (0x1UL << DOEPINT_NYET_Pos) // 0x00004000 #define DOEPINT_NYET DOEPINT_NYET_Msk // NYET interrupt -#define DOEPINT_STPKTRX_Pos (15U) -#define DOEPINT_STPKTRX_Msk (0x1UL << DOEPINT_STPKTRX_Pos) // 0x00008000 -#define DOEPINT_STPKTRX DOEPINT_STPKTRX_Msk // Setup Packet Received + +#define DOEPINT_DMA_STPKTRX_Pos (15U) +#define DOEPINT_DMA_STPKTRX_Msk (0x1UL << DOEPINT_DMA_STPKTRX_Pos) // 0x00008000 +#define DOEPINT_DMA_STPKTRX DOEPINT_DMA_STPKTRX_Msk // Setup Packet Received in Buffer DMA Mode /******************** Bit definition for DOEPTSIZ register ********************/ #define DOEPTSIZ_XFRSIZ_Pos (0U) -- cgit v1.3.1 From 07c14f30a6d6cfb1758e3496c3ea73275ae4a062 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 8 Oct 2024 12:36:45 +0700 Subject: add f407disco to hil pool --- hw/bsp/stm32h7/boards/stm32h750_weact/board.cmake | 16 ++ hw/bsp/stm32h7/boards/stm32h750_weact/board.h | 132 ++++++++++++++++ hw/bsp/stm32h7/boards/stm32h750_weact/board.mk | 21 +++ .../stm32h750_weact/stm32h750xx_flash_CM7.ld | 170 +++++++++++++++++++++ hw/bsp/stm32h7/boards/stm32h750bdk/board.cmake | 2 +- hw/bsp/stm32h7/boards/stm32h750bdk/board.mk | 2 +- hw/bsp/stm32h7/family.c | 12 +- src/portable/synopsys/dwc2/dwc2_info.md | 116 +++++++------- src/portable/synopsys/dwc2/dwc2_info.py | 23 +-- test/hil/hil_test.py | 2 +- test/hil/tinyusb.json | 24 ++- 11 files changed, 438 insertions(+), 82 deletions(-) create mode 100644 hw/bsp/stm32h7/boards/stm32h750_weact/board.cmake create mode 100644 hw/bsp/stm32h7/boards/stm32h750_weact/board.h create mode 100644 hw/bsp/stm32h7/boards/stm32h750_weact/board.mk create mode 100644 hw/bsp/stm32h7/boards/stm32h750_weact/stm32h750xx_flash_CM7.ld (limited to 'src/portable') diff --git a/hw/bsp/stm32h7/boards/stm32h750_weact/board.cmake b/hw/bsp/stm32h7/boards/stm32h750_weact/board.cmake new file mode 100644 index 000000000..6303ca462 --- /dev/null +++ b/hw/bsp/stm32h7/boards/stm32h750_weact/board.cmake @@ -0,0 +1,16 @@ +set(MCU_VARIANT stm32h750xx) +set(JLINK_DEVICE stm32h750vb) + +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${MCU_VARIANT}_flash_CM7.ld) +set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + STM32H750xx + HSE_VALUE=25000000 + CORE_CM7 + # default to PORT 0 + BOARD_TUD_RHPORT=0 + BOARD_TUD_MAX_SPEED=OPT_MODE_FULL_SPEED + ) +endfunction() diff --git a/hw/bsp/stm32h7/boards/stm32h750_weact/board.h b/hw/bsp/stm32h7/boards/stm32h750_weact/board.h new file mode 100644 index 000000000..d117637a5 --- /dev/null +++ b/hw/bsp/stm32h7/boards/stm32h750_weact/board.h @@ -0,0 +1,132 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, 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. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define LED_PORT GPIOE +#define LED_PIN GPIO_PIN_3 +#define LED_STATE_ON 1 + +// Blue push-button +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 1 + +// UART +//#define UART_DEV USART3 +//#define UART_CLK_EN __HAL_RCC_USART3_CLK_ENABLE +//#define UART_GPIO_PORT GPIOB +//#define UART_GPIO_AF GPIO_AF7_USART3 +//#define UART_TX_PIN GPIO_PIN_10 +//#define UART_RX_PIN GPIO_PIN_11 + +// VBUS Sense detection +#define OTG_FS_VBUS_SENSE 1 +#define OTG_HS_VBUS_SENSE 0 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void SystemClock_Config(void) { + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + + // Supply configuration update enable + HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY); + + // Configure the main internal regulator output voltage + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2); + while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} + + // Configure the PLL clock source + __HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_HSE); + + // Initializes the CPU, AHB and APB busses clocks + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.LSIState = RCC_LSI_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = 5; + RCC_OscInitStruct.PLL.PLLN = 96; + RCC_OscInitStruct.PLL.PLLP = 2; + RCC_OscInitStruct.PLL.PLLQ = 2; + RCC_OscInitStruct.PLL.PLLR = 2; + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; + RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; + RCC_OscInitStruct.PLL.PLLFRACN = 0; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + // Initializes the CPU, AHB and APB busses clocks + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2 + |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV1; + RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1); + + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_SPI4 + |RCC_PERIPHCLK_SPI1|RCC_PERIPHCLK_USB + |RCC_PERIPHCLK_QSPI; + PeriphClkInitStruct.PLL3.PLL3M = 10; + PeriphClkInitStruct.PLL3.PLL3N = 96; + PeriphClkInitStruct.PLL3.PLL3P = 5; + PeriphClkInitStruct.PLL3.PLL3Q = 5; + PeriphClkInitStruct.PLL3.PLL3R = 2; + PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_1; + PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOWIDE; + PeriphClkInitStruct.PLL3.PLL3FRACN = 0; + PeriphClkInitStruct.QspiClockSelection = RCC_QSPICLKSOURCE_D1HCLK; + PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL; + PeriphClkInitStruct.Spi45ClockSelection = RCC_SPI45CLKSOURCE_D2PCLK1; + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL3; + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + + // Enable USB Voltage detector + HAL_PWREx_EnableUSBVoltageDetector(); +} + +static inline void board_stm32h7_post_init(void) { + // For this board does nothing +} + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/hw/bsp/stm32h7/boards/stm32h750_weact/board.mk b/hw/bsp/stm32h7/boards/stm32h750_weact/board.mk new file mode 100644 index 000000000..a50172cb0 --- /dev/null +++ b/hw/bsp/stm32h7/boards/stm32h750_weact/board.mk @@ -0,0 +1,21 @@ +# STM32H745I-DISCO uses OTG_FS +# FIXME: Reset enumerates, un/replug USB plug does not enumerate + +CFLAGS += -DSTM32H750xx -DCORE_CM7 -DHSE_VALUE=25000000 + +# Default is FulSpeed port +PORT ?= 0 + +# GCC +SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32h750xx.s +LD_FILE_GCC = $(BOARD_PATH)/stm32h750xx_flash_CM7.ld + +# IAR +SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32h750xx.s +LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32h750xx_flash.icf + +# For flash-jlink target +JLINK_DEVICE = stm32h750vb + +# flash target using on-board stlink +flash: flash-jlink diff --git a/hw/bsp/stm32h7/boards/stm32h750_weact/stm32h750xx_flash_CM7.ld b/hw/bsp/stm32h7/boards/stm32h750_weact/stm32h750xx_flash_CM7.ld new file mode 100644 index 000000000..30f220a42 --- /dev/null +++ b/hw/bsp/stm32h7/boards/stm32h750_weact/stm32h750xx_flash_CM7.ld @@ -0,0 +1,170 @@ +/* +****************************************************************************** +** + +** File : LinkerScript.ld +** +** +** Abstract : Linker script for STM32H7 series +** 128Kbytes FLASH and 1Mbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used. +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed �as is,� without any warranty +** of any kind. +** +***************************************************************************** +** @attention +** +** Copyright (c) 2019 STMicroelectronics. +** All rights reserved. +** +** This software component is licensed by ST under BSD 3-Clause license, +** the "License"; You may not use this file except in compliance with the +** License. You may obtain a copy of the License at: +** opensource.org/licenses/BSD-3-Clause +** +**************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = 0x20020000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 1M +ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data goes into FLASH */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH + .ARM : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH + + /* used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32h7/boards/stm32h750bdk/board.cmake b/hw/bsp/stm32h7/boards/stm32h750bdk/board.cmake index 6eff708a8..e87be8255 100644 --- a/hw/bsp/stm32h7/boards/stm32h750bdk/board.cmake +++ b/hw/bsp/stm32h7/boards/stm32h750bdk/board.cmake @@ -1,5 +1,5 @@ set(MCU_VARIANT stm32h750xx) -set(JLINK_DEVICE stm32h750xb_m7) +set(JLINK_DEVICE stm32h750xb) set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${MCU_VARIANT}_flash_CM7.ld) set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash.icf) diff --git a/hw/bsp/stm32h7/boards/stm32h750bdk/board.mk b/hw/bsp/stm32h7/boards/stm32h750bdk/board.mk index d37a425fb..923c90753 100644 --- a/hw/bsp/stm32h7/boards/stm32h750bdk/board.mk +++ b/hw/bsp/stm32h7/boards/stm32h750bdk/board.mk @@ -15,7 +15,7 @@ SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_stm32h750xx.s LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32h750xx_flash.icf # For flash-jlink target -JLINK_DEVICE = stm32h750xb_m7 +JLINK_DEVICE = stm32h750xb # flash target using on-board stlink flash: flash-stlink diff --git a/hw/bsp/stm32h7/family.c b/hw/bsp/stm32h7/family.c index adeb38e74..c81437958 100644 --- a/hw/bsp/stm32h7/family.c +++ b/hw/bsp/stm32h7/family.c @@ -102,9 +102,6 @@ void board_init(void) { trace_etm_init(); - // Enable UART Clock - UART_CLK_EN(); - #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer SysTick_Config(SystemCoreClock / 1000); @@ -136,7 +133,10 @@ void board_init(void) { GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct); +#ifdef UART_DEV // Uart + UART_CLK_EN(); + GPIO_InitStruct.Pin = UART_TX_PIN | UART_RX_PIN; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; @@ -153,6 +153,7 @@ void board_init(void) { UartHandle.Init.Mode = UART_MODE_TX_RX; UartHandle.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&UartHandle); +#endif #if BOARD_TUD_RHPORT == 0 // Despite being call USB2_OTG @@ -280,8 +281,13 @@ int board_uart_read(uint8_t *buf, int len) { } int board_uart_write(void const *buf, int len) { +#ifdef UART_DEV HAL_UART_Transmit(&UartHandle, (uint8_t * )(uintptr_t) buf, len, 0xffff); +#else + (void) buf; +#endif + return len; } diff --git a/src/portable/synopsys/dwc2/dwc2_info.md b/src/portable/synopsys/dwc2/dwc2_info.md index 5c7e5e688..cfd0c81a8 100644 --- a/src/portable/synopsys/dwc2/dwc2_info.md +++ b/src/portable/synopsys/dwc2/dwc2_info.md @@ -1,58 +1,58 @@ -| | BCM2711 (Pi4) | EFM32GG FS | ESP32-S2/S3 | ESP32-P4 | ST F407/411/429 FS | ST F407/429 HS | ST F412/767 FS | ST F723 FS | ST F723 HS | ST F769 | ST H743 HS | ST L476 FS | ST U5A5 HS | GD32VF103 FS | XMC4500 | -|:---------------------------|:----------------|:-------------|:--------------|:-------------|:---------------------|:-----------------|:-----------------|:-------------|:-------------|:-------------|:-------------|:-------------|:-------------|:---------------|:-------------| -| GUID | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 | -| GSNPSID | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54320A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A | -| - specs version | 2.80a | 3.30a | 4.00a | 4.00a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.20a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a | -| GHWCFG1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | -| GHWCFG2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x215FFFD0 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 | -| - op_mode | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | noHNP noSRP | HNP SRP | HNP SRP | -| - arch | DMA internal | DMA internal | DMA internal | DMA internal | Slave only | DMA internal | Slave only | Slave only | DMA internal | DMA internal | DMA internal | Slave only | DMA internal | Slave only | DMA internal | -| - p2p (hub support) | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | -| - hs_phy_type | UTMI+ | n/a | n/a | UTMI+/ULPI | n/a | ULPI | n/a | n/a | UTMI+/ULPI | ULPI | ULPI | n/a | UTMI+ | n/a | n/a | -| - fs_phy_type | Dedicated | Dedicated | Dedicated | Shared ULPI | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | n/a | n/a | Dedicated | -| - num_dev_ep | 7 | 6 | 6 | 15 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 0 | 6 | -| - num_host_ch | 7 | 13 | 7 | 15 | 7 | 11 | 11 | 11 | 15 | 15 | 15 | 11 | 15 | 0 | 13 | -| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - mul_proc_intrpt | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - nptx_q_depth | 2 | 2 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | -| - ptx_q_depth | 2 | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | -| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 | -| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| GHWCFG3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x03805EB5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 | -| - xfer_size_width | 8 | 8 | 5 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 | -| - packet_size_width | 6 | 6 | 3 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 | -| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - i2c_enable | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | -| - vendor_ctrl_itf | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | -| - optional_feature_removed | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - synch_reset | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - otg_adp_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - battery_charger_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | -| - dfifo_depth | 4080 | 498 | 200 | 896 | 512 | 1012 | 512 | 512 | 1006 | 1006 | 952 | 512 | 952 | 0 | 634 | -| GHWCFG4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0xDFF1A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 | -| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - partial_powerdown | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - enhanced_lpm_support | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - phy_data_width | 8 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8 bit | 8/16 bit | 8/16 bit | 8 bit | 8 bit | 8 bit | 8/16 bit | 8 bit | 8 bit | 8/16 bit | -| - ctrl_ep_num | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - iddg_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - vbus_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - a_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - b_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - session_end_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | -| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | -| - num_dev_in_eps | 7 | 6 | 4 | 7 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 0 | 6 | -| - dma_desc_enable | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | -| - dma_desc_dynamic | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | +| | BCM2711 (Pi4) | EFM32GG | ESP32-S2/S3 | ESP32-P4 | ST F207/F407/411/429 FS | ST F407/429 HS | ST F412/767 FS | ST F723/L4P5 FS | ST F723 HS | ST F769 | ST H743/H750 | ST L476 FS | ST U5A5 HS | GD32VF103 | XMC4500 | +|:---------------------------|:----------------|:-------------|:--------------|:-------------|:--------------------------|:-----------------|:-----------------|:------------------|:-------------|:-------------|:---------------|:-------------|:-------------|:------------|:-------------| +| GUID | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00001000 | 0x00AEC000 | +| GSNPSID | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54320A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x00000000 | 0x4F54292A | +| - specs version | 2.80a | 3.30a | 4.00a | 4.00a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.20a | 3.30a | 3.10a | 4.11a | 0.00W | 2.92a | +| GHWCFG1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | +| GHWCFG2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x215FFFD0 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x00000000 | 0x228F5930 | +| - op_mode | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | noHNP noSRP | HNP SRP | HNP SRP | +| - arch | DMA internal | DMA internal | DMA internal | DMA internal | Slave only | DMA internal | Slave only | Slave only | DMA internal | DMA internal | DMA internal | Slave only | DMA internal | Slave only | DMA internal | +| - p2p (hub support) | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | +| - hs_phy_type | UTMI+ | n/a | n/a | UTMI+/ULPI | n/a | ULPI | n/a | n/a | UTMI+/ULPI | ULPI | ULPI | n/a | UTMI+ | n/a | n/a | +| - fs_phy_type | Dedicated | Dedicated | Dedicated | Shared ULPI | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | n/a | n/a | Dedicated | +| - num_dev_ep | 7 | 6 | 6 | 15 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 0 | 6 | +| - num_host_ch | 7 | 13 | 7 | 15 | 7 | 11 | 11 | 11 | 15 | 15 | 15 | 11 | 15 | 0 | 13 | +| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - mul_proc_intrpt | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - reserved21 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - nptx_q_depth | 2 | 2 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | +| - ptx_q_depth | 2 | 2 | 2 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 0 | 2 | +| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 8 | +| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| GHWCFG3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x03805EB5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x00000000 | 0x027A01E5 | +| - xfer_size_width | 8 | 8 | 5 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | 5 | +| - packet_size_width | 6 | 6 | 3 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | 6 | +| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - i2c_enable | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | +| - vendor_ctrl_itf | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | +| - optional_feature_removed | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - synch_reset | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - otg_adp_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - battery_charger_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | +| - dfifo_depth | 4080 | 498 | 200 | 896 | 512 | 1012 | 512 | 512 | 1006 | 1006 | 952 | 512 | 952 | 0 | 634 | +| GHWCFG4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0xDFF1A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0x00000000 | 0xDBF08030 | +| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - partial_powerdown | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - enhanced_lpm_support | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - phy_data_width | 8 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8 bit | 8/16 bit | 8/16 bit | 8 bit | 8 bit | 8 bit | 8/16 bit | 8 bit | 8 bit | 8/16 bit | +| - ctrl_ep_num | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - iddg_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - vbus_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - a_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - b_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - session_end_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | +| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | +| - num_dev_in_eps | 7 | 6 | 4 | 7 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 0 | 6 | +| - dma_desc_enable | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | +| - dma_desc_dynamic | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | diff --git a/src/portable/synopsys/dwc2/dwc2_info.py b/src/portable/synopsys/dwc2/dwc2_info.py index ac32eb585..d1793a005 100755 --- a/src/portable/synopsys/dwc2/dwc2_info.py +++ b/src/portable/synopsys/dwc2/dwc2_info.py @@ -10,20 +10,21 @@ import pandas as pd dwc2_reg_list = ['GUID', 'GSNPSID', 'GHWCFG1', 'GHWCFG2', 'GHWCFG3', 'GHWCFG4'] dwc2_reg_value = { 'BCM2711 (Pi4)': [0x2708A000, 0x4F54280A, 0, 0x228DDD50, 0xFF000E8, 0x1FF00020], - 'EFM32GG FS': [0, 0x4F54330A, 0, 0x228F5910, 0x1F204E8, 0x1BF08030], - 'ESP32-S2/S3': [0, 0x4F54400A, 0, 0x224DD930, 0xC804B5, 0xD3F0A030], + 'EFM32GG': [0, 0x4F54330A, 0, 0x228F5910, 0x01F204E8, 0x1BF08030], + 'ESP32-S2/S3': [0, 0x4F54400A, 0, 0x224DD930, 0x0C804B5, 0xD3F0A030], 'ESP32-P4': [0, 0x4F54400A, 0, 0x215FFFD0, 0x03805EB5, 0xDFF1A030], - 'ST F407/411/429 FS': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x20001E8, 0xFF08030], - 'ST F407/429 HS': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x3F403E8, 0x17F00030], - 'ST F412/767 FS': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], - 'ST F723 FS': [0x3000, 0x4F54330A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], - 'ST F723 HS': [0x3100, 0x4F54330A, 0, 0x229FE1D0, 0x3EED2E8, 0x23F00030], + 'ST F207/F407/411/429 FS': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x020001E8, 0x0FF08030], + 'ST F407/429 HS': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x03F403E8, 0x17F00030], + 'ST F412/767 FS': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x0200D1E8, 0x17F08030], + 'ST F723/L4P5 FS': [0x3000, 0x4F54330A, 0, 0x229ED520, 0x0200D1E8, 0x17F08030], + 'ST F723 HS': [0x3100, 0x4F54330A, 0, 0x229FE1D0, 0x03EED2E8, 0x23F00030], 'ST F769': [0x2100, 0x4F54320A, 0, 0x229FE190, 0x03EED2E8, 0x23F00030], - 'ST H743 HS': [0x2300, 0x4F54330A, 0, 0x229FE190, 0x3B8D2E8, 0xE3F00030], # both HS cores - 'ST L476 FS': [0x2000, 0x4F54310A, 0, 0x229ED520, 0x200D1E8, 0x17F08030], + 'ST H743/H750': [0x2300, 0x4F54330A, 0, 0x229FE190, 0x03B8D2E8, 0xE3F00030], + 'ST L476 FS': [0x2000, 0x4F54310A, 0, 0x229ED520, 0x0200D1E8, 0x17F08030], 'ST U5A5 HS': [0x5000, 0x4F54411A, 0, 0x228FE052, 0x03B882E8, 0xE2103E30], - 'GD32VF103 FS': [0x1000, 0, 0, 0, 0, 0], - 'XMC4500': [0xAEC000, 0x4F54292A, 0, 0x228F5930, 0x27A01E5, 0xDBF08030] + 'GD32VF103': [0x1000, 0, 0, 0, 0, 0], + 'XMC4500': [0xAEC000, 0x4F54292A, 0, 0x228F5930, 0x027A01E5, 0xDBF08030] + } # Combine dwc2_info with dwc2_reg_list diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 60bba9bd2..0d7cae77e 100755 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -245,7 +245,7 @@ def test_dual_host_info_to_device_cdc(board): # for pico/pico2 make this test optional failed_msg = f'Enumerated devices {enum_dev_sn} not match with declared {declared_devs}' if 'raspberry_pi_pico' in board['name']: - print(f'\r\n {failed_msg} ', end='') + print(f'\r\n {failed_msg} {STATUS_FAILED} ', end='') else: assert False, failed_msg return 0 diff --git a/test/hil/tinyusb.json b/test/hil/tinyusb.json index 2358c3c4f..44d4a617c 100644 --- a/test/hil/tinyusb.json +++ b/test/hil/tinyusb.json @@ -20,6 +20,13 @@ "flasher_sn": "000682804350", "flasher_args": "-device nrf52840_xxaa" }, + { + "name": "max32666fthr", + "uid": "0C81464124010B20FF0A08CC2C", + "flasher": "openocd_adi", + "flasher_sn": "E6614C311B597D32", + "flasher_args": "-f interface/cmsis-dap.cfg -f target/max32665.cfg" + }, { "name": "metro_m4_express", "uid": "9995AD485337433231202020FF100A34", @@ -30,13 +37,6 @@ "dual_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2002130"}] } }, - { - "name": "max32666fthr", - "uid": "0C81464124010B20FF0A08CC2C", - "flasher": "openocd_adi", - "flasher_sn": "E6614C311B597D32", - "flasher_args": "-f interface/cmsis-dap.cfg -f target/max32665.cfg" - }, { "name": "lpcxpresso11u37", "uid": "17121919", @@ -82,6 +82,16 @@ "flasher_sn": "779541626", "flasher_args": "-device stm32f072rb" }, + { + "name": "stm32f407disco", + "uid": "30001A000647313332353735", + "build" : { + "flags_on": ["", "CFG_TUD_DWC2_DMA"] + }, + "flasher": "jlink", + "flasher_sn": "000773661813", + "flasher_args": "-device stm32f407vg" + }, { "name": "stm32f769disco", "uid": "21002F000F51363531383437", -- cgit v1.3.1 From 98e94a5d6d5dfd2bb468f3c2f4c9e82925fedd91 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 9 Oct 2024 21:47:23 +0700 Subject: enhance dwc2 --- hw/bsp/xmc4000/boards/xmc4500_relax/board.cmake | 1 + src/portable/synopsys/dwc2/dcd_dwc2.c | 135 ++++++++++-------------- src/portable/synopsys/dwc2/dwc2_type.h | 6 +- 3 files changed, 61 insertions(+), 81 deletions(-) (limited to 'src/portable') diff --git a/hw/bsp/xmc4000/boards/xmc4500_relax/board.cmake b/hw/bsp/xmc4000/boards/xmc4500_relax/board.cmake index ec36bcc4d..e18741a9b 100644 --- a/hw/bsp/xmc4000/boards/xmc4500_relax/board.cmake +++ b/hw/bsp/xmc4000/boards/xmc4500_relax/board.cmake @@ -1,6 +1,7 @@ set(MCU_VARIANT XMC4500) set(JLINK_DEVICE XMC4500-1024) +#set(JLINK_OPTION "-USB 000551005307") set(LD_FILE_GNU ${SDK_DIR}/CMSIS/Infineon/COMPONENT_${MCU_VARIANT}/Source/TOOLCHAIN_GCC_ARM/XMC4500x1024.ld) function(update_board TARGET) diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 99cf3fdaa..c0700633d 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -398,12 +398,8 @@ static void bus_reset(uint8_t rhport) { tu_memclr(xfer_status, sizeof(xfer_status)); _sof_en = false; - _allocated_ep_in_count = 1; - // clear device address - dwc2->dcfg &= ~DCFG_DAD_Msk; - // 1. NAK for all OUT endpoints for (uint8_t n = 0; n < ep_count; n++) { dwc2->epout[n].doepctl |= DOEPCTL_SNAK; @@ -419,13 +415,17 @@ static void bus_reset(uint8_t rhport) { dfifo_flush_tx(dwc2, 0x10); // all tx fifo dfifo_flush_rx(dwc2); - // 3. Set up interrupt mask + // 3. Set up interrupt mask for EP0 dwc2->daintmsk = TU_BIT(DAINTMSK_OEPM_Pos) | TU_BIT(DAINTMSK_IEPM_Pos); dwc2->doepmsk = DOEPMSK_STUPM | DOEPMSK_XFRCM; dwc2->diepmsk = DIEPMSK_TOM | DIEPMSK_XFRCM; + // 4. Set up DFIFO dfifo_init(rhport); + // 5. Reset device address + dwc2->dcfg &= ~DCFG_DAD_Msk; + // Fixed both control EP0 size to 64 bytes dwc2->epin[0].diepctl &= ~(0x03 << DIEPCTL_MPSIZ_Pos); dwc2->epout[0].doepctl &= ~(0x03 << DOEPCTL_MPSIZ_Pos); @@ -907,7 +907,9 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t uint16_t const short_packet_size = total_bytes % xfer->max_size; // Zero-size packet is special case. - if (short_packet_size > 0 || (total_bytes == 0)) num_packets++; + if (short_packet_size > 0 || (total_bytes == 0)) { + num_packets++; + } // Schedule packets to be sent within interrupt edpt_schedule_packets(rhport, epnum, dir, num_packets, total_bytes); @@ -941,6 +943,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { // Interrupt Handler //-------------------------------------------------------------------- +// Process shared receive FIFO, this interrupt is only used in Slave mode static void handle_rxflvl_irq(uint8_t rhport) { dwc2_regs_t* dwc2 = DWC2_REG(rhport); volatile uint32_t const* rx_fifo = dwc2->fifo[0]; @@ -950,20 +953,8 @@ static void handle_rxflvl_irq(uint8_t rhport) { uint8_t const pktsts = (grxstsp & GRXSTSP_PKTSTS_Msk) >> GRXSTSP_PKTSTS_Pos; uint8_t const epnum = (grxstsp & GRXSTSP_EPNUM_Msk) >> GRXSTSP_EPNUM_Pos; uint16_t const bcnt = (grxstsp & GRXSTSP_BCNT_Msk) >> GRXSTSP_BCNT_Pos; - dwc2_epout_t* epout = &dwc2->epout[epnum]; -//#if CFG_TUSB_DEBUG >= DWC2_DEBUG -// const char * pktsts_str[] = -// { -// "ASSERT", "Global NAK (ISR)", "Out Data Received", "Out Transfer Complete (ISR)", -// "Setup Complete (ISR)", "ASSERT", "Setup Data Received" -// }; -// TU_LOG_LOCATION(); -// TU_LOG(DWC2_DEBUG, " EP %02X, Byte Count %u, %s\r\n", epnum, bcnt, pktsts_str[pktsts]); -// TU_LOG(DWC2_DEBUG, " daint = %08lX, doepint = %04X\r\n", (unsigned long) dwc2->daint, (unsigned int) epout->doepint); -//#endif - switch (pktsts) { // Global OUT NAK: do nothing case GRXSTS_PKTSTS_GLOBALOUTNAK: @@ -971,15 +962,14 @@ static void handle_rxflvl_irq(uint8_t rhport) { case GRXSTS_PKTSTS_SETUPRX: // Setup packet received - - // We can receive up to three setup packets in succession, but - // only the last one is valid. + // We can receive up to three setup packets in succession, but only the last one is valid. _setup_packet[0] = (*rx_fifo); _setup_packet[1] = (*rx_fifo); break; case GRXSTS_PKTSTS_SETUPDONE: - // Setup packet done (Interrupt) + // Setup packet done: + // After popping this out, dwc2 asserts a DOEPINT_SETUP interrupt which is handled by handle_epout_irq() epout->doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos); break; @@ -1011,8 +1001,8 @@ static void handle_rxflvl_irq(uint8_t rhport) { } case GRXSTS_PKTSTS_OUTDONE: - /* Out packet done (Interrupt) - After this entry is popped from the receive FIFO, the controller asserts a Transfer Completed interrupt on + /* Out packet done + After this entry is popped from the receive FIFO, dwc2 asserts a Transfer Completed interrupt on the specified OUT endpoint which will be handled by handle_epout_irq() */ break; @@ -1034,51 +1024,56 @@ static void handle_epout_irq(uint8_t rhport) { const uint32_t doepint = epout->doepint; TU_ASSERT((epout->doepint & DOEPINT_AHBERR) == 0, ); + TU_LOG1_HEX(doepint); + + // Setup and/or STPKTRX/STSPHSRX (from 3.00a) can be set along with XFRC, and also set independently. + if (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a) { + if (doepint & DOEPINT_STSPHSRX) { + // Status phase received for control write: In token received from Host + epout->doepint = DOEPINT_STSPHSRX; + } + + if (doepint & DOEPINT_STPKTRX) { + // New setup packet received, but wait for Setup done, since we can receive up to 3 setup consecutively + epout->doepint = DOEPINT_STPKTRX; + } + } + + if (doepint & DOEPINT_SETUP) { + epout->doepint = DOEPINT_SETUP; + + if(dma_enabled(dwc2)) { + dma_setup_prepare(rhport); + } + + dcd_event_setup_received(rhport, (uint8_t*) _setup_packet, true); + } + // OUT XFER complete if (doepint & DOEPINT_XFRC) { epout->doepint = DOEPINT_XFRC; - xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); + // only handle data skip if it is setup or status related + // Normal OUT transfer complete + if (!(doepint & (DOEPINT_SETUP | DOEPINT_STPKTRX | DOEPINT_STSPHSRX))) { + xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); - if(dma_enabled(dwc2)) { - if (doepint & DOEPINT_SETUP) { - // STPKTRX is only available for version from 3_00a - if ((doepint & DOEPINT_DMA_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { - epout->doepint = DOEPINT_DMA_STPKTRX; - } - } else if (doepint & DOEPINT_STSPHSRX) { - epout->doepint = DOEPINT_STSPHSRX; - } else { - if ((doepint & DOEPINT_DMA_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { - epout->doepint = DOEPINT_DMA_STPKTRX; + if(dma_enabled(dwc2)) { + if ((epnum == 0) && ep0_pending[TUSB_DIR_OUT]) { + // EP0 can only handle one packet Schedule another packet to be received. + edpt_schedule_packets(rhport, epnum, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); } else { - // EP0 can only handle one packet - if ((epnum == 0) && ep0_pending[TUSB_DIR_OUT]) { - // Schedule another packet to be received. - edpt_schedule_packets(rhport, epnum, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]); - } else { - // Fix packet length - uint16_t remain = (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos; - xfer->total_len -= remain; - // this is ZLP, so prepare EP0 for next setup - if(epnum == 0 && xfer->total_len == 0) { - dma_setup_prepare(rhport); - } - - dcd_event_xfer_complete(rhport, epnum, xfer->total_len, XFER_RESULT_SUCCESS, true); + // Fix packet length + uint16_t remain = (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos; + xfer->total_len -= remain; + // this is ZLP, so prepare EP0 for next setup + if(epnum == 0 && xfer->total_len == 0) { + dma_setup_prepare(rhport); } + + dcd_event_xfer_complete(rhport, epnum, xfer->total_len, XFER_RESULT_SUCCESS, true); } - } - } else { - // DMA_STPKTRX should only be set in Buffer DMA Mode. However, STM32L476 (slave-only) with v3.10a - // incorrectly set this along with SETUP bit. This may (or not) be STM32L476 or 3.10a specific bug - if ((doepint & DOEPINT_DMA_STPKTRX) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) { - epout->doepint = DOEPINT_DMA_STPKTRX; } else { - if ((doepint & DOEPINT_STSPHSRX) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) { - epout->doepint = DOEPINT_STSPHSRX; - } - // EP0 can only handle one packet if ((epnum == 0) && ep0_pending[TUSB_DIR_OUT]) { // Schedule another packet to be received. @@ -1089,19 +1084,6 @@ static void handle_epout_irq(uint8_t rhport) { } } } - - // SETUP packet Setup Phase done. - if (doepint & DOEPINT_SETUP) { - epout->doepint = DOEPINT_SETUP; - if ((doepint & DOEPINT_DMA_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { - epout->doepint = DOEPINT_DMA_STPKTRX; - } - if(dma_enabled(dwc2) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) { - dma_setup_prepare(rhport); - } - - dcd_event_setup_received(rhport, (uint8_t*) _setup_packet, true); - } } } } @@ -1274,13 +1256,10 @@ void dcd_int_handler(uint8_t rhport) { // RxFIFO non-empty interrupt handling. if (int_status & GINTSTS_RXFLVL) { // RXFLVL bit is read-only - - // Mask out RXFLVL while reading data from FIFO - dwc2->gintmsk &= ~GINTMSK_RXFLVLM; + dwc2->gintmsk &= ~GINTMSK_RXFLVLM; // disable RXFLVL interrupt while reading do { - // Loop until all available packets were handled - handle_rxflvl_irq(rhport); + handle_rxflvl_irq(rhport); // read all packets } while(dwc2->gintsts & GINTSTS_RXFLVL); dwc2->gintmsk |= GINTMSK_RXFLVLM; diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index d5a51fb09..cf05bbfec 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -1954,9 +1954,9 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define DOEPINT_NYET_Msk (0x1UL << DOEPINT_NYET_Pos) // 0x00004000 #define DOEPINT_NYET DOEPINT_NYET_Msk // NYET interrupt -#define DOEPINT_DMA_STPKTRX_Pos (15U) -#define DOEPINT_DMA_STPKTRX_Msk (0x1UL << DOEPINT_DMA_STPKTRX_Pos) // 0x00008000 -#define DOEPINT_DMA_STPKTRX DOEPINT_DMA_STPKTRX_Msk // Setup Packet Received in Buffer DMA Mode +#define DOEPINT_STPKTRX_Pos (15U) +#define DOEPINT_STPKTRX_Msk (0x1UL << DOEPINT_STPKTRX_Pos) // 0x00008000 +#define DOEPINT_STPKTRX DOEPINT_STPKTRX_Msk // Setup Packet Received /******************** Bit definition for DOEPTSIZ register ********************/ #define DOEPTSIZ_XFRSIZ_Pos (0U) -- cgit v1.3.1 From 1406ad84e3cd7e39771303dd23e6be361b51de96 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 10 Oct 2024 11:05:32 +0700 Subject: remove debug code --- src/portable/synopsys/dwc2/dcd_dwc2.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index c0700633d..1ba3507ef 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -1024,8 +1024,6 @@ static void handle_epout_irq(uint8_t rhport) { const uint32_t doepint = epout->doepint; TU_ASSERT((epout->doepint & DOEPINT_AHBERR) == 0, ); - TU_LOG1_HEX(doepint); - // Setup and/or STPKTRX/STSPHSRX (from 3.00a) can be set along with XFRC, and also set independently. if (dwc2->gsnpsid >= DWC2_CORE_REV_3_00a) { if (doepint & DOEPINT_STSPHSRX) { -- cgit v1.3.1 From d997f0071ea5d2d07e340d183fffb97e09526773 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 11 Oct 2024 15:21:32 +0700 Subject: change dcd_init() to take rhport struct --- .pre-commit-config.yaml | 15 +++++++++++++++ src/device/dcd.h | 2 +- src/device/usbd.c | 2 +- src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 4 ++-- src/portable/chipidea/ci_fs/dcd_ci_fs.c | 4 ++-- src/portable/chipidea/ci_hs/dcd_ci_hs.c | 4 ++-- src/portable/dialog/da146xx/dcd_da146xx.c | 4 ++-- src/portable/espressif/esp32sx/dcd_esp32sx.c | 4 ++-- src/portable/mentor/musb/dcd_musb.c | 3 ++- src/portable/microchip/pic/dcd_pic.c | 4 ++-- src/portable/microchip/pic32mz/dcd_pic32mz.c | 4 ++-- src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c | 4 ++-- src/portable/nordic/nrf5x/dcd_nrf5x.c | 3 ++- src/portable/nuvoton/nuc120/dcd_nuc120.c | 4 ++-- src/portable/nuvoton/nuc121/dcd_nuc121.c | 4 ++-- src/portable/nuvoton/nuc505/dcd_nuc505.c | 4 ++-- src/portable/nxp/khci/dcd_khci.c | 4 ++-- src/portable/nxp/lpc17_40/dcd_lpc17_40.c | 4 ++-- src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 4 ++-- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 3 ++- src/portable/renesas/rusb2/dcd_rusb2.c | 4 ++-- src/portable/sony/cxd56/dcd_cxd56.c | 4 ++-- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 3 ++- src/portable/sunxi/dcd_sunxi_musb.c | 4 ++-- src/portable/synopsys/dwc2/dcd_dwc2.c | 3 ++- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 12 ++++++++---- src/portable/valentyusb/eptri/dcd_eptri.c | 4 ++-- src/portable/wch/dcd_ch32_usbfs.c | 3 ++- src/portable/wch/dcd_ch32_usbhs.c | 3 ++- test/unit-test/test/device/msc/test_msc_device.c | 7 +++---- test/unit-test/test/device/usbd/test_usbd.c | 10 +++++----- 31 files changed, 83 insertions(+), 58 deletions(-) (limited to 'src/portable') diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bba217cc9..21da285c1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -42,3 +42,18 @@ repos: pass_filenames: false types_or: [c, header] language: system + + - id: build-fuzzer + name: build-fuzzer + files: ^(src/|test/fuzz/) + language: system + types_or: [c, header] + entry: | + export CC=clang + export CXX=clang++ + fuzz_harness=$(ls -d test/fuzz/device/*/) + for h in $fuzz_harness + do + make -C $h get-deps + make -C $h all + done diff --git a/src/device/dcd.h b/src/device/dcd.h index 3ef5188fc..8fa7b8bc1 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -108,7 +108,7 @@ void dcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_W //--------------------------------------------------------------------+ // Initialize controller to device mode -void dcd_init(uint8_t rhport); +void dcd_init(const tusb_rhport_init_t* rh_init); // Deinitialize controller, unset device mode. bool dcd_deinit(uint8_t rhport); diff --git a/src/device/usbd.c b/src/device/usbd.c index 7e35c976c..12f95ab40 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -490,7 +490,7 @@ bool tud_rhport_init(const tusb_rhport_init_t* rh_init) { _usbd_rhport = rh_init->rhport; // Init device controller driver - dcd_init(rh_init->rhport); + dcd_init(rh_init); dcd_int_enable(rh_init->rhport); return true; diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index f02415904..f4b236da6 100644 --- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -517,8 +517,8 @@ static uint16_t _ft9xx_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t len *------------------------------------------------------------------*/ // Initialize controller to device mode -void dcd_init(uint8_t rhport) -{ +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; TU_LOG2("FT9xx initialisation\r\n"); _dcd_ft9xx_attach(); diff --git a/src/portable/chipidea/ci_fs/dcd_ci_fs.c b/src/portable/chipidea/ci_fs/dcd_ci_fs.c index 02f813ab5..315e9a86d 100644 --- a/src/portable/chipidea/ci_fs/dcd_ci_fs.c +++ b/src/portable/chipidea/ci_fs/dcd_ci_fs.c @@ -267,8 +267,8 @@ static void process_bus_resume(uint8_t rhport) /*------------------------------------------------------------------*/ /* Device API *------------------------------------------------------------------*/ -void dcd_init(uint8_t rhport) -{ +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; (void) rhport; // save crystal-less setting (if available) diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index 93e1d78dd..bdb7abe41 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -234,8 +234,8 @@ static void bus_reset(uint8_t rhport) dcd_dcache_clean_invalidate(&_dcd_data, sizeof(dcd_data_t)); } -void dcd_init(uint8_t rhport) -{ +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; tu_memclr(&_dcd_data, sizeof(dcd_data_t)); ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); diff --git a/src/portable/dialog/da146xx/dcd_da146xx.c b/src/portable/dialog/da146xx/dcd_da146xx.c index d1e85c2df..05cebea0b 100644 --- a/src/portable/dialog/da146xx/dcd_da146xx.c +++ b/src/portable/dialog/da146xx/dcd_da146xx.c @@ -804,8 +804,8 @@ static void handle_ep0_nak(void) /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ -void dcd_init(uint8_t rhport) -{ +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; (void) rhport; _dcd.init_called = true; diff --git a/src/portable/espressif/esp32sx/dcd_esp32sx.c b/src/portable/espressif/esp32sx/dcd_esp32sx.c index 61911ab4c..3d4757f03 100644 --- a/src/portable/espressif/esp32sx/dcd_esp32sx.c +++ b/src/portable/espressif/esp32sx/dcd_esp32sx.c @@ -172,8 +172,8 @@ static void enum_done_processing(void) /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ -void dcd_init(uint8_t rhport) -{ +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; ESP_LOGV(TAG, "DCD init - Start"); // A. Disconnect diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index a40b3dc07..a8437ad5b 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -582,7 +582,8 @@ void print_musb_info(musb_regs_t* musb_regs) { } #endif -void dcd_init(uint8_t rhport) { +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; musb_regs_t* musb_regs = MUSB_REGS(rhport); #if CFG_TUSB_DEBUG >= MUSB_DEBUG diff --git a/src/portable/microchip/pic/dcd_pic.c b/src/portable/microchip/pic/dcd_pic.c index ccc27c3c9..3ee0ab6d5 100644 --- a/src/portable/microchip/pic/dcd_pic.c +++ b/src/portable/microchip/pic/dcd_pic.c @@ -470,8 +470,8 @@ static void process_bus_resume(uint8_t rhport) /*------------------------------------------------------------------*/ /* Device API *------------------------------------------------------------------*/ -void dcd_init(uint8_t rhport) -{ +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; intr_disable(rhport); intr_clear(rhport); diff --git a/src/portable/microchip/pic32mz/dcd_pic32mz.c b/src/portable/microchip/pic32mz/dcd_pic32mz.c index 9ad755670..004990046 100644 --- a/src/portable/microchip/pic32mz/dcd_pic32mz.c +++ b/src/portable/microchip/pic32mz/dcd_pic32mz.c @@ -120,8 +120,8 @@ static ep0_stage_t ep0_get_stage(void) /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ -void dcd_init(uint8_t rhport) -{ +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; // Disable endpoint interrupts for now USB_REGS->INTRRXEbits.w = 0; USB_REGS->INTRTXEbits.w = 0; diff --git a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c index d5c0daaeb..4117ab45f 100644 --- a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c +++ b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c @@ -245,8 +245,8 @@ static void process_bus_active(uint8_t rhport) /*------------------------------------------------------------------*/ /* Device API *------------------------------------------------------------------*/ -void dcd_init(uint8_t rhport) -{ +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; (void) rhport; tu_memclr(&_dcd, sizeof(_dcd)); diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index a63e442f3..c1084c20c 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -230,7 +230,8 @@ static void xact_in_dma(uint8_t epnum) { //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ -void dcd_init(uint8_t rhport) { +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; TU_LOG2("dcd init\r\n"); (void) rhport; } diff --git a/src/portable/nuvoton/nuc120/dcd_nuc120.c b/src/portable/nuvoton/nuc120/dcd_nuc120.c index fb12122e0..c9e8d86fd 100644 --- a/src/portable/nuvoton/nuc120/dcd_nuc120.c +++ b/src/portable/nuvoton/nuc120/dcd_nuc120.c @@ -201,8 +201,8 @@ static const uint32_t enabled_irqs = USBD_INTSTS_FLDET_STS_Msk | USBD_INTSTS_BUS NUC100/NUC120 TinyUSB API driver implementation */ -void dcd_init(uint8_t rhport) -{ +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; (void) rhport; USBD->ATTR = 0x7D0; diff --git a/src/portable/nuvoton/nuc121/dcd_nuc121.c b/src/portable/nuvoton/nuc121/dcd_nuc121.c index 873b1b7ef..78c65a91c 100644 --- a/src/portable/nuvoton/nuc121/dcd_nuc121.c +++ b/src/portable/nuvoton/nuc121/dcd_nuc121.c @@ -209,8 +209,8 @@ enum { NUC121/NUC125/NUC126 TinyUSB API driver implementation */ -void dcd_init(uint8_t rhport) -{ +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; (void) rhport; #ifdef SUPPORT_LPM diff --git a/src/portable/nuvoton/nuc505/dcd_nuc505.c b/src/portable/nuvoton/nuc505/dcd_nuc505.c index 3a92c9794..caeb89a0a 100644 --- a/src/portable/nuvoton/nuc505/dcd_nuc505.c +++ b/src/portable/nuvoton/nuc505/dcd_nuc505.c @@ -279,8 +279,8 @@ static const uint32_t enabled_irqs = USBD_GINTEN_USBIEN_Msk | \ NUC505 TinyUSB API driver implementation */ -void dcd_init(uint8_t rhport) -{ +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; (void) rhport; /* configure interrupts in their initial state; BUSINTEN and CEPINTEN will be subsequently and dynamically re-written as needed */ diff --git a/src/portable/nxp/khci/dcd_khci.c b/src/portable/nxp/khci/dcd_khci.c index ef61146aa..2d08e84a5 100644 --- a/src/portable/nxp/khci/dcd_khci.c +++ b/src/portable/nxp/khci/dcd_khci.c @@ -265,8 +265,8 @@ static void process_bus_resume(uint8_t rhport) /*------------------------------------------------------------------*/ /* Device API *------------------------------------------------------------------*/ -void dcd_init(uint8_t rhport) -{ +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; (void) rhport; // save crystal-less setting (if available) diff --git a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c index 75b29faf3..e28b27919 100644 --- a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c +++ b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c @@ -167,8 +167,8 @@ static void bus_reset(void) tu_memclr(&_dcd, sizeof(dcd_data_t)); } -void dcd_init(uint8_t rhport) -{ +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; (void) rhport; //------------- user manual 11.13 usb device controller initialization -------------// diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c index cc18cf59b..06a82c4e7 100644 --- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c +++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c @@ -289,8 +289,8 @@ static void edpt_reset_all(uint8_t rhport) } prepare_setup_packet(rhport); } -void dcd_init(uint8_t rhport) -{ +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; edpt_reset_all(rhport); dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index bc0deee32..9473d3bd8 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -369,7 +369,8 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) { #define PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY 0xff #endif -void dcd_init(uint8_t rhport) { +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; assert(rhport == 0); TU_LOG(2, "Chip Version B%u\r\n", rp2040_chip_version()); diff --git a/src/portable/renesas/rusb2/dcd_rusb2.c b/src/portable/renesas/rusb2/dcd_rusb2.c index 7c6044ca0..e8e1bf041 100644 --- a/src/portable/renesas/rusb2/dcd_rusb2.c +++ b/src/portable/renesas/rusb2/dcd_rusb2.c @@ -657,8 +657,8 @@ static void enable_interrupt(uint32_t pswi) } #endif -void dcd_init(uint8_t rhport) -{ +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; rusb2_reg_t* rusb = RUSB2_REG(rhport); rusb2_module_start(rhport, true); diff --git a/src/portable/sony/cxd56/dcd_cxd56.c b/src/portable/sony/cxd56/dcd_cxd56.c index 41814370e..fe1c42249 100644 --- a/src/portable/sony/cxd56/dcd_cxd56.c +++ b/src/portable/sony/cxd56/dcd_cxd56.c @@ -201,8 +201,8 @@ static void _dcd_resume(FAR struct usbdevclass_driver_s *driver, FAR struct usbd dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } -void dcd_init(uint8_t rhport) -{ +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; (void) rhport; usbdcd_driver.usbdevclass_driver.speed = USB_SPEED_HIGH; diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 6eea1ab32..8e9bb0b30 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -184,7 +184,8 @@ TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t *xfer_ctl_ptr(uint8_t epnum, uint //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ -void dcd_init(uint8_t rhport) { +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; // Follow the RM mentions to use a special ordering of PDWN and FRES for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us asm("NOP"); diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index 6f36ad441..d7bf1068a 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -867,8 +867,8 @@ static void usb_isr_handler(void) { dcd_int_handler(0); } -void dcd_init(uint8_t rhport) -{ +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; dcd_disconnect(rhport); USBC_HardwareReset(); USBC_PhyConfig(); diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 1ba3507ef..580960e24 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -650,9 +650,10 @@ static bool check_dwc2(dwc2_regs_t* dwc2) { return true; } -void dcd_init(uint8_t rhport) { +void dcd_init(const tusb_rhport_init_t* rh_init) { // Programming model begins in the last section of the chapter on the USB // peripheral in each Reference Manual. + const uint8_t rhport = rh_init->rhport; dwc2_regs_t* dwc2 = DWC2_REG(rhport); // Check Synopsys ID register, failed if controller clock/power is not enabled diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 6b60bc657..120d5c4b9 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -130,9 +130,8 @@ static void enable_functional_reset(const bool enable) /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ -void dcd_init (uint8_t rhport) -{ - (void) rhport; +void dcd_init(const tusb_rhport_init_t* rh_init) { + (void) rh_init; USBKEYPID = USBKEY; @@ -699,7 +698,12 @@ static void handle_bus_power_event(void *param) { // A successful lock is indicated by all PLL-related interrupt flags being cleared. if(!USBPLLIR) { - dcd_init(0); // Re-initialize the USB module. + const tusb_rhport_init_t rhport_init = { + .rhport = 0, + .role = TUSB_ROLE_DEVICE, + .speed = TUSB_SPEED_FULL + }; + dcd_init(&rhport_init); // Re-initialize the USB module. } } else { // Event caused by removal of bus power. USBPWRCTL |= VBONIE; // Enable bus-power-applied interrupt. diff --git a/src/portable/valentyusb/eptri/dcd_eptri.c b/src/portable/valentyusb/eptri/dcd_eptri.c index 8f40e3349..da7a5a81a 100644 --- a/src/portable/valentyusb/eptri/dcd_eptri.c +++ b/src/portable/valentyusb/eptri/dcd_eptri.c @@ -336,8 +336,8 @@ static void dcd_reset(void) } // Initializes the USB peripheral for device mode and enables it. -void dcd_init(uint8_t rhport) -{ +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; (void) rhport; usb_pullup_out_write(0); diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index 9ed370b40..4a7ad704b 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -123,7 +123,8 @@ static void update_out(uint8_t rhport, uint8_t ep, size_t rx_len) { } /* public functions */ -void dcd_init(uint8_t rhport) { +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; // init registers USBOTG_FS->BASE_CTRL = USBFS_CTRL_SYS_CTRL | USBFS_CTRL_INT_BUSY | USBFS_CTRL_DMA_EN; USBOTG_FS->UDEV_CTRL = USBFS_UDEV_CTRL_PD_DIS | USBFS_UDEV_CTRL_PORT_EN; diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c index 622f9c508..77ebc378c 100644 --- a/src/portable/wch/dcd_ch32_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -131,7 +131,8 @@ static void xfer_data_packet(uint8_t ep_num, tusb_dir_t ep_dir, xfer_ctl_t* xfer ep_set_response_and_toggle(ep_num, ep_dir, USBHS_EP_R_RES_ACK); } -void dcd_init(uint8_t rhport) { +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; (void) rhport; memset(&xfer_status, 0, sizeof(xfer_status)); diff --git a/test/unit-test/test/device/msc/test_msc_device.c b/test/unit-test/test/device/msc/test_msc_device.c index 3444d81c5..4033bf158 100644 --- a/test/unit-test/test/device/msc/test_msc_device.c +++ b/test/unit-test/test/device/msc/test_msc_device.c @@ -197,15 +197,14 @@ void setUp(void) dcd_int_disable_Ignore(); dcd_int_enable_Ignore(); - if ( !tud_inited() ) - { - dcd_init_Expect(rhport); - + if ( !tud_inited() ) { tusb_rhport_init_t dev_init = { .rhport = 0, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; + + dcd_init_Expect(&dev_init); tusb_init(&dev_init); } diff --git a/test/unit-test/test/device/usbd/test_usbd.c b/test/unit-test/test/device/usbd/test_usbd.c index faa6b159e..8f900f656 100644 --- a/test/unit-test/test/device/usbd/test_usbd.c +++ b/test/unit-test/test/device/usbd/test_usbd.c @@ -124,16 +124,16 @@ void setUp(void) dcd_int_disable_Ignore(); dcd_int_enable_Ignore(); - if ( !tud_inited() ) - { - mscd_init_Expect(); - dcd_init_Expect(rhport); - + if ( !tud_inited() ) { tusb_rhport_init_t dev_init = { .rhport = 0, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; + + mscd_init_Expect(); + dcd_init_Expect(&dev_init); + tusb_init(&dev_init); } } -- cgit v1.3.1 From f3b7d7515e9cae834013dc9ee3a67d87111090eb Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 11 Oct 2024 16:00:51 +0700 Subject: fix fuzzing build --- .pre-commit-config.yaml | 28 +++++++-------- src/device/dcd.h | 23 +++++++----- src/portable/microchip/samd/dcd_samd.c | 5 ++- src/portable/microchip/samg/dcd_samg.c | 4 +-- src/portable/microchip/samx7x/dcd_samx7x.c | 4 +-- src/portable/raspberrypi/pio_usb/dcd_pio_usb.c | 6 ++-- src/portable/template/dcd_template.c | 48 ++++++++------------------ test/fuzz/dcd_fuzz.cc | 4 +-- 8 files changed, 54 insertions(+), 68 deletions(-) (limited to 'src/portable') diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 21da285c1..9cd4a5ed1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -43,17 +43,17 @@ repos: types_or: [c, header] language: system - - id: build-fuzzer - name: build-fuzzer - files: ^(src/|test/fuzz/) - language: system - types_or: [c, header] - entry: | - export CC=clang - export CXX=clang++ - fuzz_harness=$(ls -d test/fuzz/device/*/) - for h in $fuzz_harness - do - make -C $h get-deps - make -C $h all - done +# - id: build-fuzzer +# name: build-fuzzer +# files: ^(src/|test/fuzz/) +# language: system +# types_or: [c, header] +# entry: | +# bash -c 'export CC=clang +# export CXX=clang++ +# fuzz_harness=$(ls -d test/fuzz/device/*/) +# for h in $fuzz_harness +# do +# make -C $h get-deps +# make -C $h all +# done' diff --git a/src/device/dcd.h b/src/device/dcd.h index 8fa7b8bc1..02f3847ff 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -194,38 +194,45 @@ extern void dcd_event_handler(dcd_event_t const * event, bool in_isr); // helper to send bus signal event TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr) { - dcd_event_t event = { .rhport = rhport, .event_id = eid }; + dcd_event_t event; + event.rhport = rhport; + event.event_id = eid; dcd_event_handler(&event, in_isr); } // helper to send bus reset event TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr) { - dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_BUS_RESET }; + dcd_event_t event; + event.rhport = rhport; + event.event_id = DCD_EVENT_BUS_RESET; event.bus_reset.speed = speed; dcd_event_handler(&event, in_isr); } // helper to send setup received TU_ATTR_ALWAYS_INLINE static inline void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr) { - dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SETUP_RECEIVED }; + dcd_event_t event; + event.rhport = rhport; + event.event_id = DCD_EVENT_SETUP_RECEIVED; memcpy(&event.setup_received, setup, sizeof(tusb_control_request_t)); - dcd_event_handler(&event, in_isr); } // helper to send transfer complete event TU_ATTR_ALWAYS_INLINE static inline void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr) { - dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_XFER_COMPLETE }; - + dcd_event_t event; + event.rhport = rhport; + event.event_id = DCD_EVENT_XFER_COMPLETE; event.xfer_complete.ep_addr = ep_addr; event.xfer_complete.len = xferred_bytes; event.xfer_complete.result = result; - dcd_event_handler(&event, in_isr); } TU_ATTR_ALWAYS_INLINE static inline void dcd_event_sof(uint8_t rhport, uint32_t frame_count, bool in_isr) { - dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SOF }; + dcd_event_t event; + event.rhport = rhport; + event.event_id = DCD_EVENT_SOF; event.sof.frame_count = frame_count; dcd_event_handler(&event, in_isr); } diff --git a/src/portable/microchip/samd/dcd_samd.c b/src/portable/microchip/samd/dcd_samd.c index 005b63faf..c3a74ad0f 100644 --- a/src/portable/microchip/samd/dcd_samd.c +++ b/src/portable/microchip/samd/dcd_samd.c @@ -78,9 +78,8 @@ static void bus_reset(void) /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ -void dcd_init (uint8_t rhport) -{ - (void) rhport; +void dcd_init(const tusb_rhport_init_t* rh_init) { + (void) rh_init; // Reset to get in a clean state. USB->DEVICE.CTRLA.bit.SWRST = true; diff --git a/src/portable/microchip/samg/dcd_samg.c b/src/portable/microchip/samg/dcd_samg.c index a15431937..2242d3336 100644 --- a/src/portable/microchip/samg/dcd_samg.c +++ b/src/portable/microchip/samg/dcd_samg.c @@ -155,8 +155,8 @@ static void bus_reset(void) } // Initialize controller to device mode -void dcd_init (uint8_t rhport) -{ +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; tu_memclr(_dcd_xfer, sizeof(_dcd_xfer)); dcd_connect(rhport); } diff --git a/src/portable/microchip/samx7x/dcd_samx7x.c b/src/portable/microchip/samx7x/dcd_samx7x.c index 9586df84d..d57db6e55 100644 --- a/src/portable/microchip/samx7x/dcd_samx7x.c +++ b/src/portable/microchip/samx7x/dcd_samx7x.c @@ -104,8 +104,8 @@ TU_ATTR_ALWAYS_INLINE static inline void CleanInValidateCache(uint32_t *addr, in //------------------------------------------------------------------ // Initialize controller to device mode -void dcd_init (uint8_t rhport) -{ +void dcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; dcd_connect(rhport); } diff --git a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c index e6daf6827..83589efa0 100644 --- a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c @@ -50,10 +50,8 @@ static usb_descriptor_buffers_t desc; *------------------------------------------------------------------*/ // Initialize controller to device mode -void dcd_init (uint8_t rhport) -{ - (void) rhport; - +void dcd_init(const tusb_rhport_init_t* rh_init) { + (void) rh_init; static pio_usb_configuration_t config = PIO_USB_DEFAULT_CONFIG; usb_device = pio_usb_device_init(&config, &desc); } diff --git a/src/portable/template/dcd_template.c b/src/portable/template/dcd_template.c index 25ee507c1..56a89e89a 100644 --- a/src/portable/template/dcd_template.c +++ b/src/portable/template/dcd_template.c @@ -40,54 +40,44 @@ *------------------------------------------------------------------*/ // Initialize controller to device mode -void dcd_init (uint8_t rhport) -{ - (void) rhport; +void dcd_init(const tusb_rhport_init_t* rh_init) { + (void) rh_init; } // Enable device interrupt -void dcd_int_enable (uint8_t rhport) -{ +void dcd_int_enable (uint8_t rhport) { (void) rhport; } // Disable device interrupt -void dcd_int_disable (uint8_t rhport) -{ +void dcd_int_disable (uint8_t rhport) { (void) rhport; } // Receive Set Address request, mcu port must also include status IN response -void dcd_set_address (uint8_t rhport, uint8_t dev_addr) -{ +void dcd_set_address (uint8_t rhport, uint8_t dev_addr) { (void) rhport; (void) dev_addr; } // Wake up host -void dcd_remote_wakeup (uint8_t rhport) -{ +void dcd_remote_wakeup (uint8_t rhport) { (void) rhport; } // Connect by enabling internal pull-up resistor on D+/D- -void dcd_connect(uint8_t rhport) -{ +void dcd_connect(uint8_t rhport) { (void) rhport; } // Disconnect by disabling internal pull-up resistor on D+/D- -void dcd_disconnect(uint8_t rhport) -{ +void dcd_disconnect(uint8_t rhport) { (void) rhport; } -void dcd_sof_enable(uint8_t rhport, bool en) -{ +void dcd_sof_enable(uint8_t rhport, bool en) { (void) rhport; (void) en; - - // TODO implement later } //--------------------------------------------------------------------+ @@ -95,8 +85,7 @@ void dcd_sof_enable(uint8_t rhport, bool en) //--------------------------------------------------------------------+ // Configure endpoint's registers according to descriptor -bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) -{ +bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) { (void) rhport; (void) ep_desc; return false; @@ -118,14 +107,12 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) return false; } -void dcd_edpt_close_all (uint8_t rhport) -{ +void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; } // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack -bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) -{ +bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) { (void) rhport; (void) ep_addr; (void) buffer; @@ -134,8 +121,7 @@ bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t } // Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c -bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) -{ +bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) { (void) rhport; (void) ep_addr; (void) ff; @@ -144,19 +130,15 @@ bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16 } // Stall endpoint -void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) -{ +void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr) { (void) rhport; (void) ep_addr; } // clear stall, data toggle is also reset to DATA0 -void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) -{ +void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) { (void) rhport; (void) ep_addr; } - - #endif diff --git a/test/fuzz/dcd_fuzz.cc b/test/fuzz/dcd_fuzz.cc index 06ddddc4a..7ef0c7446 100644 --- a/test/fuzz/dcd_fuzz.cc +++ b/test/fuzz/dcd_fuzz.cc @@ -46,8 +46,8 @@ tu_static State state = {false, 0, 0}; // All no-ops as we are fuzzing. //--------------------------------------------------------------------+ extern "C" { -void dcd_init(uint8_t rhport) { - UNUSED(rhport); +void dcd_init(const tusb_rhport_init_t* rh_init) { + UNUSED(rh_init); return; } -- cgit v1.3.1 From 1587d48e89cbaa8d0d1c870809bc40c3c8d1056f Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 11 Oct 2024 17:53:39 +0700 Subject: hcd_init() take init struct --- src/host/hcd.h | 19 ++++++------------- src/host/usbh.c | 2 +- src/portable/analog/max3421/hcd_max3421.c | 4 ++-- src/portable/chipidea/ci_hs/hcd_ci_hs.c | 3 ++- src/portable/mentor/musb/hcd_musb.c | 5 ++--- src/portable/nxp/khci/hcd_khci.c | 6 ++---- src/portable/ohci/ohci.c | 4 ++-- src/portable/raspberrypi/pio_usb/hcd_pio_usb.c | 4 ++-- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 5 ++--- src/portable/renesas/rusb2/hcd_rusb2.c | 4 ++-- src/portable/template/hcd_template.c | 5 ++--- 11 files changed, 25 insertions(+), 36 deletions(-) (limited to 'src/portable') diff --git a/src/host/hcd.h b/src/host/hcd.h index 5547c7cc5..97cb01754 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -53,26 +53,21 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -typedef enum -{ +typedef enum { HCD_EVENT_DEVICE_ATTACH, HCD_EVENT_DEVICE_REMOVE, HCD_EVENT_XFER_COMPLETE, - // Not an HCD event, just a convenient way to defer ISR function - USBH_EVENT_FUNC_CALL, - + USBH_EVENT_FUNC_CALL, // Not an HCD event HCD_EVENT_COUNT } hcd_eventid_t; -typedef struct -{ +typedef struct { uint8_t rhport; uint8_t event_id; uint8_t dev_addr; - union - { + union { // Attach, Remove struct { uint8_t hub_addr; @@ -93,11 +88,9 @@ typedef struct void* param; }func_call; }; - } hcd_event_t; -typedef struct -{ +typedef struct { uint8_t rhport; uint8_t hub_addr; uint8_t hub_port; @@ -128,7 +121,7 @@ bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_W bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param); // Initialize controller to host mode -bool hcd_init(uint8_t rhport); +bool hcd_init(const tusb_rhport_init_t* rh_init); // De-initialize controller bool hcd_deinit(uint8_t rhport); diff --git a/src/host/usbh.c b/src/host/usbh.c index 39bc8d63a..f9e6c4e97 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -405,7 +405,7 @@ bool tuh_rhport_init(const tusb_rhport_init_t* rh_init) { // Init host controller _usbh_controller = rh_init->rhport; - TU_ASSERT(hcd_init(rh_init->rhport)); + TU_ASSERT(hcd_init(rh_init)); hcd_int_enable(rh_init->rhport); return true; diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 215feb481..30d822c3b 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -494,8 +494,8 @@ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { } // Initialize controller to host mode -bool hcd_init(uint8_t rhport) { - (void) rhport; +bool hcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; tuh_max3421_int_api(rhport, false); diff --git a/src/portable/chipidea/ci_hs/hcd_ci_hs.c b/src/portable/chipidea/ci_hs/hcd_ci_hs.c index 462cbd301..fbc51f6df 100644 --- a/src/portable/chipidea/ci_hs/hcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/hcd_ci_hs.c @@ -70,7 +70,8 @@ bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) { // Controller API //--------------------------------------------------------------------+ -bool hcd_init(uint8_t rhport) { +bool hcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; ci_hs_regs_t *hcd_reg = CI_HS_REG(rhport); // Reset controller diff --git a/src/portable/mentor/musb/hcd_musb.c b/src/portable/mentor/musb/hcd_musb.c index 8fc225676..9324c6a34 100644 --- a/src/portable/mentor/musb/hcd_musb.c +++ b/src/portable/mentor/musb/hcd_musb.c @@ -556,9 +556,8 @@ static void process_pipe_rx(uint8_t rhport, uint_fast8_t pipenum) * Host API *------------------------------------------------------------------*/ -bool hcd_init(uint8_t rhport) -{ - (void)rhport; +bool hcd_init(const tusb_rhport_init_t* rh_init) { + (void) rh_init; NVIC_ClearPendingIRQ(USB0_IRQn); _hcd.bmRequestType = REQUEST_TYPE_INVALID; diff --git a/src/portable/nxp/khci/hcd_khci.c b/src/portable/nxp/khci/hcd_khci.c index 57684b259..e9c00b8f9 100644 --- a/src/portable/nxp/khci/hcd_khci.c +++ b/src/portable/nxp/khci/hcd_khci.c @@ -368,10 +368,8 @@ static void process_bus_reset(uint8_t rhport) /*------------------------------------------------------------------*/ /* Host API *------------------------------------------------------------------*/ -bool hcd_init(uint8_t rhport) -{ - (void)rhport; - +bool hcd_init(const tusb_rhport_init_t* rh_init) { + (void) rh_init; KHCI->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; while (KHCI->USBTRC0 & USB_USBTRC0_USBRESET_MASK); diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c index c59d4755e..fbaa5208e 100644 --- a/src/portable/ohci/ohci.c +++ b/src/portable/ohci/ohci.c @@ -178,8 +178,8 @@ TU_ATTR_ALWAYS_INLINE static inline void *_virt_addr(void *physical_address) } // Initialization according to 5.1.1.4 -bool hcd_init(uint8_t rhport) -{ +bool hcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; (void) rhport; //------------- Data Structure init -------------// diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c index f4de3c51d..4386bbce4 100644 --- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c @@ -55,8 +55,8 @@ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void *cfg_param) { return true; } -bool hcd_init(uint8_t rhport) { - (void) rhport; +bool hcd_init(const tusb_rhport_init_t* rh_init) { + (void) rh_init; // To run USB SOF interrupt in core1, call this init in core1 pio_usb_host_init(&pio_host_cfg); diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index 222dbbbf0..a870418a8 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -375,9 +375,8 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t //--------------------------------------------------------------------+ // HCD API //--------------------------------------------------------------------+ -bool hcd_init(uint8_t rhport) -{ - (void) rhport; +bool hcd_init(const tusb_rhport_init_t* rh_init) { + (void) rh_init; pico_trace("hcd_init %d\n", rhport); assert(rhport == 0); diff --git a/src/portable/renesas/rusb2/hcd_rusb2.c b/src/portable/renesas/rusb2/hcd_rusb2.c index f140da690..35e85a3b0 100644 --- a/src/portable/renesas/rusb2/hcd_rusb2.c +++ b/src/portable/renesas/rusb2/hcd_rusb2.c @@ -466,8 +466,8 @@ static void enable_interrupt(uint32_t pswi) } #endif -bool hcd_init(uint8_t rhport) -{ +bool hcd_init(const tusb_rhport_init_t* rh_init) { + const uint8_t rhport = rh_init->rhport; rusb2_reg_t* rusb = RUSB2_REG(rhport); rusb2_module_start(rhport, true); diff --git a/src/portable/template/hcd_template.c b/src/portable/template/hcd_template.c index b073d6057..9386e95cc 100644 --- a/src/portable/template/hcd_template.c +++ b/src/portable/template/hcd_template.c @@ -44,9 +44,8 @@ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { } // Initialize controller to host mode -bool hcd_init(uint8_t rhport) { - (void) rhport; - +bool hcd_init(const tusb_rhport_init_t* rh_init) { + (void) rh_init; return false; } -- cgit v1.3.1 From 1f18be93db39dbc57bbf34f982dbe07e209a2ae3 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 14 Oct 2024 18:27:52 +0700 Subject: change the tusb_rhport_init_t struct, exclude the rhport to make API more consistent --- .github/workflows/pre-commit.yml | 2 +- .idea/cmake.xml | 13 +++++++------ examples/device/audio_4_channel_mic/src/main.c | 3 +-- .../device/audio_4_channel_mic_freertos/src/main.c | 3 +-- examples/device/audio_test/src/main.c | 3 +-- examples/device/audio_test_freertos/src/main.c | 3 +-- examples/device/audio_test_multi_rate/src/main.c | 3 +-- examples/device/cdc_dual_ports/src/main.c | 3 +-- examples/device/cdc_msc/src/main.c | 3 +-- examples/device/cdc_msc_freertos/src/main.c | 3 +-- examples/device/cdc_uac2/src/main.c | 3 +-- examples/device/dfu/src/main.c | 3 +-- examples/device/dfu_runtime/src/main.c | 3 +-- examples/device/dynamic_configuration/src/main.c | 3 +-- examples/device/hid_boot_interface/src/main.c | 3 +-- examples/device/hid_composite/src/main.c | 3 +-- examples/device/hid_composite_freertos/src/main.c | 3 +-- examples/device/hid_generic_inout/src/main.c | 3 +-- examples/device/hid_multiple_interface/src/main.c | 3 +-- examples/device/midi_test/src/main.c | 3 +-- examples/device/msc_dual_lun/src/main.c | 3 +-- examples/device/net_lwip_webserver/src/main.c | 3 +-- examples/device/uac2_headset/src/main.c | 3 +-- examples/device/uac2_speaker_fb/src/main.c | 3 +-- examples/device/usbtmc/src/main.c | 3 +-- examples/device/video_capture/src/main.c | 6 ++---- examples/device/video_capture_2ch/src/main.c | 6 ++---- examples/device/webusb_serial/src/main.c | 3 +-- examples/dual/host_hid_to_device_cdc/src/main.c | 6 ++---- examples/dual/host_info_to_device_cdc/src/main.c | 6 ++---- examples/host/bare_api/src/main.c | 3 +-- examples/host/cdc_msc_hid/src/main.c | 3 +-- examples/host/cdc_msc_hid_freertos/src/main.c | 3 +-- examples/host/device_info/src/main.c | 3 +-- examples/host/hid_controller/src/main.c | 3 +-- examples/host/msc_file_explorer/src/main.c | 3 +-- src/class/video/video_device.c | 2 +- src/common/tusb_types.h | 1 - src/device/dcd.h | 2 +- src/device/usbd.c | 8 ++++---- src/device/usbd.h | 7 +++---- src/host/hcd.h | 2 +- src/host/usbh.c | 10 +++++----- src/host/usbh.h | 7 +++---- src/portable/analog/max3421/hcd_max3421.c | 4 ++-- src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 4 ++-- src/portable/chipidea/ci_fs/dcd_ci_fs.c | 4 ++-- src/portable/chipidea/ci_hs/dcd_ci_hs.c | 4 ++-- src/portable/chipidea/ci_hs/hcd_ci_hs.c | 8 +++++--- src/portable/dialog/da146xx/dcd_da146xx.c | 4 ++-- src/portable/espressif/esp32sx/dcd_esp32sx.c | 4 ++-- src/portable/mentor/musb/dcd_musb.c | 4 ++-- src/portable/mentor/musb/hcd_musb.c | 3 ++- src/portable/microchip/pic/dcd_pic.c | 4 ++-- src/portable/microchip/pic32mz/dcd_pic32mz.c | 4 ++-- src/portable/microchip/samd/dcd_samd.c | 4 ++-- src/portable/microchip/samg/dcd_samg.c | 5 +++-- src/portable/microchip/samx7x/dcd_samx7x.c | 4 ++-- src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c | 4 ++-- src/portable/nordic/nrf5x/dcd_nrf5x.c | 6 +++--- src/portable/nuvoton/nuc120/dcd_nuc120.c | 4 ++-- src/portable/nuvoton/nuc121/dcd_nuc121.c | 4 ++-- src/portable/nuvoton/nuc505/dcd_nuc505.c | 4 ++-- src/portable/nxp/khci/dcd_khci.c | 4 ++-- src/portable/nxp/khci/hcd_khci.c | 3 ++- src/portable/nxp/lpc17_40/dcd_lpc17_40.c | 4 ++-- src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 4 ++-- src/portable/ohci/ohci.c | 4 ++-- src/portable/raspberrypi/pio_usb/dcd_pio_usb.c | 3 ++- src/portable/raspberrypi/pio_usb/hcd_pio_usb.c | 3 ++- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 4 ++-- src/portable/raspberrypi/rp2040/hcd_rp2040.c | 3 ++- src/portable/renesas/rusb2/dcd_rusb2.c | 4 ++-- src/portable/renesas/rusb2/hcd_rusb2.c | 4 ++-- src/portable/sony/cxd56/dcd_cxd56.c | 4 ++-- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 4 ++-- src/portable/sunxi/dcd_sunxi_musb.c | 4 ++-- src/portable/synopsys/dwc2/dcd_dwc2.c | 4 ++-- src/portable/template/dcd_template.c | 4 ++-- src/portable/template/hcd_template.c | 3 ++- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 7 +++---- src/portable/valentyusb/eptri/dcd_eptri.c | 4 ++-- src/portable/wch/dcd_ch32_usbfs.c | 4 ++-- src/portable/wch/dcd_ch32_usbhs.c | 4 ++-- src/tusb.c | 16 +++++++--------- src/tusb.h | 11 ++++++----- test/fuzz/dcd_fuzz.cc | 3 ++- test/unit-test/test/device/msc/test_msc_device.c | 5 ++--- test/unit-test/test/device/usbd/test_usbd.c | 20 +++++++------------- 89 files changed, 174 insertions(+), 213 deletions(-) (limited to 'src/portable') diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 379a22ee2..530484079 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -29,7 +29,7 @@ jobs: #ceedling test:all - name: Run pre-commit - uses: pre-commit/action@v3.0.0 + uses: pre-commit/action@v3.0.1 - name: Build Fuzzer run: | diff --git a/.idea/cmake.xml b/.idea/cmake.xml index c0b55a82e..05dceda5a 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -2,6 +2,9 @@ + + + @@ -80,7 +83,7 @@ - + @@ -94,11 +97,11 @@ - + - + @@ -109,9 +112,6 @@ - - - @@ -148,6 +148,7 @@ + \ No newline at end of file diff --git a/examples/device/audio_4_channel_mic/src/main.c b/examples/device/audio_4_channel_mic/src/main.c index ca0e67fae..e8c40309e 100644 --- a/examples/device/audio_4_channel_mic/src/main.c +++ b/examples/device/audio_4_channel_mic/src/main.c @@ -87,11 +87,10 @@ int main(void) // init device stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/audio_4_channel_mic_freertos/src/main.c b/examples/device/audio_4_channel_mic_freertos/src/main.c index c1ebc4899..2ac7516cd 100644 --- a/examples/device/audio_4_channel_mic_freertos/src/main.c +++ b/examples/device/audio_4_channel_mic_freertos/src/main.c @@ -210,11 +210,10 @@ void usb_device_task(void* param) // This should be called after scheduler/kernel is started. // Otherwise it could cause kernel issue since USB IRQ handler does use RTOS queue API. tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/audio_test/src/main.c b/examples/device/audio_test/src/main.c index f4c1bf95f..018c48994 100644 --- a/examples/device/audio_test/src/main.c +++ b/examples/device/audio_test/src/main.c @@ -80,11 +80,10 @@ int main(void) // init device stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/audio_test_freertos/src/main.c b/examples/device/audio_test_freertos/src/main.c index b7d7dc042..4e2264b5d 100644 --- a/examples/device/audio_test_freertos/src/main.c +++ b/examples/device/audio_test_freertos/src/main.c @@ -157,11 +157,10 @@ void usb_device_task(void* param) // This should be called after scheduler/kernel is started. // Otherwise it could cause kernel issue since USB IRQ handler does use RTOS queue API. tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/audio_test_multi_rate/src/main.c b/examples/device/audio_test_multi_rate/src/main.c index a1c4d32db..f9dcd1b8a 100644 --- a/examples/device/audio_test_multi_rate/src/main.c +++ b/examples/device/audio_test_multi_rate/src/main.c @@ -98,11 +98,10 @@ int main(void) // init device stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/cdc_dual_ports/src/main.c b/examples/device/cdc_dual_ports/src/main.c index b446bca0b..63ae8a8c9 100644 --- a/examples/device/cdc_dual_ports/src/main.c +++ b/examples/device/cdc_dual_ports/src/main.c @@ -53,11 +53,10 @@ int main(void) { // init device stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/cdc_msc/src/main.c b/examples/device/cdc_msc/src/main.c index 47ba5a887..f36c910d7 100644 --- a/examples/device/cdc_msc/src/main.c +++ b/examples/device/cdc_msc/src/main.c @@ -52,11 +52,10 @@ int main(void) { // init device stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/cdc_msc_freertos/src/main.c b/examples/device/cdc_msc_freertos/src/main.c index a08e063ac..f70267e33 100644 --- a/examples/device/cdc_msc_freertos/src/main.c +++ b/examples/device/cdc_msc_freertos/src/main.c @@ -133,11 +133,10 @@ static void usb_device_task(void *param) { // This should be called after scheduler/kernel is started. // Otherwise it could cause kernel issue since USB IRQ handler does use RTOS queue API. tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/cdc_uac2/src/main.c b/examples/device/cdc_uac2/src/main.c index 384d910ec..b148593da 100644 --- a/examples/device/cdc_uac2/src/main.c +++ b/examples/device/cdc_uac2/src/main.c @@ -47,11 +47,10 @@ int main(void) // init device stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); #if (CFG_TUSB_MCU == OPT_MCU_RP2040) stdio_init_all(); diff --git a/examples/device/dfu/src/main.c b/examples/device/dfu/src/main.c index f2aea7cfc..af9e99857 100644 --- a/examples/device/dfu/src/main.c +++ b/examples/device/dfu/src/main.c @@ -76,11 +76,10 @@ int main(void) // init device stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/dfu_runtime/src/main.c b/examples/device/dfu_runtime/src/main.c index 5d6b907b7..4740c18c4 100644 --- a/examples/device/dfu_runtime/src/main.c +++ b/examples/device/dfu_runtime/src/main.c @@ -71,11 +71,10 @@ int main(void) // init device stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/dynamic_configuration/src/main.c b/examples/device/dynamic_configuration/src/main.c index 143570c5c..32ff58232 100644 --- a/examples/device/dynamic_configuration/src/main.c +++ b/examples/device/dynamic_configuration/src/main.c @@ -58,11 +58,10 @@ int main(void) // init device stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/hid_boot_interface/src/main.c b/examples/device/hid_boot_interface/src/main.c index dfee7421d..570e4e801 100644 --- a/examples/device/hid_boot_interface/src/main.c +++ b/examples/device/hid_boot_interface/src/main.c @@ -58,11 +58,10 @@ int main(void) // init device stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/hid_composite/src/main.c b/examples/device/hid_composite/src/main.c index 56c485982..5302af3b8 100644 --- a/examples/device/hid_composite/src/main.c +++ b/examples/device/hid_composite/src/main.c @@ -59,11 +59,10 @@ int main(void) // init device stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/hid_composite_freertos/src/main.c b/examples/device/hid_composite_freertos/src/main.c index fc07a1a39..ae091571e 100644 --- a/examples/device/hid_composite_freertos/src/main.c +++ b/examples/device/hid_composite_freertos/src/main.c @@ -137,11 +137,10 @@ void usb_device_task(void* param) // This should be called after scheduler/kernel is started. // Otherwise it could cause kernel issue since USB IRQ handler does use RTOS queue API. tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/hid_generic_inout/src/main.c b/examples/device/hid_generic_inout/src/main.c index 1bbcbf7a4..73f51002d 100644 --- a/examples/device/hid_generic_inout/src/main.c +++ b/examples/device/hid_generic_inout/src/main.c @@ -82,11 +82,10 @@ int main(void) // init device stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/hid_multiple_interface/src/main.c b/examples/device/hid_multiple_interface/src/main.c index edcedd3ca..92c7e8332 100644 --- a/examples/device/hid_multiple_interface/src/main.c +++ b/examples/device/hid_multiple_interface/src/main.c @@ -63,11 +63,10 @@ int main(void) // init device stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/midi_test/src/main.c b/examples/device/midi_test/src/main.c index b05307d1b..d7849a2c4 100644 --- a/examples/device/midi_test/src/main.c +++ b/examples/device/midi_test/src/main.c @@ -64,11 +64,10 @@ int main(void) // init device stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/msc_dual_lun/src/main.c b/examples/device/msc_dual_lun/src/main.c index fe3896ca7..012095dca 100644 --- a/examples/device/msc_dual_lun/src/main.c +++ b/examples/device/msc_dual_lun/src/main.c @@ -55,11 +55,10 @@ int main(void) { // init device stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/net_lwip_webserver/src/main.c b/examples/device/net_lwip_webserver/src/main.c index 6041b56e2..8af7a9de6 100644 --- a/examples/device/net_lwip_webserver/src/main.c +++ b/examples/device/net_lwip_webserver/src/main.c @@ -217,11 +217,10 @@ int main(void) { // init device stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/uac2_headset/src/main.c b/examples/device/uac2_headset/src/main.c index 4d28f73a4..6b2ab0973 100644 --- a/examples/device/uac2_headset/src/main.c +++ b/examples/device/uac2_headset/src/main.c @@ -101,11 +101,10 @@ int main(void) // init device stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/uac2_speaker_fb/src/main.c b/examples/device/uac2_speaker_fb/src/main.c index 1250b041d..53bbec9b6 100644 --- a/examples/device/uac2_speaker_fb/src/main.c +++ b/examples/device/uac2_speaker_fb/src/main.c @@ -107,11 +107,10 @@ int main(void) // init device stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/usbtmc/src/main.c b/examples/device/usbtmc/src/main.c index 2af581bc1..aa7902a15 100644 --- a/examples/device/usbtmc/src/main.c +++ b/examples/device/usbtmc/src/main.c @@ -56,11 +56,10 @@ int main(void) // init device stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/video_capture/src/main.c b/examples/device/video_capture/src/main.c index c5d87c660..aeeeb8930 100644 --- a/examples/device/video_capture/src/main.c +++ b/examples/device/video_capture/src/main.c @@ -69,11 +69,10 @@ int main(void) { #else // init device stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); @@ -325,11 +324,10 @@ void usb_device_task(void *param) { // This should be called after scheduler/kernel is started. // Otherwise, it could cause kernel issue since USB IRQ handler does use RTOS queue API. tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/video_capture_2ch/src/main.c b/examples/device/video_capture_2ch/src/main.c index a45e62ab0..dd6983766 100644 --- a/examples/device/video_capture_2ch/src/main.c +++ b/examples/device/video_capture_2ch/src/main.c @@ -69,11 +69,10 @@ int main(void) { #else // init device stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); @@ -333,11 +332,10 @@ void usb_device_task(void *param) { // This should be called after scheduler/kernel is started. // Otherwise, it could cause kernel issue since USB IRQ handler does use RTOS queue API. tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/device/webusb_serial/src/main.c b/examples/device/webusb_serial/src/main.c index 46215ec13..d189af91f 100644 --- a/examples/device/webusb_serial/src/main.c +++ b/examples/device/webusb_serial/src/main.c @@ -92,11 +92,10 @@ int main(void) { // init device stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/dual/host_hid_to_device_cdc/src/main.c b/examples/dual/host_hid_to_device_cdc/src/main.c index 061958aae..633f7a6ac 100644 --- a/examples/dual/host_hid_to_device_cdc/src/main.c +++ b/examples/dual/host_hid_to_device_cdc/src/main.c @@ -80,18 +80,16 @@ int main(void) { // init device and host stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); tusb_rhport_init_t host_init = { - .rhport = BOARD_TUH_RHPORT, .role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_AUTO }; - tusb_init(&host_init); + tusb_init(BOARD_TUH_RHPORT, &host_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/dual/host_info_to_device_cdc/src/main.c b/examples/dual/host_info_to_device_cdc/src/main.c index e4d802a0c..668808db2 100644 --- a/examples/dual/host_info_to_device_cdc/src/main.c +++ b/examples/dual/host_info_to_device_cdc/src/main.c @@ -83,18 +83,16 @@ int main(void) { // init device and host stack on configured roothub port tusb_rhport_init_t dev_init = { - .rhport = BOARD_TUD_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - tusb_init(&dev_init); + tusb_init(BOARD_TUD_RHPORT, &dev_init); tusb_rhport_init_t host_init = { - .rhport = BOARD_TUH_RHPORT, .role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_AUTO }; - tusb_init(&host_init); + tusb_init(BOARD_TUH_RHPORT, &host_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/host/bare_api/src/main.c b/examples/host/bare_api/src/main.c index e710e3caa..f582f4f5a 100644 --- a/examples/host/bare_api/src/main.c +++ b/examples/host/bare_api/src/main.c @@ -63,11 +63,10 @@ int main(void) // init host stack on configured roothub port tusb_rhport_init_t host_init = { - .rhport = BOARD_TUH_RHPORT, .role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_AUTO }; - tusb_init(&host_init); + tusb_init(BOARD_TUH_RHPORT, &host_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/host/cdc_msc_hid/src/main.c b/examples/host/cdc_msc_hid/src/main.c index 3a6e762b7..71257c0fe 100644 --- a/examples/host/cdc_msc_hid/src/main.c +++ b/examples/host/cdc_msc_hid/src/main.c @@ -51,11 +51,10 @@ int main(void) { // init host stack on configured roothub port tusb_rhport_init_t host_init = { - .rhport = BOARD_TUH_RHPORT, .role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_AUTO }; - tusb_init(&host_init); + tusb_init(BOARD_TUH_RHPORT, &host_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/host/cdc_msc_hid_freertos/src/main.c b/examples/host/cdc_msc_hid_freertos/src/main.c index 9d2f347c3..7fb84a40f 100644 --- a/examples/host/cdc_msc_hid_freertos/src/main.c +++ b/examples/host/cdc_msc_hid_freertos/src/main.c @@ -127,12 +127,11 @@ static void usb_host_task(void *param) { // init host stack on configured roothub port tusb_rhport_init_t host_init = { - .rhport = BOARD_TUH_RHPORT, .role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_AUTO }; - if (!tusb_init(&host_init)) { + if (!tusb_init(BOARD_TUH_RHPORT, &host_init)) { printf("Failed to init USB Host Stack\r\n"); vTaskSuspend(NULL); } diff --git a/examples/host/device_info/src/main.c b/examples/host/device_info/src/main.c index 8ca3d8a3a..0ff4f32e9 100644 --- a/examples/host/device_info/src/main.c +++ b/examples/host/device_info/src/main.c @@ -67,11 +67,10 @@ int main(void) { // init host stack on configured roothub port tusb_rhport_init_t host_init = { - .rhport = BOARD_TUH_RHPORT, .role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_AUTO }; - tusb_init(&host_init); + tusb_init(BOARD_TUH_RHPORT, &host_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/host/hid_controller/src/main.c b/examples/host/hid_controller/src/main.c index 6db47792c..ba12774bd 100644 --- a/examples/host/hid_controller/src/main.c +++ b/examples/host/hid_controller/src/main.c @@ -53,11 +53,10 @@ int main(void) // init host stack on configured roothub port tusb_rhport_init_t host_init = { - .rhport = BOARD_TUH_RHPORT, .role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_AUTO }; - tusb_init(&host_init); + tusb_init(BOARD_TUH_RHPORT, &host_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/examples/host/msc_file_explorer/src/main.c b/examples/host/msc_file_explorer/src/main.c index 11512ab65..9509035b4 100644 --- a/examples/host/msc_file_explorer/src/main.c +++ b/examples/host/msc_file_explorer/src/main.c @@ -79,11 +79,10 @@ int main(void) { // init host stack on configured roothub port tusb_rhport_init_t host_init = { - .rhport = BOARD_TUH_RHPORT, .role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_AUTO }; - tusb_init(&host_init); + tusb_init(BOARD_TUH_RHPORT, &host_init); if (board_init_after_tusb) { board_init_after_tusb(); diff --git a/src/class/video/video_device.c b/src/class/video/video_device.c index c544a09fe..70dbb5b9e 100644 --- a/src/class/video/video_device.c +++ b/src/class/video/video_device.c @@ -707,7 +707,7 @@ static bool _open_vc_itf(uint8_t rhport, videod_interface_t *self, uint_fast8_t /* The first descriptor is a video control interface descriptor. */ uint8_t const *cur = _find_desc_itf(beg, end, _desc_itfnum(beg), altnum); - TU_LOG_DRV(" cur %d\r\n", cur - beg); + TU_LOG_DRV(" cur %" PRId32 "\r\n", (int32_t) (cur - beg)); TU_VERIFY(cur < end); tusb_desc_vc_itf_t const *vc = (tusb_desc_vc_itf_t const *)cur; diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index 5dfe3ff98..53bb367cb 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -278,7 +278,6 @@ enum { // //--------------------------------------------------------------------+ typedef struct { - uint8_t rhport; tusb_role_t role; tusb_speed_t speed; } tusb_rhport_init_t; diff --git a/src/device/dcd.h b/src/device/dcd.h index 02f3847ff..64dffbaef 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -108,7 +108,7 @@ void dcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_W //--------------------------------------------------------------------+ // Initialize controller to device mode -void dcd_init(const tusb_rhport_init_t* rh_init); +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init); // Deinitialize controller, unset device mode. bool dcd_deinit(uint8_t rhport); diff --git a/src/device/usbd.c b/src/device/usbd.c index 12f95ab40..4b6600eb2 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -448,7 +448,7 @@ bool tud_inited(void) { return _usbd_rhport != RHPORT_INVALID; } -bool tud_rhport_init(const tusb_rhport_init_t* rh_init) { +bool tud_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { if (tud_inited()) { return true; // skip if already initialized } @@ -487,11 +487,11 @@ bool tud_rhport_init(const tusb_rhport_init_t* rh_init) { driver->init(); } - _usbd_rhport = rh_init->rhport; + _usbd_rhport = rhport; // Init device controller driver - dcd_init(rh_init); - dcd_int_enable(rh_init->rhport); + dcd_init(rhport, rh_init); + dcd_int_enable(rhport); return true; } diff --git a/src/device/usbd.h b/src/device/usbd.h index 05eb0173f..de6007fb3 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -38,19 +38,18 @@ extern "C" { //--------------------------------------------------------------------+ // New API to replace tud_init() to init device stack on specific roothub port -bool tud_rhport_init(const tusb_rhport_init_t* rh_init); +bool tud_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init); // Init device stack on roothub port #if TUSB_VERSION_NUMBER > 2000 // 0.20.0 -TU_ATTR_DEPRECATED("Please use tusb_init(tusb_rhport_init_t*) instead") +TU_ATTR_DEPRECATED("Please use tusb_init(rhport, rh_init) instead") #endif TU_ATTR_ALWAYS_INLINE static inline bool tud_init (uint8_t rhport) { const tusb_rhport_init_t rh_init = { - .rhport = rhport, .role = TUSB_ROLE_DEVICE, .speed = TUD_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL }; - return tud_rhport_init(&rh_init); + return tud_rhport_init(rhport, &rh_init); } // Deinit device stack on roothub port diff --git a/src/host/hcd.h b/src/host/hcd.h index 97cb01754..6518e6fd2 100644 --- a/src/host/hcd.h +++ b/src/host/hcd.h @@ -121,7 +121,7 @@ bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_W bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param); // Initialize controller to host mode -bool hcd_init(const tusb_rhport_init_t* rh_init); +bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init); // De-initialize controller bool hcd_deinit(uint8_t rhport); diff --git a/src/host/usbh.c b/src/host/usbh.c index f9e6c4e97..b5df29f50 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -352,8 +352,8 @@ bool tuh_inited(void) { return _usbh_controller != TUSB_INDEX_INVALID_8; } -bool tuh_rhport_init(const tusb_rhport_init_t* rh_init) { - if (tuh_rhport_is_active(rh_init->rhport)) { +bool tuh_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + if (tuh_rhport_is_active(rhport)) { return true; // skip if already initialized } @@ -404,9 +404,9 @@ bool tuh_rhport_init(const tusb_rhport_init_t* rh_init) { } // Init host controller - _usbh_controller = rh_init->rhport; - TU_ASSERT(hcd_init(rh_init)); - hcd_int_enable(rh_init->rhport); + _usbh_controller = rhport; + TU_ASSERT(hcd_init(rhport, rh_init)); + hcd_int_enable(rhport); return true; } diff --git a/src/host/usbh.h b/src/host/usbh.h index 9b865ac1b..20fad284e 100644 --- a/src/host/usbh.h +++ b/src/host/usbh.h @@ -121,19 +121,18 @@ void tuh_event_hook_cb(uint8_t rhport, uint32_t eventid, bool in_isr); bool tuh_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param); // New API to replace tuh_init() to init host stack on specific roothub port -bool tuh_rhport_init(const tusb_rhport_init_t* rh_init); +bool tuh_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init); // Init host stack #if TUSB_VERSION_NUMBER > 2000 // 0.20.0 -TU_ATTR_DEPRECATED("Please use tusb_init(tusb_rhport_init_t*) instead") +TU_ATTR_DEPRECATED("Please use tusb_init(rhport, rh_init) instead") #endif TU_ATTR_ALWAYS_INLINE static inline bool tuh_init(uint8_t rhport) { const tusb_rhport_init_t rh_init = { - .rhport = rhport, .role = TUSB_ROLE_HOST, .speed = TUH_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, }; - return tuh_rhport_init(&rh_init); + return tuh_rhport_init(rhport, &rh_init); } // Deinit host stack on rhport diff --git a/src/portable/analog/max3421/hcd_max3421.c b/src/portable/analog/max3421/hcd_max3421.c index 30d822c3b..c5e924266 100644 --- a/src/portable/analog/max3421/hcd_max3421.c +++ b/src/portable/analog/max3421/hcd_max3421.c @@ -494,8 +494,8 @@ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { } // Initialize controller to host mode -bool hcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rh_init; tuh_max3421_int_api(rhport, false); diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index f4b236da6..4e7b28825 100644 --- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -517,8 +517,8 @@ static uint16_t _ft9xx_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t len *------------------------------------------------------------------*/ // Initialize controller to device mode -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rh_init; TU_LOG2("FT9xx initialisation\r\n"); _dcd_ft9xx_attach(); diff --git a/src/portable/chipidea/ci_fs/dcd_ci_fs.c b/src/portable/chipidea/ci_fs/dcd_ci_fs.c index 315e9a86d..6038160cf 100644 --- a/src/portable/chipidea/ci_fs/dcd_ci_fs.c +++ b/src/portable/chipidea/ci_fs/dcd_ci_fs.c @@ -267,9 +267,9 @@ static void process_bus_resume(uint8_t rhport) /*------------------------------------------------------------------*/ /* Device API *------------------------------------------------------------------*/ -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; + (void) rh_init; // save crystal-less setting (if available) #if defined(FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED == 1 diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index bdb7abe41..5204dee66 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -234,8 +234,8 @@ static void bus_reset(uint8_t rhport) dcd_dcache_clean_invalidate(&_dcd_data, sizeof(dcd_data_t)); } -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rh_init; tu_memclr(&_dcd_data, sizeof(dcd_data_t)); ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); diff --git a/src/portable/chipidea/ci_hs/hcd_ci_hs.c b/src/portable/chipidea/ci_hs/hcd_ci_hs.c index fbc51f6df..14f8acb45 100644 --- a/src/portable/chipidea/ci_hs/hcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/hcd_ci_hs.c @@ -70,8 +70,8 @@ bool hcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) { // Controller API //--------------------------------------------------------------------+ -bool hcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rh_init; ci_hs_regs_t *hcd_reg = CI_HS_REG(rhport); // Reset controller @@ -83,7 +83,9 @@ bool hcd_init(const tusb_rhport_init_t* rh_init) { // LPC18XX/43XX need to set VBUS Power Select to HIGH // RHPORT1 is fullspeed only (need external PHY for Highspeed) hcd_reg->USBMODE = USBMODE_CM_HOST | USBMODE_VBUS_POWER_SELECT; - if ( rhport == 1 ) hcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED; + if (rhport == 1) { + hcd_reg->PORTSC1 |= PORTSC1_FORCE_FULL_SPEED; + } #else hcd_reg->USBMODE = USBMODE_CM_HOST; #endif diff --git a/src/portable/dialog/da146xx/dcd_da146xx.c b/src/portable/dialog/da146xx/dcd_da146xx.c index 05cebea0b..558e1269a 100644 --- a/src/portable/dialog/da146xx/dcd_da146xx.c +++ b/src/portable/dialog/da146xx/dcd_da146xx.c @@ -804,9 +804,9 @@ static void handle_ep0_nak(void) /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; + (void) rh_init; _dcd.init_called = true; if (_dcd.vbus_present) diff --git a/src/portable/espressif/esp32sx/dcd_esp32sx.c b/src/portable/espressif/esp32sx/dcd_esp32sx.c index 3d4757f03..d233813d4 100644 --- a/src/portable/espressif/esp32sx/dcd_esp32sx.c +++ b/src/portable/espressif/esp32sx/dcd_esp32sx.c @@ -172,8 +172,8 @@ static void enum_done_processing(void) /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rh_init; ESP_LOGV(TAG, "DCD init - Start"); // A. Disconnect diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index a8437ad5b..02c8da1e0 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -582,8 +582,8 @@ void print_musb_info(musb_regs_t* musb_regs) { } #endif -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rh_init; musb_regs_t* musb_regs = MUSB_REGS(rhport); #if CFG_TUSB_DEBUG >= MUSB_DEBUG diff --git a/src/portable/mentor/musb/hcd_musb.c b/src/portable/mentor/musb/hcd_musb.c index 9324c6a34..1c0740193 100644 --- a/src/portable/mentor/musb/hcd_musb.c +++ b/src/portable/mentor/musb/hcd_musb.c @@ -556,7 +556,8 @@ static void process_pipe_rx(uint8_t rhport, uint_fast8_t pipenum) * Host API *------------------------------------------------------------------*/ -bool hcd_init(const tusb_rhport_init_t* rh_init) { +bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rhport; (void) rh_init; NVIC_ClearPendingIRQ(USB0_IRQn); diff --git a/src/portable/microchip/pic/dcd_pic.c b/src/portable/microchip/pic/dcd_pic.c index 3ee0ab6d5..089d3f520 100644 --- a/src/portable/microchip/pic/dcd_pic.c +++ b/src/portable/microchip/pic/dcd_pic.c @@ -470,8 +470,8 @@ static void process_bus_resume(uint8_t rhport) /*------------------------------------------------------------------*/ /* Device API *------------------------------------------------------------------*/ -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rh_init; intr_disable(rhport); intr_clear(rhport); diff --git a/src/portable/microchip/pic32mz/dcd_pic32mz.c b/src/portable/microchip/pic32mz/dcd_pic32mz.c index 004990046..f1614f30c 100644 --- a/src/portable/microchip/pic32mz/dcd_pic32mz.c +++ b/src/portable/microchip/pic32mz/dcd_pic32mz.c @@ -120,8 +120,8 @@ static ep0_stage_t ep0_get_stage(void) /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rh_init; // Disable endpoint interrupts for now USB_REGS->INTRRXEbits.w = 0; USB_REGS->INTRTXEbits.w = 0; diff --git a/src/portable/microchip/samd/dcd_samd.c b/src/portable/microchip/samd/dcd_samd.c index c3a74ad0f..8120681a7 100644 --- a/src/portable/microchip/samd/dcd_samd.c +++ b/src/portable/microchip/samd/dcd_samd.c @@ -78,8 +78,8 @@ static void bus_reset(void) /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ -void dcd_init(const tusb_rhport_init_t* rh_init) { - (void) rh_init; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rhport; (void) rh_init; // Reset to get in a clean state. USB->DEVICE.CTRLA.bit.SWRST = true; diff --git a/src/portable/microchip/samg/dcd_samg.c b/src/portable/microchip/samg/dcd_samg.c index 2242d3336..b02889b24 100644 --- a/src/portable/microchip/samg/dcd_samg.c +++ b/src/portable/microchip/samg/dcd_samg.c @@ -155,8 +155,9 @@ static void bus_reset(void) } // Initialize controller to device mode -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rhport; + (void) rh_init; tu_memclr(_dcd_xfer, sizeof(_dcd_xfer)); dcd_connect(rhport); } diff --git a/src/portable/microchip/samx7x/dcd_samx7x.c b/src/portable/microchip/samx7x/dcd_samx7x.c index d57db6e55..a85d2306e 100644 --- a/src/portable/microchip/samx7x/dcd_samx7x.c +++ b/src/portable/microchip/samx7x/dcd_samx7x.c @@ -104,8 +104,8 @@ TU_ATTR_ALWAYS_INLINE static inline void CleanInValidateCache(uint32_t *addr, in //------------------------------------------------------------------ // Initialize controller to device mode -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rh_init; dcd_connect(rhport); } diff --git a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c index 4117ab45f..b74ca847a 100644 --- a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c +++ b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c @@ -245,9 +245,9 @@ static void process_bus_active(uint8_t rhport) /*------------------------------------------------------------------*/ /* Device API *------------------------------------------------------------------*/ -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; + (void) rh_init; tu_memclr(&_dcd, sizeof(_dcd)); USB_OTG_FS->BDT_PAGE_01 = (uint8_t)((uintptr_t)_dcd.bdt >> 8); diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index c1084c20c..06474e65d 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -230,10 +230,10 @@ static void xact_in_dma(uint8_t epnum) { //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; - TU_LOG2("dcd init\r\n"); +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; + (void) rh_init; + TU_LOG2("dcd init\r\n"); } void dcd_int_enable(uint8_t rhport) { diff --git a/src/portable/nuvoton/nuc120/dcd_nuc120.c b/src/portable/nuvoton/nuc120/dcd_nuc120.c index c9e8d86fd..89fca021f 100644 --- a/src/portable/nuvoton/nuc120/dcd_nuc120.c +++ b/src/portable/nuvoton/nuc120/dcd_nuc120.c @@ -201,9 +201,9 @@ static const uint32_t enabled_irqs = USBD_INTSTS_FLDET_STS_Msk | USBD_INTSTS_BUS NUC100/NUC120 TinyUSB API driver implementation */ -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; + (void) rh_init; USBD->ATTR = 0x7D0; diff --git a/src/portable/nuvoton/nuc121/dcd_nuc121.c b/src/portable/nuvoton/nuc121/dcd_nuc121.c index 78c65a91c..b813eea77 100644 --- a/src/portable/nuvoton/nuc121/dcd_nuc121.c +++ b/src/portable/nuvoton/nuc121/dcd_nuc121.c @@ -209,9 +209,9 @@ enum { NUC121/NUC125/NUC126 TinyUSB API driver implementation */ -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; + (void) rh_init; #ifdef SUPPORT_LPM USBD->ATTR = 0x7D0 | USBD_LPMACK; diff --git a/src/portable/nuvoton/nuc505/dcd_nuc505.c b/src/portable/nuvoton/nuc505/dcd_nuc505.c index caeb89a0a..3821b6ec8 100644 --- a/src/portable/nuvoton/nuc505/dcd_nuc505.c +++ b/src/portable/nuvoton/nuc505/dcd_nuc505.c @@ -279,9 +279,9 @@ static const uint32_t enabled_irqs = USBD_GINTEN_USBIEN_Msk | \ NUC505 TinyUSB API driver implementation */ -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; + (void) rh_init; /* configure interrupts in their initial state; BUSINTEN and CEPINTEN will be subsequently and dynamically re-written as needed */ USBD->GINTEN = enabled_irqs; diff --git a/src/portable/nxp/khci/dcd_khci.c b/src/portable/nxp/khci/dcd_khci.c index 2d08e84a5..1b7f56e8c 100644 --- a/src/portable/nxp/khci/dcd_khci.c +++ b/src/portable/nxp/khci/dcd_khci.c @@ -265,9 +265,9 @@ static void process_bus_resume(uint8_t rhport) /*------------------------------------------------------------------*/ /* Device API *------------------------------------------------------------------*/ -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; + (void) rh_init; // save crystal-less setting (if available) #if defined(FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED == 1 diff --git a/src/portable/nxp/khci/hcd_khci.c b/src/portable/nxp/khci/hcd_khci.c index e9c00b8f9..f5ca73c18 100644 --- a/src/portable/nxp/khci/hcd_khci.c +++ b/src/portable/nxp/khci/hcd_khci.c @@ -368,7 +368,8 @@ static void process_bus_reset(uint8_t rhport) /*------------------------------------------------------------------*/ /* Host API *------------------------------------------------------------------*/ -bool hcd_init(const tusb_rhport_init_t* rh_init) { +bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rhport; (void) rh_init; KHCI->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; while (KHCI->USBTRC0 & USB_USBTRC0_USBRESET_MASK); diff --git a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c index e28b27919..22b4500c5 100644 --- a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c +++ b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c @@ -167,9 +167,9 @@ static void bus_reset(void) tu_memclr(&_dcd, sizeof(dcd_data_t)); } -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; + (void) rh_init; //------------- user manual 11.13 usb device controller initialization -------------// // step 6 : set up control endpoint diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c index 06a82c4e7..e59a0f526 100644 --- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c +++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c @@ -289,8 +289,8 @@ static void edpt_reset_all(uint8_t rhport) } prepare_setup_packet(rhport); } -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rh_init; edpt_reset_all(rhport); dcd_registers_t* dcd_reg = _dcd_controller[rhport].regs; diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c index fbaa5208e..ce35eab70 100644 --- a/src/portable/ohci/ohci.c +++ b/src/portable/ohci/ohci.c @@ -178,9 +178,9 @@ TU_ATTR_ALWAYS_INLINE static inline void *_virt_addr(void *physical_address) } // Initialization according to 5.1.1.4 -bool hcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; + (void) rh_init; //------------- Data Structure init -------------// tu_memclr(&ohci_data, sizeof(ohci_data_t)); diff --git a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c index 83589efa0..89d60a21e 100644 --- a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c @@ -50,7 +50,8 @@ static usb_descriptor_buffers_t desc; *------------------------------------------------------------------*/ // Initialize controller to device mode -void dcd_init(const tusb_rhport_init_t* rh_init) { +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rhport; (void) rh_init; static pio_usb_configuration_t config = PIO_USB_DEFAULT_CONFIG; usb_device = pio_usb_device_init(&config, &desc); diff --git a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c index 4386bbce4..6422afff1 100644 --- a/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c @@ -55,7 +55,8 @@ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void *cfg_param) { return true; } -bool hcd_init(const tusb_rhport_init_t* rh_init) { +bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rhport; (void) rh_init; // To run USB SOF interrupt in core1, call this init in core1 diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 9473d3bd8..9a945caf8 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -369,8 +369,8 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) { #define PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY 0xff #endif -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rh_init; assert(rhport == 0); TU_LOG(2, "Chip Version B%u\r\n", rp2040_chip_version()); diff --git a/src/portable/raspberrypi/rp2040/hcd_rp2040.c b/src/portable/raspberrypi/rp2040/hcd_rp2040.c index a870418a8..2c0a3fd49 100644 --- a/src/portable/raspberrypi/rp2040/hcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/hcd_rp2040.c @@ -375,7 +375,8 @@ static void _hw_endpoint_init(struct hw_endpoint *ep, uint8_t dev_addr, uint8_t //--------------------------------------------------------------------+ // HCD API //--------------------------------------------------------------------+ -bool hcd_init(const tusb_rhport_init_t* rh_init) { +bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rhport; (void) rh_init; pico_trace("hcd_init %d\n", rhport); assert(rhport == 0); diff --git a/src/portable/renesas/rusb2/dcd_rusb2.c b/src/portable/renesas/rusb2/dcd_rusb2.c index e8e1bf041..3da4ef50b 100644 --- a/src/portable/renesas/rusb2/dcd_rusb2.c +++ b/src/portable/renesas/rusb2/dcd_rusb2.c @@ -657,8 +657,8 @@ static void enable_interrupt(uint32_t pswi) } #endif -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rh_init; rusb2_reg_t* rusb = RUSB2_REG(rhport); rusb2_module_start(rhport, true); diff --git a/src/portable/renesas/rusb2/hcd_rusb2.c b/src/portable/renesas/rusb2/hcd_rusb2.c index 35e85a3b0..4c81b05be 100644 --- a/src/portable/renesas/rusb2/hcd_rusb2.c +++ b/src/portable/renesas/rusb2/hcd_rusb2.c @@ -466,8 +466,8 @@ static void enable_interrupt(uint32_t pswi) } #endif -bool hcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rh_init; rusb2_reg_t* rusb = RUSB2_REG(rhport); rusb2_module_start(rhport, true); diff --git a/src/portable/sony/cxd56/dcd_cxd56.c b/src/portable/sony/cxd56/dcd_cxd56.c index fe1c42249..93eb8674e 100644 --- a/src/portable/sony/cxd56/dcd_cxd56.c +++ b/src/portable/sony/cxd56/dcd_cxd56.c @@ -201,9 +201,9 @@ static void _dcd_resume(FAR struct usbdevclass_driver_s *driver, FAR struct usbd dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; + (void) rh_init; usbdcd_driver.usbdevclass_driver.speed = USB_SPEED_HIGH; usbdcd_driver.usbdevclass_driver.ops = &g_driverops; diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 8e9bb0b30..a4bd2da10 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -184,8 +184,8 @@ TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t *xfer_ctl_ptr(uint8_t epnum, uint //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rh_init; // Follow the RM mentions to use a special ordering of PDWN and FRES for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us asm("NOP"); diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index d7bf1068a..85c7bef5d 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -867,8 +867,8 @@ static void usb_isr_handler(void) { dcd_int_handler(0); } -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rh_init; dcd_disconnect(rhport); USBC_HardwareReset(); USBC_PhyConfig(); diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 580960e24..e44ca96d1 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -650,10 +650,10 @@ static bool check_dwc2(dwc2_regs_t* dwc2) { return true; } -void dcd_init(const tusb_rhport_init_t* rh_init) { +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rhport; (void) rh_init; // Programming model begins in the last section of the chapter on the USB // peripheral in each Reference Manual. - const uint8_t rhport = rh_init->rhport; dwc2_regs_t* dwc2 = DWC2_REG(rhport); // Check Synopsys ID register, failed if controller clock/power is not enabled diff --git a/src/portable/template/dcd_template.c b/src/portable/template/dcd_template.c index 56a89e89a..5ce650844 100644 --- a/src/portable/template/dcd_template.c +++ b/src/portable/template/dcd_template.c @@ -40,8 +40,8 @@ *------------------------------------------------------------------*/ // Initialize controller to device mode -void dcd_init(const tusb_rhport_init_t* rh_init) { - (void) rh_init; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rhport; (void) rh_init; } // Enable device interrupt diff --git a/src/portable/template/hcd_template.c b/src/portable/template/hcd_template.c index 9386e95cc..d8bca196f 100644 --- a/src/portable/template/hcd_template.c +++ b/src/portable/template/hcd_template.c @@ -44,7 +44,8 @@ bool hcd_configure(uint8_t rhport, uint32_t cfg_id, const void* cfg_param) { } // Initialize controller to host mode -bool hcd_init(const tusb_rhport_init_t* rh_init) { +bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rhport; (void) rh_init; return false; } diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 120d5c4b9..6150c254f 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -130,8 +130,8 @@ static void enable_functional_reset(const bool enable) /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ -void dcd_init(const tusb_rhport_init_t* rh_init) { - (void) rh_init; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rhport; (void) rh_init; USBKEYPID = USBKEY; @@ -699,11 +699,10 @@ static void handle_bus_power_event(void *param) { // A successful lock is indicated by all PLL-related interrupt flags being cleared. if(!USBPLLIR) { const tusb_rhport_init_t rhport_init = { - .rhport = 0, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_FULL }; - dcd_init(&rhport_init); // Re-initialize the USB module. + dcd_init(0, &rhport_init); // Re-initialize the USB module. } } else { // Event caused by removal of bus power. USBPWRCTL |= VBONIE; // Enable bus-power-applied interrupt. diff --git a/src/portable/valentyusb/eptri/dcd_eptri.c b/src/portable/valentyusb/eptri/dcd_eptri.c index da7a5a81a..8287230a4 100644 --- a/src/portable/valentyusb/eptri/dcd_eptri.c +++ b/src/portable/valentyusb/eptri/dcd_eptri.c @@ -336,9 +336,9 @@ static void dcd_reset(void) } // Initializes the USB peripheral for device mode and enables it. -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; + (void) rh_init; usb_pullup_out_write(0); diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index 4a7ad704b..9af3a1acb 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -123,8 +123,8 @@ static void update_out(uint8_t rhport, uint8_t ep, size_t rx_len) { } /* public functions */ -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rh_init; // init registers USBOTG_FS->BASE_CTRL = USBFS_CTRL_SYS_CTRL | USBFS_CTRL_INT_BUSY | USBFS_CTRL_DMA_EN; USBOTG_FS->UDEV_CTRL = USBFS_UDEV_CTRL_PD_DIS | USBFS_UDEV_CTRL_PORT_EN; diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c index 77ebc378c..64a88914f 100644 --- a/src/portable/wch/dcd_ch32_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -131,9 +131,9 @@ static void xfer_data_packet(uint8_t ep_num, tusb_dir_t ep_dir, xfer_ctl_t* xfer ep_set_response_and_toggle(ep_num, ep_dir, USBHS_EP_R_RES_ACK); } -void dcd_init(const tusb_rhport_init_t* rh_init) { - const uint8_t rhport = rh_init->rhport; +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; + (void) rh_init; memset(&xfer_status, 0, sizeof(xfer_status)); diff --git a/src/tusb.c b/src/tusb.c index 3eb299dff..e6f8055b7 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -47,29 +47,27 @@ static tusb_role_t _rhport_role[TUP_USBIP_CONTROLLER_NUM] = { 0 }; // Public API //--------------------------------------------------------------------+ -bool tusb_rhport_init(const tusb_rhport_init_t* rh_init) { +bool tusb_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { // backward compatible called with tusb_init(void) #if defined(TUD_OPT_RHPORT) || defined(TUH_OPT_RHPORT) if (rh_init == NULL) { #if CFG_TUD_ENABLED && defined(TUD_OPT_RHPORT) // init device stack CFG_TUSB_RHPORTx_MODE must be defined const tusb_rhport_init_t dev_init = { - .rhport = TUD_OPT_RHPORT, .role = TUSB_ROLE_DEVICE, .speed = TUD_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL }; - TU_ASSERT ( tud_rhport_init(&dev_init) ); + TU_ASSERT ( tud_rhport_init(rhport, &dev_init) ); _rhport_role[TUD_OPT_RHPORT] = TUSB_ROLE_DEVICE; #endif #if CFG_TUH_ENABLED && defined(TUH_OPT_RHPORT) // init host stack CFG_TUSB_RHPORTx_MODE must be defined const tusb_rhport_init_t host_init = { - .rhport = TUH_OPT_RHPORT, .role = TUSB_ROLE_HOST, .speed = TUH_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL }; - TU_ASSERT( tuh_rhport_init(&host_init) ); + TU_ASSERT( tuh_rhport_init(TUH_OPT_RHPORT, &host_init) ); _rhport_role[TUH_OPT_RHPORT] = TUSB_ROLE_HOST; #endif @@ -78,21 +76,21 @@ bool tusb_rhport_init(const tusb_rhport_init_t* rh_init) { #endif // new API with explicit rhport and role - TU_ASSERT(rh_init->rhport < TUP_USBIP_CONTROLLER_NUM && rh_init->role != TUSB_ROLE_INVALID); + TU_ASSERT(rhport < TUP_USBIP_CONTROLLER_NUM && rh_init->role != TUSB_ROLE_INVALID); #if CFG_TUD_ENABLED if (rh_init->role == TUSB_ROLE_DEVICE) { - TU_ASSERT( tud_rhport_init(rh_init) ); + TU_ASSERT(tud_rhport_init(rhport, rh_init)); } #endif #if CFG_TUH_ENABLED if (rh_init->role == TUSB_ROLE_HOST) { - TU_ASSERT( tuh_rhport_init(rh_init) ); + TU_ASSERT(tuh_rhport_init(rhport, rh_init)); } #endif - _rhport_role[rh_init->rhport] = rh_init->role; + _rhport_role[rhport] = rh_init->role; return true; } diff --git a/src/tusb.h b/src/tusb.h index c12abba8b..2f30a5739 100644 --- a/src/tusb.h +++ b/src/tusb.h @@ -134,20 +134,21 @@ #if CFG_TUH_ENABLED || CFG_TUD_ENABLED // Internal helper for backward compatible with tusb_init(void) -bool tusb_rhport_init(const tusb_rhport_init_t* rh_init); +bool tusb_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init); // Initialize roothub port with device/host role // Note: when using with RTOS, this should be called after scheduler/kernel is started. // Otherwise, it could cause kernel issue since USB IRQ handler does use RTOS queue API. // Note2: defined as macro for backward compatible with tusb_init(void), can be changed to function in the future. #if defined(TUD_OPT_RHPORT) || defined(TUH_OPT_RHPORT) -#define _tusb_init_arg0() tusb_rhport_init(NULL) + #define _tusb_init_arg0() tusb_rhport_init(0, NULL) #else -#define _tusb_init_arg0() TU_VERIFY_STATIC(false, "CFG_TUSB_RHPORT0_MODE/CFG_TUSB_RHPORT1_MODE must be defined") + #define _tusb_init_arg0() TU_VERIFY_STATIC(false, "CFG_TUSB_RHPORT0_MODE/CFG_TUSB_RHPORT1_MODE must be defined") #endif -#define _tusb_init_arg1(_rh_init) tusb_rhport_init(_rh_init) -#define tusb_init(...) TU_FUNC_OPTIONAL_ARG(_tusb_init, __VA_ARGS__) +#define _tusb_init_arg1(_rhport) _tusb_init_arg0() +#define _tusb_init_arg2(_rhport, _rh_init) tusb_rhport_init(_rhport, _rh_init) +#define tusb_init(...) TU_FUNC_OPTIONAL_ARG(_tusb_init, __VA_ARGS__) // Check if stack is initialized bool tusb_inited(void); diff --git a/test/fuzz/dcd_fuzz.cc b/test/fuzz/dcd_fuzz.cc index 7ef0c7446..e76ae5087 100644 --- a/test/fuzz/dcd_fuzz.cc +++ b/test/fuzz/dcd_fuzz.cc @@ -46,7 +46,8 @@ tu_static State state = {false, 0, 0}; // All no-ops as we are fuzzing. //--------------------------------------------------------------------+ extern "C" { -void dcd_init(const tusb_rhport_init_t* rh_init) { +void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + UNUSED(rhport); UNUSED(rh_init); return; } diff --git a/test/unit-test/test/device/msc/test_msc_device.c b/test/unit-test/test/device/msc/test_msc_device.c index 4033bf158..60fcdb41c 100644 --- a/test/unit-test/test/device/msc/test_msc_device.c +++ b/test/unit-test/test/device/msc/test_msc_device.c @@ -199,13 +199,12 @@ void setUp(void) if ( !tud_inited() ) { tusb_rhport_init_t dev_init = { - .rhport = 0, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; - dcd_init_Expect(&dev_init); - tusb_init(&dev_init); + dcd_init_Expect(0, &dev_init); + tusb_init(0, &dev_init); } dcd_event_bus_reset(rhport, TUSB_SPEED_HIGH, false); diff --git a/test/unit-test/test/device/usbd/test_usbd.c b/test/unit-test/test/device/usbd/test_usbd.c index 8f900f656..598dac641 100644 --- a/test/unit-test/test/device/usbd/test_usbd.c +++ b/test/unit-test/test/device/usbd/test_usbd.c @@ -102,44 +102,38 @@ uint8_t const* desc_configuration; //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ -uint8_t const * tud_descriptor_device_cb(void) -{ +uint8_t const * tud_descriptor_device_cb(void) { return desc_device; } -uint8_t const * tud_descriptor_configuration_cb(uint8_t index) -{ +uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { return desc_configuration; } -uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) -{ +uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) { (void) langid; return NULL; } -void setUp(void) -{ +void setUp(void) { dcd_int_disable_Ignore(); dcd_int_enable_Ignore(); if ( !tud_inited() ) { tusb_rhport_init_t dev_init = { - .rhport = 0, .role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO }; mscd_init_Expect(); - dcd_init_Expect(&dev_init); + dcd_init_Expect(0, &dev_init); - tusb_init(&dev_init); + tusb_init(0, &dev_init); } } -void tearDown(void) -{ +void tearDown(void) { } //--------------------------------------------------------------------+ -- cgit v1.3.1 From e83e08343afca86b2bacf26822ef9032571e6f56 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 14 Oct 2024 19:42:22 +0700 Subject: change dcd_init() return from void to bool --- src/device/dcd.h | 2 +- src/device/usbd.c | 9 +++++---- src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 3 ++- src/portable/chipidea/ci_fs/dcd_ci_fs.c | 3 ++- src/portable/chipidea/ci_hs/dcd_ci_hs.c | 6 ++++-- src/portable/dialog/da146xx/dcd_da146xx.c | 7 ++++--- src/portable/espressif/esp32sx/dcd_esp32sx.c | 3 ++- src/portable/mentor/musb/dcd_musb.c | 3 ++- src/portable/microchip/pic/dcd_pic.c | 3 ++- src/portable/microchip/pic32mz/dcd_pic32mz.c | 3 ++- src/portable/microchip/samd/dcd_samd.c | 7 +++++-- src/portable/microchip/samg/dcd_samg.c | 4 +++- src/portable/microchip/samx7x/dcd_samx7x.c | 3 ++- src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c | 3 ++- src/portable/nordic/nrf5x/dcd_nrf5x.c | 3 ++- src/portable/nuvoton/nuc120/dcd_nuc120.c | 4 +++- src/portable/nuvoton/nuc121/dcd_nuc121.c | 4 +++- src/portable/nuvoton/nuc505/dcd_nuc505.c | 4 +++- src/portable/nxp/khci/dcd_khci.c | 4 +++- src/portable/nxp/lpc17_40/dcd_lpc17_40.c | 4 +++- src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 4 +++- src/portable/raspberrypi/pio_usb/dcd_pio_usb.c | 4 +++- src/portable/raspberrypi/rp2040/dcd_rp2040.c | 3 ++- src/portable/renesas/rusb2/dcd_rusb2.c | 10 ++++++---- src/portable/sony/cxd56/dcd_cxd56.c | 4 +++- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 4 +++- src/portable/sunxi/dcd_sunxi_musb.c | 5 ++++- src/portable/synopsys/dwc2/dcd_dwc2.c | 9 ++++++--- src/portable/template/dcd_template.c | 3 ++- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 4 +++- src/portable/valentyusb/eptri/dcd_eptri.c | 4 +++- src/portable/wch/dcd_ch32_usbfs.c | 4 +++- src/portable/wch/dcd_ch32_usbhs.c | 4 +++- test/fuzz/dcd_fuzz.cc | 4 ++-- test/unit-test/test/device/msc/test_msc_device.c | 2 +- test/unit-test/test/device/usbd/test_usbd.c | 2 +- 36 files changed, 103 insertions(+), 49 deletions(-) (limited to 'src/portable') diff --git a/src/device/dcd.h b/src/device/dcd.h index 64dffbaef..d01f82e01 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -108,7 +108,7 @@ void dcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) TU_ATTR_W //--------------------------------------------------------------------+ // Initialize controller to device mode -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init); +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init); // Deinitialize controller, unset device mode. bool dcd_deinit(uint8_t rhport); diff --git a/src/device/usbd.c b/src/device/usbd.c index 4b6600eb2..a730b745b 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -454,7 +454,7 @@ bool tud_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { } TU_ASSERT(rh_init); - TU_LOG_USBD("USBD init on controller %u, speed = %s\r\n", rh_init->rhport, + TU_LOG_USBD("USBD init on controller %u, speed = %s\r\n", rhport, rh_init->speed == TUSB_SPEED_HIGH ? "High" : "Full"); TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(usbd_device_t)); TU_LOG_INT(CFG_TUD_LOG_LEVEL, sizeof(dcd_event_t)); @@ -490,15 +490,16 @@ bool tud_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { _usbd_rhport = rhport; // Init device controller driver - dcd_init(rhport, rh_init); + TU_ASSERT(dcd_init(rhport, rh_init)); dcd_int_enable(rhport); return true; } bool tud_deinit(uint8_t rhport) { - // skip if not initialized - if (!tud_inited()) return true; + if (!tud_inited()) { + return true; // skip if not initialized + } TU_LOG_USBD("USBD deinit on controller %u\r\n", rhport); diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index 4e7b28825..34a8be3b6 100644 --- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -517,7 +517,7 @@ static uint16_t _ft9xx_dusb_out(uint8_t ep_number, uint8_t *buffer, uint16_t len *------------------------------------------------------------------*/ // Initialize controller to device mode -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; TU_LOG2("FT9xx initialisation\r\n"); @@ -526,6 +526,7 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { interrupt_attach(interrupt_usb_device, (int8_t)interrupt_usb_device, _ft9xx_usbd_ISR); dcd_connect(rhport); + return true; } // Enable device interrupt diff --git a/src/portable/chipidea/ci_fs/dcd_ci_fs.c b/src/portable/chipidea/ci_fs/dcd_ci_fs.c index 6038160cf..11ddb683f 100644 --- a/src/portable/chipidea/ci_fs/dcd_ci_fs.c +++ b/src/portable/chipidea/ci_fs/dcd_ci_fs.c @@ -267,7 +267,7 @@ static void process_bus_resume(uint8_t rhport) /*------------------------------------------------------------------*/ /* Device API *------------------------------------------------------------------*/ -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; @@ -296,6 +296,7 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { dcd_connect(rhport); // NVIC_ClearPendingIRQ(CIFS_IRQN); + return true; } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index 5204dee66..430a0aad1 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -234,13 +234,13 @@ static void bus_reset(uint8_t rhport) dcd_dcache_clean_invalidate(&_dcd_data, sizeof(dcd_data_t)); } -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; tu_memclr(&_dcd_data, sizeof(dcd_data_t)); ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); - TU_ASSERT(ci_ep_count(dcd_reg) <= TUP_DCD_ENDPOINT_MAX, ); + TU_ASSERT(ci_ep_count(dcd_reg) <= TUP_DCD_ENDPOINT_MAX); // Reset controller dcd_reg->USBCMD |= USBCMD_RESET; @@ -268,6 +268,8 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { usbcmd |= USBCMD_RUN_STOP; // run dcd_reg->USBCMD = usbcmd; + + return true; } void dcd_int_enable(uint8_t rhport) diff --git a/src/portable/dialog/da146xx/dcd_da146xx.c b/src/portable/dialog/da146xx/dcd_da146xx.c index 558e1269a..887f59588 100644 --- a/src/portable/dialog/da146xx/dcd_da146xx.c +++ b/src/portable/dialog/da146xx/dcd_da146xx.c @@ -804,15 +804,16 @@ static void handle_ep0_nak(void) /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; _dcd.init_called = true; - if (_dcd.vbus_present) - { + if (_dcd.vbus_present) { dcd_connect(rhport); } + + return true; } void dcd_int_enable(uint8_t rhport) diff --git a/src/portable/espressif/esp32sx/dcd_esp32sx.c b/src/portable/espressif/esp32sx/dcd_esp32sx.c index d233813d4..1b6aae026 100644 --- a/src/portable/espressif/esp32sx/dcd_esp32sx.c +++ b/src/portable/espressif/esp32sx/dcd_esp32sx.c @@ -172,7 +172,7 @@ static void enum_done_processing(void) /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; ESP_LOGV(TAG, "DCD init - Start"); @@ -211,6 +211,7 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { USB_DISCONNINTMSK_M; // host most only dcd_connect(rhport); + return true; } void dcd_set_address(uint8_t rhport, uint8_t dev_addr) diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 02c8da1e0..4fce08dd9 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -582,7 +582,7 @@ void print_musb_info(musb_regs_t* musb_regs) { } #endif -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; musb_regs_t* musb_regs = MUSB_REGS(rhport); @@ -594,6 +594,7 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { musb_dcd_int_clear(rhport); musb_dcd_phy_init(rhport); dcd_connect(rhport); + return true; } void dcd_int_enable(uint8_t rhport) { diff --git a/src/portable/microchip/pic/dcd_pic.c b/src/portable/microchip/pic/dcd_pic.c index 089d3f520..d40c4794a 100644 --- a/src/portable/microchip/pic/dcd_pic.c +++ b/src/portable/microchip/pic/dcd_pic.c @@ -470,7 +470,7 @@ static void process_bus_resume(uint8_t rhport) /*------------------------------------------------------------------*/ /* Device API *------------------------------------------------------------------*/ -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; intr_disable(rhport); intr_clear(rhport); @@ -502,6 +502,7 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { U1IE = _U1IE_URSTIE_MASK; dcd_connect(rhport); + return true; } void dcd_int_enable(uint8_t rhport) diff --git a/src/portable/microchip/pic32mz/dcd_pic32mz.c b/src/portable/microchip/pic32mz/dcd_pic32mz.c index f1614f30c..8709baf67 100644 --- a/src/portable/microchip/pic32mz/dcd_pic32mz.c +++ b/src/portable/microchip/pic32mz/dcd_pic32mz.c @@ -120,7 +120,7 @@ static ep0_stage_t ep0_get_stage(void) /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; // Disable endpoint interrupts for now USB_REGS->INTRRXEbits.w = 0; @@ -129,6 +129,7 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { USB_REGS->INTRUSBEbits.w = 7; dcd_connect(rhport); + return true; } void dcd_int_enable(uint8_t rhport) diff --git a/src/portable/microchip/samd/dcd_samd.c b/src/portable/microchip/samd/dcd_samd.c index 8120681a7..0c96f6ac4 100644 --- a/src/portable/microchip/samd/dcd_samd.c +++ b/src/portable/microchip/samd/dcd_samd.c @@ -78,8 +78,9 @@ static void bus_reset(void) /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { - (void) rhport; (void) rh_init; +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rhport; + (void) rh_init; // Reset to get in a clean state. USB->DEVICE.CTRLA.bit.SWRST = true; @@ -101,6 +102,8 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { USB->DEVICE.INTFLAG.reg |= USB->DEVICE.INTFLAG.reg; // clear pending USB->DEVICE.INTENSET.reg = /* USB_DEVICE_INTENSET_SOF | */ USB_DEVICE_INTENSET_EORST; + + return true; } #if CFG_TUSB_MCU == OPT_MCU_SAMD51 || CFG_TUSB_MCU == OPT_MCU_SAME5X diff --git a/src/portable/microchip/samg/dcd_samg.c b/src/portable/microchip/samg/dcd_samg.c index b02889b24..c88b31514 100644 --- a/src/portable/microchip/samg/dcd_samg.c +++ b/src/portable/microchip/samg/dcd_samg.c @@ -155,11 +155,13 @@ static void bus_reset(void) } // Initialize controller to device mode -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; + tu_memclr(_dcd_xfer, sizeof(_dcd_xfer)); dcd_connect(rhport); + return true; } // Enable device interrupt diff --git a/src/portable/microchip/samx7x/dcd_samx7x.c b/src/portable/microchip/samx7x/dcd_samx7x.c index a85d2306e..8aec1568d 100644 --- a/src/portable/microchip/samx7x/dcd_samx7x.c +++ b/src/portable/microchip/samx7x/dcd_samx7x.c @@ -104,9 +104,10 @@ TU_ATTR_ALWAYS_INLINE static inline void CleanInValidateCache(uint32_t *addr, in //------------------------------------------------------------------ // Initialize controller to device mode -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; dcd_connect(rhport); + return true; } // Enable device interrupt diff --git a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c index b74ca847a..1ce3da27e 100644 --- a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c +++ b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c @@ -245,7 +245,7 @@ static void process_bus_active(uint8_t rhport) /*------------------------------------------------------------------*/ /* Device API *------------------------------------------------------------------*/ -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; @@ -256,6 +256,7 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { dcd_connect(rhport); NVIC_ClearPendingIRQ(USB_FS_IRQn); + return true; } #define USB_DEVICE_INTERRUPT_PRIORITY (3U) void dcd_int_enable(uint8_t rhport) diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 06474e65d..3f53ee26e 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -230,10 +230,11 @@ static void xact_in_dma(uint8_t epnum) { //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; TU_LOG2("dcd init\r\n"); + return true; } void dcd_int_enable(uint8_t rhport) { diff --git a/src/portable/nuvoton/nuc120/dcd_nuc120.c b/src/portable/nuvoton/nuc120/dcd_nuc120.c index 89fca021f..b0b6fe857 100644 --- a/src/portable/nuvoton/nuc120/dcd_nuc120.c +++ b/src/portable/nuvoton/nuc120/dcd_nuc120.c @@ -201,7 +201,7 @@ static const uint32_t enabled_irqs = USBD_INTSTS_FLDET_STS_Msk | USBD_INTSTS_BUS NUC100/NUC120 TinyUSB API driver implementation */ -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; @@ -215,6 +215,8 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { USBD->INTSTS = enabled_irqs; USBD->INTEN = enabled_irqs; + + return true; } void dcd_int_enable(uint8_t rhport) diff --git a/src/portable/nuvoton/nuc121/dcd_nuc121.c b/src/portable/nuvoton/nuc121/dcd_nuc121.c index b813eea77..f4af97ca7 100644 --- a/src/portable/nuvoton/nuc121/dcd_nuc121.c +++ b/src/portable/nuvoton/nuc121/dcd_nuc121.c @@ -209,7 +209,7 @@ enum { NUC121/NUC125/NUC126 TinyUSB API driver implementation */ -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; @@ -227,6 +227,8 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { USBD->INTSTS = ENABLED_IRQS; USBD->INTEN = ENABLED_IRQS; + + return true; } void dcd_int_enable(uint8_t rhport) diff --git a/src/portable/nuvoton/nuc505/dcd_nuc505.c b/src/portable/nuvoton/nuc505/dcd_nuc505.c index 3821b6ec8..1c98a0a49 100644 --- a/src/portable/nuvoton/nuc505/dcd_nuc505.c +++ b/src/portable/nuvoton/nuc505/dcd_nuc505.c @@ -279,7 +279,7 @@ static const uint32_t enabled_irqs = USBD_GINTEN_USBIEN_Msk | \ NUC505 TinyUSB API driver implementation */ -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; @@ -291,6 +291,8 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { bus_reset(); usb_attach(); + + return true; } void dcd_int_enable(uint8_t rhport) diff --git a/src/portable/nxp/khci/dcd_khci.c b/src/portable/nxp/khci/dcd_khci.c index 1b7f56e8c..8398b09bf 100644 --- a/src/portable/nxp/khci/dcd_khci.c +++ b/src/portable/nxp/khci/dcd_khci.c @@ -265,7 +265,7 @@ static void process_bus_resume(uint8_t rhport) /*------------------------------------------------------------------*/ /* Device API *------------------------------------------------------------------*/ -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; @@ -294,6 +294,8 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { dcd_connect(rhport); NVIC_ClearPendingIRQ(USB0_IRQn); + + return true; } void dcd_int_enable(uint8_t rhport) diff --git a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c index 22b4500c5..855c59cd1 100644 --- a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c +++ b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c @@ -167,7 +167,7 @@ static void bus_reset(void) tu_memclr(&_dcd, sizeof(dcd_data_t)); } -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; @@ -186,6 +186,8 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { // Clear pending IRQ NVIC_ClearPendingIRQ(USB_IRQn); + + return true; } void dcd_int_enable(uint8_t rhport) diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c index e59a0f526..7d5cfb5b0 100644 --- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c +++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c @@ -289,7 +289,7 @@ static void edpt_reset_all(uint8_t rhport) } prepare_setup_packet(rhport); } -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; edpt_reset_all(rhport); @@ -303,6 +303,8 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { DEVCMDSTAT_RESET_CHANGE_MASK | DEVCMDSTAT_CONNECT_CHANGE_MASK | DEVCMDSTAT_SUSPEND_CHANGE_MASK; NVIC_ClearPendingIRQ(_dcd_controller[rhport].irqnum); + + return true; } void dcd_int_enable(uint8_t rhport) diff --git a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c index 89d60a21e..60afbd435 100644 --- a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c @@ -50,11 +50,13 @@ static usb_descriptor_buffers_t desc; *------------------------------------------------------------------*/ // Initialize controller to device mode -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; static pio_usb_configuration_t config = PIO_USB_DEFAULT_CONFIG; usb_device = pio_usb_device_init(&config, &desc); + + return true; } // Enable device interrupt diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index 9a945caf8..2e177d5cb 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -369,7 +369,7 @@ static void __tusb_irq_path_func(dcd_rp2040_irq)(void) { #define PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY 0xff #endif -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; assert(rhport == 0); @@ -406,6 +406,7 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (FORCE_VBUS_DETECT ? 0 : USB_INTS_DEV_CONN_DIS_BITS); dcd_connect(rhport); + return true; } bool dcd_deinit(uint8_t rhport) { diff --git a/src/portable/renesas/rusb2/dcd_rusb2.c b/src/portable/renesas/rusb2/dcd_rusb2.c index 3da4ef50b..ecd28973c 100644 --- a/src/portable/renesas/rusb2/dcd_rusb2.c +++ b/src/portable/renesas/rusb2/dcd_rusb2.c @@ -657,14 +657,14 @@ static void enable_interrupt(uint32_t pswi) } #endif -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; rusb2_reg_t* rusb = RUSB2_REG(rhport); rusb2_module_start(rhport, true); -// We disable SOF for now until needed later on. -// Since TinyUSB doesn't use SOF for now, and this interrupt often (1ms interval) -_dcd.sof_enabled = false; + // We disable SOF for now until needed later on. + // Since TinyUSB doesn't use SOF for now, and this interrupt often (1ms interval) + _dcd.sof_enabled = false; #ifdef RUSB2_SUPPORT_HIGHSPEED if ( rusb2_is_highspeed_rhport(rhport) ) { @@ -719,6 +719,8 @@ _dcd.sof_enabled = false; if (rusb->INTSTS0_b.VBSTS) { dcd_connect(rhport); } + + return true; } void dcd_int_enable(uint8_t rhport) { diff --git a/src/portable/sony/cxd56/dcd_cxd56.c b/src/portable/sony/cxd56/dcd_cxd56.c index 93eb8674e..b16509c6f 100644 --- a/src/portable/sony/cxd56/dcd_cxd56.c +++ b/src/portable/sony/cxd56/dcd_cxd56.c @@ -201,7 +201,7 @@ static void _dcd_resume(FAR struct usbdevclass_driver_s *driver, FAR struct usbd dcd_event_bus_signal(0, DCD_EVENT_RESUME, true); } -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; @@ -211,6 +211,8 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { usbdcd_driver.setup_queue = osal_queue_create(&_setup_queue_def); usbdev_register(&usbdcd_driver.usbdevclass_driver); + + return true; } // Enable device interrupt diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index a4bd2da10..d921429e2 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -184,7 +184,7 @@ TU_ATTR_ALWAYS_INLINE static inline xfer_ctl_t *xfer_ctl_ptr(uint8_t epnum, uint //--------------------------------------------------------------------+ // Controller API //--------------------------------------------------------------------+ -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; // Follow the RM mentions to use a special ordering of PDWN and FRES for (volatile uint32_t i = 0; i < 200; i++) { // should be a few us @@ -224,6 +224,8 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { // Enable pull-up if supported dcd_connect(rhport); + + return true; } void dcd_sof_enable(uint8_t rhport, bool en) { diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index 85c7bef5d..21f13b279 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -867,8 +867,9 @@ static void usb_isr_handler(void) { dcd_int_handler(0); } -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; + dcd_disconnect(rhport); USBC_HardwareReset(); USBC_PhyConfig(); @@ -895,6 +896,8 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { f1c100s_intc_set_isr(F1C100S_IRQ_USBOTG, usb_isr_handler); dcd_connect(rhport); + + return true; } // Connect by enabling internal pull-up resistor on D+/D- diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index e44ca96d1..f30ec5ee3 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -650,14 +650,15 @@ static bool check_dwc2(dwc2_regs_t* dwc2) { return true; } -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { - (void) rhport; (void) rh_init; +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { + (void) rhport; + (void) rh_init; // Programming model begins in the last section of the chapter on the USB // peripheral in each Reference Manual. dwc2_regs_t* dwc2 = DWC2_REG(rhport); // Check Synopsys ID register, failed if controller clock/power is not enabled - TU_ASSERT(check_dwc2(dwc2), ); + TU_ASSERT(check_dwc2(dwc2)); dcd_disconnect(rhport); if (phy_hs_supported(dwc2)) { @@ -726,6 +727,8 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { // TU_LOG_HEX(DWC2_DEBUG, dwc2->gahbcfg); dcd_connect(rhport); + + return true; } void dcd_int_enable(uint8_t rhport) { diff --git a/src/portable/template/dcd_template.c b/src/portable/template/dcd_template.c index 5ce650844..3738ac0cb 100644 --- a/src/portable/template/dcd_template.c +++ b/src/portable/template/dcd_template.c @@ -40,8 +40,9 @@ *------------------------------------------------------------------*/ // Initialize controller to device mode -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; + return true; } // Enable device interrupt diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 6150c254f..3752ae251 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -130,7 +130,7 @@ static void enable_functional_reset(const bool enable) /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; USBKEYPID = USBKEY; @@ -163,6 +163,8 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { } USBKEYPID = 0; + + return true; } // There is no "USB peripheral interrupt disable" bit on MSP430, so we have diff --git a/src/portable/valentyusb/eptri/dcd_eptri.c b/src/portable/valentyusb/eptri/dcd_eptri.c index 8287230a4..a03c94558 100644 --- a/src/portable/valentyusb/eptri/dcd_eptri.c +++ b/src/portable/valentyusb/eptri/dcd_eptri.c @@ -336,7 +336,7 @@ static void dcd_reset(void) } // Initializes the USB peripheral for device mode and enables it. -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; @@ -352,6 +352,8 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { // Turn on the external pullup usb_pullup_out_write(1); + + return true; } // Enables or disables the USB device interrupt(s). May be used to diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index 9af3a1acb..4e8e25a00 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -123,7 +123,7 @@ static void update_out(uint8_t rhport, uint8_t ep, size_t rx_len) { } /* public functions */ -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rh_init; // init registers USBOTG_FS->BASE_CTRL = USBFS_CTRL_SYS_CTRL | USBFS_CTRL_INT_BUSY | USBFS_CTRL_DMA_EN; @@ -154,6 +154,8 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { EP_DMA(3) = (uint32_t) &data.ep3_buffer.out[0]; dcd_connect(rhport); + + return true; } void dcd_int_handler(uint8_t rhport) { diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c index 64a88914f..f8bf3c889 100644 --- a/src/portable/wch/dcd_ch32_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -131,7 +131,7 @@ static void xfer_data_packet(uint8_t ep_num, tusb_dir_t ep_dir, xfer_ctl_t* xfer ep_set_response_and_toggle(ep_num, ep_dir, USBHS_EP_R_RES_ACK); } -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { (void) rhport; (void) rh_init; @@ -171,6 +171,8 @@ void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { USBHSD->DEV_AD = 0; USBHSD->CONTROL |= USBHS_DEV_PU_EN; + + return true; } void dcd_int_enable(uint8_t rhport) { diff --git a/test/fuzz/dcd_fuzz.cc b/test/fuzz/dcd_fuzz.cc index e76ae5087..046a90555 100644 --- a/test/fuzz/dcd_fuzz.cc +++ b/test/fuzz/dcd_fuzz.cc @@ -46,10 +46,10 @@ tu_static State state = {false, 0, 0}; // All no-ops as we are fuzzing. //--------------------------------------------------------------------+ extern "C" { -void dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { UNUSED(rhport); UNUSED(rh_init); - return; + return true; } void dcd_int_handler(uint8_t rhport) { diff --git a/test/unit-test/test/device/msc/test_msc_device.c b/test/unit-test/test/device/msc/test_msc_device.c index 60fcdb41c..f2a4fa295 100644 --- a/test/unit-test/test/device/msc/test_msc_device.c +++ b/test/unit-test/test/device/msc/test_msc_device.c @@ -203,7 +203,7 @@ void setUp(void) .speed = TUSB_SPEED_AUTO }; - dcd_init_Expect(0, &dev_init); + dcd_init_ExpectAndReturn(0, &dev_init, true); tusb_init(0, &dev_init); } diff --git a/test/unit-test/test/device/usbd/test_usbd.c b/test/unit-test/test/device/usbd/test_usbd.c index 598dac641..9879cd4ba 100644 --- a/test/unit-test/test/device/usbd/test_usbd.c +++ b/test/unit-test/test/device/usbd/test_usbd.c @@ -127,7 +127,7 @@ void setUp(void) { }; mscd_init_Expect(); - dcd_init_Expect(0, &dev_init); + dcd_init_ExpectAndReturn(0, &dev_init, true); tusb_init(0, &dev_init); } -- cgit v1.3.1