Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f3b5025b64 | ||
|
|
e32486f9a8 | ||
|
|
064507bfe8 | ||
|
|
e61141a45e | ||
|
|
4ce8c507b0 | ||
|
|
85e420eb54 | ||
|
|
40a052ba7f | ||
|
|
3249811a90 | ||
|
|
c5b1e1af27 | ||
|
|
78a802faa6 | ||
|
|
811550ad25 | ||
|
|
4093a3b01d | ||
|
|
9de928d6af | ||
|
|
5a94ed80cb | ||
|
|
22e150a8e6 | ||
|
|
8e0ff856fe | ||
|
|
739db92ef0 | ||
|
|
53e42e6ceb | ||
|
|
832e4c45fb | ||
|
|
52ea7e8dcf | ||
|
|
5a3b87e08c | ||
|
|
6f1228c029 | ||
|
|
e96e5fd9ca | ||
|
|
9d4faca7db | ||
|
|
c22615ea6f | ||
|
|
749cd8531f |
134
Kconfig
134
Kconfig
@@ -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,55 +125,109 @@ if CHERRYUSB
|
||||
prompt "Enable usb mtp device, it is commercial charge"
|
||||
default n
|
||||
|
||||
config CHERRYUSB_DEVICE_DFU
|
||||
bool
|
||||
prompt "Enable usb dfu device"
|
||||
default n
|
||||
|
||||
config CHERRYUSB_DEVICE_ADB
|
||||
bool
|
||||
prompt "Enable usb adb device"
|
||||
default n
|
||||
|
||||
config CHERRYUSB_DEVICE_DFU
|
||||
bool
|
||||
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
|
||||
@@ -216,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
|
||||
@@ -334,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"
|
||||
@@ -355,7 +428,6 @@ if CHERRYUSB
|
||||
prompt "demo for test msc"
|
||||
default 0
|
||||
depends on CHERRYUSB_HOST_MSC
|
||||
endif
|
||||
endmenu
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
162
Kconfig.rtt
162
Kconfig.rtt
@@ -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
|
||||
@@ -125,50 +127,125 @@ if RT_USING_CHERRYUSB
|
||||
prompt "Enable usb mtp device, it is commercial charge"
|
||||
default n
|
||||
|
||||
config RT_CHERRYUSB_DEVICE_ADB
|
||||
bool
|
||||
prompt "Enable usb adb device"
|
||||
default n
|
||||
|
||||
config RT_CHERRYUSB_DEVICE_DFU
|
||||
bool
|
||||
prompt "Enable usb dfu device"
|
||||
default n
|
||||
|
||||
config RT_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV
|
||||
bool
|
||||
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
|
||||
prompt "adb"
|
||||
depends on RT_CHERRYUSB_DEVICE_ADB
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_CHARDEV
|
||||
bool
|
||||
prompt "cdc_acm_chardev"
|
||||
depends on RT_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV
|
||||
endchoice
|
||||
|
||||
config CONFIG_USBDEV_MSC_BLOCK_DEV_NAME
|
||||
@@ -220,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
|
||||
@@ -332,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
|
||||
@@ -342,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
|
||||
endif
|
||||
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
|
||||
|
||||
169
Kconfig.rttpkg
169
Kconfig.rttpkg
@@ -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
|
||||
@@ -124,50 +126,125 @@ if PKG_USING_CHERRYUSB
|
||||
prompt "Enable usb mtp device, it is commercial charge"
|
||||
default n
|
||||
|
||||
config PKG_CHERRYUSB_DEVICE_ADB
|
||||
bool
|
||||
prompt "Enable usb adb device"
|
||||
default n
|
||||
|
||||
config PKG_CHERRYUSB_DEVICE_DFU
|
||||
bool
|
||||
prompt "Enable usb dfu device"
|
||||
default n
|
||||
|
||||
config PKG_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV
|
||||
bool
|
||||
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
|
||||
prompt "adb"
|
||||
depends on PKG_CHERRYUSB_DEVICE_ADB
|
||||
config PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_CHARDEV
|
||||
bool
|
||||
prompt "cdc_acm_chardev"
|
||||
depends on PKG_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV
|
||||
endchoice
|
||||
|
||||
config CONFIG_USBDEV_MSC_BLOCK_DEV_NAME
|
||||
@@ -219,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
|
||||
@@ -331,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
|
||||
@@ -341,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
|
||||
@@ -372,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
|
||||
@@ -393,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
|
||||
|
||||
30
SConscript
30
SConscript
@@ -70,6 +70,9 @@ if GetDepend(['PKG_CHERRYUSB_DEVICE']):
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_MUSB_BK']):
|
||||
src += Glob('port/musb/usb_dc_musb.c')
|
||||
src += Glob('port/musb/usb_glue_bk.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_MUSB_SIFLI']):
|
||||
src += Glob('port/musb/usb_dc_musb.c')
|
||||
src += Glob('port/musb/usb_glue_sifli.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_MUSB_CUSTOM']):
|
||||
src += Glob('port/musb/usb_dc_musb.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_CHIPIDEA_MCX']):
|
||||
@@ -127,13 +130,17 @@ if GetDepend(['PKG_CHERRYUSB_DEVICE']):
|
||||
src += Glob('class/cdc/usbd_cdc_ncm.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_DFU']):
|
||||
src += Glob('class/dfu/usbd_dfu.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_ADB']):
|
||||
src += Glob('class/adb/usbd_adb.c')
|
||||
src += Glob('platform/rtthread/usbd_adb_shell.c')
|
||||
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_CDC_ACM_CHARDEV']):
|
||||
src += Glob('platform/rtthread/usbd_serial.c')
|
||||
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM']):
|
||||
src += Glob('demo/cdc_acm_template.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_MSC']):
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_MSC']) or GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV']):
|
||||
src += Glob('demo/msc_ram_template.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV']):
|
||||
src += Glob('platform/rtthread/usbd_msc_blkdev.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_HID_MOUSE']):
|
||||
src += Glob('demo/hid_mouse_template.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_HID_KEYBOARD']):
|
||||
@@ -162,6 +169,10 @@ if GetDepend(['PKG_CHERRYUSB_DEVICE']):
|
||||
src += Glob('demo/winusb2.0_cdc_template.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_WINUSBV2_HID']):
|
||||
src += Glob('demo/winusb2.0_hid_template.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_ADB']):
|
||||
src += Glob('demo/adb/usbd_adb_template.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM_CHARDEV']):
|
||||
src += Glob('demo/cdc_acm_rttchardev_template.c')
|
||||
|
||||
# USB HOST
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST']):
|
||||
@@ -222,6 +233,9 @@ if GetDepend(['PKG_CHERRYUSB_HOST']):
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_MUSB_BK']):
|
||||
src += Glob('port/musb/usb_hc_musb.c')
|
||||
src += Glob('port/musb/usb_glue_bk.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_MUSB_SIFLI']):
|
||||
src += Glob('port/musb/usb_hc_musb.c')
|
||||
src += Glob('port/musb/usb_glue_sifli.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_MUSB_CUSTOM']):
|
||||
src += Glob('port/musb/usb_hc_musb.c')
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_KINETIS_MCX']):
|
||||
@@ -281,10 +295,16 @@ if GetDepend(['PKG_CHERRYUSB_HOST']):
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_PL2303']):
|
||||
src += Glob('class/vendor/serial/usbh_pl2303.c')
|
||||
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_TEMPLATE']):
|
||||
CPPDEFINES+=['TEST_USBH_MSC=0']
|
||||
if GetDepend(['CONFIG_TEST_USBH_HID']):
|
||||
src += Glob('demo/usb_host.c')
|
||||
|
||||
if GetDepend(['PKG_CHERRYUSB_HOST_CDC_ACM']) \
|
||||
or GetDepend(['PKG_CHERRYUSB_HOST_FTDI']) \
|
||||
or GetDepend(['PKG_CHERRYUSB_HOST_CH34X']) \
|
||||
or GetDepend(['PKG_CHERRYUSB_HOST_CP210X']) \
|
||||
or GetDepend(['PKG_CHERRYUSB_HOST_PL2303']):
|
||||
src += Glob('platform/rtthread/usbh_serial.c')
|
||||
|
||||
if GetDepend('RT_USING_DFS') and GetDepend(['PKG_CHERRYUSB_HOST_MSC']):
|
||||
src += Glob('platform/rtthread/usbh_dfs.c')
|
||||
|
||||
|
||||
2
VERSION
2
VERSION
@@ -1,5 +1,5 @@
|
||||
VERSION_MAJOR = 1
|
||||
VERSION_MINOR = 5
|
||||
PATCHLEVEL = 0
|
||||
PATCHLEVEL = 1
|
||||
VERSION_TWEAK = 0
|
||||
EXTRAVERSION = 0
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
|
||||
1
class/vendor/serial/usbh_ftdi.c
vendored
1
class/vendor/serial/usbh_ftdi.c
vendored
@@ -350,6 +350,7 @@ static int usbh_ftdi_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
switch (version) {
|
||||
case 0x400:
|
||||
ftdi_class->chip_type = FT232B;
|
||||
break;
|
||||
case 0x500:
|
||||
ftdi_class->chip_type = FT2232C;
|
||||
break;
|
||||
|
||||
@@ -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
|
||||
@@ -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,15 +95,25 @@ 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: "
|
||||
"bmRequestType 0x%02x, bRequest 0x%02x, wValue 0x%04x, wIndex 0x%04x, wLength 0x%04x\r\n",
|
||||
setup->bmRequestType,
|
||||
setup->bRequest,
|
||||
setup->wValue,
|
||||
setup->wIndex,
|
||||
setup->wLength);
|
||||
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,
|
||||
setup->wValue,
|
||||
setup->wIndex,
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 { \
|
||||
|
||||
@@ -164,7 +164,7 @@ static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor msc_bootuf2_descriptor = {
|
||||
const struct usb_descriptor adb_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
@@ -274,9 +274,16 @@ static void usbd_event_handler(uint8_t busid, uint8_t event)
|
||||
|
||||
static struct usbd_interface intf0;
|
||||
|
||||
#ifdef RT_USING_MSH
|
||||
extern void usbd_adb_shell_init(uint8_t in_ep, uint8_t out_ep);
|
||||
#else
|
||||
extern int shell_init(bool need_login);
|
||||
#endif
|
||||
void cherryadb_init(uint8_t busid, uint32_t reg_base)
|
||||
{
|
||||
#ifdef RT_USING_MSH
|
||||
usbd_adb_shell_init(WINUSB_IN_EP, WINUSB_OUT_EP);
|
||||
#else
|
||||
/* default password is : 12345678 */
|
||||
/* shell_init() must be called in-task */
|
||||
if (0 != shell_init(false)) {
|
||||
@@ -286,7 +293,7 @@ void cherryadb_init(uint8_t busid, uint32_t reg_base)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &adb_descriptor);
|
||||
#else
|
||||
|
||||
@@ -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
|
||||
|
||||
337
demo/cdc_acm_mavlink_template.c
Normal file
337
demo/cdc_acm_mavlink_template.c
Normal file
@@ -0,0 +1,337 @@
|
||||
/*
|
||||
* Copyright (c) 2025, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_cdc_acm.h"
|
||||
#include "chry_ringbuffer.h"
|
||||
#include <mavlink.h>
|
||||
|
||||
/*!< endpoint address */
|
||||
#define CDC_IN_EP 0x81
|
||||
#define CDC_OUT_EP 0x02
|
||||
#define CDC_INT_EP 0x83
|
||||
|
||||
#define USBD_VID 0xFFFF
|
||||
#define USBD_PID 0xFFFF
|
||||
#define USBD_MAX_POWER 100
|
||||
#define USBD_LANGID_STRING 1033
|
||||
|
||||
/*!< config descriptor size */
|
||||
#define USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN)
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define CDC_MAX_MPS 512
|
||||
#else
|
||||
#define CDC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02)
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB CDC DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor cdc_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
/*!< global descriptor */
|
||||
static const uint8_t cdc_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
///////////////////////////////////////
|
||||
USB_LANGID_INIT(USBD_LANGID_STRING),
|
||||
///////////////////////////////////////
|
||||
/// string1 descriptor
|
||||
///////////////////////////////////////
|
||||
0x14, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'C', 0x00, /* wcChar0 */
|
||||
'h', 0x00, /* wcChar1 */
|
||||
'e', 0x00, /* wcChar2 */
|
||||
'r', 0x00, /* wcChar3 */
|
||||
'r', 0x00, /* wcChar4 */
|
||||
'y', 0x00, /* wcChar5 */
|
||||
'U', 0x00, /* wcChar6 */
|
||||
'S', 0x00, /* wcChar7 */
|
||||
'B', 0x00, /* wcChar8 */
|
||||
///////////////////////////////////////
|
||||
/// string2 descriptor
|
||||
///////////////////////////////////////
|
||||
0x26, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'C', 0x00, /* wcChar0 */
|
||||
'h', 0x00, /* wcChar1 */
|
||||
'e', 0x00, /* wcChar2 */
|
||||
'r', 0x00, /* wcChar3 */
|
||||
'r', 0x00, /* wcChar4 */
|
||||
'y', 0x00, /* wcChar5 */
|
||||
'U', 0x00, /* wcChar6 */
|
||||
'S', 0x00, /* wcChar7 */
|
||||
'B', 0x00, /* wcChar8 */
|
||||
' ', 0x00, /* wcChar9 */
|
||||
'C', 0x00, /* wcChar10 */
|
||||
'D', 0x00, /* wcChar11 */
|
||||
'C', 0x00, /* wcChar12 */
|
||||
' ', 0x00, /* wcChar13 */
|
||||
'D', 0x00, /* wcChar14 */
|
||||
'E', 0x00, /* wcChar15 */
|
||||
'M', 0x00, /* wcChar16 */
|
||||
'O', 0x00, /* wcChar17 */
|
||||
///////////////////////////////////////
|
||||
/// string3 descriptor
|
||||
///////////////////////////////////////
|
||||
0x16, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'2', 0x00, /* wcChar0 */
|
||||
'0', 0x00, /* wcChar1 */
|
||||
'2', 0x00, /* wcChar2 */
|
||||
'2', 0x00, /* wcChar3 */
|
||||
'1', 0x00, /* wcChar4 */
|
||||
'2', 0x00, /* wcChar5 */
|
||||
'3', 0x00, /* wcChar6 */
|
||||
'4', 0x00, /* wcChar7 */
|
||||
'5', 0x00, /* wcChar8 */
|
||||
'6', 0x00, /* wcChar9 */
|
||||
#ifdef CONFIG_USB_HS
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
chry_ringbuffer_t usb_rx_rb;
|
||||
uint8_t usb_rx_buffer[2048];
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t temp_rx_buffer[512];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t usb_tx_buffer[MAVLINK_MAX_PACKET_LEN];
|
||||
|
||||
volatile bool ep_tx_busy_flag = false;
|
||||
|
||||
static void usbd_event_handler(uint8_t busid, uint8_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_RESUME:
|
||||
break;
|
||||
case USBD_EVENT_SUSPEND:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
ep_tx_busy_flag = false;
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(busid, CDC_OUT_EP, temp_rx_buffer, usbd_get_ep_mps(busid, CDC_OUT_EP));
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
case USBD_EVENT_CLR_REMOTE_WAKEUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
USB_LOG_RAW("actual out len:%d\r\n", (unsigned int)nbytes);
|
||||
|
||||
chry_ringbuffer_write(&usb_rx_rb, temp_rx_buffer, nbytes);
|
||||
usbd_ep_start_read(busid, CDC_OUT_EP, temp_rx_buffer, usbd_get_ep_mps(busid, CDC_OUT_EP));
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
USB_LOG_RAW("actual in len:%d\r\n", (unsigned int)nbytes);
|
||||
|
||||
if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
|
||||
/* send zlp */
|
||||
usbd_ep_start_write(busid, CDC_IN_EP, NULL, 0);
|
||||
} else {
|
||||
ep_tx_busy_flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*!< endpoint call back */
|
||||
struct usbd_endpoint cdc_out_ep = {
|
||||
.ep_addr = CDC_OUT_EP,
|
||||
.ep_cb = usbd_cdc_acm_bulk_out
|
||||
};
|
||||
|
||||
struct usbd_endpoint cdc_in_ep = {
|
||||
.ep_addr = CDC_IN_EP,
|
||||
.ep_cb = usbd_cdc_acm_bulk_in
|
||||
};
|
||||
|
||||
static struct usbd_interface intf0;
|
||||
static struct usbd_interface intf1;
|
||||
|
||||
void cdc_acm_mavlink_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
chry_ringbuffer_init(&usb_rx_rb, usb_rx_buffer, sizeof(usb_rx_buffer));
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &cdc_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, cdc_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf0));
|
||||
usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1));
|
||||
usbd_add_endpoint(busid, &cdc_out_ep);
|
||||
usbd_add_endpoint(busid, &cdc_in_ep);
|
||||
usbd_initialize(busid, reg_base, usbd_event_handler);
|
||||
}
|
||||
|
||||
void cdc_acm_mavlink_write(uint8_t *data, uint32_t len)
|
||||
{
|
||||
if (!usb_device_is_configured(0)) {
|
||||
return;
|
||||
}
|
||||
ep_tx_busy_flag = true;
|
||||
usbd_ep_start_write(0, CDC_IN_EP, data, len);
|
||||
while (ep_tx_busy_flag) {
|
||||
}
|
||||
}
|
||||
|
||||
void send_heartbeat(void)
|
||||
{
|
||||
mavlink_message_t message;
|
||||
|
||||
const uint8_t system_id = 42;
|
||||
const uint8_t base_mode = 0;
|
||||
const uint8_t custom_mode = 0;
|
||||
mavlink_msg_heartbeat_pack_chan(
|
||||
system_id,
|
||||
MAV_COMP_ID_PERIPHERAL,
|
||||
MAVLINK_COMM_0,
|
||||
&message,
|
||||
MAV_TYPE_GENERIC,
|
||||
MAV_AUTOPILOT_GENERIC,
|
||||
base_mode,
|
||||
custom_mode,
|
||||
MAV_STATE_STANDBY);
|
||||
|
||||
const int len = mavlink_msg_to_send_buffer(usb_tx_buffer, &message);
|
||||
cdc_acm_mavlink_write(usb_tx_buffer, len);
|
||||
}
|
||||
|
||||
void handle_heartbeat(const mavlink_message_t *message)
|
||||
{
|
||||
mavlink_heartbeat_t heartbeat;
|
||||
mavlink_msg_heartbeat_decode(message, &heartbeat);
|
||||
|
||||
USB_LOG_RAW("Got heartbeat from ");
|
||||
switch (heartbeat.autopilot) {
|
||||
case MAV_AUTOPILOT_GENERIC:
|
||||
USB_LOG_RAW("generic");
|
||||
break;
|
||||
case MAV_AUTOPILOT_ARDUPILOTMEGA:
|
||||
USB_LOG_RAW("ArduPilot");
|
||||
break;
|
||||
case MAV_AUTOPILOT_PX4:
|
||||
USB_LOG_RAW("PX4");
|
||||
break;
|
||||
default:
|
||||
USB_LOG_RAW("other");
|
||||
break;
|
||||
}
|
||||
USB_LOG_RAW(" autopilot\n");
|
||||
|
||||
send_heartbeat();
|
||||
}
|
||||
|
||||
void mavlink_polling(void)
|
||||
{
|
||||
uint8_t ch;
|
||||
bool ret;
|
||||
mavlink_message_t message;
|
||||
mavlink_status_t status;
|
||||
|
||||
ret = chry_ringbuffer_read_byte(&usb_rx_rb, &ch);
|
||||
if (ret) {
|
||||
if (mavlink_parse_char(MAVLINK_COMM_0, ch, &message, &status) == 1) {
|
||||
USB_LOG_INFO(
|
||||
"Received message %d from %d/%d\n",
|
||||
message.msgid, message.sysid, message.compid);
|
||||
|
||||
switch (message.msgid) {
|
||||
case MAVLINK_MSG_ID_HEARTBEAT:
|
||||
handle_heartbeat(&message);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
208
demo/cdc_acm_rttchardev_template.c
Normal file
208
demo/cdc_acm_rttchardev_template.c
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (c) 2025, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_cdc_acm.h"
|
||||
|
||||
/*!< endpoint address */
|
||||
#define CDC_IN_EP 0x81
|
||||
#define CDC_OUT_EP 0x02
|
||||
#define CDC_INT_EP 0x83
|
||||
|
||||
#define USBD_VID 0xFFFF
|
||||
#define USBD_PID 0xFFFF
|
||||
#define USBD_MAX_POWER 100
|
||||
#define USBD_LANGID_STRING 1033
|
||||
|
||||
/*!< config descriptor size */
|
||||
#define USB_CONFIG_SIZE (9 + CDC_ACM_DESCRIPTOR_LEN)
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define CDC_MAX_MPS 512
|
||||
#else
|
||||
#define CDC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02)
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB CDC DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor cdc_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
/*!< global descriptor */
|
||||
static const uint8_t cdc_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
///////////////////////////////////////
|
||||
USB_LANGID_INIT(USBD_LANGID_STRING),
|
||||
///////////////////////////////////////
|
||||
/// string1 descriptor
|
||||
///////////////////////////////////////
|
||||
0x14, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'C', 0x00, /* wcChar0 */
|
||||
'h', 0x00, /* wcChar1 */
|
||||
'e', 0x00, /* wcChar2 */
|
||||
'r', 0x00, /* wcChar3 */
|
||||
'r', 0x00, /* wcChar4 */
|
||||
'y', 0x00, /* wcChar5 */
|
||||
'U', 0x00, /* wcChar6 */
|
||||
'S', 0x00, /* wcChar7 */
|
||||
'B', 0x00, /* wcChar8 */
|
||||
///////////////////////////////////////
|
||||
/// string2 descriptor
|
||||
///////////////////////////////////////
|
||||
0x26, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'C', 0x00, /* wcChar0 */
|
||||
'h', 0x00, /* wcChar1 */
|
||||
'e', 0x00, /* wcChar2 */
|
||||
'r', 0x00, /* wcChar3 */
|
||||
'r', 0x00, /* wcChar4 */
|
||||
'y', 0x00, /* wcChar5 */
|
||||
'U', 0x00, /* wcChar6 */
|
||||
'S', 0x00, /* wcChar7 */
|
||||
'B', 0x00, /* wcChar8 */
|
||||
' ', 0x00, /* wcChar9 */
|
||||
'C', 0x00, /* wcChar10 */
|
||||
'D', 0x00, /* wcChar11 */
|
||||
'C', 0x00, /* wcChar12 */
|
||||
' ', 0x00, /* wcChar13 */
|
||||
'D', 0x00, /* wcChar14 */
|
||||
'E', 0x00, /* wcChar15 */
|
||||
'M', 0x00, /* wcChar16 */
|
||||
'O', 0x00, /* wcChar17 */
|
||||
///////////////////////////////////////
|
||||
/// string3 descriptor
|
||||
///////////////////////////////////////
|
||||
0x16, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'2', 0x00, /* wcChar0 */
|
||||
'0', 0x00, /* wcChar1 */
|
||||
'2', 0x00, /* wcChar2 */
|
||||
'2', 0x00, /* wcChar3 */
|
||||
'1', 0x00, /* wcChar4 */
|
||||
'2', 0x00, /* wcChar5 */
|
||||
'3', 0x00, /* wcChar6 */
|
||||
'4', 0x00, /* wcChar7 */
|
||||
'5', 0x00, /* wcChar8 */
|
||||
'6', 0x00, /* wcChar9 */
|
||||
#ifdef CONFIG_USB_HS
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
static void usbd_event_handler(uint8_t busid, uint8_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_RESUME:
|
||||
break;
|
||||
case USBD_EVENT_SUSPEND:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
case USBD_EVENT_CLR_REMOTE_WAKEUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
extern void usbd_cdc_acm_serial_init(uint8_t busid, uint8_t in_ep, uint8_t out_ep);
|
||||
|
||||
void cdc_acm_chardev_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &cdc_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, cdc_descriptor);
|
||||
#endif
|
||||
usbd_cdc_acm_serial_init(busid, CDC_IN_EP, CDC_OUT_EP);
|
||||
usbd_initialize(busid, reg_base, usbd_event_handler);
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ uint8_t USBD_BinaryObjectStoreDescriptor[USBD_BOS_WTOTALLENGTH] = {
|
||||
struct usb_webusb_descriptor webusb_url_desc = {
|
||||
.vendor_code = USBD_WEBUSB_VENDOR_CODE,
|
||||
.string = USBD_WebUSBURLDescriptor,
|
||||
.string_len = USBD_WINUSB_DESC_SET_LEN
|
||||
.string_len = URL_DESCRIPTOR_LENGTH
|
||||
};
|
||||
|
||||
struct usb_msosv2_descriptor msosv2_desc = {
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
- 有多少个接口就调用多少次 `usbd_add_interface`,参数填相关 `xxx_init_intf`, 如果没有支持的,手动创建一个 intf 填入
|
||||
- 有多少个端点就调用多少次 `usbd_add_endpoint`,当中断完成时,会调用到注册的端点回调中。
|
||||
|
||||
参考下面这张图:
|
||||
|
||||
.. figure:: img/api_device1.png
|
||||
|
||||
CORE
|
||||
-----------------
|
||||
|
||||
|
||||
@@ -15,12 +15,11 @@ CLASS 驱动信息结构体
|
||||
.. code-block:: C
|
||||
|
||||
struct usbh_class_info {
|
||||
uint8_t match_flags; /* Used for product specific matches; range is inclusive */
|
||||
uint8_t class; /* Base device class code */
|
||||
uint8_t subclass; /* Sub-class, depends on base class. Eg. */
|
||||
uint8_t protocol; /* Protocol, depends on base class. Eg. */
|
||||
uint16_t vid; /* Vendor ID (for vendor/product specific devices) */
|
||||
uint16_t pid; /* Product ID (for vendor/product specific devices) */
|
||||
uint8_t match_flags; /* Used for product specific matches; range is inclusive */
|
||||
uint8_t bInterfaceClass; /* Base device class code */
|
||||
uint8_t bInterfaceSubClass; /* Sub-class, depends on base class. Eg. */
|
||||
uint8_t bInterfaceProtocol; /* Protocol, depends on base class. Eg. */
|
||||
const uint16_t (*id_table)[2]; /* List of Vendor/Product ID pairs */
|
||||
const struct usbh_class_driver *class_driver;
|
||||
};
|
||||
|
||||
|
||||
@@ -186,33 +186,36 @@ usbh_submit_urb
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
struct usbh_urb {
|
||||
void *hcpriv;
|
||||
struct usbh_hubport *hport;
|
||||
struct usb_endpoint_descriptor *ep;
|
||||
uint8_t data_toggle;
|
||||
struct usb_setup_packet *setup;
|
||||
uint8_t *transfer_buffer;
|
||||
uint32_t transfer_buffer_length;
|
||||
int transfer_flags;
|
||||
uint32_t actual_length;
|
||||
uint32_t timeout;
|
||||
int errorcode;
|
||||
uint32_t num_of_iso_packets;
|
||||
uint32_t start_frame;
|
||||
usbh_complete_callback_t complete;
|
||||
void *arg;
|
||||
#if defined(__ICCARM__) || defined(__ICCRISCV__) || defined(__ICCRX__)
|
||||
struct usbh_iso_frame_packet *iso_packet;
|
||||
#else
|
||||
struct usbh_iso_frame_packet iso_packet[0];
|
||||
#endif
|
||||
};
|
||||
struct usbh_urb {
|
||||
usb_slist_t list;
|
||||
void *hcpriv;
|
||||
struct usbh_hubport *hport;
|
||||
struct usb_endpoint_descriptor *ep;
|
||||
uint8_t data_toggle;
|
||||
uint8_t interval;
|
||||
struct usb_setup_packet *setup;
|
||||
uint8_t *transfer_buffer;
|
||||
uint32_t transfer_buffer_length;
|
||||
int transfer_flags;
|
||||
uint32_t actual_length;
|
||||
uint32_t timeout;
|
||||
int errorcode;
|
||||
uint32_t num_of_iso_packets;
|
||||
uint32_t start_frame;
|
||||
usbh_complete_callback_t complete;
|
||||
void *arg;
|
||||
#if defined(__ICCARM__) || defined(__ICCRISCV__) || defined(__ICCRX__)
|
||||
struct usbh_iso_frame_packet *iso_packet;
|
||||
#else
|
||||
struct usbh_iso_frame_packet iso_packet[0];
|
||||
#endif
|
||||
};
|
||||
|
||||
- **hcpriv** 主机控制器驱动私有成员
|
||||
- **hport** 当前 urb 使用的 hport
|
||||
- **ep** 当前 urb 使用的 ep
|
||||
- **data_toggle** 当前 data toggle
|
||||
- **interval** urb 传输间隔,单位 us,如果 interval 大于 1000us,则需要使用软件定时器来维护
|
||||
- **setup** setup 请求缓冲区,端点0使用
|
||||
- **transfer_buffer** 传输的数据缓冲区
|
||||
- **transfer_buffer_length** 传输长度
|
||||
|
||||
@@ -6,8 +6,8 @@ project = 'CherryUSB'
|
||||
copyright = '2022 ~ 2025, sakumisu'
|
||||
author = 'sakumisu'
|
||||
|
||||
release = '1.5.0'
|
||||
version = '1.5.0'
|
||||
release = '1.5.1'
|
||||
version = '1.5.1'
|
||||
|
||||
# -- General configuration
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
BIN
docs/source/demo/img/rtt_adb_shell1.png
Normal file
BIN
docs/source/demo/img/rtt_adb_shell1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 66 KiB |
BIN
docs/source/demo/img/rtt_adb_shell2.png
Normal file
BIN
docs/source/demo/img/rtt_adb_shell2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 497 KiB |
28
docs/source/demo/usbd_adb.rst
Normal file
28
docs/source/demo/usbd_adb.rst
Normal file
@@ -0,0 +1,28 @@
|
||||
usbd_adb
|
||||
===============
|
||||
|
||||
本节主要介绍如何使用 adb device。支持 **cherrysh** 和 rt-thread **msh**,只需要在 main 中添加以下初始化即可。
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
cherryadb_init(0, xxxxx);
|
||||
|
||||
如果使用 rt-thread,还需要在 menuconfig 中使能 adb device。
|
||||
|
||||
.. figure:: img/rtt_adb_shell1.png
|
||||
|
||||
进入 adb
|
||||
--------------
|
||||
|
||||
- 使用 **cherrysh** 时枚举完成以后自动进入 adb 模式
|
||||
- 使用 **msh** 需要在 **msh** 中输入 ``adb_enter`` 进入 adb 模式
|
||||
|
||||
退出 adb
|
||||
--------------
|
||||
|
||||
- 使用 **cherrysh** 时输入 ``exit`` 退出 adb 模式
|
||||
- 使用 **msh** 需要在 **msh** 中输入 ``adb_exit`` 退出 adb 模式
|
||||
|
||||
.. figure:: img/cherryadb.png
|
||||
|
||||
.. figure:: img/rtt_adb_shell2.png
|
||||
@@ -48,4 +48,8 @@ usbh_hid
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
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);
|
||||
|
||||
.. note::
|
||||
|
||||
这里的 `USBH_GET_URB_INTERVAL` 是一个宏定义,用于根据 binterval 计算 URB 的传输间隔时间, 单位是 us,而定时器最低是 ms ,因此需要除以 1000。对于小于等于 1ms 的不需要使用定时器。
|
||||
@@ -18,7 +18,7 @@ usbh_msc
|
||||
|
||||
|
||||
- 不使用 fatfs,则直接使用 usbh_msc_scsi_read10 或者 usbh_msc_scsi_write10 函数进行读写操作。
|
||||
- 如果使用 fatfs,则需要在 usbh_msc_thread 中调用 fatfs 的接口进行读写操作。msc读写适配fatfs 参考 `platform/none/usbh_fatfs.c`
|
||||
- 如果使用 fatfs,则需要在 usbh_msc_thread 中调用 fatfs 的接口进行读写操作。msc读写适配fatfs 参考 `platform/fatfs/usbh_fatfs.c`
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
|
||||
@@ -104,3 +104,5 @@ TCPIP_THREAD_STACKSIZE 推荐大于 1K,防止栈溢出。
|
||||
#if TCPIP_THREAD_STACKSIZE < 1024
|
||||
#error TCPIP_THREAD_STACKSIZE must be >= 1024
|
||||
#endif
|
||||
|
||||
- 具体移植文章可以参考 https://club.rt-thread.org/ask/article/5cf3e9e0b2d95800.html
|
||||
@@ -1,2 +1,4 @@
|
||||
usbh_serial
|
||||
===============
|
||||
|
||||
当前仅支持 rt-thread device 框架,包括 cdc acm, ftdi, cp210x, ch34x, pl2303, 具体使用方式参考 rt-thread device api 即可。
|
||||
@@ -107,6 +107,7 @@ CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统的
|
||||
demo/usbd_video
|
||||
demo/usbd_winusb
|
||||
demo/usbd_webusb
|
||||
demo/usbd_adb
|
||||
demo/usbh_serial
|
||||
demo/usbh_hid
|
||||
demo/usbh_msc
|
||||
|
||||
@@ -15,7 +15,7 @@ Q & A
|
||||
- 是否能进 USB 中断
|
||||
- 芯片是否带有 cache功能,是否做了 no cache 处理,截图
|
||||
- 硬件是否正常,是否使用杜邦线连接,如果正常,请说明正常原因
|
||||
- 打开 CONFIG_USBDEV_SETUP_LOG_PRINT,并提供 log
|
||||
- 配置 **#define CONFIG_USB_DBG_LEVEL USB_DBG_LOG** 并提供 log,仅限商业 IP, 其余 IP 禁止开启 log,否则无法枚举
|
||||
- 是否流片并销售
|
||||
|
||||
其余问题提问模板
|
||||
|
||||
@@ -177,6 +177,8 @@ USB Device 移植要点
|
||||
|
||||
.. figure:: img/stm32_13.png
|
||||
|
||||
- 如果芯片带 cache,cache 修改参考 :ref:`usb_cache` 章节
|
||||
|
||||
- 调用 template 的内容初始化,并填入 `busid` 和 USB IP 的 `reg base`, `busid` 从 0 开始,不能超过 `CONFIG_USBDEV_MAX_BUS`
|
||||
|
||||
.. figure:: img/stm32_15.png
|
||||
@@ -212,13 +214,10 @@ USB Host 移植要点
|
||||
|
||||
- 拷贝 **xxx_msp.c** 中的 `HAL_HCD_MspInit` 函数中的内容到 `usb_hc_low_level_init` 函数中,屏蔽 st 生成的 usb 初始化
|
||||
- 在中断函数中调用 `USBH_IRQHandler`,并传入 `busid`
|
||||
- 链接脚本修改参考 :ref:`usbh_link_script` 章节
|
||||
- 如果芯片带 cache,cache 修改参考 :ref:`usb_cache` 章节
|
||||
- 调用 `usbh_initialize` 并填入 `busid` 和 USB IP 的 `reg base`, `busid` 从 0 开始,不能超过 `CONFIG_USBHOST_MAX_BUS`
|
||||
- 启动线程
|
||||
|
||||
.. figure:: img/stm32_18.png
|
||||
.. figure:: img/stm32_19.png
|
||||
|
||||
- 如果使用 **msc**,并且带文件系统,需要自行添加文件系统文件了,对应的 porting 编写参考 **fatfs_usbh.c** 文件。
|
||||
|
||||
.. figure:: img/stm32_21.png
|
||||
|
||||
|
||||
@@ -28,35 +28,19 @@
|
||||
#define CONFIG_USB_PRINTF(...) rt_kprintf(__VA_ARGS__)
|
||||
|
||||
* USB IP 相关的 config 需要用户自己根据芯片实际情况修改
|
||||
* 退出以后不急着编译,需要在代码中实现 `usb_dc_low_level_init` 函数。
|
||||
* 在代码中实现 `usb_dc_low_level_init` 函数
|
||||
* 在 USB 中断函数中调用 `USBD_IRQHandler`,并传入 `busid`
|
||||
* 调用 `usbd_initialize` 并填入 `busid` 和 USB IP 的 `reg base`, `busid` 从 0 开始,不能超过 `CONFIG_USBDEV_MAX_BUS`
|
||||
* 以上内容我们推荐放在 **board.c** 中,如下代码:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
void OTG_HS_IRQHandler(void)
|
||||
{
|
||||
extern void USBD_IRQHandler(uint8_t busid);
|
||||
USBD_IRQHandler(0);
|
||||
}
|
||||
|
||||
int usbd_init(void)
|
||||
{
|
||||
xxx_template_init(0, USB_OTG_HS_PERIPH_BASE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
INIT_APP_EXPORT(usbd_init);
|
||||
|
||||
* 使用 `scons --target=mdk5` 或者 `scons` 进行编译,如果是mdk,需要使用 AC6 编译器
|
||||
* 如果芯片带 cache,cache 修改参考 :ref:`usb_cache` 章节
|
||||
|
||||
主机配置
|
||||
--------------------------
|
||||
|
||||
* 选择 Enable usb host mode 并敲回车进入。
|
||||
* 选择 USB host ip,不清楚自己芯片是哪个 ip 的可以参考 **port** 目录下对应的 readme。
|
||||
* 选择 Enable usb host mode 并敲回车进入
|
||||
* 选择 USB host ip,不清楚自己芯片是哪个 ip 的可以参考 **port** 目录下对应的 readme
|
||||
* 根据需要勾选 class 驱动
|
||||
* 选择是否开启模板 demo,请注意, msc 禁止使能,因为默认对接到 dfs。
|
||||
* 选择是否开启模板 demo,推荐不用
|
||||
|
||||
.. figure:: img/env2.png
|
||||
|
||||
@@ -71,77 +55,8 @@
|
||||
|
||||
* USB IP 相关的 config 需要用户自己根据芯片实际情况修改
|
||||
* 在代码中实现 `usb_hc_low_level_init` 函数
|
||||
* 在 USB 中断函数中调用 `USBH_IRQHandler`,并传入 `busid`
|
||||
* 调用 `usbh_initialize` 并填入 `busid` 和 USB IP 的 `reg base`, `busid` 从 0 开始,不能超过 `CONFIG_USBHOST_MAX_BUS`
|
||||
* 以上内容我们推荐放在 **board.c** 中,如下代码:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
void OTG_HS_IRQHandler(void)
|
||||
{
|
||||
extern void USBH_IRQHandler(uint8_t busid);
|
||||
USBH_IRQHandler(0);
|
||||
}
|
||||
|
||||
int usbh_init(void)
|
||||
{
|
||||
usbh_initialize(0, USB_OTG_HS_PERIPH_BASE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
INIT_APP_EXPORT(usbh_init);
|
||||
|
||||
* 使用 `scons --target=mdk5` 或者 `scons` 进行编译,如果是mdk,需要使用 AC6 编译器
|
||||
* 如果使用的是 GCC ,需要在链接脚本(需要放在 flash 位置)中添加如下代码:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
/* section information for usbh class */
|
||||
. = ALIGN(4);
|
||||
__usbh_class_info_start__ = .;
|
||||
KEEP(*(.usbh_class_info))
|
||||
__usbh_class_info_end__ = .;
|
||||
|
||||
|
||||
举例如下:
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
/* The program code and other data into "FLASH" Rom type memory */
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.text) /* .text sections (code) */
|
||||
*(.text*) /* .text* sections (code) */
|
||||
*(.glue_7) /* glue arm to thumb code */
|
||||
*(.glue_7t) /* glue thumb to arm code */
|
||||
*(.eh_frame)
|
||||
|
||||
KEEP (*(.init))
|
||||
KEEP (*(.fini))
|
||||
. = ALIGN(4);
|
||||
__usbh_class_info_start__ = .;
|
||||
KEEP(*(.usbh_class_info))
|
||||
__usbh_class_info_end__ = .;
|
||||
. = ALIGN(4);
|
||||
_etext = .; /* define a global symbols at end of code */
|
||||
} > FLASH
|
||||
|
||||
借助 STM32CubeMX 生成 USB 初始化
|
||||
----------------------------------
|
||||
|
||||
使用 STM32CubeMX 主要是用来生成 usb 时钟、引脚、中断的配置。我们需要点击如图所示文件,并配置好 USB 的时钟、中断,点击 `Generate Code`。
|
||||
|
||||
.. figure:: img/stm32cubemx0.png
|
||||
.. figure:: img/stm32cubemx1.png
|
||||
.. figure:: img/stm32cubemx2.png
|
||||
.. figure:: img/stm32cubemx_clk.png
|
||||
|
||||
- 将 `main.c` 中的 `SystemClock_Config` 替换掉 `board.c` 中的配置
|
||||
|
||||
.. figure:: img/stm32_init2.png
|
||||
|
||||
.. note :: 下面步骤从 V1.5.0 开始不再需要,**fsdev/usb_glue_st.c**, **dwc2/usb_glue_st.c** 文件中已经实现
|
||||
|
||||
- 将 `stm32xxxx_hal_msp.c` 中的 `HAL_PCD_MspInit` 或者是 `HAL_HCD_MspInit` 中的内容复制到 `usb_dc_low_level_init` 和 `usb_hc_low_level_init` 函数中,举例如下:
|
||||
|
||||
.. figure:: img/stm32_init.png
|
||||
* 链接脚本修改参考 :ref:`usbh_link_script` 章节
|
||||
* 如果芯片带 cache,cache 修改参考 :ref:`usb_cache` 章节
|
||||
|
||||
@@ -12,6 +12,7 @@ USB Device 移植要点
|
||||
- 描述符的注册、class的注册、接口的注册、端点中断的注册。不会的参考 demo 下的 template
|
||||
- 调用 `usbd_initialize` 并填入 `busid` 和 USB IP 的 `reg base`, `busid` 从 0 开始,不能超过 `CONFIG_USBDEV_MAX_BUS`
|
||||
- 在中断函数中调用 `USBD_IRQHandler`,并传入 `busid`, 如果你的 SDK 中中断入口已经存在 `USBD_IRQHandler` ,请更改 USB 协议栈中的名称
|
||||
- 如果芯片带 cache,cache 修改参考 :ref:`usb_cache` 章节
|
||||
- 编译使用。各个 class 如何使用,参考 demo 下的 template
|
||||
|
||||
USB Host 移植要点
|
||||
@@ -22,7 +23,20 @@ USB Host 移植要点
|
||||
- 实现 `usb_hc_low_level_init` 函数(该函数主要负责 USB 时钟、引脚、中断的初始化)。该函数可以放在你想要放的任何参与编译的 c 文件中。如何进行 USB 的时钟、引脚、中断等初始化,请自行根据你使用的芯片原厂提供的源码中进行添加。
|
||||
- 调用 `usbh_initialize` 并填入 `busid` 和 USB IP 的 `reg base`, `busid` 从 0 开始,不能超过 `CONFIG_USBHOST_MAX_BUS`
|
||||
- 在中断函数中调用 `USBH_IRQHandler`,并传入 `busid`, 如果你的 SDK 中中断入口已经存在 `USBH_IRQHandler` ,请更改 USB 协议栈中的名称
|
||||
- 如果使用的是 GCC ,需要在链接脚本中添加如下代码(需要放在 flash 位置):
|
||||
- 链接脚本修改参考 :ref:`usbh_link_script` 章节
|
||||
- 如果芯片带 cache,cache 修改参考 :ref:`usb_cache` 章节
|
||||
- 编译使用。基础的 cdc + hid + msc 参考 `usb_host.c` 文件,其余参考 **platform** 目录下适配
|
||||
|
||||
.. _usbh_link_script:
|
||||
|
||||
主机链接脚本修改
|
||||
-----------------------
|
||||
|
||||
在使用主机时,如果没有修改链接脚本,会报 `__usbh_class_info_start__` 和 `__usbh_class_info_end__` 未定义的错误。因为主机协议栈需要在链接脚本中添加一个 section 来存储 class 信息。
|
||||
|
||||
- 如果使用的是 KEIL 无需修改
|
||||
|
||||
- 如果使用的是 GCC ,需要在链接脚本中添加如下代码(需要放在 flash 位置,建议放最后):
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
@@ -68,15 +82,17 @@ GCC 举例如下:
|
||||
place in AXI_SRAM { block cherryusb_usbh_class_info };
|
||||
keep { section .usbh_class_info};
|
||||
|
||||
- 编译使用。各个 class 如何使用,参考 demo 下的 `usb_host.c` 文件
|
||||
|
||||
带 cache 功能的芯片使用注意
|
||||
.. _usb_cache:
|
||||
|
||||
cache 配置修改
|
||||
-------------------------------
|
||||
|
||||
协议栈以及 port 中不会对 cache 区域的 ram 进行 clean 或者 invalid,所以需要使用一块非 cache 区域的 ram 来维护。 `USB_NOCACHE_RAM_SECTION` 宏表示将变量指定到非 cache ram上,
|
||||
因此,用户需要在对应的链接脚本中添加 no cache ram 的 section。默认 `USB_NOCACHE_RAM_SECTION` 定义为 `__attribute__((section(".noncacheable")))`。
|
||||
对于带 cache 的芯片,协议栈以及 port 中不会对 cache 区域的 ram 进行 clean 或者 invalid,所以需要使用一块非 cache 区域的 ram 来维护。
|
||||
`USB_NOCACHE_RAM_SECTION` 宏表示将变量指定到非 cache ram上,默认 `USB_NOCACHE_RAM_SECTION` 定义为 `__attribute__((section(".noncacheable")))`。
|
||||
因此,用户需要在对应的链接脚本中添加 no cache ram 的 section,并且 section 段包含 `.noncacheable`。
|
||||
|
||||
.. note:: 需要注意,光指定 section 是不够的,还需要配置该 section 中的 ram 是真的 nocache,一般需要配置 mpu 属性(arm 的参考 stm32h7 demo)。
|
||||
.. note:: 需要注意,光修改链接脚本中的 nocache section 是不够的,还需要配置该 section 中的 ram 是真的 nocache,一般需要配置 mpu 属性(arm 的参考 stm32h7 demo)。
|
||||
|
||||
GCC:
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
- 主机 UVC & UAC 类 MUSB IP 中 ISO 驱动和 UAC/UVC 框架, MUSB 需要为 mentor 公司制定的标准 IP
|
||||
|
||||
- 从机 MTP 类驱动, 支持多文件和多文件夹
|
||||
- 从机 MTP 类驱动, 支持多文件和多文件夹,支持 MCU 端增删文件并与 PC 同步
|
||||
|
||||
.. figure:: img/mtpdev.png
|
||||
|
||||
|
||||
@@ -125,4 +125,13 @@ v1.5.0
|
||||
- cmake,scons,kconfig 更新
|
||||
- 使用 USB_ASSERT_MSG 对部分代码检查,全面性 warning 修复
|
||||
- N32H4/MM32F5 device 支持
|
||||
- 默认使能 CONFIG_USBDEV_ADVANCE_DESC
|
||||
- 默认使能 CONFIG_USBDEV_ADVANCE_DESC
|
||||
|
||||
v1.5.1
|
||||
----------------------
|
||||
|
||||
- 支持 rt-thread 下使用 adb shell,host serial/device cdc_acm 对接 rtdevice 框架
|
||||
- **dwc2 增加多个 usbport 不同参数的配置功能,比如一个全速一个高速,fifo配置和phy配置不同**
|
||||
- **ehci 在控制传输中如果没有 nodata 阶段会导致 data qtd 未释放,导致内存泄漏**
|
||||
- **dwc2 读取 setup 使用 usbd_get_next_ep0_state 去判断,避免 setup 和 ep0 out 使用在 USB_OTG_DOEPINT_XFRC 状态下冲突**
|
||||
- sifli usb device 初步支持
|
||||
@@ -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
|
||||
|
||||
@@ -246,92 +246,12 @@
|
||||
#define CONFIG_USBHOST_BLUETOOTH_RX_SIZE 2048
|
||||
#endif
|
||||
|
||||
/* ================ USB Device Port Configuration ================*/
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
#define ESP_USBD_BASE 0x60080000
|
||||
|
||||
#define CONFIG_USBDEV_MAX_BUS 1
|
||||
// esp32s2/s3 has 7 endpoints in device mode (include ep0)
|
||||
#define CONFIG_USBDEV_EP_NUM 7
|
||||
|
||||
/* ---------------- DWC2 Configuration ---------------- */
|
||||
//esp32s2/s3 can support up to 5 IN endpoints(include ep0) at the same time
|
||||
#define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (320 / 4)
|
||||
#define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64 / 4)
|
||||
#define CONFIG_USB_DWC2_TX1_FIFO_SIZE (64 / 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 (64 / 4)
|
||||
#define CONFIG_USB_DWC2_TX5_FIFO_SIZE (64 / 4)
|
||||
#define CONFIG_USB_DWC2_TX6_FIFO_SIZE (64 / 4)
|
||||
#define CONFIG_USB_DWC2_TX7_FIFO_SIZE (0 / 4)
|
||||
#define CONFIG_USB_DWC2_TX8_FIFO_SIZE (0 / 4)
|
||||
|
||||
#define CONFIG_USB_DWC2_DMA_ENABLE
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||
#define ESP_USBD_BASE 0x50000000UL
|
||||
|
||||
#define CONFIG_USBDEV_MAX_BUS 1
|
||||
#define CONFIG_USBDEV_EP_NUM 7 // 16
|
||||
|
||||
/* ---------------- DWC2 Configuration ---------------- */
|
||||
//esp32s2/s3 can support up to 5 IN endpoints(include ep0) at the same time
|
||||
#define CONFIG_USB_DWC2_RXALL_FIFO_SIZE (1024 / 4)
|
||||
#define CONFIG_USB_DWC2_TX0_FIFO_SIZE (64 / 4)
|
||||
#define CONFIG_USB_DWC2_TX1_FIFO_SIZE (512 / 4)
|
||||
#define CONFIG_USB_DWC2_TX2_FIFO_SIZE (512 / 4)
|
||||
#define CONFIG_USB_DWC2_TX3_FIFO_SIZE (512 / 4)
|
||||
#define CONFIG_USB_DWC2_TX4_FIFO_SIZE (512 / 4)
|
||||
#define CONFIG_USB_DWC2_TX5_FIFO_SIZE (64 / 4)
|
||||
#define CONFIG_USB_DWC2_TX6_FIFO_SIZE (64 / 4)
|
||||
#define CONFIG_USB_DWC2_TX7_FIFO_SIZE (0 / 4)
|
||||
#define CONFIG_USB_DWC2_TX8_FIFO_SIZE (0 / 4)
|
||||
|
||||
#define CONFIG_USB_DWC2_DMA_ENABLE
|
||||
#define CONFIG_USB_HS
|
||||
#else
|
||||
#error "Unsupported SoC"
|
||||
#endif
|
||||
|
||||
/* ================ USB Host Port Configuration ==================*/
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
|
||||
#define ESP_USBH_BASE 0x60080000
|
||||
|
||||
#define CONFIG_USBHOST_MAX_BUS 1
|
||||
// esp32s2/s3 has 8 endpoints in host mode (include ep0)
|
||||
#define CONFIG_USBHOST_PIPE_NUM 8
|
||||
|
||||
/* ---------------- DWC2 Configuration ---------------- */
|
||||
/* largest non-periodic USB packet used / 4 */
|
||||
#define CONFIG_USB_DWC2_NPTX_FIFO_SIZE (240 / 4)
|
||||
/* largest periodic USB packet used / 4 */
|
||||
#define CONFIG_USB_DWC2_PTX_FIFO_SIZE (240 / 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 ((200 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE))
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||
#define ESP_USBH_BASE 0x50000000UL
|
||||
|
||||
#define CONFIG_USBHOST_MAX_BUS 1
|
||||
#define CONFIG_USBHOST_PIPE_NUM 16
|
||||
|
||||
/* ---------------- 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 (512 / 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 ((896 - CONFIG_USB_DWC2_NPTX_FIFO_SIZE - CONFIG_USB_DWC2_PTX_FIFO_SIZE))
|
||||
|
||||
#define CONFIG_USBDEV_MAX_BUS 2
|
||||
#define CONFIG_USBHOST_MAX_BUS 2
|
||||
#define CONFIG_USB_HS
|
||||
#else
|
||||
#error "Unsupported SoC"
|
||||
|
||||
@@ -18,7 +18,8 @@ lwip support with usb host net class(cdc_ecm/cdc_ncm/cdc_rndis/asix/rtl8152/bl61
|
||||
- DFS support with usb host msc.
|
||||
- lwip support with usb host net class(cdc_ecm/cdc_ncm/cdc_rndis/asix/rtl8152/bl616_wifi).
|
||||
- msh support with lsusb
|
||||
|
||||
- device char support with host cdc_acm/ftdi/ch34x/cp210x/pl2303
|
||||
- shell support with adb
|
||||
|
||||
## Nuttx
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ FATFS s_sd_disk;
|
||||
FIL s_file;
|
||||
BYTE work[FF_MAX_SS];
|
||||
|
||||
const TCHAR driver_num_buf[4] = { '0', ':', '/', '\0' };
|
||||
const TCHAR driver_num_buf[3] = { '0', ':', '\0' };
|
||||
|
||||
const char *show_error_string(FRESULT fresult);
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*
|
||||
* Copyright (c) 2022 ~ 2025, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "rtthread.h"
|
||||
#include "usb_config.h"
|
||||
|
||||
|
||||
156
platform/rtthread/usbd_adb_shell.c
Normal file
156
platform/rtthread/usbd_adb_shell.c
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (c) 2025, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_adb.h"
|
||||
|
||||
#ifndef CONFIG_USBDEV_SHELL_RX_BUFSIZE
|
||||
#define CONFIG_USBDEV_SHELL_RX_BUFSIZE (2048)
|
||||
#endif
|
||||
|
||||
struct usbd_adb_shell {
|
||||
struct rt_device parent;
|
||||
usb_osal_sem_t tx_done;
|
||||
struct rt_ringbuffer rx_rb;
|
||||
rt_uint8_t rx_rb_buffer[CONFIG_USBDEV_SHELL_RX_BUFSIZE];
|
||||
} g_usbd_adb_shell;
|
||||
|
||||
void usbd_adb_notify_shell_read(uint8_t *data, uint32_t len)
|
||||
{
|
||||
rt_ringbuffer_put(&g_usbd_adb_shell.rx_rb, data, len);
|
||||
|
||||
if (g_usbd_adb_shell.parent.rx_indicate) {
|
||||
g_usbd_adb_shell.parent.rx_indicate(&g_usbd_adb_shell.parent, len);
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_adb_notify_write_done(void)
|
||||
{
|
||||
if (g_usbd_adb_shell.tx_done) {
|
||||
usb_osal_sem_give(g_usbd_adb_shell.tx_done);
|
||||
}
|
||||
}
|
||||
|
||||
static rt_err_t usbd_adb_shell_open(struct rt_device *dev, rt_uint16_t oflag)
|
||||
{
|
||||
while (!usb_device_is_configured(0)) {
|
||||
rt_thread_mdelay(10);
|
||||
}
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t usbd_adb_shell_close(struct rt_device *dev)
|
||||
{
|
||||
if (g_usbd_adb_shell.tx_done) {
|
||||
usb_osal_sem_give(g_usbd_adb_shell.tx_done);
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_ssize_t usbd_adb_shell_read(struct rt_device *dev,
|
||||
rt_off_t pos,
|
||||
void *buffer,
|
||||
rt_size_t size)
|
||||
{
|
||||
return rt_ringbuffer_get(&g_usbd_adb_shell.rx_rb, (rt_uint8_t *)buffer, size);
|
||||
}
|
||||
|
||||
static rt_ssize_t usbd_adb_shell_write(struct rt_device *dev,
|
||||
rt_off_t pos,
|
||||
const void *buffer,
|
||||
rt_size_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
if (!usb_device_is_configured(0)) {
|
||||
return size;
|
||||
}
|
||||
|
||||
if (usbd_adb_can_write() && size) {
|
||||
usb_osal_sem_reset(g_usbd_adb_shell.tx_done);
|
||||
usbd_abd_write(ADB_SHELL_LOALID, buffer, size);
|
||||
usb_osal_sem_take(g_usbd_adb_shell.tx_done, 0xffffffff);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
const static struct rt_device_ops usbd_adb_shell_ops = {
|
||||
NULL,
|
||||
usbd_adb_shell_open,
|
||||
usbd_adb_shell_close,
|
||||
usbd_adb_shell_read,
|
||||
usbd_adb_shell_write,
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
void usbd_adb_shell_init(uint8_t in_ep, uint8_t out_ep)
|
||||
{
|
||||
rt_err_t ret;
|
||||
struct rt_device *device;
|
||||
|
||||
device = &(g_usbd_adb_shell.parent);
|
||||
|
||||
device->type = RT_Device_Class_Char;
|
||||
device->rx_indicate = RT_NULL;
|
||||
device->tx_complete = RT_NULL;
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
device->ops = &usbd_adb_shell_ops;
|
||||
#else
|
||||
device->init = NULL;
|
||||
device->open = usbd_adb_shell_open;
|
||||
device->close = usbd_adb_shell_close;
|
||||
device->read = usbd_adb_shell_read;
|
||||
device->write = usbd_adb_shell_write;
|
||||
device->control = NULL;
|
||||
#endif
|
||||
device->user_data = NULL;
|
||||
|
||||
/* register a character device */
|
||||
ret = rt_device_register(device, "adb-sh", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE);
|
||||
|
||||
#ifdef RT_USING_POSIX_DEVIO
|
||||
/* set fops */
|
||||
device->fops = NULL;
|
||||
#endif
|
||||
|
||||
g_usbd_adb_shell.tx_done = usb_osal_sem_create(0);
|
||||
rt_ringbuffer_init(&g_usbd_adb_shell.rx_rb, g_usbd_adb_shell.rx_rb_buffer, sizeof(g_usbd_adb_shell.rx_rb_buffer));
|
||||
}
|
||||
|
||||
static int adb_enter(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
finsh_set_device("adb-sh");
|
||||
rt_console_set_device("adb-sh");
|
||||
|
||||
return 0;
|
||||
}
|
||||
MSH_CMD_EXPORT(adb_enter, adb_enter);
|
||||
|
||||
static int adb_exit(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
usbd_adb_close(ADB_SHELL_LOALID);
|
||||
|
||||
finsh_set_device(RT_CONSOLE_DEVICE_NAME);
|
||||
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
|
||||
|
||||
return 0;
|
||||
}
|
||||
MSH_CMD_EXPORT(adb_exit, adb_exit);
|
||||
272
platform/rtthread/usbd_serial.c
Normal file
272
platform/rtthread/usbd_serial.c
Normal file
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* Copyright (c) 2025, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_cdc_acm.h"
|
||||
|
||||
#define DEV_FORMAT_CDC_ACM "usb-acm%d"
|
||||
|
||||
#ifndef CONFIG_USBDEV_MAX_CDC_ACM_CLASS
|
||||
#define CONFIG_USBDEV_MAX_CDC_ACM_CLASS (4)
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_SERIAL_RX_BUFSIZE
|
||||
#define CONFIG_USBDEV_SERIAL_RX_BUFSIZE (2048)
|
||||
#endif
|
||||
|
||||
struct usbd_serial {
|
||||
struct rt_device parent;
|
||||
uint8_t busid;
|
||||
uint8_t in_ep;
|
||||
uint8_t out_ep;
|
||||
struct usbd_interface intf_ctrl;
|
||||
struct usbd_interface intf_data;
|
||||
usb_osal_sem_t tx_done;
|
||||
uint8_t minor;
|
||||
char name[32];
|
||||
struct rt_ringbuffer rx_rb;
|
||||
rt_uint8_t rx_rb_buffer[CONFIG_USBDEV_SERIAL_RX_BUFSIZE];
|
||||
};
|
||||
|
||||
static uint32_t g_devinuse = 0;
|
||||
|
||||
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_usbd_serial_cdc_acm_rx_buf[CONFIG_USBDEV_MAX_CDC_ACM_CLASS][USB_ALIGN_UP(512, CONFIG_USB_ALIGN_SIZE)];
|
||||
|
||||
static struct usbd_serial g_usbd_serial_cdc_acm[CONFIG_USBDEV_MAX_CDC_ACM_CLASS];
|
||||
|
||||
static struct usbd_serial *usbd_serial_alloc(void)
|
||||
{
|
||||
uint8_t devno;
|
||||
struct usbd_serial *serial;
|
||||
|
||||
for (devno = 0; devno < CONFIG_USBDEV_MAX_CDC_ACM_CLASS; devno++) {
|
||||
if ((g_devinuse & (1U << devno)) == 0) {
|
||||
g_devinuse |= (1U << devno);
|
||||
|
||||
serial = &g_usbd_serial_cdc_acm[devno];
|
||||
memset(serial, 0, sizeof(struct usbd_serial));
|
||||
serial->minor = devno;
|
||||
snprintf(serial->name, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT_CDC_ACM, serial->minor);
|
||||
return serial;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void usbd_serial_free(struct usbd_serial *serial)
|
||||
{
|
||||
uint8_t devno = serial->minor;
|
||||
|
||||
if (devno < 32) {
|
||||
g_devinuse &= ~(1U << devno);
|
||||
}
|
||||
memset(serial, 0, sizeof(struct usbd_serial));
|
||||
}
|
||||
|
||||
static rt_err_t usbd_serial_open(struct rt_device *dev, rt_uint16_t oflag)
|
||||
{
|
||||
struct usbd_serial *serial;
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
serial = (struct usbd_serial *)dev;
|
||||
|
||||
if (!usb_device_is_configured(serial->busid)) {
|
||||
USB_LOG_ERR("USB device is not configured\n");
|
||||
return -RT_EPERM;
|
||||
}
|
||||
|
||||
usbd_ep_start_read(serial->busid, serial->out_ep,
|
||||
g_usbd_serial_cdc_acm_rx_buf[serial->minor],
|
||||
usbd_get_ep_mps(serial->busid, serial->out_ep));
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_ssize_t usbd_serial_read(struct rt_device *dev,
|
||||
rt_off_t pos,
|
||||
void *buffer,
|
||||
rt_size_t size)
|
||||
{
|
||||
struct usbd_serial *serial;
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
serial = (struct usbd_serial *)dev;
|
||||
|
||||
if (!usb_device_is_configured(serial->busid)) {
|
||||
return -RT_EPERM;
|
||||
}
|
||||
|
||||
return rt_ringbuffer_get(&serial->rx_rb, (rt_uint8_t *)buffer, size);
|
||||
}
|
||||
|
||||
static rt_ssize_t usbd_serial_write(struct rt_device *dev,
|
||||
rt_off_t pos,
|
||||
const void *buffer,
|
||||
rt_size_t size)
|
||||
{
|
||||
struct usbd_serial *serial;
|
||||
int ret = 0;
|
||||
rt_uint8_t *align_buf;
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
serial = (struct usbd_serial *)dev;
|
||||
|
||||
if (!usb_device_is_configured(serial->busid)) {
|
||||
return -RT_EPERM;
|
||||
}
|
||||
align_buf = (rt_uint8_t *)buffer;
|
||||
|
||||
#ifdef RT_USING_CACHE
|
||||
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
|
||||
align_buf = rt_malloc_align(size, CONFIG_USB_ALIGN_SIZE);
|
||||
if (!align_buf) {
|
||||
USB_LOG_ERR("serial get align buf failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
usb_memcpy(align_buf, buffer, size);
|
||||
}
|
||||
#endif
|
||||
usb_osal_sem_reset(serial->tx_done);
|
||||
usbd_ep_start_write(serial->busid, serial->in_ep, align_buf, size);
|
||||
ret = usb_osal_sem_take(serial->tx_done, 3000);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("serial write timeout\n");
|
||||
ret = -RT_ETIMEOUT;
|
||||
} else {
|
||||
ret = size;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
|
||||
rt_free_align(align_buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
const static struct rt_device_ops usbd_serial_ops = {
|
||||
NULL,
|
||||
usbd_serial_open,
|
||||
NULL,
|
||||
usbd_serial_read,
|
||||
usbd_serial_write,
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
rt_err_t usbd_serial_register(struct usbd_serial *serial,
|
||||
void *data)
|
||||
{
|
||||
rt_err_t ret;
|
||||
struct rt_device *device;
|
||||
RT_ASSERT(serial != RT_NULL);
|
||||
|
||||
device = &(serial->parent);
|
||||
|
||||
device->type = RT_Device_Class_Char;
|
||||
device->rx_indicate = RT_NULL;
|
||||
device->tx_complete = RT_NULL;
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
device->ops = &usbd_serial_ops;
|
||||
#else
|
||||
device->init = NULL;
|
||||
device->open = usbd_serial_open;
|
||||
device->close = NULL;
|
||||
device->read = usbd_serial_read;
|
||||
device->write = usbd_serial_write;
|
||||
device->control = NULL;
|
||||
#endif
|
||||
device->user_data = data;
|
||||
|
||||
/* register a character device */
|
||||
ret = rt_device_register(device, serial->name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE);
|
||||
|
||||
#ifdef RT_USING_POSIX_DEVIO
|
||||
/* set fops */
|
||||
device->fops = NULL;
|
||||
#endif
|
||||
rt_ringbuffer_init(&serial->rx_rb, serial->rx_rb_buffer, sizeof(serial->rx_rb_buffer));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
struct usbd_serial *serial;
|
||||
|
||||
for (uint8_t devno = 0; devno < CONFIG_USBDEV_MAX_CDC_ACM_CLASS; devno++) {
|
||||
serial = &g_usbd_serial_cdc_acm[devno];
|
||||
if (serial->out_ep == ep) {
|
||||
rt_ringbuffer_put(&serial->rx_rb, g_usbd_serial_cdc_acm_rx_buf[serial->minor], nbytes);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
struct usbd_serial *serial;
|
||||
|
||||
if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
|
||||
/* send zlp */
|
||||
usbd_ep_start_write(busid, ep, NULL, 0);
|
||||
} else {
|
||||
for (uint8_t devno = 0; devno < CONFIG_USBDEV_MAX_CDC_ACM_CLASS; devno++) {
|
||||
serial = &g_usbd_serial_cdc_acm[devno];
|
||||
if ((serial->in_ep == ep) && serial->tx_done) {
|
||||
usb_osal_sem_give(serial->tx_done);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_serial_init(uint8_t busid, uint8_t in_ep, uint8_t out_ep)
|
||||
{
|
||||
struct usbd_serial *serial;
|
||||
|
||||
struct usbd_endpoint cdc_out_ep = {
|
||||
.ep_addr = out_ep,
|
||||
.ep_cb = usbd_cdc_acm_bulk_out
|
||||
};
|
||||
|
||||
struct usbd_endpoint cdc_in_ep = {
|
||||
.ep_addr = in_ep,
|
||||
.ep_cb = usbd_cdc_acm_bulk_in
|
||||
};
|
||||
|
||||
serial = usbd_serial_alloc();
|
||||
if (serial == NULL) {
|
||||
USB_LOG_ERR("No more serial device available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
serial->busid = busid;
|
||||
serial->in_ep = in_ep;
|
||||
serial->out_ep = out_ep;
|
||||
serial->tx_done = usb_osal_sem_create(0);
|
||||
|
||||
usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &serial->intf_ctrl));
|
||||
usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &serial->intf_data));
|
||||
usbd_add_endpoint(busid, &cdc_out_ep);
|
||||
usbd_add_endpoint(busid, &cdc_in_ep);
|
||||
|
||||
if (usbd_serial_register(serial, NULL) != RT_EOK) {
|
||||
USB_LOG_ERR("Failed to register serial device\n");
|
||||
usbd_serial_free(serial);
|
||||
return;
|
||||
}
|
||||
|
||||
USB_LOG_INFO("USB CDC ACM Serial Device %s initialized\n", serial->name);
|
||||
}
|
||||
@@ -30,15 +30,15 @@ static rt_err_t rt_udisk_init(rt_device_t dev)
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static ssize_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void *buffer,
|
||||
rt_size_t size)
|
||||
static rt_ssize_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void *buffer,
|
||||
rt_size_t size)
|
||||
{
|
||||
struct usbh_msc *msc_class = (struct usbh_msc *)dev->user_data;
|
||||
int ret;
|
||||
rt_uint8_t *align_buf;
|
||||
|
||||
align_buf = (rt_uint8_t *)buffer;
|
||||
#ifdef RT_USING_CACHE
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
|
||||
align_buf = rt_malloc_align(size * msc_class->blocksize, CONFIG_USB_ALIGN_SIZE);
|
||||
if (!align_buf) {
|
||||
@@ -53,7 +53,7 @@ static ssize_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void *buffer,
|
||||
rt_kprintf("usb mass_storage read failed\n");
|
||||
return 0;
|
||||
}
|
||||
#ifdef RT_USING_CACHE
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
|
||||
usb_memcpy(buffer, align_buf, size * msc_class->blocksize);
|
||||
rt_free_align(align_buf);
|
||||
@@ -62,15 +62,15 @@ static ssize_t rt_udisk_read(rt_device_t dev, rt_off_t pos, void *buffer,
|
||||
return size;
|
||||
}
|
||||
|
||||
static ssize_t rt_udisk_write(rt_device_t dev, rt_off_t pos, const void *buffer,
|
||||
rt_size_t size)
|
||||
static rt_ssize_t rt_udisk_write(rt_device_t dev, rt_off_t pos, const void *buffer,
|
||||
rt_size_t size)
|
||||
{
|
||||
struct usbh_msc *msc_class = (struct usbh_msc *)dev->user_data;
|
||||
int ret;
|
||||
rt_uint8_t *align_buf;
|
||||
|
||||
align_buf = (rt_uint8_t *)buffer;
|
||||
#ifdef RT_USING_CACHE
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
|
||||
align_buf = rt_malloc_align(size * msc_class->blocksize, CONFIG_USB_ALIGN_SIZE);
|
||||
if (!align_buf) {
|
||||
@@ -86,7 +86,7 @@ static ssize_t rt_udisk_write(rt_device_t dev, rt_off_t pos, const void *buffer,
|
||||
rt_kprintf("usb mass_storage write failed\n");
|
||||
return 0;
|
||||
}
|
||||
#ifdef RT_USING_CACHE
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
|
||||
rt_free_align(align_buf);
|
||||
}
|
||||
|
||||
914
platform/rtthread/usbh_serial.c
Normal file
914
platform/rtthread/usbh_serial.c
Normal file
@@ -0,0 +1,914 @@
|
||||
/*
|
||||
* Copyright (c) 2025, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#include "usbh_core.h"
|
||||
#include "usbh_cdc_acm.h"
|
||||
#include "usbh_ftdi.h"
|
||||
#include "usbh_cp210x.h"
|
||||
#include "usbh_ch34x.h"
|
||||
#include "usbh_pl2303.h"
|
||||
|
||||
#define DEV_FORMAT_VENDOR "ttyUSB%d"
|
||||
#define DEV_FORMAT_CDC_ACM "ttyACM%d"
|
||||
|
||||
#define USBH_RX_MAX_SIZE 2048
|
||||
|
||||
#ifndef CONFIG_USBHOST_MAX_VENDOR_SERIAL_CLASS
|
||||
#define CONFIG_USBHOST_MAX_VENDOR_SERIAL_CLASS (4)
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBHOST_SERIAL_RX_BUFSIZE
|
||||
#define CONFIG_USBHOST_SERIAL_RX_BUFSIZE (USBH_RX_MAX_SIZE * 2)
|
||||
#endif
|
||||
|
||||
enum usbh_serial_type {
|
||||
USBH_SERIAL_TYPE_CDC_ACM = 0,
|
||||
USBH_SERIAL_TYPE_FTDI,
|
||||
USBH_SERIAL_TYPE_CP210X,
|
||||
USBH_SERIAL_TYPE_CH34X,
|
||||
USBH_SERIAL_TYPE_PL2303,
|
||||
};
|
||||
|
||||
struct usbh_serial {
|
||||
struct rt_device parent;
|
||||
enum usbh_serial_type type;
|
||||
uint8_t minor;
|
||||
char name[CONFIG_USBHOST_DEV_NAMELEN];
|
||||
struct rt_ringbuffer rx_rb;
|
||||
rt_uint8_t rx_rb_buffer[CONFIG_USBHOST_SERIAL_RX_BUFSIZE];
|
||||
};
|
||||
|
||||
static uint32_t g_devinuse_vendor = 0;
|
||||
static uint32_t g_devinuse_cdc_acm = 0;
|
||||
|
||||
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_usbh_serial_vendor_rx_buf[CONFIG_USBHOST_MAX_VENDOR_SERIAL_CLASS][USB_ALIGN_UP(USBH_RX_MAX_SIZE, CONFIG_USB_ALIGN_SIZE)];
|
||||
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_usbh_serial_cdc_acm_rx_buf[CONFIG_USBHOST_MAX_CDC_ACM_CLASS][USB_ALIGN_UP(USBH_RX_MAX_SIZE, CONFIG_USB_ALIGN_SIZE)];
|
||||
|
||||
static struct usbh_serial *usbh_serial_alloc(uint8_t type)
|
||||
{
|
||||
uint8_t devno;
|
||||
struct usbh_serial *serial;
|
||||
|
||||
for (devno = 0; devno < CONFIG_USBHOST_MAX_VENDOR_SERIAL_CLASS; devno++) {
|
||||
if ((g_devinuse_vendor & (1U << devno)) == 0) {
|
||||
g_devinuse_vendor |= (1U << devno);
|
||||
|
||||
serial = rt_malloc(sizeof(struct usbh_serial));
|
||||
memset(serial, 0, sizeof(struct usbh_serial));
|
||||
serial->type = type;
|
||||
serial->minor = devno;
|
||||
snprintf(serial->name, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT_VENDOR, serial->minor);
|
||||
return serial;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void usbh_serial_free(struct usbh_serial *serial)
|
||||
{
|
||||
uint8_t devno = serial->minor;
|
||||
|
||||
if (devno < 32) {
|
||||
g_devinuse_vendor &= ~(1U << devno);
|
||||
}
|
||||
memset(serial, 0, sizeof(struct usbh_serial));
|
||||
rt_free(serial);
|
||||
}
|
||||
|
||||
static struct usbh_serial *usbh_serial_cdc_acm_alloc(uint8_t type)
|
||||
{
|
||||
uint8_t devno;
|
||||
struct usbh_serial *serial;
|
||||
|
||||
for (devno = 0; devno < CONFIG_USBHOST_MAX_CDC_ACM_CLASS; devno++) {
|
||||
if ((g_devinuse_cdc_acm & (1U << devno)) == 0) {
|
||||
g_devinuse_cdc_acm |= (1U << devno);
|
||||
|
||||
serial = rt_malloc(sizeof(struct usbh_serial));
|
||||
memset(serial, 0, sizeof(struct usbh_serial));
|
||||
serial->type = type;
|
||||
serial->minor = devno;
|
||||
snprintf(serial->name, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT_CDC_ACM, serial->minor);
|
||||
return serial;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void usbh_serial_cdc_acm_free(struct usbh_serial *serial)
|
||||
{
|
||||
uint8_t devno = serial->minor;
|
||||
|
||||
if (devno < 32) {
|
||||
g_devinuse_cdc_acm &= ~(1U << devno);
|
||||
}
|
||||
memset(serial, 0, sizeof(struct usbh_serial));
|
||||
rt_free(serial);
|
||||
}
|
||||
|
||||
static rt_err_t usbh_serial_open(struct rt_device *dev, rt_uint16_t oflag)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
serial = (struct usbh_serial *)dev;
|
||||
|
||||
switch (serial->type) {
|
||||
case USBH_SERIAL_TYPE_CDC_ACM:
|
||||
break;
|
||||
case USBH_SERIAL_TYPE_FTDI:
|
||||
break;
|
||||
case USBH_SERIAL_TYPE_CP210X:
|
||||
break;
|
||||
case USBH_SERIAL_TYPE_CH34X:
|
||||
break;
|
||||
case USBH_SERIAL_TYPE_PL2303:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t usbh_serial_close(struct rt_device *dev)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
serial = (struct usbh_serial *)dev;
|
||||
|
||||
switch (serial->type) {
|
||||
case USBH_SERIAL_TYPE_CDC_ACM:
|
||||
break;
|
||||
case USBH_SERIAL_TYPE_FTDI:
|
||||
break;
|
||||
case USBH_SERIAL_TYPE_CP210X:
|
||||
break;
|
||||
case USBH_SERIAL_TYPE_CH34X:
|
||||
break;
|
||||
case USBH_SERIAL_TYPE_PL2303:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_ssize_t usbh_serial_read(struct rt_device *dev,
|
||||
rt_off_t pos,
|
||||
void *buffer,
|
||||
rt_size_t size)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
serial = (struct usbh_serial *)dev;
|
||||
|
||||
return rt_ringbuffer_get(&serial->rx_rb, (rt_uint8_t *)buffer, size);
|
||||
}
|
||||
|
||||
static rt_ssize_t usbh_serial_write(struct rt_device *dev,
|
||||
rt_off_t pos,
|
||||
const void *buffer,
|
||||
rt_size_t size)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
int ret = 0;
|
||||
rt_uint8_t *align_buf;
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
serial = (struct usbh_serial *)dev;
|
||||
|
||||
align_buf = (rt_uint8_t *)buffer;
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
|
||||
align_buf = rt_malloc_align(size, CONFIG_USB_ALIGN_SIZE);
|
||||
if (!align_buf) {
|
||||
USB_LOG_ERR("serial get align buf failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
usb_memcpy(align_buf, buffer, size);
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (serial->type) {
|
||||
#if defined(PKG_CHERRYUSB_HOST_CDC_ACM) || defined(RT_CHERRYUSB_HOST_CDC_ACM)
|
||||
case USBH_SERIAL_TYPE_CDC_ACM:
|
||||
ret = usbh_cdc_acm_bulk_out_transfer((struct usbh_cdc_acm *)dev->user_data, (uint8_t *)align_buf, size, RT_WAITING_FOREVER);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_cdc_acm_bulk_out_transfer failed: %d\n", ret);
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
rt_free_align(align_buf);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if defined(PKG_CHERRYUSB_HOST_FTDI) || defined(RT_CHERRYUSB_HOST_FTDI)
|
||||
case USBH_SERIAL_TYPE_FTDI:
|
||||
ret = usbh_ftdi_bulk_out_transfer((struct usbh_ftdi *)dev->user_data, (uint8_t *)align_buf, size, RT_WAITING_FOREVER);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_ftdi_bulk_out_transfer failed: %d\n", ret);
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
rt_free_align(align_buf);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if defined(PKG_CHERRYUSB_HOST_CH34X) || defined(RT_CHERRYUSB_HOST_CH34X)
|
||||
case USBH_SERIAL_TYPE_CH34X:
|
||||
ret = usbh_ch34x_bulk_out_transfer((struct usbh_ch34x *)dev->user_data, (uint8_t *)align_buf, size, RT_WAITING_FOREVER);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_ch34x_bulk_out_transfer failed: %d\n", ret);
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
rt_free_align(align_buf);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if defined(PKG_CHERRYUSB_HOST_PL2303) || defined(RT_CHERRYUSB_HOST_PL2303)
|
||||
case USBH_SERIAL_TYPE_PL2303:
|
||||
ret = usbh_pl2303_bulk_out_transfer((struct usbh_pl2303 *)dev->user_data, (uint8_t *)align_buf, size, RT_WAITING_FOREVER);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_pl2303_bulk_out_transfer failed: %d\n", ret);
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
rt_free_align(align_buf);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
if ((uint32_t)buffer & (CONFIG_USB_ALIGN_SIZE - 1)) {
|
||||
rt_free_align(align_buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static rt_err_t usbh_serial_control(struct rt_device *dev,
|
||||
int cmd,
|
||||
void *args)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
struct serial_configure *config;
|
||||
struct cdc_line_coding line_coding;
|
||||
int ret = -RT_EINVAL;
|
||||
|
||||
RT_ASSERT(dev != RT_NULL);
|
||||
|
||||
serial = (struct usbh_serial *)dev;
|
||||
|
||||
switch (serial->type) {
|
||||
#if defined(PKG_CHERRYUSB_HOST_CDC_ACM) || defined(RT_CHERRYUSB_HOST_CDC_ACM)
|
||||
case USBH_SERIAL_TYPE_CDC_ACM:
|
||||
if (cmd == RT_DEVICE_CTRL_CONFIG) {
|
||||
struct usbh_cdc_acm *cdc_acm_class;
|
||||
cdc_acm_class = (struct usbh_cdc_acm *)dev->user_data;
|
||||
|
||||
config = (struct serial_configure *)args;
|
||||
|
||||
line_coding.dwDTERate = config->baud_rate;
|
||||
line_coding.bDataBits = config->data_bits;
|
||||
line_coding.bCharFormat = 0; // STOP_BITS_1
|
||||
line_coding.bParityType = config->parity;
|
||||
|
||||
usbh_cdc_acm_set_line_coding(cdc_acm_class, &line_coding);
|
||||
}
|
||||
|
||||
ret = RT_EOK;
|
||||
break;
|
||||
#endif
|
||||
#if defined(PKG_CHERRYUSB_HOST_FTDI) || defined(RT_CHERRYUSB_HOST_FTDI)
|
||||
case USBH_SERIAL_TYPE_FTDI:
|
||||
if (cmd == RT_DEVICE_CTRL_CONFIG) {
|
||||
struct usbh_ftdi *ftdi_class;
|
||||
ftdi_class = (struct usbh_ftdi *)dev->user_data;
|
||||
|
||||
config = (struct serial_configure *)args;
|
||||
|
||||
line_coding.dwDTERate = config->baud_rate;
|
||||
line_coding.bDataBits = config->data_bits;
|
||||
line_coding.bCharFormat = 0; // STOP_BITS_1
|
||||
line_coding.bParityType = config->parity;
|
||||
|
||||
usbh_ftdi_set_line_coding(ftdi_class, &line_coding);
|
||||
}
|
||||
|
||||
ret = RT_EOK;
|
||||
break;
|
||||
#endif
|
||||
#if defined(PKG_CHERRYUSB_HOST_CP210X) || defined(RT_CHERRYUSB_HOST_CP210X)
|
||||
case USBH_SERIAL_TYPE_CP210X:
|
||||
if (cmd == RT_DEVICE_CTRL_CONFIG) {
|
||||
struct usbh_cp210x *cp210x_class;
|
||||
cp210x_class = (struct usbh_cp210x *)dev->user_data;
|
||||
|
||||
config = (struct serial_configure *)args;
|
||||
|
||||
line_coding.dwDTERate = config->baud_rate;
|
||||
line_coding.bDataBits = config->data_bits;
|
||||
line_coding.bCharFormat = 0; // STOP_BITS_1
|
||||
line_coding.bParityType = config->parity;
|
||||
|
||||
usbh_cp210x_set_line_coding(cp210x_class, &line_coding);
|
||||
}
|
||||
|
||||
ret = RT_EOK;
|
||||
break;
|
||||
#endif
|
||||
#if defined(PKG_CHERRYUSB_HOST_CH34X) || defined(RT_CHERRYUSB_HOST_CH34X)
|
||||
case USBH_SERIAL_TYPE_CH34X:
|
||||
if (cmd == RT_DEVICE_CTRL_CONFIG) {
|
||||
struct usbh_ch34x *ch34x_class;
|
||||
ch34x_class = (struct usbh_ch34x *)dev->user_data;
|
||||
|
||||
config = (struct serial_configure *)args;
|
||||
|
||||
line_coding.dwDTERate = config->baud_rate;
|
||||
line_coding.bDataBits = config->data_bits;
|
||||
line_coding.bCharFormat = 0; // STOP_BITS_1
|
||||
line_coding.bParityType = config->parity;
|
||||
|
||||
usbh_ch34x_set_line_coding(ch34x_class, &line_coding);
|
||||
}
|
||||
|
||||
ret = RT_EOK;
|
||||
break;
|
||||
#endif
|
||||
#if defined(PKG_CHERRYUSB_HOST_PL2303) || defined(RT_CHERRYUSB_HOST_PL2303)
|
||||
case USBH_SERIAL_TYPE_PL2303:
|
||||
if (cmd == RT_DEVICE_CTRL_CONFIG) {
|
||||
struct usbh_pl2303 *pl2303_class;
|
||||
pl2303_class = (struct usbh_pl2303 *)dev->user_data;
|
||||
|
||||
config = (struct serial_configure *)args;
|
||||
|
||||
line_coding.dwDTERate = config->baud_rate;
|
||||
line_coding.bDataBits = config->data_bits;
|
||||
line_coding.bCharFormat = 0; // STOP_BITS_1
|
||||
line_coding.bParityType = config->parity;
|
||||
|
||||
usbh_pl2303_set_line_coding(pl2303_class, &line_coding);
|
||||
}
|
||||
|
||||
ret = RT_EOK;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
const static struct rt_device_ops usbh_serial_ops = {
|
||||
NULL,
|
||||
usbh_serial_open,
|
||||
usbh_serial_close,
|
||||
usbh_serial_read,
|
||||
usbh_serial_write,
|
||||
usbh_serial_control
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_POSIX_DEVIO
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <dfs_file.h>
|
||||
|
||||
#ifdef RT_USING_POSIX_TERMIOS
|
||||
#include <termios.h>
|
||||
#endif
|
||||
|
||||
static rt_err_t usbh_serial_fops_rx_ind(rt_device_t dev, rt_size_t size)
|
||||
{
|
||||
rt_wqueue_wakeup(&(dev->wait_queue), (void*)POLLIN);
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
/* fops for serial */
|
||||
static int usbh_serial_fops_open(struct dfs_file *fd)
|
||||
{
|
||||
rt_err_t ret = 0;
|
||||
rt_uint16_t flags = 0;
|
||||
rt_device_t device;
|
||||
|
||||
device = (rt_device_t)fd->vnode->data;
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
|
||||
switch (fd->flags & O_ACCMODE)
|
||||
{
|
||||
case O_RDONLY:
|
||||
USB_LOG_DBG("fops open: O_RDONLY!");
|
||||
flags = RT_DEVICE_FLAG_RDONLY;
|
||||
break;
|
||||
case O_WRONLY:
|
||||
USB_LOG_DBG("fops open: O_WRONLY!");
|
||||
flags = RT_DEVICE_FLAG_WRONLY;
|
||||
break;
|
||||
case O_RDWR:
|
||||
USB_LOG_DBG("fops open: O_RDWR!");
|
||||
flags = RT_DEVICE_FLAG_RDWR;
|
||||
break;
|
||||
default:
|
||||
USB_LOG_ERR("fops open: unknown mode - %d!", fd->flags & O_ACCMODE);
|
||||
break;
|
||||
}
|
||||
|
||||
if ((fd->flags & O_ACCMODE) != O_WRONLY)
|
||||
rt_device_set_rx_indicate(device, usbh_serial_fops_rx_ind);
|
||||
ret = rt_device_open(device, flags);
|
||||
if (ret == RT_EOK) return 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int usbh_serial_fops_close(struct dfs_file *fd)
|
||||
{
|
||||
rt_device_t device;
|
||||
|
||||
device = (rt_device_t)fd->vnode->data;
|
||||
|
||||
rt_device_set_rx_indicate(device, RT_NULL);
|
||||
rt_device_close(device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usbh_serial_fops_ioctl(struct dfs_file *fd, int cmd, void *args)
|
||||
{
|
||||
rt_device_t device;
|
||||
int flags = (int)(rt_base_t)args;
|
||||
int mask = O_NONBLOCK | O_APPEND;
|
||||
|
||||
device = (rt_device_t)fd->vnode->data;
|
||||
switch (cmd)
|
||||
{
|
||||
case FIONREAD:
|
||||
break;
|
||||
case FIONWRITE:
|
||||
break;
|
||||
case F_SETFL:
|
||||
flags &= mask;
|
||||
fd->flags &= ~mask;
|
||||
fd->flags |= flags;
|
||||
break;
|
||||
}
|
||||
|
||||
return rt_device_control(device, cmd, args);
|
||||
}
|
||||
|
||||
static int usbh_serial_fops_read(struct dfs_file *fd, void *buf, size_t count)
|
||||
{
|
||||
int size = 0;
|
||||
rt_device_t device;
|
||||
|
||||
device = (rt_device_t)fd->vnode->data;
|
||||
|
||||
do
|
||||
{
|
||||
size = rt_device_read(device, -1, buf, count);
|
||||
if (size <= 0)
|
||||
{
|
||||
if (fd->flags & O_NONBLOCK)
|
||||
{
|
||||
size = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
rt_wqueue_wait(&(device->wait_queue), 0, RT_WAITING_FOREVER);
|
||||
}
|
||||
}while (size <= 0);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static int usbh_serial_fops_write(struct dfs_file *fd, const void *buf, size_t count)
|
||||
{
|
||||
rt_device_t device;
|
||||
|
||||
device = (rt_device_t)fd->vnode->data;
|
||||
return rt_device_write(device, -1, buf, count);
|
||||
}
|
||||
|
||||
static int usbh_serial_fops_poll(struct dfs_file *fd, struct rt_pollreq *req)
|
||||
{
|
||||
int mask = 0;
|
||||
int flags = 0;
|
||||
rt_device_t device;
|
||||
struct usbh_serial *serial;
|
||||
|
||||
device = (rt_device_t)fd->vnode->data;
|
||||
RT_ASSERT(device != RT_NULL);
|
||||
|
||||
serial = (struct usbh_serial *)device;
|
||||
|
||||
/* only support POLLIN */
|
||||
flags = fd->flags & O_ACCMODE;
|
||||
if (flags == O_RDONLY || flags == O_RDWR)
|
||||
{
|
||||
rt_base_t level;
|
||||
|
||||
rt_poll_add(&(device->wait_queue), req);
|
||||
|
||||
level = rt_hw_interrupt_disable();
|
||||
|
||||
if (rt_ringbuffer_data_len(&serial->rx_rb))
|
||||
mask |= POLLIN;
|
||||
rt_hw_interrupt_enable(level);
|
||||
}
|
||||
// mask|=POLLOUT;
|
||||
return mask;
|
||||
}
|
||||
|
||||
const static struct dfs_file_ops usbh_serial_fops =
|
||||
{
|
||||
usbh_serial_fops_open,
|
||||
usbh_serial_fops_close,
|
||||
usbh_serial_fops_ioctl,
|
||||
usbh_serial_fops_read,
|
||||
usbh_serial_fops_write,
|
||||
RT_NULL, /* flush */
|
||||
RT_NULL, /* lseek */
|
||||
RT_NULL, /* getdents */
|
||||
usbh_serial_fops_poll,
|
||||
};
|
||||
#endif /* RT_USING_POSIX_DEVIO */
|
||||
|
||||
rt_err_t usbh_serial_register(struct usbh_serial *serial,
|
||||
void *data)
|
||||
{
|
||||
rt_err_t ret;
|
||||
struct rt_device *device;
|
||||
RT_ASSERT(serial != RT_NULL);
|
||||
|
||||
device = &(serial->parent);
|
||||
|
||||
device->type = RT_Device_Class_Char;
|
||||
device->rx_indicate = RT_NULL;
|
||||
device->tx_complete = RT_NULL;
|
||||
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
device->ops = &usbh_serial_ops;
|
||||
#else
|
||||
device->init = NULL;
|
||||
device->open = usbh_serial_open;
|
||||
device->close = usbh_serial_close;
|
||||
device->read = usbh_serial_read;
|
||||
device->write = usbh_serial_write;
|
||||
device->control = usbh_serial_control;
|
||||
#endif
|
||||
device->user_data = data;
|
||||
|
||||
/* register a character device */
|
||||
ret = rt_device_register(device, serial->name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE);
|
||||
|
||||
#ifdef RT_USING_POSIX_DEVIO
|
||||
/* set fops */
|
||||
device->fops = &usbh_serial_fops;
|
||||
#endif
|
||||
rt_ringbuffer_init(&serial->rx_rb, serial->rx_rb_buffer, sizeof(serial->rx_rb_buffer));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void usbh_serial_unregister(struct usbh_serial *serial)
|
||||
{
|
||||
RT_ASSERT(serial != NULL);
|
||||
|
||||
rt_device_unregister(&serial->parent);
|
||||
|
||||
if (serial->type == USBH_SERIAL_TYPE_CDC_ACM) {
|
||||
usbh_serial_cdc_acm_free(serial);
|
||||
} else {
|
||||
usbh_serial_free(serial);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(PKG_CHERRYUSB_HOST_CDC_ACM) || defined(RT_CHERRYUSB_HOST_CDC_ACM)
|
||||
void usbh_cdc_acm_callback(void *arg, int nbytes)
|
||||
{
|
||||
struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)arg;
|
||||
struct usbh_serial *serial;
|
||||
int ret;
|
||||
struct usbh_urb *urb = &cdc_acm_class->bulkin_urb;
|
||||
|
||||
if (nbytes > 0) {
|
||||
serial = (struct usbh_serial *)cdc_acm_class->user_data;
|
||||
rt_ringbuffer_put(&serial->rx_rb, g_usbh_serial_cdc_acm_rx_buf[serial->minor], nbytes);
|
||||
|
||||
if (serial->parent.rx_indicate) {
|
||||
serial->parent.rx_indicate(&serial->parent, nbytes);
|
||||
}
|
||||
|
||||
usbh_bulk_urb_fill(urb, cdc_acm_class->hport, cdc_acm_class->bulkin, g_usbh_serial_cdc_acm_rx_buf[serial->minor], sizeof(g_usbh_serial_cdc_acm_rx_buf[serial->minor]), 0, usbh_cdc_acm_callback, cdc_acm_class);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
int ret;
|
||||
struct usbh_urb *urb = &cdc_acm_class->bulkin_urb;
|
||||
|
||||
serial = usbh_serial_cdc_acm_alloc(USBH_SERIAL_TYPE_CDC_ACM);
|
||||
cdc_acm_class->user_data = serial;
|
||||
|
||||
usbh_serial_register(serial, cdc_acm_class);
|
||||
|
||||
struct cdc_line_coding linecoding;
|
||||
linecoding.dwDTERate = 115200;
|
||||
linecoding.bDataBits = 8;
|
||||
linecoding.bParityType = 0;
|
||||
linecoding.bCharFormat = 0;
|
||||
usbh_cdc_acm_set_line_coding(cdc_acm_class, &linecoding);
|
||||
|
||||
usbh_bulk_urb_fill(urb, cdc_acm_class->hport, cdc_acm_class->bulkin, g_usbh_serial_cdc_acm_rx_buf[serial->minor], sizeof(g_usbh_serial_cdc_acm_rx_buf[serial->minor]), 0, usbh_cdc_acm_callback, cdc_acm_class);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
|
||||
usbh_serial_unregister(serial);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
|
||||
serial = (struct usbh_serial *)cdc_acm_class->user_data;
|
||||
usbh_serial_unregister(serial);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PKG_CHERRYUSB_HOST_FTDI) || defined(RT_CHERRYUSB_HOST_FTDI)
|
||||
void usbh_ftdi_callback(void *arg, int nbytes)
|
||||
{
|
||||
struct usbh_ftdi *ftdi_class = (struct usbh_ftdi *)arg;
|
||||
struct usbh_serial *serial;
|
||||
int ret;
|
||||
struct usbh_urb *urb = &ftdi_class->bulkin_urb;
|
||||
|
||||
if (nbytes >= 2) {
|
||||
serial = (struct usbh_serial *)ftdi_class->user_data;
|
||||
|
||||
nbytes -= 2; // Skip the first two bytes (header)
|
||||
rt_ringbuffer_put(&serial->rx_rb, &g_usbh_serial_vendor_rx_buf[serial->minor][2], nbytes);
|
||||
|
||||
if (serial->parent.rx_indicate && nbytes) {
|
||||
serial->parent.rx_indicate(&serial->parent, nbytes);
|
||||
}
|
||||
|
||||
usbh_bulk_urb_fill(urb, ftdi_class->hport, ftdi_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_ftdi_callback, ftdi_class);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_ftdi_run(struct usbh_ftdi *ftdi_class)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
int ret;
|
||||
struct usbh_urb *urb = &ftdi_class->bulkin_urb;
|
||||
|
||||
serial = usbh_serial_alloc(USBH_SERIAL_TYPE_FTDI);
|
||||
ftdi_class->user_data = serial;
|
||||
|
||||
usbh_serial_register(serial, ftdi_class);
|
||||
|
||||
struct cdc_line_coding linecoding;
|
||||
linecoding.dwDTERate = 115200;
|
||||
linecoding.bDataBits = 8;
|
||||
linecoding.bParityType = 0;
|
||||
linecoding.bCharFormat = 0;
|
||||
usbh_ftdi_set_line_coding(ftdi_class, &linecoding);
|
||||
|
||||
usbh_bulk_urb_fill(urb, ftdi_class->hport, ftdi_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_ftdi_callback, ftdi_class);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
|
||||
usbh_serial_unregister(serial);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_ftdi_stop(struct usbh_ftdi *ftdi_class)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
|
||||
serial = (struct usbh_serial *)ftdi_class->user_data;
|
||||
usbh_serial_unregister(serial);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PKG_CHERRYUSB_HOST_CH34X) || defined(RT_CHERRYUSB_HOST_CH34X)
|
||||
void usbh_ch34x_callback(void *arg, int nbytes)
|
||||
{
|
||||
struct usbh_ch34x *ch34x_class = (struct usbh_ch34x *)arg;
|
||||
struct usbh_serial *serial;
|
||||
int ret;
|
||||
struct usbh_urb *urb = &ch34x_class->bulkin_urb;
|
||||
|
||||
if (nbytes > 0) {
|
||||
serial = (struct usbh_serial *)ch34x_class->user_data;
|
||||
rt_ringbuffer_put(&serial->rx_rb, g_usbh_serial_vendor_rx_buf[serial->minor], nbytes);
|
||||
|
||||
if (serial->parent.rx_indicate) {
|
||||
serial->parent.rx_indicate(&serial->parent, nbytes);
|
||||
}
|
||||
|
||||
usbh_bulk_urb_fill(urb, ch34x_class->hport, ch34x_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_ch34x_callback, ch34x_class);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_ch34x_run(struct usbh_ch34x *ch34x_class)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
int ret;
|
||||
struct usbh_urb *urb = &ch34x_class->bulkin_urb;
|
||||
|
||||
serial = usbh_serial_alloc(USBH_SERIAL_TYPE_CH34X);
|
||||
ch34x_class->user_data = serial;
|
||||
|
||||
usbh_serial_register(serial, ch34x_class);
|
||||
|
||||
struct cdc_line_coding linecoding;
|
||||
linecoding.dwDTERate = 115200;
|
||||
linecoding.bDataBits = 8;
|
||||
linecoding.bParityType = 0;
|
||||
linecoding.bCharFormat = 0;
|
||||
usbh_ch34x_set_line_coding(ch34x_class, &linecoding);
|
||||
|
||||
usbh_bulk_urb_fill(urb, ch34x_class->hport, ch34x_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_ch34x_callback, ch34x_class);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
|
||||
usbh_serial_unregister(serial);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_ch34x_stop(struct usbh_ch34x *ch34x_class)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
|
||||
serial = (struct usbh_serial *)ch34x_class->user_data;
|
||||
usbh_serial_unregister(serial);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PKG_CHERRYUSB_HOST_CP210X) || defined(RT_CHERRYUSB_HOST_CP210X)
|
||||
void usbh_cp210x_callback(void *arg, int nbytes)
|
||||
{
|
||||
struct usbh_cp210x *cp210x_class = (struct usbh_cp210x *)arg;
|
||||
struct usbh_serial *serial;
|
||||
int ret;
|
||||
struct usbh_urb *urb = &cp210x_class->bulkin_urb;
|
||||
|
||||
if (nbytes > 0) {
|
||||
serial = (struct usbh_serial *)cp210x_class->user_data;
|
||||
rt_ringbuffer_put(&serial->rx_rb, g_usbh_serial_vendor_rx_buf[serial->minor], nbytes);
|
||||
|
||||
if (serial->parent.rx_indicate) {
|
||||
serial->parent.rx_indicate(&serial->parent, nbytes);
|
||||
}
|
||||
|
||||
usbh_bulk_urb_fill(urb, cp210x_class->hport, cp210x_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_cp210x_callback, cp210x_class);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_cp210x_run(struct usbh_cp210x *cp210x_class)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
int ret;
|
||||
struct usbh_urb *urb = &cp210x_class->bulkin_urb;
|
||||
|
||||
serial = usbh_serial_alloc(USBH_SERIAL_TYPE_CP210X);
|
||||
cp210x_class->user_data = serial;
|
||||
|
||||
usbh_serial_register(serial, cp210x_class);
|
||||
|
||||
struct cdc_line_coding linecoding;
|
||||
linecoding.dwDTERate = 115200;
|
||||
linecoding.bDataBits = 8;
|
||||
linecoding.bParityType = 0;
|
||||
linecoding.bCharFormat = 0;
|
||||
usbh_cp210x_set_line_coding(cp210x_class, &linecoding);
|
||||
|
||||
usbh_bulk_urb_fill(urb, cp210x_class->hport, cp210x_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_cp210x_callback, cp210x_class);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
|
||||
usbh_serial_unregister(serial);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_cp210x_stop(struct usbh_cp210x *cp210x_class)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
|
||||
serial = (struct usbh_serial *)cp210x_class->user_data;
|
||||
usbh_serial_unregister(serial);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PKG_CHERRYUSB_HOST_PL2303) || defined(RT_CHERRYUSB_HOST_PL2303)
|
||||
void usbh_pl2303_callback(void *arg, int nbytes)
|
||||
{
|
||||
struct usbh_pl2303 *pl2303_class = (struct usbh_pl2303 *)arg;
|
||||
struct usbh_serial *serial;
|
||||
int ret;
|
||||
struct usbh_urb *urb = &pl2303_class->bulkin_urb;
|
||||
|
||||
if (nbytes > 0) {
|
||||
serial = (struct usbh_serial *)pl2303_class->user_data;
|
||||
rt_ringbuffer_put(&serial->rx_rb, g_usbh_serial_vendor_rx_buf[serial->minor], nbytes);
|
||||
|
||||
if (serial->parent.rx_indicate) {
|
||||
serial->parent.rx_indicate(&serial->parent, nbytes);
|
||||
}
|
||||
|
||||
usbh_bulk_urb_fill(urb, pl2303_class->hport, pl2303_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_pl2303_callback, pl2303_class);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_pl2303_run(struct usbh_pl2303 *pl2303_class)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
int ret;
|
||||
struct usbh_urb *urb = &pl2303_class->bulkin_urb;
|
||||
|
||||
serial = usbh_serial_alloc(USBH_SERIAL_TYPE_PL2303);
|
||||
pl2303_class->user_data = serial;
|
||||
|
||||
usbh_serial_register(serial, pl2303_class);
|
||||
|
||||
struct cdc_line_coding linecoding;
|
||||
linecoding.dwDTERate = 115200;
|
||||
linecoding.bDataBits = 8;
|
||||
linecoding.bParityType = 0;
|
||||
linecoding.bCharFormat = 0;
|
||||
usbh_pl2303_set_line_coding(pl2303_class, &linecoding);
|
||||
|
||||
usbh_bulk_urb_fill(urb, pl2303_class->hport, pl2303_class->bulkin, g_usbh_serial_vendor_rx_buf[serial->minor], sizeof(g_usbh_serial_vendor_rx_buf[serial->minor]), 0, usbh_pl2303_callback, pl2303_class);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("usbh_submit_urb failed: %d\n", ret);
|
||||
usbh_serial_unregister(serial);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_pl2303_stop(struct usbh_pl2303 *pl2303_class)
|
||||
{
|
||||
struct usbh_serial *serial;
|
||||
|
||||
serial = (struct usbh_serial *)pl2303_class->user_data;
|
||||
usbh_serial_unregister(serial);
|
||||
}
|
||||
#endif
|
||||
@@ -543,11 +543,10 @@ void USBD_IRQHandler(uint8_t busid)
|
||||
}
|
||||
break;
|
||||
case UIS_TOKEN_OUT:
|
||||
EPn_SET_RX_NAK(epid);
|
||||
|
||||
if (epid == 0) {
|
||||
/*!< ep0 out */
|
||||
CH58x_USBFS_DEV->UEP0_CTRL ^= RB_UEP_R_TOG;
|
||||
EPn_SET_RX_NAK(epid);
|
||||
uint32_t read_count = EPn_GET_RX_LEN(0);
|
||||
memcpy(usb_dc_cfg.ep_out[epid].xfer_buf, usb_dc_cfg.ep_out[epid].ep_ram_addr, read_count);
|
||||
|
||||
@@ -563,6 +562,7 @@ void USBD_IRQHandler(uint8_t busid)
|
||||
if (epid == 4) {
|
||||
CH58x_USBFS_DEV->UEP4_CTRL ^= RB_UEP_R_TOG;
|
||||
}
|
||||
EPn_SET_RX_NAK(epid);
|
||||
uint32_t read_count = EPn_GET_RX_LEN(epid);
|
||||
memcpy(usb_dc_cfg.ep_out[epid].xfer_buf, usb_dc_cfg.ep_out[epid].ep_ram_addr, read_count);
|
||||
usb_dc_cfg.ep_out[epid].xfer_buf += read_count;
|
||||
@@ -637,4 +637,4 @@ void USB_IRQHandler(void)
|
||||
{
|
||||
extern void USBD_IRQHandler(uint8_t busid);
|
||||
USBD_IRQHandler(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
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);
|
||||
#else
|
||||
/* Select FS Embedded PHY */
|
||||
USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
|
||||
|
||||
/* 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
|
||||
USB_OTG_OUTEP(0U)->DOEPDMA = (uint32_t)psetup;
|
||||
/* EP enable */
|
||||
USB_OTG_OUTEP(0U)->DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_USBAEP;
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
USB_OTG_DEV->DCFG |= USB_OTG_SPEED_HIGH;
|
||||
#else
|
||||
if (hsphy_type == 0) {
|
||||
USB_OTG_DEV->DCFG |= USB_OTG_SPEED_FULL;
|
||||
|
||||
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 {
|
||||
USB_OTG_DEV->DCFG |= USB_OTG_SPEED_HIGH_IN_FULL;
|
||||
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 {
|
||||
USB_OTG_GLB->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
USB_ASSERT_MSG(!((uint32_t)data % CONFIG_USB_ALIGN_SIZE), "dwc2 data must be %d-byte aligned", CONFIG_USB_ALIGN_SIZE);
|
||||
#endif
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
usb_dcache_clean((uintptr_t)data, USB_ALIGN_UP(data_len, CONFIG_USB_ALIGN_SIZE));
|
||||
USB_OTG_INEP(ep_idx)->DIEPDMA = (uint32_t)data;
|
||||
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
|
||||
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);
|
||||
USB_OTG_INEP(ep_idx)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
|
||||
} 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
|
||||
USB_ASSERT_MSG(!((uint32_t)data % CONFIG_USB_ALIGN_SIZE), "dwc2 data must be %d-byte aligned", CONFIG_USB_ALIGN_SIZE);
|
||||
#endif
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
USB_OTG_OUTEP(ep_idx)->DOEPDMA = (uint32_t)data;
|
||||
#endif
|
||||
if (g_dwc2_udc[busid].user_params.device_dma_enable) {
|
||||
USB_OTG_OUTEP(ep_idx)->DOEPDMA = (uint32_t)data;
|
||||
}
|
||||
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,29 +971,30 @@ void USBD_IRQHandler(uint8_t busid)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USB_DWC2_DMA_ENABLE
|
||||
/* Handle RxQLevel Interrupt */
|
||||
if (gint_status & USB_OTG_GINTSTS_RXFLVL) {
|
||||
USB_MASK_INTERRUPT(USB_OTG_GLB, USB_OTG_GINTSTS_RXFLVL);
|
||||
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);
|
||||
|
||||
temp = USB_OTG_GLB->GRXSTSP;
|
||||
ep_idx = temp & USB_OTG_GRXSTSP_EPNUM;
|
||||
temp = USB_OTG_GLB->GRXSTSP;
|
||||
ep_idx = temp & USB_OTG_GRXSTSP_EPNUM;
|
||||
|
||||
if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> USB_OTG_GRXSTSP_PKTSTS_Pos) == STS_DATA_UPDT) {
|
||||
read_count = (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
|
||||
if (read_count != 0) {
|
||||
dwc2_ep_read(busid, g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf, read_count);
|
||||
g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf += read_count;
|
||||
if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> USB_OTG_GRXSTSP_PKTSTS_Pos) == STS_DATA_UPDT) {
|
||||
read_count = (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
|
||||
if (read_count != 0) {
|
||||
dwc2_ep_read(busid, g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf, read_count);
|
||||
g_dwc2_udc[busid].out_ep[ep_idx].xfer_buf += read_count;
|
||||
}
|
||||
} else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> USB_OTG_GRXSTSP_PKTSTS_Pos) == STS_SETUP_UPDT) {
|
||||
read_count = (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
|
||||
dwc2_ep_read(busid, (uint8_t *)&g_dwc2_udc[busid].setup, read_count);
|
||||
} else {
|
||||
/* ... */
|
||||
}
|
||||
} else if (((temp & USB_OTG_GRXSTSP_PKTSTS) >> USB_OTG_GRXSTSP_PKTSTS_Pos) == STS_SETUP_UPDT) {
|
||||
read_count = (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
|
||||
dwc2_ep_read(busid, (uint8_t *)&g_dwc2_udc[busid].setup, read_count);
|
||||
} else {
|
||||
/* ... */
|
||||
USB_UNMASK_INTERRUPT(USB_OTG_GLB, USB_OTG_GINTSTS_RXFLVL);
|
||||
}
|
||||
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,14 +1004,25 @@ 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;
|
||||
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);
|
||||
@@ -1073,7 +1031,9 @@ void USBD_IRQHandler(uint8_t busid)
|
||||
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) {
|
||||
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 +1056,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,8 +1066,10 @@ 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 ((epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE) {
|
||||
dwc2_tx_fifo_empty_procecss(busid, ep_idx);
|
||||
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;
|
||||
@@ -1124,7 +1083,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 +1112,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);
|
||||
|
||||
367
port/dwc2/usb_dwc2_param.h
Normal file
367
port/dwc2/usb_dwc2_param.h
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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, ¶m_pb14_pb15, sizeof(struct dwc2_user_params));
|
||||
} else {
|
||||
memcpy(params, ¶m_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, ¶m_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)
|
||||
{
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "freertos/task.h"
|
||||
#include "usbd_core.h"
|
||||
#include "usbh_core.h"
|
||||
#include "usb_dwc2_param.h"
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
#define DEFAULT_CPU_FREQ_MHZ CONFIG_ESP32S2_DEFAULT_CPU_FREQ_MHZ
|
||||
@@ -30,6 +31,95 @@ 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;
|
||||
|
||||
#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);
|
||||
@@ -75,11 +165,6 @@ void usb_dc_low_level_deinit(uint8_t busid)
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -129,9 +214,28 @@ void usb_hc_low_level_deinit(struct usbh_bus *bus)
|
||||
}
|
||||
}
|
||||
|
||||
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, ¶m_fs, sizeof(struct dwc2_user_params));
|
||||
#elif CONFIG_IDF_TARGET_ESP32P4
|
||||
if (reg_base == 0x50000000UL) {
|
||||
memcpy(params, ¶m_hs, sizeof(struct dwc2_user_params));
|
||||
} else {
|
||||
memcpy(params, ¶m_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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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, ¶m_pb14_pb15, sizeof(struct dwc2_user_params));
|
||||
} else {
|
||||
memcpy(params, ¶m_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)
|
||||
|
||||
@@ -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);
|
||||
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;
|
||||
}
|
||||
|
||||
//USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD;
|
||||
/* Reset after a PHY select */
|
||||
ret = dwc2_reset(bus);
|
||||
#else
|
||||
/* Select FS Embedded PHY */
|
||||
USB_OTG_GLB->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL;
|
||||
/* 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
|
||||
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;
|
||||
regval &= ~USB_OTG_HCFG_FSLSPCS;
|
||||
regval |= USB_OTG_HCFG_FSLSPCS_1;
|
||||
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;
|
||||
regval &= ~USB_OTG_HCFG_FSLSPCS;
|
||||
regval |= USB_OTG_HCFG_FSLSPCS_0;
|
||||
USB_OTG_HOST->HCFG = regval;
|
||||
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)) {
|
||||
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_FSLSPCLKSEL_6_MHZ;
|
||||
USB_OTG_HOST->HCFG = regval;
|
||||
}
|
||||
} else {
|
||||
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_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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
162
port/musb/usb_glue_sifli.c
Normal file
162
port/musb/usb_glue_sifli.c
Normal 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
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user