73 Commits

Author SHA1 Message Date
sakumisu
f3b5025b64 update(cherryusb): update to v1.5.1
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-14 11:49:37 +08:00
sakumisu
e32486f9a8 feat: support sifli
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-13 20:25:58 +08:00
sakumisu
064507bfe8 update(core/usbd_core): add ep0 state log
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-13 17:17:38 +08:00
sakumisu
e61141a45e update(port/dwc2/usb_dc_dwc2): use usbd_get_ep0_next_state for reading setup
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-13 17:17:19 +08:00
sakumisu
4ce8c507b0 update(demo): remove ep num check
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-13 16:39:33 +08:00
sakumisu
85e420eb54 update(port/fsdev): assert for fsdev log
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-13 16:39:20 +08:00
sakumisu
40a052ba7f chore(kconfig): add more config
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-11 18:34:46 +08:00
sakumisu
3249811a90 fix(port/dwc2/usb_dc_dwc2): align with CONFIG_USB_ALIGN_SIZE not only 32
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-11 18:34:26 +08:00
sakumisu
c5b1e1af27 fix typo
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-11 15:16:01 +08:00
sakumisu
78a802faa6 update(port/dwc2/usb_glue_at): update at glue with dwc2 param
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-10 21:52:58 +08:00
sakumisu
811550ad25 chore(port/dwc2): update readme
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-10 21:52:14 +08:00
mlwang
4093a3b01d fix(port/ehci): Fix the urb leak when there is no data in the control transmission 2025-07-10 21:45:45 +08:00
MDLZCOOL
9de928d6af Modify kconfig for better template choose 2025-07-10 20:19:16 +08:00
sakumisu
5a94ed80cb feat(port/dwc2): add user fifo config api
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-07 20:28:14 +08:00
sakumisu
22e150a8e6 refactor(port/dwc2): support custom config for each dwc2 usb port
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-05 16:39:54 +08:00
sakumisu
8e0ff856fe update(class/mtp): support obj remove & add event
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-03 20:54:30 +08:00
FanhuaCloud
739db92ef0 fix:(port/ch58x/usb_ch58x_dc_usbfs.c) fix out endpoint cannot receive bug 2025-07-03 16:15:08 +08:00
sakumisu
53e42e6ceb fix(platform/rtthread/usbh_serial): remove unused variable
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-02 20:17:20 +08:00
sakumisu
832e4c45fb fix(class/hub): change urb interval unit to us
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-01 21:21:59 +08:00
sakumisu
52ea7e8dcf fix(demo): fix webusb desc len
Signed-off-by: sakumisu <1203593632@qq.com>
2025-07-01 09:51:56 +08:00
sakumisu
5a3b87e08c feat(demo): add mavlink with cdc acm
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-26 18:28:46 +08:00
sakumisu
6f1228c029 fix(platform/rtthread): change ssize_t to rt_ssize_t
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-25 15:10:44 +08:00
sakumisu
e96e5fd9ca feat(platform/rtthread): support cdc acm chardev
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-25 14:07:06 +08:00
sakumisu
9d4faca7db fix(vendor/serial/usbh_ftdi): fix missing break
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-24 18:21:09 +08:00
sakumisu
c22615ea6f feat(platform/rtthread): support adb shell and serial framework
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-24 18:20:38 +08:00
sakumisu
749cd8531f docs: update rst
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-24 18:05:08 +08:00
sakumisu
734cacb177 fix(port/dwc2/usb_glue_st): fix GCCFG in stm32h7rs
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-23 22:20:17 +08:00
sakumisu
1f7070f5c9 revert(port/dwc2/usb_hc_dwc2): revert 4f831f58 change
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-23 20:12:34 +08:00
sakumisu
8d8f3e757e fix warning
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-19 20:02:19 +08:00
KK
5e890a078f msc: add support for SCSI_CMD_SYNCHCACHE10 (0x35) to fix unsupported command error 2025-06-17 16:18:03 +08:00
sakumisu
e530d86af7 docs: update version message
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-16 20:30:31 +08:00
sakumisu
300907dd4c update(platform/rtthread): move cache check into usb_check.c
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-16 20:30:23 +08:00
sakumisu
0916749a32 update(idf): increase host stack size
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-14 22:56:30 +08:00
sakumisu
9d29fece51 fix warning
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-14 21:44:54 +08:00
马龙伟
8df2be2a52 add usb net under idf platform 2025-06-14 21:02:54 +08:00
sakumisu
7f3ddf5d83 docs: update rst
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-13 21:55:37 +08:00
sakumisu
6a226e3e3c refactor(port/ch32): classify ch32 port
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-12 21:35:51 +08:00
sakumisu
8b63acd46c update(port/bl): add fs support
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-12 20:45:53 +08:00
sakumisu
f7094028b8 fix(idf): fix p4 config
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-05 22:12:26 +08:00
sakumisu
5f9d06a9f5 update(platform/fatfs): change memalign to aligned_alloc
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-05 12:40:54 +08:00
sakumisu
537ccfd945 fix(osal/usb_osal_rtthread): up version to v5.2.0 to use RT_SCHED_PRIV(self).current_priority
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-04 17:48:46 +08:00
sakumisu
6973ec73d9 update(cherryusb_config_template): update align size
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-04 16:17:18 +08:00
LiPeng
1feaed024e Fix esp32-p4 cache operation adaptation issue 2025-06-04 16:11:32 +08:00
sakumisu
88cbed9807 update(platform): make msc host with fs common for dcache
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-04 15:33:49 +08:00
sakumisu
1d95077161 feat(dcache): update dcache api
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-04 15:33:42 +08:00
sakumisu
06a0c4393b feat(platform/zephyr): support msc host with disk
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-04 15:08:50 +08:00
sakumisu
6b7d755d3a update(class/hub/usbh_hub): reduce critical section range
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-04 13:08:51 +08:00
sakumisu
078e7d1be0 docs: update rst
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-03 23:11:14 +08:00
sakumisu
ac4e4c569d feat(port/dwc2): add dcache api for esp & st
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-03 22:46:48 +08:00
sakumisu
b6650bdbc6 feat(port/dwc2/usb_dc_dwc2): support dcache
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-03 22:46:39 +08:00
sakumisu
bff8a632a9 feat(class): add usb_osal_thread_schedule_other to allow the applications which use the struct usbh_xxx to exit properly before free struct usbh_xxx
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-03 22:43:35 +08:00
sakumisu
a8bf2687bd update(core/usbd_core): include dcache & osal header
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-03 22:43:35 +08:00
sakumisu
0251e3a145 update(port/dwc2): implement usbd_dwc2_delay_ms with nop delay
Signed-off-by: sakumisu <1203593632@qq.com>
2025-06-03 22:43:35 +08:00
sakumisu
f7c354b4eb docs: update image
Signed-off-by: sakumisu <1203593632@qq.com>
2025-05-30 19:00:41 +08:00
sakumisu
ff42a6f2ea update(demo): add usbd_audio_set_sampling_freq and usbd_audio_get_sampling_freq for audio demo
Signed-off-by: sakumisu <1203593632@qq.com>
2025-05-30 17:11:26 +08:00
sakumisu
ca71e7411e fix(osal/usb_osal_liteos_m): fix task delete when thread is null
Signed-off-by: sakumisu <1203593632@qq.com>
2025-05-30 14:36:02 +08:00
sakumisu
16858c105a fix(port/dwc2/usb_hc_dwc2): fix typo
Signed-off-by: sakumisu <1203593632@qq.com>
2025-05-29 20:35:44 +08:00
sakumisu
8c5026e9cb fix overflow warning
Signed-off-by: sakumisu <1203593632@qq.com>
2025-05-29 10:51:49 +08:00
sakumisu
8a81d81435 update(class/video): change headerlen to 12 for 4 byte align, fix encoding
Signed-off-by: sakumisu <1203593632@qq.com>
2025-05-29 10:47:10 +08:00
sakumisu
c75e62c1e9 fix(idf): fix p4 config
Signed-off-by: sakumisu <1203593632@qq.com>
2025-05-28 22:33:00 +08:00
sakumisu
5a6023118e fix(port/chipidea): fix qtd buffer setting
Signed-off-by: sakumisu <1203593632@qq.com>
2025-05-28 22:32:54 +08:00
sakumisu
51ad3717c5 chore(cmake): disable bluetooth
Signed-off-by: sakumisu <1203593632@qq.com>
2025-05-28 21:24:56 +08:00
sakumisu
0ee859d339 docs: update usage, disable log
Signed-off-by: sakumisu <1203593632@qq.com>
2025-05-28 21:24:39 +08:00
sakumisu
e6d81344c3 refactor(class/video/usbd_video): zero copy for video data transfer
Signed-off-by: sakumisu <1203593632@qq.com>
2025-05-28 17:34:44 +08:00
sakumisu
af6df63acb fix(port/ch32): clear intflag first, set nak before handling ep in
Signed-off-by: sakumisu <1203593632@qq.com>
2025-05-28 12:26:26 +08:00
sakumisu
b4fb10ee98 update(core/usbd_core): clear configuration in disconnect callback
Signed-off-by: sakumisu <1203593632@qq.com>
2025-05-27 20:34:18 +08:00
sakumisu
e3c50cde10 fix(platform/usbd_fatfs_mtp): DIR with dynamic
Signed-off-by: sakumisu <1203593632@qq.com>
2025-05-27 20:34:18 +08:00
sakumisu
e65b8c0614 docs: update readme
Signed-off-by: sakumisu <1203593632@qq.com>
2025-05-27 20:34:18 +08:00
sakumisu
f9189b4278 fix warning
Signed-off-by: sakumisu <1203593632@qq.com>
2025-05-26 22:10:25 +08:00
sakumisu
51ea604ded update(demo): add ep num check for some templates
Signed-off-by: sakumisu <1203593632@qq.com>
2025-05-26 21:54:47 +08:00
sakumisu
fe24f8d4ba feat(class/mtp): support mtp device
Signed-off-by: sakumisu <1203593632@qq.com>
2025-05-26 21:54:32 +08:00
sakumisu
5fed8b7d05 update: sync code from rtthread master
Signed-off-by: sakumisu <1203593632@qq.com>
2025-05-20 18:46:18 +08:00
sakumisu
45ccc810d2 fix(demo): move dhcp_start in init
Signed-off-by: sakumisu <1203593632@qq.com>
2025-05-20 18:45:51 +08:00
137 changed files with 7316 additions and 1214 deletions

View File

@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.15)
if(CONFIG_CHERRYUSB)
if(CONFIG_CHERRYUSB OR ESP_PLATFORM)
if(BL_SDK_BASE)
message(STATUS "enable cherryusb in bouffalo_sdk")
@@ -19,7 +19,7 @@ if(BL_SDK_BASE)
set(CONFIG_CHERRYUSB_HOST_VIDEO 1)
set(CONFIG_CHERRYUSB_HOST_AUDIO 1)
set(CONFIG_CHERRYUSB_HOST_CDC_RNDIS 1)
set(CONFIG_CHERRYUSB_HOST_BLUETOOTH 1)
# set(CONFIG_CHERRYUSB_HOST_BLUETOOTH 1)
set(CONFIG_CHERRYUSB_HOST_ASIX 1)
set(CONFIG_CHERRYUSB_HOST_RTL8152 1)
set(CONFIG_CHERRYUSB_HOST_CH34X 1)
@@ -71,7 +71,7 @@ elseif(ESP_PLATFORM)
${cherryusb_incs}
${freertos_include}
PRIV_REQUIRES
usb
usb esp_mm esp_netif
LDFRAGMENTS
${ldfragments}
)
@@ -148,6 +148,9 @@ elseif(ZEPHYR_BASE)
if (CONFIG_SHELL)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/platform/zephyr/usb_cmd.c)
endif ()
if (CONFIG_FILE_SYSTEM AND CONFIG_CHERRYUSB_HOST)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/platform/zephyr/usbh_msc_disk.c)
endif ()
zephyr_library()
if(cherryusb_incs)

133
Kconfig
View File

@@ -52,6 +52,8 @@ if CHERRYUSB
bool "musb_sunxi"
config CHERRYUSB_DEVICE_MUSB_BK
bool "musb_bk"
config CHERRYUSB_DEVICE_MUSB_SIFLI
bool "musb_sifli"
config CHERRYUSB_DEVICE_MUSB_CUSTOM
bool "musb_custom"
config CHERRYUSB_DEVICE_CHIPIDEA_MCX
@@ -118,9 +120,9 @@ if CHERRYUSB
prompt "Enable usb cdc ncm device"
default n
config CHERRYUSB_DEVICE_DFU
config CHERRYUSB_DEVICE_MTP
bool
prompt "Enable usb dfu device"
prompt "Enable usb mtp device, it is commercial charge"
default n
config CHERRYUSB_DEVICE_ADB
@@ -128,45 +130,104 @@ if CHERRYUSB
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
@@ -211,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
@@ -329,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"
@@ -350,7 +428,6 @@ if CHERRYUSB
prompt "demo for test msc"
default 0
depends on CHERRYUSB_HOST_MSC
endif
endmenu
endif
endif

View File

@@ -52,6 +52,8 @@ if RT_USING_CHERRYUSB
bool "musb_sunxi"
config RT_CHERRYUSB_DEVICE_MUSB_BK
bool "musb_bk"
config RT_CHERRYUSB_DEVICE_MUSB_SIFLI
bool "musb_sifli"
config RT_CHERRYUSB_DEVICE_MUSB_CUSTOM
bool "musb_custom"
config RT_CHERRYUSB_DEVICE_CHIPIDEA_MCX
@@ -120,50 +122,130 @@ if RT_USING_CHERRYUSB
prompt "Enable usb cdc ncm device"
default n
config RT_CHERRYUSB_DEVICE_MTP
bool
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
@@ -215,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
@@ -327,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
@@ -337,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

View File

@@ -53,6 +53,8 @@ if PKG_USING_CHERRYUSB
bool "musb_sunxi"
config PKG_CHERRYUSB_DEVICE_MUSB_BK
bool "musb_bk"
config PKG_CHERRYUSB_DEVICE_MUSB_SIFLI
bool "musb_sifli"
config PKG_CHERRYUSB_DEVICE_MUSB_CUSTOM
bool "musb_custom"
config PKG_CHERRYUSB_DEVICE_CHIPIDEA_MCX
@@ -119,50 +121,130 @@ if PKG_USING_CHERRYUSB
prompt "Enable usb cdc ncm device"
default n
config PKG_CHERRYUSB_DEVICE_MTP
bool
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
@@ -214,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
@@ -326,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
@@ -336,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
@@ -367,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
@@ -388,12 +488,10 @@ if PKG_USING_CHERRYUSB
config PKG_CHERRYUSB_VER
string
default "latest" if PKG_USING_CHERRYUSB_LATEST_VERSION
default "v1.5.1" if PKG_USING_CHERRYUSB_V010501
default "v1.5.0" if PKG_USING_CHERRYUSB_V010500
default "v1.4.3" if PKG_USING_CHERRYUSB_V010403
default "v1.4.2" if PKG_USING_CHERRYUSB_V010402
default "v1.4.0" if PKG_USING_CHERRYUSB_V010400
default "v1.3.1" if PKG_USING_CHERRYUSB_V010301
default "v1.3.0" if PKG_USING_CHERRYUSB_V010300
default "v1.2.0" if PKG_USING_CHERRYUSB_V010200
default "v0.10.2" if PKG_USING_CHERRYUSB_V001002
endif

View File

@@ -71,23 +71,26 @@ CherryUSB Device Stack has the following functions:
- Support Device Firmware Upgrade CLASS (DFU)
- Support USB MIDI CLASS (MIDI)
- Support Remote NDIS (RNDIS)
- Support Media Transfer Protocol (MTP)
- Support WINUSB1.0, WINUSB2.0, WEBUSB, BOS
- Support Vendor class
- Support UF2
- Support Android Debug Bridge (Only support shell)
- Support multi device with the same USB IP
CherryUSB Device Stack resource usage (GCC 10.2 with -O2):
CherryUSB Device Stack resource usage (GCC 10.2 with -O2, disable log):
| file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) |
|:-------------:|:--------------:|:-------------------------:|:-------------:|:----------------:|
|usbd_core.c | ~6000 | (512(default) + 320) * bus | 0 | 0 |
|usbd_cdc_acm.c | ~400 | 0 | 0 | 0 |
|usbd_msc.c | ~3800 | (128 + 512(default)) * bus | 16 * bus | 0 |
|usbd_hid.c | ~360 | 0 | 0 | 0 |
|usbd_audio.c | ~1500 | 0 | 0 | 0 |
|usbd_video.c | ~3700 | 0 | 132 * bus | 0 |
|usbd_rndis.c | ~4000 | 2 * 1580(default)+156+8 | 80 | 0 |
|usbd_core.c | ~4500 | (512(default) + 320) * bus | 0 | 0 |
|usbd_cdc_acm.c | ~900 | 0 | 0 | 0 |
|usbd_msc.c | ~5000 | (128 + 512(default)) * bus | 16 * bus | 0 |
|usbd_hid.c | ~300 | 0 | 0 | 0 |
|usbd_audio.c | ~4000 | 0 | 0 | 0 |
|usbd_video.c | ~7000 | 0 | 132 * bus | 0 |
|usbd_rndis.c | ~2500 | 2 * 1580(default)+156+8 | 80 | 0 |
|usbd_cdc_ecm.c | ~900 | 2 * 1514(default)+16 | 42 | 0 |
|usbd_mtp.c | ~9000 | 2048(default)+128 | sizeof(struct mtp_object) * n| 0 |
## Host Stack Overview
@@ -114,21 +117,23 @@ CherryUSB Host Stack has the following functions:
The CherryUSB Host stack also provides the lsusb function, which allows you to view information about all mounted devices, including those on external hubs, with the help of a shell plugin.
CherryUSB Host Stack resource usage (GCC 10.2 with -O2):
CherryUSB Host Stack resource usage (GCC 10.2 with -O2, disable log):
| file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) |
|:-------------:|:--------------:|:-------------------------------:|:---------------------------:|:------------:|
|usbh_core.c | ~10000(enable lsusb)/ ~7500(disable lsusb) | (512(default) + 8 * (1+x) *n) * bus | sizeof(struct usbh_hub) * bus | raw_config_desc |
|usbh_hub.c | ~6000 | (32 + 4 * (1+x)) * bus | 12 + sizeof(struct usbh_hub) * x | 0 |
|usbh_cdc_acm.c | ~900 | 7 * x | 4 + sizeof(struct usbh_cdc_acm) * x | 0 |
|usbh_msc.c | ~3400 | 128 * x | 4 + sizeof(struct usbh_msc) * x | 0 |
|usbh_hid.c | ~1400 | 64 * x | 4 + sizeof(struct usbh_hid) * x | 0 |
|usbh_video.c | ~5700 | 128 * x | 4 + sizeof(struct usbh_video) * x | 0 |
|usbh_audio.c | ~8400 | 128 * x | 4 + sizeof(struct usbh_audio) * x | 0 |
|usbh_rndis.c | ~5200 | 512 + 2 * 2048(default)| sizeof(struct usbh_rndis) * 1 | 0 |
|usbh_cdc_ecm.c | ~2200 | 2 * 1514 + 16 | sizeof(struct usbh_cdc_ecm) * 1 | 0 |
|usbh_cdc_ncm.c | ~3500 | 2 * 2048(default) + 16 + 32 | sizeof(struct usbh_cdc_ncm) * 1 | 0 |
|usbh_bluetooth.c | ~1000 | 2 * 2048(default) | sizeof(struct usbh_bluetooth) * 1 | 0 |
|usbh_core.c | ~4500 | (512(default) + 8 * (1+x) *n) * bus | sizeof(struct usbh_hub) * bus | raw_config_desc |
|usbh_hub.c | ~3500 | (32 + 4 * (1+x)) * bus | 12 + sizeof(struct usbh_hub) * x | 0 |
|usbh_cdc_acm.c | ~600 | 7 * x | 4 + sizeof(struct usbh_cdc_acm) * x | 0 |
|usbh_msc.c | ~2000 | 128 * x | 4 + sizeof(struct usbh_msc) * x | 0 |
|usbh_hid.c | ~800 | 64 * x | 4 + sizeof(struct usbh_hid) * x | 0 |
|usbh_video.c | ~5000 | 128 * x | 4 + sizeof(struct usbh_video) * x | 0 |
|usbh_audio.c | ~4000 | 128 * x | 4 + sizeof(struct usbh_audio) * x | 0 |
|usbh_rndis.c | ~3000 | 512 + 2 * 2048(default)| sizeof(struct usbh_rndis) * 1 | 0 |
|usbh_cdc_ecm.c | ~1500 | 2 * 1514 + 16 | sizeof(struct usbh_cdc_ecm) * 1 | 0 |
|usbh_cdc_ncm.c | ~2000 | 2 * 2048(default) + 16 + 32 | sizeof(struct usbh_cdc_ncm) * 1| 0 |
|usbh_bluetooth.c | ~1000 | 2 * 2048(default) | sizeof(struct usbh_bluetooth) * 1 | 0 |
|usbh_asix.c | ~7000 | 2 * 2048(default) + 16 + 32 | sizeof(struct usbh_asix) * 1 | 0 |
|usbh_rtl8152.c | ~9000 | 16K+ 2K(default) + 2 + 32 | sizeof(struct usbh_rtl8152) * 1 | 0 |
Among them, `sizeof(struct usbh_hub)` and `sizeof(struct usbh_hubport)` are affected by the following macros:
@@ -199,7 +204,7 @@ TODO
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with musb |
|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with musb |
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | TBD |
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2 | TBD |
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2/>=v1.5.0 | TBD |
## Package Support

View File

@@ -71,6 +71,7 @@ CherryUSB Device 协议栈当前实现以下功能:
- 支持 Device Firmware Upgrade CLASS (DFU)
- 支持 USB MIDI CLASS (MIDI)
- 支持 Remote NDIS (RNDIS)
- 支持 Media Transfer Protocol (MTP)
- 支持 WINUSB1.0、WINUSB2.0、WEBUSB、BOS
- 支持 Vendor 类 class
- 支持 UF2
@@ -81,13 +82,15 @@ CherryUSB Device 协议栈资源占用说明GCC 10.2 with -O2
| file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) |
|:-------------:|:--------------:|:-------------------------:|:-------------:|:----------------:|
|usbd_core.c | ~6000 | (512(default) + 320) * bus | 0 | 0 |
|usbd_cdc_acm.c | ~400 | 0 | 0 | 0 |
|usbd_msc.c | ~3800 | (128 + 512(default)) * bus | 16 * bus | 0 |
|usbd_hid.c | ~360 | 0 | 0 | 0 |
|usbd_audio.c | ~1500 | 0 | 0 | 0 |
|usbd_video.c | ~3700 | 0 | 132 * bus | 0 |
|usbd_rndis.c | ~4000 | 2 * 1580(default)+156+8 | 80 | 0 |
|usbd_core.c | ~4500 | (512(default) + 320) * bus | 0 | 0 |
|usbd_cdc_acm.c | ~900 | 0 | 0 | 0 |
|usbd_msc.c | ~5000 | (128 + 512(default)) * bus | 16 * bus | 0 |
|usbd_hid.c | ~300 | 0 | 0 | 0 |
|usbd_audio.c | ~4000 | 0 | 0 | 0 |
|usbd_video.c | ~7000 | 0 | 132 * bus | 0 |
|usbd_rndis.c | ~2500 | 2 * 1580(default)+156+8 | 80 | 0 |
|usbd_cdc_ecm.c | ~900 | 2 * 1514(default)+16 | 42 | 0 |
|usbd_mtp.c | ~9000 | 2048(default)+128 | sizeof(struct mtp_object) * n| 0 |
## Host 协议栈简介
@@ -114,21 +117,23 @@ CherryUSB Host 协议栈当前实现以下功能:
同时CherryUSB Host 协议栈还提供了 lsusb 的功能,借助 shell 插件可以查看所有挂载设备的信息,包括外部 hub 上的设备的信息。
CherryUSB Host 协议栈资源占用说明GCC 10.2 with -O2
CherryUSB Host 协议栈资源占用说明GCC 10.2 with -O2,关闭 log
| file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) |
|:-------------:|:--------------:|:-------------------------------:|:---------------------------:|:------------:|
|usbh_core.c | ~10000(enable lsusb)/ ~7500(disable lsusb) | (512(default) + 8 * (1+x) *n) * bus | sizeof(struct usbh_hub) * bus | raw_config_desc |
|usbh_hub.c | ~6000 | (32 + 4 * (1+x)) * bus | 12 + sizeof(struct usbh_hub) * x | 0 |
|usbh_cdc_acm.c | ~900 | 7 * x | 4 + sizeof(struct usbh_cdc_acm) * x | 0 |
|usbh_msc.c | ~3400 | 128 * x | 4 + sizeof(struct usbh_msc) * x | 0 |
|usbh_hid.c | ~1400 | 64 * x | 4 + sizeof(struct usbh_hid) * x | 0 |
|usbh_video.c | ~5700 | 128 * x | 4 + sizeof(struct usbh_video) * x | 0 |
|usbh_audio.c | ~8400 | 128 * x | 4 + sizeof(struct usbh_audio) * x | 0 |
|usbh_rndis.c | ~5200 | 512 + 2 * 2048(default)| sizeof(struct usbh_rndis) * 1 | 0 |
|usbh_cdc_ecm.c | ~2200 | 2 * 1514 + 16 | sizeof(struct usbh_cdc_ecm) * 1 | 0 |
|usbh_cdc_ncm.c | ~3500 | 2 * 2048(default) + 16 + 32 | sizeof(struct usbh_cdc_ncm) * 1 | 0 |
|usbh_bluetooth.c | ~1000 | 2 * 2048(default) | sizeof(struct usbh_bluetooth) * 1 | 0 |
|usbh_core.c | ~4500 | (512(default) + 8 * (1+x) *n) * bus | sizeof(struct usbh_hub) * bus | raw_config_desc |
|usbh_hub.c | ~3500 | (32 + 4 * (1+x)) * bus | 12 + sizeof(struct usbh_hub) * x | 0 |
|usbh_cdc_acm.c | ~600 | 7 * x | 4 + sizeof(struct usbh_cdc_acm) * x | 0 |
|usbh_msc.c | ~2000 | 128 * x | 4 + sizeof(struct usbh_msc) * x | 0 |
|usbh_hid.c | ~800 | 64 * x | 4 + sizeof(struct usbh_hid) * x | 0 |
|usbh_video.c | ~5000 | 128 * x | 4 + sizeof(struct usbh_video) * x | 0 |
|usbh_audio.c | ~4000 | 128 * x | 4 + sizeof(struct usbh_audio) * x | 0 |
|usbh_rndis.c | ~3000 | 512 + 2 * 2048(default)| sizeof(struct usbh_rndis) * 1 | 0 |
|usbh_cdc_ecm.c | ~1500 | 2 * 1514 + 16 | sizeof(struct usbh_cdc_ecm) * 1 | 0 |
|usbh_cdc_ncm.c | ~2000 | 2 * 2048(default) + 16 + 32 | sizeof(struct usbh_cdc_ncm) * 1| 0 |
|usbh_bluetooth.c | ~1000 | 2 * 2048(default) | sizeof(struct usbh_bluetooth) * 1 | 0 |
|usbh_asix.c | ~7000 | 2 * 2048(default) + 16 + 32 | sizeof(struct usbh_asix) * 1 | 0 |
|usbh_rtl8152.c | ~9000 | 16K+ 2K(default) + 2 + 32 | sizeof(struct usbh_rtl8152) * 1 | 0 |
其中,`sizeof(struct usbh_hub)``sizeof(struct usbh_hubport)` 受以下宏影响:
@@ -199,7 +204,7 @@ TODO
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with musb |
|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with musb |
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | TBD |
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2 | TBD |
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2/>=v1.5.0 | TBD |
## 软件包支持

View File

@@ -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']):
@@ -106,6 +109,8 @@ if GetDepend(['PKG_CHERRYUSB_DEVICE']):
if GetDepend(['ARCH_ARM_CORTEX_A']):
LIBPATH = [cwd + '/port/pusb2']
LIBS = ['libpusb2_dc_a32_softfp_neon.a']
if GetDepend(['PKG_CHERRYUSB_DEVICE_NRF5X']):
src += Glob('port/nrf5x/usb_dc_nrf5x.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_CDC_ACM']):
src += Glob('class/cdc/usbd_cdc_acm.c')
@@ -123,15 +128,19 @@ if GetDepend(['PKG_CHERRYUSB_DEVICE']):
src += Glob('class/cdc/usbd_cdc_ecm.c')
if GetDepend(['PKG_CHERRYUSB_DEVICE_CDC_NCM']):
src += Glob('class/cdc/usbd_cdc_ncm.c')
if GetDepend(['PKG_CHERRYUSB_USING_DFU']):
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']):
@@ -160,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']):
@@ -220,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']):
@@ -279,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')

View File

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

View File

@@ -120,6 +120,9 @@ if(CONFIG_CHERRYUSB_DEVICE)
elseif(CONFIG_CHERRYUSB_DEVICE_MUSB_BK)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_dc_musb.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_glue_bk.c)
elseif(CONFIG_CHERRYUSB_DEVICE_MUSB_SIFLI)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_dc_musb.c)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_glue_sifli.c)
elseif(CONFIG_CHERRYUSB_DEVICE_MUSB_CUSTOM)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/musb/usb_dc_musb.c)
elseif(CONFIG_CHERRYUSB_DEVICE_CHIPIDEA_MCX)
@@ -257,7 +260,11 @@ if(CONFIG_CHERRYUSB_HOST)
OR CONFIG_CHERRYUSB_HOST_RTL8152
OR CONFIG_CHERRYUSB_HOST_BL616
)
list(APPEND cherryusb_srcs platform/lwip/usbh_lwip.c)
if("${CONFIG_CHERRYUSB_OSAL}" STREQUAL "idf")
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/platform/idf/usbh_net.c)
else()
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/platform/lwip/usbh_lwip.c)
endif()
endif()
if(CONFIG_CHERRYUSB_HOST_EHCI_BL)
@@ -312,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)
@@ -325,7 +335,7 @@ if(CONFIG_CHERRYUSB_HOST)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/rp2040/usb_hc_rp2040.c)
endif()
if(CHERRYUSB_HOST_TEMPLATE)
if(CONFIG_TEST_USBH_CDC_ACM OR CONFIG_TEST_USBH_HID OR CONFIG_TEST_USBH_MSC)
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/demo/usb_host.c)
endif()
endif()

View File

@@ -23,13 +23,15 @@
/* Enable print with color */
#define CONFIG_USB_PRINTF_COLOR_ENABLE
// #define CONFIG_USB_DCACHE_ENABLE
/* data align size when use dma or use dcache */
#ifndef CONFIG_USB_ALIGN_SIZE
#ifdef CONFIG_USB_DCACHE_ENABLE
#define CONFIG_USB_ALIGN_SIZE 32 // 32 or 64
#else
#define CONFIG_USB_ALIGN_SIZE 4
#endif
// #define CONFIG_USB_DCACHE_ENABLE
/* attribute data into no cache ram */
#define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable")))
@@ -45,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
*/
@@ -107,6 +106,28 @@
#define CONFIG_USBDEV_MSC_STACKSIZE 2048
#endif
#ifndef CONFIG_USBDEV_MTP_MAX_BUFSIZE
#define CONFIG_USBDEV_MTP_MAX_BUFSIZE 2048
#endif
#ifndef CONFIG_USBDEV_MTP_MAX_OBJECTS
#define CONFIG_USBDEV_MTP_MAX_OBJECTS 256
#endif
#ifndef CONFIG_USBDEV_MTP_MAX_PATHNAME
#define CONFIG_USBDEV_MTP_MAX_PATHNAME 256
#endif
#define CONFIG_USBDEV_MTP_THREAD
#ifndef CONFIG_USBDEV_MTP_PRIO
#define CONFIG_USBDEV_MTP_PRIO 4
#endif
#ifndef CONFIG_USBDEV_MTP_STACKSIZE
#define CONFIG_USBDEV_MTP_STACKSIZE 4096
#endif
#ifndef CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE
#define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 156
#endif
@@ -238,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 ---------------- */
@@ -296,34 +309,9 @@
/* ---------------- 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
/* ================ USB Dcache Configuration ==================*/
#ifdef CONFIG_USB_DCACHE_ENABLE
/* style 1*/
// void usb_dcache_clean(uintptr_t addr, uint32_t size);
// void usb_dcache_invalidate(uintptr_t addr, uint32_t size);
// void usb_dcache_flush(uintptr_t addr, uint32_t size);
/* style 2*/
// #define usb_dcache_clean(addr, size)
// #define usb_dcache_invalidate(addr, size)
// #define usb_dcache_flush(addr, size)
#endif
#ifndef usb_phyaddr2ramaddr
#define usb_phyaddr2ramaddr(addr) (addr)
#endif

View File

@@ -594,6 +594,7 @@ static int usbh_audio_ctrl_disconnect(struct usbh_hubport *hport, uint8_t intf)
}
if (hport->config.intf[intf].devname[0] != '\0') {
usb_osal_thread_schedule_other();
USB_LOG_INFO("Unregister Audio Class:%s\r\n", hport->config.intf[intf].devname);
usbh_audio_stop(audio_class);
}

View File

@@ -193,6 +193,7 @@ static int usbh_cdc_acm_disconnect(struct usbh_hubport *hport, uint8_t intf)
#endif
if (hport->config.intf[intf].devname[0] != '\0') {
usb_osal_thread_schedule_other();
USB_LOG_INFO("Unregister CDC ACM Class:%s\r\n", hport->config.intf[intf].devname);
usbh_cdc_acm_stop(cdc_acm_class);
}

View File

@@ -221,6 +221,7 @@ static int usbh_cdc_ecm_disconnect(struct usbh_hubport *hport, uint8_t intf)
}
if (hport->config.intf[intf].devname[0] != '\0') {
usb_osal_thread_schedule_other();
USB_LOG_INFO("Unregister CDC ECM Class:%s\r\n", hport->config.intf[intf].devname);
usbh_cdc_ecm_stop(cdc_ecm_class);
}

View File

@@ -52,7 +52,7 @@ static int usbh_cdc_ncm_get_ntb_parameters(struct usbh_cdc_ncm *cdc_ncm_class, s
return ret;
}
memcpy((uint8_t *)param, g_cdc_ncm_buf, ret - 8);
memcpy((uint8_t *)param, g_cdc_ncm_buf, MIN(ret - 8, sizeof(struct cdc_ncm_ntb_parameters)));
return 0;
}
@@ -239,6 +239,7 @@ static int usbh_cdc_ncm_disconnect(struct usbh_hubport *hport, uint8_t intf)
}
if (hport->config.intf[intf].devname[0] != '\0') {
usb_osal_thread_schedule_other();
USB_LOG_INFO("Unregister CDC NCM Class:%s\r\n", hport->config.intf[intf].devname);
usbh_cdc_ncm_stop(cdc_ncm_class);
}

View File

@@ -106,7 +106,7 @@ int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer)
if (ret < 8) {
return ret;
}
memcpy(buffer, g_hid_buf[hid_class->minor], ret - 8);
memcpy(buffer, g_hid_buf[hid_class->minor], MIN(ret - 8, 1));
return ret;
}
@@ -148,7 +148,7 @@ int usbh_hid_get_protocol(struct usbh_hid *hid_class, uint8_t *protocol)
if (ret < 8) {
return ret;
}
memcpy(protocol, g_hid_buf[hid_class->minor], ret - 8);
memcpy(protocol, g_hid_buf[hid_class->minor], MIN(ret - 8, 1));
return ret;
}
@@ -190,7 +190,7 @@ int usbh_hid_get_report(struct usbh_hid *hid_class, uint8_t report_type, uint8_t
if (ret < 8) {
return ret;
}
memcpy(buffer, g_hid_buf[hid_class->minor], ret - 8);
memcpy(buffer, g_hid_buf[hid_class->minor], MIN(ret - 8, buflen));
return ret;
}
@@ -299,6 +299,7 @@ int usbh_hid_disconnect(struct usbh_hubport *hport, uint8_t intf)
}
if (hport->config.intf[intf].devname[0] != '\0') {
usb_osal_thread_schedule_other();
USB_LOG_INFO("Unregister HID Class:%s\r\n", hport->config.intf[intf].devname);
usbh_hid_stop(hid_class);
}

View File

@@ -416,7 +416,7 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
hub->int_buffer = g_hub_intbuf[hub->bus->busid][hub->index - 1];
hub->int_timer = usb_osal_timer_create("hubint_tim", USBH_GET_URB_INTERVAL(hub->intin->bInterval, hport->speed), hub_int_timeout, hub, 0);
hub->int_timer = usb_osal_timer_create("hubint_tim", USBH_GET_URB_INTERVAL(hub->intin->bInterval, hport->speed) / 1000, hub_int_timeout, hub, 0);
if (hub->int_timer == NULL) {
USB_LOG_ERR("No memory to alloc int_timer\r\n");
return -USB_ERR_NOMEM;
@@ -706,8 +706,6 @@ int usbh_hub_deinitialize(struct usbh_bus *bus)
struct usbh_hub *hub;
size_t flags;
flags = usb_osal_enter_critical_section();
hub = &bus->hcd.roothub;
for (uint8_t port = 0; port < hub->nports; port++) {
hport = &hub->child[port];
@@ -715,6 +713,8 @@ int usbh_hub_deinitialize(struct usbh_bus *bus)
usbh_hubport_release(hport);
}
flags = usb_osal_enter_critical_section();
usb_hc_deinit(bus);
usb_osal_leave_critical_section(flags);

View File

@@ -807,7 +807,9 @@ static bool SCSI_CBWDecode(uint8_t busid, uint32_t nbytes)
//ret = SCSI_verify10(NULL, 0);
ret = false;
break;
case SCSI_CMD_SYNCHCACHE10:
ret = true;
break;
default:
SCSI_SetSenseData(busid, SCSI_KCQIR_INVALIDCOMMAND);
USB_LOG_WRN("unsupported cmd:0x%02x\r\n", g_usbd_msc[busid].cbw.CB[0]);

View File

@@ -342,6 +342,7 @@ static int usbh_msc_disconnect(struct usbh_hubport *hport, uint8_t intf)
}
if (hport->config.intf[intf].devname[0] != '\0') {
usb_osal_thread_schedule_other();
USB_LOG_INFO("Unregister MSC Class:%s\r\n", hport->config.intf[intf].devname);
usbh_msc_stop(msc_class);
}

682
class/mtp/usb_mtp.h Normal file
View File

@@ -0,0 +1,682 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Copyright (c) 2025, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef USB_MTP_H
#define USB_MTP_H
// clang-format off
#define MTP_STANDARD_VERSION 100
// Container Types
#define MTP_CONTAINER_TYPE_UNDEFINED 0
#define MTP_CONTAINER_TYPE_COMMAND 1
#define MTP_CONTAINER_TYPE_DATA 2
#define MTP_CONTAINER_TYPE_RESPONSE 3
#define MTP_CONTAINER_TYPE_EVENT 4
// Container Offsets
#define MTP_CONTAINER_LENGTH_OFFSET 0
#define MTP_CONTAINER_TYPE_OFFSET 4
#define MTP_CONTAINER_CODE_OFFSET 6
#define MTP_CONTAINER_TRANSACTION_ID_OFFSET 8
#define MTP_CONTAINER_PARAMETER_OFFSET 12
#define MTP_CONTAINER_HEADER_SIZE 12
// Maximum buffer size for a MTP packet.
#define MTP_BUFFER_SIZE 16384
// MTP Data Types
#define MTP_TYPE_UNDEFINED 0x0000 // Undefined
#define MTP_TYPE_INT8 0x0001 // Signed 8-bit integer
#define MTP_TYPE_UINT8 0x0002 // Unsigned 8-bit integer
#define MTP_TYPE_INT16 0x0003 // Signed 16-bit integer
#define MTP_TYPE_UINT16 0x0004 // Unsigned 16-bit integer
#define MTP_TYPE_INT32 0x0005 // Signed 32-bit integer
#define MTP_TYPE_UINT32 0x0006 // Unsigned 32-bit integer
#define MTP_TYPE_INT64 0x0007 // Signed 64-bit integer
#define MTP_TYPE_UINT64 0x0008 // Unsigned 64-bit integer
#define MTP_TYPE_INT128 0x0009 // Signed 128-bit integer
#define MTP_TYPE_UINT128 0x000A // Unsigned 128-bit integer
#define MTP_TYPE_AINT8 0x4001 // Array of signed 8-bit integers
#define MTP_TYPE_AUINT8 0x4002 // Array of unsigned 8-bit integers
#define MTP_TYPE_AINT16 0x4003 // Array of signed 16-bit integers
#define MTP_TYPE_AUINT16 0x4004 // Array of unsigned 16-bit integers
#define MTP_TYPE_AINT32 0x4005 // Array of signed 32-bit integers
#define MTP_TYPE_AUINT32 0x4006 // Array of unsigned 32-bit integers
#define MTP_TYPE_AINT64 0x4007 // Array of signed 64-bit integers
#define MTP_TYPE_AUINT64 0x4008 // Array of unsigned 64-bit integers
#define MTP_TYPE_AINT128 0x4009 // Array of signed 128-bit integers
#define MTP_TYPE_AUINT128 0x400A // Array of unsigned 128-bit integers
#define MTP_TYPE_STR 0xFFFF // Variable-length Unicode string
// MTP Format Codes
#define MTP_FORMAT_UNDEFINED 0x3000 // Undefined object
#define MTP_FORMAT_ASSOCIATION 0x3001 // Association (for example, a folder)
#define MTP_FORMAT_SCRIPT 0x3002 // Device model-specific script
#define MTP_FORMAT_EXECUTABLE 0x3003 // Device model-specific binary executable
#define MTP_FORMAT_TEXT 0x3004 // Text file
#define MTP_FORMAT_HTML 0x3005 // Hypertext Markup Language file (text)
#define MTP_FORMAT_DPOF 0x3006 // Digital Print Order Format file (text)
#define MTP_FORMAT_AIFF 0x3007 // Audio clip
#define MTP_FORMAT_WAV 0x3008 // Audio clip
#define MTP_FORMAT_MP3 0x3009 // Audio clip
#define MTP_FORMAT_AVI 0x300A // Video clip
#define MTP_FORMAT_MPEG 0x300B // Video clip
#define MTP_FORMAT_ASF 0x300C // Microsoft Advanced Streaming Format (video)
#define MTP_FORMAT_DEFINED 0x3800 // Unknown image object
#define MTP_FORMAT_EXIF_JPEG 0x3801 // Exchangeable File Format, JEIDA standard
#define MTP_FORMAT_TIFF_EP 0x3802 // Tag Image File Format for Electronic Photography
#define MTP_FORMAT_FLASHPIX 0x3803 // Structured Storage Image Format
#define MTP_FORMAT_BMP 0x3804 // Microsoft Windows Bitmap file
#define MTP_FORMAT_CIFF 0x3805 // Canon Camera Image File Format
#define MTP_FORMAT_GIF 0x3807 // Graphics Interchange Format
#define MTP_FORMAT_JFIF 0x3808 // JPEG File Interchange Format
#define MTP_FORMAT_CD 0x3809 // PhotoCD Image Pac
#define MTP_FORMAT_PICT 0x380A // Quickdraw Image Format
#define MTP_FORMAT_PNG 0x380B // Portable Network Graphics
#define MTP_FORMAT_TIFF 0x380D // Tag Image File Format
#define MTP_FORMAT_TIFF_IT 0x380E // Tag Image File Format for Information Technology (graphic arts)
#define MTP_FORMAT_JP2 0x380F // JPEG2000 Baseline File Format
#define MTP_FORMAT_JPX 0x3810 // JPEG2000 Extended File Format
#define MTP_FORMAT_DNG 0x3811 // Digital Negative
#define MTP_FORMAT_HEIF 0x3812 // HEIF images
#define MTP_FORMAT_UNDEFINED_FIRMWARE 0xB802
#define MTP_FORMAT_WINDOWS_IMAGE_FORMAT 0xB881
#define MTP_FORMAT_UNDEFINED_AUDIO 0xB900
#define MTP_FORMAT_WMA 0xB901
#define MTP_FORMAT_OGG 0xB902
#define MTP_FORMAT_AAC 0xB903
#define MTP_FORMAT_AUDIBLE 0xB904
#define MTP_FORMAT_FLAC 0xB906
#define MTP_FORMAT_UNDEFINED_VIDEO 0xB980
#define MTP_FORMAT_WMV 0xB981
#define MTP_FORMAT_MP4_CONTAINER 0xB982 // ISO 14496-1
#define MTP_FORMAT_MP2 0xB983
#define MTP_FORMAT_3GP_CONTAINER 0xB984 // 3GPP file format. Details: http://www.3gpp.org/ftp/Specs/html-info/26244.htm (page title - \u201cTransparent end-to-end packet switched streaming service, 3GPP file format\u201d).
#define MTP_FORMAT_UNDEFINED_COLLECTION 0xBA00
#define MTP_FORMAT_ABSTRACT_MULTIMEDIA_ALBUM 0xBA01
#define MTP_FORMAT_ABSTRACT_IMAGE_ALBUM 0xBA02
#define MTP_FORMAT_ABSTRACT_AUDIO_ALBUM 0xBA03
#define MTP_FORMAT_ABSTRACT_VIDEO_ALBUM 0xBA04
#define MTP_FORMAT_ABSTRACT_AV_PLAYLIST 0xBA05
#define MTP_FORMAT_ABSTRACT_CONTACT_GROUP 0xBA06
#define MTP_FORMAT_ABSTRACT_MESSAGE_FOLDER 0xBA07
#define MTP_FORMAT_ABSTRACT_CHAPTERED_PRODUCTION 0xBA08
#define MTP_FORMAT_ABSTRACT_AUDIO_PLAYLIST 0xBA09
#define MTP_FORMAT_ABSTRACT_VIDEO_PLAYLIST 0xBA0A
#define MTP_FORMAT_ABSTRACT_MEDIACAST 0xBA0B // For use with mediacasts; references multimedia enclosures of RSS feeds or episodic content
#define MTP_FORMAT_WPL_PLAYLIST 0xBA10
#define MTP_FORMAT_M3U_PLAYLIST 0xBA11
#define MTP_FORMAT_MPL_PLAYLIST 0xBA12
#define MTP_FORMAT_ASX_PLAYLIST 0xBA13
#define MTP_FORMAT_PLS_PLAYLIST 0xBA14
#define MTP_FORMAT_UNDEFINED_DOCUMENT 0xBA80
#define MTP_FORMAT_ABSTRACT_DOCUMENT 0xBA81
#define MTP_FORMAT_XML_DOCUMENT 0xBA82
#define MTP_FORMAT_MS_WORD_DOCUMENT 0xBA83
#define MTP_FORMAT_MHT_COMPILED_HTML_DOCUMENT 0xBA84
#define MTP_FORMAT_MS_EXCEL_SPREADSHEET 0xBA85
#define MTP_FORMAT_MS_POWERPOINT_PRESENTATION 0xBA86
#define MTP_FORMAT_UNDEFINED_MESSAGE 0xBB00
#define MTP_FORMAT_ABSTRACT_MESSSAGE 0xBB01
#define MTP_FORMAT_UNDEFINED_CONTACT 0xBB80
#define MTP_FORMAT_ABSTRACT_CONTACT 0xBB81
#define MTP_FORMAT_VCARD_2 0xBB82
// MTP Object Property Codes
#define MTP_PROPERTY_STORAGE_ID 0xDC01
#define MTP_PROPERTY_OBJECT_FORMAT 0xDC02
#define MTP_PROPERTY_PROTECTION_STATUS 0xDC03
#define MTP_PROPERTY_OBJECT_SIZE 0xDC04
#define MTP_PROPERTY_ASSOCIATION_TYPE 0xDC05
#define MTP_PROPERTY_ASSOCIATION_DESC 0xDC06
#define MTP_PROPERTY_OBJECT_FILE_NAME 0xDC07
#define MTP_PROPERTY_DATE_CREATED 0xDC08
#define MTP_PROPERTY_DATE_MODIFIED 0xDC09
#define MTP_PROPERTY_KEYWORDS 0xDC0A
#define MTP_PROPERTY_PARENT_OBJECT 0xDC0B
#define MTP_PROPERTY_ALLOWED_FOLDER_CONTENTS 0xDC0C
#define MTP_PROPERTY_HIDDEN 0xDC0D
#define MTP_PROPERTY_SYSTEM_OBJECT 0xDC0E
#define MTP_PROPERTY_PERSISTENT_UID 0xDC41
#define MTP_PROPERTY_SYNC_ID 0xDC42
#define MTP_PROPERTY_PROPERTY_BAG 0xDC43
#define MTP_PROPERTY_NAME 0xDC44
#define MTP_PROPERTY_CREATED_BY 0xDC45
#define MTP_PROPERTY_ARTIST 0xDC46
#define MTP_PROPERTY_DATE_AUTHORED 0xDC47
#define MTP_PROPERTY_DESCRIPTION 0xDC48
#define MTP_PROPERTY_URL_REFERENCE 0xDC49
#define MTP_PROPERTY_LANGUAGE_LOCALE 0xDC4A
#define MTP_PROPERTY_COPYRIGHT_INFORMATION 0xDC4B
#define MTP_PROPERTY_SOURCE 0xDC4C
#define MTP_PROPERTY_ORIGIN_LOCATION 0xDC4D
#define MTP_PROPERTY_DATE_ADDED 0xDC4E
#define MTP_PROPERTY_NON_CONSUMABLE 0xDC4F
#define MTP_PROPERTY_CORRUPT_UNPLAYABLE 0xDC50
#define MTP_PROPERTY_PRODUCER_SERIAL_NUMBER 0xDC51
#define MTP_PROPERTY_REPRESENTATIVE_SAMPLE_FORMAT 0xDC81
#define MTP_PROPERTY_REPRESENTATIVE_SAMPLE_SIZE 0xDC82
#define MTP_PROPERTY_REPRESENTATIVE_SAMPLE_HEIGHT 0xDC83
#define MTP_PROPERTY_REPRESENTATIVE_SAMPLE_WIDTH 0xDC84
#define MTP_PROPERTY_REPRESENTATIVE_SAMPLE_DURATION 0xDC85
#define MTP_PROPERTY_REPRESENTATIVE_SAMPLE_DATA 0xDC86
#define MTP_PROPERTY_WIDTH 0xDC87
#define MTP_PROPERTY_HEIGHT 0xDC88
#define MTP_PROPERTY_DURATION 0xDC89
#define MTP_PROPERTY_RATING 0xDC8A
#define MTP_PROPERTY_TRACK 0xDC8B
#define MTP_PROPERTY_GENRE 0xDC8C
#define MTP_PROPERTY_CREDITS 0xDC8D
#define MTP_PROPERTY_LYRICS 0xDC8E
#define MTP_PROPERTY_SUBSCRIPTION_CONTENT_ID 0xDC8F
#define MTP_PROPERTY_PRODUCED_BY 0xDC90
#define MTP_PROPERTY_USE_COUNT 0xDC91
#define MTP_PROPERTY_SKIP_COUNT 0xDC92
#define MTP_PROPERTY_LAST_ACCESSED 0xDC93
#define MTP_PROPERTY_PARENTAL_RATING 0xDC94
#define MTP_PROPERTY_META_GENRE 0xDC95
#define MTP_PROPERTY_COMPOSER 0xDC96
#define MTP_PROPERTY_EFFECTIVE_RATING 0xDC97
#define MTP_PROPERTY_SUBTITLE 0xDC98
#define MTP_PROPERTY_ORIGINAL_RELEASE_DATE 0xDC99
#define MTP_PROPERTY_ALBUM_NAME 0xDC9A
#define MTP_PROPERTY_ALBUM_ARTIST 0xDC9B
#define MTP_PROPERTY_MOOD 0xDC9C
#define MTP_PROPERTY_DRM_STATUS 0xDC9D
#define MTP_PROPERTY_SUB_DESCRIPTION 0xDC9E
#define MTP_PROPERTY_IS_CROPPED 0xDCD1
#define MTP_PROPERTY_IS_COLOUR_CORRECTED 0xDCD2
#define MTP_PROPERTY_IMAGE_BIT_DEPTH 0xDCD3
#define MTP_PROPERTY_F_NUMBER 0xDCD4
#define MTP_PROPERTY_EXPOSURE_TIME 0xDCD5
#define MTP_PROPERTY_EXPOSURE_INDEX 0xDCD6
#define MTP_PROPERTY_TOTAL_BITRATE 0xDE91
#define MTP_PROPERTY_BITRATE_TYPE 0xDE92
#define MTP_PROPERTY_SAMPLE_RATE 0xDE93
#define MTP_PROPERTY_NUMBER_OF_CHANNELS 0xDE94
#define MTP_PROPERTY_AUDIO_BIT_DEPTH 0xDE95
#define MTP_PROPERTY_SCAN_TYPE 0xDE97
#define MTP_PROPERTY_AUDIO_WAVE_CODEC 0xDE99
#define MTP_PROPERTY_AUDIO_BITRATE 0xDE9A
#define MTP_PROPERTY_VIDEO_FOURCC_CODEC 0xDE9B
#define MTP_PROPERTY_VIDEO_BITRATE 0xDE9C
#define MTP_PROPERTY_FRAMES_PER_THOUSAND_SECONDS 0xDE9D
#define MTP_PROPERTY_KEYFRAME_DISTANCE 0xDE9E
#define MTP_PROPERTY_BUFFER_SIZE 0xDE9F
#define MTP_PROPERTY_ENCODING_QUALITY 0xDEA0
#define MTP_PROPERTY_ENCODING_PROFILE 0xDEA1
#define MTP_PROPERTY_DISPLAY_NAME 0xDCE0
#define MTP_PROPERTY_BODY_TEXT 0xDCE1
#define MTP_PROPERTY_SUBJECT 0xDCE2
#define MTP_PROPERTY_PRIORITY 0xDCE3
#define MTP_PROPERTY_GIVEN_NAME 0xDD00
#define MTP_PROPERTY_MIDDLE_NAMES 0xDD01
#define MTP_PROPERTY_FAMILY_NAME 0xDD02
#define MTP_PROPERTY_PREFIX 0xDD03
#define MTP_PROPERTY_SUFFIX 0xDD04
#define MTP_PROPERTY_PHONETIC_GIVEN_NAME 0xDD05
#define MTP_PROPERTY_PHONETIC_FAMILY_NAME 0xDD06
#define MTP_PROPERTY_EMAIL_PRIMARY 0xDD07
#define MTP_PROPERTY_EMAIL_PERSONAL_1 0xDD08
#define MTP_PROPERTY_EMAIL_PERSONAL_2 0xDD09
#define MTP_PROPERTY_EMAIL_BUSINESS_1 0xDD0A
#define MTP_PROPERTY_EMAIL_BUSINESS_2 0xDD0B
#define MTP_PROPERTY_EMAIL_OTHERS 0xDD0C
#define MTP_PROPERTY_PHONE_NUMBER_PRIMARY 0xDD0D
#define MTP_PROPERTY_PHONE_NUMBER_PERSONAL 0xDD0E
#define MTP_PROPERTY_PHONE_NUMBER_PERSONAL_2 0xDD0F
#define MTP_PROPERTY_PHONE_NUMBER_BUSINESS 0xDD10
#define MTP_PROPERTY_PHONE_NUMBER_BUSINESS_2 0xDD11
#define MTP_PROPERTY_PHONE_NUMBER_MOBILE 0xDD12
#define MTP_PROPERTY_PHONE_NUMBER_MOBILE_2 0xDD13
#define MTP_PROPERTY_FAX_NUMBER_PRIMARY 0xDD14
#define MTP_PROPERTY_FAX_NUMBER_PERSONAL 0xDD15
#define MTP_PROPERTY_FAX_NUMBER_BUSINESS 0xDD16
#define MTP_PROPERTY_PAGER_NUMBER 0xDD17
#define MTP_PROPERTY_PHONE_NUMBER_OTHERS 0xDD18
#define MTP_PROPERTY_PRIMARY_WEB_ADDRESS 0xDD19
#define MTP_PROPERTY_PERSONAL_WEB_ADDRESS 0xDD1A
#define MTP_PROPERTY_BUSINESS_WEB_ADDRESS 0xDD1B
#define MTP_PROPERTY_INSTANT_MESSANGER_ADDRESS 0xDD1C
#define MTP_PROPERTY_INSTANT_MESSANGER_ADDRESS_2 0xDD1D
#define MTP_PROPERTY_INSTANT_MESSANGER_ADDRESS_3 0xDD1E
#define MTP_PROPERTY_POSTAL_ADDRESS_PERSONAL_FULL 0xDD1F
#define MTP_PROPERTY_POSTAL_ADDRESS_PERSONAL_LINE_1 0xDD20
#define MTP_PROPERTY_POSTAL_ADDRESS_PERSONAL_LINE_2 0xDD21
#define MTP_PROPERTY_POSTAL_ADDRESS_PERSONAL_CITY 0xDD22
#define MTP_PROPERTY_POSTAL_ADDRESS_PERSONAL_REGION 0xDD23
#define MTP_PROPERTY_POSTAL_ADDRESS_PERSONAL_POSTAL_CODE 0xDD24
#define MTP_PROPERTY_POSTAL_ADDRESS_PERSONAL_COUNTRY 0xDD25
#define MTP_PROPERTY_POSTAL_ADDRESS_BUSINESS_FULL 0xDD26
#define MTP_PROPERTY_POSTAL_ADDRESS_BUSINESS_LINE_1 0xDD27
#define MTP_PROPERTY_POSTAL_ADDRESS_BUSINESS_LINE_2 0xDD28
#define MTP_PROPERTY_POSTAL_ADDRESS_BUSINESS_CITY 0xDD29
#define MTP_PROPERTY_POSTAL_ADDRESS_BUSINESS_REGION 0xDD2A
#define MTP_PROPERTY_POSTAL_ADDRESS_BUSINESS_POSTAL_CODE 0xDD2B
#define MTP_PROPERTY_POSTAL_ADDRESS_BUSINESS_COUNTRY 0xDD2C
#define MTP_PROPERTY_POSTAL_ADDRESS_OTHER_FULL 0xDD2D
#define MTP_PROPERTY_POSTAL_ADDRESS_OTHER_LINE_1 0xDD2E
#define MTP_PROPERTY_POSTAL_ADDRESS_OTHER_LINE_2 0xDD2F
#define MTP_PROPERTY_POSTAL_ADDRESS_OTHER_CITY 0xDD30
#define MTP_PROPERTY_POSTAL_ADDRESS_OTHER_REGION 0xDD31
#define MTP_PROPERTY_POSTAL_ADDRESS_OTHER_POSTAL_CODE 0xDD32
#define MTP_PROPERTY_POSTAL_ADDRESS_OTHER_COUNTRY 0xDD33
#define MTP_PROPERTY_ORGANIZATION_NAME 0xDD34
#define MTP_PROPERTY_PHONETIC_ORGANIZATION_NAME 0xDD35
#define MTP_PROPERTY_ROLE 0xDD36
#define MTP_PROPERTY_BIRTHDATE 0xDD37
#define MTP_PROPERTY_MESSAGE_TO 0xDD40
#define MTP_PROPERTY_MESSAGE_CC 0xDD41
#define MTP_PROPERTY_MESSAGE_BCC 0xDD42
#define MTP_PROPERTY_MESSAGE_READ 0xDD43
#define MTP_PROPERTY_MESSAGE_RECEIVED_TIME 0xDD44
#define MTP_PROPERTY_MESSAGE_SENDER 0xDD45
#define MTP_PROPERTY_ACTIVITY_BEGIN_TIME 0xDD50
#define MTP_PROPERTY_ACTIVITY_END_TIME 0xDD51
#define MTP_PROPERTY_ACTIVITY_LOCATION 0xDD52
#define MTP_PROPERTY_ACTIVITY_REQUIRED_ATTENDEES 0xDD54
#define MTP_PROPERTY_ACTIVITY_OPTIONAL_ATTENDEES 0xDD55
#define MTP_PROPERTY_ACTIVITY_RESOURCES 0xDD56
#define MTP_PROPERTY_ACTIVITY_ACCEPTED 0xDD57
#define MTP_PROPERTY_ACTIVITY_TENTATIVE 0xDD58
#define MTP_PROPERTY_ACTIVITY_DECLINED 0xDD59
#define MTP_PROPERTY_ACTIVITY_REMAINDER_TIME 0xDD5A
#define MTP_PROPERTY_ACTIVITY_OWNER 0xDD5B
#define MTP_PROPERTY_ACTIVITY_STATUS 0xDD5C
#define MTP_PROPERTY_OWNER 0xDD5D
#define MTP_PROPERTY_EDITOR 0xDD5E
#define MTP_PROPERTY_WEBMASTER 0xDD5F
#define MTP_PROPERTY_URL_SOURCE 0xDD60
#define MTP_PROPERTY_URL_DESTINATION 0xDD61
#define MTP_PROPERTY_TIME_BOOKMARK 0xDD62
#define MTP_PROPERTY_OBJECT_BOOKMARK 0xDD63
#define MTP_PROPERTY_BYTE_BOOKMARK 0xDD64
#define MTP_PROPERTY_LAST_BUILD_DATE 0xDD70
#define MTP_PROPERTY_TIME_TO_LIVE 0xDD71
#define MTP_PROPERTY_MEDIA_GUID 0xDD72
// MTP Device Property Codes
#define MTP_DEVICE_PROPERTY_UNDEFINED 0x5000
#define MTP_DEVICE_PROPERTY_BATTERY_LEVEL 0x5001
#define MTP_DEVICE_PROPERTY_FUNCTIONAL_MODE 0x5002
#define MTP_DEVICE_PROPERTY_IMAGE_SIZE 0x5003
#define MTP_DEVICE_PROPERTY_COMPRESSION_SETTING 0x5004
#define MTP_DEVICE_PROPERTY_WHITE_BALANCE 0x5005
#define MTP_DEVICE_PROPERTY_RGB_GAIN 0x5006
#define MTP_DEVICE_PROPERTY_F_NUMBER 0x5007
#define MTP_DEVICE_PROPERTY_FOCAL_LENGTH 0x5008
#define MTP_DEVICE_PROPERTY_FOCUS_DISTANCE 0x5009
#define MTP_DEVICE_PROPERTY_FOCUS_MODE 0x500A
#define MTP_DEVICE_PROPERTY_EXPOSURE_METERING_MODE 0x500B
#define MTP_DEVICE_PROPERTY_FLASH_MODE 0x500C
#define MTP_DEVICE_PROPERTY_EXPOSURE_TIME 0x500D
#define MTP_DEVICE_PROPERTY_EXPOSURE_PROGRAM_MODE 0x500E
#define MTP_DEVICE_PROPERTY_EXPOSURE_INDEX 0x500F
#define MTP_DEVICE_PROPERTY_EXPOSURE_BIAS_COMPENSATION 0x5010
#define MTP_DEVICE_PROPERTY_DATETIME 0x5011
#define MTP_DEVICE_PROPERTY_CAPTURE_DELAY 0x5012
#define MTP_DEVICE_PROPERTY_STILL_CAPTURE_MODE 0x5013
#define MTP_DEVICE_PROPERTY_CONTRAST 0x5014
#define MTP_DEVICE_PROPERTY_SHARPNESS 0x5015
#define MTP_DEVICE_PROPERTY_DIGITAL_ZOOM 0x5016
#define MTP_DEVICE_PROPERTY_EFFECT_MODE 0x5017
#define MTP_DEVICE_PROPERTY_BURST_NUMBER 0x5018
#define MTP_DEVICE_PROPERTY_BURST_INTERVAL 0x5019
#define MTP_DEVICE_PROPERTY_TIMELAPSE_NUMBER 0x501A
#define MTP_DEVICE_PROPERTY_TIMELAPSE_INTERVAL 0x501B
#define MTP_DEVICE_PROPERTY_FOCUS_METERING_MODE 0x501C
#define MTP_DEVICE_PROPERTY_UPLOAD_URL 0x501D
#define MTP_DEVICE_PROPERTY_ARTIST 0x501E
#define MTP_DEVICE_PROPERTY_COPYRIGHT_INFO 0x501F
#define MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER 0xD401
#define MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME 0xD402
#define MTP_DEVICE_PROPERTY_VOLUME 0xD403
#define MTP_DEVICE_PROPERTY_SUPPORTED_FORMATS_ORDERED 0xD404
#define MTP_DEVICE_PROPERTY_DEVICE_ICON 0xD405
#define MTP_DEVICE_PROPERTY_PLAYBACK_RATE 0xD410
#define MTP_DEVICE_PROPERTY_PLAYBACK_OBJECT 0xD411
#define MTP_DEVICE_PROPERTY_PLAYBACK_CONTAINER_INDEX 0xD412
#define MTP_DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO 0xD406
#define MTP_DEVICE_PROPERTY_PERCEIVED_DEVICE_TYPE 0xD407
// MTP Operation Codes
#define MTP_OPERATION_GET_DEVICE_INFO 0x1001
#define MTP_OPERATION_OPEN_SESSION 0x1002
#define MTP_OPERATION_CLOSE_SESSION 0x1003
#define MTP_OPERATION_GET_STORAGE_IDS 0x1004
#define MTP_OPERATION_GET_STORAGE_INFO 0x1005
#define MTP_OPERATION_GET_NUM_OBJECTS 0x1006
#define MTP_OPERATION_GET_OBJECT_HANDLES 0x1007
#define MTP_OPERATION_GET_OBJECT_INFO 0x1008
#define MTP_OPERATION_GET_OBJECT 0x1009
#define MTP_OPERATION_GET_THUMB 0x100A
#define MTP_OPERATION_DELETE_OBJECT 0x100B
#define MTP_OPERATION_SEND_OBJECT_INFO 0x100C
#define MTP_OPERATION_SEND_OBJECT 0x100D
#define MTP_OPERATION_INITIATE_CAPTURE 0x100E
#define MTP_OPERATION_FORMAT_STORE 0x100F
#define MTP_OPERATION_RESET_DEVICE 0x1010
#define MTP_OPERATION_SELF_TEST 0x1011
#define MTP_OPERATION_SET_OBJECT_PROTECTION 0x1012
#define MTP_OPERATION_POWER_DOWN 0x1013
#define MTP_OPERATION_GET_DEVICE_PROP_DESC 0x1014
#define MTP_OPERATION_GET_DEVICE_PROP_VALUE 0x1015
#define MTP_OPERATION_SET_DEVICE_PROP_VALUE 0x1016
#define MTP_OPERATION_RESET_DEVICE_PROP_VALUE 0x1017
#define MTP_OPERATION_TERMINATE_OPEN_CAPTURE 0x1018
#define MTP_OPERATION_MOVE_OBJECT 0x1019
#define MTP_OPERATION_COPY_OBJECT 0x101A
#define MTP_OPERATION_GET_PARTIAL_OBJECT 0x101B
#define MTP_OPERATION_INITIATE_OPEN_CAPTURE 0x101C
#define MTP_OPERATION_GET_OBJECT_PROPS_SUPPORTED 0x9801
#define MTP_OPERATION_GET_OBJECT_PROP_DESC 0x9802
#define MTP_OPERATION_GET_OBJECT_PROP_VALUE 0x9803
#define MTP_OPERATION_SET_OBJECT_PROP_VALUE 0x9804
#define MTP_OPERATION_GET_OBJECT_PROP_LIST 0x9805
#define MTP_OPERATION_SET_OBJECT_PROP_LIST 0x9806
#define MTP_OPERATION_GET_INTERDEPENDENT_PROP_DESC 0x9807
#define MTP_OPERATION_SEND_OBJECT_PROP_LIST 0x9808
#define MTP_OPERATION_GET_OBJECT_REFERENCES 0x9810
#define MTP_OPERATION_SET_OBJECT_REFERENCES 0x9811
#define MTP_OPERATION_SKIP 0x9820
// Android extensions for direct file IO
// Same as GetPartialObject, but with 64 bit offset
#define MTP_OPERATION_GET_PARTIAL_OBJECT_64 0x95C1
// Same as GetPartialObject64, but copying host to device
#define MTP_OPERATION_SEND_PARTIAL_OBJECT 0x95C2
// Truncates file to 64 bit length
#define MTP_OPERATION_TRUNCATE_OBJECT 0x95C3
// Must be called before using SendPartialObject and TruncateObject
#define MTP_OPERATION_BEGIN_EDIT_OBJECT 0x95C4
// Called to commit changes made by SendPartialObject and TruncateObject
#define MTP_OPERATION_END_EDIT_OBJECT 0x95C5
// MTP Response Codes
#define MTP_RESPONSE_UNDEFINED 0x2000
#define MTP_RESPONSE_OK 0x2001
#define MTP_RESPONSE_GENERAL_ERROR 0x2002
#define MTP_RESPONSE_SESSION_NOT_OPEN 0x2003
#define MTP_RESPONSE_INVALID_TRANSACTION_ID 0x2004
#define MTP_RESPONSE_OPERATION_NOT_SUPPORTED 0x2005
#define MTP_RESPONSE_PARAMETER_NOT_SUPPORTED 0x2006
#define MTP_RESPONSE_INCOMPLETE_TRANSFER 0x2007
#define MTP_RESPONSE_INVALID_STORAGE_ID 0x2008
#define MTP_RESPONSE_INVALID_OBJECT_HANDLE 0x2009
#define MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED 0x200A
#define MTP_RESPONSE_INVALID_OBJECT_FORMAT_CODE 0x200B
#define MTP_RESPONSE_STORAGE_FULL 0x200C
#define MTP_RESPONSE_OBJECT_WRITE_PROTECTED 0x200D
#define MTP_RESPONSE_STORE_READ_ONLY 0x200E
#define MTP_RESPONSE_ACCESS_DENIED 0x200F
#define MTP_RESPONSE_NO_THUMBNAIL_PRESENT 0x2010
#define MTP_RESPONSE_SELF_TEST_FAILED 0x2011
#define MTP_RESPONSE_PARTIAL_DELETION 0x2012
#define MTP_RESPONSE_STORE_NOT_AVAILABLE 0x2013
#define MTP_RESPONSE_SPECIFICATION_BY_FORMAT_UNSUPPORTED 0x2014
#define MTP_RESPONSE_NO_VALID_OBJECT_INFO 0x2015
#define MTP_RESPONSE_INVALID_CODE_FORMAT 0x2016
#define MTP_RESPONSE_UNKNOWN_VENDOR_CODE 0x2017
#define MTP_RESPONSE_CAPTURE_ALREADY_TERMINATED 0x2018
#define MTP_RESPONSE_DEVICE_BUSY 0x2019
#define MTP_RESPONSE_INVALID_PARENT_OBJECT 0x201A
#define MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT 0x201B
#define MTP_RESPONSE_INVALID_DEVICE_PROP_VALUE 0x201C
#define MTP_RESPONSE_INVALID_PARAMETER 0x201D
#define MTP_RESPONSE_SESSION_ALREADY_OPEN 0x201E
#define MTP_RESPONSE_TRANSACTION_CANCELLED 0x201F
#define MTP_RESPONSE_SPECIFICATION_OF_DESTINATION_UNSUPPORTED 0x2020
#define MTP_RESPONSE_INVALID_OBJECT_PROP_CODE 0xA801
#define MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT 0xA802
#define MTP_RESPONSE_INVALID_OBJECT_PROP_VALUE 0xA803
#define MTP_RESPONSE_INVALID_OBJECT_REFERENCE 0xA804
#define MTP_RESPONSE_GROUP_NOT_SUPPORTED 0xA805
#define MTP_RESPONSE_INVALID_DATASET 0xA806
#define MTP_RESPONSE_SPECIFICATION_BY_GROUP_UNSUPPORTED 0xA807
#define MTP_RESPONSE_SPECIFICATION_BY_DEPTH_UNSUPPORTED 0xA808
#define MTP_RESPONSE_OBJECT_TOO_LARGE 0xA809
#define MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED 0xA80A
#define MTP_RESPONSE_NO_RESPONSE 0xFFFF
// MTP Event Codes
#define MTP_EVENT_UNDEFINED 0x4000
#define MTP_EVENT_CANCEL_TRANSACTION 0x4001
#define MTP_EVENT_OBJECT_ADDED 0x4002
#define MTP_EVENT_OBJECT_REMOVED 0x4003
#define MTP_EVENT_STORE_ADDED 0x4004
#define MTP_EVENT_STORE_REMOVED 0x4005
#define MTP_EVENT_DEVICE_PROP_CHANGED 0x4006
#define MTP_EVENT_OBJECT_INFO_CHANGED 0x4007
#define MTP_EVENT_DEVICE_INFO_CHANGED 0x4008
#define MTP_EVENT_REQUEST_OBJECT_TRANSFER 0x4009
#define MTP_EVENT_STORE_FULL 0x400A
#define MTP_EVENT_DEVICE_RESET 0x400B
#define MTP_EVENT_STORAGE_INFO_CHANGED 0x400C
#define MTP_EVENT_CAPTURE_COMPLETE 0x400D
#define MTP_EVENT_UNREPORTED_STATUS 0x400E
#define MTP_EVENT_OBJECT_PROP_CHANGED 0xC801
#define MTP_EVENT_OBJECT_PROP_DESC_CHANGED 0xC802
#define MTP_EVENT_OBJECT_REFERENCES_CHANGED 0xC803
// Storage Type
#define MTP_STORAGE_FIXED_ROM 0x0001
#define MTP_STORAGE_REMOVABLE_ROM 0x0002
#define MTP_STORAGE_FIXED_RAM 0x0003
#define MTP_STORAGE_REMOVABLE_RAM 0x0004
// Storage File System
#define MTP_STORAGE_FILESYSTEM_FLAT 0x0001
#define MTP_STORAGE_FILESYSTEM_HIERARCHICAL 0x0002
#define MTP_STORAGE_FILESYSTEM_DCF 0x0003
// Storage Access Capability
#define MTP_STORAGE_READ_WRITE 0x0000
#define MTP_STORAGE_READ_ONLY_WITHOUT_DELETE 0x0001
#define MTP_STORAGE_READ_ONLY_WITH_DELETE 0x0002
// Association Type
#define MTP_ASSOCIATION_TYPE_UNDEFINED 0x0000
#define MTP_ASSOCIATION_TYPE_GENERIC_FOLDER 0x0001
// MTP class reqeusts
#define MTP_REQUEST_CANCEL 0x64
#define MTP_REQUEST_GET_EXT_EVENT_DATA 0x65
#define MTP_REQUEST_RESET 0x66
#define MTP_REQUEST_GET_DEVICE_STATUS 0x67
// clang-format on
#define USB_MTP_CLASS 0x06
#define USB_MTP_SUB_CLASS 0x01U
#define USB_MTP_PROTOCOL 0x01U
struct mtp_header {
uint32_t conlen;
uint16_t contype;
uint16_t code;
uint32_t trans_id;
uint32_t param[];
};
struct mtp_string {
uint8_t len;
uint16_t string[255];
};
struct mtp_device_info {
uint16_t StandardVersion;
uint32_t VendorExtensionID;
uint16_t VendorExtensionVersion;
uint8_t VendorExtensionDesc_len;
uint16_t VendorExtensionDesc[255];
uint16_t FunctionalMode;
uint32_t OperationsSupported_len;
uint16_t OperationsSupported[255];
uint32_t EventsSupported_len;
uint16_t EventsSupported[255];
uint32_t DevicePropertiesSupported_len;
uint16_t DevicePropertiesSupported[255];
uint32_t CaptureFormats_len;
uint16_t CaptureFormats[255];
uint32_t ImageFormats_len;
uint16_t ImageFormats[255];
uint8_t Manufacturer_len;
uint16_t Manufacturer[255];
uint8_t Model_len;
uint16_t Model[255];
uint8_t DeviceVersion_len;
uint16_t DeviceVersion[255];
uint8_t SerialNumber_len;
uint16_t SerialNumber[255];
} __PACKED;
struct mtp_object_props_support {
uint32_t ObjectPropCode_len;
uint16_t ObjectPropCode[255];
} __PACKED;
struct mtp_device_prop_desc {
uint16_t DevicePropertyCode;
uint16_t DataType;
uint8_t GetSet;
uint16_t DefaultValue[1];
uint16_t CurrentValue[1];
uint8_t FormFlag;
} __PACKED;
struct mtp_storage_id {
uint32_t StorageIDS_len;
uint32_t StorageIDS[255];
} __PACKED;
struct mtp_storage_info {
uint16_t StorageType;
uint16_t FilesystemType;
uint16_t AccessCapability;
uint64_t MaxCapability;
uint64_t FreeSpaceInBytes;
uint32_t FreeSpaceInObjects;
uint8_t StorageDescription_len;
uint8_t StorageDescription[255];
uint8_t VolumeIdentifier_len;
uint8_t VolumeIdentifier[255];
} __PACKED;
struct mtp_object_handles {
uint32_t ObjectHandle_len;
uint32_t ObjectHandle[255];
} __PACKED;
struct mtp_object_prop_desc {
uint16_t ObjectPropertyCode;
uint16_t DataType;
uint8_t GetSet;
uint8_t DefValue[16];
uint32_t GroupCode;
uint8_t FormFlag;
} __PACKED;
struct mtp_object_prop_element {
uint32_t ObjectHandle;
uint16_t PropertyCode;
uint16_t Datatype;
uint8_t value[8];
} __PACKED;
struct mtp_object_prop_list {
uint32_t element_len;
struct mtp_object_prop_element element[1];
} __PACKED;
struct mtp_object_info {
uint32_t StorageId;
uint16_t ObjectFormat;
uint16_t ProtectionStatus;
uint32_t ObjectCompressedSize;
uint16_t ThumbFormat;
uint32_t ThumbCompressedSize;
uint32_t ThumbPixWidth;
uint32_t ThumbPixHeight;
uint32_t ImagePixWidth;
uint32_t ImagePixHeight;
uint32_t ImageBitDepth;
uint32_t ParentObject;
uint16_t AssociationType;
uint32_t AssociationDesc;
uint32_t SequenceNumber;
uint8_t Filename_len;
uint16_t Filename[CONFIG_USBDEV_MTP_MAX_PATHNAME];
uint8_t CaptureDate[6];
uint8_t ModificationDate[6];
} __PACKED;
struct mtp_object {
uint32_t storage_id;
uint32_t handle;
uint32_t parent_handle;
uint16_t format;
bool is_dir;
bool is_readonly;
bool is_hidden;
uint32_t file_size;
uint32_t file_full_name_length;
char file_full_name[CONFIG_USBDEV_MTP_MAX_PATHNAME];
bool in_use;
};
/*Length of template descriptor: 23 bytes*/
#define MTP_DESCRIPTOR_LEN (9 + 7 + 7 + 7)
// clang-format off
#define MTP_DESCRIPTOR_INIT(bFirstInterface, out_ep, in_ep, int_ep, wMaxPacketSize, str_idx) \
/* Interface */ \
0x09, /* bLength */ \
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
bFirstInterface, /* bInterfaceNumber */ \
0x00, /* bAlternateSetting */ \
0x03, /* bNumEndpoints */ \
USB_DEVICE_CLASS_IMAGE, /* bInterfaceClass */ \
USB_MTP_SUB_CLASS, /* bInterfaceSubClass */ \
USB_MTP_PROTOCOL, /* bInterfaceProtocol */ \
str_idx, /* iInterface */ \
0x07, /* bLength */ \
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
out_ep, /* bEndpointAddress */ \
0x02, /* bmAttributes */ \
WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \
0x00, /* bInterval */ \
0x07, /* bLength */ \
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
in_ep, /* bEndpointAddress */ \
0x02, /* bmAttributes */ \
WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \
0x00, /* bInterval */ \
0x07, /* bLength */ \
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
int_ep, /* bEndpointAddress */ \
0x03, /* bmAttributes */ \
WBVAL(0x1c), /* wMaxPacketSize */ \
0x06 /* bInterval */
// clang-format on
#endif

65
class/mtp/usbd_mtp.h Normal file
View File

@@ -0,0 +1,65 @@
/*
* Copyright (c) 2025, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef USBD_MTP_H
#define USBD_MTP_H
#include "usb_mtp.h"
#include <sys/stat.h>
#include <fcntl.h>
/* gcc toolchain does not implement dirent.h, so we define our own MTP_DIR and mtp_dirent */
typedef void MTP_DIR;
struct mtp_statfs {
size_t f_bsize; /* block size */
size_t f_blocks; /* total data blocks in file system */
size_t f_bfree; /* free blocks in file system */
};
struct mtp_dirent {
uint8_t d_type; /* The type of the file */
uint8_t d_namlen; /* The length of the not including the terminating null file name */
uint16_t d_reclen; /* length of this record */
char d_name[CONFIG_USBDEV_MTP_MAX_PATHNAME]; /* The null-terminated file name */
};
#ifdef __cplusplus
extern "C" {
#endif
struct usbd_interface *usbd_mtp_init_intf(struct usbd_interface *intf,
const uint8_t out_ep,
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);
int usbd_mtp_mkdir(const char *path);
int usbd_mtp_rmdir(const char *path);
MTP_DIR *usbd_mtp_opendir(const char *name);
int usbd_mtp_closedir(MTP_DIR *d);
struct mtp_dirent *usbd_mtp_readdir(MTP_DIR *d);
int usbd_mtp_statfs(const char *path, struct mtp_statfs *buf);
int usbd_mtp_stat(const char *file, struct stat *buf);
int usbd_mtp_open(const char *path, uint8_t mode);
int usbd_mtp_close(int fd);
int usbd_mtp_read(int fd, void *buf, size_t len);
int usbd_mtp_write(int fd, const void *buf, size_t len);
int usbd_mtp_unlink(const char *path);
#ifdef __cplusplus
}
#endif
#endif /* USBD_MTP_H */

View File

@@ -0,0 +1,312 @@
/*
* Copyright (c) 2025, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef USBD_MTP_SUPPORT_H
#define USBD_MTP_SUPPORT_H
#define MTP_VERSION 100
typedef struct _profile_property {
uint16_t prop_code;
uint16_t data_type;
uint8_t getset;
uint64_t default_value;
uint32_t group_code;
uint8_t form_flag;
uint16_t format_code;
} profile_property;
typedef struct _format_property {
uint16_t format_code;
uint16_t *properties;
} formats_property;
const char mtp_extension_string[] = "microsoft.com: 1.0; android.com: 1.0;";
const uint16_t supported_op[] = {
MTP_OPERATION_GET_DEVICE_INFO, //0x1001
MTP_OPERATION_OPEN_SESSION, //0x1002
MTP_OPERATION_CLOSE_SESSION, //0x1003
MTP_OPERATION_GET_STORAGE_IDS, //0x1004
MTP_OPERATION_GET_STORAGE_INFO, //0x1005
//MTP_OPERATION_GET_NUM_OBJECTS ,//0x1006
MTP_OPERATION_GET_OBJECT_HANDLES, //0x1007
MTP_OPERATION_GET_OBJECT_INFO, //0x1008
MTP_OPERATION_GET_OBJECT, //0x1009
//MTP_OPERATION_GET_THUMB ,//0x100A
MTP_OPERATION_DELETE_OBJECT, //0x100B
MTP_OPERATION_SEND_OBJECT_INFO, //0x100C
MTP_OPERATION_SEND_OBJECT, //0x100D
MTP_OPERATION_GET_DEVICE_PROP_DESC, //0x1014
// MTP_OPERATION_GET_DEVICE_PROP_VALUE ,//0x1015
// MTP_OPERATION_SET_DEVICE_PROP_VALUE ,//0x1016
//MTP_OPERATION_RESET_DEVICE_PROP_VALUE ,//0x1017
// MTP_OPERATION_GET_PARTIAL_OBJECT ,//0x101B
MTP_OPERATION_GET_OBJECT_PROPS_SUPPORTED, //0x9801
// MTP_OPERATION_GET_OBJECT_PROP_DESC, //0x9802
// MTP_OPERATION_GET_OBJECT_PROP_VALUE ,//0x9803
// MTP_OPERATION_SET_OBJECT_PROP_VALUE ,//0x9804
// MTP_OPERATION_GET_OBJECT_PROP_LIST ,//0x9805
//MTP_OPERATION_GET_OBJECT_REFERENCES ,//0x9810
//MTP_OPERATION_SET_OBJECT_REFERENCES ,//0x9811
// MTP_OPERATION_GET_PARTIAL_OBJECT_64 ,//0x95C1
// MTP_OPERATION_SEND_PARTIAL_OBJECT ,//0x95C2
// MTP_OPERATION_TRUNCATE_OBJECT ,//0x95C3
// MTP_OPERATION_BEGIN_EDIT_OBJECT ,//0x95C4
// MTP_OPERATION_END_EDIT_OBJECT //0x95C5
};
int supported_op_size = sizeof(supported_op);
const uint16_t supported_event[] = {
MTP_EVENT_OBJECT_ADDED, // 0x4002
MTP_EVENT_OBJECT_REMOVED, // 0x4003
MTP_EVENT_STORE_ADDED, // 0x4004
MTP_EVENT_STORE_REMOVED, // 0x4005
MTP_EVENT_STORAGE_INFO_CHANGED, // 0x400C
MTP_EVENT_OBJECT_INFO_CHANGED, // 0x4007
MTP_EVENT_DEVICE_PROP_CHANGED, // 0x4006
MTP_EVENT_OBJECT_PROP_CHANGED // 0xC801
};
int supported_event_size = sizeof(supported_event);
const formats_property support_format_properties[] = {
// format code prop code
{ MTP_FORMAT_UNDEFINED, (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED,
0xFFFF } },
{ MTP_FORMAT_ASSOCIATION, (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED,
0xFFFF } }
#if 0
{ MTP_FORMAT_TEXT , (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED,
0xFFFF}
},
{ MTP_FORMAT_HTML , (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED,
0xFFFF}
},
{ MTP_FORMAT_MP4_CONTAINER, (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED, MTP_PROPERTY_ARTIST, MTP_PROPERTY_ALBUM_NAME,
MTP_PROPERTY_DURATION, MTP_PROPERTY_DESCRIPTION, MTP_PROPERTY_WIDTH, MTP_PROPERTY_HEIGHT, MTP_PROPERTY_DATE_AUTHORED,
0xFFFF}
},
{ MTP_FORMAT_3GP_CONTAINER, (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED, MTP_PROPERTY_ARTIST, MTP_PROPERTY_ALBUM_NAME,
MTP_PROPERTY_DURATION, MTP_PROPERTY_DESCRIPTION, MTP_PROPERTY_WIDTH, MTP_PROPERTY_HEIGHT, MTP_PROPERTY_DATE_AUTHORED,
0xFFFF}
},
{ MTP_FORMAT_WAV , (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED,MTP_PROPERTY_ARTIST,MTP_PROPERTY_ALBUM_NAME,
MTP_PROPERTY_ALBUM_ARTIST, MTP_PROPERTY_TRACK, MTP_PROPERTY_ORIGINAL_RELEASE_DATE, MTP_PROPERTY_GENRE, MTP_PROPERTY_COMPOSER,
MTP_PROPERTY_AUDIO_WAVE_CODEC, MTP_PROPERTY_BITRATE_TYPE, MTP_PROPERTY_AUDIO_BITRATE, MTP_PROPERTY_NUMBER_OF_CHANNELS,MTP_PROPERTY_SAMPLE_RATE,
0xFFFF}
},
{ MTP_FORMAT_MP3 , (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED,MTP_PROPERTY_ARTIST,MTP_PROPERTY_ALBUM_NAME,
MTP_PROPERTY_ALBUM_ARTIST, MTP_PROPERTY_TRACK, MTP_PROPERTY_ORIGINAL_RELEASE_DATE, MTP_PROPERTY_GENRE, MTP_PROPERTY_COMPOSER,
MTP_PROPERTY_AUDIO_WAVE_CODEC, MTP_PROPERTY_BITRATE_TYPE, MTP_PROPERTY_AUDIO_BITRATE, MTP_PROPERTY_NUMBER_OF_CHANNELS,MTP_PROPERTY_SAMPLE_RATE,
0xFFFF}
},
{ MTP_FORMAT_MPEG , (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED, MTP_PROPERTY_ARTIST, MTP_PROPERTY_ALBUM_NAME,
MTP_PROPERTY_DURATION, MTP_PROPERTY_DESCRIPTION, MTP_PROPERTY_WIDTH, MTP_PROPERTY_HEIGHT, MTP_PROPERTY_DATE_AUTHORED,
0xFFFF}
},
{ MTP_FORMAT_EXIF_JPEG , (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED, MTP_PROPERTY_DESCRIPTION, MTP_PROPERTY_WIDTH,
MTP_PROPERTY_HEIGHT, MTP_PROPERTY_DATE_AUTHORED,
0xFFFF}
},
{ MTP_FORMAT_BMP , (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED, MTP_PROPERTY_DESCRIPTION, MTP_PROPERTY_WIDTH,
MTP_PROPERTY_HEIGHT, MTP_PROPERTY_DATE_AUTHORED,
0xFFFF}
},
{ MTP_FORMAT_GIF , (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED, MTP_PROPERTY_DESCRIPTION, MTP_PROPERTY_WIDTH,
MTP_PROPERTY_HEIGHT, MTP_PROPERTY_DATE_AUTHORED,
0xFFFF}
},
{ MTP_FORMAT_JFIF , (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED, MTP_PROPERTY_DESCRIPTION, MTP_PROPERTY_WIDTH,
MTP_PROPERTY_HEIGHT, MTP_PROPERTY_DATE_AUTHORED,
0xFFFF}
},
{ MTP_FORMAT_WMA , (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED, MTP_PROPERTY_ARTIST, MTP_PROPERTY_ALBUM_NAME,
MTP_PROPERTY_ALBUM_ARTIST, MTP_PROPERTY_TRACK, MTP_PROPERTY_ORIGINAL_RELEASE_DATE, MTP_PROPERTY_DURATION, MTP_PROPERTY_DESCRIPTION,
MTP_PROPERTY_GENRE, MTP_PROPERTY_COMPOSER, MTP_PROPERTY_AUDIO_WAVE_CODEC, MTP_PROPERTY_BITRATE_TYPE, MTP_PROPERTY_AUDIO_BITRATE,
MTP_PROPERTY_NUMBER_OF_CHANNELS, MTP_PROPERTY_SAMPLE_RATE,
0xFFFF}
},
{ MTP_FORMAT_OGG , (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED, MTP_PROPERTY_ARTIST, MTP_PROPERTY_ALBUM_NAME,
MTP_PROPERTY_ALBUM_ARTIST, MTP_PROPERTY_TRACK, MTP_PROPERTY_ORIGINAL_RELEASE_DATE, MTP_PROPERTY_DURATION, MTP_PROPERTY_DESCRIPTION,
MTP_PROPERTY_GENRE, MTP_PROPERTY_COMPOSER, MTP_PROPERTY_AUDIO_WAVE_CODEC, MTP_PROPERTY_BITRATE_TYPE, MTP_PROPERTY_AUDIO_BITRATE,
MTP_PROPERTY_NUMBER_OF_CHANNELS, MTP_PROPERTY_SAMPLE_RATE,
0xFFFF}
},
{ MTP_FORMAT_AAC , (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED, MTP_PROPERTY_ARTIST, MTP_PROPERTY_ALBUM_NAME,
MTP_PROPERTY_ALBUM_ARTIST, MTP_PROPERTY_TRACK, MTP_PROPERTY_ORIGINAL_RELEASE_DATE, MTP_PROPERTY_DURATION, MTP_PROPERTY_DESCRIPTION,
MTP_PROPERTY_GENRE, MTP_PROPERTY_COMPOSER, MTP_PROPERTY_AUDIO_WAVE_CODEC, MTP_PROPERTY_BITRATE_TYPE, MTP_PROPERTY_AUDIO_BITRATE,
MTP_PROPERTY_NUMBER_OF_CHANNELS, MTP_PROPERTY_SAMPLE_RATE,
0xFFFF}
},
{ MTP_FORMAT_ABSTRACT_AV_PLAYLIST, (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED,
0xFFFF}
},
{ MTP_FORMAT_WPL_PLAYLIST, (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED,
0xFFFF}
},
{ MTP_FORMAT_M3U_PLAYLIST, (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED,
0xFFFF}
},
{ MTP_FORMAT_PLS_PLAYLIST, (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED,
0xFFFF}
},
{ MTP_FORMAT_XML_DOCUMENT, (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED,
0xFFFF}
},
{ MTP_FORMAT_FLAC , (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED,
0xFFFF}
},
{ MTP_FORMAT_AVI , (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED, MTP_PROPERTY_ARTIST, MTP_PROPERTY_ALBUM_NAME,
MTP_PROPERTY_DURATION, MTP_PROPERTY_DESCRIPTION, MTP_PROPERTY_WIDTH, MTP_PROPERTY_HEIGHT, MTP_PROPERTY_DATE_AUTHORED,
0xFFFF}
},
{ MTP_FORMAT_ASF , (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED, MTP_PROPERTY_ARTIST, MTP_PROPERTY_ALBUM_NAME,
MTP_PROPERTY_DURATION, MTP_PROPERTY_DESCRIPTION, MTP_PROPERTY_WIDTH, MTP_PROPERTY_HEIGHT, MTP_PROPERTY_DATE_AUTHORED,
0xFFFF}
},
{ MTP_FORMAT_MS_WORD_DOCUMENT, (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED,
0xFFFF}
},
{ MTP_FORMAT_MS_EXCEL_SPREADSHEET, (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED,
0xFFFF}
},
{ MTP_FORMAT_MS_POWERPOINT_PRESENTATION, (uint16_t[]){ MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, MTP_PROPERTY_OBJECT_SIZE,
MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID,
MTP_PROPERTY_NAME, MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_CREATED,
0xFFFF}
}
#endif
,
{ 0xFFFF, (uint16_t[]){ 0xFFFF } }
};
const profile_property support_object_properties[] = {
// prop_code data_type getset default_value group_code form_flag format_code
{ MTP_PROPERTY_STORAGE_ID, MTP_TYPE_UINT32, 0x00, 0x00000000, 0x000000001, 0x00, 0xFFFF },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_UNDEFINED, 0x000000000, 0x00, MTP_FORMAT_UNDEFINED },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_ASSOCIATION, 0x000000000, 0x00, MTP_FORMAT_ASSOCIATION },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_TEXT, 0x000000000, 0x00, MTP_FORMAT_TEXT },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_HTML, 0x000000000, 0x00, MTP_FORMAT_HTML },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_WAV, 0x000000000, 0x00, MTP_FORMAT_WAV },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_MP3, 0x000000000, 0x00, MTP_FORMAT_MP3 },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_MPEG, 0x000000000, 0x00, MTP_FORMAT_MPEG },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_EXIF_JPEG, 0x000000000, 0x00, MTP_FORMAT_EXIF_JPEG },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_BMP, 0x000000000, 0x00, MTP_FORMAT_BMP },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_AIFF, 0x000000000, 0x00, MTP_FORMAT_AIFF },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_MPEG, 0x000000000, 0x00, MTP_FORMAT_MPEG },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_WMA, 0x000000000, 0x00, MTP_FORMAT_WMA },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_OGG, 0x000000000, 0x00, MTP_FORMAT_OGG },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_AAC, 0x000000000, 0x00, MTP_FORMAT_AAC },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_MP4_CONTAINER, 0x000000000, 0x00, MTP_FORMAT_MP4_CONTAINER },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_3GP_CONTAINER, 0x000000000, 0x00, MTP_FORMAT_3GP_CONTAINER },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_ABSTRACT_AV_PLAYLIST, 0x000000000, 0x00, MTP_FORMAT_ABSTRACT_AV_PLAYLIST },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_WPL_PLAYLIST, 0x000000000, 0x00, MTP_FORMAT_WPL_PLAYLIST },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_M3U_PLAYLIST, 0x000000000, 0x00, MTP_FORMAT_M3U_PLAYLIST },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_PLS_PLAYLIST, 0x000000000, 0x00, MTP_FORMAT_PLS_PLAYLIST },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_XML_DOCUMENT, 0x000000000, 0x00, MTP_FORMAT_XML_DOCUMENT },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_FLAC, 0x000000000, 0x00, MTP_FORMAT_FLAC },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_AVI, 0x000000000, 0x00, MTP_FORMAT_AVI },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_ASF, 0x000000000, 0x00, MTP_FORMAT_ASF },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_MS_WORD_DOCUMENT, 0x000000000, 0x00, MTP_FORMAT_MS_WORD_DOCUMENT },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_MS_EXCEL_SPREADSHEET, 0x000000000, 0x00, MTP_FORMAT_MS_EXCEL_SPREADSHEET },
{ MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16, 0x00, MTP_FORMAT_MS_POWERPOINT_PRESENTATION, 0x000000000, 0x00, MTP_FORMAT_MS_POWERPOINT_PRESENTATION },
{ MTP_PROPERTY_OBJECT_SIZE, MTP_TYPE_UINT64, 0x00, 0x0000000000000000, 0x000000000, 0x00, MTP_FORMAT_ASSOCIATION },
{ MTP_PROPERTY_STORAGE_ID, MTP_TYPE_UINT32, 0x00, 0x00000000, 0x000000000, 0x00, MTP_FORMAT_ASSOCIATION },
{ MTP_PROPERTY_PROTECTION_STATUS, MTP_TYPE_UINT16, 0x00, 0x0000, 0x000000000, 0x00, MTP_FORMAT_ASSOCIATION },
{ MTP_PROPERTY_DISPLAY_NAME, MTP_TYPE_STR, 0x00, 0x0000, 0x000000000, 0x00, MTP_FORMAT_ASSOCIATION },
{ MTP_PROPERTY_OBJECT_FILE_NAME, MTP_TYPE_STR, 0x01, 0x0000, 0x000000000, 0x00, MTP_FORMAT_ASSOCIATION },
{ MTP_PROPERTY_DATE_CREATED, MTP_TYPE_STR, 0x00, 0x00, 0x000000000, 0x00, MTP_FORMAT_ASSOCIATION },
{ MTP_PROPERTY_DATE_MODIFIED, MTP_TYPE_STR, 0x00, 0x00, 0x000000000, 0x00, MTP_FORMAT_ASSOCIATION },
{ MTP_PROPERTY_PARENT_OBJECT, MTP_TYPE_UINT32, 0x00, 0x00000000, 0x000000000, 0x00, MTP_FORMAT_ASSOCIATION },
{ MTP_PROPERTY_PERSISTENT_UID, MTP_TYPE_UINT128, 0x00, 0x00, 0x000000000, 0x00, MTP_FORMAT_ASSOCIATION },
{ MTP_PROPERTY_NAME, MTP_TYPE_STR, 0x00, 0x00, 0x000000000, 0x00, MTP_FORMAT_ASSOCIATION },
{ MTP_PROPERTY_OBJECT_SIZE, MTP_TYPE_UINT64, 0x00, 0x0000000000000000, 0x000000000, 0x00, MTP_FORMAT_UNDEFINED },
{ MTP_PROPERTY_STORAGE_ID, MTP_TYPE_UINT32, 0x00, 0x00000000, 0x000000000, 0x00, MTP_FORMAT_UNDEFINED },
{ MTP_PROPERTY_PROTECTION_STATUS, MTP_TYPE_UINT16, 0x00, 0x0000, 0x000000000, 0x00, MTP_FORMAT_UNDEFINED },
{ MTP_PROPERTY_DISPLAY_NAME, MTP_TYPE_STR, 0x00, 0x0000, 0x000000000, 0x00, MTP_FORMAT_UNDEFINED },
{ MTP_PROPERTY_OBJECT_FILE_NAME, MTP_TYPE_STR, 0x01, 0x0000, 0x000000000, 0x00, MTP_FORMAT_UNDEFINED },
{ MTP_PROPERTY_DATE_CREATED, MTP_TYPE_STR, 0x00, 0x00, 0x000000000, 0x00, MTP_FORMAT_UNDEFINED },
{ MTP_PROPERTY_DATE_MODIFIED, MTP_TYPE_STR, 0x00, 0x00, 0x000000000, 0x00, MTP_FORMAT_UNDEFINED },
{ MTP_PROPERTY_PARENT_OBJECT, MTP_TYPE_UINT32, 0x00, 0x00000000, 0x000000000, 0x00, MTP_FORMAT_UNDEFINED },
{ MTP_PROPERTY_PERSISTENT_UID, MTP_TYPE_UINT128, 0x00, 0x00, 0x000000000, 0x00, MTP_FORMAT_UNDEFINED },
{ MTP_PROPERTY_NAME, MTP_TYPE_STR, 0x00, 0x00, 0x000000000, 0x00, MTP_FORMAT_UNDEFINED },
//{MTP_PROPERTY_ASSOCIATION_TYPE, MTP_TYPE_UINT16, 0x00, 0x0001 , 0x000000000 , 0x00 , 0xFFFF },
{ MTP_PROPERTY_ASSOCIATION_DESC, MTP_TYPE_UINT32, 0x00, 0x00000000, 0x000000000, 0x00, 0xFFFF },
{ MTP_PROPERTY_PROTECTION_STATUS, MTP_TYPE_UINT16, 0x00, 0x0000, 0x000000000, 0x00, 0xFFFF },
{ MTP_PROPERTY_HIDDEN, MTP_TYPE_UINT16, 0x00, 0x0000, 0x000000000, 0x00, 0xFFFF },
{ 0xFFFF, MTP_TYPE_UINT32, 0x00, 0x00000000, 0x000000000, 0x00 }
};
const profile_property support_device_properties[] = {
// prop_code data_type getset default_value group_code form_flag
//{MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER, MTP_TYPE_UINT32, 0x00, 0x00000000 , 0x000000000 , 0x00 },
//{MTP_DEVICE_PROPERTY_IMAGE_SIZE, MTP_TYPE_UINT32, 0x00, 0x00000000 , 0x000000000 , 0x00 },
{ MTP_DEVICE_PROPERTY_BATTERY_LEVEL, MTP_TYPE_UINT16, 0x00, 0x00000000, 0x000000000, 0x00 },
{ MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME, MTP_TYPE_STR, 0x00, 0x00000000, 0x000000000, 0x00 },
{ 0xFFFF, MTP_TYPE_UINT32, 0x00, 0x00000000, 0x000000000, 0x00 }
};
#endif

View File

@@ -74,7 +74,7 @@ static int usbh_asix_read_cmd(struct usbh_asix *asix_class,
if (ret < 8) {
return ret;
}
memcpy(data, g_asix_buf, ret - 8);
memcpy(data, g_asix_buf, MIN(ret - 8, size));
return ret;
}
@@ -638,6 +638,7 @@ static int usbh_asix_disconnect(struct usbh_hubport *hport, uint8_t intf)
}
if (hport->config.intf[intf].devname[0] != '\0') {
usb_osal_thread_schedule_other();
USB_LOG_INFO("Unregister ASIX Class:%s\r\n", hport->config.intf[intf].devname);
usbh_asix_stop(asix_class);
}

View File

@@ -965,7 +965,7 @@ static int usbh_rtl8152_read_regs(struct usbh_rtl8152 *rtl8152_class,
if (ret < 8) {
return ret;
}
memcpy(data, g_rtl8152_buf, ret - 8);
memcpy(data, g_rtl8152_buf, MIN(ret - 8, size));
return ret;
}
@@ -1138,7 +1138,7 @@ static void ocp_write_dword(struct usbh_rtl8152 *tp, uint16_t type, uint16_t ind
static uint16_t ocp_read_word(struct usbh_rtl8152 *tp, uint16_t type, uint16_t index)
{
uint32_t data;
uint32_t tmp;
uint32_t tmp = 0;
uint16_t byen = BYTE_EN_WORD;
uint8_t shift = index & 2;
@@ -1178,7 +1178,7 @@ static void ocp_write_word(struct usbh_rtl8152 *tp, uint16_t type, uint16_t inde
static uint8_t ocp_read_byte(struct usbh_rtl8152 *tp, uint16_t type, uint16_t index)
{
uint32_t data;
uint32_t tmp;
uint32_t tmp = 0;
uint8_t shift = index & 3;
index &= ~3;
@@ -1254,7 +1254,7 @@ static inline int r8152_mdio_read(struct usbh_rtl8152 *tp, uint32_t reg_addr)
static uint8_t usbh_rtl8152_get_version(struct usbh_rtl8152 *rtl8152_class)
{
uint8_t version;
uint32_t temp;
uint32_t temp = 0;
uint32_t ocp_data;
usbh_rtl8152_read_regs(rtl8152_class, PLA_TCR0, MCU_TYPE_PLA, 4, &temp);
@@ -2121,6 +2121,7 @@ static int usbh_rtl8152_disconnect(struct usbh_hubport *hport, uint8_t intf)
}
if (hport->config.intf[intf].devname[0] != '\0') {
usb_osal_thread_schedule_other();
USB_LOG_INFO("Unregister rtl8152 Class:%s\r\n", hport->config.intf[intf].devname);
usbh_rtl8152_stop(rtl8152_class);
}

View File

@@ -311,6 +311,7 @@ static int usbh_ch34x_disconnect(struct usbh_hubport *hport, uint8_t intf)
}
if (hport->config.intf[intf].devname[0] != '\0') {
usb_osal_thread_schedule_other();
USB_LOG_INFO("Unregister CH34X Class:%s\r\n", hport->config.intf[intf].devname);
usbh_ch34x_stop(ch34x_class);
}

View File

@@ -260,6 +260,7 @@ static int usbh_cp210x_disconnect(struct usbh_hubport *hport, uint8_t intf)
}
if (hport->config.intf[intf].devname[0] != '\0') {
usb_osal_thread_schedule_other();
USB_LOG_INFO("Unregister CP210X Class:%s\r\n", hport->config.intf[intf].devname);
usbh_cp210x_stop(cp210x_class);
}

View File

@@ -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;
@@ -440,6 +441,7 @@ static int usbh_ftdi_disconnect(struct usbh_hubport *hport, uint8_t intf)
}
if (hport->config.intf[intf].devname[0] != '\0') {
usb_osal_thread_schedule_other();
USB_LOG_INFO("Unregister FTDI Class:%s\r\n", hport->config.intf[intf].devname);
usbh_ftdi_stop(ftdi_class);
}

View File

@@ -375,6 +375,7 @@ static int usbh_pl2303_disconnect(struct usbh_hubport *hport, uint8_t intf)
}
if (hport->config.intf[intf].devname[0] != '\0') {
usb_osal_thread_schedule_other();
USB_LOG_INFO("Unregister PL2303 Class:%s\r\n", hport->config.intf[intf].devname);
usbh_pl2303_stop(pl2303_class);
}

View File

@@ -337,6 +337,7 @@ static int usbh_bl616_disconnect(struct usbh_hubport *hport, uint8_t intf)
}
if (hport->config.intf[intf].devname[0] != '\0') {
usb_osal_thread_schedule_other();
USB_LOG_INFO("Unregister BL616 WIFI Class:%s\r\n", hport->config.intf[intf].devname);
usbh_bl616_stop(bl616_class);
}

View File

@@ -86,6 +86,7 @@ int usbh_xbox_disconnect(struct usbh_hubport *hport, uint8_t intf)
}
if (hport->config.intf[intf].devname[0] != '\0') {
usb_osal_thread_schedule_other();
USB_LOG_INFO("Unregister XBOX Class:%s\r\n", hport->config.intf[intf].devname);
usbh_xbox_stop(xbox_class);
}

View File

@@ -1237,7 +1237,7 @@ struct video_autoexposure_mode {
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType : INTERFACE */ \
bInterfaceNumber, /* bInterfaceNumber: Index of this interface */ \
bAlternateSetting, /* bAlternateSetting: Index of this alternate setting */ \
bNumEndpoints, /* bNumEndpoints : 0 endpoints no bandwidth used*/ \
bNumEndpoints, /* bNumEndpoints : 0 endpoints, no bandwidth used*/ \
0x0e, /* bInterfaceClass : CC_VIDEO */ \
0x02, /* bInterfaceSubClass : SC_VIDEOSTREAMING */ \
0x00, /* bInterfaceProtocol : PC_PROTOCOL_UNDEFINED */ \
@@ -1315,8 +1315,8 @@ struct video_autoexposure_mode {
bNumFrameDescriptors, /* bNumFrameDescriptors : One frame descriptor for this format follows. */ \
0x00, /* bmFlags : Uses fixed size samples.. */ \
0x01, /* bDefaultFrameIndex : Default frame index is 1. */ \
0x00, /* bAspectRatioX : Non-interlaced stream not required. */ \
0x00, /* bAspectRatioY : Non-interlaced stream not required. */ \
0x00, /* bAspectRatioX : Non-interlaced stream, not required. */ \
0x00, /* bAspectRatioY : Non-interlaced stream, not required. */ \
0x00, /* bmInterlaceFlags : Non-interlaced stream */ \
0x00 /* bCopyProtect : No restrictions imposed on the duplication of this video stream. */
@@ -1346,8 +1346,8 @@ struct video_autoexposure_mode {
VIDEO_GUID_H264, \
0x00, /* bmFlags : Uses fixed size samples.. */ \
0x01, /* bDefaultFrameIndex : Default frame index is 1. */ \
0x00, /* bAspectRatioX : Non-interlaced stream not required. */ \
0x00, /* bAspectRatioY : Non-interlaced stream not required. */ \
0x00, /* bAspectRatioX : Non-interlaced stream, not required. */ \
0x00, /* bAspectRatioY : Non-interlaced stream, not required. */ \
0x00, /* bmInterlaceFlags : Non-interlaced stream */ \
0x00, /* bCopyProtect : No restrictions imposed on the duplication of this video stream. */ \
0x00 /* Variable size: False */

View File

@@ -18,20 +18,14 @@ struct usbd_video_priv {
uint8_t power_mode;
uint8_t error_code;
struct video_entity_info info[3];
uint8_t *ep_buf0;
uint8_t *ep_buf1;
bool ep_buf0_ready;
bool ep_buf1_ready;
uint32_t ep_buf0_len;
uint32_t ep_buf1_len;
uint8_t ep_buf_idx;
uint8_t *ep_buf;
bool stream_finish;
uint32_t max_packets;
uint8_t *stream_buf;
uint32_t stream_len;
uint32_t stream_offset;
uint8_t stream_frameid;
uint32_t stream_headerlen;
bool do_copy;
} g_usbd_video[CONFIG_USBDEV_MAX_BUS];
static int usbd_video_control_request_handler(uint8_t busid, struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
@@ -753,41 +747,7 @@ static void usbd_video_probe_and_commit_controls_init(uint8_t busid, uint32_t dw
g_usbd_video[busid].commit.bMaxVersion = 0;
g_usbd_video[busid].stream_frameid = 0;
g_usbd_video[busid].stream_headerlen = 2;
}
static uint32_t usbd_video_prepare_ep_buf_data(uint8_t busid, uint32_t remain, uint8_t *ep_buf)
{
struct video_payload_header *header;
uint32_t len;
uint32_t offset;
len = MIN(remain, (g_usbd_video[busid].probe.dwMaxPayloadTransferSize - g_usbd_video[busid].stream_headerlen) * g_usbd_video[busid].max_packets);
offset = 0;
while (len > 0) {
header = (struct video_payload_header *)&ep_buf[offset];
header->bHeaderLength = g_usbd_video[busid].stream_headerlen;
header->headerInfoUnion.bmheaderInfo = 0;
header->headerInfoUnion.headerInfoBits.endOfHeader = 1;
header->headerInfoUnion.headerInfoBits.endOfFrame = 0;
header->headerInfoUnion.headerInfoBits.frameIdentifier = g_usbd_video[busid].stream_frameid;
uint32_t len2 = MIN(len, g_usbd_video[busid].probe.dwMaxPayloadTransferSize - g_usbd_video[busid].stream_headerlen);
usb_memcpy(&ep_buf[offset + g_usbd_video[busid].stream_headerlen],
&g_usbd_video[busid].stream_buf[g_usbd_video[busid].stream_offset],
len2);
g_usbd_video[busid].stream_offset += len2;
len -= len2;
offset += (len2 + g_usbd_video[busid].stream_headerlen);
if (g_usbd_video[busid].stream_offset == g_usbd_video[busid].stream_len) {
header->headerInfoUnion.headerInfoBits.endOfFrame = 1;
}
}
return offset;
g_usbd_video[busid].stream_headerlen = 12;
}
struct usbd_interface *usbd_video_init_intf(uint8_t busid,
@@ -817,69 +777,88 @@ struct usbd_interface *usbd_video_init_intf(uint8_t busid,
bool usbd_video_stream_split_transfer(uint8_t busid, uint8_t ep)
{
uint32_t remain;
struct video_payload_header *header;
static uint32_t offset = 0;
static uint32_t len = 0;
if (g_usbd_video[busid].ep_buf1_ready && (g_usbd_video[busid].ep_buf_idx == 0)) { /* callback: buf1 ready and buf0 was sent */
g_usbd_video[busid].ep_buf0_ready = false;
g_usbd_video[busid].ep_buf_idx = 1;
usbd_ep_start_write(busid, ep, g_usbd_video[busid].ep_buf1, g_usbd_video[busid].ep_buf1_len);
} else if (g_usbd_video[busid].ep_buf0_ready && (g_usbd_video[busid].ep_buf_idx == 1)) { /* callback: buf0 ready and buf1 was sent */
g_usbd_video[busid].ep_buf1_ready = false;
g_usbd_video[busid].ep_buf_idx = 0;
usbd_ep_start_write(busid, ep, g_usbd_video[busid].ep_buf0, g_usbd_video[busid].ep_buf0_len);
if (g_usbd_video[busid].stream_finish) {
g_usbd_video[busid].stream_finish = false;
return true;
}
offset = g_usbd_video[busid].stream_offset;
len = MIN(g_usbd_video[busid].stream_len,
g_usbd_video[busid].probe.dwMaxPayloadTransferSize -
g_usbd_video[busid].stream_headerlen);
if (g_usbd_video[busid].do_copy) {
header = (struct video_payload_header *)&g_usbd_video[busid].ep_buf[0];
usb_memcpy(&g_usbd_video[busid].ep_buf[g_usbd_video[busid].stream_headerlen], &g_usbd_video[busid].stream_buf[offset], len);
} else {
if (g_usbd_video[busid].stream_finish) {
return true;
}
header = (struct video_payload_header *)&g_usbd_video[busid].stream_buf[offset - g_usbd_video[busid].stream_headerlen];
}
if (!g_usbd_video[busid].ep_buf0_ready) {
remain = g_usbd_video[busid].stream_len - g_usbd_video[busid].stream_offset;
if (remain == 0) {
g_usbd_video[busid].stream_frameid ^= 1;
g_usbd_video[busid].stream_finish = true;
} else {
g_usbd_video[busid].ep_buf0_len = usbd_video_prepare_ep_buf_data(busid, remain, g_usbd_video[busid].ep_buf0);
g_usbd_video[busid].ep_buf0_ready = true;
if (!g_usbd_video[busid].ep_buf1_ready) {
g_usbd_video[busid].ep_buf_idx = 0;
usbd_ep_start_write(busid, ep, g_usbd_video[busid].ep_buf0, g_usbd_video[busid].ep_buf0_len);
}
}
memset(header, 0, g_usbd_video[busid].stream_headerlen);
header->bHeaderLength = g_usbd_video[busid].stream_headerlen;
header->headerInfoUnion.bmheaderInfo = 0;
header->headerInfoUnion.headerInfoBits.endOfHeader = 1;
header->headerInfoUnion.headerInfoBits.endOfFrame = 0;
header->headerInfoUnion.headerInfoBits.frameIdentifier = g_usbd_video[busid].stream_frameid;
g_usbd_video[busid].stream_offset += len;
g_usbd_video[busid].stream_len -= len;
if (g_usbd_video[busid].stream_len == 0) {
header->headerInfoUnion.headerInfoBits.endOfFrame = 1;
g_usbd_video[busid].stream_frameid ^= 1;
g_usbd_video[busid].stream_finish = true;
}
if (!g_usbd_video[busid].ep_buf1_ready) {
remain = g_usbd_video[busid].stream_len - g_usbd_video[busid].stream_offset;
if (remain == 0) {
g_usbd_video[busid].stream_frameid ^= 1;
g_usbd_video[busid].stream_finish = true;
} else {
g_usbd_video[busid].ep_buf1_len = usbd_video_prepare_ep_buf_data(busid, remain, g_usbd_video[busid].ep_buf1);
g_usbd_video[busid].ep_buf1_ready = true;
}
if (g_usbd_video[busid].do_copy) {
usbd_ep_start_write(busid, ep,
g_usbd_video[busid].ep_buf,
g_usbd_video[busid].stream_headerlen + len);
} else {
usbd_ep_start_write(busid, ep,
&g_usbd_video[busid].stream_buf[offset - g_usbd_video[busid].stream_headerlen],
g_usbd_video[busid].stream_headerlen + len);
}
return false;
}
int usbd_video_stream_start_write(uint8_t busid, uint8_t ep, uint8_t *ep_buf0, uint8_t *ep_buf1, uint32_t ep_bufsize, uint8_t *stream_buf, uint32_t stream_len)
int usbd_video_stream_start_write(uint8_t busid, uint8_t ep, uint8_t *ep_buf, uint8_t *stream_buf, uint32_t stream_len, bool do_copy)
{
struct video_payload_header *header;
if ((usb_device_is_configured(busid) == 0) || (stream_len == 0)) {
return -1;
}
g_usbd_video[busid].ep_buf0 = ep_buf0;
g_usbd_video[busid].ep_buf1 = ep_buf1;
g_usbd_video[busid].ep_buf0_ready = false;
g_usbd_video[busid].ep_buf1_ready = false;
g_usbd_video[busid].ep_buf_idx = 0;
g_usbd_video[busid].stream_finish = false;
g_usbd_video[busid].max_packets = ep_bufsize / g_usbd_video[busid].probe.dwMaxPayloadTransferSize;
g_usbd_video[busid].ep_buf = ep_buf;
g_usbd_video[busid].stream_buf = stream_buf;
g_usbd_video[busid].stream_len = stream_len;
g_usbd_video[busid].stream_offset = 0;
g_usbd_video[busid].stream_finish = false;
g_usbd_video[busid].do_copy = do_copy;
usbd_video_stream_split_transfer(busid, ep);
uint32_t len = MIN(g_usbd_video[busid].stream_len,
g_usbd_video[busid].probe.dwMaxPayloadTransferSize -
g_usbd_video[busid].stream_headerlen);
header = (struct video_payload_header *)&ep_buf[0];
header->bHeaderLength = g_usbd_video[busid].stream_headerlen;
header->headerInfoUnion.bmheaderInfo = 0;
header->headerInfoUnion.headerInfoBits.endOfHeader = 1;
header->headerInfoUnion.headerInfoBits.endOfFrame = 0;
header->headerInfoUnion.headerInfoBits.frameIdentifier = g_usbd_video[busid].stream_frameid;
usb_memcpy(&ep_buf[g_usbd_video[busid].stream_headerlen], stream_buf, len);
g_usbd_video[busid].stream_offset += len;
g_usbd_video[busid].stream_len -= len;
usbd_ep_start_write(busid, ep, ep_buf, g_usbd_video[busid].stream_headerlen + len);
return 0;
}

View File

@@ -22,7 +22,7 @@ void usbd_video_open(uint8_t busid, uint8_t intf);
void usbd_video_close(uint8_t busid, uint8_t intf);
bool usbd_video_stream_split_transfer(uint8_t busid, uint8_t ep);
int usbd_video_stream_start_write(uint8_t busid, uint8_t ep, uint8_t *ep_buf0, uint8_t *ep_buf1, uint32_t ep_bufsize, uint8_t *stream_buf, uint32_t stream_len);
int usbd_video_stream_start_write(uint8_t busid, uint8_t ep, uint8_t *ep_buf, uint8_t *stream_buf, uint32_t stream_len, bool do_copy);
#ifdef __cplusplus
}

View File

@@ -483,6 +483,7 @@ static int usbh_video_ctrl_disconnect(struct usbh_hubport *hport, uint8_t intf)
}
if (hport->config.intf[intf].devname[0] != '\0') {
usb_osal_thread_schedule_other();
USB_LOG_INFO("Unregister Video Class:%s\r\n", hport->config.intf[intf].devname);
usbh_video_stop(video_class);
}

View File

@@ -134,6 +134,7 @@ static int usbh_bluetooth_disconnect(struct usbh_hubport *hport, uint8_t intf)
// }
#endif
if (hport->config.intf[intf].devname[0] != '\0') {
usb_osal_thread_schedule_other();
USB_LOG_INFO("Unregister Bluetooth Class:%s\r\n", hport->config.intf[intf].devname);
usbh_bluetooth_stop(bluetooth_class);
}

View File

@@ -438,6 +438,7 @@ static int usbh_rndis_disconnect(struct usbh_hubport *hport, uint8_t intf)
// }
if (hport->config.intf[intf].devname[0] != '\0') {
usb_osal_thread_schedule_other();
USB_LOG_INFO("Unregister RNDIS Class:%s\r\n", hport->config.intf[intf].devname);
usbh_rndis_stop(rndis_class);
}

View File

@@ -10,6 +10,9 @@
#if CONFIG_USB_ALIGN_SIZE % 32
#error "CONFIG_USB_ALIGN_SIZE must be multiple of 32"
#endif
void usb_dcache_clean(uintptr_t addr, size_t size);
void usb_dcache_invalidate(uintptr_t addr, size_t size);
void usb_dcache_flush(uintptr_t addr, size_t size);
#else
#define usb_dcache_clean(addr, size)
#define usb_dcache_invalidate(addr, size)

View File

@@ -42,6 +42,7 @@ struct usb_osal_timer {
*/
usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size, uint32_t prio, usb_thread_entry_t entry, void *args);
void usb_osal_thread_delete(usb_osal_thread_t thread);
void usb_osal_thread_schedule_other(void);
usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count);
void usb_osal_sem_delete(usb_osal_sem_t sem);

View File

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

View File

@@ -83,8 +83,8 @@ USB_NOCACHE_RAM_SECTION struct usbd_core_priv {
uint8_t intf_altsetting[16];
uint8_t intf_offset;
struct usbd_tx_rx_msg tx_msg[CONFIG_USBDEV_EP_NUM];
struct usbd_tx_rx_msg rx_msg[CONFIG_USBDEV_EP_NUM];
struct usbd_tx_rx_msg tx_msg[16];
struct usbd_tx_rx_msg rx_msg[16];
void (*event_handler)(uint8_t busid, uint8_t event);
} g_usbd_core[CONFIG_USBDEV_MAX_BUS];
@@ -95,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:
@@ -1123,6 +1131,7 @@ void usbd_event_connect_handler(uint8_t busid)
void usbd_event_disconnect_handler(uint8_t busid)
{
g_usbd_core[busid].configuration = 0;
g_usbd_core[busid].event_handler(busid, USBD_EVENT_DISCONNECTED);
}
@@ -1170,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");
@@ -1239,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");
}
}
@@ -1265,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 */
@@ -1310,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);
@@ -1337,9 +1356,8 @@ static void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint3
usbd_ep_start_read(busid, USB_CONTROL_OUT_EP0, g_usbd_core[busid].ep0_data_buf, g_usbd_core[busid].ep0_data_buf_residue);
}
} else {
g_usbd_core[busid].ep0_next_state = USBD_EP0_STATE_SETUP;
/* Read out status completely, do nothing */
USB_LOG_DBG("EP0 recv out status\r\n");
g_usbd_core[busid].ep0_next_state = USBD_EP0_STATE_SETUP;
}
}

View File

@@ -22,7 +22,9 @@ extern "C" {
#include "usb_list.h"
#include "usb_log.h"
#include "usb_dc.h"
#include "usb_osal.h"
#include "usb_memcpy.h"
#include "usb_dcache.h"
#include "usb_version.h"
enum usbd_event_type {

View File

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

View File

@@ -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

View File

@@ -220,6 +220,7 @@ const uint8_t audio_v1_descriptor[] = {
volatile bool tx_flag = 0;
volatile bool ep_tx_busy_flag = false;
volatile uint32_t s_mic_sample_rate;
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
@@ -260,6 +261,26 @@ void usbd_audio_close(uint8_t busid, uint8_t intf)
tx_flag = 0;
}
void usbd_audio_set_sampling_freq(uint8_t busid, uint8_t ep, uint32_t sampling_freq)
{
if (ep == AUDIO_IN_EP) {
s_mic_sample_rate = sampling_freq;
}
}
uint32_t usbd_audio_get_sampling_freq(uint8_t busid, uint8_t ep)
{
(void)busid;
uint32_t freq = 0;
if (ep == AUDIO_IN_EP) {
freq = s_mic_sample_rate;
}
return freq;
}
void usbd_audio_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual in len:%d\r\n", (unsigned int)nbytes);

View File

@@ -258,6 +258,8 @@ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t s_speaker_feedback_buffer[4];
volatile bool tx_flag = 0;
volatile bool rx_flag = 0;
volatile bool ep_tx_busy_flag = false;
volatile uint32_t s_mic_sample_rate;
volatile uint32_t s_speaker_sample_rate;
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
@@ -291,7 +293,7 @@ void usbd_audio_open(uint8_t busid, uint8_t intf)
/* setup first out ep read transfer */
usbd_ep_start_read(busid, AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET);
#if USING_FEEDBACK == 1
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(AUDIO_SPEAKER_FREQ);
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(s_speaker_sample_rate);
AUDIO_FEEDBACK_TO_BUF_FS(s_speaker_feedback_buffer, feedback_value); /* uac1 can only use 10.14 */
usbd_ep_start_write(busid, AUDIO_OUT_FEEDBACK_EP, s_speaker_feedback_buffer, FEEDBACK_ENDP_PACKET_SIZE);
#endif
@@ -315,6 +317,30 @@ void usbd_audio_close(uint8_t busid, uint8_t intf)
}
}
void usbd_audio_set_sampling_freq(uint8_t busid, uint8_t ep, uint32_t sampling_freq)
{
if (ep == AUDIO_OUT_EP) {
s_speaker_sample_rate = sampling_freq;
} else if (ep == AUDIO_IN_EP) {
s_mic_sample_rate = sampling_freq;
}
}
uint32_t usbd_audio_get_sampling_freq(uint8_t busid, uint8_t ep)
{
(void)busid;
uint32_t freq = 0;
if (ep == AUDIO_OUT_EP) {
freq = s_speaker_sample_rate;
} else if (ep == AUDIO_IN_EP) {
freq = s_mic_sample_rate;
}
return freq;
}
void usbd_audio_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual out len:%d\r\n", (unsigned int)nbytes);
@@ -331,7 +357,7 @@ void usbd_audio_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
void usbd_audio_iso_out_feedback_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
USB_LOG_RAW("actual feedback len:%d\r\n", (unsigned int)nbytes);
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(AUDIO_SPEAKER_FREQ);
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(s_speaker_sample_rate);
AUDIO_FEEDBACK_TO_BUF_FS(s_speaker_feedback_buffer, feedback_value);
usbd_ep_start_write(busid, AUDIO_OUT_FEEDBACK_EP, s_speaker_feedback_buffer, FEEDBACK_ENDP_PACKET_SIZE);
}

View File

@@ -235,6 +235,7 @@ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[AUDIO_IN_PACKET];
volatile bool tx_flag = 0;
volatile bool ep_tx_busy_flag = false;
volatile uint32_t s_mic_sample_rate;
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
@@ -273,6 +274,26 @@ void usbd_audio_close(uint8_t busid, uint8_t intf)
tx_flag = 0;
}
void usbd_audio_set_sampling_freq(uint8_t busid, uint8_t ep, uint32_t sampling_freq)
{
if (ep == AUDIO_IN_EP) {
s_mic_sample_rate = sampling_freq;
}
}
uint32_t usbd_audio_get_sampling_freq(uint8_t busid, uint8_t ep)
{
(void)busid;
uint32_t freq = 0;
if (ep == AUDIO_IN_EP) {
freq = s_mic_sample_rate;
}
return freq;
}
void usbd_audio_get_sampling_freq_table(uint8_t busid, uint8_t ep, uint8_t **sampling_freq_table)
{
if (ep == AUDIO_IN_EP) {

View File

@@ -342,6 +342,8 @@ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[AUDIO_IN_PACKET];
volatile bool tx_flag = 0;
volatile bool rx_flag = 0;
volatile bool ep_tx_busy_flag = false;
volatile uint32_t s_mic_sample_rate;
volatile uint32_t s_speaker_sample_rate;
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
@@ -402,6 +404,30 @@ void usbd_audio_close(uint8_t busid, uint8_t intf)
}
}
void usbd_audio_set_sampling_freq(uint8_t busid, uint8_t ep, uint32_t sampling_freq)
{
if (ep == AUDIO_OUT_EP) {
s_speaker_sample_rate = sampling_freq;
} else if (ep == AUDIO_IN_EP) {
s_mic_sample_rate = sampling_freq;
}
}
uint32_t usbd_audio_get_sampling_freq(uint8_t busid, uint8_t ep)
{
(void)busid;
uint32_t freq = 0;
if (ep == AUDIO_OUT_EP) {
freq = s_speaker_sample_rate;
} else if (ep == AUDIO_IN_EP) {
freq = s_mic_sample_rate;
}
return freq;
}
void usbd_audio_get_sampling_freq_table(uint8_t busid, uint8_t ep, uint8_t **sampling_freq_table)
{
if (ep == AUDIO_OUT_EP) {
@@ -429,10 +455,10 @@ void usbd_audio_iso_out_feedback_callback(uint8_t busid, uint8_t ep, uint32_t nb
{
USB_LOG_RAW("actual feedback len:%d\r\n", nbytes);
#ifdef CONFIG_USB_HS
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_HS(AUDIO_FREQ);
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_HS(s_speaker_sample_rate);
AUDIO_FEEDBACK_TO_BUF_HS(s_speaker_feedback_buffer, feedback_value);
#else
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(AUDIO_FREQ);
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(s_speaker_sample_rate);
AUDIO_FEEDBACK_TO_BUF_FS(s_speaker_feedback_buffer, feedback_value);
#endif
usbd_ep_start_write(busid, AUDIO_OUT_FEEDBACK_EP, s_speaker_feedback_buffer, FEEDBACK_ENDP_PACKET_SIZE);

View File

@@ -274,6 +274,7 @@ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[AUDIO_OUT_PACKET];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t s_speaker_feedback_buffer[4];
volatile bool rx_flag = 0;
volatile uint32_t s_speaker_sample_rate;
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
@@ -307,10 +308,10 @@ void usbd_audio_open(uint8_t busid, uint8_t intf)
usbd_ep_start_read(busid, AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET);
#if USING_FEEDBACK == 1
#ifdef CONFIG_USB_HS
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_HS(AUDIO_FREQ);
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_HS(s_speaker_sample_rate);
AUDIO_FEEDBACK_TO_BUF_HS(s_speaker_feedback_buffer, feedback_value);
#else
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(AUDIO_FREQ);
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(s_speaker_sample_rate);
AUDIO_FEEDBACK_TO_BUF_FS(s_speaker_feedback_buffer, feedback_value);
#endif
usbd_ep_start_write(busid, AUDIO_OUT_FEEDBACK_EP, s_speaker_feedback_buffer, FEEDBACK_ENDP_PACKET_SIZE);
@@ -324,6 +325,26 @@ void usbd_audio_close(uint8_t busid, uint8_t intf)
rx_flag = 0;
}
void usbd_audio_set_sampling_freq(uint8_t busid, uint8_t ep, uint32_t sampling_freq)
{
if (ep == AUDIO_OUT_EP) {
s_speaker_sample_rate = sampling_freq;
}
}
uint32_t usbd_audio_get_sampling_freq(uint8_t busid, uint8_t ep)
{
(void)busid;
uint32_t freq = 0;
if (ep == AUDIO_OUT_EP) {
freq = s_speaker_sample_rate;
}
return freq;
}
void usbd_audio_get_sampling_freq_table(uint8_t busid, uint8_t ep, uint8_t **sampling_freq_table)
{
if (ep == AUDIO_OUT_EP) {
@@ -342,10 +363,10 @@ void usbd_audio_iso_out_feedback_callback(uint8_t busid, uint8_t ep, uint32_t nb
{
USB_LOG_RAW("actual feedback len:%d\r\n", (unsigned int)nbytes);
#ifdef CONFIG_USB_HS
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_HS(AUDIO_FREQ);
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_HS(s_speaker_sample_rate);
AUDIO_FEEDBACK_TO_BUF_HS(s_speaker_feedback_buffer, feedback_value);
#else
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(AUDIO_FREQ);
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(s_speaker_sample_rate);
AUDIO_FEEDBACK_TO_BUF_FS(s_speaker_feedback_buffer, feedback_value);
#endif
usbd_ep_start_write(busid, AUDIO_OUT_FEEDBACK_EP, s_speaker_feedback_buffer, FEEDBACK_ENDP_PACKET_SIZE);

View 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;
}
}
}
}

View 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);
}

View File

@@ -276,7 +276,8 @@ void cdc_ecm_lwip_init(void)
eth_device_init(&cdc_ecm_dev, "u0");
eth_device_linkchange(&cdc_ecm_dev, RT_FALSE);
eth_device_linkchange(&cdc_ecm_dev, RT_TRUE);
dhcpd_start("u0");
}
void usbd_cdc_ecm_data_recv_done(uint32_t len)
@@ -439,10 +440,6 @@ static void usbd_event_handler(uint8_t busid, uint8_t event)
case USBD_EVENT_SUSPEND:
break;
case USBD_EVENT_CONFIGURED:
#ifdef RT_USING_LWIP
eth_device_linkchange(&cdc_ecm_dev, RT_TRUE);
dhcpd_start("u0");
#endif
break;
case USBD_EVENT_SET_REMOTE_WAKEUP:
break;

View File

@@ -249,7 +249,8 @@ void rndis_lwip_init(void)
eth_device_init(&rndis_dev, "u0");
eth_device_linkchange(&rndis_dev, RT_FALSE);
eth_device_linkchange(&rndis_dev, RT_TRUE);
dhcpd_start("u0");
}
void usbd_rndis_data_recv_done(uint32_t len)
@@ -412,10 +413,6 @@ static void usbd_event_handler(uint8_t busid, uint8_t event)
case USBD_EVENT_SUSPEND:
break;
case USBD_EVENT_CONFIGURED:
#ifdef RT_USING_LWIP
eth_device_linkchange(&rndis_dev, RT_TRUE);
dhcpd_start("u0");
#endif
break;
case USBD_EVENT_SET_REMOTE_WAKEUP:
break;
@@ -439,7 +436,7 @@ void cdc_rndis_init(uint8_t busid, uintptr_t reg_base)
#else
usbd_desc_register(busid, cdc_rndis_descriptor);
#endif
usbd_add_interface(busid, usbd_rndis_init_intf(&intf0, CDC_OUT_EP, CDC_IN_EP, CDC_INT_EP, mac));
usbd_add_interface(busid, usbd_rndis_init_intf(&intf1, CDC_OUT_EP, CDC_IN_EP, CDC_INT_EP, mac));
usbd_add_interface(busid, usbd_rndis_init_intf(&intf0, CDC_OUT_EP, CDC_IN_EP, CDC_INT_EP, (uint8_t *)mac));
usbd_add_interface(busid, usbd_rndis_init_intf(&intf1, CDC_OUT_EP, CDC_IN_EP, CDC_INT_EP, (uint8_t *)mac));
usbd_initialize(busid, reg_base, usbd_event_handler);
}

250
demo/mtp_template.c Normal file
View File

@@ -0,0 +1,250 @@
/*
* Copyright (c) 2025 sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*
*/
#include "usbd_core.h"
#include "usbd_mtp.h"
#if 1
#error "commercial charge"
#endif
#ifndef CONFIG_USBDEV_MTP_THREAD
#warning mtp depends on filesystem, suggest to enable CONFIG_USBDEV_MTP_THREAD
#endif
#define WCID_VENDOR_CODE 0x01
__ALIGN_BEGIN const uint8_t WCID_StringDescriptor_MSOS[18] __ALIGN_END = {
///////////////////////////////////////
/// MS OS string descriptor
///////////////////////////////////////
0x12, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
/* MSFT100 */
'M', 0x00, 'S', 0x00, 'F', 0x00, 'T', 0x00, /* wcChar_7 */
'1', 0x00, '0', 0x00, '0', 0x00, /* wcChar_7 */
WCID_VENDOR_CODE, /* bVendorCode */
0x00, /* bReserved */
};
__ALIGN_BEGIN const uint8_t WINUSB_WCIDDescriptor[40] __ALIGN_END = {
///////////////////////////////////////
/// WCID descriptor
///////////////////////////////////////
0x28, 0x00, 0x00, 0x00, /* dwLength */
0x00, 0x01, /* bcdVersion */
0x04, 0x00, /* wIndex */
0x01, /* bCount */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_7 */
///////////////////////////////////////
/// WCID function descriptor
///////////////////////////////////////
0x00, /* bFirstInterfaceNumber */
0x01, /* bReserved */
/* MTP */
'M', 'T', 'P', 0x00, 0x00, 0x00, 0x00, 0x00, /* cCID_8 */
/* */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* cSubCID_8 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_6 */
};
__ALIGN_BEGIN const uint8_t WINUSB_IF0_WCIDProperties[142] __ALIGN_END = {
///////////////////////////////////////
/// WCID property descriptor
///////////////////////////////////////
0x8e, 0x00, 0x00, 0x00, /* dwLength */
0x00, 0x01, /* bcdVersion */
0x05, 0x00, /* wIndex */
0x01, 0x00, /* wCount */
///////////////////////////////////////
/// registry propter descriptor
///////////////////////////////////////
0x84, 0x00, 0x00, 0x00, /* dwSize */
0x01, 0x00, 0x00, 0x00, /* dwPropertyDataType */
0x28, 0x00, /* wPropertyNameLength */
/* DeviceInterfaceGUID */
'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, /* wcName_20 */
'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, /* wcName_20 */
't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, /* wcName_20 */
'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, /* wcName_20 */
'U', 0x00, 'I', 0x00, 'D', 0x00, 0x00, 0x00, /* wcName_20 */
0x4e, 0x00, 0x00, 0x00, /* dwPropertyDataLength */
/* {1D4B2365-4749-48EA-B38A-7C6FDDDD7E26} */
'{', 0x00, '1', 0x00, 'D', 0x00, '4', 0x00, /* wcData_39 */
'B', 0x00, '2', 0x00, '3', 0x00, '6', 0x00, /* wcData_39 */
'5', 0x00, '-', 0x00, '4', 0x00, '7', 0x00, /* wcData_39 */
'4', 0x00, '9', 0x00, '-', 0x00, '4', 0x00, /* wcData_39 */
'8', 0x00, 'E', 0x00, 'A', 0x00, '-', 0x00, /* wcData_39 */
'B', 0x00, '3', 0x00, '8', 0x00, 'A', 0x00, /* wcData_39 */
'-', 0x00, '7', 0x00, 'C', 0x00, '6', 0x00, /* wcData_39 */
'F', 0x00, 'D', 0x00, 'D', 0x00, 'D', 0x00, /* wcData_39 */
'D', 0x00, '7', 0x00, 'E', 0x00, '2', 0x00, /* wcData_39 */
'6', 0x00, '}', 0x00, 0x00, 0x00, /* wcData_39 */
};
const uint8_t bos_descriptor[] = {
0x05, 0x0f, 0x16, 0x00, 0x02,
0x07, 0x10, 0x02, 0x06, 0x00, 0x00, 0x00,
0x0a, 0x10, 0x03, 0x00, 0x0f, 0x00, 0x01, 0x01, 0xf4, 0x01
};
/*!< endpoint address */
#define MTP_IN_EP 0x81
#define MTP_OUT_EP 0x02
#define MTP_INT_EP 0x83
/*!< config descriptor size */
#define USB_CONFIG_SIZE (9 + MTP_DESCRIPTOR_LEN)
static const uint8_t device_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0201, 0x01)
};
static const uint8_t config_descriptor_hs[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
MTP_DESCRIPTOR_INIT(0x00, MTP_OUT_EP, MTP_IN_EP, MTP_INT_EP, USB_BULK_EP_MPS_HS, 0x02),
};
static const uint8_t config_descriptor_fs[] = {
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
MTP_DESCRIPTOR_INIT(0x00, MTP_OUT_EP, MTP_IN_EP, MTP_INT_EP, USB_BULK_EP_MPS_FS, 0x02),
};
static const uint8_t device_quality_descriptor[] = {
USB_DEVICE_QUALIFIER_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, 0x01),
};
static const uint8_t other_speed_config_descriptor_hs[] = {
USB_OTHER_SPEED_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
MTP_DESCRIPTOR_INIT(0x00, MTP_OUT_EP, MTP_IN_EP, MTP_INT_EP, USB_BULK_EP_MPS_FS, 0x02),
};
static const uint8_t other_speed_config_descriptor_fs[] = {
USB_OTHER_SPEED_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
MTP_DESCRIPTOR_INIT(0x00, MTP_OUT_EP, MTP_IN_EP, MTP_INT_EP, USB_BULK_EP_MPS_HS, 0x02),
};
static const char *string_descriptors[] = {
(const char[]){ 0x09, 0x04 }, /* Langid */
"CherryUSB", /* Manufacturer */
"CherryUSB MTP DEMO", /* Product */
"2025053000", /* Serial Number */
};
static const uint8_t *device_descriptor_callback(uint8_t speed)
{
(void)speed;
return device_descriptor;
}
static const uint8_t *config_descriptor_callback(uint8_t speed)
{
if (speed == USB_SPEED_HIGH) {
return config_descriptor_hs;
} else if (speed == USB_SPEED_FULL) {
return config_descriptor_fs;
} else {
return NULL;
}
}
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
{
(void)speed;
return device_quality_descriptor;
}
static const uint8_t *other_speed_config_descriptor_callback(uint8_t speed)
{
if (speed == USB_SPEED_HIGH) {
return other_speed_config_descriptor_hs;
} else if (speed == USB_SPEED_FULL) {
return other_speed_config_descriptor_fs;
} else {
return NULL;
}
}
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
{
(void)speed;
if (index >= (sizeof(string_descriptors) / sizeof(char *))) {
return NULL;
}
return string_descriptors[index];
}
const uint8_t *WINUSB_IFx_WCIDProperties[] = {
WINUSB_IF0_WCIDProperties,
};
struct usb_msosv1_descriptor msosv1_desc = {
.string = WCID_StringDescriptor_MSOS,
.vendor_code = WCID_VENDOR_CODE,
.compat_id = WINUSB_WCIDDescriptor,
.comp_id_property = WINUSB_IFx_WCIDProperties,
};
const struct usb_bos_descriptor bos_desc = {
.string = bos_descriptor,
.string_len = 22
};
const struct usb_descriptor mtp_descriptor = {
.device_descriptor_callback = device_descriptor_callback,
.config_descriptor_callback = config_descriptor_callback,
.device_quality_descriptor_callback = device_quality_descriptor_callback,
.other_speed_descriptor_callback = other_speed_config_descriptor_callback,
.string_descriptor_callback = string_descriptor_callback,
.bos_descriptor = &bos_desc,
.msosv1_descriptor = &msosv1_desc,
};
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;
}
}
static struct usbd_interface intf0;
extern void usbd_mtp_mount();
void mtp_init(uint8_t busid, uint32_t reg_base)
{
usbd_mtp_mount();
usbd_desc_register(busid, &mtp_descriptor);
usbd_add_interface(busid, usbd_mtp_init_intf(&intf0, MTP_OUT_EP, MTP_IN_EP, MTP_INT_EP));
usbd_initialize(busid, reg_base, usbd_event_handler);
}

View File

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

View File

@@ -7,8 +7,6 @@
#include "usbd_video.h"
#include "cherryusb_h264.h"
#define MAX_PACKETS_IN_ONE_TRANSFER 1
#define VIDEO_IN_EP 0x81
#define VIDEO_INT_EP 0x83
@@ -282,7 +280,8 @@ void video_init(uint8_t busid, uintptr_t reg_base)
usbd_initialize(busid, reg_base, usbd_event_handler);
}
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[2][40 * 1024];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[MAX_PAYLOAD_SIZE];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t frame_buffer[32 * 1024];
void video_test(uint8_t busid)
{
@@ -294,7 +293,8 @@ void video_test(uint8_t busid)
while (1) {
if (tx_flag) {
iso_tx_busy = true;
usbd_video_stream_start_write(busid, VIDEO_IN_EP, &packet_buffer[0][0], &packet_buffer[1][0], MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE, (uint8_t *)cherryusb_h264, sizeof(cherryusb_h264));
memcpy(frame_buffer, cherryusb_h264, sizeof(cherryusb_h264)); // cherryusb_h264 is a static yuyv frame buffer, so we need copy it to frame_buffer
usbd_video_stream_start_write(busid, VIDEO_IN_EP, packet_buffer, (uint8_t *)frame_buffer, sizeof(cherryusb_h264), false);
while (iso_tx_busy) {
if (tx_flag == 0) {
break;

View File

@@ -7,8 +7,6 @@
#include "usbd_video.h"
#include "cherryusb_mjpeg.h"
#define MAX_PACKETS_IN_ONE_TRANSFER 1
#define VIDEO_IN_EP 0x81
#define VIDEO_INT_EP 0x83
@@ -282,7 +280,8 @@ void video_init(uint8_t busid, uintptr_t reg_base)
usbd_initialize(busid, reg_base, usbd_event_handler);
}
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[2][MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[MAX_PAYLOAD_SIZE];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t frame_buffer[32 * 1024];
void video_test(uint8_t busid)
{
@@ -291,7 +290,8 @@ void video_test(uint8_t busid)
while (1) {
if (tx_flag) {
iso_tx_busy = true;
usbd_video_stream_start_write(busid, VIDEO_IN_EP, &packet_buffer[0][0], &packet_buffer[1][0], MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE, (uint8_t *)cherryusb_mjpeg, sizeof(cherryusb_mjpeg));
memcpy(frame_buffer, cherryusb_mjpeg, sizeof(cherryusb_mjpeg)); // cherryusb_mjpeg is a static MJPEG frame buffer, so we need copy it to frame_buffer
usbd_video_stream_start_write(busid, VIDEO_IN_EP, packet_buffer, (uint8_t *)frame_buffer, sizeof(cherryusb_mjpeg), false);
while (iso_tx_busy) {
if (tx_flag == 0) {
break;

View File

@@ -7,8 +7,6 @@
#include "usbd_video.h"
#include "cherryusb_yuyv.h"
#define MAX_PACKETS_IN_ONE_TRANSFER 1
#define VIDEO_IN_EP 0x81
#define VIDEO_INT_EP 0x83
@@ -286,7 +284,8 @@ void video_init(uint8_t busid, uintptr_t reg_base)
usbd_initialize(busid, reg_base, usbd_event_handler);
}
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[2][MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[MAX_PAYLOAD_SIZE];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t frame_buffer[32 * 1024];
void video_test(uint8_t busid)
{
@@ -295,7 +294,8 @@ void video_test(uint8_t busid)
while (1) {
if (tx_flag) {
iso_tx_busy = true;
usbd_video_stream_start_write(busid, VIDEO_IN_EP, &packet_buffer[0][0], &packet_buffer[1][0], MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE, (uint8_t *)cherryusb_yuyv, sizeof(cherryusb_yuyv));
memcpy(frame_buffer, cherryusb_yuyv, sizeof(cherryusb_yuyv)); // cherryusb_yuyv is a static yuyv frame buffer, so we need copy it to frame_buffer
usbd_video_stream_start_write(busid, VIDEO_IN_EP, packet_buffer, (uint8_t *)frame_buffer, sizeof(cherryusb_yuyv), false);
while (iso_tx_busy) {
if (tx_flag == 0) {
break;

View File

@@ -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 = {

View File

@@ -7,6 +7,10 @@
- 有多少个接口就调用多少次 `usbd_add_interface`,参数填相关 `xxx_init_intf`, 如果没有支持的,手动创建一个 intf 填入
- 有多少个端点就调用多少次 `usbd_add_endpoint`,当中断完成时,会调用到注册的端点回调中。
参考下面这张图:
.. figure:: img/api_device1.png
CORE
-----------------

View File

@@ -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;
};

View File

@@ -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** 传输长度

View File

@@ -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

View File

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 497 KiB

View 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

View File

@@ -45,13 +45,11 @@ demo 包含 **video_static_yuyv_template**, **video_static_mjpeg_template**, **v
USB_ENDPOINT_DESCRIPTOR_INIT(VIDEO_IN_EP, 0x05, VIDEO_PACKET_SIZE, 0x01),
- 使用 `usbd_video_stream_start_write` 传输数据
- 使用 `usbd_video_stream_start_write` 传输数据, 最后 **do_copy** 选项表示是否将数据 copy 到 packet_buffer,
如果不选择 copy 则会直接在原图像数据中填充头部信息,并直接发送,达到 zero copy 功能。
1传输采用双缓冲的形式 **MAX_PACKETS_IN_ONE_TRANSFER** 表示一次传输可以携带多少个 **MAX_PAYLOAD_SIZE**,通常 IP 只能为 1
- 因为提供的是静态数据,不能被修改,因此需要重新给一个 frame_buffer 用于图像传输,在实际对接 camera 场景中是动态数据,直接使用 camera 的数据缓冲区即可
2在中断完成中调用 `usbd_video_stream_split_transfer` 继续下一次传输,直到返回为 true 表示传输完成。这边的分裂传输只是表示将图片数据拆成 **MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE** 份传输。
3通常 IP 不支持一次传输非常大的数据,比如传输 1MB因此需要做分裂传输但是会增加中断次数。并且一次传输非常大数据也是需要足够的 RAM。
.. code-block:: C
@@ -63,7 +61,8 @@ demo 包含 **video_static_yuyv_template**, **video_static_mjpeg_template**, **v
}
}
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[2][MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[MAX_PAYLOAD_SIZE];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t frame_buffer[32 * 1024];
void video_test(uint8_t busid)
{
@@ -72,7 +71,8 @@ demo 包含 **video_static_yuyv_template**, **video_static_mjpeg_template**, **v
while (1) {
if (tx_flag) {
iso_tx_busy = true;
usbd_video_stream_start_write(busid, VIDEO_IN_EP, &packet_buffer[0][0], &packet_buffer[1][0], MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE, (uint8_t *)cherryusb_mjpeg, sizeof(cherryusb_mjpeg));
memcpy(frame_buffer, cherryusb_mjpeg, sizeof(cherryusb_mjpeg)); // cherryusb_mjpeg is a static MJPEG frame buffer, so we need copy it to frame_buffer
usbd_video_stream_start_write(busid, VIDEO_IN_EP, packet_buffer, (uint8_t *)frame_buffer, sizeof(cherryusb_mjpeg), false);
while (iso_tx_busy) {
if (tx_flag == 0) {
break;

View File

@@ -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 的不需要使用定时器。

View File

@@ -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

View File

@@ -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

View File

@@ -1,2 +1,4 @@
usbh_serial
===============
当前仅支持 rt-thread device 框架,包括 cdc acm, ftdi, cp210x, ch34x, pl2303, 具体使用方式参考 rt-thread device api 即可。

View File

@@ -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

View File

@@ -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否则无法枚举
- 是否流片并销售
其余问题提问模板

View File

@@ -177,6 +177,8 @@ USB Device 移植要点
.. figure:: img/stm32_13.png
- 如果芯片带 cachecache 修改参考 :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` 章节
- 如果芯片带 cachecache 修改参考 :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

View File

@@ -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 编译器
* 如果芯片带 cachecache 修改参考 :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` 章节
* 如果芯片带 cachecache 修改参考 :ref:`usb_cache` 章节

View File

@@ -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 协议栈中的名称
- 如果芯片带 cachecache 修改参考 :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` 章节
- 如果芯片带 cachecache 修改参考 :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:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

After

Width:  |  Height:  |  Size: 842 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 MiB

View File

@@ -49,6 +49,14 @@ USB Device RNDIS
.. figure:: img/usbdev_rndis_win.png
.. figure:: img/usbdev_rndis_linux.png
USB Device UVC
-----------------------
演示 USB Device UVC + 摄像头传输 YUYV/MJPEG 640 * 480 图像。FPS 30。
.. figure:: img/usbdev_uvc_mjpeg.png
.. figure:: img/usbdev_uvc_yuv.png
USB Host HUB
-----------------------

Binary file not shown.

After

Width:  |  Height:  |  Size: 353 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

View File

@@ -20,7 +20,15 @@
- 主机 UVC & UAC 类 MUSB IP 中 ISO 驱动和 UAC/UVC 框架, MUSB 需要为 mentor 公司制定的标准 IP
- 从机 MTP 类驱动
- 从机 MTP 类驱动, 支持多文件和多文件夹,支持 MCU 端增删文件并与 PC 同步
.. figure:: img/mtpdev.png
- 从机 TMC 类驱动
.. figure:: img/tmcdev1.png
.. figure:: img/tmcdev2.png
- USB 网卡类高性能版本优化,包含 CDC-NCM, CDC-RNDIS, 私有类驱动(支持多包发送和接收),下面举例 RNDIS
.. figure:: img/rndistx.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View File

@@ -138,6 +138,10 @@ USB 对这个问题的解决办法,就是强制插 0也就是位填充
在数据被NRZI编码之前在数据流中每六个连续的1之后插入一个0以强制NRZI数据流中的过渡这使接收器逻辑至少每七位有一次数据转换以保证数据和时钟的锁定。比特填充是从同步模式开始启用。结束同步模式的数据 "一 "被算作是序列中的第一个 "一"。序列中的第一个。除了高速EOP期间发射器的位填充总是被强制执行。如果需要按照
位填充规则的要求零位将被插入即使它是数据包结束EOP信号前的最后一位。接收器必须对NRZI数据进行解码识别填充位并将其丢弃。
.. caution:: 以下内容可以用一张图概括,了解即可,没有必要死记硬背
.. figure:: img/usbstruct.png
USB 字段(域)
---------------------

View File

@@ -97,7 +97,7 @@ v1.4.3
- **host msc 将 scsi 初始化从枚举线程中移出在mount阶段调用并增加了testunity 多次尝试,兼容一部分 U 盘**
- rp2040 主从支持
- **nuttx fsserialnet 组件支持**
- dwc2、ehci、ohci 主机 dcache功能支持
- dwc2、ehci、ohci 主机 dcache功能支持v1.5.0 完善)
- t113、MCXA156、CH585 、 **stm32h7r 支持**
- 修复 v1.4.1 中 altsetting 为0时应该关闭所有端点的问题
@@ -105,17 +105,33 @@ v1.5.0
----------------------
- **协议栈内部全局 buffer 需要使用 USB_ALIGN_UP 对齐, 用于开启 dcache 并且不使能 nocache 时使用**
- **平台代码更新,平台相关转移到 platform增加 lvgl 键鼠支持blackmagic 支持, filex 支持**
- liteos-m, zephyr os 支持
- device msc 裸机读写采用变量模式而不是ringbuffer
- **完善 ehci/ohci dcache 模式下的处理** add CONFIG_USB_EHCI_DESC_DCACHE_ENABLE for qh&qtd&itd, add CONFIG_USB_OHCI_DESC_DCACHE_ENABLE for ed&td
- ehci qtd 使用 qtd alloc & free节省内存目前是 qh 携带 qtd
- **平台代码更新,平台相关转移到 platform增加 lvgl 键鼠支持blackmagic 支持filex 支持, zephyr disk支持esp-idf netif支持**
- **device sof callback 支持**
- **dwc2 、fsdev st 下实现底层 API 和中断,直接调用 HAL_PCD_MSP 和 HAL_HCD_MSP不需要用户复制粘贴**
- **DWC2 实现 SPLIT 功能,高速模式下支持外部高速 hub 对接 FS/LS 设备**
- liteos-m, zephyr os 支持
- device msc 裸机读写采用变量模式而不是ringbuffer
- ehci qtd 使用 qtd alloc & free节省内存目前是 qh 携带 qtd
- rndis/ECM device msc demo 更新,支持 rt-thread 下免修改
- **memcpy 全部使用 usb_memcpy 替换arm 库存在非对其访问问题**
- ch32 device iso 更新
- cmakekconfig 更新
- 使用 USB_ASSERT_MSG 对部分代码检查
- N32H4mm32f5 支持
- **重构 device mtp 驱动(收费使用)**
- **device tmc 驱动(收费使用)**
- **重构device video 传输,直接在图像数据中填充 uvc header达到zero memcpy**
- **增加 usb_osal_thread_schedule_other api用于在释放 class 资源之前,先释放所有 class 线程,避免释放 class 资源以后线程还在使用该 class 资源**
- **dwc2 device 增加 dcache 功能,可用于 cortex-M7/ESP32P4**
- **bouffalo/hpm/esp/st/nxp dcache api 支持**
- ch32 device iso 更新IP 目录重新分类
- cmakesconskconfig 更新
- 使用 USB_ASSERT_MSG 对部分代码检查,全面性 warning 修复
- N32H4/MM32F5 device 支持
- 默认使能 CONFIG_USBDEV_ADVANCE_DESC
v1.5.1
----------------------
- 支持 rt-thread 下使用 adb shellhost 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 初步支持

View File

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

View File

@@ -8,6 +8,7 @@
#include "sdkconfig.h"
#include "esp_rom_sys.h"
#include "esp_attr.h"
/* ================ USB common Configuration ================ */
@@ -25,8 +26,15 @@
#define CONFIG_USB_ALIGN_SIZE 4
#endif
// #define CONFIG_USB_DCACHE_ENABLE
/* attribute data into no cache ram */
#define USB_NOCACHE_RAM_SECTION
#define USB_NOCACHE_RAM_SECTION DRAM_DMA_ALIGNED_ATTR
/* use usb_memcpy default for high performance but cost more flash memory.
* And, arm libc has a bug that memcpy() may cause data misalignment when the size is not a multiple of 4.
*/
// #define CONFIG_USB_MEMCPY_DISABLE
/* ================= USB Device Stack Configuration ================ */
@@ -49,6 +57,9 @@
/* Enable test mode */
// #define CONFIG_USBDEV_TEST_MODE
/* enable advance desc register api */
#define CONFIG_USBDEV_ADVANCE_DESC
/* move ep0 setup handler from isr to thread */
// #define CONFIG_USBDEV_EP0_THREAD
@@ -84,7 +95,7 @@
// #define CONFIG_USBDEV_MSC_POLLING
/* move msc read & write from isr to thread */
// #define CONFIG_USBDEV_MSC_THREAD
#define CONFIG_USBDEV_MSC_THREAD
#ifndef CONFIG_USBDEV_MSC_PRIO
#define CONFIG_USBDEV_MSC_PRIO 4
@@ -94,6 +105,28 @@
#define CONFIG_USBDEV_MSC_STACKSIZE 2048
#endif
#ifndef CONFIG_USBDEV_MTP_MAX_BUFSIZE
#define CONFIG_USBDEV_MTP_MAX_BUFSIZE 2048
#endif
#ifndef CONFIG_USBDEV_MTP_MAX_OBJECTS
#define CONFIG_USBDEV_MTP_MAX_OBJECTS 256
#endif
#ifndef CONFIG_USBDEV_MTP_MAX_PATHNAME
#define CONFIG_USBDEV_MTP_MAX_PATHNAME 256
#endif
#define CONFIG_USBDEV_MTP_THREAD
#ifndef CONFIG_USBDEV_MTP_PRIO
#define CONFIG_USBDEV_MTP_PRIO 4
#endif
#ifndef CONFIG_USBDEV_MTP_STACKSIZE
#define CONFIG_USBDEV_MTP_STACKSIZE 4096
#endif
#ifndef CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE
#define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 156
#endif
@@ -112,6 +145,7 @@
#endif
#define CONFIG_USBDEV_RNDIS_USING_LWIP
#define CONFIG_USBDEV_CDC_ECM_USING_LWIP
/* ================ USB HOST Stack Configuration ================== */
@@ -134,10 +168,10 @@
#define CONFIG_USBHOST_PSC_PRIO 0
#endif
#ifndef CONFIG_USBHOST_PSC_STACKSIZE
#define CONFIG_USBHOST_PSC_STACKSIZE 2048
#define CONFIG_USBHOST_PSC_STACKSIZE 4096
#endif
// #define CONFIG_USBHOST_GET_STRING_DESC
//#define CONFIG_USBHOST_GET_STRING_DESC
// #define CONFIG_USBHOST_MSOS_ENABLE
#ifndef CONFIG_USBHOST_MSOS_VENDOR_CODE
@@ -212,65 +246,21 @@
#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_ESP32C5 || CONFIG_IDF_TARGET_ESP32P4
#define CONFIG_USB_HS
#define ESP_USBD_BASE 0x60080000
// todo: check c5, p4 in later
#define CONFIG_USBDEV_EP_NUM 7
#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_ESP32C5 || CONFIG_IDF_TARGET_ESP32P4
// todo: check c5, p4 in later
#define ESP_USBH_BASE 0x60080000
#define CONFIG_USBHOST_PIPE_NUM 8
#elif CONFIG_IDF_TARGET_ESP32P4
#define CONFIG_USBDEV_MAX_BUS 2
#define CONFIG_USBHOST_MAX_BUS 2
#define CONFIG_USB_HS
#else
#error "Unsupported SoC"
#endif
#define CONFIG_USBDEV_ADVANCE_DESC
#if CONFIG_IDF_TARGET_ESP32P4
#define CONFIG_USB_DCACHE_ENABLE
#undef CONFIG_USB_ALIGN_SIZE
#define CONFIG_USB_ALIGN_SIZE CONFIG_CACHE_L1_CACHE_LINE_SIZE
#endif

View File

@@ -25,6 +25,18 @@ void usb_osal_thread_delete(usb_osal_thread_t thread)
vTaskDelete(thread);
}
void usb_osal_thread_schedule_other(void)
{
TaskHandle_t xCurrentTask = xTaskGetCurrentTaskHandle();
const UBaseType_t old_priority = uxTaskPriorityGet(xCurrentTask);
vTaskPrioritySet(xCurrentTask, tskIDLE_PRIORITY);
taskYIELD();
vTaskPrioritySet(xCurrentTask, old_priority);
}
usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count)
{
return (usb_osal_sem_t)xSemaphoreCreateCounting(1, initial_count);

View File

@@ -30,6 +30,18 @@ void usb_osal_thread_delete(usb_osal_thread_t thread)
vTaskDelete(thread);
}
void usb_osal_thread_schedule_other(void)
{
TaskHandle_t xCurrentTask = xTaskGetCurrentTaskHandle();
const UBaseType_t old_priority = uxTaskPriorityGet(xCurrentTask);
vTaskPrioritySet(xCurrentTask, tskIDLE_PRIORITY);
taskYIELD();
vTaskPrioritySet(xCurrentTask, old_priority);
}
usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count)
{
usb_osal_sem_t sem = (usb_osal_sem_t)xSemaphoreCreateCounting(1, initial_count);

View File

@@ -15,33 +15,19 @@
#include "los_memory.h"
#include "los_swtmr.h"
typedef struct _usb_osal_thread {
UINT32 task_id;
char name[128];
} _usb_osal_thread_t;
usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size, uint32_t prio, usb_thread_entry_t entry, void *args)
{
_usb_osal_thread_t *t;
UINT32 task_id;
UINT32 ret;
TSK_INIT_PARAM_S task_init_param = {
.usTaskPrio = prio,
.pfnTaskEntry = (TSK_ENTRY_FUNC)entry,
.uwStackSize = stack_size,
.uwArg = (UINT32)args,
.pcName = name
};
t = usb_osal_malloc(sizeof(_usb_osal_thread_t));
if (t == NULL) {
USB_LOG_ERR("alloc thread %s failed\r\n", name);
while (1) {
}
}
strncpy(t->name, name, sizeof(t->name));
task_init_param.pcName = t->name;
ret = LOS_TaskCreate(&task_id, &task_init_param);
if (ret != LOS_OK) {
USB_LOG_ERR("Create task[%s] failed code[%u]\r\n", name, ret);
@@ -49,25 +35,36 @@ usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size,
}
}
t->task_id = task_id;
return (usb_osal_thread_t)t;
return (usb_osal_thread_t)task_id;
}
void usb_osal_thread_delete(usb_osal_thread_t thread)
{
_usb_osal_thread_t *t = (_usb_osal_thread_t *)thread;
UINT32 task_id = t->task_id;
UINT32 task_id = (UINT32)thread;
UINT32 ret;
if (thread == NULL) {
task_id = LOS_CurTaskIDGet();
}
ret = LOS_TaskDelete(task_id);
if (ret != LOS_OK) {
USB_LOG_ERR("Delete task id[%u] failed code[%u]\r\n", task_id, ret);
while (1) {
}
}
}
usb_osal_free(t);
void usb_osal_thread_schedule_other(void)
{
UINT32 task_id = LOS_CurTaskIDGet();
const UINT16 old_priority = LOS_TaskPriGet(task_id);
LOS_TaskPriSet(task_id, OS_TASK_PRIORITY_LOWEST);
LOS_TaskYield();
LOS_TaskPriSet(task_id, old_priority);
}
usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count)
@@ -91,7 +88,7 @@ void usb_osal_sem_delete(usb_osal_sem_t sem)
ret = LOS_SemDelete(sem_handle);
if (ret != LOS_OK) {
USB_LOG_ERR("Delete sem handle[%u] failed code[%u]\r\n",\
USB_LOG_ERR("Delete sem handle[%u] failed code[%u]\r\n",
sem_handle, ret);
while (1) {
}
@@ -103,9 +100,10 @@ int usb_osal_sem_take(usb_osal_sem_t sem, uint32_t timeout)
UINT32 sem_handle = (UINT32)sem;
UINT32 ret;
ret = LOS_SemPend(sem_handle, \
timeout == USB_OSAL_WAITING_FOREVER ? \
LOS_WAIT_FOREVER : timeout);
ret = LOS_SemPend(sem_handle,
timeout == USB_OSAL_WAITING_FOREVER ?
LOS_WAIT_FOREVER :
timeout);
return ret == LOS_OK ? 0 : -USB_ERR_TIMEOUT;
}
@@ -122,7 +120,6 @@ int usb_osal_sem_give(usb_osal_sem_t sem)
void usb_osal_sem_reset(usb_osal_sem_t sem)
{
}
usb_osal_mutex_t usb_osal_mutex_create(void)
@@ -146,8 +143,8 @@ void usb_osal_mutex_delete(usb_osal_mutex_t mutex)
ret = LOS_MuxDelete(mux_handle);
if (ret != LOS_OK) {
USB_LOG_ERR("Delete mux handle[%u] failed code[%u]\r\n",\
mux_handle, ret);
USB_LOG_ERR("Delete mux handle[%u] failed code[%u]\r\n",
mux_handle, ret);
while (1) {
}
}
@@ -194,7 +191,7 @@ void usb_osal_mq_delete(usb_osal_mq_t mq)
ret = LOS_QueueDelete(queue_id);
if (ret != LOS_OK) {
USB_LOG_ERR("Delete queue id[%u] failed code[%u]\r\n",\
USB_LOG_ERR("Delete queue id[%u] failed code[%u]\r\n",
queue_id, ret);
while (1) {
}
@@ -247,12 +244,13 @@ struct usb_osal_timer *usb_osal_timer_create(const char *name, uint32_t timeout_
memset(timer_handle, 0x00, sizeof(struct usb_osal_timer));
ret = LOS_SwtmrCreate(timeout_ms,
is_period ? LOS_SWTMR_MODE_PERIOD : LOS_SWTMR_MODE_NO_SELFDELETE,
(SWTMR_PROC_FUNC)handler, &timer_id, (UINT32)argument
is_period ? LOS_SWTMR_MODE_PERIOD : LOS_SWTMR_MODE_NO_SELFDELETE,
(SWTMR_PROC_FUNC)handler, &timer_id, (UINT32)argument
#if (LOSCFG_BASE_CORE_SWTMR_ALIGN == 1)
,OS_SWTMR_ROUSES_IGNORE, OS_SWTMR_ALIGN_INSENSITIVE
,
OS_SWTMR_ROUSES_IGNORE, OS_SWTMR_ALIGN_INSENSITIVE
#endif
);
);
if (ret != LOS_OK) {
USB_LOG_ERR("Create software timer failed code[%u]\r\n", ret);
@@ -276,7 +274,7 @@ void usb_osal_timer_delete(struct usb_osal_timer *timer)
ret = LOS_SwtmrDelete(timer_id);
if (ret != LOS_OK) {
USB_LOG_ERR("Delete software timer id[%u] failed code[%u]\r\n",\
USB_LOG_ERR("Delete software timer id[%u] failed code[%u]\r\n",
timer_id, ret);
while (1) {
}
@@ -291,7 +289,7 @@ void usb_osal_timer_start(struct usb_osal_timer *timer)
ret = LOS_SwtmrStart(timer_id);
if (ret != LOS_OK) {
USB_LOG_ERR("Start software timer id[%u] failed code[%u]\r\n",\
USB_LOG_ERR("Start software timer id[%u] failed code[%u]\r\n",
timer_id, ret);
while (1) {
}
@@ -305,7 +303,7 @@ void usb_osal_timer_stop(struct usb_osal_timer *timer)
ret = LOS_SwtmrStop(timer_id);
if (ret != LOS_OK) {
USB_LOG_ERR("Stop software timer id[%u] failed code[%u]\r\n",\
USB_LOG_ERR("Stop software timer id[%u] failed code[%u]\r\n",
timer_id, ret);
while (1) {
}

View File

@@ -63,6 +63,18 @@ void usb_osal_thread_delete(usb_osal_thread_t thread)
kthread_delete(pid);
}
void usb_osal_thread_schedule_other(void)
{
struct tcb_s *tcb = nxsched_self();
const int old_priority = tcb->sched_priority;
nxsched_set_priority(tcb, SCHED_PRIORITY_MIN);
sched_yield();
nxsched_set_priority(tcb, old_priority);
}
usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count)
{
int ret;

View File

@@ -34,6 +34,23 @@ void usb_osal_thread_delete(usb_osal_thread_t thread)
rt_thread_delete(thread);
}
void usb_osal_thread_schedule_other(void)
{
rt_thread_t self = rt_thread_self();
rt_uint8_t priority;
#if (RTTHREAD_VERSION >= RT_VERSION_CHECK(5, 2, 0))
const rt_uint8_t old_priority = RT_SCHED_PRIV(self).current_priority;
#else
const rt_uint8_t old_priority = self->current_priority;
#endif
priority = RT_THREAD_PRIORITY_MAX - 1;
rt_thread_control(self, RT_THREAD_CTRL_CHANGE_PRIORITY, (void *)&priority);
rt_thread_yield();
rt_thread_control(self, RT_THREAD_CTRL_CHANGE_PRIORITY, (void *)&old_priority);
}
usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count)
{
usb_osal_sem_t sem = (usb_osal_sem_t)rt_sem_create("usbh_sem", initial_count, RT_IPC_FLAG_FIFO);

View File

@@ -69,6 +69,18 @@ void usb_osal_thread_delete(usb_osal_thread_t thread)
tx_byte_release(thread);
}
void usb_osal_thread_schedule_other(void)
{
TX_THREAD *current_thread = tx_thread_identify();
const UINT old_priority = current_thread->tx_thread_priority;
tx_thread_priority_change(current_thread, TX_MAX_PRIORITIES - 1, &old_priority);
tx_thread_relinquish();
tx_thread_priority_change(current_thread, old_priority, &old_priority);
}
usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count)
{
TX_SEMAPHORE *sem_ptr = TX_NULL;

View File

@@ -74,6 +74,22 @@ void usb_osal_thread_delete(usb_osal_thread_t thread)
k_free(thread);
}
void usb_osal_thread_schedule_other(void)
{
#if (KERNELVERSION >= 0x3070000)
struct k_thread *current_thread = k_sched_current_thread_query();
#else
struct k_thread *current_thread = z_current_get();
#endif
const int old_priority = k_thread_priority_get(current_thread);
k_thread_priority_set(current_thread, K_LOWEST_APPLICATION_THREAD_PRIO);
k_yield();
k_thread_priority_set(current_thread, old_priority);
}
usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count)
{
struct k_sem *sem;

View File

@@ -5,7 +5,8 @@ This is a platform support for other opensource projects.
## Fatfs
Fatfs support with usb host msc.
- Fatfs support with usb host msc.
- Fatfs support with usb device mtp.
## lwip
@@ -17,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
@@ -34,6 +36,7 @@ lwip support with usb host net class(cdc_ecm/cdc_ncm/cdc_rndis/asix/rtl8152/bl61
## Zephyr
- shell support with lsusb
- disk support with usb host msc
## LVGL

View File

@@ -0,0 +1,351 @@
/*
* Copyright (c) 2025, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "ff.h"
#include "diskio.h"
#include "usbd_core.h"
#include "usb_osal.h"
#include "usbd_mtp.h"
FATFS s_sd_disk;
FIL s_file;
BYTE work[FF_MAX_SS];
const TCHAR driver_num_buf[3] = { '0', ':', '\0' };
const char *show_error_string(FRESULT fresult);
static FRESULT sd_mount_fs(void)
{
FRESULT fresult = f_mount(&s_sd_disk, driver_num_buf, 1);
if (fresult == FR_OK) {
printf("SD card has been mounted successfully\n");
} else {
printf("Failed to mount SD card, cause: %s\n", show_error_string(fresult));
}
return fresult;
}
#if 0
static FRESULT sd_mkfs(void)
{
printf("Formatting the SD card, depending on the SD card capacity, the formatting process may take a long time\n");
FRESULT fresult = f_mkfs(driver_num_buf, NULL, work, sizeof(work));
if (fresult != FR_OK) {
printf("Making File system failed, cause: %s\n", show_error_string(fresult));
} else {
printf("Making file system is successful\n");
}
return fresult;
}
#endif
static FRESULT sd_write_file(void)
{
FRESULT fresult = f_open(&s_file, "0:/readme.txt", FA_WRITE | FA_CREATE_ALWAYS);
if (fresult != FR_OK) {
printf("Create new file failed, cause: %d\n", show_error_string(fresult));
} else {
printf("Create new file successfully, status=%d\n", fresult);
}
char hello_str[] = "Hello, this is SD card FATFS demo\n";
UINT byte_written;
fresult = f_write(&s_file, hello_str, sizeof(hello_str), &byte_written);
if (fresult != FR_OK) {
printf("Write file failed, cause: %s\n", show_error_string(fresult));
} else {
printf("Write file operation is successfully\n");
}
f_close(&s_file);
return fresult;
}
const char *show_error_string(FRESULT fresult)
{
const char *result_str;
switch (fresult) {
case FR_OK:
result_str = "succeeded";
break;
case FR_DISK_ERR:
result_str = "A hard error occurred in the low level disk I/O level";
break;
case FR_INT_ERR:
result_str = "Assertion failed";
break;
case FR_NOT_READY:
result_str = "The physical drive cannot work";
break;
case FR_NO_FILE:
result_str = "Could not find the file";
break;
case FR_NO_PATH:
result_str = "Could not find the path";
break;
case FR_INVALID_NAME:
result_str = "Tha path name format is invalid";
break;
case FR_DENIED:
result_str = "Access denied due to prohibited access or directory full";
break;
case FR_EXIST:
result_str = "Access denied due to prohibited access";
break;
case FR_INVALID_OBJECT:
result_str = "The file/directory object is invalid";
break;
case FR_WRITE_PROTECTED:
result_str = "The physical drive is write protected";
break;
case FR_INVALID_DRIVE:
result_str = "The logical driver number is invalid";
break;
case FR_NOT_ENABLED:
result_str = "The volume has no work area";
break;
case FR_NO_FILESYSTEM:
result_str = "There is no valid FAT volume";
break;
case FR_MKFS_ABORTED:
result_str = "THe f_mkfs() aborted due to any problem";
break;
case FR_TIMEOUT:
result_str = "Could not get a grant to access the volume within defined period";
break;
case FR_LOCKED:
result_str = "The operation is rejected according to the file sharing policy";
break;
case FR_NOT_ENOUGH_CORE:
result_str = "LFN working buffer could not be allocated";
break;
case FR_TOO_MANY_OPEN_FILES:
result_str = "Number of open files > FF_FS_LOCK";
break;
case FR_INVALID_PARAMETER:
result_str = "Given parameter is invalid";
break;
default:
result_str = "Unknown error";
break;
}
return result_str;
}
const char *usbd_mtp_fs_root_path(void)
{
return driver_num_buf;
}
const char *usbd_mtp_fs_description(void)
{
return "CherryUSB MTP";
}
int usbd_mtp_mkdir(const char *path)
{
FRESULT result = f_mkdir(path);
if (result != FR_OK) {
printf("f_mkdir failed, cause: %s\n", show_error_string(result));
return -1;
}
return 0; // Directory created successfully
}
int usbd_mtp_rmdir(const char *path)
{
FRESULT result = f_rmdir(path);
if (result != FR_OK) {
printf("f_mkdir failed, cause: %s\n", show_error_string(result));
return -1;
}
return 0; // Directory created successfully
}
MTP_DIR *usbd_mtp_opendir(const char *name)
{
FRESULT result;
DIR *dir;
dir = usb_osal_malloc(sizeof(DIR));
result = f_opendir(dir, name);
if (result != FR_OK) {
printf("f_opendir failed, cause: %s\n", show_error_string(result));
usb_osal_free(dir);
return NULL; // Failed to open directory
}
return (MTP_DIR *)dir;
}
int usbd_mtp_closedir(MTP_DIR *dir)
{
FRESULT result;
result = f_closedir((DIR *)dir);
if (result != FR_OK) {
printf("f_closedir failed, cause: %s\n", show_error_string(result));
return -1; // Failed to close directory
}
usb_osal_free(dir); // Free the directory structure
return result;
}
struct mtp_dirent *usbd_mtp_readdir(MTP_DIR *dir)
{
FILINFO fno;
FRESULT result;
result = f_readdir((DIR *)dir, &fno);
if (result != FR_OK || fno.fname[0] == 0)
return NULL;
static struct mtp_dirent dirent;
memset(&dirent, 0, sizeof(struct mtp_dirent));
strncpy(dirent.d_name, fno.fname, sizeof(dirent.d_name) - 1);
dirent.d_name[sizeof(dirent.d_name) - 1] = '\0';
dirent.d_namlen = strlen(dirent.d_name);
return &dirent;
}
#undef SS
#if FF_MAX_SS == FF_MIN_SS
#define SS(fs) ((UINT)FF_MAX_SS) /* Fixed sector size */
#else
#define SS(fs) ((fs)->ssize) /* Variable sector size */
#endif
int usbd_mtp_stat(const char *path, struct stat *buf)
{
FILINFO file_info;
FRESULT result;
FATFS *f;
f = &s_sd_disk;
result = f_stat(path, &file_info);
if (result != FR_OK) {
printf("f_stat failed, cause: %s\n", show_error_string(result));
return -1;
}
buf->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH |
S_IWUSR | S_IWGRP | S_IWOTH;
if (file_info.fattrib & AM_DIR) {
buf->st_mode &= ~S_IFREG;
buf->st_mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
}
if (file_info.fattrib & AM_RDO)
buf->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
buf->st_size = file_info.fsize;
buf->st_blksize = f->csize * SS(f);
if (file_info.fattrib & AM_ARC) {
buf->st_blocks = file_info.fsize ? ((file_info.fsize - 1) / SS(f) / f->csize + 1) : 0;
buf->st_blocks *= (buf->st_blksize / 512); // man say st_blocks is number of 512B blocks allocated
} else {
buf->st_blocks = f->csize;
}
return 0;
}
int usbd_mtp_statfs(const char *path, struct mtp_statfs *buf)
{
FATFS *f;
FRESULT res;
DWORD fre_clust, fre_sect, tot_sect;
f = &s_sd_disk;
res = f_getfree(path, &fre_clust, &f);
if (res != FR_OK) {
printf("f_getfree failed, cause: %s\n", show_error_string(res));
return -1;
}
tot_sect = (f->n_fatent - 2) * f->csize;
fre_sect = fre_clust * f->csize;
buf->f_blocks = tot_sect;
buf->f_bfree = fre_sect;
#if FF_MAX_SS != FF_MIN_SS
buf->f_bsize = f->ssize;
#else
buf->f_bsize = FF_MIN_SS;
#endif
return 0;
}
int usbd_mtp_open(const char *path, uint8_t mode)
{
BYTE flags;
if (mode == O_RDONLY) {
flags = FA_READ | FA_OPEN_EXISTING;
} else if (mode == O_WRONLY) {
flags = FA_WRITE | FA_OPEN_ALWAYS;
} else if (mode == O_RDWR) {
flags = FA_READ | FA_WRITE | FA_OPEN_ALWAYS;
} else {
return -1; // Invalid mode
}
FRESULT result = f_open(&s_file, path, flags);
if (result != FR_OK) {
printf("f_open failed, cause: %s\n", show_error_string(result));
return -1;
}
return 0;
}
int usbd_mtp_close(int fd)
{
FRESULT result = f_close(&s_file);
if (result != FR_OK) {
printf("f_close failed, cause: %s\n", show_error_string(result));
return -1;
}
return 0;
}
int usbd_mtp_read(int fd, void *buf, size_t len)
{
UINT bytes_read;
FRESULT result = f_read(&s_file, buf, len, &bytes_read);
if (result != FR_OK) {
printf("f_read failed, cause: %s\n", show_error_string(result));
return -1;
}
return bytes_read; // Return number of bytes read
}
int usbd_mtp_write(int fd, const void *buf, size_t len)
{
UINT bytes_written;
FRESULT result = f_write(&s_file, buf, len, &bytes_written);
if (result != FR_OK) {
printf("f_write failed, cause: %s\n", show_error_string(result));
return -1;
}
return bytes_written; // Return number of bytes written
}
int usbd_mtp_unlink(const char *path)
{
FRESULT result = f_unlink(path);
if (result != FR_OK) {
printf("f_unlink failed, cause: %s\n", show_error_string(result));
return -1;
}
return 0; // File deleted successfully
}
void usbd_mtp_mount()
{
sd_mount_fs();
// write a file to test the SD card
sd_write_file();
}

View File

@@ -10,11 +10,6 @@
struct usbh_msc *active_msc_class;
int USB_disk_status(void)
{
return RES_OK;
}
int USB_disk_initialize(void)
{
active_msc_class = (struct usbh_msc *)usbh_find_class_instance("/dev/sda");
@@ -28,14 +23,69 @@ int USB_disk_initialize(void)
return RES_OK;
}
int USB_disk_status(void)
{
return RES_OK;
}
int USB_disk_read(BYTE *buff, LBA_t sector, UINT count)
{
return usbh_msc_scsi_read10(active_msc_class, sector, buff, count);
int ret;
uint8_t *align_buf;
align_buf = (uint8_t *)buff;
#ifdef CONFIG_USB_DCACHE_ENABLE
if ((uint32_t)buff & (CONFIG_USB_ALIGN_SIZE - 1)) {
align_buf = (uint8_t *)aligned_alloc(CONFIG_USB_ALIGN_SIZE, count * active_msc_class->blocksize);
if (!align_buf) {
printf("msc get align buf failed\r\n");
return -USB_ERR_NOMEM;
}
}
#endif
ret = usbh_msc_scsi_read10(active_msc_class, sector, align_buf, count);
if (ret < 0) {
ret = RES_ERROR;
} else {
ret = RES_OK;
}
#ifdef CONFIG_USB_DCACHE_ENABLE
if ((uint32_t)buff & (CONFIG_USB_ALIGN_SIZE - 1)) {
usb_memcpy(buff, align_buf, count * active_msc_class->blocksize);
free(align_buf);
}
#endif
return ret;
}
int USB_disk_write(const BYTE *buff, LBA_t sector, UINT count)
{
return usbh_msc_scsi_write10(active_msc_class, sector, buff, count);
int ret;
uint8_t *align_buf;
align_buf = (uint8_t *)buff;
#ifdef CONFIG_USB_DCACHE_ENABLE
if ((uint32_t)buff & (CONFIG_USB_ALIGN_SIZE - 1)) {
align_buf = (uint8_t *)aligned_alloc(CONFIG_USB_ALIGN_SIZE, count * active_msc_class->blocksize);
if (!align_buf) {
printf("msc get align buf failed\r\n");
return -USB_ERR_NOMEM;
}
usb_memcpy(align_buf, buff, count * active_msc_class->blocksize);
}
#endif
ret = usbh_msc_scsi_write10(active_msc_class, sector, align_buf, count);
if (ret < 0) {
ret = RES_ERROR;
} else {
ret = RES_OK;
}
#ifdef CONFIG_USB_DCACHE_ENABLE
if ((uint32_t)buff & (CONFIG_USB_ALIGN_SIZE - 1)) {
free(align_buf);
}
#endif
return ret;
}
int USB_disk_ioctl(BYTE cmd, void *buff)

408
platform/idf/usbh_net.c Normal file
View File

@@ -0,0 +1,408 @@
/*
* Copyright (c) 2025, Loogg
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdlib.h>
#include <inttypes.h>
#include "lwip/netif.h"
#include "esp_log.h"
#include "esp_event.h"
#include "esp_check.h"
#include "esp_netif.h"
#include "usbh_core.h"
#if TCPIP_THREAD_STACKSIZE < 1024
#error TCPIP_THREAD_STACKSIZE must be >= 1024
#endif
// #define CONFIG_USBHOST_PLATFORM_CDC_ECM
// #define CONFIG_USBHOST_PLATFORM_CDC_RNDIS
// #define CONFIG_USBHOST_PLATFORM_CDC_NCM
// #define CONFIG_USBHOST_PLATFORM_ASIX
// #define CONFIG_USBHOST_PLATFORM_RTL8152
// #define CONFIG_USBHOST_PLATFORM_BL616
struct usbh_net_netif_glue {
esp_netif_driver_base_t base;
esp_event_handler_instance_t ins_got_ip;
void *usbh_class;
esp_err_t (*transmit)(void *h, void *buffer, size_t len);
};
static void usbh_net_input_common(struct usbh_net_netif_glue *netif_glue, uint8_t *buf, uint32_t len)
{
uint8_t *input_buf = buf;
#if !LWIP_TCPIP_CORE_LOCKING_INPUT
input_buf = usb_osal_malloc(len);
if (input_buf == NULL) {
USB_LOG_ERR("No memory to alloc input buffer\r\n");
return;
}
usb_memcpy(input_buf, buf, len);
#endif
esp_netif_receive(netif_glue->base.netif, input_buf, len, NULL);
}
static void usbh_net_free(void *h, void *buffer)
{
#if !LWIP_TCPIP_CORE_LOCKING_INPUT
usb_osal_free(buffer);
#endif
}
static esp_err_t usbh_net_post_attach(esp_netif_t *esp_netif, void *args)
{
struct usbh_net_netif_glue *netif_glue = (struct usbh_net_netif_glue *)args;
netif_glue->base.netif = esp_netif;
// set driver related config to esp-netif
esp_netif_driver_ifconfig_t driver_ifconfig = {
.handle = netif_glue,
.transmit = netif_glue->transmit,
.driver_free_rx_buffer = usbh_net_free,
};
ESP_ERROR_CHECK(esp_netif_set_driver_config(esp_netif, &driver_ifconfig));
return ESP_OK;
}
static void usbh_net_action_got_ip(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
struct usbh_net_netif_glue *netif_glue = (struct usbh_net_netif_glue *)handler_args;
ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
const esp_netif_ip_info_t *ip_info = &event->ip_info;
USB_LOG_INFO("NETIF %s Got IP Address\r\n", esp_netif_get_ifkey(netif_glue->base.netif));
USB_LOG_INFO("IP:" IPSTR "\r\n", IP2STR(&ip_info->ip));
USB_LOG_INFO("MASK:" IPSTR "\r\n", IP2STR(&ip_info->netmask));
USB_LOG_INFO("GW:" IPSTR "\r\n\r\n", IP2STR(&ip_info->gw));
}
static esp_err_t usbh_net_netif_glue_init_common(struct usbh_net_netif_glue *netif_glue, void *usbh_class, esp_err_t (*transmit)(void *h, void *buffer, size_t len))
{
netif_glue->usbh_class = usbh_class;
netif_glue->transmit = transmit;
netif_glue->base.post_attach = usbh_net_post_attach;
return esp_event_handler_instance_register(IP_EVENT, IP_EVENT_ETH_GOT_IP, usbh_net_action_got_ip, netif_glue, &netif_glue->ins_got_ip);
}
static esp_err_t usbh_net_netif_glue_deinit_common(struct usbh_net_netif_glue *netif_glue)
{
return esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_ETH_GOT_IP, netif_glue->ins_got_ip);
}
#ifdef CONFIG_USBHOST_PLATFORM_CDC_ECM
#include "usbh_cdc_ecm.h"
struct usbh_net_netif_glue g_cdc_ecm_netif_glue;
static esp_err_t usbh_cdc_ecm_transmit(void *h, void *buffer, size_t len)
{
int ret;
(void)h;
usb_memcpy(usbh_cdc_ecm_get_eth_txbuf(), buffer, len);
ret = usbh_cdc_ecm_eth_output(len);
if (ret < 0) {
return ESP_FAIL;
}
return ESP_OK;
}
void usbh_cdc_ecm_eth_input(uint8_t *buf, uint32_t buflen)
{
usbh_net_input_common(&g_cdc_ecm_netif_glue, buf, buflen);
}
void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class)
{
memset(&g_cdc_ecm_netif_glue, 0, sizeof(struct usbh_net_netif_glue));
esp_netif_inherent_config_t base_cfg = ESP_NETIF_INHERENT_DEFAULT_ETH();
base_cfg.if_key = "u0";
base_cfg.if_desc = "usbh cdc ecm";
esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
netif_cfg.base = &base_cfg;
esp_netif_t *esp_netif = esp_netif_new(&netif_cfg);
usbh_net_netif_glue_init_common(&g_cdc_ecm_netif_glue, cdc_ecm_class, usbh_cdc_ecm_transmit);
esp_netif_attach(esp_netif, &g_cdc_ecm_netif_glue.base);
esp_netif_set_mac(esp_netif, cdc_ecm_class->mac);
esp_netif_action_start(esp_netif, NULL, 0, NULL);
esp_netif_action_connected(esp_netif, NULL, 0, NULL);
usb_osal_thread_create("usbh_cdc_ecm_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_ecm_rx_thread, NULL);
}
void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class)
{
(void)cdc_ecm_class;
usbh_net_netif_glue_deinit_common(&g_cdc_ecm_netif_glue);
esp_netif_action_stop(g_cdc_ecm_netif_glue.base.netif, NULL, 0, NULL);
esp_netif_destroy(g_cdc_ecm_netif_glue.base.netif);
}
#endif
#ifdef CONFIG_USBHOST_PLATFORM_CDC_RNDIS
#include "usbh_rndis.h"
struct usb_osal_timer *timer_handle;
static void rndis_dev_keepalive_timeout(void *arg)
{
struct usbh_rndis *rndis_class = (struct usbh_rndis *)arg;
usbh_rndis_keepalive(rndis_class);
}
void timer_init(struct usbh_rndis *rndis_class)
{
timer_handle = usb_osal_timer_create("rndis_keepalive", 5000, rndis_dev_keepalive_timeout, rndis_class, true);
if (NULL != timer_handle) {
usb_osal_timer_start(timer_handle);
} else {
USB_LOG_ERR("timer creation failed! \r\n");
for (;;) {
;
}
}
}
struct usbh_net_netif_glue g_rndis_netif_glue;
static esp_err_t usbh_rndis_transmit(void *h, void *buffer, size_t len)
{
int ret;
(void)h;
usb_memcpy(usbh_rndis_get_eth_txbuf(), buffer, len);
ret = usbh_rndis_eth_output(len);
if (ret < 0) {
return ESP_FAIL;
}
return ESP_OK;
}
void usbh_rndis_eth_input(uint8_t *buf, uint32_t buflen)
{
usbh_net_input_common(&g_rndis_netif_glue, buf, buflen);
}
void usbh_rndis_run(struct usbh_rndis *rndis_class)
{
memset(&g_rndis_netif_glue, 0, sizeof(struct usbh_net_netif_glue));
esp_netif_inherent_config_t base_cfg = ESP_NETIF_INHERENT_DEFAULT_ETH();
base_cfg.if_key = "u2";
base_cfg.if_desc = "usbh rndis";
esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
netif_cfg.base = &base_cfg;
esp_netif_t *esp_netif = esp_netif_new(&netif_cfg);
usbh_net_netif_glue_init_common(&g_rndis_netif_glue, rndis_class, usbh_rndis_transmit);
esp_netif_attach(esp_netif, &g_rndis_netif_glue.base);
esp_netif_set_mac(esp_netif, rndis_class->mac);
esp_netif_action_start(esp_netif, NULL, 0, NULL);
esp_netif_action_connected(esp_netif, NULL, 0, NULL);
usb_osal_thread_create("usbh_rndis_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rndis_rx_thread, NULL);
//timer_init(rndis_class);
}
void usbh_rndis_stop(struct usbh_rndis *rndis_class)
{
(void)rndis_class;
usbh_net_netif_glue_deinit_common(&g_rndis_netif_glue);
esp_netif_action_stop(g_rndis_netif_glue.base.netif, NULL, 0, NULL);
esp_netif_destroy(g_rndis_netif_glue.base.netif);
// xTimerStop(timer_handle, 0);
// xTimerDelete(timer_handle, 0);
}
#endif
#ifdef CONFIG_USBHOST_PLATFORM_CDC_NCM
#include "usbh_cdc_ncm.h"
struct usbh_net_netif_glue g_cdc_ncm_netif_glue;
static esp_err_t usbh_cdc_ncm_transmit(void *h, void *buffer, size_t len)
{
int ret;
(void)h;
usb_memcpy(usbh_cdc_ncm_get_eth_txbuf(), buffer, len);
ret = usbh_cdc_ncm_eth_output(len);
if (ret < 0) {
return ESP_FAIL;
}
return ESP_OK;
}
void usbh_cdc_ncm_eth_input(uint8_t *buf, uint32_t buflen)
{
usbh_net_input_common(&g_cdc_ncm_netif_glue, buf, buflen);
}
void usbh_cdc_ncm_run(struct usbh_cdc_ncm *cdc_ncm_class)
{
memset(&g_cdc_ncm_netif_glue, 0, sizeof(struct usbh_net_netif_glue));
esp_netif_inherent_config_t base_cfg = ESP_NETIF_INHERENT_DEFAULT_ETH();
base_cfg.if_key = "u1";
base_cfg.if_desc = "usbh cdc ncm";
esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
netif_cfg.base = &base_cfg;
esp_netif_t *esp_netif = esp_netif_new(&netif_cfg);
usbh_net_netif_glue_init_common(&g_cdc_ncm_netif_glue, cdc_ncm_class, usbh_cdc_ncm_transmit);
esp_netif_attach(esp_netif, &g_cdc_ncm_netif_glue.base);
esp_netif_set_mac(esp_netif, cdc_ncm_class->mac);
esp_netif_action_start(esp_netif, NULL, 0, NULL);
esp_netif_action_connected(esp_netif, NULL, 0, NULL);
usb_osal_thread_create("usbh_cdc_ncm_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_ncm_rx_thread, NULL);
}
void usbh_cdc_ncm_stop(struct usbh_cdc_ncm *cdc_ncm_class)
{
(void)cdc_ncm_class;
usbh_net_netif_glue_deinit_common(&g_cdc_ncm_netif_glue);
esp_netif_action_stop(g_cdc_ncm_netif_glue.base.netif, NULL, 0, NULL);
esp_netif_destroy(g_cdc_ncm_netif_glue.base.netif);
}
#endif
#ifdef CONFIG_USBHOST_PLATFORM_ASIX
#include "usbh_asix.h"
struct usbh_net_netif_glue g_asix_netif_glue;
static esp_err_t usbh_asix_transmit(void *h, void *buffer, size_t len)
{
int ret;
(void)h;
usb_memcpy(usbh_asix_get_eth_txbuf(), buffer, len);
ret = usbh_asix_eth_output(len);
if (ret < 0) {
return ESP_FAIL;
}
return ESP_OK;
}
void usbh_asix_eth_input(uint8_t *buf, uint32_t buflen)
{
usbh_net_input_common(&g_asix_netif_glue, buf, buflen);
}
void usbh_asix_run(struct usbh_asix *asix_class)
{
memset(&g_asix_netif_glue, 0, sizeof(struct usbh_net_netif_glue));
esp_netif_inherent_config_t base_cfg = ESP_NETIF_INHERENT_DEFAULT_ETH();
base_cfg.if_key = "u3";
base_cfg.if_desc = "usbh asix";
esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
netif_cfg.base = &base_cfg;
esp_netif_t *esp_netif = esp_netif_new(&netif_cfg);
usbh_net_netif_glue_init_common(&g_asix_netif_glue, asix_class, usbh_asix_transmit);
esp_netif_attach(esp_netif, &g_asix_netif_glue.base);
esp_netif_set_mac(esp_netif, asix_class->mac);
esp_netif_action_start(esp_netif, NULL, 0, NULL);
esp_netif_action_connected(esp_netif, NULL, 0, NULL);
usb_osal_thread_create("usbh_asix_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_asix_rx_thread, NULL);
}
void usbh_asix_stop(struct usbh_asix *asix_class)
{
(void)asix_class;
usbh_net_netif_glue_deinit_common(&g_asix_netif_glue);
esp_netif_action_stop(g_asix_netif_glue.base.netif, NULL, 0, NULL);
esp_netif_destroy(g_asix_netif_glue.base.netif);
}
#endif
#ifdef CONFIG_USBHOST_PLATFORM_RTL8152
#include "usbh_rtl8152.h"
struct usbh_net_netif_glue g_rtl8152_netif_glue;
static esp_err_t usbh_rtl8152_transmit(void *h, void *buffer, size_t len)
{
int ret;
(void)h;
usb_memcpy(usbh_rtl8152_get_eth_txbuf(), buffer, len);
ret = usbh_rtl8152_eth_output(len);
if (ret < 0) {
return ESP_FAIL;
}
return ESP_OK;
}
void usbh_rtl8152_eth_input(uint8_t *buf, uint32_t buflen)
{
usbh_net_input_common(&g_rtl8152_netif_glue, buf, buflen);
}
void usbh_rtl8152_run(struct usbh_rtl8152 *rtl8152_class)
{
memset(&g_rtl8152_netif_glue, 0, sizeof(struct usbh_net_netif_glue));
esp_netif_inherent_config_t base_cfg = ESP_NETIF_INHERENT_DEFAULT_ETH();
base_cfg.if_key = "u4";
base_cfg.if_desc = "usbh rtl8152";
esp_netif_config_t netif_cfg = ESP_NETIF_DEFAULT_ETH();
netif_cfg.base = &base_cfg;
esp_netif_t *esp_netif = esp_netif_new(&netif_cfg);
usbh_net_netif_glue_init_common(&g_rtl8152_netif_glue, rtl8152_class, usbh_rtl8152_transmit);
esp_netif_attach(esp_netif, &g_rtl8152_netif_glue.base);
esp_netif_set_mac(esp_netif, rtl8152_class->mac);
esp_netif_action_start(esp_netif, NULL, 0, NULL);
esp_netif_action_connected(esp_netif, NULL, 0, NULL);
usb_osal_thread_create("usbh_rtl8152_rx", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_rtl8152_rx_thread, NULL);
}
void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class)
{
(void)rtl8152_class;
usbh_net_netif_glue_deinit_common(&g_rtl8152_netif_glue);
esp_netif_action_stop(g_rtl8152_netif_glue.base.netif, NULL, 0, NULL);
esp_netif_destroy(g_rtl8152_netif_glue.base.netif);
}
#endif

View File

@@ -1,4 +1,10 @@
/*
* Copyright (c) 2022 ~ 2025, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "rtthread.h"
#include "usb_config.h"
#if defined(PKG_CHERRYUSB_HOST) || defined(RT_CHERRYUSB_HOST)
@@ -11,3 +17,20 @@
#endif
#endif
#if defined(ARCH_ARM_CORTEX_M7) || \
defined(SOC_HPM6000) || defined(SOC_HPM6E00) || defined(SOC_HPM6P00) || \
defined(BSP_USING_BL61X) || defined(BSP_USING_BL808)
#ifndef RT_USING_CACHE
#error RT_USING_CACHE must be enabled in this chip
#endif
#endif
#ifdef RT_USING_CACHE
#ifndef CONFIG_USB_DCACHE_ENABLE
#error CONFIG_USB_DCACHE_ENABLE must be enabled
#endif
#if RT_ALIGN_SIZE != 32 && RT_ALIGN_SIZE != 64
#error RT_ALIGN_SIZE must be cacheline to 32 or 64
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More