update(cherryusb): update to v1.5.1

Signed-off-by: sakumisu <1203593632@qq.com>
This commit is contained in:
sakumisu 2025-07-15 13:57:24 +08:00 committed by Rbb666
parent 53fcd9d085
commit 5e03e07c43
34 changed files with 2196 additions and 701 deletions

View File

@ -52,6 +52,8 @@ if CHERRYUSB
bool "musb_sunxi"
config CHERRYUSB_DEVICE_MUSB_BK
bool "musb_bk"
config CHERRYUSB_DEVICE_MUSB_SIFLI
bool "musb_sifli"
config CHERRYUSB_DEVICE_MUSB_CUSTOM
bool "musb_custom"
config CHERRYUSB_DEVICE_CHIPIDEA_MCX
@ -123,7 +125,6 @@ if CHERRYUSB
prompt "Enable usb mtp device, it is commercial charge"
default n
config CHERRYUSB_DEVICE_ADB
bool
prompt "Enable usb adb device"
@ -134,45 +135,99 @@ if CHERRYUSB
prompt "Enable usb dfu device"
default n
config USBDEV_REQUEST_BUFFER_LEN
int
prompt "Set device control transfer max buffer size"
default 512
config USBDEV_MSC_MAX_BUFSIZE
int
prompt "Set usb msc device max buffer size"
default 512
help
Set the maximum buffer size for usb msc device, it is used to transfer data.
you can change it to a larger value if you need larger speed but must be a power of blocksize.
config USBDEV_RNDIS_USING_LWIP
bool
prompt "Enable usb rndis device with lwip for lan"
default n
config USBDEV_CDC_ECM_USING_LWIP
bool
prompt "Enable usb cdc ecm device with lwip for lan"
default n
choice
prompt "Select usb device template"
prompt "Select usb device template, please select class driver first"
default CHERRYUSB_DEVICE_TEMPLATE_NONE
config CHERRYUSB_DEVICE_TEMPLATE_NONE
bool "none (Implement it yourself)"
bool
prompt "none (Implement it yourself)"
config CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM
bool "cdc_acm"
bool
prompt "cdc_acm"
depends on CHERRYUSB_DEVICE_CDC_ACM
config CHERRYUSB_DEVICE_TEMPLATE_MSC
bool "msc"
bool
prompt "msc_ram"
depends on CHERRYUSB_DEVICE_MSC
config CHERRYUSB_DEVICE_TEMPLATE_HID_KEYBOARD
bool "hid_keyboard"
bool
prompt "hid_keyboard"
depends on CHERRYUSB_DEVICE_HID
config CHERRYUSB_DEVICE_TEMPLATE_HID_MOUSE
bool "hid_mouse"
bool
prompt "hid_mouse"
depends on CHERRYUSB_DEVICE_HID
config CHERRYUSB_DEVICE_TEMPLATE_HID_CUSTOM
bool "hid_custom"
bool
prompt "hid_custom"
depends on CHERRYUSB_DEVICE_HID
config CHERRYUSB_DEVICE_TEMPLATE_VIDEO
bool "video"
bool
prompt "video"
depends on CHERRYUSB_DEVICE_VIDEO
config CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V1_MIC_SPEAKER
bool "audio_v1_mic_speaker_multichan"
bool
prompt "audio_v1_mic_speaker_multichan"
depends on CHERRYUSB_DEVICE_AUDIO
config CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V2_MIC_SPEAKER
bool "audio_v2_mic_speaker_multichan"
bool
prompt "audio_v2_mic_speaker_multichan"
depends on CHERRYUSB_DEVICE_AUDIO
config CHERRYUSB_DEVICE_TEMPLATE_CDC_RNDIS
bool "cdc_rndis"
bool
prompt "cdc_rndis"
depends on CHERRYUSB_DEVICE_CDC_RNDIS
config CHERRYUSB_DEVICE_TEMPLATE_CDC_ECM
bool "cdc_ecm"
bool
prompt "cdc_ecm"
depends on CHERRYUSB_DEVICE_CDC_ECM
config CHERRYUSB_DEVICE_TEMPLATE_CDC_NCM
bool "cdc_ncm"
bool
prompt "cdc_ncm"
depends on CHERRYUSB_DEVICE_CDC_NCM
config CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC
bool "cdc_acm_msc"
bool
prompt "cdc_acm_msc"
depends on CHERRYUSB_DEVICE_CDC_ACM && CHERRYUSB_DEVICE_MSC
config CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC_HID
bool "cdc_acm_msc_hid"
bool
prompt "cdc_acm_msc_hid"
depends on CHERRYUSB_DEVICE_CDC_ACM && CHERRYUSB_DEVICE_MSC && CHERRYUSB_DEVICE_HID
config CHERRYUSB_DEVICE_TEMPLATE_WINUSBV1
bool "winusbv1"
bool
prompt "winusbv1"
config CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_CDC
bool "winusbv2_cdc"
bool
prompt "winusbv2_cdc"
depends on CHERRYUSB_DEVICE_CDC_ACM
config CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_HID
bool "winusbv2_hid"
bool
prompt "winusbv2_hid"
depends on CHERRYUSB_DEVICE_HID
endchoice
endif
menuconfig CHERRYUSB_HOST
@ -217,6 +272,8 @@ if CHERRYUSB
bool "musb_sunxi"
config CHERRYUSB_HOST_MUSB_BK
bool "musb_bk"
config CHERRYUSB_HOST_MUSB_SIFLI
bool "musb_sifli"
config CHERRYUSB_HOST_MUSB_CUSTOM
bool "musb_custom"
config CHERRYUSB_HOST_PUSB2
@ -335,12 +392,27 @@ if CHERRYUSB
config USBHOST_PLATFORM_RTL8152
bool
config CHERRYUSB_HOST_TEMPLATE
bool
prompt "Use usb host template"
default n
config USBHOST_PSC_PRIO
int
prompt "Set hubport change thread priority, 0 is the max priority"
default 0
if CHERRYUSB_HOST_TEMPLATE
config USBHOST_PSC_STACKSIZE
int
prompt "Set hubport change thread stacksize"
default 4096
config USBHOST_REQUEST_BUFFER_LEN
int
prompt "Set host control transfer max buffer size"
default 512
config USBHOST_CONTROL_TRANSFER_TIMEOUT
int
prompt "Set host control transfer timeout, unit is ms"
default 500
menu "Select USB host template, please select class driver first"
config TEST_USBH_CDC_ACM
int
prompt "demo for test cdc acm"
@ -356,7 +428,6 @@ if CHERRYUSB
prompt "demo for test msc"
default 0
depends on CHERRYUSB_HOST_MSC
endmenu
endif
endif
endif

View File

@ -52,6 +52,8 @@ if RT_USING_CHERRYUSB
bool "musb_sunxi"
config RT_CHERRYUSB_DEVICE_MUSB_BK
bool "musb_bk"
config RT_CHERRYUSB_DEVICE_MUSB_SIFLI
bool "musb_sifli"
config RT_CHERRYUSB_DEVICE_MUSB_CUSTOM
bool "musb_custom"
config RT_CHERRYUSB_DEVICE_CHIPIDEA_MCX
@ -140,49 +142,110 @@ if RT_USING_CHERRYUSB
prompt "Enable chardev for cdc acm device"
default n
config CONFIG_USBDEV_REQUEST_BUFFER_LEN
int
prompt "Set device control transfer max buffer size"
default 512
config CONFIG_USBDEV_MSC_MAX_BUFSIZE
int
prompt "Set usb msc device max buffer size"
default 512
help
Set the maximum buffer size for usb msc device, it is used to transfer data.
you can change it to a larger value if you need larger speed but must be a power of blocksize.
config CONFIG_USBDEV_RNDIS_USING_LWIP
bool
prompt "Enable usb rndis device with lwip for lan"
default n
config CONFIG_USBDEV_CDC_ECM_USING_LWIP
bool
prompt "Enable usb cdc ecm device with lwip for lan"
default n
choice
prompt "Select usb device template"
prompt "Select usb device template, please select class driver first"
default RT_CHERRYUSB_DEVICE_TEMPLATE_NONE
config RT_CHERRYUSB_DEVICE_TEMPLATE_NONE
bool "none (Implement it yourself)"
bool
prompt "none (Implement it yourself)"
config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM
bool "cdc_acm"
bool
prompt "cdc_acm"
depends on RT_CHERRYUSB_DEVICE_CDC_ACM
config RT_CHERRYUSB_DEVICE_TEMPLATE_MSC
bool "msc_ram"
bool
prompt "msc_ram"
depends on RT_CHERRYUSB_DEVICE_MSC
config RT_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV
bool "msc_blkdev"
bool
prompt "msc_blkdev"
depends on RT_CHERRYUSB_DEVICE_MSC
config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_KEYBOARD
bool "hid_keyboard"
bool
prompt "hid_keyboard"
depends on RT_CHERRYUSB_DEVICE_HID
config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_MOUSE
bool "hid_mouse"
bool
prompt "hid_mouse"
depends on RT_CHERRYUSB_DEVICE_HID
config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_CUSTOM
bool "hid_custom"
bool
prompt "hid_custom"
depends on RT_CHERRYUSB_DEVICE_HID
config RT_CHERRYUSB_DEVICE_TEMPLATE_VIDEO
bool "video"
bool
prompt "video"
depends on RT_CHERRYUSB_DEVICE_VIDEO
config RT_CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V1_MIC_SPEAKER
bool "audio_v1_mic_speaker_multichan"
bool
prompt "audio_v1_mic_speaker_multichan"
depends on RT_CHERRYUSB_DEVICE_AUDIO
config RT_CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V2_MIC_SPEAKER
bool "audio_v2_mic_speaker_multichan"
bool
prompt "audio_v2_mic_speaker_multichan"
depends on RT_CHERRYUSB_DEVICE_AUDIO
config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_RNDIS
bool "cdc_rndis"
bool
prompt "cdc_rndis"
depends on RT_CHERRYUSB_DEVICE_CDC_RNDIS
config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ECM
bool "cdc_ecm"
bool
prompt "cdc_ecm"
depends on RT_CHERRYUSB_DEVICE_CDC_ECM
config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_NCM
bool "cdc_ncm"
bool
prompt "cdc_ncm"
depends on RT_CHERRYUSB_DEVICE_CDC_NCM
config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC
bool "cdc_acm_msc"
bool
prompt "cdc_acm_msc"
depends on RT_CHERRYUSB_DEVICE_CDC_ACM && RT_CHERRYUSB_DEVICE_MSC
config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC_HID
bool "cdc_acm_msc_hid"
bool
prompt "cdc_acm_msc_hid"
depends on RT_CHERRYUSB_DEVICE_CDC_ACM && RT_CHERRYUSB_DEVICE_MSC && RT_CHERRYUSB_DEVICE_HID
config RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV1
bool "winusbv1"
bool
prompt "winusbv1"
config RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_CDC
bool "winusbv2_cdc"
bool
prompt "winusbv2_cdc"
depends on RT_CHERRYUSB_DEVICE_CDC_ACM
config RT_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_HID
bool "winusbv2_hid"
bool
prompt "winusbv2_hid"
depends on RT_CHERRYUSB_DEVICE_HID
config RT_CHERRYUSB_DEVICE_TEMPLATE_ADB
bool "adb"
bool
prompt "adb"
depends on RT_CHERRYUSB_DEVICE_ADB
config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_CHARDEV
bool "cdc_acm_chardev"
bool
prompt "cdc_acm_chardev"
depends on RT_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV
endchoice
config CONFIG_USBDEV_MSC_BLOCK_DEV_NAME
@ -234,6 +297,8 @@ if RT_USING_CHERRYUSB
bool "musb_sunxi"
config RT_CHERRYUSB_HOST_MUSB_BK
bool "musb_bk"
config RT_CHERRYUSB_HOST_MUSB_SIFLI
bool "musb_sifli"
config RT_CHERRYUSB_HOST_MUSB_CUSTOM
bool "musb_custom"
config RT_CHERRYUSB_HOST_PUSB2
@ -346,6 +411,26 @@ if RT_USING_CHERRYUSB
config CONFIG_USBHOST_PLATFORM_RTL8152
bool
config CONFIG_USBHOST_PSC_PRIO
int
prompt "Set hubport change thread priority, 0 is the max priority"
default 0
config CONFIG_USBHOST_PSC_STACKSIZE
int
prompt "Set hubport change thread stacksize"
default 4096
config CONFIG_USBHOST_REQUEST_BUFFER_LEN
int
prompt "Set host control transfer max buffer size"
default 512
config CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT
int
prompt "Set host control transfer timeout, unit is ms"
default 500
config RT_LWIP_PBUF_POOL_BUFSIZE
int "The size of each pbuf in the pbuf pool"
range 1500 2000
@ -356,23 +441,22 @@ if RT_USING_CHERRYUSB
depends on RT_CHERRYUSB_HOST_MSC
default "/"
config RT_CHERRYUSB_HOST_TEMPLATE
bool
prompt "Use usb host template"
default n
if RT_CHERRYUSB_HOST_TEMPLATE
config TEST_USBH_CDC_ACM
menu "Select USB host template, please select class driver first"
config CONFIG_TEST_USBH_CDC_ACM
int
prompt "demo for test cdc acm"
prompt "demo for test cdc acm, cannot enable this demo, we have used serial framework instead"
default 0
depends on CHERRYUSB_HOST_CDC_ACM
config TEST_USBH_HID
depends on RT_CHERRYUSB_HOST_CDC_ACM
config CONFIG_TEST_USBH_HID
int
prompt "demo for test hid"
default 0
depends on CHERRYUSB_HOST_HID
depends on RT_CHERRYUSB_HOST_HID
config CONFIG_TEST_USBH_MSC
int
prompt "demo for test msc, cannot enable this demo, we have used dfs instead"
default 0
depends on RT_CHERRYUSB_HOST_MSC
endmenu
endif
endif
endif

View File

@ -53,6 +53,8 @@ if PKG_USING_CHERRYUSB
bool "musb_sunxi"
config PKG_CHERRYUSB_DEVICE_MUSB_BK
bool "musb_bk"
config PKG_CHERRYUSB_DEVICE_MUSB_SIFLI
bool "musb_sifli"
config PKG_CHERRYUSB_DEVICE_MUSB_CUSTOM
bool "musb_custom"
config PKG_CHERRYUSB_DEVICE_CHIPIDEA_MCX
@ -139,49 +141,110 @@ if PKG_USING_CHERRYUSB
prompt "Enable chardev for cdc acm device"
default n
config CONFIG_USBDEV_REQUEST_BUFFER_LEN
int
prompt "Set device control transfer max buffer size"
default 512
config CONFIG_USBDEV_MSC_MAX_BUFSIZE
int
prompt "Set usb msc device max buffer size"
default 512
help
Set the maximum buffer size for usb msc device, it is used to transfer data.
you can change it to a larger value if you need larger speed but must be a power of blocksize.
config CONFIG_USBDEV_RNDIS_USING_LWIP
bool
prompt "Enable usb rndis device with lwip for lan"
default n
config CONFIG_USBDEV_CDC_ECM_USING_LWIP
bool
prompt "Enable usb cdc ecm device with lwip for lan"
default n
choice
prompt "Select usb device template"
prompt "Select usb device template, please select class driver first"
default PKG_CHERRYUSB_DEVICE_TEMPLATE_NONE
config PKG_CHERRYUSB_DEVICE_TEMPLATE_NONE
bool "none (Implement it yourself)"
bool
prompt "none (Implement it yourself)"
config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM
bool "cdc_acm"
bool
prompt "cdc_acm"
depends on PKG_CHERRYUSB_DEVICE_CDC_ACM
config PKG_CHERRYUSB_DEVICE_TEMPLATE_MSC
bool "msc_ram"
bool
prompt "msc_ram"
depends on PKG_CHERRYUSB_DEVICE_MSC
config PKG_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV
bool "msc_blkdev"
bool
prompt "msc_blkdev"
depends on PKG_CHERRYUSB_DEVICE_MSC
config PKG_CHERRYUSB_DEVICE_TEMPLATE_HID_KEYBOARD
bool "hid_keyboard"
bool
prompt "hid_keyboard"
depends on PKG_CHERRYUSB_DEVICE_HID
config PKG_CHERRYUSB_DEVICE_TEMPLATE_HID_MOUSE
bool "hid_mouse"
bool
prompt "hid_mouse"
depends on PKG_CHERRYUSB_DEVICE_HID
config PKG_CHERRYUSB_DEVICE_TEMPLATE_HID_CUSTOM
bool "hid_custom"
bool
prompt "hid_custom"
depends on PKG_CHERRYUSB_DEVICE_HID
config PKG_CHERRYUSB_DEVICE_TEMPLATE_VIDEO
bool "video"
bool
prompt "video"
depends on PKG_CHERRYUSB_DEVICE_VIDEO
config PKG_CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V1_MIC_SPEAKER
bool "audio_v1_mic_speaker_multichan"
bool
prompt "audio_v1_mic_speaker_multichan"
depends on PKG_CHERRYUSB_DEVICE_AUDIO
config PKG_CHERRYUSB_DEVICE_TEMPLATE_AUDIO_V2_MIC_SPEAKER
bool "audio_v2_mic_speaker_multichan"
bool
prompt "audio_v2_mic_speaker_multichan"
depends on PKG_CHERRYUSB_DEVICE_AUDIO
config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_RNDIS
bool "cdc_rndis"
bool
prompt "cdc_rndis"
depends on PKG_CHERRYUSB_DEVICE_CDC_RNDIS
config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ECM
bool "cdc_ecm"
bool
prompt "cdc_ecm"
depends on PKG_CHERRYUSB_DEVICE_CDC_ECM
config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_NCM
bool "cdc_ncm"
bool
prompt "cdc_ncm"
depends on PKG_CHERRYUSB_DEVICE_CDC_NCM
config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC
bool "cdc_acm_msc"
bool
prompt "cdc_acm_msc"
depends on PKG_CHERRYUSB_DEVICE_CDC_ACM && PKG_CHERRYUSB_DEVICE_MSC
config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_MSC_HID
bool "cdc_acm_msc_hid"
bool
prompt "cdc_acm_msc_hid"
depends on PKG_CHERRYUSB_DEVICE_CDC_ACM && PKG_CHERRYUSB_DEVICE_MSC && PKG_CHERRYUSB_DEVICE_HID
config PKG_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV1
bool "winusbv1"
bool
prompt "winusbv1"
config PKG_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_CDC
bool "winusbv2_cdc"
bool
prompt "winusbv2_cdc"
depends on PKG_CHERRYUSB_DEVICE_CDC_ACM
config PKG_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_HID
bool "winusbv2_hid"
bool
prompt "winusbv2_hid"
depends on PKG_CHERRYUSB_DEVICE_HID
config PKG_CHERRYUSB_DEVICE_TEMPLATE_ADB
bool "adb"
bool
prompt "adb"
depends on PKG_CHERRYUSB_DEVICE_ADB
config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_CHARDEV
bool "cdc_acm_chardev"
bool
prompt "cdc_acm_chardev"
depends on PKG_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV
endchoice
config CONFIG_USBDEV_MSC_BLOCK_DEV_NAME
@ -233,6 +296,8 @@ if PKG_USING_CHERRYUSB
bool "musb_sunxi"
config PKG_CHERRYUSB_HOST_MUSB_BK
bool "musb_bk"
config PKG_CHERRYUSB_HOST_MUSB_SIFLI
bool "musb_sifli"
config PKG_CHERRYUSB_HOST_MUSB_CUSTOM
bool "musb_custom"
config PKG_CHERRYUSB_HOST_PUSB2
@ -345,6 +410,26 @@ if PKG_USING_CHERRYUSB
config CONFIG_USBHOST_PLATFORM_RTL8152
bool
config CONFIG_USBHOST_PSC_PRIO
int
prompt "Set hubport change thread priority, 0 is the max priority"
default 0
config CONFIG_USBHOST_PSC_STACKSIZE
int
prompt "Set hubport change thread stacksize"
default 4096
config CONFIG_USBHOST_REQUEST_BUFFER_LEN
int
prompt "Set host control transfer max buffer size"
default 512
config CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT
int
prompt "Set host control transfer timeout, unit is ms"
default 500
config RT_LWIP_PBUF_POOL_BUFSIZE
int "The size of each pbuf in the pbuf pool"
range 1500 2000
@ -355,23 +440,23 @@ if PKG_USING_CHERRYUSB
depends on RT_CHERRYUSB_HOST_MSC
default "/"
config PKG_CHERRYUSB_HOST_TEMPLATE
bool
prompt "Use usb host template"
default n
if PKG_CHERRYUSB_HOST_TEMPLATE
config TEST_USBH_CDC_ACM
menu "Select USB host template, please select class driver first"
config CONFIG_TEST_USBH_CDC_ACM
int
prompt "demo for test cdc acm"
prompt "demo for test cdc acm, cannot enable this demo, we have used serial framework instead"
default 0
depends on PKG_CHERRYUSB_HOST_CDC_ACM
config TEST_USBH_HID
config CONFIG_TEST_USBH_HID
int
prompt "demo for test hid"
default 0
depends on PKG_CHERRYUSB_HOST_HID
endif
config CONFIG_TEST_USBH_MSC
int
prompt "demo for test msc, cannot enable this demo, we have used dfs instead"
default 0
depends on PKG_CHERRYUSB_HOST_MSC
endmenu
endif
config PKG_CHERRYUSB_PATH
@ -386,18 +471,14 @@ if PKG_USING_CHERRYUSB
config PKG_USING_CHERRYUSB_LATEST_VERSION
bool "latest"
config PKG_USING_CHERRYUSB_V010501
bool "v1.5.1"
config PKG_USING_CHERRYUSB_V010500
bool "v1.5.0"
config PKG_USING_CHERRYUSB_V010403
bool "v1.4.3"
config PKG_USING_CHERRYUSB_V010402
bool "v1.4.2"
config PKG_USING_CHERRYUSB_V010400
bool "v1.4.0"
config PKG_USING_CHERRYUSB_V010301
bool "v1.3.1"
config PKG_USING_CHERRYUSB_V010300
bool "v1.3.0"
config PKG_USING_CHERRYUSB_V010200
bool "v1.2.0"
config PKG_USING_CHERRYUSB_V001002
@ -407,12 +488,10 @@ if PKG_USING_CHERRYUSB
config PKG_CHERRYUSB_VER
string
default "latest" if PKG_USING_CHERRYUSB_LATEST_VERSION
default "v1.5.1" if PKG_USING_CHERRYUSB_V010501
default "v1.5.0" if PKG_USING_CHERRYUSB_V010500
default "v1.4.3" if PKG_USING_CHERRYUSB_V010403
default "v1.4.2" if PKG_USING_CHERRYUSB_V010402
default "v1.4.0" if PKG_USING_CHERRYUSB_V010400
default "v1.3.1" if PKG_USING_CHERRYUSB_V010301
default "v1.3.0" if PKG_USING_CHERRYUSB_V010300
default "v1.2.0" if PKG_USING_CHERRYUSB_V010200
default "v0.10.2" if PKG_USING_CHERRYUSB_V001002
endif

View File

@ -70,6 +70,9 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']):
if GetDepend(['RT_CHERRYUSB_DEVICE_MUSB_BK']):
src += Glob('port/musb/usb_dc_musb.c')
src += Glob('port/musb/usb_glue_bk.c')
if GetDepend(['RT_CHERRYUSB_DEVICE_MUSB_SIFLI']):
src += Glob('port/musb/usb_dc_musb.c')
src += Glob('port/musb/usb_glue_sifli.c')
if GetDepend(['RT_CHERRYUSB_DEVICE_MUSB_CUSTOM']):
src += Glob('port/musb/usb_dc_musb.c')
if GetDepend(['RT_CHERRYUSB_DEVICE_CHIPIDEA_MCX']):
@ -230,6 +233,9 @@ if GetDepend(['RT_CHERRYUSB_HOST']):
if GetDepend(['RT_CHERRYUSB_HOST_MUSB_BK']):
src += Glob('port/musb/usb_hc_musb.c')
src += Glob('port/musb/usb_glue_bk.c')
if GetDepend(['RT_CHERRYUSB_HOST_MUSB_SIFLI']):
src += Glob('port/musb/usb_hc_musb.c')
src += Glob('port/musb/usb_glue_sifli.c')
if GetDepend(['RT_CHERRYUSB_HOST_MUSB_CUSTOM']):
src += Glob('port/musb/usb_hc_musb.c')
if GetDepend(['RT_CHERRYUSB_HOST_KINETIS_MCX']):
@ -289,8 +295,7 @@ if GetDepend(['RT_CHERRYUSB_HOST']):
if GetDepend(['RT_CHERRYUSB_HOST_PL2303']):
src += Glob('class/vendor/serial/usbh_pl2303.c')
if GetDepend(['RT_CHERRYUSB_HOST_TEMPLATE']):
CPPDEFINES+=['TEST_USBH_MSC=0']
if GetDepend(['CONFIG_TEST_USBH_HID']):
src += Glob('demo/usb_host.c')
if GetDepend(['RT_CHERRYUSB_HOST_CDC_ACM']) \

View File

@ -1,5 +1,5 @@
VERSION_MAJOR = 1
VERSION_MINOR = 5
PATCHLEVEL = 0
PATCHLEVEL = 1
VERSION_TWEAK = 0
EXTRAVERSION = 0

View File

@ -120,6 +120,9 @@ if(CONFIG_CHERRYUSB_DEVICE)
elseif(CONFIG_CHERRYUSB_DEVICE_MUSB_BK)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_dc_musb.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_glue_bk.c)
elseif(CONFIG_CHERRYUSB_DEVICE_MUSB_SIFLI)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_dc_musb.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_glue_sifli.c)
elseif(CONFIG_CHERRYUSB_DEVICE_MUSB_CUSTOM)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_dc_musb.c)
elseif(CONFIG_CHERRYUSB_DEVICE_CHIPIDEA_MCX)
@ -316,6 +319,9 @@ if(CONFIG_CHERRYUSB_HOST)
elseif(CONFIG_CHERRYUSB_HOST_MUSB_BK)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_hc_musb.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_glue_bk.c)
elseif(CONFIG_CHERRYUSB_HOST_MUSB_SIFLI)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_hc_musb.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_glue_sifli.c)
elseif(CONFIG_CHERRYUSB_HOST_MUSB_CUSTOM)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_hc_musb.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_glue_bk.c)
@ -329,7 +335,7 @@ if(CONFIG_CHERRYUSB_HOST)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/rp2040/usb_hc_rp2040.c)
endif()
if(CHERRYUSB_HOST_TEMPLATE)
if(CONFIG_TEST_USBH_CDC_ACM OR CONFIG_TEST_USBH_HID OR CONFIG_TEST_USBH_MSC)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/demo/usb_host.c)
endif()
endif()

View File

@ -47,9 +47,6 @@
#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 512
#endif
/* Setup packet log for debug */
// #define CONFIG_USBDEV_SETUP_LOG_PRINT
/* Send ep0 in data from user buffer instead of copying into ep0 reqdata
* Please note that user buffer must be aligned with CONFIG_USB_ALIGN_SIZE
*/
@ -262,28 +259,20 @@
// #define CONFIG_USBDEV_SOF_ENABLE
/* When your chip hardware supports high-speed and wants to initialize it in high-speed mode, the relevant IP will configure the internal or external high-speed PHY according to CONFIG_USB_HS. */
/* When your chip hardware supports high-speed and wants to initialize it in high-speed mode,
* the relevant IP will configure the internal or external high-speed PHY according to CONFIG_USB_HS.
*
* in xxx32 chips, only pb14/pb15 can support hs mode, pa11/pa12 is not supported(only a few supports, but we ignore them).
*/
// #define CONFIG_USB_HS
/* ---------------- FSDEV Configuration ---------------- */
//#define CONFIG_USBDEV_FSDEV_PMA_ACCESS 2 // maybe 1 or 2, many chips may have a difference
/* ---------------- DWC2 Configuration ---------------- */
/* (5 * number of control endpoints + 8) + ((largest USB packet used / 4) + 1 for
* status information) + (2 * number of OUT endpoints) + 1 for Global NAK
*/
// #define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (1024 / 4)
/* IN Endpoints Max packet Size / 4 */
// #define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64 / 4)
// #define CONFIG_USB_DWC2_TX1_FIFO_SIZE (1024 / 4)
// #define CONFIG_USB_DWC2_TX2_FIFO_SIZE (64 / 4)
// #define CONFIG_USB_DWC2_TX3_FIFO_SIZE (64 / 4)
// #define CONFIG_USB_DWC2_TX4_FIFO_SIZE (0 / 4)
// #define CONFIG_USB_DWC2_TX5_FIFO_SIZE (0 / 4)
// #define CONFIG_USB_DWC2_TX6_FIFO_SIZE (0 / 4)
// #define CONFIG_USB_DWC2_TX7_FIFO_SIZE (0 / 4)
// #define CONFIG_USB_DWC2_TX8_FIFO_SIZE (0 / 4)
/* enable dwc2 buffer dma mode for device
* in xxx32 chips, only pb14/pb15 can support dma mode, pa11/pa12 is not supported(only a few supports, but we ignore them)
*/
// #define CONFIG_USB_DWC2_DMA_ENABLE
/* ---------------- MUSB Configuration ---------------- */
@ -320,17 +309,6 @@
/* ---------------- XHCI Configuration ---------------- */
#define CONFIG_USB_XHCI_HCCR_OFFSET (0x0)
/* ---------------- DWC2 Configuration ---------------- */
/* largest non-periodic USB packet used / 4 */
// #define CONFIG_USB_DWC2_NPTX_FIFO_SIZE (512 / 4)
/* largest periodic USB packet used / 4 */
// #define CONFIG_USB_DWC2_PTX_FIFO_SIZE (1024 / 4)
/*
* (largest USB packet used / 4) + 1 for status information + 1 transfer complete +
* 1 location each for Bulk/Control endpoint for handling NAK/NYET scenario
*/
// #define CONFIG_USB_DWC2_RX_FIFO_SIZE ((1012 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE))
/* ---------------- MUSB Configuration ---------------- */
// #define CONFIG_USB_MUSB_SUNXI

View File

@ -416,7 +416,7 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
hub->int_buffer = g_hub_intbuf[hub->bus->busid][hub->index - 1];
hub->int_timer = usb_osal_timer_create("hubint_tim", USBH_GET_URB_INTERVAL(hub->intin->bInterval, hport->speed), hub_int_timeout, hub, 0);
hub->int_timer = usb_osal_timer_create("hubint_tim", USBH_GET_URB_INTERVAL(hub->intin->bInterval, hport->speed) / 1000, hub_int_timeout, hub, 0);
if (hub->int_timer == NULL) {
USB_LOG_ERR("No memory to alloc int_timer\r\n");
return -USB_ERR_NOMEM;

View File

@ -675,9 +675,8 @@ struct mtp_object {
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
int_ep, /* bEndpointAddress */ \
0x03, /* bmAttributes */ \
0x1c, /* wMaxPacketSize */ \
0x00, /* bInterval */ \
0x06 /* bLength */
WBVAL(0x1c), /* wMaxPacketSize */ \
0x06 /* bInterval */
// clang-format on
#endif

View File

@ -36,6 +36,9 @@ struct usbd_interface *usbd_mtp_init_intf(struct usbd_interface *intf,
const uint8_t in_ep,
const uint8_t int_ep);
int usbd_mtp_notify_object_add(const char *path);
int usbd_mtp_notify_object_remove(const char *path);
const char *usbd_mtp_fs_root_path(void);
const char *usbd_mtp_fs_description(void);

View File

@ -15,7 +15,7 @@
#undef CHERRYUSB_VERSION_STR
#endif
#define CHERRYUSB_VERSION 0x010500
#define CHERRYUSB_VERSION_STR "v1.5.0"
#define CHERRYUSB_VERSION 0x010501
#define CHERRYUSB_VERSION_STR "v1.5.1"
#endif

View File

@ -83,8 +83,8 @@ USB_NOCACHE_RAM_SECTION struct usbd_core_priv {
uint8_t intf_altsetting[16];
uint8_t intf_offset;
struct usbd_tx_rx_msg tx_msg[CONFIG_USBDEV_EP_NUM];
struct usbd_tx_rx_msg rx_msg[CONFIG_USBDEV_EP_NUM];
struct usbd_tx_rx_msg tx_msg[16];
struct usbd_tx_rx_msg rx_msg[16];
void (*event_handler)(uint8_t busid, uint8_t event);
} g_usbd_core[CONFIG_USBDEV_MAX_BUS];
@ -95,7 +95,7 @@ static void usbd_class_event_notify_handler(uint8_t busid, uint8_t event, void *
static void usbd_print_setup(struct usb_setup_packet *setup)
{
USB_LOG_INFO("Setup: "
USB_LOG_ERR("Setup: "
"bmRequestType 0x%02x, bRequest 0x%02x, wValue 0x%04x, wIndex 0x%04x, wLength 0x%04x\r\n",
setup->bmRequestType,
setup->bRequest,
@ -104,6 +104,16 @@ static void usbd_print_setup(struct usb_setup_packet *setup)
setup->wLength);
}
#if (CONFIG_USB_DBG_LEVEL >= USB_DBG_LOG)
static const char *usb_ep0_state_string[] = {
"setup",
"indata",
"outdata",
"instatus",
"outstatus"
};
#endif
static bool is_device_configured(uint8_t busid)
{
return (g_usbd_core[busid].configuration != 0);
@ -524,8 +534,6 @@ static bool usbd_set_interface(uint8_t busid, uint8_t iface, uint8_t alt_setting
if_desc = (void *)p;
}
USB_LOG_DBG("Current iface %u alt setting %u",
cur_iface, cur_alt_setting);
break;
case USB_DESCRIPTOR_TYPE_ENDPOINT:
@ -1171,9 +1179,14 @@ static void __usbd_event_ep0_setup_complete_handler(uint8_t busid, struct usb_se
{
uint8_t *buf;
#ifdef CONFIG_USBDEV_SETUP_LOG_PRINT
usbd_print_setup(setup);
#endif
USB_LOG_DBG("[%s] 0x%02x 0x%02x 0x%04x 0x%04x 0x%04x\r\n",
usb_ep0_state_string[usbd_get_ep0_next_state(busid)],
setup->bmRequestType,
setup->bRequest,
setup->wValue,
setup->wIndex,
setup->wLength);
if (setup->wLength > CONFIG_USBDEV_REQUEST_BUFFER_LEN) {
if ((setup->bmRequestType & USB_REQUEST_DIR_MASK) == USB_REQUEST_DIR_OUT) {
USB_LOG_ERR("Request buffer too small\r\n");
@ -1240,7 +1253,6 @@ static void __usbd_event_ep0_setup_complete_handler(uint8_t busid, struct usb_se
*/
if ((setup->wLength > g_usbd_core[busid].ep0_data_buf_len) && (!(g_usbd_core[busid].ep0_data_buf_len % USB_CTRL_EP_MPS))) {
g_usbd_core[busid].zlp_flag = true;
USB_LOG_DBG("EP0 Set zlp\r\n");
}
}
@ -1266,7 +1278,10 @@ static void usbd_event_ep0_in_complete_handler(uint8_t busid, uint8_t ep, uint32
g_usbd_core[busid].ep0_data_buf += nbytes;
g_usbd_core[busid].ep0_data_buf_residue -= nbytes;
USB_LOG_DBG("EP0 send %d bytes, %d remained\r\n", (unsigned int)nbytes, (unsigned int)g_usbd_core[busid].ep0_data_buf_residue);
USB_LOG_DBG("[%s] in %d bytes, %d remained\r\n",
usb_ep0_state_string[usbd_get_ep0_next_state(busid)],
(unsigned int)nbytes,
(unsigned int)g_usbd_core[busid].ep0_data_buf_residue);
if (g_usbd_core[busid].ep0_data_buf_residue != 0) {
/* Start sending the remain data */
@ -1311,12 +1326,15 @@ static void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint3
(void)ep;
(void)setup;
USB_LOG_DBG("[%s] out %d bytes, %d remained\r\n",
usb_ep0_state_string[usbd_get_ep0_next_state(busid)],
(unsigned int)nbytes,
(unsigned int)g_usbd_core[busid].ep0_data_buf_residue);
if (nbytes > 0) {
g_usbd_core[busid].ep0_data_buf += nbytes;
g_usbd_core[busid].ep0_data_buf_residue -= nbytes;
USB_LOG_DBG("EP0 recv %d bytes, %d remained\r\n", (unsigned int)nbytes, (unsigned int)g_usbd_core[busid].ep0_data_buf_residue);
if (g_usbd_core[busid].ep0_data_buf_residue == 0) {
#ifdef CONFIG_USBDEV_EP0_THREAD
usb_osal_mq_send(g_usbd_core[busid].usbd_ep0_mq, USB_EP0_STATE_OUT);
@ -1338,9 +1356,8 @@ static void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint3
usbd_ep_start_read(busid, USB_CONTROL_OUT_EP0, g_usbd_core[busid].ep0_data_buf, g_usbd_core[busid].ep0_data_buf_residue);
}
} else {
g_usbd_core[busid].ep0_next_state = USBD_EP0_STATE_SETUP;
/* Read out status completely, do nothing */
USB_LOG_DBG("EP0 recv out status\r\n");
g_usbd_core[busid].ep0_next_state = USBD_EP0_STATE_SETUP;
}
}

View File

@ -47,7 +47,7 @@ extern "C" {
#define CLASS_INFO_DEFINE __attribute__((section(".usbh_class_info"))) __USED __ALIGNED(1)
#endif
#define USBH_GET_URB_INTERVAL(interval, speed) (speed < USB_SPEED_HIGH ? interval : (1 << (interval - 1)))
#define USBH_GET_URB_INTERVAL(interval, speed) (speed < USB_SPEED_HIGH ? (interval * 1000) : ((1 << (interval - 1)) * 125))
#define USBH_EP_INIT(ep, ep_desc) \
do { \

View File

@ -8,10 +8,6 @@
#include "usbd_cdc_acm.h"
#include "usbd_hid.h"
#if CONFIG_USBDEV_EP_NUM < 7
#error endpoint number is too small for this demo, please try other chips
#endif
/*!< endpoint address */
#define CDC_IN_EP 0x81
#define CDC_OUT_EP 0x02

View File

@ -7,10 +7,6 @@
#include "usbd_cdc_acm.h"
#include "usbd_msc.h"
#if CONFIG_USBDEV_EP_NUM < 6
#error endpoint number is too small for this demo, please try other chips
#endif
/*!< endpoint address */
#define CDC_IN_EP 0x81
#define CDC_OUT_EP 0x02

View File

@ -6,10 +6,6 @@
#include "usbd_core.h"
#include "usbd_cdc_acm.h"
#if CONFIG_USBDEV_EP_NUM < 8
#error endpoint number is too small for this demo, please try other chips
#endif
/*!< endpoint address */
#define CDC_IN_EP 0x81
#define CDC_OUT_EP 0x01

View File

@ -10,17 +10,17 @@
#include "usbh_video.h"
#include "usbh_audio.h"
#ifndef TEST_USBH_CDC_ACM
#define TEST_USBH_CDC_ACM 1
#ifndef CONFIG_TEST_USBH_CDC_ACM
#define CONFIG_TEST_USBH_CDC_ACM 1
#endif
#ifndef TEST_USBH_CDC_SPEED
#define TEST_USBH_CDC_SPEED 0
#endif
#ifndef TEST_USBH_HID
#define TEST_USBH_HID 1
#ifndef CONFIG_TEST_USBH_HID
#define CONFIG_TEST_USBH_HID 1
#endif
#ifndef TEST_USBH_MSC
#define TEST_USBH_MSC 1
#ifndef CONFIG_TEST_USBH_MSC
#define CONFIG_TEST_USBH_MSC 1
#endif
#ifndef TEST_USBH_MSC_FATFS
#define TEST_USBH_MSC_FATFS 0
@ -28,18 +28,18 @@
#ifndef TEST_USBH_MSC_FATFS_SPEED
#define TEST_USBH_MSC_FATFS_SPEED 0
#endif
#ifndef TEST_USBH_AUDIO
#define TEST_USBH_AUDIO 0
#ifndef CONFIG_TEST_USBH_AUDIO
#define CONFIG_TEST_USBH_AUDIO 0
#endif
#ifndef TEST_USBH_VIDEO
#define TEST_USBH_VIDEO 0
#ifndef CONFIG_TEST_USBH_VIDEO
#define CONFIG_TEST_USBH_VIDEO 0
#endif
#if defined(TEST_USBH_CDC_ECM) || defined(TEST_USBH_CDC_RNDIS) || defined(TEST_USBH_ASIX) || defined(TEST_USBH_RTL8152)
#error we have move those class implements into platform/none/usbh_lwip.c, and you should call tcpip_init(NULL, NULL) in your app
#endif
#if TEST_USBH_CDC_ACM
#if CONFIG_TEST_USBH_CDC_ACM
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t cdc_buffer[4096];
#if TEST_USBH_CDC_SPEED
@ -115,7 +115,7 @@ delete:
}
#endif
#if TEST_USBH_HID
#if CONFIG_TEST_USBH_HID
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t hid_buffer[128];
void usbh_hid_callback(void *arg, int nbytes)
@ -157,7 +157,7 @@ delete:
}
#endif
#if TEST_USBH_MSC
#if CONFIG_TEST_USBH_MSC
#if TEST_USBH_MSC_FATFS
#include "ff.h"
@ -326,7 +326,7 @@ delete:
}
#endif
#if TEST_USBH_CDC_ACM
#if CONFIG_TEST_USBH_CDC_ACM
void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class)
{
usb_osal_thread_create("usbh_cdc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_acm_thread, cdc_acm_class);
@ -337,7 +337,7 @@ void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class)
}
#endif
#if TEST_USBH_HID
#if CONFIG_TEST_USBH_HID
void usbh_hid_run(struct usbh_hid *hid_class)
{
usb_osal_thread_create("usbh_hid", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_hid_thread, hid_class);
@ -348,7 +348,7 @@ void usbh_hid_stop(struct usbh_hid *hid_class)
}
#endif
#if TEST_USBH_MSC
#if CONFIG_TEST_USBH_MSC
void usbh_msc_run(struct usbh_msc *msc_class)
{
usb_osal_thread_create("usbh_msc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_msc_thread, msc_class);
@ -359,11 +359,11 @@ void usbh_msc_stop(struct usbh_msc *msc_class)
}
#endif
#if TEST_USBH_AUDIO
#if CONFIG_TEST_USBH_AUDIO
#error "commercial charge"
#endif
#if TEST_USBH_VIDEO
#if CONFIG_TEST_USBH_VIDEO
#error "commercial charge"
#endif

View File

@ -6,10 +6,6 @@
#include "usbd_core.h"
#include "usbd_cdc_acm.h"
#if CONFIG_USBDEV_EP_NUM < 6
#error endpoint number is too small for this demo, please try other chips
#endif
#define WINUSB_IN_EP 0x81
#define WINUSB_OUT_EP 0x02

View File

@ -6,10 +6,6 @@
#include "usbd_core.h"
#include "usbd_hid.h"
#if CONFIG_USBDEV_EP_NUM < 4
#error endpoint number is too small for this demo, please try other chips
#endif
#define WINUSB_IN_EP 0x81
#define WINUSB_OUT_EP 0x02

View File

@ -1,4 +1,4 @@
version: "1.5.0"
version: "1.5.1"
description: CherryUSB is a tiny and portable USB Stack (device & host) for embedded system with USB IP
tags:
- usb
@ -18,7 +18,7 @@ repository: https://github.com/cherry-embedded/CherryUSB.git
documentation: https://cherryusb.readthedocs.io/
issues: https://github.com/cherry-embedded/CherryUSB/issues
dependencies:
idf: ">=5.0"
idf: ">=4.4.1"
targets:
- esp32s2
- esp32s3

View File

@ -6,24 +6,25 @@ If you are using more than one port, all ip parameters must be the same(like fif
## STM32
**有且仅有 PB14/PB15 引脚支持 host 模式, 部分 F7/H7 可能 PA11/PA12 也支持**。
- STM32F105xc、STM32F107xc
- STM32F205xx、STM32F207xx、STM32F215xx、STM32F217xx
- STM32F401xc、STM32F401xe、STM32F405xx、STM32F407xx、STM32F411xe、STM32F412cx、STM32F412rx、STM32F412vx、STM32F412zx、STM32F413xx、STM32F415xx、STM32F417xx、STM32F423xx、STM32F423xx、STM32F429xx、STM32F437xx、STM32F439xx、STM32F446xx、STM32F469xx、STM32F479xx
- STM32F7xx
- STM32H7xx
- STM32L4xx
- STM32MPxx
- STM32U5xx
## AT32
**有且仅有 AT32F405xx PB14/PB15引脚支持 host 模式**。
- AT32F402xx、AT32F405xx、AT32F415xx、AT32F423xx、AT32F425xx、AT32F435xx、AT32F437xx
## GD32
CONFIG_USBDEV_EP_NUM 必须为4 或者 6并删除 usb_dc_dwc2.c 中 while(1){}
当 CONFIG_USBDEV_EP_NUM 为4 时fifo_num 不得大于 320 字
当 CONFIG_USBDEV_EP_NUM 为6 时fifo_num 不得大于 1280 字
**由于无法读取 DWC2 配置信息,并且有部分寄存器是非标准的,因此暂时无法支持 GD 系列**。
- GD32F30X_CL
- GD32F405、GD32F407

View File

@ -5,6 +5,7 @@
*/
#include "usbd_core.h"
#include "usb_dwc2_reg.h"
#include "usb_dwc2_param.h"
// clang-format off
#if defined ( __CC_ARM )
@ -51,46 +52,6 @@
#endif
// clang-format on
#ifndef CONFIG_USB_DWC2_RXALL_FIFO_SIZE
#define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (1024 / 4)
#endif
#ifndef CONFIG_USB_DWC2_TX0_FIFO_SIZE
#define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64 / 4)
#endif
#ifndef CONFIG_USB_DWC2_TX1_FIFO_SIZE
#define CONFIG_USB_DWC2_TX1_FIFO_SIZE (1024 / 4)
#endif
#ifndef CONFIG_USB_DWC2_TX2_FIFO_SIZE
#define CONFIG_USB_DWC2_TX2_FIFO_SIZE (64 / 4)
#endif
#ifndef CONFIG_USB_DWC2_TX3_FIFO_SIZE
#define CONFIG_USB_DWC2_TX3_FIFO_SIZE (64 / 4)
#endif
#ifndef CONFIG_USB_DWC2_TX4_FIFO_SIZE
#define CONFIG_USB_DWC2_TX4_FIFO_SIZE (64 / 4)
#endif
#ifndef CONFIG_USB_DWC2_TX5_FIFO_SIZE
#define CONFIG_USB_DWC2_TX5_FIFO_SIZE (64 / 4)
#endif
#ifndef CONFIG_USB_DWC2_TX6_FIFO_SIZE
#define CONFIG_USB_DWC2_TX6_FIFO_SIZE (0 / 4)
#endif
#ifndef CONFIG_USB_DWC2_TX7_FIFO_SIZE
#define CONFIG_USB_DWC2_TX7_FIFO_SIZE (0 / 4)
#endif
#ifndef CONFIG_USB_DWC2_TX8_FIFO_SIZE
#define CONFIG_USB_DWC2_TX8_FIFO_SIZE (0 / 4)
#endif
#define USBD_BASE (g_usbdev_bus[busid].reg_base)
#define USB_OTG_GLB ((DWC2_GlobalTypeDef *)(USBD_BASE))
@ -115,9 +76,11 @@ struct dwc2_ep_state {
/* Driver state */
USB_NOCACHE_RAM_SECTION struct dwc2_udc {
USB_MEM_ALIGNX struct usb_setup_packet setup;
USB_MEM_ALIGNX uint32_t GSNPSID;
struct dwc2_ep_state in_ep[CONFIG_USBDEV_EP_NUM]; /*!< IN endpoint parameters*/
struct dwc2_ep_state out_ep[CONFIG_USBDEV_EP_NUM]; /*!< OUT endpoint parameters */
USB_MEM_ALIGNX uint8_t pad; /* Pad to CONFIG_USB_ALIGN_SIZE bytes */
struct dwc2_hw_params hw_params;
struct dwc2_user_params user_params;
struct dwc2_ep_state in_ep[16]; /*!< IN endpoint parameters*/
struct dwc2_ep_state out_ep[16]; /*!< OUT endpoint parameters */
} g_dwc2_udc[CONFIG_USBDEV_MAX_BUS];
static inline int dwc2_reset(uint8_t busid)
@ -135,7 +98,7 @@ static inline int dwc2_reset(uint8_t busid)
count = 0U;
USB_OTG_GLB->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
if (g_dwc2_udc[busid].GSNPSID < 0x4F54420AU) {
if (g_dwc2_udc[busid].hw_params.snpsid < 0x4F54420AU) {
do {
if (++count > 200000U) {
USB_LOG_ERR("DWC2 reset timeout\r\n");
@ -160,22 +123,42 @@ static inline int dwc2_reset(uint8_t busid)
static inline int dwc2_core_init(uint8_t busid)
{
int ret;
#if defined(CONFIG_USB_HS)
/* Init The ULPI Interface */
USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
uint32_t regval;
/* Select vbus source */
USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
/* Reset after a PHY select */
ret = dwc2_reset(busid);
#else
if (g_dwc2_udc[busid].user_params.phy_type == DWC2_PHY_TYPE_PARAM_FS) {
/* Select FS Embedded PHY */
USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
} else {
regval = USB_OTG_GLB->GUSBCFG;
regval &= ~USB_OTG_GUSBCFG_PHYSEL;
/* disable external vbus source */
regval &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
/* disable ULPI FS/LS */
regval &= ~(USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_ULPICSM);
switch (g_dwc2_udc[busid].user_params.phy_type) {
case DWC2_PHY_TYPE_PARAM_ULPI:
regval |= USB_OTG_GUSBCFG_ULPI_UTMI_SEL;
regval &= ~USB_OTG_GUSBCFG_PHYIF16;
regval &= ~USB_OTG_GUSBCFG_DDR_SEL;
if (g_dwc2_udc[busid].user_params.phy_utmi_width == 16) {
regval |= USB_OTG_GUSBCFG_PHYIF16;
}
break;
case DWC2_PHY_TYPE_PARAM_UTMI:
regval &= ~USB_OTG_GUSBCFG_ULPI_UTMI_SEL;
regval &= ~USB_OTG_GUSBCFG_PHYIF16;
break;
default:
break;
}
USB_OTG_GLB->GUSBCFG = regval;
}
/* Reset after a PHY select */
ret = dwc2_reset(busid);
#endif
return ret;
}
@ -285,8 +268,6 @@ static void dwc2_set_turnaroundtime(uint8_t busid, uint32_t hclk, uint8_t speed)
UsbTrd = USBD_DEFAULT_TRDT_VALUE;
}
USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_TOCAL;
USB_OTG_GLB->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
USB_OTG_GLB->GUSBCFG |= (uint32_t)((UsbTrd << USB_OTG_GUSBCFG_TRDT_Pos) & USB_OTG_GUSBCFG_TRDT);
}
@ -347,11 +328,11 @@ static void dwc2_ep0_start_read_setup(uint8_t busid, uint8_t *psetup)
USB_OTG_OUTEP(0U)->DOEPTSIZ |= (3U * 8U);
USB_OTG_OUTEP(0U)->DOEPTSIZ |= USB_OTG_DOEPTSIZ_STUPCNT;
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
if (g_dwc2_udc[busid].user_params.device_dma_enable) {
USB_OTG_OUTEP(0U)->DOEPDMA = (uint32_t)psetup;
/* EP enable */
USB_OTG_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_USBAEP;
#endif
}
}
void dwc2_ep_write(uint8_t busid, uint8_t ep_idx, uint8_t *src, uint16_t len)
@ -504,41 +485,13 @@ static inline uint32_t dwc2_get_inep_intstatus(uint8_t busid, uint8_t epnum)
int usb_dc_init(uint8_t busid)
{
int ret;
uint8_t fsphy_type;
uint8_t hsphy_type;
uint8_t dma_support;
uint8_t endpoints;
uint32_t fifo_num;
memset(&g_dwc2_udc[busid], 0, sizeof(struct dwc2_udc));
usb_dc_low_level_init(busid);
/*
Full-Speed PHY Interface Type (FSPhyType)
2'b00: Full-speed interface not supported
2'b01: Dedicated full-speed interface
2'b10: FS pins shared with UTMI+ pins
2'b11: FS pins shared with ULPI pins
High-Speed PHY Interface Type (HSPhyType)
2'b00: High-Speed interface not supported
2'b01: UTMI+
2'b10: ULPI
2'b11: UTMI+ and ULPI
Architecture (OtgArch)
2'b00: Slave-Only
2'b01: External DMA
2'b10: Internal DMA
Others: Reserved
*/
fsphy_type = ((USB_OTG_GLB->GHWCFG2 & (0x03 << 8)) >> 8);
hsphy_type = ((USB_OTG_GLB->GHWCFG2 & (0x03 << 6)) >> 6);
dma_support = ((USB_OTG_GLB->GHWCFG2 & (0x03 << 3)) >> 3);
endpoints = ((USB_OTG_GLB->GHWCFG2 & (0x0f << 10)) >> 10) + 1;
USB_LOG_INFO("========== dwc2 udc params ==========\r\n");
USB_LOG_INFO("========== dwc2 dcd params ==========\r\n");
USB_LOG_INFO("CID:%08x\r\n", (unsigned int)USB_OTG_GLB->CID);
USB_LOG_INFO("GSNPSID:%08x\r\n", (unsigned int)USB_OTG_GLB->GSNPSID);
USB_LOG_INFO("GHWCFG1:%08x\r\n", (unsigned int)USB_OTG_GLB->GHWCFG1);
@ -546,26 +499,40 @@ int usb_dc_init(uint8_t busid)
USB_LOG_INFO("GHWCFG3:%08x\r\n", (unsigned int)USB_OTG_GLB->GHWCFG3);
USB_LOG_INFO("GHWCFG4:%08x\r\n", (unsigned int)USB_OTG_GLB->GHWCFG4);
USB_LOG_INFO("dwc2 fsphy type:%d, hsphy type:%d, dma support:%d\r\n", fsphy_type, hsphy_type, dma_support);
USB_LOG_INFO("dwc2 has %d endpoints and dfifo depth(32-bit words) is %d, default config: %d endpoints\r\n", endpoints, (USB_OTG_GLB->GHWCFG3 >> 16), CONFIG_USBDEV_EP_NUM);
USB_LOG_INFO("=================================\r\n");
dwc2_get_hwparams(USBD_BASE, &g_dwc2_udc[busid].hw_params);
dwc2_get_user_params(USBD_BASE, &g_dwc2_udc[busid].user_params);
USB_ASSERT_MSG(endpoints >= CONFIG_USBDEV_EP_NUM, "dwc2 has less endpoints than config, please check");
if (g_dwc2_udc[busid].user_params.phy_utmi_width == 0) {
g_dwc2_udc[busid].user_params.phy_utmi_width = 8;
}
if (g_dwc2_udc[busid].user_params.total_fifo_size == 0) {
g_dwc2_udc[busid].user_params.total_fifo_size = g_dwc2_udc[busid].hw_params.total_fifo_size;
}
g_dwc2_udc[busid].GSNPSID = USB_OTG_GLB->GSNPSID;
USB_OTG_DEV->DCTL |= USB_OTG_DCTL_SDIS;
USB_LOG_INFO("dwc2 has %d endpoints and dfifo depth(32-bit words) is %d\r\n",
g_dwc2_udc[busid].hw_params.num_dev_ep + 1,
g_dwc2_udc[busid].user_params.total_fifo_size);
USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
USB_OTG_DEV->DCTL |= USB_OTG_DCTL_SDIS;
/* This is vendor register */
USB_OTG_GLB->GCCFG = usbd_get_dwc2_gccfg_conf(USBD_BASE);
USB_OTG_GLB->GCCFG = g_dwc2_udc[busid].user_params.device_gccfg;
ret = dwc2_core_init(busid);
/* Force Device Mode*/
dwc2_set_mode(busid, USB_OTG_MODE_DEVICE);
if (g_dwc2_udc[busid].user_params.b_session_valid_override) {
/* B-peripheral session valid override enable */
USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
}
USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_TOCAL;
for (uint8_t i = 0U; i < 15U; i++) {
USB_OTG_GLB->DIEPTXF[i] = 0U;
}
@ -575,15 +542,17 @@ int usb_dc_init(uint8_t busid)
/* Device speed configuration */
USB_OTG_DEV->DCFG &= ~USB_OTG_DCFG_DSPD;
#if defined(CONFIG_USB_HS)
if (g_dwc2_udc[busid].user_params.phy_type != DWC2_PHY_TYPE_PARAM_FS) {
USB_ASSERT_MSG(g_dwc2_udc[busid].hw_params.hs_phy_type != 0, "This dwc2 version does not support hs, so stop working");
USB_OTG_DEV->DCFG |= USB_OTG_SPEED_HIGH;
#else
if (hsphy_type == 0) {
} else {
if (g_dwc2_udc[busid].hw_params.hs_phy_type == 0) {
USB_OTG_DEV->DCFG |= USB_OTG_SPEED_FULL;
} else {
USB_OTG_DEV->DCFG |= USB_OTG_SPEED_HIGH_IN_FULL;
}
#endif
}
/* Clear all pending Device Interrupts */
USB_OTG_DEV->DIEPMSK = 0U;
@ -600,58 +569,35 @@ int usb_dc_init(uint8_t busid)
USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT |
USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_WUIM;
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
USB_ASSERT_MSG(((USB_OTG_GLB->GHWCFG2 & (0x3U << 3)) >> 3) == 2, "This dwc2 version does not support dma mode, so stop working");
if (g_dwc2_udc[busid].user_params.device_dma_enable) {
USB_ASSERT_MSG(g_dwc2_udc[busid].hw_params.arch == GHWCFG2_INT_DMA_ARCH, "This dwc2 version does not support dma mode, so stop working");
USB_OTG_DEV->DCFG &= ~USB_OTG_DCFG_DESCDMA;
USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_HBSTLEN;
USB_OTG_GLB->GAHBCFG |= (USB_OTG_GAHBCFG_DMAEN | USB_OTG_GAHBCFG_HBSTLEN_4);
#else
} else {
USB_OTG_GLB->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
#endif
#if CONFIG_DWC2_VBUS_SENSING
USB_OTG_GLB->GINTMSK |= (USB_OTG_GINTMSK_OTGINT | USB_OTG_GINTMSK_SRQIM);
#endif
}
#ifdef CONFIG_USBDEV_SOF_ENABLE
USB_OTG_GLB->GINTMSK |= USB_OTG_GINTMSK_SOFM;
#endif
USB_OTG_GLB->GRXFSIZ = (CONFIG_USB_DWC2_RXALL_FIFO_SIZE);
USB_OTG_GLB->GRXFSIZ = g_dwc2_udc[busid].user_params.device_rx_fifo_size;
dwc2_set_txfifo(busid, 0, CONFIG_USB_DWC2_TX0_FIFO_SIZE);
dwc2_set_txfifo(busid, 1, CONFIG_USB_DWC2_TX1_FIFO_SIZE);
dwc2_set_txfifo(busid, 2, CONFIG_USB_DWC2_TX2_FIFO_SIZE);
dwc2_set_txfifo(busid, 3, CONFIG_USB_DWC2_TX3_FIFO_SIZE);
fifo_num = g_dwc2_udc[busid].user_params.device_rx_fifo_size;
for (uint8_t i = 0; i < (g_dwc2_udc[busid].hw_params.num_dev_ep + 1); i++) {
dwc2_set_txfifo(busid, i, g_dwc2_udc[busid].user_params.device_tx_fifo_size[i]);
fifo_num += g_dwc2_udc[busid].user_params.device_tx_fifo_size[i];
fifo_num = CONFIG_USB_DWC2_RXALL_FIFO_SIZE;
fifo_num += CONFIG_USB_DWC2_TX0_FIFO_SIZE;
fifo_num += CONFIG_USB_DWC2_TX1_FIFO_SIZE;
fifo_num += CONFIG_USB_DWC2_TX2_FIFO_SIZE;
fifo_num += CONFIG_USB_DWC2_TX3_FIFO_SIZE;
#if CONFIG_USBDEV_EP_NUM > 4
dwc2_set_txfifo(busid, 4, CONFIG_USB_DWC2_TX4_FIFO_SIZE);
fifo_num += CONFIG_USB_DWC2_TX4_FIFO_SIZE;
#endif
#if CONFIG_USBDEV_EP_NUM > 5
dwc2_set_txfifo(busid, 5, CONFIG_USB_DWC2_TX5_FIFO_SIZE);
fifo_num += CONFIG_USB_DWC2_TX5_FIFO_SIZE;
#endif
#if CONFIG_USBDEV_EP_NUM > 6
dwc2_set_txfifo(busid, 6, CONFIG_USB_DWC2_TX6_FIFO_SIZE);
fifo_num += CONFIG_USB_DWC2_TX6_FIFO_SIZE;
#endif
#if CONFIG_USBDEV_EP_NUM > 7
dwc2_set_txfifo(busid, 7, CONFIG_USB_DWC2_TX7_FIFO_SIZE);
fifo_num += CONFIG_USB_DWC2_TX7_FIFO_SIZE;
#endif
#if CONFIG_USBDEV_EP_NUM > 8
dwc2_set_txfifo(busid, 8, CONFIG_USB_DWC2_TX8_FIFO_SIZE);
fifo_num += CONFIG_USB_DWC2_TX8_FIFO_SIZE;
#endif
USB_ASSERT_MSG(fifo_num <= g_dwc2_udc[busid].user_params.total_fifo_size, "Your fifo config is overflow, please check");
}
USB_ASSERT_MSG(fifo_num <= (USB_OTG_GLB->GHWCFG3 >> 16), "Your fifo config is overflow, please check");
/* xxx32 chips do not follow (USB_OTG_GLB->GHWCFG3 >> 16) if hsphy_type is zero, they use 1.25KB(320 DWORD) */
USB_ASSERT_MSG(!((hsphy_type == 0) && (fifo_num > 320)), "Your fifo config is larger than 320 , please check");
if (g_dwc2_udc[busid].user_params.phy_type != DWC2_PHY_TYPE_PARAM_FS) {
USB_ASSERT_MSG(g_dwc2_udc[busid].user_params.device_rx_fifo_size >= (5 + 8 + 512 / 4 + 1 + 2 * 8 + 1), "Your rx fifo size config is invalid, please check");
} else {
USB_ASSERT_MSG(g_dwc2_udc[busid].user_params.device_rx_fifo_size >= (5 + 8 + 64 / 4 + 1 + 2 * 8 + 1), "Your rx fifo size config is invalid, please check");
}
ret = dwc2_flush_txfifo(busid, 0x10U);
ret = dwc2_flush_rxfifo(busid);
@ -725,7 +671,7 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
{
uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress);
USB_ASSERT_MSG(ep_idx < CONFIG_USBDEV_EP_NUM, "Ep addr %02x overflow", ep->bEndpointAddress);
USB_ASSERT_MSG(ep_idx < (g_dwc2_udc[busid].hw_params.num_dev_ep + 1), "Ep addr %02x overflow", ep->bEndpointAddress);
if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) {
g_dwc2_udc[busid].out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
@ -829,11 +775,11 @@ int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
}
USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_STALL;
}
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
if (ep_idx == 0) {
if ((ep_idx == 0) && g_dwc2_udc[busid].user_params.device_dma_enable) {
dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
}
#endif
return 0;
}
@ -884,9 +830,9 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui
USB_ASSERT_MSG(!((uint32_t)data % 0x04), "dwc2 data must be 4-byte aligned");
#ifdef CONFIG_USB_DCACHE_ENABLE
if (g_dwc2_udc[busid].user_params.device_dma_enable) {
USB_ASSERT_MSG(!((uint32_t)data % CONFIG_USB_ALIGN_SIZE), "dwc2 data must be %d-byte aligned", CONFIG_USB_ALIGN_SIZE);
#endif
}
if (!data && data_len) {
return -1;
@ -935,18 +881,18 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui
USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1U << 29));
}
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
if (g_dwc2_udc[busid].user_params.device_dma_enable) {
usb_dcache_clean((uintptr_t)data, USB_ALIGN_UP(data_len, CONFIG_USB_ALIGN_SIZE));
USB_OTG_INEP(ep_idx)->DIEPDMA = (uint32_t)data;
USB_OTG_INEP(ep_idx)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
#else
} else {
USB_OTG_INEP(ep_idx)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
/* Enable the Tx FIFO Empty Interrupt for this EP */
if (data_len > 0U) {
USB_OTG_DEV->DIEPEMPMSK |= 1UL << (ep_idx & 0x0f);
}
#endif
}
return 0;
}
@ -957,9 +903,9 @@ int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t
USB_ASSERT_MSG(!((uint32_t)data % 0x04), "dwc2 data must be 4-byte aligned");
#ifdef CONFIG_USB_DCACHE_ENABLE
if (g_dwc2_udc[busid].user_params.device_dma_enable) {
USB_ASSERT_MSG(!((uint32_t)data % CONFIG_USB_ALIGN_SIZE), "dwc2 data must be %d-byte aligned", CONFIG_USB_ALIGN_SIZE);
#endif
}
if (!data && data_len) {
return -1;
@ -996,9 +942,9 @@ int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t
USB_OTG_OUTEP(ep_idx)->DOEPTSIZ |= (USB_OTG_DOEPTSIZ_XFRSIZ & data_len);
}
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
if (g_dwc2_udc[busid].user_params.device_dma_enable) {
USB_OTG_OUTEP(ep_idx)->DOEPDMA = (uint32_t)data;
#endif
}
if (g_dwc2_udc[busid].out_ep[ep_idx].ep_type == USB_ENDPOINT_TYPE_ISOCHRONOUS) {
if ((USB_OTG_DEV->DSTS & (1U << 8)) == 0U) {
USB_OTG_OUTEP(ep_idx)->DOEPCTL &= ~USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
@ -1025,7 +971,7 @@ void USBD_IRQHandler(uint8_t busid)
return;
}
#ifndef CONFIG_USB_DWC2_DMA_ENABLE
if (!g_dwc2_udc[busid].user_params.device_dma_enable) {
/* Handle RxQLevel Interrupt */
if (gint_status & USB_OTG_GINTSTS_RXFLVL) {
USB_MASK_INTERRUPT(USB_OTG_GLB, USB_OTG_GINTSTS_RXFLVL);
@ -1047,7 +993,8 @@ void USBD_IRQHandler(uint8_t busid)
}
USB_UNMASK_INTERRUPT(USB_OTG_GLB, USB_OTG_GINTSTS_RXFLVL);
}
#endif
}
if (gint_status & USB_OTG_GINTSTS_OEPINT) {
ep_idx = 0;
ep_intr = dwc2_get_outeps_intstatus(busid);
@ -1057,25 +1004,44 @@ void USBD_IRQHandler(uint8_t busid)
if ((epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC) {
if (ep_idx == 0) {
if (usbd_get_ep0_next_state(busid) == USBD_EP0_STATE_SETUP) {
goto process_setup; // goto ep0 setup, xfer_len is not used
}
if (g_dwc2_udc[busid].out_ep[ep_idx].xfer_len == 0) {
/* If ep0 xfer_len is 0, it means that we are in outstatus phase */
g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len = 0;
} else {
/* If ep0 xfer_len is not 0, it means that we are in outdata phase */
g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len = g_dwc2_udc[busid].out_ep[ep_idx].xfer_len - ((USB_OTG_OUTEP(ep_idx)->DOEPTSIZ) & USB_OTG_DOEPTSIZ_XFRSIZ);
}
g_dwc2_udc[busid].out_ep[ep_idx].xfer_len = 0;
if (g_dwc2_udc[busid].user_params.device_dma_enable) {
usb_dcache_invalidate((uintptr_t)g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf, USB_ALIGN_UP(g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len, CONFIG_USB_ALIGN_SIZE));
}
usbd_event_ep_out_complete_handler(busid, 0x00, g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len);
if (usbd_get_ep0_next_state(busid) == USBD_EP0_STATE_SETUP) {
/* Out status, start reading setup */
dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
} else {
g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len = g_dwc2_udc[busid].out_ep[ep_idx].xfer_len - ((USB_OTG_OUTEP(ep_idx)->DOEPTSIZ) & USB_OTG_DOEPTSIZ_XFRSIZ);
g_dwc2_udc[busid].out_ep[ep_idx].xfer_len = 0;
usb_dcache_invalidate((uintptr_t)g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf, USB_ALIGN_UP(g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len, CONFIG_USB_ALIGN_SIZE));
usbd_event_ep_out_complete_handler(busid, 0x00, g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len);
}
} else {
g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len = g_dwc2_udc[busid].out_ep[ep_idx].xfer_len - ((USB_OTG_OUTEP(ep_idx)->DOEPTSIZ) & USB_OTG_DOEPTSIZ_XFRSIZ);
g_dwc2_udc[busid].out_ep[ep_idx].xfer_len = 0;
if (g_dwc2_udc[busid].user_params.device_dma_enable) {
usb_dcache_invalidate((uintptr_t)g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf, USB_ALIGN_UP(g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len, CONFIG_USB_ALIGN_SIZE));
}
usbd_event_ep_out_complete_handler(busid, ep_idx, g_dwc2_udc[busid].out_ep[ep_idx].actual_xfer_len);
}
}
// clang-format off
process_setup:
// clang-format on
if ((epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) {
if (g_dwc2_udc[busid].user_params.device_dma_enable) {
usb_dcache_invalidate((uintptr_t)&g_dwc2_udc[busid].setup, USB_ALIGN_UP(8, CONFIG_USB_ALIGN_SIZE));
}
usbd_event_ep0_setup_complete_handler(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
}
}
@ -1096,10 +1062,7 @@ void USBD_IRQHandler(uint8_t busid)
g_dwc2_udc[busid].in_ep[ep_idx].xfer_len = 0;
usbd_event_ep_in_complete_handler(busid, 0x80, g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len);
if (g_dwc2_udc[busid].setup.wLength && ((g_dwc2_udc[busid].setup.bmRequestType & USB_REQUEST_DIR_MASK) == USB_REQUEST_DIR_OUT)) {
/* In status, start reading setup */
dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
} else if (g_dwc2_udc[busid].setup.wLength == 0) {
if (usbd_get_ep0_next_state(busid) == USBD_EP0_STATE_SETUP) {
/* In status, start reading setup */
dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);
}
@ -1109,10 +1072,12 @@ void USBD_IRQHandler(uint8_t busid)
usbd_event_ep_in_complete_handler(busid, ep_idx | 0x80, g_dwc2_udc[busid].in_ep[ep_idx].actual_xfer_len);
}
}
if (!g_dwc2_udc[busid].user_params.device_dma_enable) {
if ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE) {
dwc2_tx_fifo_empty_procecss(busid, ep_idx);
}
}
}
ep_intr >>= 1U;
ep_idx++;
}
@ -1124,7 +1089,7 @@ void USBD_IRQHandler(uint8_t busid)
dwc2_flush_txfifo(busid, 0x10U);
dwc2_flush_rxfifo(busid);
for (uint8_t i = 0U; i < CONFIG_USBDEV_EP_NUM; i++) {
for (uint8_t i = 0U; i < (g_dwc2_udc[busid].hw_params.num_dev_ep + 1); i++) {
if (i == 0U) {
USB_OTG_INEP(i)->DIEPCTL = USB_OTG_DIEPCTL_SNAK;
USB_OTG_OUTEP(i)->DOEPCTL = USB_OTG_DOEPCTL_SNAK;
@ -1153,7 +1118,8 @@ void USBD_IRQHandler(uint8_t busid)
USB_OTG_DEV->DIEPMSK = USB_OTG_DIEPMSK_XFRCM;
memset(&g_dwc2_udc[busid], 0, sizeof(struct dwc2_udc));
memset(g_dwc2_udc[busid].in_ep, 0, sizeof(struct dwc2_ep_state) * 16);
memset(g_dwc2_udc[busid].out_ep, 0, sizeof(struct dwc2_ep_state) * 16);
usbd_event_reset_handler(busid);
/* Start reading setup */
dwc2_ep0_start_read_setup(busid, (uint8_t *)&g_dwc2_udc[busid].setup);

View File

@ -0,0 +1,367 @@
/*
* Copyright (c) 2025, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __USB_DWC2_PARAM_H__
#define __USB_DWC2_PARAM_H__
/* Maximum number of Endpoints/HostChannels */
#define MAX_EPS_CHANNELS 16
#define HSOTG_REG(x) (x)
#define dwc2_readl(addr) \
(*(volatile uint32_t *)(addr))
#define GUID_OFFSET HSOTG_REG(0x003c)
#define GSNPSID_OFFSET HSOTG_REG(0x0040)
#define GSNPSID_ID_MASK 0xffff0000
#define GHWCFG1_OFFSET HSOTG_REG(0x0044)
#define GHWCFG2_OFFSET HSOTG_REG(0x0048)
#define GHWCFG2_OTG_ENABLE_IC_USB (1U << 31)
#define GHWCFG2_DEV_TOKEN_Q_DEPTH_MASK (0x1f << 26)
#define GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT 26
#define GHWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK (0x3 << 24)
#define GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT 24
#define GHWCFG2_NONPERIO_TX_Q_DEPTH_MASK (0x3 << 22)
#define GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT 22
#define GHWCFG2_MULTI_PROC_INT (1 << 20)
#define GHWCFG2_DYNAMIC_FIFO (1 << 19)
#define GHWCFG2_PERIO_EP_SUPPORTED (1 << 18)
#define GHWCFG2_NUM_HOST_CHAN_MASK (0xf << 14)
#define GHWCFG2_NUM_HOST_CHAN_SHIFT 14
#define GHWCFG2_NUM_DEV_EP_MASK (0xf << 10)
#define GHWCFG2_NUM_DEV_EP_SHIFT 10
#define GHWCFG2_FS_PHY_TYPE_MASK (0x3 << 8)
#define GHWCFG2_FS_PHY_TYPE_SHIFT 8
#define GHWCFG2_FS_PHY_TYPE_NOT_SUPPORTED 0
#define GHWCFG2_FS_PHY_TYPE_DEDICATED 1
#define GHWCFG2_FS_PHY_TYPE_SHARED_UTMI 2
#define GHWCFG2_FS_PHY_TYPE_SHARED_ULPI 3
#define GHWCFG2_HS_PHY_TYPE_MASK (0x3 << 6)
#define GHWCFG2_HS_PHY_TYPE_SHIFT 6
#define GHWCFG2_HS_PHY_TYPE_NOT_SUPPORTED 0
#define GHWCFG2_HS_PHY_TYPE_UTMI 1
#define GHWCFG2_HS_PHY_TYPE_ULPI 2
#define GHWCFG2_HS_PHY_TYPE_UTMI_ULPI 3
#define GHWCFG2_POINT2POINT (1 << 5)
#define GHWCFG2_ARCHITECTURE_MASK (0x3 << 3)
#define GHWCFG2_ARCHITECTURE_SHIFT 3
#define GHWCFG2_SLAVE_ONLY_ARCH 0
#define GHWCFG2_EXT_DMA_ARCH 1
#define GHWCFG2_INT_DMA_ARCH 2
#define GHWCFG2_OP_MODE_MASK (0x7 << 0)
#define GHWCFG2_OP_MODE_SHIFT 0
#define GHWCFG2_OP_MODE_HNP_SRP_CAPABLE 0
#define GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE 1
#define GHWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE 2
#define GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE 3
#define GHWCFG2_OP_MODE_NO_SRP_CAPABLE_DEVICE 4
#define GHWCFG2_OP_MODE_SRP_CAPABLE_HOST 5
#define GHWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST 6
#define GHWCFG2_OP_MODE_UNDEFINED 7
#define GHWCFG3_OFFSET HSOTG_REG(0x004c)
#define GHWCFG3_DFIFO_DEPTH_MASK (0xffff << 16)
#define GHWCFG3_DFIFO_DEPTH_SHIFT 16
#define GHWCFG3_OTG_LPM_EN (1 << 15)
#define GHWCFG3_BC_SUPPORT (1 << 14)
#define GHWCFG3_OTG_ENABLE_HSIC (1 << 13)
#define GHWCFG3_ADP_SUPP (1 << 12)
#define GHWCFG3_SYNCH_RESET_TYPE (1 << 11)
#define GHWCFG3_OPTIONAL_FEATURES (1 << 10)
#define GHWCFG3_VENDOR_CTRL_IF (1 << 9)
#define GHWCFG3_I2C (1 << 8)
#define GHWCFG3_OTG_FUNC (1 << 7)
#define GHWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK (0x7 << 4)
#define GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT 4
#define GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK (0xf << 0)
#define GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT 0
#define GHWCFG4_OFFSET HSOTG_REG(0x0050)
#define GHWCFG4_DESC_DMA_DYN (1U << 31)
#define GHWCFG4_DESC_DMA (1 << 30)
#define GHWCFG4_NUM_IN_EPS_MASK (0xf << 26)
#define GHWCFG4_NUM_IN_EPS_SHIFT 26
#define GHWCFG4_DED_FIFO_EN (1 << 25)
#define GHWCFG4_DED_FIFO_SHIFT 25
#define GHWCFG4_SESSION_END_FILT_EN (1 << 24)
#define GHWCFG4_B_VALID_FILT_EN (1 << 23)
#define GHWCFG4_A_VALID_FILT_EN (1 << 22)
#define GHWCFG4_VBUS_VALID_FILT_EN (1 << 21)
#define GHWCFG4_IDDIG_FILT_EN (1 << 20)
#define GHWCFG4_NUM_DEV_MODE_CTRL_EP_MASK (0xf << 16)
#define GHWCFG4_NUM_DEV_MODE_CTRL_EP_SHIFT 16
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK (0x3 << 14)
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT 14
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_8 0
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_16 1
#define GHWCFG4_UTMI_PHY_DATA_WIDTH_8_OR_16 2
#define GHWCFG4_ACG_SUPPORTED (1 << 12)
#define GHWCFG4_IPG_ISOC_SUPPORTED (1 << 11)
#define GHWCFG4_SERVICE_INTERVAL_SUPPORTED (1 << 10)
#define GHWCFG4_XHIBER (1 << 7)
#define GHWCFG4_HIBER (1 << 6)
#define GHWCFG4_MIN_AHB_FREQ (1 << 5)
#define GHWCFG4_POWER_OPTIMIZ (1 << 4)
#define GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK (0xf << 0)
#define GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT 0
/**
* struct dwc2_hw_params - Autodetected parameters.
*
* These parameters are the various parameters read from hardware
* registers during initialization. They typically contain the best
* supported or maximum value that can be configured in the
* corresponding dwc2_core_params value.
*
* The values that are not in dwc2_core_params are documented below.
*
* @snpsid: Value from SNPSID register
* @dev_ep_dirs: Direction of device endpoints (GHWCFG1)
*
* @op_mode: Mode of Operation
* 0 - HNP- and SRP-Capable OTG (Host & Device)
* 1 - SRP-Capable OTG (Host & Device)
* 2 - Non-HNP and Non-SRP Capable OTG (Host & Device)
* 3 - SRP-Capable Device
* 4 - Non-OTG Device
* 5 - SRP-Capable Host
* 6 - Non-OTG Host
* @arch: Architecture
* 0 - Slave only
* 1 - External DMA
* 2 - Internal DMA
* @enable_dynamic_fifo: 0 - Use coreConsultant-specified FIFO size parameters
* 1 - Allow dynamic FIFO sizing (default, if available)
* @host_channels: The number of host channel registers to use
* 1 to 16
* @hs_phy_type: High-speed PHY interface type
* 0 - High-speed interface not supported
* 1 - UTMI+
* 2 - ULPI
* 3 - UTMI+ and ULPI
* @fs_phy_type: Full-speed PHY interface type
* 0 - Full speed interface not supported
* 1 - Dedicated full speed interface
* 2 - FS pins shared with UTMI+ pins
* 3 - FS pins shared with ULPI pins
* @num_dev_ep: Number of device endpoints available
* @nperio_tx_q_depth:
* Non-Periodic Request Queue Depth
* 2, 4 or 8
* @dev_token_q_depth: Device Mode IN Token Sequence Learning Queue
* Depth
* 0 to 30
* @host_perio_tx_q_depth:
* Host Mode Periodic Request Queue Depth
* 2, 4 or 8
*
* @max_transfer_size: The maximum transfer size supported, in bytes
* 2047 to 65,535
* Actual maximum value is autodetected and also
* the default.
* @max_packet_count: The maximum number of packets in a transfer
* 15 to 511
* Actual maximum value is autodetected and also
* the default.
* @i2c_enable: Specifies whether to use the I2Cinterface for a full
* speed PHY. This parameter is only applicable if phy_type
* is FS.
* 0 - No (default)
* 1 - Yes
* @total_fifo_size: Total internal RAM for FIFOs (bytes)
* @lpm_mode: For enabling Link Power Management in the controller
* 0 - Disable
* 1 - Enable
*
* @en_multiple_tx_fifo: Specifies whether dedicated per-endpoint transmit FIFOs
* are enabled for non-periodic IN endpoints in device
* mode.
* @num_dev_in_eps: Number of device IN endpoints available
* @num_dev_perio_in_ep: Number of device periodic IN endpoints
* available
* @dma_desc_enable: When DMA mode is enabled, specifies whether to use
* address DMA mode or descriptor DMA mode for accessing
* the data FIFOs. The driver will automatically detect the
* value for this if none is specified.
* 0 - Address DMA
* 1 - Descriptor DMA (default, if available)
* @power_optimized: Are power optimizations enabled?
* @hibernation: Is hibernation enabled?
* @utmi_phy_data_width: UTMI+ PHY data width
* 0 - 8 bits
* 1 - 16 bits
* 2 - 8 or 16 bits
* @acg_enable: For enabling Active Clock Gating in the controller
* 0 - Disable
* 1 - Enable
* @ipg_isoc_en: This feature indicates that the controller supports
* the worst-case scenario of Rx followed by Rx
* Interpacket Gap (IPG) (32 bitTimes) as per the utmi
* specification for any token following ISOC OUT token.
* 0 - Don't support
* 1 - Support
* @service_interval_mode: For enabling service interval based scheduling in the
* controller.
* 0 - Disable
* 1 - Enable
*/
struct dwc2_hw_params {
uint32_t snpsid;
uint32_t dev_ep_dirs;
unsigned op_mode : 3;
unsigned arch : 2;
unsigned enable_dynamic_fifo : 1;
unsigned host_channels : 5;
unsigned hs_phy_type : 2;
unsigned fs_phy_type : 2;
unsigned num_dev_ep : 4;
unsigned nperio_tx_q_depth : 3;
unsigned host_perio_tx_q_depth : 3;
unsigned dev_token_q_depth : 5;
unsigned max_transfer_size : 26;
unsigned max_packet_count : 11;
unsigned i2c_enable : 1;
unsigned total_fifo_size : 16;
unsigned lpm_mode : 1;
unsigned en_multiple_tx_fifo : 1;
unsigned num_dev_in_eps : 4;
unsigned num_dev_perio_in_ep : 4;
unsigned dma_desc_enable : 1;
unsigned power_optimized : 1;
unsigned hibernation : 1;
unsigned utmi_phy_data_width : 2;
unsigned acg_enable : 1;
unsigned ipg_isoc_en : 1;
unsigned service_interval_mode : 1;
};
#define DWC2_PHY_TYPE_PARAM_FS 0
#define DWC2_PHY_TYPE_PARAM_UTMI 1
#define DWC2_PHY_TYPE_PARAM_ULPI 2
struct dwc2_user_params {
uint8_t phy_type;
uint8_t phy_utmi_width;
bool device_dma_enable;
bool device_dma_desc_enable;
/* (5 * number of control endpoints + 8) + ((largest USB packet used / 4) + 1 for
* status information) + (2 * number of OUT endpoints) + 1 for Global NAK
*/
uint16_t device_rx_fifo_size;
/* IN Endpoints Max packet Size / 4 */
uint16_t device_tx_fifo_size[MAX_EPS_CHANNELS];
bool host_dma_desc_enable;
/*
* (largest USB packet used / 4) + 1 for status information + 1 transfer complete +
* 1 location each for Bulk/Control endpoint for handling NAK/NYET scenario
*/
uint16_t host_rx_fifo_size;
/* largest non-periodic USB packet used / 4 */
uint16_t host_nperio_tx_fifo_size;
/* largest periodic USB packet used / 4 */
uint16_t host_perio_tx_fifo_size;
uint32_t device_gccfg;
uint32_t host_gccfg;
bool b_session_valid_override;
uint32_t total_fifo_size;
};
struct usb_dwc2_user_fifo_config {
/* (5 * number of control endpoints + 8) + ((largest USB packet used / 4) + 1 for
* status information) + (2 * number of OUT endpoints) + 1 for Global NAK
*/
uint16_t device_rx_fifo_size;
/* IN Endpoints Max packet Size / 4 */
uint16_t device_tx_fifo_size[MAX_EPS_CHANNELS];
};
static inline void dwc2_get_hwparams(uint32_t reg_base, struct dwc2_hw_params *hw)
{
unsigned int width;
uint32_t snpsid, hwcfg1, hwcfg2, hwcfg3, hwcfg4;
snpsid = dwc2_readl(reg_base + GSNPSID_OFFSET);
hwcfg1 = dwc2_readl(reg_base + GHWCFG1_OFFSET);
hwcfg2 = dwc2_readl(reg_base + GHWCFG2_OFFSET);
hwcfg3 = dwc2_readl(reg_base + GHWCFG3_OFFSET);
hwcfg4 = dwc2_readl(reg_base + GHWCFG4_OFFSET);
/* snpsid */
hw->snpsid = snpsid;
/* hwcfg1 */
hw->dev_ep_dirs = hwcfg1;
/* hwcfg2 */
hw->op_mode = (hwcfg2 & GHWCFG2_OP_MODE_MASK) >>
GHWCFG2_OP_MODE_SHIFT;
hw->arch = (hwcfg2 & GHWCFG2_ARCHITECTURE_MASK) >>
GHWCFG2_ARCHITECTURE_SHIFT;
hw->enable_dynamic_fifo = !!(hwcfg2 & GHWCFG2_DYNAMIC_FIFO);
hw->host_channels = 1 + ((hwcfg2 & GHWCFG2_NUM_HOST_CHAN_MASK) >>
GHWCFG2_NUM_HOST_CHAN_SHIFT);
hw->hs_phy_type = (hwcfg2 & GHWCFG2_HS_PHY_TYPE_MASK) >>
GHWCFG2_HS_PHY_TYPE_SHIFT;
hw->fs_phy_type = (hwcfg2 & GHWCFG2_FS_PHY_TYPE_MASK) >>
GHWCFG2_FS_PHY_TYPE_SHIFT;
hw->num_dev_ep = (hwcfg2 & GHWCFG2_NUM_DEV_EP_MASK) >>
GHWCFG2_NUM_DEV_EP_SHIFT;
hw->nperio_tx_q_depth =
(hwcfg2 & GHWCFG2_NONPERIO_TX_Q_DEPTH_MASK) >>
GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT << 1;
hw->host_perio_tx_q_depth =
(hwcfg2 & GHWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK) >>
GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT << 1;
hw->dev_token_q_depth =
(hwcfg2 & GHWCFG2_DEV_TOKEN_Q_DEPTH_MASK) >>
GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT;
/* hwcfg3 */
width = (hwcfg3 & GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK) >>
GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT;
hw->max_transfer_size = (1 << (width + 11)) - 1;
width = (hwcfg3 & GHWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK) >>
GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT;
hw->max_packet_count = (1 << (width + 4)) - 1;
hw->i2c_enable = !!(hwcfg3 & GHWCFG3_I2C);
hw->total_fifo_size = (hwcfg3 & GHWCFG3_DFIFO_DEPTH_MASK) >>
GHWCFG3_DFIFO_DEPTH_SHIFT;
hw->lpm_mode = !!(hwcfg3 & GHWCFG3_OTG_LPM_EN);
/* hwcfg4 */
hw->en_multiple_tx_fifo = !!(hwcfg4 & GHWCFG4_DED_FIFO_EN);
hw->num_dev_perio_in_ep = (hwcfg4 & GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK) >>
GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT;
hw->num_dev_in_eps = (hwcfg4 & GHWCFG4_NUM_IN_EPS_MASK) >>
GHWCFG4_NUM_IN_EPS_SHIFT;
hw->dma_desc_enable = !!(hwcfg4 & GHWCFG4_DESC_DMA);
hw->power_optimized = !!(hwcfg4 & GHWCFG4_POWER_OPTIMIZ);
hw->hibernation = !!(hwcfg4 & GHWCFG4_HIBER);
hw->utmi_phy_data_width = (hwcfg4 & GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK) >>
GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT;
hw->acg_enable = !!(hwcfg4 & GHWCFG4_ACG_SUPPORTED);
hw->ipg_isoc_en = !!(hwcfg4 & GHWCFG4_IPG_ISOC_SUPPORTED);
hw->service_interval_mode = !!(hwcfg4 &
GHWCFG4_SERVICE_INTERVAL_SUPPORTED);
}
void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params);
void dwc2_get_user_fifo_config(uint32_t reg_base, struct usb_dwc2_user_fifo_config *config);
#endif

View File

@ -209,12 +209,15 @@ typedef struct
#define USB_OTG_HCFG_FSLSPCS_Pos (0U)
#define USB_OTG_HCFG_FSLSPCS_Msk (0x3UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000003 */
#define USB_OTG_HCFG_FSLSPCS USB_OTG_HCFG_FSLSPCS_Msk /*!< FS/LS PHY clock select */
#define USB_OTG_HCFG_FSLSPCS_0 (0x1UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000001 */
#define USB_OTG_HCFG_FSLSPCS_1 (0x2UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000002 */
#define USB_OTG_HCFG_FSLSPCLKSEL_30_60_MHZ (0x0UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000000 */
#define USB_OTG_HCFG_FSLSPCLKSEL_48_MHZ (0x1UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000001 */
#define USB_OTG_HCFG_FSLSPCLKSEL_6_MHZ (0x2UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000002 */
#define USB_OTG_HCFG_FSLSS_Pos (2U)
#define USB_OTG_HCFG_FSLSS_Msk (0x1UL << USB_OTG_HCFG_FSLSS_Pos) /*!< 0x00000004 */
#define USB_OTG_HCFG_FSLSS USB_OTG_HCFG_FSLSS_Msk /*!< FS- and LS-only support */
#define USB_OTG_HFIR_RELOAD_CTRL_Pos (16U)
#define USB_OTG_HFIR_RELOAD_CTRL_Msk (0x1UL << USB_OTG_HFIR_RELOAD_CTRL_Pos)
#define USB_OTG_HFIR_RELOAD_CTRL USB_OTG_HFIR_RELOAD_CTRL_Msk
/******************** Bit definition for USB_OTG_DCFG register ********************/
#define USB_OTG_DCFG_DSPD_Pos (0U)
@ -385,12 +388,20 @@ typedef struct
#define USB_OTG_GUSBCFG_TOCAL_Pos (0U)
#define USB_OTG_GUSBCFG_TOCAL_Msk (0x7UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000007 */
#define USB_OTG_GUSBCFG_TOCAL USB_OTG_GUSBCFG_TOCAL_Msk /*!< FS timeout calibration */
#define USB_OTG_GUSBCFG_TOCAL_0 (0x1UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000001 */
#define USB_OTG_GUSBCFG_TOCAL_1 (0x2UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000002 */
#define USB_OTG_GUSBCFG_TOCAL_2 (0x4UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000004 */
#define USB_OTG_GUSBCFG_PHYIF_Pos (3U)
#define USB_OTG_GUSBCFG_PHYIF_Msk (0x1UL << USB_OTG_GUSBCFG_PHYIF_Pos)
#define USB_OTG_GUSBCFG_PHYIF USB_OTG_GUSBCFG_PHYIF_Msk
#define USB_OTG_GUSBCFG_PHYIF8 (0x0UL << USB_OTG_GUSBCFG_PHYIF_Pos)
#define USB_OTG_GUSBCFG_PHYIF16 (0x1UL << USB_OTG_GUSBCFG_PHYIF_Pos)
#define USB_OTG_GUSBCFG_ULPI_UTMI_SEL_Pos (4U)
#define USB_OTG_GUSBCFG_ULPI_UTMI_SEL_Msk (0x1UL << USB_OTG_GUSBCFG_ULPI_UTMI_SEL_Pos)
#define USB_OTG_GUSBCFG_ULPI_UTMI_SEL USB_OTG_GUSBCFG_ULPI_UTMI_SEL_Msk
#define USB_OTG_GUSBCFG_PHYSEL_Pos (6U)
#define USB_OTG_GUSBCFG_PHYSEL_Msk (0x1UL << USB_OTG_GUSBCFG_PHYSEL_Pos) /*!< 0x00000040 */
#define USB_OTG_GUSBCFG_PHYSEL USB_OTG_GUSBCFG_PHYSEL_Msk /*!< USB 2.0 high-speed ULPI PHY or USB 1.1 full-speed serial transceiver select */
#define USB_OTG_GUSBCFG_DDR_SEL_Pos (7U)
#define USB_OTG_GUSBCFG_DDR_SEL_Msk (0x1UL << USB_OTG_GUSBCFG_DDR_SEL_Pos)
#define USB_OTG_GUSBCFG_DDR_SEL USB_OTG_GUSBCFG_DDR_SEL_Msk
#define USB_OTG_GUSBCFG_SRPCAP_Pos (8U)
#define USB_OTG_GUSBCFG_SRPCAP_Msk (0x1UL << USB_OTG_GUSBCFG_SRPCAP_Pos) /*!< 0x00000100 */
#define USB_OTG_GUSBCFG_SRPCAP USB_OTG_GUSBCFG_SRPCAP_Msk /*!< SRP-capable */
@ -1720,7 +1731,5 @@ typedef struct
void usb_dc_low_level_init(uint8_t busid);
void usb_dc_low_level_deinit(uint8_t busid);
uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base);
uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base);
void usbd_dwc2_delay_ms(uint8_t ms);
#endif

View File

@ -3,60 +3,106 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usb_config.h"
#include "stdint.h"
#include "usb_dwc2_reg.h"
#include "usbd_core.h"
#include "usbh_core.h"
#include "usb_dwc2_param.h"
extern unsigned int system_core_clock;
uint32_t SystemCoreClock;
/* you can find this config in function: usb_global_init, file:at32fxxx_usb.c, for example:
*
* usbx->gccfg_bit.pwrdown = TRUE;
* usbx->gccfg_bit.avalidsesen = TRUE;
* usbx->gccfg_bit.bvalidsesen = TRUE;
*
*/
uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base)
const struct dwc2_user_params param_pa11_pa12 = {
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
.device_dma_enable = false,
.device_dma_desc_enable = false,
.device_rx_fifo_size = (320 - 16 - 16 - 16 - 16),
.device_tx_fifo_size = {
[0] = 16, // 64 byte
[1] = 16, // 64 byte
[2] = 16, // 64 byte
[3] = 16, // 64 byte
[4] = 0,
[5] = 0,
[6] = 0,
[7] = 0,
[8] = 0,
[9] = 0,
[10] = 0,
[11] = 0,
[12] = 0,
[13] = 0,
[14] = 0,
[15] = 0 },
#ifdef AT32F415xx
.device_gccfg = ((1 << 16) | (1 << 18) | (1 << 19) | (1 << 21)),
#else
.device_gccfg = ((1 << 16) | (1 << 21)),
#endif
.total_fifo_size = 320 // 1280 byte
};
#if __has_include("at32f402_405.h")
#include "at32f402_405.h"
const struct dwc2_user_params param_pb14_pb15 = {
.phy_type = DWC2_PHY_TYPE_PARAM_UTMI,
.device_dma_enable = true,
.device_dma_desc_enable = false,
.device_rx_fifo_size = (1008 - 16 - 256 - 128 - 128 - 128 - 128),
.device_tx_fifo_size = {
[0] = 16, // 64 byte
[1] = 256, // 1024 byte
[2] = 128, // 512 byte
[3] = 128, // 512 byte
[4] = 128, // 512 byte
[5] = 128, // 512 byte
[6] = 0,
[7] = 0,
[8] = 0,
[9] = 0,
[10] = 0,
[11] = 0,
[12] = 0,
[13] = 0,
[14] = 0,
[15] = 0 },
.host_dma_desc_enable = false,
.host_rx_fifo_size = 628,
.host_nperio_tx_fifo_size = 128, // 512 byte
.host_perio_tx_fifo_size = 256, // 1024 byte
.device_gccfg = ((1 << 16) | (1 << 21)),
.host_gccfg = ((1 << 16) | (1 << 21))
};
#endif
#ifndef CONFIG_USB_DWC2_CUSTOM_PARAM
void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params)
{
SystemCoreClock = system_core_clock;
#ifdef CONFIG_USB_HS
return ((1 << 16) | (1 << 21));
#if __has_include("at32f402_405.h")
if (reg_base == OTGHS_BASE) {
memcpy(params, &param_pb14_pb15, sizeof(struct dwc2_user_params));
} else {
memcpy(params, &param_pa11_pa12, sizeof(struct dwc2_user_params));
}
#else
// AT32F415
#if defined(AT32F415RCT7) || defined(AT32F415RCT7_7) || defined(AT32F415CCT7) || \
defined(AT32F415CCU7) || defined(AT32F415KCU7_4) || defined(AT32F415RBT7) || \
defined(AT32F415RBT7_7) || defined(AT32F415CBT7) || defined(AT32F415CBU7) || \
defined(AT32F415KBU7_4) || defined(AT32F415R8T7) || defined(AT32F415R8T7_7) || \
defined(AT32F415C8T7) || defined(AT32F415K8U7_4)
return ((1 << 16) | (1 << 18) | (1 << 19) | (1 << 21));
#else
return ((1 << 16) | (1 << 21));
memcpy(params, &param_pa11_pa12, sizeof(struct dwc2_user_params));
#endif
#ifdef CONFIG_USB_DWC2_CUSTOM_FIFO
struct usb_dwc2_user_fifo_config s_dwc2_fifo_config;
dwc2_get_user_fifo_config(reg_base, &s_dwc2_fifo_config);
params->device_rx_fifo_size = s_dwc2_fifo_config.device_rx_fifo_size;
for (uint8_t i = 0; i < MAX_EPS_CHANNELS; i++) {
params->device_tx_fifo_size[i] = s_dwc2_fifo_config.device_tx_fifo_size[i];
}
#endif
}
uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base)
{
SystemCoreClock = system_core_clock;
#ifdef CONFIG_USB_HS
return ((1 << 16) | (1 << 21));
#else
// AT32F415
#if defined(AT32F415RCT7) || defined(AT32F415RCT7_7) || defined(AT32F415CCT7) || \
defined(AT32F415CCU7) || defined(AT32F415KCU7_4) || defined(AT32F415RBT7) || \
defined(AT32F415RBT7_7) || defined(AT32F415CBT7) || defined(AT32F415CBU7) || \
defined(AT32F415KBU7_4) || defined(AT32F415R8T7) || defined(AT32F415R8T7_7) || \
defined(AT32F415C8T7) || defined(AT32F415K8U7_4)
return ((1 << 16) | (1 << 18) | (1 << 19) | (1 << 21));
#else
return ((1 << 16) | (1 << 21));
#endif
#endif
}
extern uint32_t SystemCoreClock;
void usbd_dwc2_delay_ms(uint8_t ms)
{

View File

@ -12,7 +12,12 @@
#include "freertos/task.h"
#include "usbd_core.h"
#include "usbh_core.h"
#include "usb_dwc2_param.h"
#define GET_USB_INDEX(reg_base) 0
#define GET_USB_INTR_SOURCE(reg_base) ETS_USB_INTR_SOURCE
#define GET_USB_PHY_TARGET(reg_base) USB_PHY_TARGET_INT
#define GET_USB_PHY_SPEED(reg_base) USB_PHY_SPEED_UNDEFINED
#ifdef CONFIG_IDF_TARGET_ESP32S2
#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ
#define DEFAULT_USB_INTR_SOURCE ETS_USB_INTR_SOURCE
@ -20,42 +25,141 @@
#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ
#define DEFAULT_USB_INTR_SOURCE ETS_USB_INTR_SOURCE
#elif CONFIG_IDF_TARGET_ESP32P4
#undef GET_USB_INDEX
#define GET_USB_INDEX(reg_base) ((reg_base) == (void*)ESP_USB_HS0_BASE ? 0 : 1)
#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ
#define DEFAULT_USB_INTR_SOURCE ETS_USB_OTG_INTR_SOURCE
#define USB_FS_INTR_SOURCE ETS_USB_OTG11_CH0_INTR_SOURCE
#undef GET_USB_INTR_SOURCE
#define GET_USB_INTR_SOURCE(reg_base) ((reg_base) == (void*)ESP_USB_HS0_BASE ? DEFAULT_USB_INTR_SOURCE : USB_FS_INTR_SOURCE)
#undef GET_USB_PHY_TARGET
#define GET_USB_PHY_TARGET(reg_base) ((reg_base) == (void*)ESP_USB_HS0_BASE ? USB_PHY_TARGET_UTMI : USB_PHY_TARGET_INT)
#undef GET_USB_PHY_SPEED
#define GET_USB_PHY_SPEED(reg_base) ((reg_base) == (void*)ESP_USB_HS0_BASE ? USB_PHY_SPEED_HIGH : USB_PHY_SPEED_FULL)
#else
#define DEFAULT_CPU_FREQ_MHZ 160
#endif
uint32_t SystemCoreClock = (DEFAULT_CPU_FREQ_MHZ * 1000 * 1000);
static usb_phy_handle_t s_phy_handle = NULL;
static intr_handle_t s_interrupt_handle = NULL;
static usb_phy_handle_t s_phy_handle[SOC_USB_OTG_PERIPH_NUM] = {NULL};
static intr_handle_t s_interrupt_handle[SOC_USB_OTG_PERIPH_NUM] = {NULL};
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
const struct dwc2_user_params param_fs = {
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
.device_dma_enable = true,
.device_dma_desc_enable = false,
.device_rx_fifo_size = (200 - 16 * 7),
.device_tx_fifo_size = {
[0] = 16, // 64 byte
[1] = 16, // 64 byte
[2] = 16, // 64 byte
[3] = 16, // 64 byte
[4] = 16, // 64 byte
[5] = 16, // 64 byte
[6] = 16, // 64 byte
[7] = 0,
[8] = 0,
[9] = 0,
[10] = 0,
[11] = 0,
[12] = 0,
[13] = 0,
[14] = 0,
[15] = 0 },
.host_dma_desc_enable = false,
.host_rx_fifo_size = 80,
.host_nperio_tx_fifo_size = 60, // 240 byte
.host_perio_tx_fifo_size = 60, // 240 byte
};
#elif CONFIG_IDF_TARGET_ESP32P4
const struct dwc2_user_params param_fs = {
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
.device_dma_enable = true,
.device_dma_desc_enable = false,
.device_rx_fifo_size = (200 - 16 * 7),
.device_tx_fifo_size = {
[0] = 16, // 64 byte
[1] = 16, // 64 byte
[2] = 16, // 64 byte
[3] = 16, // 64 byte
[4] = 16, // 64 byte
[5] = 16, // 64 byte
[6] = 16, // 64 byte
[7] = 0,
[8] = 0,
[9] = 0,
[10] = 0,
[11] = 0,
[12] = 0,
[13] = 0,
[14] = 0,
[15] = 0 },
.host_dma_desc_enable = false,
.host_rx_fifo_size = (200 - 60 - 60),
.host_nperio_tx_fifo_size = 60, // 240 byte
.host_perio_tx_fifo_size = 60, // 240 byte
};
const struct dwc2_user_params param_hs = {
.phy_type = DWC2_PHY_TYPE_PARAM_UTMI,
.device_dma_enable = true,
.device_dma_desc_enable = false,
.device_rx_fifo_size = (896 - 16 - 128 - 128 - 128 - 128 - 16 - 16),
.device_tx_fifo_size = {
[0] = 16, // 64 byte
[1] = 128, // 512 byte
[2] = 128, // 512 byte
[3] = 128, // 512 byte
[4] = 128, // 512 byte
[5] = 16, // 64 byte
[6] = 16, // 64 byte
[7] = 0,
[8] = 0,
[9] = 0,
[10] = 0,
[11] = 0,
[12] = 0,
[13] = 0,
[14] = 0,
[15] = 0 },
.host_dma_desc_enable = false,
.host_rx_fifo_size = (896 - 128 - 128),
.host_nperio_tx_fifo_size = 128, // 512 byte
.host_perio_tx_fifo_size = 128, // 512 byte
};
#endif
static void usb_dc_interrupt_cb(void *arg_pv)
{
extern void USBD_IRQHandler(uint8_t busid);
USBD_IRQHandler(0);
uint8_t busid = (uintptr_t)arg_pv;
USBD_IRQHandler(busid);
}
void usb_dc_low_level_init(uint8_t busid)
{
esp_err_t ret;
void *reg_base = (void*)g_usbdev_bus[busid].reg_base;
usb_phy_config_t phy_config = {
.controller = USB_PHY_CTRL_OTG,
.otg_mode = USB_OTG_MODE_DEVICE,
#if CONFIG_IDF_TARGET_ESP32P4 // ESP32-P4 has 2 USB-DWC peripherals, each with its dedicated PHY. We support HS+UTMI only ATM.
.target = USB_PHY_TARGET_UTMI,
#else
.target = USB_PHY_TARGET_INT,
#endif
};
phy_config.target = GET_USB_PHY_TARGET(reg_base);
phy_config.otg_speed = GET_USB_PHY_SPEED(reg_base);
esp_err_t ret = usb_new_phy(&phy_config, &s_phy_handle);
ret = usb_new_phy(&phy_config, &s_phy_handle[GET_USB_INDEX(reg_base)]);
if (ret != ESP_OK) {
USB_LOG_ERR("USB Phy Init Failed!\r\n");
return;
}
uintptr_t arg = busid;
// TODO: Check when to enable interrupt
ret = esp_intr_alloc(DEFAULT_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, usb_dc_interrupt_cb, 0, &s_interrupt_handle);
ret = esp_intr_alloc(GET_USB_INTR_SOURCE(reg_base), ESP_INTR_FLAG_LOWMED, usb_dc_interrupt_cb, (void *)arg, &s_interrupt_handle[GET_USB_INDEX(reg_base)]);
if (ret != ESP_OK) {
USB_LOG_ERR("USB Interrupt Init Failed!\r\n");
return;
@ -65,51 +169,46 @@ void usb_dc_low_level_init(uint8_t busid)
void usb_dc_low_level_deinit(uint8_t busid)
{
if (s_interrupt_handle) {
esp_intr_free(s_interrupt_handle);
s_interrupt_handle = NULL;
void *reg_base = (void*)g_usbdev_bus[busid].reg_base;
if (s_interrupt_handle[GET_USB_INDEX(reg_base)]) {
esp_intr_free(s_interrupt_handle[GET_USB_INDEX(reg_base)]);
s_interrupt_handle[GET_USB_INDEX(reg_base)] = NULL;
}
if (s_phy_handle) {
usb_del_phy(s_phy_handle);
s_phy_handle = NULL;
if (s_phy_handle[GET_USB_INDEX(reg_base)]) {
usb_del_phy(s_phy_handle[GET_USB_INDEX(reg_base)]);
s_phy_handle[GET_USB_INDEX(reg_base)] = NULL;
}
}
uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base)
{
return 0;
}
static void usb_hc_interrupt_cb(void *arg_pv)
{
extern void USBH_IRQHandler(uint8_t busid);
USBH_IRQHandler(0);
uint8_t busid = (uintptr_t)arg_pv;
USBH_IRQHandler(busid);
}
void usb_hc_low_level_init(struct usbh_bus *bus)
{
void *reg_base = (void*)bus->hcd.reg_base;
// Host Library defaults to internal PHY
usb_phy_config_t phy_config = {
.controller = USB_PHY_CTRL_OTG,
#if CONFIG_IDF_TARGET_ESP32P4 // ESP32-P4 has 2 USB-DWC peripherals, each with its dedicated PHY. We support HS+UTMI only ATM.
.target = USB_PHY_TARGET_UTMI,
#else
.target = USB_PHY_TARGET_INT,
#endif
.otg_mode = USB_OTG_MODE_HOST,
.otg_speed = USB_PHY_SPEED_UNDEFINED, // In Host mode, the speed is determined by the connected device
.ext_io_conf = NULL,
.otg_io_conf = NULL,
};
phy_config.target = GET_USB_PHY_TARGET(reg_base);
esp_err_t ret = usb_new_phy(&phy_config, &s_phy_handle);
esp_err_t ret = usb_new_phy(&phy_config, &s_phy_handle[GET_USB_INDEX(reg_base)]);
if (ret != ESP_OK) {
USB_LOG_ERR("USB Phy Init Failed!\r\n");
return;
}
uintptr_t arg = bus->busid;
// TODO: Check when to enable interrupt
ret = esp_intr_alloc(DEFAULT_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, usb_hc_interrupt_cb, 0, &s_interrupt_handle);
ret = esp_intr_alloc(GET_USB_INTR_SOURCE(reg_base), ESP_INTR_FLAG_LOWMED, usb_hc_interrupt_cb, (void*)(arg), &s_interrupt_handle[GET_USB_INDEX(reg_base)]);
if (ret != ESP_OK) {
USB_LOG_ERR("USB Interrupt Init Failed!\r\n");
return;
@ -119,19 +218,39 @@ void usb_hc_low_level_init(struct usbh_bus *bus)
void usb_hc_low_level_deinit(struct usbh_bus *bus)
{
if (s_interrupt_handle) {
esp_intr_free(s_interrupt_handle);
s_interrupt_handle = NULL;
void *reg_base = (void*)bus->hcd.reg_base;
if (s_interrupt_handle[GET_USB_INDEX(reg_base)]) {
esp_intr_free(s_interrupt_handle[GET_USB_INDEX(reg_base)]);
s_interrupt_handle[GET_USB_INDEX(reg_base)] = NULL;
}
if (s_phy_handle) {
usb_del_phy(s_phy_handle);
s_phy_handle = NULL;
if (s_phy_handle[GET_USB_INDEX(reg_base)]) {
usb_del_phy(s_phy_handle[GET_USB_INDEX(reg_base)]);
s_phy_handle[GET_USB_INDEX(reg_base)] = NULL;
}
}
uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base)
void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params)
{
return 0;
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
memcpy(params, &param_fs, sizeof(struct dwc2_user_params));
#elif CONFIG_IDF_TARGET_ESP32P4
if (reg_base == ESP_USB_HS0_BASE) {
memcpy(params, &param_hs, sizeof(struct dwc2_user_params));
} else {
memcpy(params, &param_fs, sizeof(struct dwc2_user_params));
}
#endif
#ifdef CONFIG_USB_DWC2_CUSTOM_FIFO
struct usb_dwc2_user_fifo_config s_dwc2_fifo_config;
dwc2_get_user_fifo_config(reg_base, &s_dwc2_fifo_config);
params->device_rx_fifo_size = s_dwc2_fifo_config.device_rx_fifo_size;
for (uint8_t i = 0; i < MAX_EPS_CHANNELS; i++)
{
params->device_tx_fifo_size[i] = s_dwc2_fifo_config.device_tx_fifo_size[i];
}
#endif
}
void usbd_dwc2_delay_ms(uint8_t ms)

View File

@ -7,6 +7,10 @@
#include "stdint.h"
#include "usb_dwc2_reg.h"
#if 1
#error you need to modify some usb register values then use this chip
#endif
#if CONFIG_USBDEV_EP_NUM != 4 && CONFIG_USBDEV_EP_NUM != 6
#error "gd32 only has 4 endpoints for pa11/pa12 and 6 endpoints for pb14/pb15"
#endif

View File

@ -5,22 +5,549 @@
*/
#include "usbd_core.h"
#include "usbh_core.h"
#include "usb_dwc2_param.h"
#ifndef CONFIG_USB_DWC2_CUSTOM_PARAM
#if __has_include("stm32f1xx_hal.h")
#include "stm32f1xx_hal.h"
const struct dwc2_user_params param_pa11_pa12 = {
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
.device_dma_enable = false,
.device_dma_desc_enable = false,
.device_rx_fifo_size = (320 - 16 - 16 - 16 - 16),
.device_tx_fifo_size = {
[0] = 16, // 64 byte
[1] = 16, // 64 byte
[2] = 16, // 64 byte
[3] = 16, // 64 byte
[4] = 0,
[5] = 0,
[6] = 0,
[7] = 0,
[8] = 0,
[9] = 0,
[10] = 0,
[11] = 0,
[12] = 0,
[13] = 0,
[14] = 0,
[15] = 0 },
.device_gccfg = ((1 << 16) | (1 << 21)), // fs: USB_OTG_GCCFG_PWRDWN | USB_OTG_GCCFG_NOVBUSSENS
.total_fifo_size = 320 // 1280 byte
};
const struct dwc2_user_params param_pb14_pb15 = { 0 }; // do not support
#if defined(HAL_HCD_MODULE_ENABLED)
#error "HAL_HCD_MODULE_ENABLED is not supported for STM32F1xx, please use HAL_PCD_MODULE_ENABLED"
#endif
#elif __has_include("stm32f2xx_hal.h")
#include "stm32f2xx_hal.h"
const struct dwc2_user_params param_pa11_pa12 = {
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
.device_dma_enable = false,
.device_dma_desc_enable = false,
.device_rx_fifo_size = (320 - 16 - 16 - 16 - 16),
.device_tx_fifo_size = {
[0] = 16, // 64 byte
[1] = 16, // 64 byte
[2] = 16, // 64 byte
[3] = 16, // 64 byte
[4] = 0,
[5] = 0,
[6] = 0,
[7] = 0,
[8] = 0,
[9] = 0,
[10] = 0,
[11] = 0,
[12] = 0,
[13] = 0,
[14] = 0,
[15] = 0 },
.device_gccfg = ((1 << 16) | (1 << 21)), // fs: USB_OTG_GCCFG_PWRDWN | USB_OTG_GCCFG_NOVBUSSENS
.total_fifo_size = 320 // 1280 byte
};
const struct dwc2_user_params param_pb14_pb15 = {
#ifdef CONFIG_USB_HS
.phy_type = DWC2_PHY_TYPE_PARAM_UTMI,
#else
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
#endif
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
.device_dma_enable = true,
#else
.device_dma_enable = false,
#endif
.device_dma_desc_enable = false,
.device_rx_fifo_size = (1012 - 16 - 256 - 128 - 128 - 128 - 128),
.device_tx_fifo_size = {
[0] = 16, // 64 byte
[1] = 256, // 1024 byte
[2] = 128, // 512 byte
[3] = 128, // 512 byte
[4] = 128, // 512 byte
[5] = 128, // 512 byte
[6] = 0,
[7] = 0,
[8] = 0,
[9] = 0,
[10] = 0,
[11] = 0,
[12] = 0,
[13] = 0,
[14] = 0,
[15] = 0 },
.host_dma_desc_enable = false,
.host_rx_fifo_size = 628,
.host_nperio_tx_fifo_size = 128, // 512 byte
.host_perio_tx_fifo_size = 256, // 1024 byte
#ifdef CONFIG_USB_HS
.device_gccfg = 0,
.host_gccfg = 0,
#else
.device_gccfg = ((1 << 16) | (1 << 21)), // fs: USB_OTG_GCCFG_PWRDWN | USB_OTG_GCCFG_NOVBUSSENS hs:0
.host_gccfg = ((1 << 16) | (1 << 21)) // fs: USB_OTG_GCCFG_PWRDWN | USB_OTG_GCCFG_NOVBUSSENS hs:0
#endif
};
#elif __has_include("stm32f4xx_hal.h")
#include "stm32f4xx_hal.h"
const struct dwc2_user_params param_pa11_pa12 = {
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
.device_dma_enable = false,
.device_dma_desc_enable = false,
.device_rx_fifo_size = (320 - 16 - 16 - 16 - 16),
.device_tx_fifo_size = {
[0] = 16, // 64 byte
[1] = 16, // 64 byte
[2] = 16, // 64 byte
[3] = 16, // 64 byte
[4] = 0,
[5] = 0,
[6] = 0,
[7] = 0,
[8] = 0,
[9] = 0,
[10] = 0,
[11] = 0,
[12] = 0,
[13] = 0,
[14] = 0,
[15] = 0 },
#if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || \
defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || \
defined(STM32F423xx)
.device_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN
.b_session_valid_override = true,
#else
.device_gccfg = ((1 << 16) | (1 << 21)), // fs: USB_OTG_GCCFG_PWRDWN | USB_OTG_GCCFG_NOVBUSSENS
#endif
.total_fifo_size = 320 // 1280 byte
};
const struct dwc2_user_params param_pb14_pb15 = {
#ifdef CONFIG_USB_HS
.phy_type = DWC2_PHY_TYPE_PARAM_UTMI,
#else
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
#endif
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
.device_dma_enable = true,
#else
.device_dma_enable = false,
#endif
.device_dma_desc_enable = false,
.device_rx_fifo_size = (1012 - 16 - 256 - 128 - 128 - 128 - 128),
.device_tx_fifo_size = {
[0] = 16, // 64 byte
[1] = 256, // 1024 byte
[2] = 128, // 512 byte
[3] = 128, // 512 byte
[4] = 128, // 512 byte
[5] = 128, // 512 byte
[6] = 0,
[7] = 0,
[8] = 0,
[9] = 0,
[10] = 0,
[11] = 0,
[12] = 0,
[13] = 0,
[14] = 0,
[15] = 0 },
.host_dma_desc_enable = false,
.host_rx_fifo_size = 628,
.host_nperio_tx_fifo_size = 128, // 512 byte
.host_perio_tx_fifo_size = 256, // 1024 byte
#ifdef CONFIG_USB_HS
.device_gccfg = 0,
.host_gccfg = 0,
#else
#if defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || \
defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || \
defined(STM32F423xx)
.device_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN
.host_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN
.b_session_valid_override = true,
#else
.device_gccfg = ((1 << 16) | (1 << 21)), // fs: USB_OTG_GCCFG_PWRDWN | USB_OTG_GCCFG_NOVBUSSENS hs:0
.host_gccfg = ((1 << 16) | (1 << 21)) // fs: USB_OTG_GCCFG_PWRDWN | USB_OTG_GCCFG_NOVBUSSENS hs:0
#endif
#endif
};
#elif __has_include("stm32f7xx_hal.h")
#include "stm32f7xx_hal.h"
const struct dwc2_user_params param_pa11_pa12 = {
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
.device_dma_enable = false,
.device_dma_desc_enable = false,
.device_rx_fifo_size = (320 - 16 - 16 - 16 - 16),
.device_tx_fifo_size = {
[0] = 16, // 64 byte
[1] = 16, // 64 byte
[2] = 16, // 64 byte
[3] = 16, // 64 byte
[4] = 0,
[5] = 0,
[6] = 0,
[7] = 0,
[8] = 0,
[9] = 0,
[10] = 0,
[11] = 0,
[12] = 0,
[13] = 0,
[14] = 0,
[15] = 0 },
.device_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN
.host_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN
.b_session_valid_override = true,
.total_fifo_size = 320 // 1280 byte
};
const struct dwc2_user_params param_pb14_pb15 = {
#if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F732xx) || defined(STM32F733xx)
.phy_type = DWC2_PHY_TYPE_PARAM_UTMI,
#else
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
#endif
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
.device_dma_enable = true,
#else
.device_dma_enable = false,
#endif
.device_dma_desc_enable = false,
.device_rx_fifo_size = (1006 - 16 - 256 - 128 - 128 - 128 - 128),
.device_tx_fifo_size = {
[0] = 16, // 64 byte
[1] = 256, // 1024 byte
[2] = 128, // 512 byte
[3] = 128, // 512 byte
[4] = 128, // 512 byte
[5] = 128, // 512 byte
[6] = 0,
[7] = 0,
[8] = 0,
[9] = 0,
[10] = 0,
[11] = 0,
[12] = 0,
[13] = 0,
[14] = 0,
[15] = 0 },
.host_dma_desc_enable = false,
.host_rx_fifo_size = 622,
.host_nperio_tx_fifo_size = 128, // 512 byte
.host_perio_tx_fifo_size = 256, // 1024 byte
#if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F732xx) || defined(STM32F733xx)
.device_gccfg = (1 << 23), // USB_OTG_GCCFG_PHYHSEN
.host_gccfg = (1 << 23), // USB_OTG_GCCFG_PHYHSEN
#else
#ifdef CONFIG_USB_HS
.device_gccfg = 0,
.host_gccfg = 0,
#else
.device_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN hs:0
.host_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN hs:0
#endif
#endif
.b_session_valid_override = true
};
#elif __has_include("stm32h7xx_hal.h")
#include "stm32h7xx_hal.h"
const struct dwc2_user_params param_pa11_pa12 = {
.phy_type = DWC2_PHY_TYPE_PARAM_FS, // DWC2_PHY_TYPE_PARAM_UTMI
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
.device_dma_enable = true,
#else
.device_dma_enable = false,
#endif
.device_dma_desc_enable = false,
.device_rx_fifo_size = (952 - 16 - 256 - 128 - 128 - 128 - 128),
.device_tx_fifo_size = {
[0] = 16, // 64 byte
[1] = 256, // 1024 byte
[2] = 128, // 512 byte
[3] = 128, // 512 byte
[4] = 128, // 512 byte
[5] = 128, // 512 byte
[6] = 0,
[7] = 0,
[8] = 0,
[9] = 0,
[10] = 0,
[11] = 0,
[12] = 0,
[13] = 0,
[14] = 0,
[15] = 0 },
.host_dma_desc_enable = false,
.host_rx_fifo_size = 568,
.host_nperio_tx_fifo_size = 128, // 512 byte
.host_perio_tx_fifo_size = 256, // 1024 byte
.device_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN hs:0
.host_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN hs:0
.b_session_valid_override = true
};
const struct dwc2_user_params param_pb14_pb15 = {
#ifdef CONFIG_USB_HS
.phy_type = DWC2_PHY_TYPE_PARAM_UTMI,
#else
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
#endif
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
.device_dma_enable = true,
#else
.device_dma_enable = false,
#endif
.device_dma_desc_enable = false,
.device_rx_fifo_size = (952 - 16 - 256 - 128 - 128 - 128 - 128),
.device_tx_fifo_size = {
[0] = 16, // 64 byte
[1] = 256, // 1024 byte
[2] = 128, // 512 byte
[3] = 128, // 512 byte
[4] = 128, // 512 byte
[5] = 128, // 512 byte
[6] = 0,
[7] = 0,
[8] = 0,
[9] = 0,
[10] = 0,
[11] = 0,
[12] = 0,
[13] = 0,
[14] = 0,
[15] = 0 },
.host_dma_desc_enable = false,
.host_rx_fifo_size = 568,
.host_nperio_tx_fifo_size = 128, // 512 byte
.host_perio_tx_fifo_size = 256, // 1024 byte
#ifdef CONFIG_USB_HS
.device_gccfg = 0,
.host_gccfg = 0,
#else
.device_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN hs:0
.host_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN hs:0
#endif
.b_session_valid_override = true
};
#elif __has_include("stm32h7rsxx_hal.h")
#include "stm32h7rsxx_hal.h"
const struct dwc2_user_params param_pa11_pa12 = {
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
.device_dma_enable = false,
.device_dma_desc_enable = false,
.device_rx_fifo_size = (320 - 16 - 16 - 16 - 16),
.device_tx_fifo_size = {
[0] = 16, // 64 byte
[1] = 16, // 64 byte
[2] = 16, // 64 byte
[3] = 16, // 64 byte
[4] = 0,
[5] = 0,
[6] = 0,
[7] = 0,
[8] = 0,
[9] = 0,
[10] = 0,
[11] = 0,
[12] = 0,
[13] = 0,
[14] = 0,
[15] = 0 },
.device_gccfg = (1 << 16), // fs: USB_OTG_GCCFG_PWRDWN
.b_session_valid_override = true,
.total_fifo_size = 320 // 1280 byte
};
const struct dwc2_user_params param_pb14_pb15 = {
.phy_type = DWC2_PHY_TYPE_PARAM_UTMI,
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
.device_dma_enable = true,
#else
.device_dma_enable = false,
#endif
.device_dma_desc_enable = false,
.device_rx_fifo_size = (952 - 16 - 256 - 128 - 128 - 128 - 128),
.device_tx_fifo_size = {
[0] = 16, // 64 byte
[1] = 256, // 1024 byte
[2] = 128, // 512 byte
[3] = 128, // 512 byte
[4] = 128, // 512 byte
[5] = 128, // 512 byte
[6] = 0,
[7] = 0,
[8] = 0,
[9] = 0,
[10] = 0,
[11] = 0,
[12] = 0,
[13] = 0,
[14] = 0,
[15] = 0 },
.host_dma_desc_enable = false,
.host_rx_fifo_size = 568,
.host_nperio_tx_fifo_size = 128, // 512 byte
.host_perio_tx_fifo_size = 256, // 1024 byte
.device_gccfg = ((1 << 23) | (1 << 24)), // hs: USB_OTG_GCCFG_VBVALEXTOEN | USB_OTG_GCCFG_VBVALOVAL
.host_gccfg = (1 << 25) // hs: USB_OTG_GCCFG_PULLDOWNEN
};
#elif __has_include("stm32l4xx_hal.h")
#include "stm32l4xx_hal.h"
const struct dwc2_user_params param_pa11_pa12 = {
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
.device_dma_enable = false,
.device_dma_desc_enable = false,
.device_rx_fifo_size = (320 - 16 - 16 - 16 - 16),
.device_tx_fifo_size = {
[0] = 16, // 64 byte
[1] = 16, // 64 byte
[2] = 16, // 64 byte
[3] = 16, // 64 byte
[4] = 0,
[5] = 0,
[6] = 0,
[7] = 0,
[8] = 0,
[9] = 0,
[10] = 0,
[11] = 0,
[12] = 0,
[13] = 0,
[14] = 0,
[15] = 0 },
.device_gccfg = (1 << 16),
.b_session_valid_override = true,
.total_fifo_size = 320 // 1280 byte
};
const struct dwc2_user_params param_pb14_pb15 = { 0 }; // do not support
#if defined(HAL_HCD_MODULE_ENABLED)
#error "HAL_HCD_MODULE_ENABLED is not supported for STM32L4xx, please use HAL_PCD_MODULE_ENABLED"
#endif
#elif __has_include("stm32u5xx_hal.h")
#include "stm32u5xx_hal.h"
const struct dwc2_user_params param_pa11_pa12 = {
.phy_type = DWC2_PHY_TYPE_PARAM_FS,
.device_dma_enable = false,
.device_dma_desc_enable = false,
.device_rx_fifo_size = (320 - 16 - 16 - 16 - 16),
.device_tx_fifo_size = {
[0] = 16, // 64 byte
[1] = 16, // 64 byte
[2] = 16, // 64 byte
[3] = 16, // 64 byte
[4] = 0,
[5] = 0,
[6] = 0,
[7] = 0,
[8] = 0,
[9] = 0,
[10] = 0,
[11] = 0,
[12] = 0,
[13] = 0,
[14] = 0,
[15] = 0 },
.device_gccfg = (1 << 16),
.b_session_valid_override = true,
.total_fifo_size = 320 // 1280 byte
};
#if defined(STM32U595xx) || defined(STM32U5A5xx) || defined(STM32U599xx) || defined(STM32U5A9xx) || \
defined(STM32U5F7xx) || defined(STM32U5G7xx) || defined(STM32U5F9xx) || defined(STM32U5G9xx)
const struct dwc2_user_params param_pb14_pb15 = {
.phy_type = DWC2_PHY_TYPE_PARAM_UTMI,
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
.device_dma_enable = true,
#else
.device_dma_enable = false,
#endif
.device_dma_desc_enable = false,
.device_rx_fifo_size = (952 - 16 - 256 - 128 - 128 - 128 - 128),
.device_tx_fifo_size = {
[0] = 16, // 64 byte
[1] = 256, // 1024 byte
[2] = 128, // 512 byte
[3] = 128, // 512 byte
[4] = 128, // 512 byte
[5] = 128, // 512 byte
[6] = 0,
[7] = 0,
[8] = 0,
[9] = 0,
[10] = 0,
[11] = 0,
[12] = 0,
[13] = 0,
[14] = 0,
[15] = 0 },
.host_dma_desc_enable = false,
.host_rx_fifo_size = 568,
.host_nperio_tx_fifo_size = 128, // 512 byte
.host_perio_tx_fifo_size = 256, // 1024 byte
.device_gccfg = ((1 << 23) | (1 << 24)), // hs: USB_OTG_GCCFG_VBVALEXTOEN | USB_OTG_GCCFG_VBVALOVAL
.host_gccfg = (1 << 25) // hs: USB_OTG_GCCFG_PULLDOWNEN
};
#else
const struct dwc2_user_params param_pb14_pb15 = { 0 }; // do not support
#endif
#endif
#endif // CONFIG_USB_DWC2_CUSTOM_PARAM
#if !defined(HAL_HCD_MODULE_ENABLED) && !defined(HAL_PCD_MODULE_ENABLED)
#error please define HAL_HCD_MODULE_ENABLED or HAL_PCD_MODULE_ENABLED in stm32xxx_hal_conf.h
@ -36,74 +563,6 @@ static usb_dwc2_irq g_usb_dwc2_irq[2];
static uint8_t g_usb_dwc2_busid[2] = { 0, 0 };
static struct dwc2_instance g_dwc2_instance;
#ifdef HAL_PCD_MODULE_ENABLED
void usb_dc_low_level_init(uint8_t busid)
{
if (g_usbdev_bus[busid].reg_base == 0x40040000UL) { // USB_OTG_HS_PERIPH_BASE
g_usb_dwc2_busid[1] = busid;
g_usb_dwc2_irq[1] = USBD_IRQHandler;
} else {
g_usb_dwc2_busid[0] = busid;
g_usb_dwc2_irq[0] = USBD_IRQHandler;
}
g_dwc2_instance.Instance = (USB_OTG_GlobalTypeDef *)g_usbdev_bus[busid].reg_base;
HAL_PCD_MspInit((PCD_HandleTypeDef *)&g_dwc2_instance);
}
void usb_dc_low_level_deinit(uint8_t busid)
{
if (g_usbdev_bus[busid].reg_base == 0x40040000UL) { // USB_OTG_HS_PERIPH_BASE
g_usb_dwc2_busid[1] = 0;
g_usb_dwc2_irq[1] = NULL;
} else {
g_usb_dwc2_busid[0] = 0;
g_usb_dwc2_irq[0] = NULL;
}
g_dwc2_instance.Instance = (USB_OTG_GlobalTypeDef *)g_usbdev_bus[busid].reg_base;
HAL_PCD_MspDeInit((PCD_HandleTypeDef *)&g_dwc2_instance);
}
#endif
#ifdef HAL_HCD_MODULE_ENABLED
void usb_hc_low_level_init(struct usbh_bus *bus)
{
if (bus->hcd.reg_base == 0x40040000UL) { // USB_OTG_HS_PERIPH_BASE
g_usb_dwc2_busid[1] = bus->hcd.hcd_id;
g_usb_dwc2_irq[1] = USBH_IRQHandler;
} else {
g_usb_dwc2_busid[0] = bus->hcd.hcd_id;
g_usb_dwc2_irq[0] = USBH_IRQHandler;
}
g_dwc2_instance.Instance = (USB_OTG_GlobalTypeDef *)bus->hcd.reg_base;
HAL_HCD_MspInit((HCD_HandleTypeDef *)&g_dwc2_instance);
}
void usb_hc_low_level_deinit(struct usbh_bus *bus)
{
if (bus->hcd.reg_base == 0x40040000UL) { // USB_OTG_HS_PERIPH_BASE
g_usb_dwc2_busid[1] = 0;
g_usb_dwc2_irq[1] = NULL;
} else {
g_usb_dwc2_busid[0] = 0;
g_usb_dwc2_irq[0] = NULL;
}
g_dwc2_instance.Instance = (USB_OTG_GlobalTypeDef *)bus->hcd.reg_base;
HAL_HCD_MspDeInit((HCD_HandleTypeDef *)&g_dwc2_instance);
}
#endif
/* you can find this config in function: USB_DevInit, file:stm32xxx_ll_usb.c, for example:
*
* USBx->GCCFG |= USB_OTG_GCCFG_PWRDWN;
* USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS;
* USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN;
* USBx->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN;
*
*/
#if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F732xx) || defined(STM32F733xx)
/**
* @brief Enables control of a High Speed USB PHY
@ -163,62 +622,96 @@ static int usb_hsphy_init(uint32_t hse_value)
}
#endif
uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base)
#ifdef HAL_PCD_MODULE_ENABLED
void usb_dc_low_level_init(uint8_t busid)
{
#if __has_include("stm32h7xx.h") || __has_include("stm32f7xx.h") || __has_include("stm32l4xx.h")
#define USB_OTG_GLB ((USB_OTG_GlobalTypeDef *)(reg_base))
/* B-peripheral session valid override enable */
USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN;
USB_OTG_GLB->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL;
#endif
if (g_usbdev_bus[busid].reg_base == 0x40040000UL) { // USB_OTG_HS_PERIPH_BASE
g_usb_dwc2_busid[1] = busid;
g_usb_dwc2_irq[1] = USBD_IRQHandler;
} else {
g_usb_dwc2_busid[0] = busid;
g_usb_dwc2_irq[0] = USBD_IRQHandler;
}
g_dwc2_instance.Instance = (USB_OTG_GlobalTypeDef *)g_usbdev_bus[busid].reg_base;
HAL_PCD_MspInit((PCD_HandleTypeDef *)&g_dwc2_instance);
#ifdef CONFIG_USB_HS
#if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F732xx) || defined(STM32F733xx)
USB_OTG_GLB->GCCFG = (1 << 23);
usb_hsphy_init(25000000U);
return (1 << 23); /* Enable USB HS PHY USBx->GCCFG |= USB_OTG_GCCFG_PHYHSEN;*/
#elif __has_include("stm32h7rsxx.h")
return ((1 << 23) | (1 << 24));
#else
return 0;
#endif
#else
#if __has_include("stm32h7xx.h") || __has_include("stm32f7xx.h") || __has_include("stm32l4xx.h")
return (1 << 16);
#else
return ((1 << 16) | (1 << 21));
#endif
#endif
}
uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base)
void usb_dc_low_level_deinit(uint8_t busid)
{
#if __has_include("stm32h7xx.h") || __has_include("stm32f7xx.h") || __has_include("stm32l4xx.h")
#define USB_OTG_GLB ((USB_OTG_GlobalTypeDef *)(reg_base))
/* B-peripheral session valid override enable */
USB_OTG_GLB->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOEN;
USB_OTG_GLB->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOVAL;
if (g_usbdev_bus[busid].reg_base == 0x40040000UL) { // USB_OTG_HS_PERIPH_BASE
g_usb_dwc2_busid[1] = 0;
g_usb_dwc2_irq[1] = NULL;
} else {
g_usb_dwc2_busid[0] = 0;
g_usb_dwc2_irq[0] = NULL;
}
g_dwc2_instance.Instance = (USB_OTG_GlobalTypeDef *)g_usbdev_bus[busid].reg_base;
HAL_PCD_MspDeInit((PCD_HandleTypeDef *)&g_dwc2_instance);
}
#endif
#ifdef CONFIG_USB_HS
#ifdef HAL_HCD_MODULE_ENABLED
void usb_hc_low_level_init(struct usbh_bus *bus)
{
if (bus->hcd.reg_base == 0x40040000UL) { // USB_OTG_HS_PERIPH_BASE
g_usb_dwc2_busid[1] = bus->hcd.hcd_id;
g_usb_dwc2_irq[1] = USBH_IRQHandler;
} else {
g_usb_dwc2_busid[0] = bus->hcd.hcd_id;
g_usb_dwc2_irq[0] = USBH_IRQHandler;
}
g_dwc2_instance.Instance = (USB_OTG_GlobalTypeDef *)bus->hcd.reg_base;
HAL_HCD_MspInit((HCD_HandleTypeDef *)&g_dwc2_instance);
#if defined(STM32F722xx) || defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F732xx) || defined(STM32F733xx)
USB_OTG_GLB->GCCFG = (1 << 23);
usb_hsphy_init(25000000U);
return (1 << 23); /* Enable USB HS PHY USBx->GCCFG |= USB_OTG_GCCFG_PHYHSEN;*/
#elif __has_include("stm32h7rsxx.h")
return (1 << 25);
#else
return 0;
#endif
#else
#if __has_include("stm32h7xx.h") || __has_include("stm32f7xx.h") || __has_include("stm32l4xx.h")
return (1 << 16);
#else
return ((1 << 16) | (1 << 21));
#endif
#endif
}
void usb_hc_low_level_deinit(struct usbh_bus *bus)
{
if (bus->hcd.reg_base == 0x40040000UL) { // USB_OTG_HS_PERIPH_BASE
g_usb_dwc2_busid[1] = 0;
g_usb_dwc2_irq[1] = NULL;
} else {
g_usb_dwc2_busid[0] = 0;
g_usb_dwc2_irq[0] = NULL;
}
g_dwc2_instance.Instance = (USB_OTG_GlobalTypeDef *)bus->hcd.reg_base;
HAL_HCD_MspDeInit((HCD_HandleTypeDef *)&g_dwc2_instance);
}
#endif
#ifndef CONFIG_USB_DWC2_CUSTOM_PARAM
void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params)
{
if (reg_base == 0x40040000UL) { // USB_OTG_HS_PERIPH_BASE
memcpy(params, &param_pb14_pb15, sizeof(struct dwc2_user_params));
} else {
memcpy(params, &param_pa11_pa12, sizeof(struct dwc2_user_params));
}
#ifdef CONFIG_USB_DWC2_CUSTOM_FIFO
struct usb_dwc2_user_fifo_config s_dwc2_fifo_config;
dwc2_get_user_fifo_config(reg_base, &s_dwc2_fifo_config);
params->device_rx_fifo_size = s_dwc2_fifo_config.device_rx_fifo_size;
for (uint8_t i = 0; i < MAX_EPS_CHANNELS; i++)
{
params->device_tx_fifo_size[i] = s_dwc2_fifo_config.device_tx_fifo_size[i];
}
#endif
}
#endif
extern uint32_t SystemCoreClock;
void usbd_dwc2_delay_ms(uint8_t ms)

View File

@ -6,28 +6,7 @@
#include "usbh_core.h"
#include "usbh_hub.h"
#include "usb_dwc2_reg.h"
#ifndef CONFIG_USBHOST_PIPE_NUM
#define CONFIG_USBHOST_PIPE_NUM 12
#endif
/* largest non-periodic USB packet used / 4 */
#ifndef CONFIG_USB_DWC2_NPTX_FIFO_SIZE
#define CONFIG_USB_DWC2_NPTX_FIFO_SIZE (512 / 4)
#endif
/* largest periodic USB packet used / 4 */
#ifndef CONFIG_USB_DWC2_PTX_FIFO_SIZE
#define CONFIG_USB_DWC2_PTX_FIFO_SIZE (1024 / 4)
#endif
/*
* (largest USB packet used / 4) + 1 for status information + 1 transfer complete +
* 1 location each for Bulk/Control endpoint for handling NAK/NYET scenario
*/
#ifndef CONFIG_USB_DWC2_RX_FIFO_SIZE
#define CONFIG_USB_DWC2_RX_FIFO_SIZE ((1012 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE))
#endif
#include "usb_dwc2_param.h"
#define USB_OTG_GLB ((DWC2_GlobalTypeDef *)(bus->hcd.reg_base))
#define USB_OTG_PCGCCTL *(__IO uint32_t *)((uint32_t)bus->hcd.reg_base + USB_OTG_PCGCCTL_BASE)
@ -56,8 +35,9 @@ struct dwc2_hcd {
volatile bool port_csc;
volatile bool port_pec;
volatile bool port_occ;
uint32_t GSNPSID;
struct dwc2_chan chan_pool[CONFIG_USBHOST_PIPE_NUM];
struct dwc2_hw_params hw_params;
struct dwc2_user_params user_params;
struct dwc2_chan chan_pool[16];
} g_dwc2_hcd[CONFIG_USBHOST_MAX_BUS];
#define DWC2_EP0_STATE_SETUP 0
@ -81,7 +61,7 @@ static inline int dwc2_reset(struct usbh_bus *bus)
count = 0U;
USB_OTG_GLB->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
if (g_dwc2_hcd[bus->hcd.hcd_id].GSNPSID < 0x4F54420AU) {
if (g_dwc2_hcd[bus->hcd.hcd_id].hw_params.snpsid < 0x4F54420AU) {
do {
if (++count > 200000U) {
USB_LOG_ERR("DWC2 reset timeout\r\n");
@ -106,22 +86,43 @@ static inline int dwc2_reset(struct usbh_bus *bus)
static inline int dwc2_core_init(struct usbh_bus *bus)
{
int ret;
#if defined(CONFIG_USB_HS)
/* Init The ULPI Interface */
USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
uint32_t regval;
/* Select vbus source */
USB_OTG_GLB->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
//USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
/* Reset after a PHY select */
ret = dwc2_reset(bus);
#else
if (g_dwc2_hcd[bus->hcd.hcd_id].user_params.phy_type == DWC2_PHY_TYPE_PARAM_FS) {
/* Select FS Embedded PHY */
USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
} else {
regval = USB_OTG_GLB->GUSBCFG;
regval &= ~USB_OTG_GUSBCFG_PHYSEL;
/* disable external vbus source */
regval &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
/* disable ULPI FS/LS */
regval &= ~(USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_ULPICSM);
switch (g_dwc2_hcd[bus->hcd.hcd_id].user_params.phy_type) {
case DWC2_PHY_TYPE_PARAM_ULPI:
regval |= USB_OTG_GUSBCFG_ULPI_UTMI_SEL;
regval &= ~USB_OTG_GUSBCFG_PHYIF16;
regval &= ~USB_OTG_GUSBCFG_DDR_SEL;
break;
case DWC2_PHY_TYPE_PARAM_UTMI:
regval &= ~USB_OTG_GUSBCFG_ULPI_UTMI_SEL;
regval &= ~USB_OTG_GUSBCFG_PHYIF16;
if (g_dwc2_hcd[bus->hcd.hcd_id].user_params.phy_utmi_width == 16) {
regval |= USB_OTG_GUSBCFG_PHYIF16;
}
break;
default:
break;
}
USB_OTG_GLB->GUSBCFG = regval;
}
/* Reset after a PHY select */
ret = dwc2_reset(bus);
#endif
return ret;
}
@ -390,13 +391,60 @@ static inline uint16_t dwc2_get_full_frame_num(struct usbh_bus *bus)
return ((frame & 0x3FFF) >> 3);
}
/**
* dwc2_calc_frame_interval() - Calculates the correct frame Interval value for
* the HFIR register according to PHY type and speed
*
* NOTE: The caller can modify the value of the HFIR register only after the
* Port Enable bit of the Host Port Control and Status register (HPRT.EnaPort)
* has been set
*/
uint32_t dwc2_calc_frame_interval(struct usbh_bus *bus)
{
uint32_t usbcfg;
uint32_t hprt0;
int clock = 60; /* default value */
usbcfg = USB_OTG_GLB->GUSBCFG;
hprt0 = USB_OTG_HPRT;
if (!(usbcfg & USB_OTG_GUSBCFG_PHYSEL) && (usbcfg & USB_OTG_GUSBCFG_ULPI_UTMI_SEL) &&
!(usbcfg & USB_OTG_GUSBCFG_PHYIF16))
clock = 60;
if ((usbcfg & USB_OTG_GUSBCFG_PHYSEL) && g_dwc2_hcd[bus->hcd.hcd_id].hw_params.fs_phy_type ==
GHWCFG2_FS_PHY_TYPE_SHARED_ULPI)
clock = 48;
if (!(usbcfg & USB_OTG_GUSBCFG_PHYLPCS) && !(usbcfg & USB_OTG_GUSBCFG_PHYSEL) &&
!(usbcfg & USB_OTG_GUSBCFG_ULPI_UTMI_SEL) && (usbcfg & USB_OTG_GUSBCFG_PHYIF16))
clock = 30;
if (!(usbcfg & USB_OTG_GUSBCFG_PHYLPCS) && !(usbcfg & USB_OTG_GUSBCFG_PHYSEL) &&
!(usbcfg & USB_OTG_GUSBCFG_ULPI_UTMI_SEL) && !(usbcfg & USB_OTG_GUSBCFG_PHYIF16))
clock = 60;
if ((usbcfg & USB_OTG_GUSBCFG_PHYLPCS) && !(usbcfg & USB_OTG_GUSBCFG_PHYSEL) &&
!(usbcfg & USB_OTG_GUSBCFG_ULPI_UTMI_SEL) && (usbcfg & USB_OTG_GUSBCFG_PHYIF16))
clock = 48;
if ((usbcfg & USB_OTG_GUSBCFG_PHYSEL) && !(usbcfg & USB_OTG_GUSBCFG_PHYIF16) &&
g_dwc2_hcd[bus->hcd.hcd_id].hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_SHARED_UTMI)
clock = 48;
if ((usbcfg & USB_OTG_GUSBCFG_PHYSEL) &&
g_dwc2_hcd[bus->hcd.hcd_id].hw_params.fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED)
clock = 48;
if ((hprt0 & USB_OTG_HPRT_PSPD) >> USB_OTG_HPRT_PSPD_Pos == HPRT0_PRTSPD_HIGH_SPEED)
/* High speed case */
return 125 * clock - 1;
/* FS/LS case */
return 1000 * clock - 1;
}
static int dwc2_chan_alloc(struct usbh_bus *bus)
{
size_t flags;
int chidx;
flags = usb_osal_enter_critical_section();
for (chidx = 0; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) {
for (chidx = 0; chidx < g_dwc2_hcd[bus->hcd.hcd_id].hw_params.host_channels; chidx++) {
if (!g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx].inuse) {
g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx].inuse = true;
usb_osal_leave_critical_section(flags);
@ -544,18 +592,11 @@ __WEAK void usb_hc_low_level_deinit(struct usbh_bus *bus)
int usb_hc_init(struct usbh_bus *bus)
{
int ret;
uint8_t channels;
memset(&g_dwc2_hcd[bus->hcd.hcd_id], 0, sizeof(struct dwc2_hcd));
for (uint8_t chidx = 0; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) {
g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx].waitsem = usb_osal_sem_create(0);
}
usb_hc_low_level_init(bus);
channels = ((USB_OTG_GLB->GHWCFG2 & (0x0f << 14)) >> 14) + 1;
USB_LOG_INFO("========== dwc2 hcd params ==========\r\n");
USB_LOG_INFO("CID:%08x\r\n", (unsigned int)USB_OTG_GLB->CID);
USB_LOG_INFO("GSNPSID:%08x\r\n", (unsigned int)USB_OTG_GLB->GSNPSID);
@ -564,34 +605,70 @@ int usb_hc_init(struct usbh_bus *bus)
USB_LOG_INFO("GHWCFG3:%08x\r\n", (unsigned int)USB_OTG_GLB->GHWCFG3);
USB_LOG_INFO("GHWCFG4:%08x\r\n", (unsigned int)USB_OTG_GLB->GHWCFG4);
USB_LOG_INFO("dwc2 has %d channels and dfifo depth(32-bit words) is %d\r\n", channels, (USB_OTG_GLB->GHWCFG3 >> 16));
dwc2_get_hwparams(bus->hcd.reg_base, &g_dwc2_hcd[bus->hcd.hcd_id].hw_params);
dwc2_get_user_params(bus->hcd.reg_base, &g_dwc2_hcd[bus->hcd.hcd_id].user_params);
USB_ASSERT_MSG(((USB_OTG_GLB->GHWCFG2 & (0x3U << 3)) >> 3) == 2, "This dwc2 version does not support dma mode, so stop working");
USB_ASSERT_MSG(channels >= CONFIG_USBHOST_PIPE_NUM, "dwc2 has less channels than config, please check");
USB_ASSERT_MSG((CONFIG_USB_DWC2_RX_FIFO_SIZE + CONFIG_USB_DWC2_NPTX_FIFO_SIZE + CONFIG_USB_DWC2_PTX_FIFO_SIZE) <= (USB_OTG_GLB->GHWCFG3 >> 16),
if (g_dwc2_hcd[bus->hcd.hcd_id].user_params.phy_utmi_width == 0) {
g_dwc2_hcd[bus->hcd.hcd_id].user_params.phy_utmi_width = 8;
}
if (g_dwc2_hcd[bus->hcd.hcd_id].user_params.total_fifo_size == 0) {
g_dwc2_hcd[bus->hcd.hcd_id].user_params.total_fifo_size = g_dwc2_hcd[bus->hcd.hcd_id].hw_params.total_fifo_size;
}
for (uint8_t chidx = 0; chidx < g_dwc2_hcd[bus->hcd.hcd_id].hw_params.host_channels; chidx++) {
g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx].waitsem = usb_osal_sem_create(0);
}
USB_LOG_INFO("dwc2 has %d channels and dfifo depth(32-bit words) is %d\r\n",
g_dwc2_hcd[bus->hcd.hcd_id].hw_params.host_channels,
g_dwc2_hcd[bus->hcd.hcd_id].user_params.total_fifo_size);
USB_ASSERT_MSG(g_dwc2_hcd[bus->hcd.hcd_id].hw_params.arch == GHWCFG2_INT_DMA_ARCH, "This dwc2 version does not support dma mode, so stop working");
USB_ASSERT_MSG((g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_rx_fifo_size +
g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_nperio_tx_fifo_size +
g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_perio_tx_fifo_size) <=
g_dwc2_hcd[bus->hcd.hcd_id].user_params.total_fifo_size,
"Your fifo config is overflow, please check");
g_dwc2_hcd[bus->hcd.hcd_id].GSNPSID = USB_OTG_GLB->GSNPSID;
USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
/* This is vendor register */
USB_OTG_GLB->GCCFG = usbh_get_dwc2_gccfg_conf(bus->hcd.reg_base);
USB_OTG_GLB->GCCFG = g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_gccfg;
if (g_dwc2_hcd[bus->hcd.hcd_id].user_params.phy_type != DWC2_PHY_TYPE_PARAM_FS) {
USB_ASSERT_MSG(g_dwc2_hcd[bus->hcd.hcd_id].hw_params.hs_phy_type != 0, "This dwc2 version does not support hs, so stop working");
}
ret = dwc2_core_init(bus);
/* Force Host Mode*/
dwc2_set_mode(bus, USB_OTG_MODE_HOST);
usb_osal_msleep(50);
/* B-peripheral session valid override enable */
USB_OTG_GLB->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOEN;
USB_OTG_GLB->GOTGCTL &= ~USB_OTG_GOTGCTL_BVALOVAL;
USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_TOCAL;
/* Restart the Phy Clock */
USB_OTG_PCGCCTL = 0U;
/* Set default Max speed support */
USB_OTG_HOST->HCFG &= ~(USB_OTG_HCFG_FSLSS);
USB_OTG_HOST->HCFG &= ~USB_OTG_HCFG_FSLSS;
USB_OTG_HOST->HCFG &= ~USB_OTG_HCFG_FSLSPCS;
if (g_dwc2_hcd[bus->hcd.hcd_id].user_params.phy_type == DWC2_PHY_TYPE_PARAM_FS) {
USB_OTG_HOST->HCFG |= USB_OTG_HCFG_FSLSPCLKSEL_48_MHZ;
} else {
USB_OTG_HOST->HCFG |= USB_OTG_HCFG_FSLSPCLKSEL_30_60_MHZ;
}
if (g_dwc2_hcd[bus->hcd.hcd_id].hw_params.snpsid > 0x4F54292AU) {
USB_OTG_HOST->HCFG |= USB_OTG_HFIR_RELOAD_CTRL;
}
/* Clear all pending HC Interrupts */
for (uint8_t i = 0U; i < CONFIG_USBHOST_PIPE_NUM; i++) {
for (uint8_t i = 0U; i < g_dwc2_hcd[bus->hcd.hcd_id].hw_params.host_channels; i++) {
USB_OTG_HC(i)->HCINT = 0xFFFFFFFFU;
USB_OTG_HC(i)->HCINTMSK = 0U;
}
@ -603,9 +680,11 @@ int usb_hc_init(struct usbh_bus *bus)
USB_OTG_GLB->GINTSTS = 0xFFFFFFFFU;
/* set Rx FIFO size */
USB_OTG_GLB->GRXFSIZ = CONFIG_USB_DWC2_RX_FIFO_SIZE;
USB_OTG_GLB->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((CONFIG_USB_DWC2_NPTX_FIFO_SIZE << 16) & USB_OTG_NPTXFD) | CONFIG_USB_DWC2_RX_FIFO_SIZE);
USB_OTG_GLB->HPTXFSIZ = (uint32_t)(((CONFIG_USB_DWC2_PTX_FIFO_SIZE << 16) & USB_OTG_HPTXFSIZ_PTXFD) | (CONFIG_USB_DWC2_RX_FIFO_SIZE + CONFIG_USB_DWC2_NPTX_FIFO_SIZE));
USB_OTG_GLB->GRXFSIZ = g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_rx_fifo_size;
USB_OTG_GLB->DIEPTXF0_HNPTXFSIZ = (uint32_t)(((g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_nperio_tx_fifo_size << 16) & USB_OTG_NPTXFD) |
g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_rx_fifo_size);
USB_OTG_GLB->HPTXFSIZ = (uint32_t)(((g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_perio_tx_fifo_size << 16) & USB_OTG_HPTXFSIZ_PTXFD) |
(g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_rx_fifo_size + g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_nperio_tx_fifo_size));
ret = dwc2_flush_txfifo(bus, 0x10U);
ret = dwc2_flush_rxfifo(bus);
@ -637,7 +716,7 @@ int usb_hc_deinit(struct usbh_bus *bus)
dwc2_flush_rxfifo(bus);
/* Flush out any leftover queued requests. */
for (uint32_t i = 0U; i <= 15U; i++) {
for (uint32_t i = 0U; i < g_dwc2_hcd[bus->hcd.hcd_id].hw_params.host_channels; i++) {
value = USB_OTG_HC(i)->HCCHAR;
value |= USB_OTG_HCCHAR_CHDIS;
value &= ~USB_OTG_HCCHAR_CHENA;
@ -646,7 +725,7 @@ int usb_hc_deinit(struct usbh_bus *bus)
}
/* Halt all channels to put them into a known state. */
for (uint32_t i = 0U; i <= 15U; i++) {
for (uint32_t i = 0U; i < g_dwc2_hcd[bus->hcd.hcd_id].hw_params.host_channels; i++) {
value = USB_OTG_HC(i)->HCCHAR;
value |= USB_OTG_HCCHAR_CHDIS;
value |= USB_OTG_HCCHAR_CHENA;
@ -670,7 +749,7 @@ int usb_hc_deinit(struct usbh_bus *bus)
dwc2_drivebus(bus, 0);
usb_osal_msleep(200);
for (uint8_t chidx = 0; chidx < CONFIG_USBHOST_PIPE_NUM; chidx++) {
for (uint8_t chidx = 0; chidx < g_dwc2_hcd[bus->hcd.hcd_id].hw_params.host_channels; chidx++) {
usb_osal_sem_delete(g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[chidx].waitsem);
}
@ -858,18 +937,18 @@ int usbh_submit_urb(struct usbh_urb *urb)
if (urb->ep->bEndpointAddress & 0x80) {
/* Check if pipe rx fifo is overflow */
if (USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) > (CONFIG_USB_DWC2_RX_FIFO_SIZE * 4)) {
if (USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) > (g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_rx_fifo_size * 4)) {
return -USB_ERR_RANGE;
}
} else {
/* Check if intr and iso pipe tx fifo is overflow */
if (((USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_ISOCHRONOUS) ||
(USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_INTERRUPT)) &&
USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) > (CONFIG_USB_DWC2_PTX_FIFO_SIZE * 4)) {
USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) > (g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_perio_tx_fifo_size * 4)) {
return -USB_ERR_RANGE;
} else {
/* Check if control and bulk pipe tx fifo is overflow */
if (USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) > (CONFIG_USB_DWC2_NPTX_FIFO_SIZE * 4)) {
if (USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) > (g_dwc2_hcd[bus->hcd.hcd_id].user_params.host_nperio_tx_fifo_size * 4)) {
return -USB_ERR_RANGE;
}
}
@ -1297,7 +1376,7 @@ static void dwc2_outchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num)
static void dwc2_port_irq_handler(struct usbh_bus *bus)
{
__IO uint32_t hprt0, hprt0_dup;
__IO uint32_t hprt0, hprt0_dup, regval;
/* Handle Host Port Interrupts */
hprt0 = USB_OTG_HPRT;
@ -1322,26 +1401,28 @@ static void dwc2_port_irq_handler(struct usbh_bus *bus)
g_dwc2_hcd[bus->hcd.hcd_id].port_pec = 1;
if ((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA) {
#if defined(CONFIG_USB_HS)
#else
regval = USB_OTG_HOST->HFIR;
regval &= ~USB_OTG_HFIR_FRIVL;
regval |= dwc2_calc_frame_interval(bus) & USB_OTG_HFIR_FRIVL;
USB_OTG_HOST->HFIR = regval;
if (g_dwc2_hcd[bus->hcd.hcd_id].user_params.phy_type == DWC2_PHY_TYPE_PARAM_FS) {
if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17)) {
USB_OTG_HOST->HFIR = 6000U;
if ((USB_OTG_HOST->HCFG & USB_OTG_HCFG_FSLSPCS) != USB_OTG_HCFG_FSLSPCS_1) {
uint32_t regval = USB_OTG_HOST->HCFG;
if ((USB_OTG_HOST->HCFG & USB_OTG_HCFG_FSLSPCS) != USB_OTG_HCFG_FSLSPCLKSEL_6_MHZ) {
regval = USB_OTG_HOST->HCFG;
regval &= ~USB_OTG_HCFG_FSLSPCS;
regval |= USB_OTG_HCFG_FSLSPCS_1;
regval |= USB_OTG_HCFG_FSLSPCLKSEL_6_MHZ;
USB_OTG_HOST->HCFG = regval;
}
} else {
USB_OTG_HOST->HFIR = 48000U;
if ((USB_OTG_HOST->HCFG & USB_OTG_HCFG_FSLSPCS) != USB_OTG_HCFG_FSLSPCS_0) {
uint32_t regval = USB_OTG_HOST->HCFG;
if ((USB_OTG_HOST->HCFG & USB_OTG_HCFG_FSLSPCS) != USB_OTG_HCFG_FSLSPCLKSEL_48_MHZ) {
regval = USB_OTG_HOST->HCFG;
regval &= ~USB_OTG_HCFG_FSLSPCS;
regval |= USB_OTG_HCFG_FSLSPCS_0;
regval |= USB_OTG_HCFG_FSLSPCLKSEL_48_MHZ;
USB_OTG_HOST->HCFG = regval;
}
}
#endif
}
} else {
}
}
@ -1380,7 +1461,7 @@ void USBH_IRQHandler(uint8_t busid)
}
if (gint_status & USB_OTG_GINTSTS_HCINT) {
chan_int = (USB_OTG_HOST->HAINT & USB_OTG_HOST->HAINTMSK) & 0xFFFFU;
for (uint8_t i = 0U; i < CONFIG_USBHOST_PIPE_NUM; i++) {
for (uint8_t i = 0U; i < g_dwc2_hcd[bus->hcd.hcd_id].hw_params.host_channels; i++) {
if ((chan_int & (1UL << (i & 0xFU))) != 0U) {
if ((USB_OTG_HC(i)->HCCHAR & USB_OTG_HCCHAR_EPDIR) == USB_OTG_HCCHAR_EPDIR) {
dwc2_inchan_irq_handler(bus, i);

View File

@ -336,10 +336,8 @@ static struct ehci_qh_hw *ehci_control_urb_init(struct usbh_bus *bus, struct usb
}
qtd_setup = ehci_qtd_alloc(bus);
qtd_data = ehci_qtd_alloc(bus);
qtd_status = ehci_qtd_alloc(bus);
USB_ASSERT_MSG(qtd_setup && qtd_data && qtd_status, "ctrl qtd alloc failed");
USB_ASSERT_MSG(qtd_setup && qtd_status, "ctrl qtd alloc failed");
ehci_qh_fill(qh,
urb->hport->dev_addr,
@ -363,6 +361,9 @@ static struct ehci_qh_hw *ehci_control_urb_init(struct usbh_bus *bus, struct usb
/* fill data qtd */
if (setup->wLength > 0) {
qtd_data = ehci_qtd_alloc(bus);
USB_ASSERT_MSG(qtd_data, "ctrl qtd alloc failed");
if ((setup->bmRequestType & 0x80) == 0x80) {
token = QTD_TOKEN_PID_IN;
} else {

View File

@ -5,6 +5,10 @@
*/
#include "usbd_core.h"
#if (CONFIG_USB_DBG_LEVEL >= USB_DBG_LOG)
#error "fsdev cannot enable USB_DBG_LOG"
#endif
#ifndef CONFIG_USBDEV_FSDEV_PMA_ACCESS
#error "please define CONFIG_USBDEV_FSDEV_PMA_ACCESS in usb_config.h"
#endif

View File

@ -283,6 +283,13 @@ int usb_dc_init(uint8_t busid)
int usb_dc_deinit(uint8_t busid)
{
HWREGB(USB_BASE + MUSB_IE_OFFSET) = 0;
HWREGH(USB_BASE + MUSB_TXIE_OFFSET) = 0;
HWREGH(USB_BASE + MUSB_RXIE_OFFSET) = 0;
HWREGB(USB_BASE + MUSB_POWER_OFFSET) &= ~USB_POWER_SOFTCONN;
usb_dc_low_level_deinit();
return 0;
}
@ -345,8 +352,10 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
g_musb_udc.out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
g_musb_udc.out_ep[ep_idx].ep_enable = true;
#ifndef CONFIG_USB_MUSB_SIFLI
USB_ASSERT_MSG((8 << HWREGB(USB_BASE + MUSB_RXFIFOSZ_OFFSET)) >= g_musb_udc.out_ep[ep_idx].ep_mps,
"Ep %02x fifo is overflow", ep->bEndpointAddress);
#endif
HWREGH(USB_BASE + MUSB_IND_RXMAP_OFFSET) = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
@ -394,8 +403,10 @@ int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
g_musb_udc.in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
g_musb_udc.in_ep[ep_idx].ep_enable = true;
#ifndef CONFIG_USB_MUSB_SIFLI
USB_ASSERT_MSG((8 << HWREGB(USB_BASE + MUSB_TXFIFOSZ_OFFSET)) >= g_musb_udc.in_ep[ep_idx].ep_mps,
"Ep %02x fifo is overflow", ep->bEndpointAddress);
#endif
HWREGH(USB_BASE + MUSB_IND_TXMAP_OFFSET) = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);

View File

@ -0,0 +1,162 @@
/*
* Copyright (c) 2025, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#include "usbh_core.h"
#include "usb_musb_reg.h"
#undef USB_POWER_SOFTCONN
#undef USB_DEVCTL_FSDEV
#undef USB_DEVCTL_LSDEV
#undef USB_DEVCTL_SESSION
#undef USB_POWER_HSENAB
#undef USB_POWER_HSMODE
#undef USB_POWER_RESET
#undef USB_POWER_RESUME
#ifndef CONFIG_USB_MUSB_SIFLI
#error must define CONFIG_USB_MUSB_SIFLI when use sunxi chips
#endif
#include "bf0_hal.h"
uint8_t usbd_get_musb_fifo_cfg(struct musb_fifo_cfg **cfg)
{
*cfg = NULL; // No FIFO configuration for this implementation, readonly
return 0;
}
uint8_t usbh_get_musb_fifo_cfg(struct musb_fifo_cfg **cfg)
{
*cfg = NULL; // No FIFO configuration for this implementation, readonly
return 0;
}
uint32_t usb_get_musb_ram_size(void)
{
return 0xFFFF; // No specific RAM size for this implementation
}
void usbd_musb_delay_ms(uint8_t ms)
{
/* implement later */
}
#ifdef PKG_CHERRYUSB_DEVICE
void usb_dc_low_level_init(uint8_t busid)
{
HAL_RCC_EnableModule(RCC_MOD_USBC);
#ifdef SOC_SF32LB58X
//hwp_usbc->utmicfg12 = hwp_usbc->utmicfg12 | 0x3; //set xo_clk_sel
hwp_usbc->ldo25 = hwp_usbc->ldo25 | 0xa; //set psw_en and ldo25_en
HAL_Delay(1);
hwp_usbc->swcntl3 = 0x1; //set utmi_en for USB2.0
hwp_usbc->usbcfg = hwp_usbc->usbcfg | 0x40; //enable usb PLL.
#elif defined(SOC_SF32LB56X) || defined(SOC_SF32LB52X)
hwp_hpsys_cfg->USBCR |= HPSYS_CFG_USBCR_DM_PD | HPSYS_CFG_USBCR_DP_EN | HPSYS_CFG_USBCR_USB_EN;
#elif defined(SOC_SF32LB55X)
hwp_hpsys_cfg->USBCR |= HPSYS_CFG_USBCR_DM_PD | HPSYS_CFG_USBCR_USB_EN;
#endif
#ifndef SOC_SF32LB55X
hwp_usbc->usbcfg |= (USB_USBCFG_AVALID | USB_USBCFG_AVALID_DR);
hwp_usbc->dpbrxdisl = 0xFE;
hwp_usbc->dpbtxdisl = 0xFE;
#endif
NVIC_EnableIRQ(USBC_IRQn);
__HAL_SYSCFG_Enable_USB();
}
void usb_dc_low_level_deinit(uint8_t busid)
{
NVIC_DisableIRQ(USBC_IRQn);
#ifdef SOC_SF32LB58X
hwp_usbc->usbcfg &= ~0x40; // Disable usb PLL.
hwp_usbc->swcntl3 = 0x0;
hwp_usbc->ldo25 &= ~0xa; // Disable psw_en and ldo25_en
#elif defined(SOC_SF32LB56X) || defined(SOC_SF32LB52X)
hwp_hpsys_cfg->USBCR &= ~(HPSYS_CFG_USBCR_DM_PD | HPSYS_CFG_USBCR_DP_EN | HPSYS_CFG_USBCR_USB_EN);
#elif defined(SOC_SF32LB55X)
hwp_hpsys_cfg->USBCR &= ~(HPSYS_CFG_USBCR_DM_PD | HPSYS_CFG_USBCR_USB_EN);
#endif
/* reset USB to make DP change to PULLDOWN state */
hwp_hpsys_rcc->RSTR2 |= HPSYS_RCC_RSTR2_USBC;
HAL_Delay_us(100);
hwp_hpsys_rcc->RSTR2 &= ~HPSYS_RCC_RSTR2_USBC;
HAL_RCC_DisableModule(RCC_MOD_USBC);
}
#endif
#ifdef PKG_CHERRYUSB_HOST
void usb_hc_low_level_init(struct usbh_bus *bus)
{
HAL_RCC_EnableModule(RCC_MOD_USBC);
#ifdef SOC_SF32LB58X
//hwp_usbc->utmicfg12 = hwp_usbc->utmicfg12 | 0x3; //set xo_clk_sel
hwp_usbc->ldo25 = hwp_usbc->ldo25 | 0xa; //set psw_en and ldo25_en
HAL_Delay(1);
hwp_usbc->swcntl3 = 0x1; //set utmi_en for USB2.0
hwp_usbc->usbcfg = hwp_usbc->usbcfg | 0x40; //enable usb PLL.
#elif defined(SOC_SF32LB56X) || defined(SOC_SF32LB52X)
hwp_hpsys_cfg->USBCR |= HPSYS_CFG_USBCR_DM_PD | HPSYS_CFG_USBCR_DP_EN | HPSYS_CFG_USBCR_USB_EN;
#elif defined(SOC_SF32LB55X)
hwp_hpsys_cfg->USBCR |= HPSYS_CFG_USBCR_DM_PD | HPSYS_CFG_USBCR_USB_EN;
#endif
#ifndef SOC_SF32LB55X
hwp_usbc->usbcfg |= (USB_USBCFG_AVALID | USB_USBCFG_AVALID_DR);
hwp_usbc->dpbrxdisl = 0xFE;
hwp_usbc->dpbtxdisl = 0xFE;
#endif
__HAL_SYSCFG_Enable_USB();
hwp_usbc->usbcfg &= 0xEF;
hwp_usbc->dbgl = 0x80;
NVIC_EnableIRQ(USBC_IRQn);
}
void usb_hc_low_level_deinit(struct usbh_bus *bus)
{
NVIC_DisableIRQ(USBC_IRQn);
#ifdef SOC_SF32LB58X
hwp_usbc->usbcfg &= ~0x40; // Disable usb PLL.
hwp_usbc->swcntl3 = 0x0;
hwp_usbc->ldo25 &= ~0xa; // Disable psw_en and ldo25_en
#elif defined(SOC_SF32LB56X) || defined(SOC_SF32LB52X)
hwp_hpsys_cfg->USBCR &= ~(HPSYS_CFG_USBCR_DM_PD | HPSYS_CFG_USBCR_DP_EN | HPSYS_CFG_USBCR_USB_EN);
#elif defined(SOC_SF32LB55X)
hwp_hpsys_cfg->USBCR &= ~(HPSYS_CFG_USBCR_DM_PD | HPSYS_CFG_USBCR_USB_EN);
#endif
/* reset USB to make DP change to PULLDOWN state */
hwp_hpsys_rcc->RSTR2 |= HPSYS_RCC_RSTR2_USBC;
HAL_Delay_us(100);
hwp_hpsys_rcc->RSTR2 &= ~HPSYS_RCC_RSTR2_USBC;
HAL_RCC_DisableModule(RCC_MOD_USBC);
}
void musb_reset_prev(void)
{
#if defined(SF32LB58X)
hwp_usbc->rsvd0 = 0xc; //58
#endif
}
void musb_reset_post(void)
{
#if defined(SF32LB58X)
hwp_usbc->rsvd0 = 0x0; //58
#endif
}
#endif
void USBC_IRQHandler(void)
{
#ifdef PKG_CHERRYUSB_DEVICE
USBD_IRQHandler(0);
#endif
#ifdef PKG_CHERRYUSB_HOST
USBH_IRQHandler(0);
#endif
}

View File

@ -429,9 +429,18 @@ static int usbh_reset_port(struct usbh_bus *bus, const uint8_t port)
{
g_musb_hcd[bus->hcd.hcd_id].port_pe = 0;
HWREGB(USB_BASE + MUSB_POWER_OFFSET) |= USB_POWER_RESET;
#ifdef CONFIG_USB_MUSB_SIFLI
extern void musb_reset_prev(void);
musb_reset_prev();
#endif
usb_osal_msleep(20);
HWREGB(USB_BASE + MUSB_POWER_OFFSET) &= ~(USB_POWER_RESET);
usb_osal_msleep(20);
#ifdef CONFIG_USB_MUSB_SIFLI
extern void musb_reset_post(void);
musb_reset_post();
#endif
g_musb_hcd[bus->hcd.hcd_id].port_pe = 1;
return 0;
}