From a0202df920889b57f79560760f6a38632e52c364 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 25 Oct 2021 13:49:59 +0700 Subject: add TU_ARGS_APPLY(), TU_CHECK_MCU() now could check list of mcus --- src/common/tusb_common.h | 31 ------------------------------- src/common/tusb_compiler.h | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 31 deletions(-) (limited to 'src/common') diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index fc92654b7..bf9641622 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -235,37 +235,6 @@ TU_ATTR_ALWAYS_INLINE static inline void tu_unaligned_write16 (void* mem, ui #endif -/*------------------------------------------------------------------*/ -/* Count number of arguments of __VA_ARGS__ - * - reference https://groups.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s - * - _GET_NTH_ARG() takes args >= N (64) but only expand to Nth one (64th) - * - _RSEQ_N() is reverse sequential to N to add padding to have - * Nth position is the same as the number of arguments - * - ##__VA_ARGS__ is used to deal with 0 paramerter (swallows comma) - *------------------------------------------------------------------*/ -#ifndef TU_ARGS_NUM - -#define TU_ARGS_NUM(...) _TU_NARG(_0, ##__VA_ARGS__,_RSEQ_N()) - -#define _TU_NARG(...) _GET_NTH_ARG(__VA_ARGS__) -#define _GET_NTH_ARG( \ - _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \ - _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \ - _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \ - _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \ - _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \ - _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \ - _61,_62,_63,N,...) N -#define _RSEQ_N() \ - 62,61,60, \ - 59,58,57,56,55,54,53,52,51,50, \ - 49,48,47,46,45,44,43,42,41,40, \ - 39,38,37,36,35,34,33,32,31,30, \ - 29,28,27,26,25,24,23,22,21,20, \ - 19,18,17,16,15,14,13,12,11,10, \ - 9,8,7,6,5,4,3,2,1,0 -#endif - // To be removed //------------- Binary constant -------------// #if defined(__GNUC__) && !defined(__CC_ARM) diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index 3e85939b0..b0999b5d9 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -67,6 +67,46 @@ #define TU_LITTLE_ENDIAN (0x12u) #define TU_BIG_ENDIAN (0x21u) +/*------------------------------------------------------------------*/ +/* Count number of arguments of __VA_ARGS__ + * - reference https://groups.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s + * - _GET_NTH_ARG() takes args >= N (64) but only expand to Nth one (64th) + * - _RSEQ_N() is reverse sequential to N to add padding to have + * Nth position is the same as the number of arguments + * - ##__VA_ARGS__ is used to deal with 0 paramerter (swallows comma) + *------------------------------------------------------------------*/ +#define TU_ARGS_NUM(...) _TU_NARG(_0, ##__VA_ARGS__,_RSEQ_N()) + +#define _TU_NARG(...) _GET_NTH_ARG(__VA_ARGS__) +#define _GET_NTH_ARG( \ + _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \ + _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \ + _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \ + _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \ + _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \ + _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \ + _61,_62,_63,N,...) N +#define _RSEQ_N() \ + 62,61,60, \ + 59,58,57,56,55,54,53,52,51,50, \ + 49,48,47,46,45,44,43,42,41,40, \ + 39,38,37,36,35,34,33,32,31,30, \ + 29,28,27,26,25,24,23,22,21,20, \ + 19,18,17,16,15,14,13,12,11,10, \ + 9,8,7,6,5,4,3,2,1,0 + +// Apply an macro X to each of the arguments with an separated of choice +#define TU_ARGS_APPLY(_X, _s, ...) TU_XSTRCAT(_TU_ARGS_APPLY_, TU_ARGS_NUM(__VA_ARGS__))(_X, _s, __VA_ARGS__) + +#define _TU_ARGS_APPLY_1(_X, _s, _a1) _X(_a1) +#define _TU_ARGS_APPLY_2(_X, _s, _a1, _a2) _X(_a1) _s _X(_a2) +#define _TU_ARGS_APPLY_3(_X, _s, _a1, _a2, _a3) _X(_a1) _s _TU_ARGS_APPLY_2(_X, _s, _a2, _a3) +#define _TU_ARGS_APPLY_4(_X, _s, _a1, _a2, _a3, _a4) _X(_a1) _s _TU_ARGS_APPLY_3(_X, _s, _a2, _a3, _a4) +#define _TU_ARGS_APPLY_5(_X, _s, _a1, _a2, _a3, _a4, _a5) _X(_a1) _s _TU_ARGS_APPLY_4(_X, _s, _a2, _a3, _a4, _a5) +#define _TU_ARGS_APPLY_6(_X, _s, _a1, _a2, _a3, _a4, _a5, _a6) _X(_a1) _s _TU_ARGS_APPLY_5(_X, _s, _a2, _a3, _a4, _a5, _a6) +#define _TU_ARGS_APPLY_7(_X, _s, _a1, _a2, _a3, _a4, _a5, _a6, _a7) _X(_a1) _s _TU_ARGS_APPLY_6(_X, _s, _a2, _a3, _a4, _a5, _a6, _a7) +#define _TU_ARGS_APPLY_8(_X, _s, _a1, _a2, _a3, _a4, _a5, _a6, _a7, _a8) _X(_a1) _s _TU_ARGS_APPLY_7(_X, _s, _a2, _a3, _a4, _a5, _a6, _a7, _a8) + //--------------------------------------------------------------------+ // Compiler porting with Attribute and Endian //--------------------------------------------------------------------+ -- cgit v1.3.1 From dbd31895bc234ff6d76d3fe736dc613890ab7acb Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 25 Oct 2021 17:04:03 +0700 Subject: change usage of TU_CHECK_MCU() to prevent macro conflict --- .../audio_4_channel_mic/src/usb_descriptors.c | 12 ++-- examples/device/audio_test/src/usb_descriptors.c | 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 +- .../device/video_capture/src/usb_descriptors.c | 4 +- src/class/msc/msc_device.c | 2 +- src/common/tusb_compiler.h | 2 +- src/device/dcd_attr.h | 73 +++++++++++----------- src/host/hcd_attr.h | 46 +++++++------- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 11 ++-- src/portable/synopsys/dwc2/dcd_dwc2.c | 6 +- src/tusb_option.h | 2 +- 14 files changed, 85 insertions(+), 91 deletions(-) (limited to 'src/common') diff --git a/examples/device/audio_4_channel_mic/src/usb_descriptors.c b/examples/device/audio_4_channel_mic/src/usb_descriptors.c index b6a5bd5c2..93ae2ea47 100644 --- a/examples/device/audio_4_channel_mic/src/usb_descriptors.c +++ b/examples/device/audio_4_channel_mic/src/usb_descriptors.c @@ -81,12 +81,12 @@ enum #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_AUDIO * TUD_AUDIO_MIC_FOUR_CH_DESC_LEN) -#if TU_CHECK_MCU(LPC175X_6X) || TU_CHECK_MCU(LPC177X_8X) || TU_CHECK_MCU(LPC40XX) +#if TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... #define EPNUM_AUDIO 0x03 -#elif TU_CHECK_MCU(NRF5X) +#elif TU_CHECK_MCU(OPT_MCU_NRF5X) // nRF5x ISO can only be endpoint 8 #define EPNUM_AUDIO 0x08 @@ -96,11 +96,11 @@ enum uint8_t const desc_configuration[] = { - // Interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), + // Interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100), - // Interface number, string index, EP Out & EP In address, EP size - TUD_AUDIO_MIC_FOUR_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN) + // Interface number, string index, EP Out & EP In address, EP size + TUD_AUDIO_MIC_FOUR_CH_DESCRIPTOR(/*_itfnum*/ ITF_NUM_AUDIO_CONTROL, /*_stridx*/ 0, /*_nBytesPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX, /*_nBitsUsedPerSample*/ CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX*8, /*_epin*/ 0x80 | EPNUM_AUDIO, /*_epsize*/ CFG_TUD_AUDIO_EP_SZ_IN) }; // Invoked when received GET CONFIGURATION DESCRIPTOR diff --git a/examples/device/audio_test/src/usb_descriptors.c b/examples/device/audio_test/src/usb_descriptors.c index 348f5eede..09b2a2d45 100644 --- a/examples/device/audio_test/src/usb_descriptors.c +++ b/examples/device/audio_test/src/usb_descriptors.c @@ -86,7 +86,7 @@ enum // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... #define EPNUM_AUDIO 0x03 -#elif TU_CHECK_MCU(NRF5X) +#elif TU_CHECK_MCU(OPT_MCU_NRF5X) // nRF5x ISO can only be endpoint 8 #define EPNUM_AUDIO 0x08 diff --git a/examples/device/cdc_msc_freertos/src/main.c b/examples/device/cdc_msc_freertos/src/main.c index 65b7fda3b..2d3426f1d 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.h" #include "tusb.h" -#if TU_CHECK_MCU(ESP32S2) || TU_CHECK_MCU(ESP32S3) +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) // ESP-IDF need "freertos/" prefix in include path. // CFG_TUSB_OS_INC_PATH should be defined accordingly. #include "freertos/FreeRTOS.h" @@ -105,14 +105,14 @@ int main(void) (void) xTaskCreateStatic( cdc_task, "cdc", CDC_STACK_SZIE, NULL, configMAX_PRIORITIES-2, cdc_stack, &cdc_taskdef); // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 -#if !( TU_CHECK_MCU(ESP32S2) || TU_CHECK_MCU(ESP32S3) ) +#if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) vTaskStartScheduler(); #endif return 0; } -#if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3 +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) 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 d4bbdee48..55e84c62d 100644 --- a/examples/device/cdc_msc_freertos/src/tusb_config.h +++ b/examples/device/cdc_msc_freertos/src/tusb_config.h @@ -68,7 +68,7 @@ #define CFG_TUSB_OS OPT_OS_FREERTOS // Espressif IDF requires "freertos/" prefix in include path -#if TU_CHECK_MCU(ESP32S2) || TU_CHECK_MCU(ESP32S3) +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) #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 b25c71f64..336f5d426 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(ESP32S2) || TU_CHECK_MCU(ESP32S3) +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) // ESP-IDF need "freertos/" prefix in include path. // CFG_TUSB_OS_INC_PATH should be defined accordingly. #include "freertos/FreeRTOS.h" @@ -105,14 +105,14 @@ int main(void) (void) xTaskCreateStatic( hid_task, "hid", HID_STACK_SZIE, NULL, configMAX_PRIORITIES-2, hid_stack, &hid_taskdef); // skip starting scheduler (and return) for ESP32-S2 or ESP32-S3 -#if !( TU_CHECK_MCU(ESP32S2) || TU_CHECK_MCU(ESP32S3) ) +#if !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) vTaskStartScheduler(); #endif return 0; } -#if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3 +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) 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 b061dce3f..062f32ac3 100644 --- a/examples/device/hid_composite_freertos/src/tusb_config.h +++ b/examples/device/hid_composite_freertos/src/tusb_config.h @@ -68,7 +68,7 @@ #define CFG_TUSB_OS OPT_OS_FREERTOS // Espressif IDF requires "freertos/" prefix in include path -#if TU_CHECK_MCU(ESP32S2) || TU_CHECK_MCU(ESP32S3) +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) #define CFG_TUSB_OS_INC_PATH freertos/ #endif diff --git a/examples/device/video_capture/src/usb_descriptors.c b/examples/device/video_capture/src/usb_descriptors.c index 404ffe070..da8ec8e89 100644 --- a/examples/device/video_capture/src/usb_descriptors.c +++ b/examples/device/video_capture/src/usb_descriptors.c @@ -77,12 +77,12 @@ uint8_t const * tud_descriptor_device_cb(void) #define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_VIDEO_CAPTURE_DESC_LEN) -#if TU_CHECK_MCU(LPC175X_6X) || TU_CHECK_MCU(LPC177X_8X) || TU_CHECK_MCU(LPC40XX) +#if TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In, 5 Bulk etc ... #define EPNUM_VIDEO_IN 0x83 -#elif TU_CHECK_MCU(NRF5X) +#elif TU_CHECK_MCU(OPT_MCU_NRF5X) // nRF5x ISO can only be endpoint 8 #define EPNUM_VIDEO_IN 0x88 diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 81522be46..dd490dd68 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -617,7 +617,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t } } - #if TU_CHECK_MCU(CXD56) + #if TU_CHECK_MCU(OPT_MCU_CXD56) // WORKAROUND: cxd56 has its own nuttx usb stack which does not forward Set/ClearFeature(Endpoint) to DCD. // There is no way for us to know when EP is un-stall, therefore we will unconditionally un-stall here and // hope everything will work diff --git a/src/common/tusb_compiler.h b/src/common/tusb_compiler.h index b0999b5d9..d3284c62a 100644 --- a/src/common/tusb_compiler.h +++ b/src/common/tusb_compiler.h @@ -69,7 +69,7 @@ /*------------------------------------------------------------------*/ /* Count number of arguments of __VA_ARGS__ - * - reference https://groups.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s + * - reference https://stackoverflow.com/questions/2124339/c-preprocessor-va-args-number-of-arguments * - _GET_NTH_ARG() takes args >= N (64) but only expand to Nth one (64th) * - _RSEQ_N() is reverse sequential to N to add padding to have * Nth position is the same as the number of arguments diff --git a/src/device/dcd_attr.h b/src/device/dcd_attr.h index ddec481a8..54627eaa0 100644 --- a/src/device/dcd_attr.h +++ b/src/device/dcd_attr.h @@ -36,59 +36,59 @@ // - PORT_HIGHSPEED: mask to indicate which port support highspeed mode, bit0 for port0 and so on. //------------- NXP -------------// -#if TU_CHECK_MCU(LPC11UXX, LPC13XX, LPC15XX) +#if TU_CHECK_MCU(OPT_MCU_LPC11UXX, OPT_MCU_LPC13XX, OPT_MCU_LPC15XX) #define DCD_ATTR_ENDPOINT_MAX 5 -#elif TU_CHECK_MCU(LPC175X_6X, LPC177X_8X, LPC40XX) +#elif TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) #define DCD_ATTR_ENDPOINT_MAX 16 -#elif TU_CHECK_MCU(LPC18XX, LPC43XX) +#elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) // TODO USB0 has 6, USB1 has 4 #define DCD_ATTR_ENDPOINT_MAX 6 -#elif TU_CHECK_MCU(LPC51UXX) +#elif TU_CHECK_MCU(OPT_MCU_LPC51UXX) #define DCD_ATTR_ENDPOINT_MAX 5 -#elif TU_CHECK_MCU(LPC54XXX) +#elif TU_CHECK_MCU(OPT_MCU_LPC54XXX) // TODO USB0 has 5, USB1 has 6 #define DCD_ATTR_ENDPOINT_MAX 6 -#elif TU_CHECK_MCU(LPC55XX) +#elif TU_CHECK_MCU(OPT_MCU_LPC55XX) // TODO USB0 has 5, USB1 has 6 #define DCD_ATTR_ENDPOINT_MAX 6 -#elif TU_CHECK_MCU(MIMXRT10XX) +#elif TU_CHECK_MCU(OPT_MCU_MIMXRT10XX) #define DCD_ATTR_ENDPOINT_MAX 8 -#elif TU_CHECK_MCU(MKL25ZXX, K32L2BXX) +#elif TU_CHECK_MCU(OPT_MCU_MKL25ZXX, OPT_MCU_K32L2BXX) #define DCD_ATTR_ENDPOINT_MAX 16 -#elif TU_CHECK_MCU(MM32F327X) +#elif TU_CHECK_MCU(OPT_MCU_MM32F327X) #define DCD_ATTR_ENDPOINT_MAX 16 //------------- Nordic -------------// -#elif TU_CHECK_MCU(NRF5X) +#elif TU_CHECK_MCU(OPT_MCU_NRF5X) // 8 CBI + 1 ISO #define DCD_ATTR_ENDPOINT_MAX 9 //------------- Microchip -------------// -#elif TU_CHECK_MCU(SAMD21, SAMD51, SAME5X) || \ - TU_CHECK_MCU(SAMD11, SAML21, SAML22) +#elif TU_CHECK_MCU(OPT_MCU_SAMD21, OPT_MCU_SAMD51, OPT_MCU_SAME5X) || \ + TU_CHECK_MCU(OPT_MCU_SAMD11, OPT_MCU_SAML21, OPT_MCU_SAML22) #define DCD_ATTR_ENDPOINT_MAX 8 -#elif TU_CHECK_MCU(SAMG) +#elif TU_CHECK_MCU(OPT_MCU_SAMG) #define DCD_ATTR_ENDPOINT_MAX 6 #define DCD_ATTR_ENDPOINT_EXCLUSIVE_NUMBER -#elif TU_CHECK_MCU(SAMX7X) +#elif TU_CHECK_MCU(OPT_MCU_SAMX7X) #define DCD_ATTR_ENDPOINT_MAX 10 #define DCD_ATTR_ENDPOINT_EXCLUSIVE_NUMBER //------------- ST -------------// -#elif TU_CHECK_MCU(STM32F0) +#elif TU_CHECK_MCU(OPT_MCU_STM32F0) #define DCD_ATTR_ENDPOINT_MAX 8 -#elif TU_CHECK_MCU(STM32F1) +#elif TU_CHECK_MCU(OPT_MCU_STM32F1) #if defined (STM32F105x8) || defined (STM32F105xB) || defined (STM32F105xC) || \ defined (STM32F107xB) || defined (STM32F107xC) #define DCD_ATTR_ENDPOINT_MAX 4 @@ -97,32 +97,32 @@ #define DCD_ATTR_ENDPOINT_MAX 8 #endif -#elif TU_CHECK_MCU(STM32F2) +#elif TU_CHECK_MCU(OPT_MCU_STM32F2) // FS has 4 ep, HS has 5 ep #define DCD_ATTR_ENDPOINT_MAX 6 #define DCD_ATTR_DWC2_STM32 -#elif TU_CHECK_MCU(STM32F3) +#elif TU_CHECK_MCU(OPT_MCU_STM32F3) #define DCD_ATTR_ENDPOINT_MAX 8 -#elif TU_CHECK_MCU(STM32F4) +#elif TU_CHECK_MCU(OPT_MCU_STM32F4) // For most mcu, FS has 4, HS has 6. TODO 446/469/479 HS has 9 #define DCD_ATTR_ENDPOINT_MAX 6 #define DCD_ATTR_DWC2_STM32 -#elif TU_CHECK_MCU(STM32F7) +#elif TU_CHECK_MCU(OPT_MCU_STM32F7) // FS has 6, HS has 9 #define DCD_ATTR_ENDPOINT_MAX 9 #define DCD_ATTR_DWC2_STM32 -#elif TU_CHECK_MCU(STM32H7) +#elif TU_CHECK_MCU(OPT_MCU_STM32H7) #define DCD_ATTR_ENDPOINT_MAX 9 #define DCD_ATTR_DWC2_STM32 -#elif TU_CHECK_MCU(STM32L0, STM32L1) +#elif TU_CHECK_MCU(OPT_MCU_STM32L0, OPT_MCU_STM32L1) #define DCD_ATTR_ENDPOINT_MAX 8 -#elif TU_CHECK_MCU(STM32L4) +#elif TU_CHECK_MCU(OPT_MCU_STM32L4) #if defined (STM32L475xx) || defined (STM32L476xx) || \ defined (STM32L485xx) || defined (STM32L486xx) || defined (STM32L496xx) || \ defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || \ @@ -134,53 +134,50 @@ #endif //------------- Sony -------------// -#elif TU_CHECK_MCU(CXD56) +#elif TU_CHECK_MCU(OPT_MCU_CXD56) #define DCD_ATTR_ENDPOINT_MAX 7 #define DCD_ATTR_ENDPOINT_EXCLUSIVE_NUMBER //------------- TI -------------// -#elif TU_CHECK_MCU(MSP430x5xx) +#elif TU_CHECK_MCU(OPT_MCU_MSP430x5xx) #define DCD_ATTR_ENDPOINT_MAX 8 //------------- ValentyUSB -------------// -#elif TU_CHECK_MCU(VALENTYUSB_EPTRI) +#elif TU_CHECK_MCU(OPT_MCU_VALENTYUSB_EPTRI) #define DCD_ATTR_ENDPOINT_MAX 16 //------------- Nuvoton -------------// -#elif TU_CHECK_MCU(NUC121) || TU_CHECK_MCU(NUC126) +#elif TU_CHECK_MCU(OPT_MCU_NUC121, OPT_MCU_NUC126) #define DCD_ATTR_ENDPOINT_MAX 8 -#elif TU_CHECK_MCU(NUC120) +#elif TU_CHECK_MCU(OPT_MCU_NUC120) #define DCD_ATTR_ENDPOINT_MAX 6 -#elif TU_CHECK_MCU(NUC505) +#elif TU_CHECK_MCU(OPT_MCU_NUC505) #define DCD_ATTR_ENDPOINT_MAX 12 //------------- Espressif -------------// -#elif TU_CHECK_MCU(ESP32S2, ESP32S3) +#elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) #define DCD_ATTR_ENDPOINT_MAX 6 //------------- Dialog -------------// -#elif TU_CHECK_MCU(DA1469X) +#elif TU_CHECK_MCU(OPT_MCU_DA1469X) #define DCD_ATTR_ENDPOINT_MAX 4 //------------- Raspberry Pi -------------// -#elif TU_CHECK_MCU(RP2040) +#elif TU_CHECK_MCU(OPT_MCU_RP2040) #define DCD_ATTR_ENDPOINT_MAX 16 //------------- Silabs -------------// -#elif TU_CHECK_MCU(EFM32GG) || TU_CHECK_MCU(EFM32GG11) || TU_CHECK_MCU(EFM32GG12) +#elif TU_CHECK_MCU(OPT_MCU_EFM32GG, OPT_MCU_EFM32GG11, OPT_MCU_EFM32GG12) #define DCD_ATTR_ENDPOINT_MAX 7 //------------- Renesas -------------// -#elif TU_CHECK_MCU(RX63X) || TU_CHECK_MCU(RX65X) || TU_CHECK_MCU(RX72N) +#elif TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N) #define DCD_ATTR_ENDPOINT_MAX 10 -//#elif TU_CHECK_MCU(MM32F327X) -// #define DCD_ATTR_ENDPOINT_MAX not known yet - //------------- GigaDevice -------------// -#elif TU_CHECK_MCU(GD32VF103) +#elif TU_CHECK_MCU(OPT_MCU_GD32VF103) #define DCD_ATTR_ENDPOINT_MAX 4 #else diff --git a/src/host/hcd_attr.h b/src/host/hcd_attr.h index 729fc407b..a9bc242d7 100644 --- a/src/host/hcd_attr.h +++ b/src/host/hcd_attr.h @@ -34,64 +34,64 @@ // - PORT_HIGHSPEED: mask to indicate which port support highspeed mode, bit0 for port0 and so on. //------------- NXP -------------// -#if TU_CHECK_MCU(LPC175X_6X) || TU_CHECK_MCU(LPC177X_8X) || TU_CHECK_MCU(LPC40XX) +#if TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) #define HCD_ATTR_OHCI -#elif TU_CHECK_MCU(LPC18XX) || TU_CHECK_MCU(LPC43XX) +#elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) #define HCD_ATTR_EHCI_TRANSDIMENSION -#elif TU_CHECK_MCU(LPC54XXX) +#elif TU_CHECK_MCU(OPT_MCU_LPC54XXX) // #define HCD_ATTR_EHCI_NXP_PTD -#elif TU_CHECK_MCU(LPC55XX) +#elif TU_CHECK_MCU(OPT_MCU_LPC55XX) // #define HCD_ATTR_EHCI_NXP_PTD -#elif TU_CHECK_MCU(MIMXRT10XX) +#elif TU_CHECK_MCU(OPT_MCU_MIMXRT10XX) #define HCD_ATTR_EHCI_TRANSDIMENSION -#elif TU_CHECK_MCU(MKL25ZXX) +#elif TU_CHECK_MCU(OPT_MCU_MKL25ZXX) //------------- Microchip -------------// -#elif TU_CHECK_MCU(SAMD21) || TU_CHECK_MCU(SAMD51) || TU_CHECK_MCU(SAME5X) || \ - TU_CHECK_MCU(SAMD11) || TU_CHECK_MCU(SAML21) || TU_CHECK_MCU(SAML22) +#elif TU_CHECK_MCU(OPT_MCU_SAMD21, OPT_MCU_SAMD51, OPT_MCU_SAME5X) || \ + TU_CHECK_MCU(OPT_MCU_SAMD11, OPT_MCU_SAML21, OPT_MCU_SAML22) -#elif TU_CHECK_MCU(SAMG) +#elif TU_CHECK_MCU(OPT_MCU_SAMG) -#elif TU_CHECK_MCU(SAMX7X) +#elif TU_CHECK_MCU(OPT_MCU_SAMX7X) //------------- ST -------------// -#elif TU_CHECK_MCU(STM32F0) || TU_CHECK_MCU(STM32F1) || TU_CHECK_MCU(STM32F3) || \ - TU_CHECK_MCU(STM32L0) || TU_CHECK_MCU(STM32L1) || TU_CHECK_MCU(STM32L4) +#elif TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32F1, OPT_MCU_STM32F3) || \ + TU_CHECK_MCU(OPT_MCU_STM32L0, OPT_MCU_STM32L1, OPT_MCU_STM32L4) -#elif TU_CHECK_MCU(STM32F2) || TU_CHECK_MCU(STM32F4) || TU_CHECK_MCU(STM32F3) +#elif TU_CHECK_MCU(OPT_MCU_STM32F2, OPT_MCU_STM32F3, OPT_MCU_STM32F4) -#elif TU_CHECK_MCU(STM32F7) +#elif TU_CHECK_MCU(OPT_MCU_STM32F7) -#elif TU_CHECK_MCU(STM32H7) +#elif TU_CHECK_MCU(OPT_MCU_STM32H7) //------------- Sony -------------// -#elif TU_CHECK_MCU(CXD56) +#elif TU_CHECK_MCU(OPT_MCU_CXD56) //------------- Nuvoton -------------// -#elif TU_CHECK_MCU(NUC505) +#elif TU_CHECK_MCU(OPT_MCU_NUC505) //------------- Espressif -------------// -#elif TU_CHECK_MCU(ESP32S2) || TU_CHECK_MCU(ESP32S3) +#elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) //------------- Raspberry Pi -------------// -#elif TU_CHECK_MCU(RP2040) +#elif TU_CHECK_MCU(OPT_MCU_RP2040) //------------- Silabs -------------// -#elif TU_CHECK_MCU(EFM32GG) || TU_CHECK_MCU(EFM32GG11) || TU_CHECK_MCU(EFM32GG12) +#elif TU_CHECK_MCU(OPT_MCU_EFM32GG, OPT_MCU_EFM32GG11, OPT_MCU_EFM32GG12) //------------- Renesas -------------// -#elif TU_CHECK_MCU(RX63X) || TU_CHECK_MCU(RX65X) || TU_CHECK_MCU(RX72N) +#elif TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N) -//#elif TU_CHECK_MCU(MM32F327X) +//#elif TU_CHECK_MCU(OPT_MCU_MM32F327X) // #define DCD_ATTR_ENDPOINT_MAX not known yet //------------- GigaDevice -------------// -#elif TU_CHECK_MCU(GD32VF103) +#elif TU_CHECK_MCU(OPT_MCU_GD32VF103) #else // #warning "DCD_ATTR_ENDPOINT_MAX is not defined for this MCU, default to 8" diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index ca6564d46..933f352a2 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -109,13 +109,10 @@ #define STM32F1_FSDEV #endif -#if (TUSB_OPT_DEVICE_ENABLED) && ( \ - (CFG_TUSB_MCU == OPT_MCU_STM32F0 ) || \ - (CFG_TUSB_MCU == OPT_MCU_STM32F1 && defined(STM32F1_FSDEV)) || \ - (CFG_TUSB_MCU == OPT_MCU_STM32F3 ) || \ - (CFG_TUSB_MCU == OPT_MCU_STM32L0 ) || \ - (CFG_TUSB_MCU == OPT_MCU_STM32L1 ) \ - ) +#if TUSB_OPT_DEVICE_ENABLED && \ + ( TU_CHECK_MCU(OPT_MCU_STM32F0, OPT_MCU_STM32F3, OPT_MCU_STM32L0, OPT_MCU_STM32L1) || \ + (TU_CHECK_MCU(OPT_MCU_STM32F1) && defined(STM32F1_FSDEV)) \ + ) // In order to reduce the dependance on HAL, we undefine this. // Some definitions are copied to our private include file. diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index fca5321f7..7ae10652c 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -31,16 +31,16 @@ #include "device/dcd_attr.h" #if TUSB_OPT_DEVICE_ENABLED && \ - ( defined(DCD_ATTR_DWC2_STM32) || TU_CHECK_MCU(ESP32S2, ESP32S3, GD32VF103) ) + ( defined(DCD_ATTR_DWC2_STM32) || TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_GD32VF103) ) #include "device/dcd.h" #include "dwc2_type.h" #if defined(DCD_ATTR_DWC2_STM32) #include "dwc2_stm32.h" -#elif TU_CHECK_MCU(ESP32S2, ESP32S3) +#elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) #include "dwc2_esp32.h" -#elif TU_CHECK_MCU(GD32VF103) +#elif TU_CHECK_MCU(OPT_MCU_GD32VF103) #include "dwc2_gd32.h" #else #error "Unsupported MCUs" diff --git a/src/tusb_option.h b/src/tusb_option.h index d707c44c7..509ff4a3c 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -130,7 +130,7 @@ // Helper to 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 == OPT_MCU_##_m) +#define _TU_CHECK_MCU(_m) (CFG_TUSB_MCU == _m) #define TU_CHECK_MCU(...) (TU_ARGS_APPLY(_TU_CHECK_MCU, ||, __VA_ARGS__)) //--------------------------------------------------------------------+ -- cgit v1.3.1 From bb5dab5c2e81be277214a6704a8d90e89a5b4759 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 26 Oct 2021 22:48:01 +0700 Subject: add hw config struct --- hw/bsp/board.c | 2 +- src/common/tusb_common.h | 4 +- src/portable/synopsys/dwc2/dcd_dwc2.c | 92 +++++++++++-- src/portable/synopsys/dwc2/dwc2_type.h | 234 ++++++++++++++++++++++----------- 4 files changed, 240 insertions(+), 92 deletions(-) (limited to 'src/common') diff --git a/hw/bsp/board.c b/hw/bsp/board.c index 2c18b61b4..afacdef9f 100644 --- a/hw/bsp/board.c +++ b/hw/bsp/board.c @@ -96,7 +96,7 @@ void board_led_task(void) TU_ATTR_USED int sys_write (int fhdl, const void *buf, size_t count) { (void) fhdl; - SEGGER_RTT_Write(0, (char*) buf, (int) count); + SEGGER_RTT_Write(0, (const char*) buf, (int) count); return count; } diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index bf9641622..e62bcde12 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -303,8 +303,8 @@ void tu_print_var(uint8_t const* buf, uint32_t bufsize) #define TU_LOG1 tu_printf #define TU_LOG1_MEM tu_print_mem #define TU_LOG1_VAR(_x) tu_print_var((uint8_t const*)(_x), sizeof(*(_x))) -#define TU_LOG1_INT(_x) tu_printf(#_x " = %ld\r\n", (uint32_t) (_x) ) -#define TU_LOG1_HEX(_x) tu_printf(#_x " = %lX\r\n", (uint32_t) (_x) ) +#define TU_LOG1_INT(_x) tu_printf(#_x " = %ld\r\n", (unsigned long) (_x) ) +#define TU_LOG1_HEX(_x) tu_printf(#_x " = %lX\r\n", (unsigned long) (_x) ) // Log Level 2: Warn #if CFG_TUSB_DEBUG >= 2 diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 67f84a083..7b02c75cd 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -74,14 +74,14 @@ typedef struct { } xfer_ctl_t; xfer_ctl_t xfer_status[DWC2_EP_MAX][2]; -#define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] +#define XFER_CTL_BASE(_ep, _dir) (&xfer_status[_ep][_dir]) // EP0 transfers are limited to 1 packet - larger sizes has to be split static uint16_t ep0_pending[2]; // Index determines direction as tusb_dir_t type // 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) -static bool _out_ep_closed; // Flag to check if RX FIFO size needs an update (reduce its size) +static bool _out_ep_closed; // Flag to check if RX FIFO size needs an update (reduce its size) // Calculate the RX FIFO size according to recommendations from reference manual static inline uint16_t calc_rx_ff_size(uint16_t ep_size) @@ -120,14 +120,15 @@ static void bus_reset(uint8_t rhport) dwc2->dcfg &= ~DCFG_DAD_Msk; // 1. NAK for all OUT endpoints - for(uint8_t n = 0; n < DWC2_EP_MAX; n++) { + for ( uint8_t n = 0; n < DWC2_EP_MAX; n++ ) + { dwc2->epout[n].doepctl |= DOEPCTL_SNAK; } // 2. Un-mask interrupt bits dwc2->daintmsk = (1 << DAINTMSK_OEPM_Pos) | (1 << DAINTMSK_IEPM_Pos); dwc2->doepmsk = DOEPMSK_STUPM | DOEPMSK_XFRCM; - dwc2->diepmsk = DIEPMSK_TOM | DIEPMSK_XFRCM; + dwc2->diepmsk = DIEPMSK_TOM | DIEPMSK_XFRCM; // "USB Data FIFOs" section in reference manual // Peripheral FIFO architecture @@ -188,7 +189,8 @@ static void bus_reset(uint8_t rhport) // Fixed control EP0 size to 64 bytes dwc2->epin[0].diepctl &= ~(0x03 << DIEPCTL_MPSIZ_Pos); - xfer_status[0][TUSB_DIR_OUT].max_size = xfer_status[0][TUSB_DIR_IN].max_size = 64; + 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); @@ -210,7 +212,7 @@ static void set_speed(uint8_t rhport, tusb_speed_t speed) if ( rhport == 1 ) { - bitvalue = ((TUSB_SPEED_HIGH == speed) ? DCD_HIGH_SPEED : DCD_FULL_SPEED_USE_HS); + bitvalue = (TUSB_SPEED_HIGH == speed ? DCD_HIGH_SPEED : DCD_FULL_SPEED_USE_HS); } else { @@ -287,7 +289,7 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c // A full IN transfer (multiple packets, possibly) triggers XFRC. epin[epnum].dieptsiz = (num_packets << DIEPTSIZ_PKTCNT_Pos) | - ((total_bytes << DIEPTSIZ_XFRSIZ_Pos) & DIEPTSIZ_XFRSIZ_Msk); + ((total_bytes << DIEPTSIZ_XFRSIZ_Pos) & DIEPTSIZ_XFRSIZ_Msk); epin[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK; @@ -311,10 +313,11 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c // 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) | - ((total_bytes << DOEPTSIZ_XFRSIZ_Pos) & DOEPTSIZ_XFRSIZ_Msk); + ((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 ) + 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)); @@ -326,13 +329,82 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c /*------------------------------------------------------------------*/ /* Controller API *------------------------------------------------------------------*/ +void print_dwc2_info(dwc2_regs_t * dwc2) +{ + dwc2_ghwcfg2_t const * hw_cfg2 = &dwc2->ghwcfg2_bm; + dwc2_ghwcfg3_t const * hw_cfg3 = &dwc2->ghwcfg3_bm; + dwc2_ghwcfg4_t const * hw_cfg4 = &dwc2->ghwcfg4_bm; + + TU_LOG_HEX(1, dwc2->guid); + TU_LOG_HEX(1, dwc2->gsnpsid); + TU_LOG_HEX(1, dwc2->ghwcfg1); + + // HW configure 2 + TU_LOG(1, "\r\n"); + TU_LOG_HEX(1, dwc2->ghwcfg2); + TU_LOG_INT(1, hw_cfg2->op_mode ); + TU_LOG_INT(1, hw_cfg2->arch ); + TU_LOG_INT(1, hw_cfg2->point2point ); + TU_LOG_INT(1, hw_cfg2->hs_phy_type ); + TU_LOG_INT(1, hw_cfg2->fs_phy_type ); + TU_LOG_INT(1, hw_cfg2->num_dev_ep ); + TU_LOG_INT(1, hw_cfg2->num_host_ch ); + TU_LOG_INT(1, hw_cfg2->period_channel_support ); + TU_LOG_INT(1, hw_cfg2->enable_dynamic_fifo ); + TU_LOG_INT(1, hw_cfg2->mul_cpu_int ); + TU_LOG_INT(1, hw_cfg2->nperiod_tx_q_depth ); + TU_LOG_INT(1, hw_cfg2->host_period_tx_q_depth ); + TU_LOG_INT(1, hw_cfg2->dev_token_q_depth ); + TU_LOG_INT(1, hw_cfg2->otg_enable_ic_usb ); + + // HW configure 3 + TU_LOG(1, "\r\n"); + TU_LOG_HEX(1, dwc2->ghwcfg3); + TU_LOG_INT(1, hw_cfg3->xfer_size_width ); + TU_LOG_INT(1, hw_cfg3->packet_size_width ); + TU_LOG_INT(1, hw_cfg3->otg_enable ); + TU_LOG_INT(1, hw_cfg3->i2c_enable ); + TU_LOG_INT(1, hw_cfg3->vendor_ctrl_itf ); + TU_LOG_INT(1, hw_cfg3->optional_feature_removed ); + TU_LOG_INT(1, hw_cfg3->synch_reset ); + TU_LOG_INT(1, hw_cfg3->otg_adp_support ); + TU_LOG_INT(1, hw_cfg3->otg_enable_hsic ); + TU_LOG_INT(1, hw_cfg3->otg_bc_support ); + TU_LOG_INT(1, hw_cfg3->lpm_mode ); + TU_LOG_INT(1, hw_cfg3->total_fifo_size ); + + // HW configure 4 + TU_LOG(1, "\r\n"); + TU_LOG_HEX(1, dwc2->ghwcfg4); + TU_LOG_INT(1, hw_cfg4->num_dev_period_in_ep ); + TU_LOG_INT(1, hw_cfg4->power_optimized ); + TU_LOG_INT(1, hw_cfg4->ahb_freq_min ); + TU_LOG_INT(1, hw_cfg4->hibernation ); + TU_LOG_INT(1, hw_cfg4->service_interval_mode ); + TU_LOG_INT(1, hw_cfg4->ipg_isoc_en ); + TU_LOG_INT(1, hw_cfg4->acg_enable ); + TU_LOG_INT(1, hw_cfg4->utmi_phy_data_width ); + TU_LOG_INT(1, hw_cfg4->dev_ctrl_ep_num ); + TU_LOG_INT(1, hw_cfg4->iddg_filter_enabled ); + TU_LOG_INT(1, hw_cfg4->vbus_valid_filter_enabled ); + TU_LOG_INT(1, hw_cfg4->a_valid_filter_enabled ); + TU_LOG_INT(1, hw_cfg4->b_valid_filter_enabled ); + TU_LOG_INT(1, hw_cfg4->dedicated_fifos ); + TU_LOG_INT(1, hw_cfg4->num_dev_in_eps ); + TU_LOG_INT(1, hw_cfg4->dma_desc_enable ); + TU_LOG_INT(1, hw_cfg4->dma_dynamic ); +} + void dcd_init (uint8_t rhport) { // 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 GSNPSID + // check gsnpsid + //TU_LOG_HEX(1, dwc2->gsnpsid); + + print_dwc2_info(dwc2); // No HNP/SRP (no OTG support), program timeout later. if ( rhport == 1 ) diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index 5669aa88d..58e628970 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -19,6 +19,27 @@ #include "stdint.h" +/* DWC OTG HW Release versions */ +#define DWC2_CORE_REV_2_71a 0x4f54271a +#define DWC2_CORE_REV_2_72a 0x4f54272a +#define DWC2_CORE_REV_2_80a 0x4f54280a +#define DWC2_CORE_REV_2_90a 0x4f54290a +#define DWC2_CORE_REV_2_91a 0x4f54291a +#define DWC2_CORE_REV_2_92a 0x4f54292a +#define DWC2_CORE_REV_2_94a 0x4f54294a +#define DWC2_CORE_REV_3_00a 0x4f54300a +#define DWC2_CORE_REV_3_10a 0x4f54310a +#define DWC2_CORE_REV_4_00a 0x4f54400a +#define DWC2_CORE_REV_4_20a 0x4f54420a +#define DWC2_FS_IOT_REV_1_00a 0x5531100a +#define DWC2_HS_IOT_REV_1_00a 0x5532100a +#define DWC2_CORE_REV_MASK 0x0000ffff + +/* DWC OTG HW Core ID */ +#define DWC2_OTG_ID 0x4f540000 +#define DWC2_FS_IOT_ID 0x55310000 +#define DWC2_HS_IOT_ID 0x55320000 + #ifdef __cplusplus extern "C" { #endif @@ -37,93 +58,165 @@ typedef struct } HS_PHYC_GlobalTypeDef; #endif +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 otg_bc_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 +}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"); + // Host Channel typedef struct { - volatile uint32_t hcchar; // 500 + 20*ch Host Channel Characteristics Register - volatile uint32_t hcsplt; // 504 + 20*ch Host Channel Split Control Register - volatile uint32_t hcint; // 508 + 20*ch Host Channel Interrupt Register - volatile uint32_t hcintmsk; // 50C + 20*ch Host Channel Interrupt Mask Register - volatile uint32_t hctsiz; // 510 + 20*ch Host Channel Transfer Size Register - volatile uint32_t hcdma; // 514 + 20*ch Host Channel DMA Address Register + 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 + volatile uint32_t hcintmsk; // 50C + 20*ch Host Channel Interrupt Mask + volatile uint32_t hctsiz; // 510 + 20*ch Host Channel Transfer Size + volatile uint32_t hcdma; // 514 + 20*ch Host Channel DMA Address uint32_t reserved518; // 518 + 20*ch - volatile uint32_t hcdmab; // 51C + 20*ch Host Channel DMA Address Register + volatile uint32_t hcdmab; // 51C + 20*ch Host Channel DMA Address } dwc2_channel_t; // Endpoint IN 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 - uint32_t reserved0c; // 90C - volatile uint32_t dieptsiz; // 910 + 20*ep Device IN Endpoint Transfer Size - volatile uint32_t diepdma; // 914 + 20*ep Device IN Endpoint DMA Address - volatile uint32_t dtxfsts; // 918 + 20*ep Device IN Endpoint Tx FIFO Status - uint32_t reserved1c; // 91C + 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 + uint32_t reserved0c; // 90C + volatile uint32_t dieptsiz; // 910 + 20*ep Device IN Endpoint Transfer Size + volatile uint32_t diepdma; // 914 + 20*ep Device IN Endpoint DMA Address + volatile uint32_t dtxfsts; // 918 + 20*ep Device IN Endpoint Tx FIFO Status + uint32_t reserved1c; // 91C } dwc2_epin_t; // Endpoint OUT 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 - uint32_t reserved0c; // B0C - volatile uint32_t doeptsiz; // B10 + 20*ep Device OUT Endpoint Transfer Size - volatile uint32_t doepdma; // B14 + 20*ep Device OUT Endpoint DMA Address - uint32_t reserved18[2]; // B18..B1C + 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 + uint32_t reserved0c; // B0C + volatile uint32_t doeptsiz; // B10 + 20*ep Device OUT Endpoint Transfer Size + volatile uint32_t doepdma; // B14 + 20*ep Device OUT Endpoint DMA Address + uint32_t reserved18[2]; // B18..B1C } dwc2_epout_t; typedef struct { //------------- Core Global -------------// - volatile uint32_t gotgctl; // 000 OTG Control and Status Register - volatile uint32_t gotgint; // 004 OTG Interrupt Register - volatile uint32_t gahbcfg; // 008 AHB Configuration Register - volatile uint32_t gusbcfg; // 00c USB Configuration Register - volatile uint32_t grstctl; // 010 Reset Register - volatile uint32_t gintsts; // 014 Interrupt Register - volatile uint32_t gintmsk; // 018 Interrupt Mask Register - volatile uint32_t grxstsr; // 01c Receive Status Debug Read Register - volatile uint32_t grxstsp; // 020 Receive Status Read/Pop Register - volatile uint32_t grxfsiz; // 024 Receive FIFO Size Register + 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 Register - volatile uint32_t gnptxfsiz; // 028 Non-periodic Transmit FIFO Size Register + 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 Register - volatile uint32_t gi2cctl; // 030 I2C Address Register - volatile uint32_t gpvndctl; // 034 PHY Vendor Control Register + 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 Register + volatile uint32_t ggpio; // 038 General Purpose IO volatile uint32_t stm32_gccfg; // 038 STM32 General Core Configuration }; - volatile uint32_t guid; // 03C User ID Register - volatile uint32_t gsnpsid; // 040 Synopsys ID Register - volatile uint32_t ghwcfg1; // 044 User Hardware Configuration 1 Register - volatile uint32_t ghwcfg2; // 048 User Hardware Configuration 2 Register - volatile uint32_t ghwcfg3; // 04C User Hardware Configuration 3 Register - volatile uint32_t ghwcfg4; // 050 User Hardware Configuration 4 Register - volatile uint32_t glpmcfg; // 054 Core LPM Configuration Register - volatile uint32_t gpwrdn; // 058 Power Down Register - volatile uint32_t gdfifocfg; // 05C DFIFO Software Configuration Register - volatile uint32_t gadpctl; // 060 ADP Timer, Control and Status Register - + 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 + dwc2_ghwcfg2_t ghwcfg2_bm; +}; +union { + volatile uint32_t ghwcfg3; // 04C User Hardware Configuration3 + dwc2_ghwcfg3_t ghwcfg3_bm; +}; +union { + volatile uint32_t ghwcfg4; // 050 User Hardware Configuration4 + 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 Register - volatile uint32_t dieptxf[15]; // 104..13C Device Periodic Transmit FIFO Size Register + 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 Register - volatile uint32_t hfir; // 404 Host Frame Interval Register + 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 Register + 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 Register + 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 @@ -133,18 +226,18 @@ union { uint32_t reserved700[64]; // 700..7FF //------------- Device -------------// - volatile uint32_t dcfg; // 800 Device Configuration Register - volatile uint32_t dctl; // 804 Device Control Register - volatile uint32_t dsts; // 808 Device Status Register (RO) + 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 read register1 - volatile uint32_t dtknqr2; // 824 Device IN token sequence learning queue read register2 - volatile uint32_t dvbusdis; // 828 Device VBUS Discharge Time Register - volatile uint32_t dvbuspulse; // 82C Device VBUS Pulsing Time Register + 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 @@ -176,23 +269,6 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, epout ) == 0x0B00, "incorrect size"); TU_VERIFY_STATIC(offsetof(dwc2_regs_t, pcgctrl) == 0x0E00, "incorrect size"); TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); -//--------------------------------------------------------------------+ -// Register Base Address -//--------------------------------------------------------------------+ - -#define DWC2_GLOBAL_BASE 0x00000000UL -#define DWC2_DEVICE_BASE 0x00000800UL -#define DWC2_IN_ENDPOINT_BASE 0x00000900UL -#define DWC2_OUT_ENDPOINT_BASE 0x00000B00UL -#define DWC2_EP_REG_SIZE 0x00000020UL -#define DWC2_HOST_BASE 0x00000400UL -#define DWC2_HOST_PORT_BASE 0x00000440UL -#define DWC2_HOST_CHANNEL_BASE 0x00000500UL -#define DWC2_HOST_CHANNEL_SIZE 0x00000020UL -#define DWC2_PCGCCTL_BASE 0x00000E00UL -#define DWC2_FIFO_BASE 0x00001000UL -#define DWC2_FIFO_SIZE 0x00001000UL - //--------------------------------------------------------------------+ // Register Bit Definitions //--------------------------------------------------------------------+ -- cgit v1.3.1 From 6c67fc412516950622a13fb34ddc10b64b9b3843 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 29 Oct 2021 00:53:30 +0700 Subject: correctly init hs phy for bcm --- examples/device/cdc_msc/src/tusb_config.h | 5 +- examples/device/hid_composite/src/tusb_config.h | 4 +- src/common/tusb_types.h | 4 +- src/portable/synopsys/dwc2/dcd_dwc2.c | 211 ++++++++++++++---------- src/portable/synopsys/dwc2/dwc2_type.h | 166 +++++++++---------- 5 files changed, 204 insertions(+), 186 deletions(-) (limited to 'src/common') diff --git a/examples/device/cdc_msc/src/tusb_config.h b/examples/device/cdc_msc/src/tusb_config.h index a3802f536..499966cb4 100644 --- a/examples/device/cdc_msc/src/tusb_config.h +++ b/examples/device/cdc_msc/src/tusb_config.h @@ -47,9 +47,8 @@ // RHPort max operational speed can defined by board.mk // Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed #ifndef BOARD_DEVICE_RHPORT_SPEED - #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56 || CFG_TUSB_MCU == OPT_MCU_SAMX7X || \ - CFG_TUSB_MCU == OPT_MCU_BCM2711) + #if TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX, OPT_MCU_MIMXRT10XX, OPT_MCU_NUC505) ||\ + TU_CHECK_MCU(OPT_MCU_CXD56, OPT_MCU_SAMX7X, OPT_MCU_BCM2711) #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED #else #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED diff --git a/examples/device/hid_composite/src/tusb_config.h b/examples/device/hid_composite/src/tusb_config.h index 868424e6d..8fa5e5cd4 100644 --- a/examples/device/hid_composite/src/tusb_config.h +++ b/examples/device/hid_composite/src/tusb_config.h @@ -47,8 +47,8 @@ // RHPort max operational speed can defined by board.mk // Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed #ifndef BOARD_DEVICE_RHPORT_SPEED - #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ - CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56 || CFG_TUSB_MCU == OPT_MCU_SAMX7X) + #if TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX, OPT_MCU_MIMXRT10XX, OPT_MCU_NUC505) ||\ + TU_CHECK_MCU(OPT_MCU_CXD56, OPT_MCU_SAMX7X, OPT_MCU_BCM2711) #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED #else #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index 233def466..5b26f5aec 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -47,8 +47,8 @@ typedef enum { TUSB_SPEED_FULL = 0, - TUSB_SPEED_LOW , - TUSB_SPEED_HIGH, + TUSB_SPEED_LOW = 1, + TUSB_SPEED_HIGH = 2, TUSB_SPEED_INVALID = 0xff, }tusb_speed_t; diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index 0d2766c38..ce9b58e03 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -199,35 +199,6 @@ static void bus_reset(uint8_t rhport) dwc2->gintmsk |= GINTMSK_OEPINT | GINTMSK_IEPINT; } - -static tusb_speed_t get_speed(uint8_t rhport) -{ - (void) rhport; - dwc2_regs_t * dwc2 = DWC2_REG(rhport); - uint32_t const enum_spd = (dwc2->dsts & DSTS_ENUMSPD_Msk) >> DSTS_ENUMSPD_Pos; - return (enum_spd == DCD_HIGH_SPEED) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL; -} - -static void set_speed(uint8_t rhport, tusb_speed_t speed) -{ - uint32_t bitvalue; - - if ( rhport == 1 ) - { - bitvalue = (TUSB_SPEED_HIGH == speed ? DCD_HIGH_SPEED : DCD_FULL_SPEED_USE_HS); - } - else - { - bitvalue = DCD_FULL_SPEED; - } - - dwc2_regs_t * dwc2 = DWC2_REG(rhport); - - // Clear and set speed bits - dwc2->dcfg &= ~(3 << DCFG_DSPD_Pos); - dwc2->dcfg |= (bitvalue << DCFG_DSPD_Pos); -} - static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t const dir, uint16_t const num_packets, uint16_t total_bytes) { (void) rhport; @@ -371,90 +342,136 @@ static void reset_core(dwc2_regs_t * dwc2) // wait for device mode ? } -void dcd_init (uint8_t rhport) +static bool has_hs_phy(dwc2_regs_t * dwc2) { - // 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); + return TUD_OPT_HIGH_SPEED && dwc2->ghwcfg2_bm.hs_phy_type != HS_PHY_TYPE_NONE; +} - // Check Synopsys ID, failed if controller is not enabled - uint32_t const gsnpsid = dwc2->gsnpsid & GSNPSID_ID_MASK; - TU_ASSERT(gsnpsid == DWC2_OTG_ID || gsnpsid == DWC2_FS_IOT_ID || gsnpsid == DWC2_HS_IOT_ID, ); +static void phy_fs_init(dwc2_regs_t * dwc2) +{ + TU_LOG1("Fullspeed PHY init\r\n"); - print_dwc2_info(dwc2); + // Select FS PHY + dwc2->gusbcfg |= GUSBCFG_PHYSEL; - // Force device mode - dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_FHMOD) | GUSBCFG_FDMOD; + // Reset core after selecting PHY + reset_core(dwc2); - uint32_t const hs_phy_type = dwc2->ghwcfg2_bm.hs_phy_type; + // set turn around + // The values above are calculated for the minimum AHB frequency of 30 MHz. USB turnaround + // time is critical for certification where long cables and 5-Hubs are used, so if + // you need the AHB to run at less than 30 MHz, and if USB turnaround time is not critical, + // these bits can be programmed to a larger value. + dwc2_set_turnaround(dwc2, TUSB_SPEED_FULL); - if( !TUD_OPT_HIGH_SPEED || hs_phy_type == HS_PHY_TYPE_NONE) - { - // max speed is full or core does not support highspeed - TU_LOG2("Fullspeed PHY init\r\n"); + // set max speed + dwc2->dcfg = (dwc2->dcfg & ~DCFG_DSPD_Msk) | (DCFG_DSPD_FS << DCFG_DSPD_Pos); - // Select FS PHY - dwc2->gusbcfg |= GUSBCFG_PHYSEL; + #if defined(DCD_ATTR_DWC2_STM32) + // activate FS PHY on stm32 + dwc2->stm32_gccfg |= STM32_GCCFG_PWRDWN; + #endif +} - // Reset core after selecting PHY - reset_core(dwc2); +static void phy_hs_init(dwc2_regs_t * dwc2) +{ + uint32_t gusbcfg = dwc2->gusbcfg; - #if defined(DCD_ATTR_DWC2_STM32) - // activate FS PHY on stm32 - dwc2->stm32_gccfg |= STM32_GCCFG_PWRDWN; - #endif - }else + // De-select FS PHY + gusbcfg &= ~GUSBCFG_PHYSEL; + + if (dwc2->ghwcfg2_bm.hs_phy_type == HS_PHY_TYPE_ULPI) { - // Highspeed mode + TU_LOG1("Highspeed ULPI PHY init\r\n"); - #if defined(DCD_ATTR_DWC2_STM32) - // Disable STM32 FS PHY - dwc2->stm32_gccfg &= ~STM32_GCCFG_PWRDWN; - #endif + // Select ULPI + gusbcfg |= GUSBCFG_ULPI_UTMI_SEL; - uint32_t gusbcfg = dwc2->gusbcfg; + // ULPI 8-bit interface, single data rate + gusbcfg &= ~(GUSBCFG_PHYIF16 | GUSBCFG_DDRSEL); - // De-select FS PHY - gusbcfg &= ~GUSBCFG_PHYSEL; + // default internal VBUS Indicator and Drive + gusbcfg &= ~(GUSBCFG_ULPIEVBUSD | GUSBCFG_ULPIEVBUSI); - if (hs_phy_type == HS_PHY_TYPE_ULPI) - { - TU_LOG2("Highspeed ULPI PHY init\r\n"); + // Disable FS/LS ULPI + gusbcfg &= ~(GUSBCFG_ULPIFSLS | GUSBCFG_ULPICSM); + }else + { + TU_LOG1("Highspeed UTMI+ PHY init\r\n"); - // Select ULPI - gusbcfg |= GUSBCFG_ULPI_UTMI_SEL; + // Select UTMI+ with 8-bit interface + gusbcfg &= ~(GUSBCFG_ULPI_UTMI_SEL | GUSBCFG_PHYIF16); - // ULPI 8-bit interface, single data rate - gusbcfg &= ~(GUSBCFG_PHYIF16 | GUSBCFG_DDRSEL); + // Set 16-bit interface if supported + if (dwc2->ghwcfg4_bm.utmi_phy_data_width) gusbcfg |= GUSBCFG_PHYIF16; - // default internal VBUS Indicator and Drive - gusbcfg &= ~(GUSBCFG_ULPIEVBUSD | GUSBCFG_ULPIEVBUSI); + #if defined(DCD_ATTR_DWC2_STM32) && defined(USB_HS_PHYC) + dwc2_stm32_utmi_phy_init(dwc2); + #endif + } - // Disable FS/LS ULPI - gusbcfg &= ~(GUSBCFG_ULPIFSLS | GUSBCFG_ULPICSM); - }else - { - TU_LOG2("Highspeed UTMI+ PHY init\r\n"); + // Apply config + dwc2->gusbcfg = gusbcfg; + + #if defined(DCD_ATTR_DWC2_STM32) + // Disable STM32 FS PHY + dwc2->stm32_gccfg &= ~STM32_GCCFG_PWRDWN; + #endif + + // Reset core after selecting PHY + reset_core(dwc2); + + // Set turn-around, must after core reset otherwise it will be clear + // 9 if UTMI interface is 8-bit, 5 if 16-bit + // The values above are calculated for the minimum AHB frequency of 30 MHz. USB turnaround + // time is critical for certification where long cables and 5-Hubs are used, so if + // you need the AHB to run at less than 30 MHz, and if USB turnaround time is not critical, + // these bits can be programmed to a larger value. + gusbcfg &= ~GUSBCFG_TRDT_Msk; + gusbcfg |= (dwc2->ghwcfg4_bm.utmi_phy_data_width ? 5u : 9u) << GUSBCFG_TRDT_Pos; + dwc2->gusbcfg = gusbcfg; // Apply config + + // Set max speed + dwc2->dcfg = (dwc2->dcfg & ~DCFG_DSPD_Msk) | (DCFG_DSPD_HS << DCFG_DSPD_Pos); +} - // Select UTMI+ with 8-bit interface - gusbcfg &= ~(GUSBCFG_ULPI_UTMI_SEL | GUSBCFG_PHYIF16); +void dcd_init (uint8_t rhport) +{ + // 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); - // Set 16-bit interface if supported - if (dwc2->ghwcfg4_bm.utmi_phy_data_width) gusbcfg |= GUSBCFG_PHYIF16; + // Check Synopsys ID, failed if controller is not enabled + uint32_t const gsnpsid = dwc2->gsnpsid & GSNPSID_ID_MASK; + TU_ASSERT(gsnpsid == DWC2_OTG_ID || gsnpsid == DWC2_FS_IOT_ID || gsnpsid == DWC2_HS_IOT_ID, ); - #if defined(DCD_ATTR_DWC2_STM32) && defined(USB_HS_PHYC) - dwc2_stm32_utmi_phy_init(dwc2); - #endif - } + print_dwc2_info(dwc2); - dwc2->gusbcfg = gusbcfg; + // Force device mode + dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_FHMOD) | GUSBCFG_FDMOD; - // Reset core after selecting PHY - reset_core(dwc2); + if( !has_hs_phy(dwc2) ) + { + // core does not support highspeed or hs-phy is not present + phy_fs_init(dwc2); + }else + { + // Highspeed + phy_hs_init(dwc2); } + /* Set HS/FS Timeout Calibration to 7 (max available value). + * The number of PHY clocks that the application programs in + * this field is added to the high/full speed interpacket timeout + * duration in the core to account for any additional delays + * introduced by the PHY. This can be required, because the delay + * introduced by the PHY in generating the linestate condition + * can vary from one PHY to another. + */ + // dwc2->gusbcfg |= (7ul << GUSBCFG_TOCAL_Pos); + // Restart PHY clock - dwc2->pcgctrl = 0; + dwc2->pcgctl &= ~(PCGCTL_STOPPCLK | PCGCTL_GATEHCLK | PCGCTL_PWRCLMP | PCGCTL_RSTPDWNMODULE); // Clear all interrupts dwc2->gintsts |= dwc2->gintsts; @@ -468,8 +485,6 @@ void dcd_init (uint8_t rhport) // (non zero-length packet), send STALL back and discard. dwc2->dcfg |= DCFG_NZLSOHSK; - set_speed(rhport, TUD_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL); - dwc2->gintmsk |= GINTMSK_USBRST | GINTMSK_ENUMDNEM | GINTMSK_USBSUSPM | GINTMSK_WUIM | GINTMSK_RXFLVLM; @@ -1088,9 +1103,23 @@ void dcd_int_handler(uint8_t rhport) dwc2->gintsts = GINTSTS_ENUMDNE; - tusb_speed_t const speed = get_speed(rhport); + tusb_speed_t speed; + switch ((dwc2->dsts & DSTS_ENUMSPD_Msk) >> DSTS_ENUMSPD_Pos) + { + case DSTS_ENUMSPD_HS: + speed = TUSB_SPEED_HIGH; + break; + + case DSTS_ENUMSPD_FS_HSPHY: + case DSTS_ENUMSPD_FS: + speed = TUSB_SPEED_FULL; + break; + + case DSTS_ENUMSPD_LS: + speed = TUSB_SPEED_LOW; + break; + } - dwc2_set_turnaround(dwc2, speed); dcd_event_bus_reset(rhport, speed, true); } diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index 5ded366d7..7e472310f 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -259,8 +259,8 @@ union { uint32_t reservedd00[64]; // D00..DFF //------------- Power Clock -------------// - volatile uint32_t pcgctrl; // E00 Power and Clock Gating Control - volatile uint32_t pcgcctl1; // E04 + volatile uint32_t pcgctl; // E00 Power and Clock Gating Control + volatile uint32_t pcgctl1; // E04 uint32_t reservede08[126]; // E08..FFF //------------- FIFOs -------------// @@ -273,7 +273,7 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, channel) == 0x0500, "incorrect size"); TU_VERIFY_STATIC(offsetof(dwc2_regs_t, dcfg ) == 0x0800, "incorrect size"); TU_VERIFY_STATIC(offsetof(dwc2_regs_t, epin ) == 0x0900, "incorrect size"); TU_VERIFY_STATIC(offsetof(dwc2_regs_t, epout ) == 0x0B00, "incorrect size"); -TU_VERIFY_STATIC(offsetof(dwc2_regs_t, pcgctrl) == 0x0E00, "incorrect size"); +TU_VERIFY_STATIC(offsetof(dwc2_regs_t, pcgctl ) == 0x0E00, "incorrect size"); TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); //--------------------------------------------------------------------+ @@ -346,39 +346,6 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define HCFG_FSLSS_Msk (0x1UL << HCFG_FSLSS_Pos) // 0x00000004 */ #define HCFG_FSLSS HCFG_FSLSS_Msk // FS- and LS-only support */ -/******************** Bit definition for DCFG register ********************/ -#define DCFG_DSPD_Pos (0U) -#define DCFG_DSPD_Msk (0x3UL << DCFG_DSPD_Pos) // 0x00000003 */ -#define DCFG_DSPD DCFG_DSPD_Msk // Device speed */ -#define DCFG_DSPD_0 (0x1UL << DCFG_DSPD_Pos) // 0x00000001 */ -#define DCFG_DSPD_1 (0x2UL << DCFG_DSPD_Pos) // 0x00000002 */ -#define DCFG_NZLSOHSK_Pos (2U) -#define DCFG_NZLSOHSK_Msk (0x1UL << DCFG_NZLSOHSK_Pos) // 0x00000004 */ -#define DCFG_NZLSOHSK DCFG_NZLSOHSK_Msk // Nonzero-length status OUT handshake */ - -#define DCFG_DAD_Pos (4U) -#define DCFG_DAD_Msk (0x7FUL << DCFG_DAD_Pos) // 0x000007F0 */ -#define DCFG_DAD DCFG_DAD_Msk // Device address */ -#define DCFG_DAD_0 (0x01UL << DCFG_DAD_Pos) // 0x00000010 */ -#define DCFG_DAD_1 (0x02UL << DCFG_DAD_Pos) // 0x00000020 */ -#define DCFG_DAD_2 (0x04UL << DCFG_DAD_Pos) // 0x00000040 */ -#define DCFG_DAD_3 (0x08UL << DCFG_DAD_Pos) // 0x00000080 */ -#define DCFG_DAD_4 (0x10UL << DCFG_DAD_Pos) // 0x00000100 */ -#define DCFG_DAD_5 (0x20UL << DCFG_DAD_Pos) // 0x00000200 */ -#define DCFG_DAD_6 (0x40UL << DCFG_DAD_Pos) // 0x00000400 */ - -#define DCFG_PFIVL_Pos (11U) -#define DCFG_PFIVL_Msk (0x3UL << DCFG_PFIVL_Pos) // 0x00001800 */ -#define DCFG_PFIVL DCFG_PFIVL_Msk // Periodic (micro)frame interval */ -#define DCFG_PFIVL_0 (0x1UL << DCFG_PFIVL_Pos) // 0x00000800 */ -#define DCFG_PFIVL_1 (0x2UL << DCFG_PFIVL_Pos) // 0x00001000 */ - -#define DCFG_PERSCHIVL_Pos (24U) -#define DCFG_PERSCHIVL_Msk (0x3UL << DCFG_PERSCHIVL_Pos) // 0x03000000 */ -#define DCFG_PERSCHIVL DCFG_PERSCHIVL_Msk // Periodic scheduling interval */ -#define DCFG_PERSCHIVL_0 (0x1UL << DCFG_PERSCHIVL_Pos) // 0x01000000 */ -#define DCFG_PERSCHIVL_1 (0x2UL << DCFG_PERSCHIVL_Pos) // 0x02000000 */ - /******************** Bit definition for PCGCR register ********************/ #define PCGCR_STPPCLK_Pos (0U) #define PCGCR_STPPCLK_Msk (0x1UL << PCGCR_STPPCLK_Pos) // 0x00000001 */ @@ -413,6 +380,41 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define GOTGINT_IDCHNG_Msk (0x1UL << GOTGINT_IDCHNG_Pos) // 0x00100000 */ #define GOTGINT_IDCHNG GOTGINT_IDCHNG_Msk // Change in ID pin input value */ +/******************** Bit definition for DCFG register ********************/ +#define DCFG_DSPD_Pos (0U) +#define DCFG_DSPD_Msk (0x3UL << DCFG_DSPD_Pos) // 0x00000003 +#define DCFG_DSPD_HS 0 // Highspeed +#define DCFG_DSPD_FS_HSPHY 1 // Fullspeed on HS PHY +#define DCFG_DSPD_LS 2 // Lowspeed +#define DCFG_DSPD_FS 3 // Fullspeed on FS PHY + +#define DCFG_NZLSOHSK_Pos (2U) +#define DCFG_NZLSOHSK_Msk (0x1UL << DCFG_NZLSOHSK_Pos) // 0x00000004 */ +#define DCFG_NZLSOHSK DCFG_NZLSOHSK_Msk // Nonzero-length status OUT handshake */ + +#define DCFG_DAD_Pos (4U) +#define DCFG_DAD_Msk (0x7FUL << DCFG_DAD_Pos) // 0x000007F0 */ +#define DCFG_DAD DCFG_DAD_Msk // Device address */ +#define DCFG_DAD_0 (0x01UL << DCFG_DAD_Pos) // 0x00000010 */ +#define DCFG_DAD_1 (0x02UL << DCFG_DAD_Pos) // 0x00000020 */ +#define DCFG_DAD_2 (0x04UL << DCFG_DAD_Pos) // 0x00000040 */ +#define DCFG_DAD_3 (0x08UL << DCFG_DAD_Pos) // 0x00000080 */ +#define DCFG_DAD_4 (0x10UL << DCFG_DAD_Pos) // 0x00000100 */ +#define DCFG_DAD_5 (0x20UL << DCFG_DAD_Pos) // 0x00000200 */ +#define DCFG_DAD_6 (0x40UL << DCFG_DAD_Pos) // 0x00000400 */ + +#define DCFG_PFIVL_Pos (11U) +#define DCFG_PFIVL_Msk (0x3UL << DCFG_PFIVL_Pos) // 0x00001800 */ +#define DCFG_PFIVL DCFG_PFIVL_Msk // Periodic (micro)frame interval */ +#define DCFG_PFIVL_0 (0x1UL << DCFG_PFIVL_Pos) // 0x00000800 */ +#define DCFG_PFIVL_1 (0x2UL << DCFG_PFIVL_Pos) // 0x00001000 */ + +#define DCFG_PERSCHIVL_Pos (24U) +#define DCFG_PERSCHIVL_Msk (0x3UL << DCFG_PERSCHIVL_Pos) // 0x03000000 */ +#define DCFG_PERSCHIVL DCFG_PERSCHIVL_Msk // Periodic scheduling interval */ +#define DCFG_PERSCHIVL_0 (0x1UL << DCFG_PERSCHIVL_Pos) // 0x01000000 */ +#define DCFG_PERSCHIVL_1 (0x2UL << DCFG_PERSCHIVL_Pos) // 0x02000000 */ + /******************** Bit definition for DCTL register ********************/ #define DCTL_RWUSIG_Pos (0U) #define DCTL_RWUSIG_Msk (0x1UL << DCTL_RWUSIG_Pos) // 0x00000001 */ @@ -466,12 +468,15 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define DSTS_SUSPSTS_Pos (0U) #define DSTS_SUSPSTS_Msk (0x1UL << DSTS_SUSPSTS_Pos) // 0x00000001 */ #define DSTS_SUSPSTS DSTS_SUSPSTS_Msk // Suspend status */ - #define DSTS_ENUMSPD_Pos (1U) #define DSTS_ENUMSPD_Msk (0x3UL << DSTS_ENUMSPD_Pos) // 0x00000006 */ #define DSTS_ENUMSPD DSTS_ENUMSPD_Msk // Enumerated speed */ -#define DSTS_ENUMSPD_0 (0x1UL << DSTS_ENUMSPD_Pos) // 0x00000002 */ -#define DSTS_ENUMSPD_1 (0x2UL << DSTS_ENUMSPD_Pos) // 0x00000004 */ +#define DSTS_ENUMSPD_HS 0 // Highspeed +#define DSTS_ENUMSPD_FS_HSPHY 1 // Fullspeed on HS PHY +#define DSTS_ENUMSPD_LS 2 // Lowspeed +#define DSTS_ENUMSPD_FS 3 // Fullspeed on FS PHY + + #define DSTS_EERR_Pos (3U) #define DSTS_EERR_Msk (0x1UL << DSTS_EERR_Pos) // 0x00000008 */ #define DSTS_EERR DSTS_EERR_Msk // Erratic error */ @@ -501,15 +506,12 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define GAHBCFG_PTXFELVL_Msk (0x1UL << GAHBCFG_PTXFELVL_Pos) // 0x00000100 */ #define GAHBCFG_PTXFELVL GAHBCFG_PTXFELVL_Msk // Periodic TxFIFO empty level */ -#define GSNPSID_ID_MASK TU_GENMASK(31, 16) +#define GSNPSID_ID_MASK TU_GENMASK(31, 16) /******************** Bit definition for GUSBCFG register ********************/ #define GUSBCFG_TOCAL_Pos (0U) #define GUSBCFG_TOCAL_Msk (0x7UL << GUSBCFG_TOCAL_Pos) // 0x00000007 */ #define GUSBCFG_TOCAL GUSBCFG_TOCAL_Msk // FS timeout calibration */ -#define GUSBCFG_TOCAL_0 (0x1UL << GUSBCFG_TOCAL_Pos) // 0x00000001 */ -#define GUSBCFG_TOCAL_1 (0x2UL << GUSBCFG_TOCAL_Pos) // 0x00000002 */ -#define GUSBCFG_TOCAL_2 (0x4UL << GUSBCFG_TOCAL_Pos) // 0x00000004 */ #define GUSBCFG_PHYIF16_Pos (3U) #define GUSBCFG_PHYIF16_Msk (0x1UL << GUSBCFG_PHYIF16_Pos) // 0x00000008 */ #define GUSBCFG_PHYIF16 GUSBCFG_PHYIF16_Msk // PHY Interface (PHYIf) */ @@ -519,7 +521,7 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define GUSBCFG_PHYSEL_Pos (6U) #define GUSBCFG_PHYSEL_Msk (0x1UL << GUSBCFG_PHYSEL_Pos) // 0x00000040 */ #define GUSBCFG_PHYSEL GUSBCFG_PHYSEL_Msk // USB 2.0 high-speed ULPI PHY or USB 1.1 full-speed serial transceiver select */ -#define GUSBCFG_DDRSEL TU_BIT(7) // Single Data Rate (SDR) or Double Data Rate (DDR) or ULPI interface. +#define GUSBCFG_DDRSEL TU_BIT(7) // Single Data Rate (SDR) or Double Data Rate (DDR) or ULPI interface. #define GUSBCFG_SRPCAP_Pos (8U) #define GUSBCFG_SRPCAP_Msk (0x1UL << GUSBCFG_SRPCAP_Pos) // 0x00000100 */ #define GUSBCFG_SRPCAP GUSBCFG_SRPCAP_Msk // SRP-capable */ @@ -597,8 +599,8 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define GRSTCTL_TXFNUM_2 (0x04UL << GRSTCTL_TXFNUM_Pos) // 0x00000100 */ #define GRSTCTL_TXFNUM_3 (0x08UL << GRSTCTL_TXFNUM_Pos) // 0x00000200 */ #define GRSTCTL_TXFNUM_4 (0x10UL << GRSTCTL_TXFNUM_Pos) // 0x00000400 */ -#define GRSTCTL_CSFTRST_DONE_Pos (29) -#define GRSTCTL_CSFTRST_DONE (1u << GRSTCTL_CSFTRST_DONE_Pos) // Reset Done, only available from v4.20a +#define GRSTCTL_CSFTRST_DONE_Pos (29) +#define GRSTCTL_CSFTRST_DONE (1u << GRSTCTL_CSFTRST_DONE_Pos) // Reset Done, only available from v4.20a #define GRSTCTL_DMAREQ_Pos (30U) #define GRSTCTL_DMAREQ_Msk (0x1UL << GRSTCTL_DMAREQ_Pos) // 0x40000000 */ #define GRSTCTL_DMAREQ GRSTCTL_DMAREQ_Msk // DMA request signal */ @@ -1672,48 +1674,36 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define DOEPTSIZ_STUPCNT_0 (0x1UL << DOEPTSIZ_STUPCNT_Pos) // 0x20000000 */ #define DOEPTSIZ_STUPCNT_1 (0x2UL << DOEPTSIZ_STUPCNT_Pos) // 0x40000000 */ -/******************** Bit definition for PCGCCTL register ********************/ -#define PCGCCTL_STOPCLK_Pos (0U) -#define PCGCCTL_STOPCLK_Msk (0x1UL << PCGCCTL_STOPCLK_Pos) // 0x00000001 */ -#define PCGCCTL_STOPCLK PCGCCTL_STOPCLK_Msk // SETUP packet count */ -#define PCGCCTL_GATECLK_Pos (1U) -#define PCGCCTL_GATECLK_Msk (0x1UL << PCGCCTL_GATECLK_Pos) // 0x00000002 */ -#define PCGCCTL_GATECLK PCGCCTL_GATECLK_Msk //Bit 0 */ -#define PCGCCTL_PHYSUSP_Pos (4U) -#define PCGCCTL_PHYSUSP_Msk (0x1UL << PCGCCTL_PHYSUSP_Pos) // 0x00000010 */ -#define PCGCCTL_PHYSUSP PCGCCTL_PHYSUSP_Msk //Bit 1 */ - -/******************** Bit definition for USBPHYC_PLL1 register ********************/ -#define HS_PHYC_PLL1_PLLEN_Pos (0U) -#define HS_PHYC_PLL1_PLLEN_Msk (0x1UL << HS_PHYC_PLL1_PLLEN_Pos) // 0x00000001 */ -#define HS_PHYC_PLL1_PLLEN HS_PHYC_PLL1_PLLEN_Msk // Enable PLL */ -#define HS_PHYC_PLL1_PLLSEL_Pos (1U) -#define HS_PHYC_PLL1_PLLSEL_Msk (0x7UL << HS_PHYC_PLL1_PLLSEL_Pos) // 0x0000000E */ -#define HS_PHYC_PLL1_PLLSEL HS_PHYC_PLL1_PLLSEL_Msk // Controls PHY frequency operation selection */ -#define HS_PHYC_PLL1_PLLSEL_1 (0x1UL << HS_PHYC_PLL1_PLLSEL_Pos) // 0x00000002 */ -#define HS_PHYC_PLL1_PLLSEL_2 (0x2UL << HS_PHYC_PLL1_PLLSEL_Pos) // 0x00000004 */ -#define HS_PHYC_PLL1_PLLSEL_3 (0x4UL << HS_PHYC_PLL1_PLLSEL_Pos) // 0x00000008 */ - -#define HS_PHYC_PLL1_PLLSEL_12MHZ 0x00000000U // PHY PLL1 input clock frequency 12 MHz */ -#define HS_PHYC_PLL1_PLLSEL_12_5MHZ HS_PHYC_PLL1_PLLSEL_1 // PHY PLL1 input clock frequency 12.5 MHz */ -#define HS_PHYC_PLL1_PLLSEL_16MHZ (uint32_t)(HS_PHYC_PLL1_PLLSEL_1 | HS_PHYC_PLL1_PLLSEL_2) // PHY PLL1 input clock frequency 16 MHz */ -#define HS_PHYC_PLL1_PLLSEL_24MHZ HS_PHYC_PLL1_PLLSEL_3 // PHY PLL1 input clock frequency 24 MHz */ -#define HS_PHYC_PLL1_PLLSEL_25MHZ (uint32_t)(HS_PHYC_PLL1_PLLSEL_2 | HS_PHYC_PLL1_PLLSEL_3) // PHY PLL1 input clock frequency 25 MHz */ - -/******************** Bit definition for USBPHYC_LDO register ********************/ -#define HS_PHYC_LDO_USED_Pos (0U) -#define HS_PHYC_LDO_USED_Msk (0x1UL << HS_PHYC_LDO_USED_Pos) // 0x00000001 */ -#define HS_PHYC_LDO_USED HS_PHYC_LDO_USED_Msk // Monitors the usage status of the PHY's LDO */ -#define HS_PHYC_LDO_STATUS_Pos (1U) -#define HS_PHYC_LDO_STATUS_Msk (0x1UL << HS_PHYC_LDO_STATUS_Pos) // 0x00000002 */ -#define HS_PHYC_LDO_STATUS HS_PHYC_LDO_STATUS_Msk // Monitors the status of the PHY's LDO. */ -#define HS_PHYC_LDO_DISABLE_Pos (2U) -#define HS_PHYC_LDO_DISABLE_Msk (0x1UL << HS_PHYC_LDO_DISABLE_Pos) // 0x00000004 */ -#define HS_PHYC_LDO_DISABLE HS_PHYC_LDO_DISABLE_Msk // Controls disable of the High Speed PHY's LDO */ - -#define HS_PHYC_LDO_ENABLE_Pos HS_PHYC_LDO_DISABLE_Pos -#define HS_PHYC_LDO_ENABLE_Msk HS_PHYC_LDO_DISABLE_Msk -#define HS_PHYC_LDO_ENABLE HS_PHYC_LDO_DISABLE +/******************** Bit definition for PCGCTL register ********************/ +#define PCGCTL_IF_DEV_MODE TU_BIT(31) +#define PCGCTL_P2HD_PRT_SPD_MASK (0x3ul << 29) +#define PCGCTL_P2HD_PRT_SPD_SHIFT 29 +#define PCGCTL_P2HD_DEV_ENUM_SPD_MASK (0x3ul << 27) +#define PCGCTL_P2HD_DEV_ENUM_SPD_SHIFT 27 +#define PCGCTL_MAC_DEV_ADDR_MASK (0x7ful << 20) +#define PCGCTL_MAC_DEV_ADDR_SHIFT 20 +#define PCGCTL_MAX_TERMSEL TU_BIT(19) +#define PCGCTL_MAX_XCVRSELECT_MASK (0x3ul << 17) +#define PCGCTL_MAX_XCVRSELECT_SHIFT 17 +#define PCGCTL_PORT_POWER TU_BIT(16) +#define PCGCTL_PRT_CLK_SEL_MASK (0x3ul << 14) +#define PCGCTL_PRT_CLK_SEL_SHIFT 14 +#define PCGCTL_ESS_REG_RESTORED TU_BIT(13) +#define PCGCTL_EXTND_HIBER_SWITCH TU_BIT(12) +#define PCGCTL_EXTND_HIBER_PWRCLMP TU_BIT(11) +#define PCGCTL_ENBL_EXTND_HIBER TU_BIT(10) +#define PCGCTL_RESTOREMODE TU_BIT(9) +#define PCGCTL_RESETAFTSUSP TU_BIT(8) +#define PCGCTL_DEEP_SLEEP TU_BIT(7) +#define PCGCTL_PHY_IN_SLEEP TU_BIT(6) +#define PCGCTL_ENBL_SLEEP_GATING TU_BIT(5) +#define PCGCTL_RSTPDWNMODULE TU_BIT(3) +#define PCGCTL_PWRCLMP TU_BIT(2) +#define PCGCTL_GATEHCLK TU_BIT(1) +#define PCGCTL_STOPPCLK TU_BIT(0) + +#define PCGCTL1_TIMER (0x3ul << 1) +#define PCGCTL1_GATEEN TU_BIT(0) #ifdef __cplusplus } -- cgit v1.3.1 From 660e8b8c887091e17323c361f25e804a5d06d6df Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 29 Oct 2021 16:08:19 +0700 Subject: skip snpsid check for gd32, abstract phyfs turnaround, set max timeout calibration. still has issue with gd32 with msc (does work with running with rtt as log). --- src/common/tusb_common.h | 3 + src/portable/synopsys/dwc2/dcd_dwc2.c | 191 +++++++++++++++++--------------- src/portable/synopsys/dwc2/dwc2_bcm.h | 7 +- src/portable/synopsys/dwc2/dwc2_esp32.h | 8 +- src/portable/synopsys/dwc2/dwc2_gd32.h | 8 +- src/portable/synopsys/dwc2/dwc2_stm32.h | 61 +++++----- src/portable/synopsys/dwc2/dwc2_type.h | 13 ++- 7 files changed, 144 insertions(+), 147 deletions(-) (limited to 'src/common') diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index e62bcde12..9b9e2b007 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -111,6 +111,9 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte2(uint32_t ui32) { return TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte1(uint32_t ui32) { return TU_U32_BYTE1(ui32); } TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u32_byte0(uint32_t ui32) { return TU_U32_BYTE0(ui32); } +TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u32_high16(uint32_t ui32) { return (uint16_t) (ui32 >> 16); } +TU_ATTR_ALWAYS_INLINE static inline uint16_t tu_u32_low16 (uint32_t ui32) { return (uint16_t) (ui32 & 0x0000ffffu); } + TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u16_high(uint16_t ui16) { return TU_U16_HIGH(ui16); } TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u16_low (uint16_t ui16) { return TU_U16_LOW(ui16); } diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index ce9b58e03..aad7e45cc 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -54,16 +54,8 @@ #define DWC2_REG(_port) ((dwc2_regs_t*) DWC2_REG_BASE) -enum -{ - DCD_HIGH_SPEED = 0, // Highspeed mode - DCD_FULL_SPEED_USE_HS = 1, // Full speed in Highspeed port (probably with internal PHY) - DCD_FULL_SPEED = 3, // Full speed with internal PHY -}; - -// PHYSEL, ULPISEL -// UTMI internal HS PHY -// ULPI external HS PHY +// Debug level for DWC2 +#define DWC2_DEBUG 1 static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2]; @@ -261,71 +253,73 @@ 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) { dwc2_ghwcfg2_t const * hw_cfg2 = &dwc2->ghwcfg2_bm; dwc2_ghwcfg3_t const * hw_cfg3 = &dwc2->ghwcfg3_bm; dwc2_ghwcfg4_t const * hw_cfg4 = &dwc2->ghwcfg4_bm; - TU_LOG_HEX(1, dwc2->guid); - TU_LOG_HEX(1, dwc2->gsnpsid); - TU_LOG_HEX(1, dwc2->ghwcfg1); + TU_LOG_HEX(DWC2_DEBUG, dwc2->guid); + TU_LOG_HEX(DWC2_DEBUG, dwc2->gsnpsid); + TU_LOG_HEX(DWC2_DEBUG, dwc2->ghwcfg1); // HW configure 2 - TU_LOG(1, "\r\n"); - TU_LOG_HEX(1, dwc2->ghwcfg2); - TU_LOG_INT(1, hw_cfg2->op_mode ); - TU_LOG_INT(1, hw_cfg2->arch ); - TU_LOG_INT(1, hw_cfg2->point2point ); - TU_LOG_INT(1, hw_cfg2->hs_phy_type ); - TU_LOG_INT(1, hw_cfg2->fs_phy_type ); - TU_LOG_INT(1, hw_cfg2->num_dev_ep ); - TU_LOG_INT(1, hw_cfg2->num_host_ch ); - TU_LOG_INT(1, hw_cfg2->period_channel_support ); - TU_LOG_INT(1, hw_cfg2->enable_dynamic_fifo ); - TU_LOG_INT(1, hw_cfg2->mul_cpu_int ); - TU_LOG_INT(1, hw_cfg2->nperiod_tx_q_depth ); - TU_LOG_INT(1, hw_cfg2->host_period_tx_q_depth ); - TU_LOG_INT(1, hw_cfg2->dev_token_q_depth ); - TU_LOG_INT(1, hw_cfg2->otg_enable_ic_usb ); + TU_LOG(DWC2_DEBUG, "\r\n"); + TU_LOG_HEX(DWC2_DEBUG, dwc2->ghwcfg2); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->op_mode ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->arch ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->point2point ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->hs_phy_type ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->fs_phy_type ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->num_dev_ep ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->num_host_ch ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->period_channel_support ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->enable_dynamic_fifo ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->mul_cpu_int ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->nperiod_tx_q_depth ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->host_period_tx_q_depth ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->dev_token_q_depth ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg2->otg_enable_ic_usb ); // HW configure 3 - TU_LOG(1, "\r\n"); - TU_LOG_HEX(1, dwc2->ghwcfg3); - TU_LOG_INT(1, hw_cfg3->xfer_size_width ); - TU_LOG_INT(1, hw_cfg3->packet_size_width ); - TU_LOG_INT(1, hw_cfg3->otg_enable ); - TU_LOG_INT(1, hw_cfg3->i2c_enable ); - TU_LOG_INT(1, hw_cfg3->vendor_ctrl_itf ); - TU_LOG_INT(1, hw_cfg3->optional_feature_removed ); - TU_LOG_INT(1, hw_cfg3->synch_reset ); - TU_LOG_INT(1, hw_cfg3->otg_adp_support ); - TU_LOG_INT(1, hw_cfg3->otg_enable_hsic ); - TU_LOG_INT(1, hw_cfg3->battery_charger_support ); - TU_LOG_INT(1, hw_cfg3->lpm_mode ); - TU_LOG_INT(1, hw_cfg3->total_fifo_size ); + TU_LOG(DWC2_DEBUG, "\r\n"); + TU_LOG_HEX(DWC2_DEBUG, dwc2->ghwcfg3); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->xfer_size_width ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->packet_size_width ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->otg_enable ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->i2c_enable ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->vendor_ctrl_itf ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->optional_feature_removed ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->synch_reset ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->otg_adp_support ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->otg_enable_hsic ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->battery_charger_support ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->lpm_mode ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg3->total_fifo_size ); // HW configure 4 - TU_LOG(1, "\r\n"); - TU_LOG_HEX(1, dwc2->ghwcfg4); - TU_LOG_INT(1, hw_cfg4->num_dev_period_in_ep ); - TU_LOG_INT(1, hw_cfg4->power_optimized ); - TU_LOG_INT(1, hw_cfg4->ahb_freq_min ); - TU_LOG_INT(1, hw_cfg4->hibernation ); - TU_LOG_INT(1, hw_cfg4->service_interval_mode ); - TU_LOG_INT(1, hw_cfg4->ipg_isoc_en ); - TU_LOG_INT(1, hw_cfg4->acg_enable ); - TU_LOG_INT(1, hw_cfg4->utmi_phy_data_width ); - TU_LOG_INT(1, hw_cfg4->dev_ctrl_ep_num ); - TU_LOG_INT(1, hw_cfg4->iddg_filter_enabled ); - TU_LOG_INT(1, hw_cfg4->vbus_valid_filter_enabled ); - TU_LOG_INT(1, hw_cfg4->a_valid_filter_enabled ); - TU_LOG_INT(1, hw_cfg4->b_valid_filter_enabled ); - TU_LOG_INT(1, hw_cfg4->dedicated_fifos ); - TU_LOG_INT(1, hw_cfg4->num_dev_in_eps ); - TU_LOG_INT(1, hw_cfg4->dma_desc_enable ); - TU_LOG_INT(1, hw_cfg4->dma_dynamic ); + TU_LOG(DWC2_DEBUG, "\r\n"); + TU_LOG_HEX(DWC2_DEBUG, dwc2->ghwcfg4); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->num_dev_period_in_ep ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->power_optimized ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->ahb_freq_min ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->hibernation ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->service_interval_mode ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->ipg_isoc_en ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->acg_enable ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->utmi_phy_data_width ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->dev_ctrl_ep_num ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->iddg_filter_enabled ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->vbus_valid_filter_enabled ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->a_valid_filter_enabled ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->b_valid_filter_enabled ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->dedicated_fifos ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->num_dev_in_eps ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->dma_desc_enable ); + TU_LOG_INT(DWC2_DEBUG, hw_cfg4->dma_dynamic ); } +#endif static void reset_core(dwc2_regs_t * dwc2) { @@ -342,14 +336,15 @@ static void reset_core(dwc2_regs_t * dwc2) // wait for device mode ? } -static bool has_hs_phy(dwc2_regs_t * dwc2) +static bool phy_hs_supported(dwc2_regs_t * dwc2) { + // note: esp32 incorrect report its hs_phy_type as utmi return TUD_OPT_HIGH_SPEED && dwc2->ghwcfg2_bm.hs_phy_type != HS_PHY_TYPE_NONE; } static void phy_fs_init(dwc2_regs_t * dwc2) { - TU_LOG1("Fullspeed PHY init\r\n"); + TU_LOG(DWC2_DEBUG, "Fullspeed PHY init\r\n"); // Select FS PHY dwc2->gusbcfg |= GUSBCFG_PHYSEL; @@ -358,11 +353,11 @@ static void phy_fs_init(dwc2_regs_t * dwc2) reset_core(dwc2); // set turn around - // The values above are calculated for the minimum AHB frequency of 30 MHz. USB turnaround - // time is critical for certification where long cables and 5-Hubs are used, so if - // you need the AHB to run at less than 30 MHz, and if USB turnaround time is not critical, + // USB turnaround time is critical for certification where long cables and 5-Hubs are used. + // So if you need the AHB to run at less than 30 MHz, and if USB turnaround time is not critical, // these bits can be programmed to a larger value. - dwc2_set_turnaround(dwc2, TUSB_SPEED_FULL); + //TU_LOG_INT(DWC2_DEBUG, (dwc2->gusbcfg & GUSBCFG_TRDT_Msk) >> GUSBCFG_TRDT_Pos ); + dwc2_phyfs_set_turnaround(dwc2); // set max speed dwc2->dcfg = (dwc2->dcfg & ~DCFG_DSPD_Msk) | (DCFG_DSPD_FS << DCFG_DSPD_Pos); @@ -382,7 +377,7 @@ static void phy_hs_init(dwc2_regs_t * dwc2) if (dwc2->ghwcfg2_bm.hs_phy_type == HS_PHY_TYPE_ULPI) { - TU_LOG1("Highspeed ULPI PHY init\r\n"); + TU_LOG(DWC2_DEBUG, "Highspeed ULPI PHY init\r\n"); // Select ULPI gusbcfg |= GUSBCFG_ULPI_UTMI_SEL; @@ -397,7 +392,7 @@ static void phy_hs_init(dwc2_regs_t * dwc2) gusbcfg &= ~(GUSBCFG_ULPIFSLS | GUSBCFG_ULPICSM); }else { - TU_LOG1("Highspeed UTMI+ PHY init\r\n"); + TU_LOG(DWC2_DEBUG, "Highspeed UTMI+ PHY init\r\n"); // Select UTMI+ with 8-bit interface gusbcfg &= ~(GUSBCFG_ULPI_UTMI_SEL | GUSBCFG_PHYIF16); @@ -422,11 +417,8 @@ static void phy_hs_init(dwc2_regs_t * dwc2) reset_core(dwc2); // Set turn-around, must after core reset otherwise it will be clear - // 9 if UTMI interface is 8-bit, 5 if 16-bit - // The values above are calculated for the minimum AHB frequency of 30 MHz. USB turnaround - // time is critical for certification where long cables and 5-Hubs are used, so if - // you need the AHB to run at less than 30 MHz, and if USB turnaround time is not critical, - // these bits can be programmed to a larger value. + // - 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; dwc2->gusbcfg = gusbcfg; // Apply config @@ -435,31 +427,45 @@ static void phy_hs_init(dwc2_regs_t * dwc2) dwc2->dcfg = (dwc2->dcfg & ~DCFG_DSPD_Msk) | (DCFG_DSPD_HS << DCFG_DSPD_Pos); } +static bool check_dwc2(dwc2_regs_t * dwc2) +{ + // For some reasons: GD32VF103 snpsid and all hwcfg register are always zero (skip it) +#if !TU_CHECK_MCU(OPT_MCU_GD32VF103) + uint32_t const gsnpsid = dwc2->gsnpsid & GSNPSID_ID_MASK; + TU_ASSERT(gsnpsid == DWC2_OTG_ID || gsnpsid == DWC2_FS_IOT_ID || gsnpsid == DWC2_HS_IOT_ID); +#endif + +#if CFG_TUSB_DEBUG >= DWC2_DEBUG + print_dwc2_info(dwc2); +#endif + + return true; +} + void dcd_init (uint8_t rhport) { // 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, failed if controller is not enabled - uint32_t const gsnpsid = dwc2->gsnpsid & GSNPSID_ID_MASK; - TU_ASSERT(gsnpsid == DWC2_OTG_ID || gsnpsid == DWC2_FS_IOT_ID || gsnpsid == DWC2_HS_IOT_ID, ); - - print_dwc2_info(dwc2); + // Check Synopsys ID register, failed if controller clock/power is not enabled + TU_VERIFY(check_dwc2(dwc2), ); // Force device mode dwc2->gusbcfg = (dwc2->gusbcfg & ~GUSBCFG_FHMOD) | GUSBCFG_FDMOD; - if( !has_hs_phy(dwc2) ) - { - // core does not support highspeed or hs-phy is not present - phy_fs_init(dwc2); - }else + if( phy_hs_supported(dwc2) ) { // Highspeed phy_hs_init(dwc2); + }else + { + // core does not support highspeed or hs-phy is not present + phy_fs_init(dwc2); } + TU_LOG_HEX(DWC2_DEBUG, dwc2->gusbcfg); + /* Set HS/FS Timeout Calibration to 7 (max available value). * The number of PHY clocks that the application programs in * this field is added to the high/full speed interpacket timeout @@ -468,7 +474,7 @@ void dcd_init (uint8_t rhport) * introduced by the PHY in generating the linestate condition * can vary from one PHY to another. */ - // dwc2->gusbcfg |= (7ul << GUSBCFG_TOCAL_Pos); + dwc2->gusbcfg |= (7ul << GUSBCFG_TOCAL_Pos); // Restart PHY clock dwc2->pcgctl &= ~(PCGCTL_STOPPCLK | PCGCTL_GATEHCLK | PCGCTL_PWRCLMP | PCGCTL_RSTPDWNMODULE); @@ -617,7 +623,7 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) _allocated_fifo_words_tx += fifo_size; - TU_LOG(2, " Allocated %u bytes at offset %u", fifo_size*4, DWC2_EP_FIFO_SIZE-_allocated_fifo_words_tx*4); + TU_LOG(DWC2_DEBUG, " Allocated %u bytes at offset %u", fifo_size*4, DWC2_EP_FIFO_SIZE-_allocated_fifo_words_tx*4); // DIEPTXF starts at FIFO #1. // Both TXFD and TXSA are in unit of 32-bit words. @@ -1110,14 +1116,15 @@ void dcd_int_handler(uint8_t rhport) speed = TUSB_SPEED_HIGH; break; + case DSTS_ENUMSPD_LS: + speed = TUSB_SPEED_LOW; + break; + case DSTS_ENUMSPD_FS_HSPHY: case DSTS_ENUMSPD_FS: + default: speed = TUSB_SPEED_FULL; break; - - case DSTS_ENUMSPD_LS: - speed = TUSB_SPEED_LOW; - break; } dcd_event_bus_reset(rhport, speed, true); @@ -1204,7 +1211,7 @@ void dcd_int_handler(uint8_t rhport) // // Check for Incomplete isochronous IN transfer // if(int_status & GINTSTS_IISOIXFR) { // printf(" IISOIXFR!\r\n"); - //// TU_LOG2(" IISOIXFR!\r\n"); + //// TU_LOG(DWC2_DEBUG, " IISOIXFR!\r\n"); // } } diff --git a/src/portable/synopsys/dwc2/dwc2_bcm.h b/src/portable/synopsys/dwc2/dwc2_bcm.h index da1f23ae0..c064946cf 100644 --- a/src/portable/synopsys/dwc2/dwc2_bcm.h +++ b/src/portable/synopsys/dwc2/dwc2_bcm.h @@ -58,11 +58,10 @@ static inline void dwc2_remote_wakeup_delay(void) // TODO implement later } -static inline void dwc2_set_turnaround(dwc2_regs_t * core, tusb_speed_t speed) +static inline void dwc2_phyfs_set_turnaround(dwc2_regs_t * dwc2) { - // TODO implement later - (void) core; - (void) speed; + (void) dwc2; + // do nothing since bcm alwyas use HS PHY } #ifdef __cplusplus diff --git a/src/portable/synopsys/dwc2/dwc2_esp32.h b/src/portable/synopsys/dwc2/dwc2_esp32.h index b8a040041..af5d5f093 100644 --- a/src/portable/synopsys/dwc2/dwc2_esp32.h +++ b/src/portable/synopsys/dwc2/dwc2_esp32.h @@ -67,12 +67,10 @@ static inline void dwc2_remote_wakeup_delay(void) vTaskDelay(pdMS_TO_TICKS(1)); } -static inline void dwc2_set_turnaround(dwc2_regs_t * core, tusb_speed_t speed) +static inline void dwc2_phyfs_set_turnaround(dwc2_regs_t * dwc2) { - (void) core; - (void) speed; - - // keep the reset value + (void) dwc2; + // keep the reset value which is 5 on this port } #ifdef __cplusplus diff --git a/src/portable/synopsys/dwc2/dwc2_gd32.h b/src/portable/synopsys/dwc2/dwc2_gd32.h index de3ccb3b0..15e73ad1e 100644 --- a/src/portable/synopsys/dwc2/dwc2_gd32.h +++ b/src/portable/synopsys/dwc2/dwc2_gd32.h @@ -76,12 +76,10 @@ static inline void dwc2_remote_wakeup_delay(void) while ( count-- ) __asm volatile ("nop"); } -static inline void dwc2_set_turnaround(dwc2_regs_t * core, tusb_speed_t speed) +static inline void dwc2_phyfs_set_turnaround(dwc2_regs_t * dwc2) { - (void) core; - (void) speed; - - // keep the reset value + // use recommeded value 6 by stm32 for mcu with AHB clock > 32Mhz + dwc2->gusbcfg = (dwc2->gusbcfg & GUSBCFG_TRDT_Msk) | (6u << GUSBCFG_TRDT_Pos); } diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index b77cda2ca..4d0ed3f0a 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -113,44 +113,33 @@ static inline void dwc2_remote_wakeup_delay(void) } // Set turn-around timeout according to link speed -static inline void dwc2_set_turnaround(dwc2_regs_t * dwc2, tusb_speed_t speed) +static inline void dwc2_phyfs_set_turnaround(dwc2_regs_t * dwc2) { - dwc2->gusbcfg &= ~GUSBCFG_TRDT; - - if ( speed == TUSB_SPEED_HIGH ) - { - // Use fixed 0x09 for Highspeed - dwc2->gusbcfg |= (0x09 << GUSBCFG_TRDT_Pos); - } + // Turnaround timeout depends on the AHB clock dictated by STM32 Reference Manual + uint32_t turnaround; + + if ( SystemCoreClock >= 32000000U ) + turnaround = 0x6u; + else if ( SystemCoreClock >= 27500000U ) + turnaround = 0x7u; + else if ( SystemCoreClock >= 24000000U ) + turnaround = 0x8u; + else if ( SystemCoreClock >= 21800000U ) + turnaround = 0x9u; + else if ( SystemCoreClock >= 20000000U ) + turnaround = 0xAu; + else if ( SystemCoreClock >= 18500000U ) + turnaround = 0xBu; + else if ( SystemCoreClock >= 17200000U ) + turnaround = 0xCu; + else if ( SystemCoreClock >= 16000000U ) + turnaround = 0xDu; + else if ( SystemCoreClock >= 15000000U ) + turnaround = 0xEu; else - { - // Turnaround timeout depends on the MCU clock - uint32_t turnaround; - - if ( SystemCoreClock >= 32000000U ) - turnaround = 0x6U; - else if ( SystemCoreClock >= 27500000U ) - turnaround = 0x7U; - else if ( SystemCoreClock >= 24000000U ) - turnaround = 0x8U; - else if ( SystemCoreClock >= 21800000U ) - turnaround = 0x9U; - else if ( SystemCoreClock >= 20000000U ) - turnaround = 0xAU; - else if ( SystemCoreClock >= 18500000U ) - turnaround = 0xBU; - else if ( SystemCoreClock >= 17200000U ) - turnaround = 0xCU; - else if ( SystemCoreClock >= 16000000U ) - turnaround = 0xDU; - else if ( SystemCoreClock >= 15000000U ) - turnaround = 0xEU; - else - turnaround = 0xFU; - - // Fullspeed depends on MCU clocks, but we will use 0x06 for 32+ Mhz - dwc2->gusbcfg |= (turnaround << GUSBCFG_TRDT_Pos); - } + turnaround = 0xFu; + + dwc2->gusbcfg = (dwc2->gusbcfg & GUSBCFG_TRDT_Msk) | (turnaround << GUSBCFG_TRDT_Pos); } #if defined(USB_HS_PHYC) diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h index 7e472310f..7b3db4dd9 100644 --- a/src/portable/synopsys/dwc2/dwc2_type.h +++ b/src/portable/synopsys/dwc2/dwc2_type.h @@ -59,12 +59,19 @@ typedef struct #endif enum { - HS_PHY_TYPE_NONE = 0 , + 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 , }; +enum { + FS_PHY_TYPE_NONE = 0, // not supported + FS_PHY_TYPE_DEDICATED, + FS_PHY_TYPE_UTMI, + FS_PHY_TYPE_ULPI, +}; + typedef struct TU_ATTR_PACKED { uint32_t op_mode : 3; // 0: HNP and SRP | 1: SRP | 2: non-HNP, non-SRP @@ -531,10 +538,6 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo ) == 0x1000, "incorrect size"); #define GUSBCFG_TRDT_Pos (10U) #define GUSBCFG_TRDT_Msk (0xFUL << GUSBCFG_TRDT_Pos) // 0x00003C00 */ #define GUSBCFG_TRDT GUSBCFG_TRDT_Msk // USB turnaround time */ -#define GUSBCFG_TRDT_0 (0x1UL << GUSBCFG_TRDT_Pos) // 0x00000400 */ -#define GUSBCFG_TRDT_1 (0x2UL << GUSBCFG_TRDT_Pos) // 0x00000800 */ -#define GUSBCFG_TRDT_2 (0x4UL << GUSBCFG_TRDT_Pos) // 0x00001000 */ -#define GUSBCFG_TRDT_3 (0x8UL << GUSBCFG_TRDT_Pos) // 0x00002000 */ #define GUSBCFG_PHYLPCS_Pos (15U) #define GUSBCFG_PHYLPCS_Msk (0x1UL << GUSBCFG_PHYLPCS_Pos) // 0x00008000 */ #define GUSBCFG_PHYLPCS GUSBCFG_PHYLPCS_Msk // PHY Low-power clock select */ -- cgit v1.3.1