Compare commits
86 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b7d6e34bb | ||
|
|
316b256baa | ||
|
|
5e406f41c1 | ||
|
|
043c594cd8 | ||
|
|
cc4ed56a88 | ||
|
|
6ada1e0260 | ||
|
|
75ddfc8e4d | ||
|
|
2baec4fd32 | ||
|
|
efde616203 | ||
|
|
921ed9b697 | ||
|
|
4070603e57 | ||
|
|
3fa3f3e356 | ||
|
|
f99e03c850 | ||
|
|
8abe7bcc2a | ||
|
|
34cda737ed | ||
|
|
c5310e1093 | ||
|
|
75dd9ae62d | ||
|
|
e37d5d3866 | ||
|
|
1330b98ad8 | ||
|
|
63bc4e9363 | ||
|
|
82e4baf908 | ||
|
|
af88c8e90b | ||
|
|
b00fd55aff | ||
|
|
84dfcef639 | ||
|
|
201b3ebb2c | ||
|
|
68c9779898 | ||
|
|
dbaad329bf | ||
|
|
d0890c2caf | ||
|
|
2c24b54bf1 | ||
|
|
e475dd730b | ||
|
|
1df1fefa39 | ||
|
|
b0e1cf4c02 | ||
|
|
215d72f8f9 | ||
|
|
55e4adccd6 | ||
|
|
5f39f6dce9 | ||
|
|
f65a6589ed | ||
|
|
93c069ac67 | ||
|
|
0be8327785 | ||
|
|
132db88885 | ||
|
|
3b5cb7603f | ||
|
|
e1585f801c | ||
|
|
2e7c4953ce | ||
|
|
1d84f735d3 | ||
|
|
8955bf5f0d | ||
|
|
914d3cbf42 | ||
|
|
db330b42e7 | ||
|
|
f45e0f47fa | ||
|
|
e9b5023c79 | ||
|
|
b461821639 | ||
|
|
27ff38f745 | ||
|
|
62276b1e8b | ||
|
|
902f1da407 | ||
|
|
e88756a412 | ||
|
|
82cd954252 | ||
|
|
2364d0a6ba | ||
|
|
9f9c44d974 | ||
|
|
d0a6ecbe89 | ||
|
|
2a8a7ecdf0 | ||
|
|
9bcea9ae37 | ||
|
|
82596cea4b | ||
|
|
43a45fc2fc | ||
|
|
52edc32521 | ||
|
|
fc9afb5405 | ||
|
|
843af28b2b | ||
|
|
9a67853751 | ||
|
|
051c380f3b | ||
|
|
4f83b333a0 | ||
|
|
1bd423cef9 | ||
|
|
9b72a17a5b | ||
|
|
ed323a6fa4 | ||
|
|
77f0afb94f | ||
|
|
7e749a8a7b | ||
|
|
6c5be4aa1f | ||
|
|
d0ab9d7f89 | ||
|
|
e3d4797928 | ||
|
|
ea1beea612 | ||
|
|
9e9e4df50b | ||
|
|
16f55a5a19 | ||
|
|
c2d34d10a4 | ||
|
|
512de54d33 | ||
|
|
69e240355d | ||
|
|
cfb3ae23f8 | ||
|
|
61e82e0eeb | ||
|
|
9291c1459c | ||
|
|
24f854d209 | ||
|
|
cf97d5276e |
28
README.md
28
README.md
@@ -88,7 +88,8 @@ CherryUSB Host Stack has the following functions:
|
||||
- Support Communication Device Class (CDC)
|
||||
- Support Human Interface Device (HID)
|
||||
- Support Mass Storage Class (MSC)
|
||||
- Support USB VIDEO CLASS
|
||||
- Support USB Video CLASS
|
||||
- Support USB Audio CLASS
|
||||
- Support Remote NDIS (RNDIS)
|
||||
- Support Vendor class
|
||||
|
||||
@@ -98,12 +99,13 @@ CherryUSB Host Stack resource usage (GCC 10.2 with -O2):
|
||||
|
||||
| file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) |
|
||||
|:-------------:|:--------------:|:-------------------------------:|:---------------------------:|:-------------------------------:|
|
||||
|usbh_core.c | 4261 | 512 | 28 | sizeof(struct usbh_urb) |
|
||||
|usbh_hub.c | 4633 | sizeof(struct usbh_hub) * (1+n) | sizeof(struct usbh_hubport) + 20 | 0 |
|
||||
|usbh_cdc_acm.c | 1004 | 7 | 4 | sizeof(struct usbh_cdc_acm) * x |
|
||||
|usbh_core.c | 4417 | 512 | 28 | sizeof(struct usbh_urb) |
|
||||
|usbh_hub.c | 4895 | 32 + 1* (1+n) | 16 + sizeof(struct usbh_hub) * (1+n) | 0 |
|
||||
|usbh_cdc_acm.c | 1064 | 7 | 4 | sizeof(struct usbh_cdc_acm) * x |
|
||||
|usbh_msc.c | 1776 | 32 | 4 | sizeof(struct usbh_msc) * x |
|
||||
|usbh_hid.c | 822 | 128 | 4 | sizeof(struct usbh_hid) * x |
|
||||
|usbh_video.c | 3587 | 128 | 4100(yuv2rgb) | sizeof(struct usbh_video) * x |
|
||||
|usbh_hid.c | 922 | 128 | 4 | sizeof(struct usbh_hid) * x |
|
||||
|usbh_video.c | 3592 | 128 | 4 | sizeof(struct usbh_video) * x |
|
||||
|usbh_audio.c | 3230 | 128 | 4 | sizeof(struct usbh_audio) * x |
|
||||
|
||||
Among them, `sizeof(struct usbh_hub)` and `sizeof(struct usbh_hubport)` are affected by the following macros:
|
||||
|
||||
@@ -133,19 +135,19 @@ Note: After version 0.4.1, the dcd drivers have been refactored and some reposit
|
||||
|
||||
| Manufacturer | CHIP or Series | USB IP| Repo Url |Corresponds to master version|
|
||||
|:--------------------:|:------------------:|:-----:|:--------:|:---------------------------:|
|
||||
|Bouffalolab | BL702 | bouffalolab|[bl_mcu_sdk](https://github.com/bouffalolab/bl_mcu_sdk/tree/master/examples/usb)| latest |
|
||||
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/es32)|latest |
|
||||
|AllwinnerTech | F1C100S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|latest |
|
||||
|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bl_mcu_sdk](https://github.com/CherryUSB/cherryusb_bouffalolab)| latest |
|
||||
|ST | STM32F103C8T6 | fsdev |[stm32f103_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/stm32/usb_device/stm32f103c8t6)|latest |
|
||||
|ST | STM32F4 | dwc2 |[stm32f429_device_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/stm32/usb_device/stm32f429igt6) [stm32f429_host_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/stm32/usb_host/stm32f429igt6)|latest |
|
||||
|ST | STM32H7 | dwc2 |[stm32h743_device_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/stm32/usb_device/stm32h743vbt6) [stm32h743_host_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/stm32/usb_host/stm32h743xih6)|latest |
|
||||
|HPMicro | HPM6750 | hpm/ehci |[hpm_repo](https://github.com/CherryUSB/cherryusb_hpmicro)|latest |
|
||||
|HPMicro | HPM6750 | hpm/ehci |[hpm_repo](https://github.com/CherryUSB/cherryusb_hpmicro)|v0.6.0 |
|
||||
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/es32)|latest |
|
||||
|AllwinnerTech | F1C100S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|latest |
|
||||
|Phytium | e2000 | xhci |[phytium _repo](https://gitee.com/phytium_embedded/phytium-standalone-sdk)|latest |
|
||||
|WCH | CH32V307 | ch32_usbfs/ch32_usbhs|[ch32v307_repo](https://github.com/CherryUSB/cherryusb_ch32v307)|latest |
|
||||
|WCH | CH57x | ch58x |[ch57x_repo](https://github.com/CherryUSB/cherryusb_ch57x)|v0.4.1 |
|
||||
|Raspberry pi | rp2040 | rp2040 |[rp2040_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/rp2040)|latest |
|
||||
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|latest |
|
||||
|Nordicsemi | Nrf52840 | nrf5x |[nrf5x_repo](https://github.com/CherryUSB/cherryusb_nrf5x)|latest |
|
||||
|Nuvoton | Nuc442 | nuvoton |[nuc442_repo](https://github.com/CherryUSB/cherryusb_nuc442)|v0.4.1 |
|
||||
|Geehy | APM32E10x APM32F0xx| fsdev |[apm32_repo](https://github.com/CherryUSB/cherryusb_apm32)|v0.4.1 |
|
||||
|Nordicsemi | Nrf52840 | nrf5x |[nrf5x_repo](https://github.com/CherryUSB/cherryusb_nrf5x)|latest |
|
||||
|Espressif | esp32 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|v0.4.1 |
|
||||
|Mindmotion | MM32L3xx | mm32 |[mm32_repo](https://github.com/CherryUSB/cherryusb_mm32)|v0.4.1 |
|
||||
|
||||
|
||||
28
README_zh.md
28
README_zh.md
@@ -87,7 +87,8 @@ CherryUSB Host 协议栈当前实现以下功能:
|
||||
- 支持 Communication Device Class (CDC)
|
||||
- 支持 Human Interface Device (HID)
|
||||
- 支持 Mass Storage Class (MSC)
|
||||
- 支持 USB VIDEO CLASS
|
||||
- Support USB Video CLASS
|
||||
- Support USB Audio CLASS
|
||||
- 支持 Remote NDIS (RNDIS)
|
||||
- 支持 Vendor 类 class
|
||||
|
||||
@@ -97,12 +98,13 @@ CherryUSB Host 协议栈资源占用说明(GCC 10.2 with -O2):
|
||||
|
||||
| file | FLASH (Byte) | No Cache RAM (Byte) | RAM (Byte) | Heap (Byte) |
|
||||
|:-------------:|:--------------:|:-------------------------------:|:---------------------------:|:-------------------------------:|
|
||||
|usbh_core.c | 4261 | 512 | 28 | sizeof(struct usbh_urb) |
|
||||
|usbh_hub.c | 4633 | sizeof(struct usbh_hub) * (1+n) | sizeof(struct usbh_hubport) + 20 | 0 |
|
||||
|usbh_cdc_acm.c | 1004 | 7 | 4 | sizeof(struct usbh_cdc_acm) * x |
|
||||
|usbh_core.c | 4417 | 512 | 28 | sizeof(struct usbh_urb) |
|
||||
|usbh_hub.c | 4895 | 32 + 1* (1+n) | 16 + sizeof(struct usbh_hub) * (1+n) | 0 |
|
||||
|usbh_cdc_acm.c | 1064 | 7 | 4 | sizeof(struct usbh_cdc_acm) * x |
|
||||
|usbh_msc.c | 1776 | 32 | 4 | sizeof(struct usbh_msc) * x |
|
||||
|usbh_hid.c | 822 | 128 | 4 | sizeof(struct usbh_hid) * x |
|
||||
|usbh_video.c | 3587 | 128 | 4100(yuv2rgb) | sizeof(struct usbh_video) * x |
|
||||
|usbh_hid.c | 922 | 128 | 4 | sizeof(struct usbh_hid) * x |
|
||||
|usbh_video.c | 3592 | 128 | 4 | sizeof(struct usbh_video) * x |
|
||||
|usbh_audio.c | 3230 | 128 | 4 | sizeof(struct usbh_audio) * x |
|
||||
|
||||
其中,`sizeof(struct usbh_hub)` 和 `sizeof(struct usbh_hubport)` 受以下宏影响:
|
||||
|
||||
@@ -132,19 +134,19 @@ USB 基本知识点与 CherryUSB Device 协议栈是如何编写的,参考 [Ch
|
||||
|
||||
| 厂商 | 芯片或者系列 | USB IP| 仓库链接 | 对应 master 版本 |
|
||||
|:--------------------:|:------------------:|:-----:|:--------:|:---------------------------:|
|
||||
|Bouffalolab | BL702 | bouffalolab|[bl_mcu_sdk](https://github.com/bouffalolab/bl_mcu_sdk/tree/master/examples/usb)| latest |
|
||||
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/es32)|latest |
|
||||
|AllwinnerTech | F1C100S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|latest |
|
||||
|Bouffalolab | BL702/BL616/BL808 | bouffalolab/ehci|[bl_mcu_sdk](https://github.com/CherryUSB/cherryusb_bouffalolab)| latest |
|
||||
|ST | STM32F103C8T6 | fsdev |[stm32f103_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/stm32/usb_device/stm32f103c8t6)|latest |
|
||||
|ST | STM32F4 | dwc2 |[stm32f429_device_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/stm32/usb_device/stm32f429igt6) [stm32f429_host_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/stm32/usb_host/stm32f429igt6)|latest |
|
||||
|ST | STM32H7 | dwc2 |[stm32h743_device_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/stm32/usb_device/stm32h743vbt6) [stm32h743_host_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/stm32/usb_host/stm32h743xih6)|latest |
|
||||
|HPMicro | HPM6750 | hpm/ehci |[hpm_repo](https://github.com/CherryUSB/cherryusb_hpmicro)|latest |
|
||||
|HPMicro | HPM6750 | hpm/ehci |[hpm_repo](https://github.com/CherryUSB/cherryusb_hpmicro)|v0.6.0 |
|
||||
|Essemi | ES32F36xx | musb |[es32f369_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/es32)|latest |
|
||||
|AllwinnerTech | F1C100S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|latest |
|
||||
|Phytium | e2000 | xhci |[phytium _repo](https://gitee.com/phytium_embedded/phytium-standalone-sdk)|latest |
|
||||
|WCH | CH32V307 | ch32_usbfs/ch32_usbhs|[ch32v307_repo](https://github.com/CherryUSB/cherryusb_ch32v307)|latest |
|
||||
|WCH | CH57x | ch58x |[ch57x_repo](https://github.com/CherryUSB/cherryusb_ch57x)|v0.4.1 |
|
||||
|Raspberry pi | rp2040 | rp2040 |[rp2040_repo](https://github.com/sakumisu/CherryUSB/tree/master/demo/rp2040)|latest |
|
||||
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|latest |
|
||||
|Nordicsemi | Nrf52840 | nrf5x |[nrf5x_repo](https://github.com/CherryUSB/cherryusb_nrf5x)|latest |
|
||||
|Nuvoton | Nuc442 | nuvoton |[nuc442_repo](https://github.com/CherryUSB/cherryusb_nuc442)|v0.4.1 |
|
||||
|Geehy | APM32E10x APM32F0xx| fsdev |[apm32_repo](https://github.com/CherryUSB/cherryusb_apm32)|v0.4.1 |
|
||||
|Nordicsemi | Nrf52840 | nrf5x |[nrf5x_repo](https://github.com/CherryUSB/cherryusb_nrf5x)|latest |
|
||||
|Espressif | esp32 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|v0.4.1 |
|
||||
|Mindmotion | MM32L3xx | mm32 |[mm32_repo](https://github.com/CherryUSB/cherryusb_mm32)|v0.4.1 |
|
||||
|
||||
|
||||
@@ -62,6 +62,10 @@ if GetDepend(['PKG_CHERRYUSB_DEVICE']):
|
||||
CPPDEFINES += ['CONFIG_USB_DWC2_PORT=FS_PORT']
|
||||
elif GetDepend(['PKG_CHERRYUSB_DEVICE_DWC2_PORT_HS']):
|
||||
CPPDEFINES += ['CONFIG_USB_DWC2_PORT=HS_PORT']
|
||||
if GetDepend(['SOC_SERIES_STM32F7']):
|
||||
CPPDEFINES += ['STM32F7']
|
||||
elif GetDepend(['SOC_SERIES_STM32H7']):
|
||||
CPPDEFINES += ['STM32H7']
|
||||
|
||||
if GetDepend(['PKG_CHERRYUSB_DEVICE_MUSB']):
|
||||
src += Glob('port/musb/usb_dc_musb.c')
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#ifndef CHERRYUSB_CONFIG_H
|
||||
#define CHERRYUSB_CONFIG_H
|
||||
|
||||
#define CHERRYUSB_VERSION 0x000700
|
||||
#define CHERRYUSB_VERSION 0x000800
|
||||
|
||||
/* ================ USB common Configuration ================ */
|
||||
|
||||
@@ -44,6 +44,27 @@
|
||||
/* Enable test mode */
|
||||
// #define CONFIG_USBDEV_TEST_MODE
|
||||
|
||||
//#define CONFIG_USBDEV_TX_THREAD
|
||||
//#define CONFIG_USBDEV_RX_THREAD
|
||||
|
||||
#ifdef CONFIG_USBDEV_TX_THREAD
|
||||
#ifndef CONFIG_USBDEV_TX_PRIO
|
||||
#define CONFIG_USBDEV_TX_PRIO 4
|
||||
#endif
|
||||
#ifndef CONFIG_USBDEV_TX_STACKSIZE
|
||||
#define CONFIG_USBDEV_TX_STACKSIZE 2048
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_RX_THREAD
|
||||
#ifndef CONFIG_USBDEV_RX_PRIO
|
||||
#define CONFIG_USBDEV_RX_PRIO 4
|
||||
#endif
|
||||
#ifndef CONFIG_USBDEV_RX_STACKSIZE
|
||||
#define CONFIG_USBDEV_RX_STACKSIZE 2048
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_BLOCK_SIZE
|
||||
#define CONFIG_USBDEV_MSC_BLOCK_SIZE 512
|
||||
#endif
|
||||
@@ -60,18 +81,6 @@
|
||||
#define CONFIG_USBDEV_MSC_VERSION_STRING "0.01"
|
||||
#endif
|
||||
|
||||
// #define CONFIG_USBDEV_MSC_THREAD
|
||||
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
#ifndef CONFIG_USBDEV_MSC_STACKSIZE
|
||||
#define CONFIG_USBDEV_MSC_STACKSIZE 2048
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_PRIO
|
||||
#define CONFIG_USBDEV_MSC_PRIO 4
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_AUDIO_VERSION
|
||||
#define CONFIG_USBDEV_AUDIO_VERSION 0x0100
|
||||
#endif
|
||||
|
||||
@@ -132,6 +132,12 @@
|
||||
#define AUDIO_FORMAT_ALAW 0x0004
|
||||
#define AUDIO_FORMAT_MULAW 0x0005
|
||||
|
||||
#define AUDIO_V2_FORMAT_PCM 0x00000001
|
||||
#define AUDIO_V2_FORMAT_PCM8 0x00000002
|
||||
#define AUDIO_V2_FORMAT_IEEE_FLOAT 0x00000004
|
||||
#define AUDIO_V2_FORMAT_ALAW 0x00000008
|
||||
#define AUDIO_V2_FORMAT_MULAW 0x00000010
|
||||
|
||||
/* bmChannelConfig: a bitmap field that indicates which spatial locations
|
||||
* are occupied by the channels present in the cluster. The bit allocations
|
||||
* are as follows:
|
||||
@@ -640,7 +646,7 @@ struct audio_cs_if_ac_feature_unit_descriptor {
|
||||
uint8_t iFeature;
|
||||
} __PACKED;
|
||||
|
||||
#define AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(ch, n) (7 + ch * n)
|
||||
#define AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(ch, n) (7 + (ch + 1) * n)
|
||||
|
||||
struct audio_cs_if_as_general_descriptor {
|
||||
uint8_t bLength;
|
||||
@@ -754,7 +760,7 @@ struct audio_cs_ep_ep_general_descriptor {
|
||||
__VA_ARGS__, /* bmaControls(0) Mute */ \
|
||||
0x00 /* iTerminal */
|
||||
|
||||
#define AUDIO_AS_DESCRIPTOR_INIT(bInterfaceNumber, bTerminalLink, bNrChannels, bEndpointAddress, wMaxPacketSize, bInterval, ...) \
|
||||
#define AUDIO_AS_DESCRIPTOR_INIT(bInterfaceNumber, bTerminalLink, bNrChannels, bSubFrameSize, bBitResolution, bEndpointAddress, wMaxPacketSize, bInterval, ...) \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
bInterfaceNumber, /* bInterfaceNumber */ \
|
||||
@@ -784,8 +790,8 @@ struct audio_cs_ep_ep_general_descriptor {
|
||||
AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ \
|
||||
AUDIO_FORMAT_TYPE_I, /* bFormatType */ \
|
||||
bNrChannels, /* bNrChannels */ \
|
||||
0x02, /* bSubFrameSize : 2 Bytes per audio subframe */ \
|
||||
0x10, /* bBitResolution : 16 bits per sample */ \
|
||||
bSubFrameSize, /* bSubFrameSize : Bytes per audio subframe */ \
|
||||
bBitResolution, /* bBitResolution : bits per sample */ \
|
||||
(PP_NARG(__VA_ARGS__)/3), /* bSamFreqType : only one frequency supported */ \
|
||||
__VA_ARGS__, /* tSamFreq : Audio sampling frequency coded on 3 bytes */ \
|
||||
0x09, /* bLength */ \
|
||||
@@ -905,7 +911,7 @@ struct audio_v2_cs_if_ac_feature_unit_descriptor {
|
||||
uint8_t iFeature;
|
||||
} __PACKED;
|
||||
|
||||
#define AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(ch) (6 + ch * 4)
|
||||
#define AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(ch) (6 + (ch + 1) * 4)
|
||||
|
||||
struct audio_v2_cs_if_as_general_descriptor {
|
||||
uint8_t bLength;
|
||||
@@ -959,7 +965,7 @@ struct audio_v2_control_range3_param_block {
|
||||
bFirstInterface, \
|
||||
bInterfaceCount, \
|
||||
USB_DEVICE_CLASS_AUDIO, \
|
||||
AUDIO_SUBCLASS_AUDIOCONTROL, \
|
||||
AUDIO_SUBCLASS_UNDEFINED, \
|
||||
AUDIO_PROTOCOLv20, \
|
||||
0x00, \
|
||||
/* ------------------ AudioControl Interface ------------------ */\
|
||||
@@ -1049,10 +1055,10 @@ struct audio_v2_control_range3_param_block {
|
||||
0x10, /* bLength */ \
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \
|
||||
AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */ \
|
||||
bTerminalLink, /* bTerminalLink : Unit ID of the Output Terminal*/ \
|
||||
bTerminalLink, /* bTerminalLink : Unit ID of the Output or Input Terminal*/ \
|
||||
0x00, /* bmControls */ \
|
||||
AUDIO_FORMAT_TYPE_I, /* bFormatType : AUDIO_FORMAT_TYPE_I */ \
|
||||
DBVAL(AUDIO_FORMAT_PCM), /* bmFormats PCM */ \
|
||||
DBVAL(AUDIO_V2_FORMAT_PCM), /* bmFormats PCM */ \
|
||||
bNrChannels, /* bNrChannels */ \
|
||||
DBVAL(bmChannelConfig), /* bmChannelConfig */ \
|
||||
0x00, /* iChannelNames */ \
|
||||
@@ -1063,10 +1069,10 @@ struct audio_v2_control_range3_param_block {
|
||||
bSubslotSize, /* bSubslotSize */ \
|
||||
bBitResolution, /* bBitResolution */ \
|
||||
0x07, /* bLength */ \
|
||||
0x05, /* bDescriptorType */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
bEndpointAddress, /* bEndpointAddress 3 out endpoint for Audio */ \
|
||||
0x01, /* bmAttributes */ \
|
||||
WBVAL(wMaxPacketSize), /* XXXX wMaxPacketSize in Bytes (Freq(Samples)*2(Stereo)*2(HalfWord)) */ \
|
||||
WBVAL(wMaxPacketSize), /* XXXX wMaxPacketSize in Bytes (SampleRate * SlotByteSize * NumChannels) */ \
|
||||
bInterval, /* bInterval */ \
|
||||
0x08, /* bLength */ \
|
||||
AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ \
|
||||
|
||||
@@ -46,36 +46,6 @@ struct audio_entity_info {
|
||||
|
||||
static usb_slist_t usbd_audio_entity_info_head = USB_SLIST_OBJECT_INIT(usbd_audio_entity_info_head);
|
||||
|
||||
#if CONFIG_USBDEV_AUDIO_VERSION >= 0x0200
|
||||
const uint8_t default_sampling_freq_table[] = {
|
||||
AUDIO_SAMPLE_FREQ_NUM(1),
|
||||
// AUDIO_SAMPLE_FREQ_4B(8000),
|
||||
// AUDIO_SAMPLE_FREQ_4B(8000),
|
||||
// AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||
AUDIO_SAMPLE_FREQ_4B(16000),
|
||||
AUDIO_SAMPLE_FREQ_4B(16000),
|
||||
AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||
AUDIO_SAMPLE_FREQ_4B(32000),
|
||||
AUDIO_SAMPLE_FREQ_4B(32000),
|
||||
AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||
AUDIO_SAMPLE_FREQ_4B(44100),
|
||||
AUDIO_SAMPLE_FREQ_4B(44100),
|
||||
AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||
AUDIO_SAMPLE_FREQ_4B(48000),
|
||||
AUDIO_SAMPLE_FREQ_4B(48000),
|
||||
AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||
AUDIO_SAMPLE_FREQ_4B(88200),
|
||||
AUDIO_SAMPLE_FREQ_4B(88200),
|
||||
AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||
AUDIO_SAMPLE_FREQ_4B(96000),
|
||||
AUDIO_SAMPLE_FREQ_4B(96000),
|
||||
AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||
AUDIO_SAMPLE_FREQ_4B(192000),
|
||||
AUDIO_SAMPLE_FREQ_4B(192000),
|
||||
AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||
};
|
||||
#endif
|
||||
|
||||
#if CONFIG_USBDEV_AUDIO_VERSION < 0x0200
|
||||
static int audio_class_endpoint_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
@@ -109,6 +79,7 @@ static int audio_class_endpoint_request_handler(struct usb_setup_packet *setup,
|
||||
sampling_freq = 16000;
|
||||
memcpy(*data, &sampling_freq, 4);
|
||||
*len = 4;
|
||||
USB_LOG_DBG("Get ep:%02x %d Hz\r\n", ep, (int)sampling_freq);
|
||||
break;
|
||||
default:
|
||||
USB_LOG_WRN("Unhandled Audio Class bRequest 0x%02x\r\n", setup->bRequest);
|
||||
@@ -246,6 +217,7 @@ static int audio_class_interface_request_handler(struct usb_setup_packet *setup,
|
||||
*len = 1;
|
||||
} else {
|
||||
mute = (*data)[0];
|
||||
current_feature_control->mute_bCUR = mute;
|
||||
USB_LOG_DBG("Set UnitId:%d ch[%d] mute %s\r\n", entity_id, ch, mute_string[mute]);
|
||||
usbd_audio_set_mute(entity_id, ch, mute);
|
||||
}
|
||||
@@ -299,6 +271,7 @@ static int audio_class_interface_request_handler(struct usb_setup_packet *setup,
|
||||
case AUDIO_CS_CONTROL_SAM_FREQ:
|
||||
if (setup->bmRequestType & USB_REQUEST_DIR_MASK) {
|
||||
memcpy(*data, &sampling_freq[ch], sizeof(uint32_t));
|
||||
USB_LOG_DBG("Get ClockId:%d ch[%d] %d Hz\r\n", entity_id, ch, (int)sampling_freq[ch]);
|
||||
*len = 4;
|
||||
} else {
|
||||
memcpy(&sampling_freq[ch], *data, setup->wLength);
|
||||
@@ -327,8 +300,9 @@ static int audio_class_interface_request_handler(struct usb_setup_packet *setup,
|
||||
|
||||
usbd_audio_get_sampling_freq_table(entity_id, &sampling_freq_table);
|
||||
num = (uint16_t)((uint16_t)(sampling_freq_table[1] << 8) | ((uint16_t)sampling_freq_table[0]));
|
||||
*data = sampling_freq_table;
|
||||
memcpy(*data, sampling_freq_table, (12 * num + 2));
|
||||
*len = (12 * num + 2);
|
||||
USB_LOG_DBG("Get sampling_freq_table entity_id:%d ch[%d] addr:%x\r\n", entity_id, ch, (uint32_t)sampling_freq_table);
|
||||
} else {
|
||||
}
|
||||
break;
|
||||
@@ -415,7 +389,7 @@ void usbd_audio_add_entity(uint8_t entity_id, uint16_t bDescriptorSubtype)
|
||||
control->volume.subrange[ch].wMax = 100;
|
||||
control->volume.subrange[ch].wRes = 1;
|
||||
control->mute[ch] = 0;
|
||||
control->volume_bCUR = 50;
|
||||
control->volume_bCUR = 0;
|
||||
control->mute_bCUR = 0;
|
||||
}
|
||||
#endif
|
||||
@@ -446,12 +420,13 @@ __WEAK void usbd_audio_set_mute(uint8_t entity_id, uint8_t ch, uint8_t enable)
|
||||
__WEAK void usbd_audio_set_sampling_freq(uint8_t entity_id, uint8_t ep_ch, uint32_t sampling_freq)
|
||||
{
|
||||
}
|
||||
|
||||
#if CONFIG_USBDEV_AUDIO_VERSION >= 0x0200
|
||||
__WEAK void usbd_audio_get_sampling_freq_table(uint8_t entity_id, uint8_t **sampling_freq_table)
|
||||
{
|
||||
*sampling_freq_table = (uint8_t *)default_sampling_freq_table;
|
||||
}
|
||||
#endif
|
||||
|
||||
__WEAK void usbd_audio_set_pitch(uint8_t ep, bool enable)
|
||||
{
|
||||
}
|
||||
424
class/audio/usbh_audio.c
Normal file
424
class/audio/usbh_audio.c
Normal file
@@ -0,0 +1,424 @@
|
||||
/*
|
||||
* Copyright (c) 2022, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbh_core.h"
|
||||
#include "usbh_audio.h"
|
||||
|
||||
#define DEV_FORMAT "/dev/audio%d"
|
||||
|
||||
/* general descriptor field offsets */
|
||||
#define DESC_bLength 0 /** Length offset */
|
||||
#define DESC_bDescriptorType 1 /** Descriptor type offset */
|
||||
#define DESC_bDescriptorSubType 2 /** Descriptor subtype offset */
|
||||
|
||||
/* interface descriptor field offsets */
|
||||
#define INTF_DESC_bInterfaceNumber 2 /** Interface number offset */
|
||||
#define INTF_DESC_bAlternateSetting 3 /** Alternate setting offset */
|
||||
|
||||
static uint32_t g_devinuse = 0;
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_audio_buf[128];
|
||||
|
||||
static int usbh_audio_devno_alloc(struct usbh_audio *audio_class)
|
||||
{
|
||||
int devno;
|
||||
|
||||
for (devno = 0; devno < 32; devno++) {
|
||||
uint32_t bitno = 1 << devno;
|
||||
if ((g_devinuse & bitno) == 0) {
|
||||
g_devinuse |= bitno;
|
||||
audio_class->minor = devno;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -EMFILE;
|
||||
}
|
||||
|
||||
static void usbh_audio_devno_free(struct usbh_audio *audio_class)
|
||||
{
|
||||
int devno = audio_class->minor;
|
||||
|
||||
if (devno >= 0 && devno < 32) {
|
||||
g_devinuse &= ~(1 << devno);
|
||||
}
|
||||
}
|
||||
|
||||
int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t samp_freq)
|
||||
{
|
||||
struct usb_setup_packet *setup = audio_class->hport->setup;
|
||||
struct usb_endpoint_descriptor *ep_desc;
|
||||
uint8_t mult;
|
||||
uint16_t mps;
|
||||
int ret;
|
||||
uint8_t intf = 0xff;
|
||||
uint8_t altsetting = 1;
|
||||
|
||||
if (audio_class->is_opened) {
|
||||
return -EMFILE;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < audio_class->module_num; i++) {
|
||||
if (strcmp(name, audio_class->module[i].name) == 0) {
|
||||
for (uint8_t j = 0; j < audio_class->num_of_intf_altsettings; j++) {
|
||||
for (uint8_t k = 0; k < audio_class->module[i].altsetting[j].sampfreq_num; k++) {
|
||||
if (audio_class->module[i].altsetting[j].sampfreq[k] == samp_freq) {
|
||||
intf = audio_class->module[i].data_intf;
|
||||
altsetting = j;
|
||||
goto freq_found;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
|
||||
freq_found:
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
|
||||
setup->bRequest = USB_REQUEST_SET_INTERFACE;
|
||||
setup->wValue = altsetting;
|
||||
setup->wIndex = intf;
|
||||
setup->wLength = 0;
|
||||
|
||||
ret = usbh_control_transfer(audio_class->hport->ep0, setup, NULL);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ep_desc = &audio_class->hport->config.intf[intf].altsetting[altsetting].ep[0].ep_desc;
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_ENDPOINT;
|
||||
setup->bRequest = AUDIO_REQUEST_SET_CUR;
|
||||
setup->wValue = (AUDIO_EP_CONTROL_SAMPLING_FEQ << 8) | 0x00;
|
||||
setup->wIndex = ep_desc->bEndpointAddress;
|
||||
setup->wLength = 3;
|
||||
|
||||
memcpy(g_audio_buf, &samp_freq, 3);
|
||||
ret = usbh_control_transfer(audio_class->hport->ep0, setup, g_audio_buf);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
mult = (ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK) >> USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT;
|
||||
mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
|
||||
if (ep_desc->bEndpointAddress & 0x80) {
|
||||
audio_class->isoin_mps = mps * (mult + 1);
|
||||
usbh_hport_activate_epx(&audio_class->isoin, audio_class->hport, ep_desc);
|
||||
} else {
|
||||
audio_class->isoout_mps = mps * (mult + 1);
|
||||
usbh_hport_activate_epx(&audio_class->isoout, audio_class->hport, ep_desc);
|
||||
}
|
||||
|
||||
USB_LOG_INFO("Open audio module :%s, altsetting: %u\r\n", name, altsetting);
|
||||
audio_class->is_opened = true;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usbh_audio_close(struct usbh_audio *audio_class, const char *name)
|
||||
{
|
||||
struct usb_setup_packet *setup = audio_class->hport->setup;
|
||||
struct usb_endpoint_descriptor *ep_desc;
|
||||
int ret;
|
||||
uint8_t intf = 0xff;
|
||||
uint8_t altsetting = 1;
|
||||
|
||||
for (size_t i = 0; i < audio_class->module_num; i++) {
|
||||
if (strcmp(name, audio_class->module[i].name) == 0) {
|
||||
intf = audio_class->module[i].data_intf;
|
||||
}
|
||||
}
|
||||
|
||||
if (intf == 0xff) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
USB_LOG_INFO("Close audio module :%s\r\n", name);
|
||||
audio_class->is_opened = false;
|
||||
|
||||
ep_desc = &audio_class->hport->config.intf[intf].altsetting[altsetting].ep[0].ep_desc;
|
||||
if (ep_desc->bEndpointAddress & 0x80) {
|
||||
if (audio_class->isoin) {
|
||||
usbh_pipe_free(audio_class->isoin);
|
||||
audio_class->isoin = NULL;
|
||||
}
|
||||
} else {
|
||||
if (audio_class->isoout) {
|
||||
usbh_pipe_free(audio_class->isoout);
|
||||
audio_class->isoout = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
|
||||
setup->bRequest = USB_REQUEST_SET_INTERFACE;
|
||||
setup->wValue = 0;
|
||||
setup->wIndex = intf;
|
||||
setup->wLength = 0;
|
||||
|
||||
ret = usbh_control_transfer(audio_class->hport->ep0, setup, NULL);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void usbh_audio_list_module(struct usbh_audio *audio_class)
|
||||
{
|
||||
USB_LOG_INFO("============= Audio module information ===================\r\n");
|
||||
USB_LOG_INFO("bcdADC :%04x\r\n", audio_class->bcdADC);
|
||||
USB_LOG_INFO("Num of modules :%u\r\n", audio_class->module_num);
|
||||
USB_LOG_INFO("Num of altsettings:%u\r\n", audio_class->num_of_intf_altsettings);
|
||||
|
||||
for (uint8_t i = 0; i < audio_class->module_num; i++) {
|
||||
USB_LOG_INFO(" module name :%s\r\n", audio_class->module[i].name);
|
||||
USB_LOG_INFO(" module feature unit id :%d\r\n", audio_class->module[i].feature_unit_id);
|
||||
|
||||
for (uint8_t j = 0; j < audio_class->num_of_intf_altsettings; j++) {
|
||||
if (j == 0) {
|
||||
USB_LOG_INFO(" Ingore altsetting 0\r\n");
|
||||
continue;
|
||||
}
|
||||
USB_LOG_INFO(" Altsetting %u\r\n", j);
|
||||
USB_LOG_INFO(" module channels :%u\r\n", audio_class->module[i].altsetting[j].channels);
|
||||
//USB_LOG_INFO(" module format_type :%u\r\n",audio_class->module[i].altsetting[j].format_type);
|
||||
USB_LOG_INFO(" module bitresolution :%u\r\n", audio_class->module[i].altsetting[j].bitresolution);
|
||||
USB_LOG_INFO(" module sampfreq num :%u\r\n", audio_class->module[i].altsetting[j].sampfreq_num);
|
||||
|
||||
for (uint8_t k = 0; k < audio_class->module[i].altsetting[j].sampfreq_num; k++) {
|
||||
USB_LOG_INFO(" module sampfreq :%d hz\r\n", audio_class->module[i].altsetting[j].sampfreq[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
USB_LOG_INFO("============= Audio module information ===================\r\n");
|
||||
}
|
||||
|
||||
static int usbh_audio_ctrl_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
int ret;
|
||||
uint8_t cur_iface = 0xff;
|
||||
uint8_t cur_iface_count = 0xff;
|
||||
uint8_t cur_alt_setting = 0xff;
|
||||
uint8_t input_offset = 0;
|
||||
uint8_t output_offset = 0;
|
||||
uint8_t feature_unit_offset = 0;
|
||||
uint8_t format_offset = 0;
|
||||
uint8_t *p;
|
||||
|
||||
struct usbh_audio *audio_class = usb_malloc(sizeof(struct usbh_audio));
|
||||
if (audio_class == NULL) {
|
||||
USB_LOG_ERR("Fail to alloc audio_class\r\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(audio_class, 0, sizeof(struct usbh_audio));
|
||||
usbh_audio_devno_alloc(audio_class);
|
||||
audio_class->hport = hport;
|
||||
audio_class->ctrl_intf = intf;
|
||||
audio_class->num_of_intf_altsettings = hport->config.intf[intf + 1].altsetting_num;
|
||||
|
||||
hport->config.intf[intf].priv = audio_class;
|
||||
|
||||
p = hport->raw_config_desc;
|
||||
while (p[DESC_bLength]) {
|
||||
switch (p[DESC_bDescriptorType]) {
|
||||
case USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION:
|
||||
cur_iface_count = p[3];
|
||||
break;
|
||||
case USB_DESCRIPTOR_TYPE_INTERFACE:
|
||||
cur_iface = p[INTF_DESC_bInterfaceNumber];
|
||||
cur_alt_setting = p[INTF_DESC_bAlternateSetting];
|
||||
break;
|
||||
case USB_DESCRIPTOR_TYPE_ENDPOINT:
|
||||
break;
|
||||
case AUDIO_INTERFACE_DESCRIPTOR_TYPE:
|
||||
if (cur_iface == audio_class->ctrl_intf) {
|
||||
switch (p[DESC_bDescriptorSubType]) {
|
||||
case AUDIO_CONTROL_HEADER: {
|
||||
struct audio_cs_if_ac_header_descriptor *desc = (struct audio_cs_if_ac_header_descriptor *)p;
|
||||
audio_class->bcdADC = desc->bcdADC;
|
||||
audio_class->bInCollection = desc->bInCollection;
|
||||
} break;
|
||||
case AUDIO_CONTROL_INPUT_TERMINAL: {
|
||||
struct audio_cs_if_ac_input_terminal_descriptor *desc = (struct audio_cs_if_ac_input_terminal_descriptor *)p;
|
||||
|
||||
audio_class->module[input_offset].input_terminal_id = desc->bTerminalID;
|
||||
audio_class->module[input_offset].input_terminal_type = desc->wTerminalType;
|
||||
audio_class->module[input_offset].input_channel_config = desc->wChannelConfig;
|
||||
|
||||
if (desc->wTerminalType == AUDIO_TERMINAL_STREAMING) {
|
||||
audio_class->module[input_offset].terminal_link_id = desc->bTerminalID;
|
||||
}
|
||||
if (desc->wTerminalType == AUDIO_INTERM_MIC) {
|
||||
audio_class->module[input_offset].name = "mic";
|
||||
}
|
||||
input_offset++;
|
||||
} break;
|
||||
break;
|
||||
case AUDIO_CONTROL_OUTPUT_TERMINAL: {
|
||||
struct audio_cs_if_ac_output_terminal_descriptor *desc = (struct audio_cs_if_ac_output_terminal_descriptor *)p;
|
||||
audio_class->module[output_offset].output_terminal_id = desc->bTerminalID;
|
||||
audio_class->module[output_offset].output_terminal_type = desc->wTerminalType;
|
||||
if (desc->wTerminalType == AUDIO_TERMINAL_STREAMING) {
|
||||
audio_class->module[output_offset].terminal_link_id = desc->bTerminalID;
|
||||
}
|
||||
if (desc->wTerminalType == AUDIO_OUTTERM_SPEAKER) {
|
||||
audio_class->module[output_offset].name = "speaker";
|
||||
}
|
||||
output_offset++;
|
||||
} break;
|
||||
case AUDIO_CONTROL_FEATURE_UNIT: {
|
||||
struct audio_cs_if_ac_feature_unit_descriptor *desc = (struct audio_cs_if_ac_feature_unit_descriptor *)p;
|
||||
audio_class->module[feature_unit_offset].feature_unit_id = desc->bUnitID;
|
||||
audio_class->module[feature_unit_offset].feature_unit_controlsize = desc->bControlSize;
|
||||
|
||||
for (uint8_t j = 0; j < desc->bControlSize; j++) {
|
||||
audio_class->module[feature_unit_offset].feature_unit_controls[j] = p[6 + j];
|
||||
}
|
||||
feature_unit_offset++;
|
||||
} break;
|
||||
case AUDIO_CONTROL_PROCESSING_UNIT:
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if ((cur_iface < (audio_class->ctrl_intf + cur_iface_count)) && (cur_iface > audio_class->ctrl_intf)) {
|
||||
switch (p[DESC_bDescriptorSubType]) {
|
||||
case AUDIO_STREAMING_GENERAL:
|
||||
|
||||
break;
|
||||
case AUDIO_STREAMING_FORMAT_TYPE: {
|
||||
struct audio_cs_if_as_format_type_descriptor *desc = (struct audio_cs_if_as_format_type_descriptor *)p;
|
||||
|
||||
audio_class->module[format_offset].data_intf = cur_iface;
|
||||
audio_class->module[format_offset].altsetting[cur_alt_setting].channels = desc->bNrChannels;
|
||||
audio_class->module[format_offset].altsetting[cur_alt_setting].format_type = desc->bFormatType;
|
||||
audio_class->module[format_offset].altsetting[cur_alt_setting].bitresolution = desc->bBitResolution;
|
||||
audio_class->module[format_offset].altsetting[cur_alt_setting].sampfreq_num = desc->bSamFreqType;
|
||||
|
||||
for (uint8_t j = 0; j < desc->bSamFreqType; j++) {
|
||||
audio_class->module[format_offset].altsetting[cur_alt_setting].sampfreq[j] = (uint32_t)(p[10 + j] << 16) |
|
||||
(uint32_t)(p[9 + j] << 8) |
|
||||
(uint32_t)(p[8 + j] << 0);
|
||||
}
|
||||
if (cur_alt_setting == (hport->config.intf[intf + 1].altsetting_num - 1)) {
|
||||
format_offset++;
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
/* skip to next descriptor */
|
||||
p += p[DESC_bLength];
|
||||
}
|
||||
|
||||
if ((input_offset != output_offset) && (input_offset != feature_unit_offset) && (input_offset != format_offset)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
audio_class->module_num = input_offset;
|
||||
|
||||
for (size_t i = 0; i < audio_class->module_num; i++) {
|
||||
ret = usbh_audio_close(audio_class, audio_class->module[i].name);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Fail to close audio module :%s\r\n", audio_class->module[i].name);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
usbh_audio_list_module(audio_class);
|
||||
|
||||
snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, audio_class->minor);
|
||||
USB_LOG_INFO("Register Audio Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
|
||||
usbh_audio_run(audio_class);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usbh_audio_ctrl_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
struct usbh_audio *audio_class = (struct usbh_audio *)hport->config.intf[intf].priv;
|
||||
|
||||
if (audio_class) {
|
||||
usbh_audio_devno_free(audio_class);
|
||||
|
||||
if (audio_class->isoin) {
|
||||
usbh_pipe_free(audio_class->isoin);
|
||||
}
|
||||
|
||||
if (audio_class->isoout) {
|
||||
usbh_pipe_free(audio_class->isoout);
|
||||
}
|
||||
|
||||
usbh_audio_stop(audio_class);
|
||||
memset(audio_class, 0, sizeof(struct usbh_audio));
|
||||
usb_free(audio_class);
|
||||
|
||||
if (hport->config.intf[intf].devname[0] != '\0')
|
||||
USB_LOG_INFO("Unregister Audio Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int usbh_audio_data_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usbh_audio_data_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
__WEAK void usbh_audio_run(struct usbh_audio *audio_class)
|
||||
{
|
||||
}
|
||||
|
||||
__WEAK void usbh_audio_stop(struct usbh_audio *audio_class)
|
||||
{
|
||||
}
|
||||
|
||||
const struct usbh_class_driver audio_ctrl_class_driver = {
|
||||
.driver_name = "audio_ctrl",
|
||||
.connect = usbh_audio_ctrl_connect,
|
||||
.disconnect = usbh_audio_ctrl_disconnect
|
||||
};
|
||||
|
||||
const struct usbh_class_driver audio_streaming_class_driver = {
|
||||
.driver_name = "audio_streaming",
|
||||
.connect = usbh_audio_data_connect,
|
||||
.disconnect = usbh_audio_data_disconnect
|
||||
};
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info audio_ctrl_intf_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS,
|
||||
.class = USB_DEVICE_CLASS_AUDIO,
|
||||
.subclass = AUDIO_SUBCLASS_AUDIOCONTROL,
|
||||
.protocol = 0x00,
|
||||
.vid = 0x00,
|
||||
.pid = 0x00,
|
||||
.class_driver = &audio_ctrl_class_driver
|
||||
};
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info audio_streaming_intf_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS,
|
||||
.class = USB_DEVICE_CLASS_AUDIO,
|
||||
.subclass = AUDIO_SUBCLASS_AUDIOSTREAMING,
|
||||
.protocol = 0x00,
|
||||
.vid = 0x00,
|
||||
.pid = 0x00,
|
||||
.class_driver = &audio_streaming_class_driver
|
||||
};
|
||||
72
class/audio/usbh_audio.h
Normal file
72
class/audio/usbh_audio.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2022, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef USBH_AUDIO_H
|
||||
#define USBH_AUDIO_H
|
||||
|
||||
#include "usb_audio.h"
|
||||
|
||||
struct usbh_audio_format_type {
|
||||
uint8_t channels;
|
||||
uint8_t format_type;
|
||||
uint8_t bitresolution;
|
||||
uint8_t sampfreq_num;
|
||||
uint32_t sampfreq[3];
|
||||
};
|
||||
|
||||
/**
|
||||
* bSourceID in feature_unit = input_terminal_id
|
||||
* bSourceID in output_terminal = feature_unit_id
|
||||
* terminal_link_id = input_terminal_id or output_terminal_id (if input_terminal_type or output_terminal_type is 0x0101)
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct usbh_audio_module {
|
||||
const char *name;
|
||||
uint8_t data_intf;
|
||||
uint8_t input_terminal_id;
|
||||
uint16_t input_terminal_type;
|
||||
uint16_t input_channel_config;
|
||||
uint8_t output_terminal_id;
|
||||
uint16_t output_terminal_type;
|
||||
uint8_t feature_unit_id;
|
||||
uint8_t feature_unit_controlsize;
|
||||
uint8_t feature_unit_controls[8];
|
||||
uint8_t terminal_link_id;
|
||||
struct usbh_audio_format_type altsetting[CONFIG_USBHOST_MAX_INTF_ALTSETTINGS];
|
||||
};
|
||||
|
||||
struct usbh_audio {
|
||||
struct usbh_hubport *hport;
|
||||
|
||||
uint8_t ctrl_intf; /* interface number */
|
||||
uint8_t minor;
|
||||
usbh_pipe_t isoin; /* ISO IN endpoint */
|
||||
usbh_pipe_t isoout; /* ISO OUT endpoint */
|
||||
uint16_t isoin_mps;
|
||||
uint16_t isoout_mps;
|
||||
bool is_opened;
|
||||
uint16_t bcdADC;
|
||||
uint8_t bInCollection;
|
||||
uint8_t num_of_intf_altsettings;
|
||||
struct usbh_audio_module module[2];
|
||||
uint8_t module_num;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int usbh_audio_open(struct usbh_audio *audio_class, const char *name, uint32_t samp_freq);
|
||||
int usbh_audio_close(struct usbh_audio *audio_class, const char *name);
|
||||
|
||||
void usbh_audio_run(struct usbh_audio *audio_class);
|
||||
void usbh_audio_stop(struct usbh_audio *audio_class);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* USBH_AUDIO_H */
|
||||
@@ -38,7 +38,7 @@ static void usbh_cdc_acm_devno_free(struct usbh_cdc_acm *cdc_acm_class)
|
||||
|
||||
int usbh_cdc_acm_set_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_line_coding *line_coding)
|
||||
{
|
||||
struct usb_setup_packet *setup = &cdc_acm_class->hport->setup;
|
||||
struct usb_setup_packet *setup = cdc_acm_class->hport->setup;
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
|
||||
setup->bRequest = CDC_REQUEST_SET_LINE_CODING;
|
||||
@@ -53,7 +53,7 @@ int usbh_cdc_acm_set_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_
|
||||
|
||||
int usbh_cdc_acm_get_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_line_coding *line_coding)
|
||||
{
|
||||
struct usb_setup_packet *setup = &cdc_acm_class->hport->setup;
|
||||
struct usb_setup_packet *setup = cdc_acm_class->hport->setup;
|
||||
int ret;
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
|
||||
@@ -72,7 +72,7 @@ int usbh_cdc_acm_get_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_
|
||||
|
||||
int usbh_cdc_acm_set_line_state(struct usbh_cdc_acm *cdc_acm_class, bool dtr, bool rts)
|
||||
{
|
||||
struct usb_setup_packet *setup = &cdc_acm_class->hport->setup;
|
||||
struct usb_setup_packet *setup = cdc_acm_class->hport->setup;
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
|
||||
setup->bRequest = CDC_REQUEST_SET_CONTROL_LINE_STATE;
|
||||
@@ -146,6 +146,7 @@ static int usbh_cdc_acm_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
|
||||
USB_LOG_INFO("Register CDC ACM Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
|
||||
usbh_cdc_acm_run(cdc_acm_class);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -166,6 +167,7 @@ static int usbh_cdc_acm_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
usbh_pipe_free(cdc_acm_class->bulkout);
|
||||
}
|
||||
|
||||
usbh_cdc_acm_stop(cdc_acm_class);
|
||||
memset(cdc_acm_class, 0, sizeof(struct usbh_cdc_acm));
|
||||
usb_free(cdc_acm_class);
|
||||
|
||||
@@ -176,12 +178,38 @@ static int usbh_cdc_acm_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int usbh_cdc_data_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usbh_cdc_data_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
__WEAK void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
__WEAK void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const struct usbh_class_driver cdc_acm_class_driver = {
|
||||
.driver_name = "cdc_acm",
|
||||
.connect = usbh_cdc_acm_connect,
|
||||
.disconnect = usbh_cdc_acm_disconnect
|
||||
};
|
||||
|
||||
const struct usbh_class_driver cdc_data_class_driver = {
|
||||
.driver_name = "cdc_data",
|
||||
.connect = usbh_cdc_data_connect,
|
||||
.disconnect = usbh_cdc_data_disconnect
|
||||
};
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info cdc_acm_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
|
||||
.class = USB_DEVICE_CLASS_CDC,
|
||||
@@ -191,3 +219,13 @@ CLASS_INFO_DEFINE const struct usbh_class_info cdc_acm_class_info = {
|
||||
.pid = 0x00,
|
||||
.class_driver = &cdc_acm_class_driver
|
||||
};
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info cdc_data_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS,
|
||||
.class = USB_DEVICE_CLASS_CDC_DATA,
|
||||
.subclass = 0x00,
|
||||
.protocol = 0x00,
|
||||
.vid = 0x00,
|
||||
.pid = 0x00,
|
||||
.class_driver = &cdc_data_class_driver
|
||||
};
|
||||
|
||||
@@ -32,6 +32,9 @@ int usbh_cdc_acm_set_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_
|
||||
int usbh_cdc_acm_get_line_coding(struct usbh_cdc_acm *cdc_acm_class, struct cdc_line_coding *line_coding);
|
||||
int usbh_cdc_acm_set_line_state(struct usbh_cdc_acm *cdc_acm_class, bool dtr, bool rts);
|
||||
|
||||
void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class);
|
||||
void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -130,7 +130,7 @@ static void dfu_request_upload(struct usb_setup_packet *setup, uint8_t **data, u
|
||||
usbd_dfu_cfg.buffer.d8[2] = DFU_CMD_ERASE;
|
||||
|
||||
/* Send the status data over EP0 */
|
||||
*data = usbd_dfu_cfg.buffer.d8;
|
||||
memcpy(*data, usbd_dfu_cfg.buffer.d8, 3);
|
||||
*len = 3;
|
||||
} else if (usbd_dfu_cfg.wblock_num > 1U) {
|
||||
usbd_dfu_cfg.dev_state = DFU_STATE_DFU_UPLOAD_IDLE;
|
||||
@@ -146,7 +146,7 @@ static void dfu_request_upload(struct usb_setup_packet *setup, uint8_t **data, u
|
||||
phaddr = dfu_read_flash((uint8_t *)addr, usbd_dfu_cfg.buffer.d8, usbd_dfu_cfg.wlength);
|
||||
|
||||
/* Send the status data over EP0 */
|
||||
*data = usbd_dfu_cfg.buffer.d8;
|
||||
memcpy(*data, usbd_dfu_cfg.buffer.d8, usbd_dfu_cfg.wlength);
|
||||
*len = usbd_dfu_cfg.wlength;
|
||||
} else /* unsupported usbd_dfu_cfg.wblock_num */
|
||||
{
|
||||
@@ -369,9 +369,7 @@ static void dfu_request_getstatus(struct usb_setup_packet *setup, uint8_t **data
|
||||
}
|
||||
|
||||
/* Send the status data over EP0 */
|
||||
uint8_t temp_data[6];
|
||||
memcpy(temp_data, usbd_dfu_cfg.dev_status, 6);
|
||||
*data = temp_data;
|
||||
memcpy(*data, usbd_dfu_cfg.dev_status, 6);
|
||||
*len = 6;
|
||||
|
||||
if (usbd_dfu_cfg.firmwar_flag == 1) {
|
||||
@@ -407,7 +405,7 @@ static void dfu_request_clrstatus(void)
|
||||
static void dfu_request_getstate(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
/* Return the current state of the DFU interface */
|
||||
*data = &usbd_dfu_cfg.dev_state;
|
||||
(*data)[0] = usbd_dfu_cfg.dev_state;
|
||||
*len = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ static void usbh_hid_devno_free(struct usbh_hid *hid_class)
|
||||
|
||||
static int usbh_hid_get_report_descriptor(struct usbh_hid *hid_class, uint8_t *buffer)
|
||||
{
|
||||
struct usb_setup_packet *setup = &hid_class->hport->setup;
|
||||
struct usb_setup_packet *setup = hid_class->hport->setup;
|
||||
int ret;
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
|
||||
@@ -58,7 +58,7 @@ static int usbh_hid_get_report_descriptor(struct usbh_hid *hid_class, uint8_t *b
|
||||
|
||||
int usbh_hid_set_idle(struct usbh_hid *hid_class, uint8_t report_id, uint8_t duration)
|
||||
{
|
||||
struct usb_setup_packet *setup = &hid_class->hport->setup;
|
||||
struct usb_setup_packet *setup = hid_class->hport->setup;
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
|
||||
setup->bRequest = HID_REQUEST_SET_IDLE;
|
||||
@@ -71,7 +71,7 @@ int usbh_hid_set_idle(struct usbh_hid *hid_class, uint8_t report_id, uint8_t dur
|
||||
|
||||
int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer)
|
||||
{
|
||||
struct usb_setup_packet *setup = &hid_class->hport->setup;
|
||||
struct usb_setup_packet *setup = hid_class->hport->setup;
|
||||
int ret;
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
|
||||
@@ -90,7 +90,7 @@ int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer)
|
||||
|
||||
int usbh_hid_set_protocol(struct usbh_hid *hid_class, uint8_t protocol)
|
||||
{
|
||||
struct usb_setup_packet *setup = &hid_class->hport->setup;
|
||||
struct usb_setup_packet *setup = hid_class->hport->setup;
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
|
||||
setup->bRequest = HID_REQUEST_SET_PROTOCOL;
|
||||
@@ -148,7 +148,8 @@ int usbh_hid_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
|
||||
USB_LOG_INFO("Register HID Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
|
||||
return 0;
|
||||
usbh_hid_run(hid_class);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usbh_hid_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
@@ -168,6 +169,7 @@ int usbh_hid_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
usbh_pipe_free(hid_class->intout);
|
||||
}
|
||||
|
||||
usbh_hid_stop(hid_class);
|
||||
memset(hid_class, 0, sizeof(struct usbh_hid));
|
||||
usb_free(hid_class);
|
||||
|
||||
@@ -178,27 +180,27 @@ int usbh_hid_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
return ret;
|
||||
}
|
||||
|
||||
__WEAK void usbh_hid_run(struct usbh_hid *hid_class)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
__WEAK void usbh_hid_stop(struct usbh_hid *hid_class)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const struct usbh_class_driver hid_class_driver = {
|
||||
.driver_name = "hid",
|
||||
.connect = usbh_hid_connect,
|
||||
.disconnect = usbh_hid_disconnect
|
||||
};
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info hid_keyboard_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info hid_custom_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS,
|
||||
.class = USB_DEVICE_CLASS_HID,
|
||||
.subclass = HID_SUBCLASS_BOOTIF,
|
||||
.protocol = HID_PROTOCOL_KEYBOARD,
|
||||
.vid = 0x00,
|
||||
.pid = 0x00,
|
||||
.class_driver = &hid_class_driver
|
||||
};
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info hid_mouse_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
|
||||
.class = USB_DEVICE_CLASS_HID,
|
||||
.subclass = HID_SUBCLASS_BOOTIF,
|
||||
.protocol = HID_PROTOCOL_MOUSE,
|
||||
.subclass = 0x00,
|
||||
.protocol = 0x00,
|
||||
.vid = 0x00,
|
||||
.pid = 0x00,
|
||||
.class_driver = &hid_class_driver
|
||||
|
||||
@@ -25,6 +25,9 @@ extern "C" {
|
||||
int usbh_hid_set_idle(struct usbh_hid *hid_class, uint8_t report_id, uint8_t duration);
|
||||
int usbh_hid_get_idle(struct usbh_hid *hid_class, uint8_t *buffer);
|
||||
|
||||
void usbh_hid_run(struct usbh_hid *hid_class);
|
||||
void usbh_hid_stop(struct usbh_hid *hid_class);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
|
||||
#define DEV_FORMAT "/dev/hub%d"
|
||||
|
||||
#define DEBOUNCE_TIMEOUT 400
|
||||
#define DEBOUNCE_TIME_STEP 25
|
||||
#define HUB_DEBOUNCE_TIMEOUT 1500
|
||||
#define HUB_DEBOUNCE_STEP 25
|
||||
#define HUB_DEBOUNCE_STABLE 100
|
||||
#define DELAY_TIME_AFTER_RESET 200
|
||||
|
||||
#define EXTHUB_FIRST_INDEX 2
|
||||
@@ -16,24 +17,26 @@
|
||||
static uint32_t g_devinuse = 0;
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hub_buf[32];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_hub_intbuf[CONFIG_USBHOST_MAX_EXTHUBS + 1][1];
|
||||
|
||||
usb_slist_t hub_event_head = USB_SLIST_OBJECT_INIT(hub_event_head);
|
||||
usb_slist_t hub_class_head = USB_SLIST_OBJECT_INIT(hub_class_head);
|
||||
|
||||
usb_osal_sem_t hub_event_wait;
|
||||
usb_osal_thread_t hub_thread;
|
||||
usb_osal_mq_t hub_mq;
|
||||
|
||||
USB_NOCACHE_RAM_SECTION struct usbh_hub roothub;
|
||||
struct usbh_hubport roothub_parent_port;
|
||||
|
||||
USB_NOCACHE_RAM_SECTION struct usbh_hub exthub[CONFIG_USBHOST_MAX_EXTHUBS];
|
||||
struct usbh_hub roothub;
|
||||
|
||||
#if CONFIG_USBHOST_MAX_EXTHUBS > 0
|
||||
struct usbh_hub exthub[CONFIG_USBHOST_MAX_EXTHUBS];
|
||||
#endif
|
||||
extern int usbh_hport_activate_ep0(struct usbh_hubport *hport);
|
||||
extern int usbh_hport_deactivate_ep0(struct usbh_hubport *hport);
|
||||
extern int usbh_enumerate(struct usbh_hubport *hport);
|
||||
static void usbh_hub_thread_wakeup(struct usbh_hub *hub);
|
||||
|
||||
static const char *speed_table[] = { "error-speed", "low-speed", "full-speed", "high-speed", "wireless-speed", "super-speed", "superplus-speed" };
|
||||
|
||||
#if CONFIG_USBHOST_MAX_EXTHUBS > 0
|
||||
static int usbh_hub_devno_alloc(void)
|
||||
{
|
||||
int devno;
|
||||
@@ -55,13 +58,24 @@ static void usbh_hub_devno_free(uint8_t devno)
|
||||
g_devinuse &= ~(1 << devno);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void usbh_hub_register(struct usbh_hub *hub)
|
||||
{
|
||||
usb_slist_add_tail(&hub_class_head, &hub->list);
|
||||
}
|
||||
|
||||
static void usbh_hub_unregister(struct usbh_hub *hub)
|
||||
{
|
||||
usb_slist_remove(&hub_class_head, &hub->list);
|
||||
}
|
||||
|
||||
static int _usbh_hub_get_hub_descriptor(struct usbh_hub *hub, uint8_t *buffer)
|
||||
{
|
||||
struct usb_setup_packet *setup;
|
||||
int ret;
|
||||
|
||||
setup = &hub->parent->setup;
|
||||
setup = hub->parent->setup;
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE;
|
||||
setup->bRequest = USB_REQUEST_GET_DESCRIPTOR;
|
||||
@@ -82,7 +96,7 @@ static int _usbh_hub_get_status(struct usbh_hub *hub, uint8_t *buffer)
|
||||
struct usb_setup_packet *setup;
|
||||
int ret;
|
||||
|
||||
setup = &hub->parent->setup;
|
||||
setup = hub->parent->setup;
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_DEVICE;
|
||||
setup->bRequest = HUB_REQUEST_GET_STATUS;
|
||||
@@ -103,7 +117,7 @@ static int _usbh_hub_get_portstatus(struct usbh_hub *hub, uint8_t port, struct h
|
||||
struct usb_setup_packet *setup;
|
||||
int ret;
|
||||
|
||||
setup = &hub->parent->setup;
|
||||
setup = hub->parent->setup;
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_OTHER;
|
||||
setup->bRequest = HUB_REQUEST_GET_STATUS;
|
||||
@@ -123,7 +137,7 @@ static int _usbh_hub_set_feature(struct usbh_hub *hub, uint8_t port, uint8_t fea
|
||||
{
|
||||
struct usb_setup_packet *setup;
|
||||
|
||||
setup = &hub->parent->setup;
|
||||
setup = hub->parent->setup;
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_OTHER;
|
||||
setup->bRequest = HUB_REQUEST_SET_FEATURE;
|
||||
@@ -138,7 +152,7 @@ static int _usbh_hub_clear_feature(struct usbh_hub *hub, uint8_t port, uint8_t f
|
||||
{
|
||||
struct usb_setup_packet *setup;
|
||||
|
||||
setup = &hub->parent->setup;
|
||||
setup = hub->parent->setup;
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_OTHER;
|
||||
setup->bRequest = HUB_REQUEST_CLEAR_FEATURE;
|
||||
@@ -225,12 +239,7 @@ static int usbh_hub_clear_feature(struct usbh_hub *hub, uint8_t port, uint8_t fe
|
||||
}
|
||||
}
|
||||
|
||||
static void usbh_hub_thread_wakeup(struct usbh_hub *hub)
|
||||
{
|
||||
usb_slist_add_tail(&hub_event_head, &hub->hub_event_list);
|
||||
usb_osal_sem_give(hub_event_wait);
|
||||
}
|
||||
|
||||
#if CONFIG_USBHOST_MAX_EXTHUBS > 0
|
||||
static void hub_int_complete_callback(void *arg, int nbytes)
|
||||
{
|
||||
struct usbh_hub *hub = (struct usbh_hub *)arg;
|
||||
@@ -302,6 +311,7 @@ static int usbh_hub_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
usbh_hub_register(hub);
|
||||
USB_LOG_INFO("Register HUB Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
|
||||
hub->int_buffer = g_hub_intbuf[hub->index - 1];
|
||||
usbh_int_urb_fill(&hub->intin_urb, hub->intin, hub->int_buffer, 1, 0, hub_int_complete_callback, hub);
|
||||
usbh_submit_urb(&hub->intin_urb);
|
||||
return 0;
|
||||
@@ -326,7 +336,7 @@ static int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
usbh_hport_deactivate_ep0(child);
|
||||
for (uint8_t i = 0; i < child->config.config_desc.bNumInterfaces; i++) {
|
||||
if (child->config.intf[i].class_driver && child->config.intf[i].class_driver->disconnect) {
|
||||
ret = CLASS_DISCONNECT(child, i);
|
||||
CLASS_DISCONNECT(child, i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,20 +352,20 @@ static int usbh_hub_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void usbh_roothub_register(void)
|
||||
static void usbh_hubport_release(struct usbh_hubport *child)
|
||||
{
|
||||
memset(&roothub, 0, sizeof(struct usbh_hub));
|
||||
memset(&roothub_parent_port, 0, sizeof(struct usbh_hubport));
|
||||
roothub_parent_port.port = 1;
|
||||
roothub_parent_port.dev_addr = 1;
|
||||
roothub.connected = true;
|
||||
roothub.index = 1;
|
||||
roothub.is_roothub = true;
|
||||
roothub.parent = &roothub_parent_port;
|
||||
roothub.hub_addr = roothub_parent_port.dev_addr;
|
||||
roothub.hub_desc.bNbrPorts = CONFIG_USBHOST_MAX_RHPORTS;
|
||||
usbh_hub_register(&roothub);
|
||||
if (child->connected) {
|
||||
child->connected = false;
|
||||
usbh_hport_deactivate_ep0(child);
|
||||
for (uint8_t i = 0; i < child->config.config_desc.bNumInterfaces; i++) {
|
||||
if (child->config.intf[i].class_driver && child->config.intf[i].class_driver->disconnect) {
|
||||
CLASS_DISCONNECT(child, i);
|
||||
}
|
||||
}
|
||||
child->config.config_desc.bNumInterfaces = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void usbh_hub_events(struct usbh_hub *hub)
|
||||
@@ -419,8 +429,7 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
if (portchange & HUB_PORT_STATUS_C_CONNECTION) {
|
||||
uint16_t connection = 0;
|
||||
uint16_t debouncestable = 0;
|
||||
for (uint32_t debouncetime = 0; debouncetime < DEBOUNCE_TIMEOUT; debouncetime += DEBOUNCE_TIME_STEP) {
|
||||
usb_osal_msleep(DEBOUNCE_TIME_STEP);
|
||||
for (uint32_t debouncetime = 0; debouncetime < HUB_DEBOUNCE_TIMEOUT; debouncetime += HUB_DEBOUNCE_STEP) {
|
||||
/* Read hub port status */
|
||||
ret = usbh_hub_get_portstatus(hub, port + 1, &port_status);
|
||||
if (ret < 0) {
|
||||
@@ -432,21 +441,29 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
portchange = port_status.wPortChange;
|
||||
|
||||
USB_LOG_DBG("Port %u, status:0x%02x, change:0x%02x\r\n", port + 1, portstatus, portchange);
|
||||
if ((portstatus & HUB_PORT_STATUS_CONNECTION) == connection) {
|
||||
if (connection) {
|
||||
if (++debouncestable == 4) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!(portchange & HUB_PORT_STATUS_C_CONNECTION) &&
|
||||
((portstatus & HUB_PORT_STATUS_CONNECTION) == connection)) {
|
||||
debouncestable += HUB_DEBOUNCE_STEP;
|
||||
if (debouncestable >= HUB_DEBOUNCE_STABLE) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
debouncestable = 0;
|
||||
connection = portstatus & HUB_PORT_STATUS_CONNECTION;
|
||||
}
|
||||
|
||||
connection = portstatus & HUB_PORT_STATUS_CONNECTION;
|
||||
|
||||
if (portchange & HUB_PORT_STATUS_C_CONNECTION) {
|
||||
usbh_hub_clear_feature(hub, port + 1, HUB_PORT_FEATURE_C_CONNECTION);
|
||||
}
|
||||
|
||||
usb_osal_msleep(HUB_DEBOUNCE_STEP);
|
||||
}
|
||||
|
||||
/** check if debounce ok */
|
||||
if (debouncestable < HUB_DEBOUNCE_STABLE) {
|
||||
USB_LOG_ERR("Failed to debounce port %u\r\n", port + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Last, check connect status */
|
||||
@@ -484,39 +501,43 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
}
|
||||
|
||||
child = &hub->child[port];
|
||||
/** release child sources first */
|
||||
usbh_hubport_release(child);
|
||||
|
||||
memset(child, 0, sizeof(struct usbh_hubport));
|
||||
child->parent = hub;
|
||||
child->connected = true;
|
||||
child->port = port + 1;
|
||||
child->speed = speed;
|
||||
|
||||
|
||||
USB_LOG_INFO("New %s device on Hub %u, Port %u connected\r\n", speed_table[speed], hub->index, port + 1);
|
||||
|
||||
/* Configure EP0 with the default maximum packet size */
|
||||
usbh_hport_activate_ep0(child);
|
||||
|
||||
if (usbh_enumerate(child) < 0) {
|
||||
/** release child sources */
|
||||
usbh_hubport_release(child);
|
||||
USB_LOG_ERR("Port %u enumerate fail\r\n", port + 1);
|
||||
}
|
||||
} else {
|
||||
child = &hub->child[port];
|
||||
/** release child sources */
|
||||
usbh_hubport_release(child);
|
||||
USB_LOG_ERR("Failed to enable port %u\r\n", port + 1);
|
||||
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
child = &hub->child[port];
|
||||
child->connected = false;
|
||||
usbh_hport_deactivate_ep0(child);
|
||||
for (uint8_t i = 0; i < child->config.config_desc.bNumInterfaces; i++) {
|
||||
if (child->config.intf[i].class_driver && child->config.intf[i].class_driver->disconnect) {
|
||||
CLASS_DISCONNECT(child, i);
|
||||
}
|
||||
}
|
||||
|
||||
/** release child sources */
|
||||
usbh_hubport_release(child);
|
||||
USB_LOG_INFO("Device on Hub %u, Port %u disconnected\r\n", hub->index, port + 1);
|
||||
usbh_device_unmount_done_callback(child);
|
||||
child->config.config_desc.bNumInterfaces = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hub->int_buffer[0] = 0;
|
||||
/* Start next hub int transfer */
|
||||
if (!hub->is_roothub && hub->connected) {
|
||||
usbh_submit_urb(&hub->intin_urb);
|
||||
@@ -525,48 +546,50 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
||||
|
||||
static void usbh_hub_thread(void *argument)
|
||||
{
|
||||
size_t flags;
|
||||
struct usbh_hub *hub;
|
||||
int ret = 0;
|
||||
|
||||
usb_hc_init();
|
||||
while (1) {
|
||||
ret = usb_osal_sem_take(hub_event_wait, 0xffffffff);
|
||||
ret = usb_osal_mq_recv(hub_mq, (uint32_t *)&hub, 0xffffffff);
|
||||
if (ret < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
while (!usb_slist_isempty(&hub_event_head)) {
|
||||
struct usbh_hub *hub = usb_slist_first_entry(&hub_event_head, struct usbh_hub, hub_event_list);
|
||||
flags = usb_osal_enter_critical_section();
|
||||
usb_slist_remove(&hub_event_head, &hub->hub_event_list);
|
||||
usb_osal_leave_critical_section(flags);
|
||||
usbh_hub_events(hub);
|
||||
}
|
||||
usbh_hub_events(hub);
|
||||
}
|
||||
}
|
||||
|
||||
static void usbh_roothub_register(void)
|
||||
{
|
||||
memset(&roothub, 0, sizeof(struct usbh_hub));
|
||||
|
||||
roothub.connected = true;
|
||||
roothub.index = 1;
|
||||
roothub.is_roothub = true;
|
||||
roothub.parent = NULL;
|
||||
roothub.hub_addr = 1;
|
||||
roothub.hub_desc.bNbrPorts = CONFIG_USBHOST_MAX_RHPORTS;
|
||||
usbh_hub_register(&roothub);
|
||||
}
|
||||
|
||||
static void usbh_hub_thread_wakeup(struct usbh_hub *hub)
|
||||
{
|
||||
usb_osal_mq_send(hub_mq, (uint32_t)hub);
|
||||
}
|
||||
|
||||
void usbh_roothub_thread_wakeup(uint8_t port)
|
||||
{
|
||||
roothub.int_buffer = g_hub_intbuf[roothub.index - 1];
|
||||
roothub.int_buffer[0] |= (1 << port);
|
||||
usbh_hub_thread_wakeup(&roothub);
|
||||
}
|
||||
|
||||
void usbh_hub_register(struct usbh_hub *hub)
|
||||
{
|
||||
usb_slist_add_tail(&hub_class_head, &hub->list);
|
||||
}
|
||||
|
||||
void usbh_hub_unregister(struct usbh_hub *hub)
|
||||
{
|
||||
usb_slist_remove(&hub_class_head, &hub->list);
|
||||
}
|
||||
|
||||
int usbh_hub_initialize(void)
|
||||
{
|
||||
usbh_roothub_register();
|
||||
|
||||
hub_event_wait = usb_osal_sem_create(0);
|
||||
if (hub_event_wait == NULL) {
|
||||
hub_mq = usb_osal_mq_create(7);
|
||||
if (hub_mq == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -576,19 +599,20 @@ int usbh_hub_initialize(void)
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct usbh_class_driver hub_driver = {
|
||||
#if CONFIG_USBHOST_MAX_EXTHUBS > 0
|
||||
const struct usbh_class_driver hub_class_driver = {
|
||||
.driver_name = "hub",
|
||||
.connect = usbh_hub_connect,
|
||||
.disconnect = usbh_hub_disconnect
|
||||
};
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info hub_info = {
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info hub_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS,
|
||||
.class = USB_DEVICE_CLASS_HUB,
|
||||
.subclass = 0,
|
||||
.protocol = 0,
|
||||
.vid = 0x00,
|
||||
.pid = 0x00,
|
||||
.class_driver = &hub_driver
|
||||
.class_driver = &hub_class_driver
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -19,8 +19,6 @@ extern usb_slist_t hub_class_head;
|
||||
extern "C" {
|
||||
#endif
|
||||
void usbh_roothub_thread_wakeup(uint8_t port);
|
||||
void usbh_hub_register(struct usbh_hub *hub);
|
||||
void usbh_hub_unregister(struct usbh_hub *hub);
|
||||
int usbh_hub_initialize(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -6,13 +6,6 @@
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_msc.h"
|
||||
#include "usb_scsi.h"
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
#include "usb_osal.h"
|
||||
#endif
|
||||
|
||||
#define MSC_THREAD_OP_READ_MEM 1
|
||||
#define MSC_THREAD_OP_WRITE_MEM 2
|
||||
#define MSC_THREAD_OP_WRITE_DONE 3
|
||||
|
||||
#define MSD_OUT_EP_IDX 0
|
||||
#define MSD_IN_EP_IDX 1
|
||||
@@ -49,13 +42,6 @@ USB_NOCACHE_RAM_SECTION struct usbd_msc_cfg_priv {
|
||||
uint8_t block_buffer[CONFIG_USBDEV_MSC_BLOCK_SIZE];
|
||||
} usbd_msc_cfg;
|
||||
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
static volatile uint8_t thread_op;
|
||||
static usb_osal_sem_t msc_sem;
|
||||
static usb_osal_thread_t msc_thread;
|
||||
static volatile uint32_t current_byte_read;
|
||||
#endif
|
||||
|
||||
static void usbd_msc_reset(void)
|
||||
{
|
||||
usbd_msc_cfg.stage = MSC_READ_CBW;
|
||||
@@ -74,7 +60,7 @@ static int msc_storage_class_interface_request_handler(struct usb_setup_packet *
|
||||
break;
|
||||
|
||||
case MSC_REQUEST_GET_MAX_LUN:
|
||||
*data = (uint8_t *)(&usbd_msc_cfg.max_lun);
|
||||
(*data)[0] = usbd_msc_cfg.max_lun;
|
||||
*len = 1;
|
||||
break;
|
||||
|
||||
@@ -635,17 +621,11 @@ static bool SCSI_processRead(void)
|
||||
|
||||
transfer_len = MIN(usbd_msc_cfg.nsectors * usbd_msc_cfg.scsi_blk_size, CONFIG_USBDEV_MSC_BLOCK_SIZE);
|
||||
|
||||
/* Start reading one sector */
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
thread_op = MSC_THREAD_OP_READ_MEM;
|
||||
usb_osal_sem_give(msc_sem);
|
||||
return true;
|
||||
#else
|
||||
if (usbd_msc_sector_read(usbd_msc_cfg.start_sector, usbd_msc_cfg.block_buffer, transfer_len) != 0) {
|
||||
SCSI_SetSenseData(SCSI_KCQHE_UREINRESERVEDAREA);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
usbd_ep_start_write(mass_ep_data[MSD_IN_EP_IDX].ep_addr, usbd_msc_cfg.block_buffer, transfer_len);
|
||||
|
||||
usbd_msc_cfg.start_sector += (transfer_len / usbd_msc_cfg.scsi_blk_size);
|
||||
@@ -659,47 +639,15 @@ static bool SCSI_processRead(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
static void usbd_msc_thread_memory_read_done(void)
|
||||
{
|
||||
size_t flags;
|
||||
uint32_t transfer_len;
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
|
||||
transfer_len = MIN(usbd_msc_cfg.nsectors * usbd_msc_cfg.scsi_blk_size, CONFIG_USBDEV_MSC_BLOCK_SIZE);
|
||||
|
||||
usbd_ep_start_write(mass_ep_data[MSD_IN_EP_IDX].ep_addr,
|
||||
usbd_msc_cfg.block_buffer, transfer_len);
|
||||
|
||||
usbd_msc_cfg.start_sector += (transfer_len / usbd_msc_cfg.scsi_blk_size);
|
||||
usbd_msc_cfg.nsectors -= (transfer_len / usbd_msc_cfg.scsi_blk_size);
|
||||
usbd_msc_cfg.csw.dDataResidue -= transfer_len;
|
||||
|
||||
if (usbd_msc_cfg.nsectors == 0) {
|
||||
usbd_msc_cfg.stage = MSC_SEND_CSW;
|
||||
}
|
||||
usb_osal_leave_critical_section(flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool SCSI_processWrite(uint32_t nbytes)
|
||||
{
|
||||
uint32_t data_len = 0;
|
||||
USB_LOG_DBG("write lba:%d\r\n", usbd_msc_cfg.start_sector);
|
||||
|
||||
/* Start writing one sector */
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
thread_op = MSC_THREAD_OP_WRITE_MEM;
|
||||
current_byte_read = nbytes;
|
||||
usb_osal_sem_give(msc_sem);
|
||||
return true;
|
||||
#else
|
||||
if (usbd_msc_sector_write(usbd_msc_cfg.start_sector, usbd_msc_cfg.block_buffer, nbytes) != 0) {
|
||||
SCSI_SetSenseData(SCSI_KCQHE_WRITEFAULT);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
usbd_msc_cfg.start_sector += (nbytes / usbd_msc_cfg.scsi_blk_size);
|
||||
usbd_msc_cfg.nsectors -= (nbytes / usbd_msc_cfg.scsi_blk_size);
|
||||
@@ -715,29 +663,6 @@ static bool SCSI_processWrite(uint32_t nbytes)
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
static void usbd_msc_thread_memory_write_done()
|
||||
{
|
||||
size_t flags;
|
||||
uint32_t data_len = 0;
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
|
||||
usbd_msc_cfg.start_sector += (current_byte_read / usbd_msc_cfg.scsi_blk_size);
|
||||
usbd_msc_cfg.nsectors -= (current_byte_read / usbd_msc_cfg.scsi_blk_size);
|
||||
usbd_msc_cfg.csw.dDataResidue -= current_byte_read;
|
||||
|
||||
if (usbd_msc_cfg.nsectors == 0) {
|
||||
usbd_msc_send_csw(CSW_STATUS_CMD_PASSED);
|
||||
} else {
|
||||
data_len = MIN(usbd_msc_cfg.nsectors * usbd_msc_cfg.scsi_blk_size, CONFIG_USBDEV_MSC_BLOCK_SIZE);
|
||||
usbd_ep_start_read(mass_ep_data[MSD_OUT_EP_IDX].ep_addr, usbd_msc_cfg.block_buffer, data_len);
|
||||
}
|
||||
|
||||
usb_osal_leave_critical_section(flags);
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool SCSI_CBWDecode(uint32_t nbytes)
|
||||
{
|
||||
uint8_t *buf2send = usbd_msc_cfg.block_buffer;
|
||||
@@ -883,35 +808,6 @@ void mass_storage_bulk_in(uint8_t ep, uint32_t nbytes)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
static void usbd_msc_thread(void *argument)
|
||||
{
|
||||
uint32_t data_len = 0;
|
||||
while (1) {
|
||||
usb_osal_sem_take(msc_sem, 0xffffffff);
|
||||
|
||||
switch (thread_op) {
|
||||
case MSC_THREAD_OP_READ_MEM:
|
||||
data_len = MIN(usbd_msc_cfg.nsectors * usbd_msc_cfg.scsi_blk_size, CONFIG_USBDEV_MSC_BLOCK_SIZE);
|
||||
if (usbd_msc_sector_read(usbd_msc_cfg.start_sector, usbd_msc_cfg.block_buffer, data_len) != 0) {
|
||||
SCSI_SetSenseData(SCSI_KCQHE_UREINRESERVEDAREA);
|
||||
}
|
||||
usbd_msc_thread_memory_read_done();
|
||||
break;
|
||||
case MSC_THREAD_OP_WRITE_MEM:
|
||||
data_len = MIN(usbd_msc_cfg.nsectors * usbd_msc_cfg.scsi_blk_size, CONFIG_USBDEV_MSC_BLOCK_SIZE);
|
||||
if (usbd_msc_sector_write(usbd_msc_cfg.start_sector, usbd_msc_cfg.block_buffer, data_len) != 0) {
|
||||
SCSI_SetSenseData(SCSI_KCQHE_WRITEFAULT);
|
||||
}
|
||||
usbd_msc_thread_memory_write_done();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
struct usbd_interface *usbd_msc_init_intf(struct usbd_interface *intf, const uint8_t out_ep, const uint8_t in_ep)
|
||||
{
|
||||
intf->class_interface_handler = msc_storage_class_interface_request_handler;
|
||||
@@ -935,14 +831,6 @@ struct usbd_interface *usbd_msc_init_intf(struct usbd_interface *intf, const uin
|
||||
USB_LOG_ERR("msc block buffer overflow\r\n");
|
||||
return NULL;
|
||||
}
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
msc_sem = usb_osal_sem_create(1);
|
||||
msc_thread = usb_osal_thread_create("usbd_msc", CONFIG_USBDEV_MSC_STACKSIZE, CONFIG_USBDEV_MSC_PRIO, usbd_msc_thread, NULL);
|
||||
if (msc_thread == NULL) {
|
||||
USB_LOG_ERR("no enough memory to alloc msc thread\r\n");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return intf;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ static void usbh_msc_devno_free(struct usbh_msc *msc_class)
|
||||
|
||||
static int usbh_msc_get_maxlun(struct usbh_msc *msc_class, uint8_t *buffer)
|
||||
{
|
||||
struct usb_setup_packet *setup = &msc_class->hport->setup;
|
||||
struct usb_setup_packet *setup = msc_class->hport->setup;
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
|
||||
setup->bRequest = MSC_REQUEST_GET_MAX_LUN;
|
||||
@@ -371,6 +371,7 @@ static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
|
||||
USB_LOG_INFO("Register MSC Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
|
||||
usbh_msc_run(msc_class);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -391,6 +392,7 @@ static int usbh_msc_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
usbh_pipe_free(msc_class->bulkout);
|
||||
}
|
||||
|
||||
usbh_msc_stop(msc_class);
|
||||
memset(msc_class, 0, sizeof(struct usbh_msc));
|
||||
usb_free(msc_class);
|
||||
|
||||
@@ -401,6 +403,16 @@ static int usbh_msc_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
return ret;
|
||||
}
|
||||
|
||||
__WEAK void usbh_msc_run(struct usbh_msc *msc_class)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
__WEAK void usbh_msc_stop(struct usbh_msc *msc_class)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const struct usbh_class_driver msc_class_driver = {
|
||||
.driver_name = "msc",
|
||||
.connect = usbh_msc_connect,
|
||||
|
||||
@@ -25,6 +25,9 @@ struct usbh_msc {
|
||||
int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors);
|
||||
int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors);
|
||||
|
||||
void usbh_msc_run(struct usbh_msc *msc_class);
|
||||
void usbh_msc_stop(struct usbh_msc *msc_class);
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -11,15 +11,196 @@
|
||||
#define USB_MTP_SUB_CLASS 0x01U
|
||||
#define USB_MTP_PROTOCOL 0x01U
|
||||
|
||||
/* MTP class requests */
|
||||
#define MTP_REQUEST_CANCEL 0x64U
|
||||
#define MTP_REQUEST_GET_EXT_EVENT_DATA 0x65U
|
||||
#define MTP_REQUEST_RESET 0x66U
|
||||
#define MTP_REQUEST_GET_DEVICE_STATUS 0x67U
|
||||
|
||||
/* Container Types */
|
||||
#define MTP_CONTAINER_TYPE_UNDEFINED 0U
|
||||
#define MTP_CONTAINER_TYPE_COMMAND 1U
|
||||
#define MTP_CONTAINER_TYPE_DATA 2U
|
||||
#define MTP_CONTAINER_TYPE_RESPONSE 3U
|
||||
#define MTP_CONTAINER_TYPE_EVENT 4U
|
||||
|
||||
/*
|
||||
* MTP Class specification Revision 1.1
|
||||
* Appendix D. Operations
|
||||
*/
|
||||
|
||||
/* Operations code */
|
||||
#define MTP_OP_GET_DEVICE_INFO 0x1001U
|
||||
#define MTP_OP_OPEN_SESSION 0x1002U
|
||||
#define MTP_OP_CLOSE_SESSION 0x1003U
|
||||
#define MTP_OP_GET_STORAGE_IDS 0x1004U
|
||||
#define MTP_OP_GET_STORAGE_INFO 0x1005U
|
||||
#define MTP_OP_GET_NUM_OBJECTS 0x1006U
|
||||
#define MTP_OP_GET_OBJECT_HANDLES 0x1007U
|
||||
#define MTP_OP_GET_OBJECT_INFO 0x1008U
|
||||
#define MTP_OP_GET_OBJECT 0x1009U
|
||||
#define MTP_OP_GET_THUMB 0x100AU
|
||||
#define MTP_OP_DELETE_OBJECT 0x100BU
|
||||
#define MTP_OP_SEND_OBJECT_INFO 0x100CU
|
||||
#define MTP_OP_SEND_OBJECT 0x100DU
|
||||
#define MTP_OP_FORMAT_STORE 0x100FU
|
||||
#define MTP_OP_RESET_DEVICE 0x1010U
|
||||
#define MTP_OP_GET_DEVICE_PROP_DESC 0x1014U
|
||||
#define MTP_OP_GET_DEVICE_PROP_VALUE 0x1015U
|
||||
#define MTP_OP_SET_DEVICE_PROP_VALUE 0x1016U
|
||||
#define MTP_OP_RESET_DEVICE_PROP_VALUE 0x1017U
|
||||
#define MTP_OP_TERMINATE_OPEN_CAPTURE 0x1018U
|
||||
#define MTP_OP_MOVE_OBJECT 0x1019U
|
||||
#define MTP_OP_COPY_OBJECT 0x101AU
|
||||
#define MTP_OP_GET_PARTIAL_OBJECT 0x101BU
|
||||
#define MTP_OP_INITIATE_OPEN_CAPTURE 0x101CU
|
||||
#define MTP_OP_GET_OBJECT_PROPS_SUPPORTED 0x9801U
|
||||
#define MTP_OP_GET_OBJECT_PROP_DESC 0x9802U
|
||||
#define MTP_OP_GET_OBJECT_PROP_VALUE 0x9803U
|
||||
#define MTP_OP_SET_OBJECT_PROP_VALUE 0x9804U
|
||||
#define MTP_OP_GET_OBJECT_PROPLIST 0x9805U
|
||||
#define MTP_OP_GET_OBJECT_PROP_REFERENCES 0x9810U
|
||||
#define MTP_OP_GETSERVICEIDS 0x9301U
|
||||
#define MTP_OP_GETSERVICEINFO 0x9302U
|
||||
#define MTP_OP_GETSERVICECAPABILITIES 0x9303U
|
||||
#define MTP_OP_GETSERVICEPROPDESC 0x9304U
|
||||
|
||||
/* MTP response code */
|
||||
#define MTP_RESPONSE_OK 0x2001U
|
||||
#define MTP_RESPONSE_GENERAL_ERROR 0x2002U
|
||||
#define MTP_RESPONSE_PARAMETER_NOT_SUPPORTED 0x2006U
|
||||
#define MTP_RESPONSE_INCOMPLETE_TRANSFER 0x2007U
|
||||
#define MTP_RESPONSE_INVALID_STORAGE_ID 0x2008U
|
||||
#define MTP_RESPONSE_INVALID_OBJECT_HANDLE 0x2009U
|
||||
#define MTP_RESPONSE_DEVICEPROP_NOT_SUPPORTED 0x200AU
|
||||
#define MTP_RESPONSE_STORE_FULL 0x200CU
|
||||
#define MTP_RESPONSE_ACCESS_DENIED 0x200FU
|
||||
#define MTP_RESPONSE_STORE_NOT_AVAILABLE 0x2013U
|
||||
#define MTP_RESPONSE_SPECIFICATION_BY_FORMAT_NOT_SUPPORTED 0x2014U
|
||||
#define MTP_RESPONSE_NO_VALID_OBJECT_INFO 0x2015U
|
||||
#define MTP_RESPONSE_DEVICE_BUSY 0x2019U
|
||||
#define MTP_RESPONSE_INVALID_PARENT_OBJECT 0x201AU
|
||||
#define MTP_RESPONSE_INVALID_PARAMETER 0x201DU
|
||||
#define MTP_RESPONSE_SESSION_ALREADY_OPEN 0x201EU
|
||||
#define MTP_RESPONSE_TRANSACTION_CANCELLED 0x201FU
|
||||
#define MTP_RESPONSE_INVALID_OBJECT_PROP_CODE 0xA801U
|
||||
#define MTP_RESPONSE_SPECIFICATION_BY_GROUP_UNSUPPORTED 0xA807U
|
||||
#define MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED 0xA80AU
|
||||
|
||||
/* MTP Object format codes */
|
||||
#define MTP_OBJ_FORMAT_UNDEFINED 0x3000U
|
||||
#define MTP_OBJ_FORMAT_ASSOCIATION 0x3001U
|
||||
#define MTP_OBJ_FORMAT_SCRIPT 0x3002U
|
||||
#define MTP_OBJ_FORMAT_EXECUTABLE 0x3003U
|
||||
#define MTP_OBJ_FORMAT_TEXT 0x3004U
|
||||
#define MTP_OBJ_FORMAT_HTML 0x3005U
|
||||
#define MTP_OBJ_FORMAT_DPOF 0x3006U
|
||||
#define MTP_OBJ_FORMAT_AIFF 0x3007U
|
||||
#define MTP_OBJ_FORMAT_WAV 0x3008U
|
||||
#define MTP_OBJ_FORMAT_MP3 0x3009U
|
||||
#define MTP_OBJ_FORMAT_AVI 0x300AU
|
||||
#define MTP_OBJ_FORMAT_MPEG 0x300BU
|
||||
#define MTP_OBJ_FORMAT_ASF 0x300CU
|
||||
#define MTP_OBJ_FORMAT_DEFINED 0x3800U
|
||||
#define MTP_OBJ_FORMAT_EXIF_JPEG 0x3801U
|
||||
#define MTP_OBJ_FORMAT_TIFF_EP 0x3802U
|
||||
#define MTP_OBJ_FORMAT_FLASHPIX 0x3803U
|
||||
#define MTP_OBJ_FORMAT_BMP 0x3804U
|
||||
#define MTP_OBJ_FORMAT_CIFF 0x3805U
|
||||
#define MTP_OBJ_FORMAT_UNDEFINED_RESERVED0 0x3806U
|
||||
#define MTP_OBJ_FORMAT_GIF 0x3807U
|
||||
#define MTP_OBJ_FORMAT_JFIF 0x3808U
|
||||
#define MTP_OBJ_FORMAT_CD 0x3809U
|
||||
#define MTP_OBJ_FORMAT_PICT 0x380AU
|
||||
#define MTP_OBJ_FORMAT_PNG 0x380BU
|
||||
#define MTP_OBJ_FORMAT_UNDEFINED_RESERVED1 0x380CU
|
||||
#define MTP_OBJ_FORMAT_TIFF 0x380DU
|
||||
#define MTP_OBJ_FORMAT_TIFF_IT 0x380EU
|
||||
#define MTP_OBJ_FORMAT_JP2 0x380FU
|
||||
#define MTP_OBJ_FORMAT_JPX 0x3810U
|
||||
#define MTP_OBJ_FORMAT_UNDEFINED_FIRMWARE 0xB802U
|
||||
#define MTP_OBJ_FORMAT_WINDOWS_IMAGE_FORMAT 0xB881U
|
||||
#define MTP_OBJ_FORMAT_UNDEFINED_AUDIO 0xB900U
|
||||
#define MTP_OBJ_FORMAT_WMA 0xB901U
|
||||
#define MTP_OBJ_FORMAT_OGG 0xB902U
|
||||
#define MTP_OBJ_FORMAT_AAC 0xB903U
|
||||
#define MTP_OBJ_FORMAT_AUDIBLE 0xB904U
|
||||
#define MTP_OBJ_FORMAT_FLAC 0xB906U
|
||||
#define MTP_OBJ_FORMAT_UNDEFINED_VIDEO 0xB980U
|
||||
#define MTP_OBJ_FORMAT_WMV 0xB981U
|
||||
#define MTP_OBJ_FORMAT_MP4_CONTAINER 0xB982U
|
||||
#define MTP_OBJ_FORMAT_MP2 0xB983U
|
||||
#define MTP_OBJ_FORMAT_3GP_CONTAINER 0xB984U
|
||||
|
||||
/* MTP event codes*/
|
||||
#define MTP_EVENT_UNDEFINED 0x4000U
|
||||
#define MTP_EVENT_CANCELTRANSACTION 0x4001U
|
||||
#define MTP_EVENT_OBJECTADDED 0x4002U
|
||||
#define MTP_EVENT_OBJECTREMOVED 0x4003U
|
||||
#define MTP_EVENT_STOREADDED 0x4004U
|
||||
#define MTP_EVENT_STOREREMOVED 0x4005U
|
||||
#define MTP_EVENT_DEVICEPROPCHANGED 0x4006U
|
||||
#define MTP_EVENT_OBJECTINFOCHANGED 0x4007U
|
||||
#define MTP_EVENT_DEVICEINFOCHANGED 0x4008U
|
||||
#define MTP_EVENT_REQUESTOBJECTTRANSFER 0x4009U
|
||||
#define MTP_EVENT_STOREFULL 0x400AU
|
||||
#define MTP_EVENT_DEVICERESET 0x400BU
|
||||
#define MTP_EVENT_STORAGEINFOCHANGED 0x400CU
|
||||
#define MTP_EVENT_CAPTURECOMPLETE 0x400DU
|
||||
#define MTP_EVENT_UNREPORTEDSTATUS 0x400EU
|
||||
#define MTP_EVENT_OBJECTPROPCHANGED 0xC801U
|
||||
#define MTP_EVENT_OBJECTPROPDESCCHANGED 0xC802U
|
||||
#define MTP_EVENT_OBJECTREFERENCESCHANGED 0xC803U
|
||||
|
||||
/* MTP device properties code*/
|
||||
#define MTP_DEV_PROP_UNDEFINED 0x5000U
|
||||
#define MTP_DEV_PROP_BATTERY_LEVEL 0x5001U
|
||||
#define MTP_DEV_PROP_FUNCTIONAL_MODE 0x5002U
|
||||
#define MTP_DEV_PROP_IMAGE_SIZE 0x5003U
|
||||
#define MTP_DEV_PROP_COMPRESSION_SETTING 0x5004U
|
||||
#define MTP_DEV_PROP_WHITE_BALANCE 0x5005U
|
||||
#define MTP_DEV_PROP_RGB_GAIN 0x5006U
|
||||
#define MTP_DEV_PROP_F_NUMBER 0x5007U
|
||||
#define MTP_DEV_PROP_FOCAL_LENGTH 0x5008U
|
||||
#define MTP_DEV_PROP_FOCUS_DISTANCE 0x5009U
|
||||
#define MTP_DEV_PROP_FOCUS_MODE 0x500AU
|
||||
#define MTP_DEV_PROP_EXPOSURE_METERING_MODE 0x500BU
|
||||
#define MTP_DEV_PROP_FLASH_MODE 0x500CU
|
||||
#define MTP_DEV_PROP_EXPOSURE_TIME 0x500DU
|
||||
#define MTP_DEV_PROP_EXPOSURE_PROGRAM_MODE 0x500EU
|
||||
#define MTP_DEV_PROP_EXPOSURE_INDEX 0x500FU
|
||||
#define MTP_DEV_PROP_EXPOSURE_BIAS_COMPENSATION 0x5010U
|
||||
#define MTP_DEV_PROP_DATETIME 0x5011U
|
||||
#define MTP_DEV_PROP_CAPTURE_DELAY 0x5012U
|
||||
#define MTP_DEV_PROP_STILL_CAPTURE_MODE 0x5013U
|
||||
#define MTP_DEV_PROP_CONTRAST 0x5014U
|
||||
#define MTP_DEV_PROP_SHARPNESS 0x5015U
|
||||
#define MTP_DEV_PROP_DIGITAL_ZOOM 0x5016U
|
||||
#define MTP_DEV_PROP_EFFECT_MODE 0x5017U
|
||||
#define MTP_DEV_PROP_BURST_NUMBER 0x5018U
|
||||
#define MTP_DEV_PROP_BURST_INTERVAL 0x5019U
|
||||
#define MTP_DEV_PROP_TIMELAPSE_NUMBER 0x501AU
|
||||
#define MTP_DEV_PROP_TIMELAPSE_INTERVAL 0x501BU
|
||||
#define MTP_DEV_PROP_FOCUS_METERING_MODE 0x501CU
|
||||
#define MTP_DEV_PROP_UPLOAD_URL 0x501DU
|
||||
#define MTP_DEV_PROP_ARTIST 0x501EU
|
||||
#define MTP_DEV_PROP_COPYRIGHT_INFO 0x501FU
|
||||
#define MTP_DEV_PROP_SYNCHRONIZATION_PARTNER 0xD401U
|
||||
#define MTP_DEV_PROP_DEVICE_FRIENDLY_NAME 0xD402U
|
||||
#define MTP_DEV_PROP_VOLUME 0xD403U
|
||||
#define MTP_DEV_PROP_SUPPORTEDFORMATSORDERED 0xD404U
|
||||
#define MTP_DEV_PROP_DEVICEICON 0xD405U
|
||||
#define MTP_DEV_PROP_PLAYBACK_RATE 0xD410U
|
||||
#define MTP_DEV_PROP_PLAYBACK_OBJECT 0xD411U
|
||||
#define MTP_DEV_PROP_PLAYBACK_CONTAINER 0xD412U
|
||||
#define MTP_DEV_PROP_SESSION_INITIATOR_VERSION_INFO 0xD406U
|
||||
#define MTP_DEV_PROP_PERCEIVED_DEVICE_TYPE 0xD407U
|
||||
|
||||
/*
|
||||
* MTP Class specification Revision 1.1
|
||||
* Appendix B. Object Properties
|
||||
*/
|
||||
|
||||
/* MTP OBJECT PROPERTIES supported*/
|
||||
#define MTP_OB_PROP_STORAGE_ID 0xDC01U
|
||||
#define MTP_OB_PROP_OBJECT_FORMAT 0xDC02U
|
||||
@@ -188,130 +369,6 @@
|
||||
#define MTP_OB_PROP_TIME_TO_LIVE 0xDD71U
|
||||
#define MTP_OB_PROP_MEDIA_GUID 0xDD72U
|
||||
|
||||
/* MTP event codes*/
|
||||
#define MTP_EVENT_UNDEFINED 0x4000U
|
||||
#define MTP_EVENT_CANCELTRANSACTION 0x4001U
|
||||
#define MTP_EVENT_OBJECTADDED 0x4002U
|
||||
#define MTP_EVENT_OBJECTREMOVED 0x4003U
|
||||
#define MTP_EVENT_STOREADDED 0x4004U
|
||||
#define MTP_EVENT_STOREREMOVED 0x4005U
|
||||
#define MTP_EVENT_DEVICEPROPCHANGED 0x4006U
|
||||
#define MTP_EVENT_OBJECTINFOCHANGED 0x4007U
|
||||
#define MTP_EVENT_DEVICEINFOCHANGED 0x4008U
|
||||
#define MTP_EVENT_REQUESTOBJECTTRANSFER 0x4009U
|
||||
#define MTP_EVENT_STOREFULL 0x400AU
|
||||
#define MTP_EVENT_DEVICERESET 0x400BU
|
||||
#define MTP_EVENT_STORAGEINFOCHANGED 0x400CU
|
||||
#define MTP_EVENT_CAPTURECOMPLETE 0x400DU
|
||||
#define MTP_EVENT_UNREPORTEDSTATUS 0x400EU
|
||||
#define MTP_EVENT_OBJECTPROPCHANGED 0xC801U
|
||||
#define MTP_EVENT_OBJECTPROPDESCCHANGED 0xC802U
|
||||
#define MTP_EVENT_OBJECTREFERENCESCHANGED 0xC803U
|
||||
|
||||
/*
|
||||
* MTP Class specification Revision 1.1
|
||||
* Appendix D. Operations
|
||||
*/
|
||||
|
||||
/* Operations code */
|
||||
#define MTP_OP_GET_DEVICE_INFO 0x1001U
|
||||
#define MTP_OP_OPEN_SESSION 0x1002U
|
||||
#define MTP_OP_CLOSE_SESSION 0x1003U
|
||||
#define MTP_OP_GET_STORAGE_IDS 0x1004U
|
||||
#define MTP_OP_GET_STORAGE_INFO 0x1005U
|
||||
#define MTP_OP_GET_NUM_OBJECTS 0x1006U
|
||||
#define MTP_OP_GET_OBJECT_HANDLES 0x1007U
|
||||
#define MTP_OP_GET_OBJECT_INFO 0x1008U
|
||||
#define MTP_OP_GET_OBJECT 0x1009U
|
||||
#define MTP_OP_GET_THUMB 0x100AU
|
||||
#define MTP_OP_DELETE_OBJECT 0x100BU
|
||||
#define MTP_OP_SEND_OBJECT_INFO 0x100CU
|
||||
#define MTP_OP_SEND_OBJECT 0x100DU
|
||||
#define MTP_OP_FORMAT_STORE 0x100FU
|
||||
#define MTP_OP_RESET_DEVICE 0x1010U
|
||||
#define MTP_OP_GET_DEVICE_PROP_DESC 0x1014U
|
||||
#define MTP_OP_GET_DEVICE_PROP_VALUE 0x1015U
|
||||
#define MTP_OP_SET_DEVICE_PROP_VALUE 0x1016U
|
||||
#define MTP_OP_RESET_DEVICE_PROP_VALUE 0x1017U
|
||||
#define MTP_OP_TERMINATE_OPEN_CAPTURE 0x1018U
|
||||
#define MTP_OP_MOVE_OBJECT 0x1019U
|
||||
#define MTP_OP_COPY_OBJECT 0x101AU
|
||||
#define MTP_OP_GET_PARTIAL_OBJECT 0x101BU
|
||||
#define MTP_OP_INITIATE_OPEN_CAPTURE 0x101CU
|
||||
#define MTP_OP_GET_OBJECT_PROPS_SUPPORTED 0x9801U
|
||||
#define MTP_OP_GET_OBJECT_PROP_DESC 0x9802U
|
||||
#define MTP_OP_GET_OBJECT_PROP_VALUE 0x9803U
|
||||
#define MTP_OP_SET_OBJECT_PROP_VALUE 0x9804U
|
||||
#define MTP_OP_GET_OBJECT_PROPLIST 0x9805U
|
||||
#define MTP_OP_GET_OBJECT_PROP_REFERENCES 0x9810U
|
||||
#define MTP_OP_GETSERVICEIDS 0x9301U
|
||||
#define MTP_OP_GETSERVICEINFO 0x9302U
|
||||
#define MTP_OP_GETSERVICECAPABILITIES 0x9303U
|
||||
#define MTP_OP_GETSERVICEPROPDESC 0x9304U
|
||||
|
||||
/*
|
||||
* MTP Class specification Revision 1.1
|
||||
* Appendix C. Device Properties
|
||||
*/
|
||||
|
||||
/* MTP device properties code*/
|
||||
#define MTP_DEV_PROP_UNDEFINED 0x5000U
|
||||
#define MTP_DEV_PROP_BATTERY_LEVEL 0x5001U
|
||||
#define MTP_DEV_PROP_FUNCTIONAL_MODE 0x5002U
|
||||
#define MTP_DEV_PROP_IMAGE_SIZE 0x5003U
|
||||
#define MTP_DEV_PROP_COMPRESSION_SETTING 0x5004U
|
||||
#define MTP_DEV_PROP_WHITE_BALANCE 0x5005U
|
||||
#define MTP_DEV_PROP_RGB_GAIN 0x5006U
|
||||
#define MTP_DEV_PROP_F_NUMBER 0x5007U
|
||||
#define MTP_DEV_PROP_FOCAL_LENGTH 0x5008U
|
||||
#define MTP_DEV_PROP_FOCUS_DISTANCE 0x5009U
|
||||
#define MTP_DEV_PROP_FOCUS_MODE 0x500AU
|
||||
#define MTP_DEV_PROP_EXPOSURE_METERING_MODE 0x500BU
|
||||
#define MTP_DEV_PROP_FLASH_MODE 0x500CU
|
||||
#define MTP_DEV_PROP_EXPOSURE_TIME 0x500DU
|
||||
#define MTP_DEV_PROP_EXPOSURE_PROGRAM_MODE 0x500EU
|
||||
#define MTP_DEV_PROP_EXPOSURE_INDEX 0x500FU
|
||||
#define MTP_DEV_PROP_EXPOSURE_BIAS_COMPENSATION 0x5010U
|
||||
#define MTP_DEV_PROP_DATETIME 0x5011U
|
||||
#define MTP_DEV_PROP_CAPTURE_DELAY 0x5012U
|
||||
#define MTP_DEV_PROP_STILL_CAPTURE_MODE 0x5013U
|
||||
#define MTP_DEV_PROP_CONTRAST 0x5014U
|
||||
#define MTP_DEV_PROP_SHARPNESS 0x5015U
|
||||
#define MTP_DEV_PROP_DIGITAL_ZOOM 0x5016U
|
||||
#define MTP_DEV_PROP_EFFECT_MODE 0x5017U
|
||||
#define MTP_DEV_PROP_BURST_NUMBER 0x5018U
|
||||
#define MTP_DEV_PROP_BURST_INTERVAL 0x5019U
|
||||
#define MTP_DEV_PROP_TIMELAPSE_NUMBER 0x501AU
|
||||
#define MTP_DEV_PROP_TIMELAPSE_INTERVAL 0x501BU
|
||||
#define MTP_DEV_PROP_FOCUS_METERING_MODE 0x501CU
|
||||
#define MTP_DEV_PROP_UPLOAD_URL 0x501DU
|
||||
#define MTP_DEV_PROP_ARTIST 0x501EU
|
||||
#define MTP_DEV_PROP_COPYRIGHT_INFO 0x501FU
|
||||
#define MTP_DEV_PROP_SYNCHRONIZATION_PARTNER 0xD401U
|
||||
#define MTP_DEV_PROP_DEVICE_FRIENDLY_NAME 0xD402U
|
||||
#define MTP_DEV_PROP_VOLUME 0xD403U
|
||||
#define MTP_DEV_PROP_SUPPORTEDFORMATSORDERED 0xD404U
|
||||
#define MTP_DEV_PROP_DEVICEICON 0xD405U
|
||||
#define MTP_DEV_PROP_PLAYBACK_RATE 0xD410U
|
||||
#define MTP_DEV_PROP_PLAYBACK_OBJECT 0xD411U
|
||||
#define MTP_DEV_PROP_PLAYBACK_CONTAINER 0xD412U
|
||||
#define MTP_DEV_PROP_SESSION_INITIATOR_VERSION_INFO 0xD406U
|
||||
#define MTP_DEV_PROP_PERCEIVED_DEVICE_TYPE 0xD407U
|
||||
|
||||
/* Container Types */
|
||||
#define MTP_CONT_TYPE_UNDEFINED 0U
|
||||
#define MTP_CONT_TYPE_COMMAND 1U
|
||||
#define MTP_CONT_TYPE_DATA 2U
|
||||
#define MTP_CONT_TYPE_RESPONSE 3U
|
||||
#define MTP_CONT_TYPE_EVENT 4U
|
||||
|
||||
#ifndef MTP_STORAGE_ID
|
||||
#define MTP_STORAGE_ID 0x00010001U /* SD card is inserted*/
|
||||
#endif /* MTP_STORAGE_ID */
|
||||
|
||||
#define MTP_NBR_STORAGE_ID 1U
|
||||
#define FREE_SPACE_IN_OBJ_NOT_USED 0xFFFFFFFFU
|
||||
|
||||
/* MTP storage type */
|
||||
#define MTP_STORAGE_UNDEFINED 0U
|
||||
#define MTP_STORAGE_FIXED_ROM 0x0001U
|
||||
@@ -346,4 +403,101 @@
|
||||
#define MTP_PROP_GET 0x00U
|
||||
#define MTP_PROP_GET_SET 0x01U
|
||||
|
||||
#define MTP_SESSION_CLOSED 0x00
|
||||
#define MTP_SESSION_OPENED 0x01
|
||||
|
||||
struct mtp_container_command {
|
||||
uint32_t conlen;
|
||||
uint16_t contype;
|
||||
uint16_t code;
|
||||
uint32_t trans_id;
|
||||
uint32_t param1;
|
||||
uint32_t param2;
|
||||
uint32_t param3;
|
||||
uint32_t param4;
|
||||
uint32_t param5;
|
||||
} __PACKED;
|
||||
|
||||
struct mtp_container_data {
|
||||
uint32_t conlen;
|
||||
uint16_t contype;
|
||||
uint16_t code;
|
||||
uint32_t trans_id;
|
||||
uint8_t data[512];
|
||||
} __PACKED;
|
||||
|
||||
struct mtp_container_response {
|
||||
uint32_t conlen;
|
||||
uint16_t contype;
|
||||
uint16_t code;
|
||||
uint32_t trans_id;
|
||||
} __PACKED;
|
||||
|
||||
/*Length of template descriptor: 23 bytes*/
|
||||
#define MTP_DESCRIPTOR_LEN (9 + 7 + 7 + 7)
|
||||
|
||||
// clang-format off
|
||||
#ifndef CONFIG_USB_HS
|
||||
#define MTP_DESCRIPTOR_INIT(bFirstInterface, out_ep, in_ep, int_ep, str_idx) \
|
||||
/* Interface */ \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
bFirstInterface, /* bInterfaceNumber */ \
|
||||
0x00, /* bAlternateSetting */ \
|
||||
0x03, /* bNumEndpoints */ \
|
||||
USB_DEVICE_CLASS_MASS_STORAGE, /* 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 */ \
|
||||
0x40, 0x00, /* wMaxPacketSize */ \
|
||||
0x00, /* bInterval */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
in_ep, /* bEndpointAddress */ \
|
||||
0x02, /* bmAttributes */ \
|
||||
0x40, 0x00, /* wMaxPacketSize */ \
|
||||
0x00, /* bInterval */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
int_ep, /* bEndpointAddress */ \
|
||||
0x03, /* bmAttributes */ \
|
||||
0x1c, 0x00, /* wMaxPacketSize */ \
|
||||
0x06 /* bInterval */
|
||||
#else
|
||||
#define MTP_DESCRIPTOR_INIT(bFirstInterface, out_ep, in_ep, int_ep, str_idx) \
|
||||
/* Interface */ \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
bFirstInterface, /* bInterfaceNumber */ \
|
||||
0x00, /* bAlternateSetting */ \
|
||||
0x03, /* bNumEndpoints */ \
|
||||
USB_DEVICE_CLASS_MASS_STORAGE, /* 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 */ \
|
||||
0x00, 0x02, /* wMaxPacketSize */ \
|
||||
0x00, /* bInterval */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
in_ep, /* bEndpointAddress */ \
|
||||
0x02, /* bmAttributes */ \
|
||||
0x00, 0x02, /* wMaxPacketSize */ \
|
||||
0x00, /* bInterval */ \
|
||||
0x07, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
int_ep, /* bEndpointAddress */ \
|
||||
0x03, /* bmAttributes */ \
|
||||
0x1c, 0x00, /* wMaxPacketSize */ \
|
||||
0x06 /* bInterval */
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
#endif /* USB_MTP_H */
|
||||
|
||||
@@ -5,23 +5,39 @@
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_mtp.h"
|
||||
#include "usbd_mtp_config.h"
|
||||
|
||||
struct mtp_cfg_priv {
|
||||
uint8_t device_status;
|
||||
} usbd_mtp_cfg;
|
||||
/* MTP Stage */
|
||||
enum Stage {
|
||||
MTP_READ_COMMAND = 0,
|
||||
MTP_DATA_OUT = 1,
|
||||
MTP_DATA_IN = 2,
|
||||
MTP_SEND_RESPONSE = 3,
|
||||
MTP_WAIT_RESPONSE = 4,
|
||||
};
|
||||
|
||||
/* max USB packet size */
|
||||
USB_NOCACHE_RAM_SECTION struct usbd_mtp {
|
||||
USB_MEM_ALIGNX struct mtp_container_command con_command;
|
||||
USB_MEM_ALIGNX struct mtp_container_data con_data;
|
||||
USB_MEM_ALIGNX struct mtp_container_response con_response;
|
||||
enum Stage stage;
|
||||
uint8_t session_state;
|
||||
uint32_t response_code;
|
||||
} g_usbd_mtp;
|
||||
|
||||
/* Max USB packet size */
|
||||
#ifndef CONFIG_USB_HS
|
||||
#define MTP_BULK_EP_MPS 64
|
||||
#else
|
||||
#define MTP_BULK_EP_MPS 512
|
||||
#endif
|
||||
|
||||
#define MSD_OUT_EP_IDX 0
|
||||
#define MSD_IN_EP_IDX 1
|
||||
#define MTP_OUT_EP_IDX 0
|
||||
#define MTP_IN_EP_IDX 1
|
||||
#define MTP_INT_EP_IDX 2
|
||||
|
||||
/* Describe EndPoints configuration */
|
||||
static struct usbd_interface mtp_ep_data[2];
|
||||
static struct usbd_endpoint mtp_ep_data[3];
|
||||
|
||||
static int mtp_class_interface_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
@@ -51,12 +67,462 @@ static int mtp_class_interface_request_handler(struct usb_setup_packet *setup, u
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void usbd_mtp_bulk_out(uint8_t ep)
|
||||
static void usbd_mtp_send_response(uint32_t code)
|
||||
{
|
||||
USB_LOG_DBG("Send response\r\n");
|
||||
|
||||
g_usbd_mtp.stage = MTP_WAIT_RESPONSE;
|
||||
|
||||
g_usbd_mtp.con_response.conlen = 12;
|
||||
g_usbd_mtp.con_response.contype = MTP_CONTAINER_TYPE_RESPONSE;
|
||||
g_usbd_mtp.con_response.code = code;
|
||||
g_usbd_mtp.con_response.trans_id = g_usbd_mtp.con_command.trans_id;
|
||||
|
||||
usbd_ep_start_write(mtp_ep_data[MTP_IN_EP_IDX].ep_addr, (uint8_t *)&g_usbd_mtp.con_response, 12);
|
||||
}
|
||||
|
||||
static void usbd_mtp_bulk_in(uint8_t ep)
|
||||
static void usbd_mtp_send_info(uint8_t *data, uint32_t len)
|
||||
{
|
||||
USB_LOG_DBG("Send info\r\n");
|
||||
|
||||
g_usbd_mtp.stage = MTP_SEND_RESPONSE;
|
||||
|
||||
g_usbd_mtp.con_data.conlen = 12 + len;
|
||||
g_usbd_mtp.con_data.contype = MTP_CONTAINER_TYPE_DATA;
|
||||
g_usbd_mtp.con_data.code = MTP_RESPONSE_OK;
|
||||
g_usbd_mtp.con_data.trans_id = g_usbd_mtp.con_command.trans_id;
|
||||
|
||||
memcpy(g_usbd_mtp.con_data.data, data, len);
|
||||
usbd_ep_start_write(mtp_ep_data[MTP_IN_EP_IDX].ep_addr, (uint8_t *)&g_usbd_mtp.con_data, 12 + len);
|
||||
}
|
||||
|
||||
static void usbd_mtp_get_device_info(void)
|
||||
{
|
||||
struct mtp_device_info device_info;
|
||||
uint16_t i;
|
||||
|
||||
device_info.StandardVersion = 100;
|
||||
device_info.VendorExtensionID = 0x06;
|
||||
device_info.VendorExtensionVersion = 100;
|
||||
device_info.VendorExtensionDesc_len = (uint8_t)CONFIG_MTP_VEND_EXT_DESC_LEN;
|
||||
|
||||
for (i = 0; i < CONFIG_MTP_VEND_EXT_DESC_LEN; i++) {
|
||||
device_info.VendorExtensionDesc[i] = VendExtDesc[i];
|
||||
}
|
||||
|
||||
/* device supports one mode , standard mode */
|
||||
device_info.FunctionalMode = 0x0000;
|
||||
|
||||
/* All supported operation */
|
||||
device_info.OperationsSupported_len = CONFIG_MTP_SUPP_OP_LEN;
|
||||
for (i = 0U; i < CONFIG_MTP_SUPP_OP_LEN; i++) {
|
||||
device_info.OperationsSupported[i] = SuppOP[i];
|
||||
}
|
||||
|
||||
/* event that are currently generated by the device*/
|
||||
device_info.EventsSupported_len = CONFIG_MTP_SUPP_EVENTS_LEN;
|
||||
|
||||
for (i = 0U; i < CONFIG_MTP_SUPP_EVENTS_LEN; i++) {
|
||||
device_info.EventsSupported[i] = SuppEvents[i];
|
||||
}
|
||||
|
||||
device_info.DevicePropertiesSupported_len = CONFIG_MTP_SUPP_DEVICE_PROP_LEN;
|
||||
|
||||
for (i = 0U; i < CONFIG_MTP_SUPP_DEVICE_PROP_LEN; i++) {
|
||||
device_info.DevicePropertiesSupported[i] = DevicePropSupp[i];
|
||||
}
|
||||
|
||||
device_info.CaptureFormats_len = CONFIG_MTP_SUPP_CAPT_FORMAT_LEN;
|
||||
|
||||
for (i = 0U; i < CONFIG_MTP_SUPP_CAPT_FORMAT_LEN; i++) {
|
||||
device_info.CaptureFormats[i] = SuppCaptFormat[i];
|
||||
}
|
||||
|
||||
device_info.ImageFormats_len = CONFIG_MTP_SUPP_IMG_FORMAT_LEN; /* number of image formats that are supported by the device*/
|
||||
for (i = 0U; i < CONFIG_MTP_SUPP_IMG_FORMAT_LEN; i++) {
|
||||
device_info.ImageFormats[i] = SuppImgFormat[i];
|
||||
}
|
||||
|
||||
device_info.Manufacturer_len = (uint8_t)CONFIG_MTP_MANUF_LEN;
|
||||
for (i = 0U; i < CONFIG_MTP_MANUF_LEN; i++) {
|
||||
device_info.Manufacturer[i] = Manuf[i];
|
||||
}
|
||||
|
||||
device_info.Model_len = (uint8_t)CONFIG_MTP_MODEL_LEN;
|
||||
for (i = 0U; i < CONFIG_MTP_MODEL_LEN; i++) {
|
||||
device_info.Model[i] = Model[i];
|
||||
}
|
||||
|
||||
device_info.DeviceVersion_len = (uint8_t)CONFIG_MTP_DEVICE_VERSION_LEN;
|
||||
for (i = 0U; i < CONFIG_MTP_DEVICE_VERSION_LEN; i++) {
|
||||
device_info.DeviceVersion[i] = DeviceVers[i];
|
||||
}
|
||||
|
||||
device_info.SerialNumber_len = (uint8_t)CONFIG_MTP_SERIAL_NBR_LEN;
|
||||
for (i = 0U; i < CONFIG_MTP_SERIAL_NBR_LEN; i++) {
|
||||
device_info.SerialNumber[i] = SerialNbr[i];
|
||||
}
|
||||
|
||||
usbd_mtp_send_info((uint8_t *)&device_info, sizeof(struct mtp_device_info));
|
||||
}
|
||||
|
||||
static void usbd_mtp_open_session(void)
|
||||
{
|
||||
usbd_mtp_send_response(MTP_RESPONSE_OK);
|
||||
}
|
||||
|
||||
static void usbd_mtp_get_storage_ids(void)
|
||||
{
|
||||
struct mtp_storage_id storage_id;
|
||||
|
||||
storage_id.StorageIDS_len = CONFIG_MTP_STORAGE_ID_LEN;
|
||||
storage_id.StorageIDS[0] = MTP_STORAGE_ID;
|
||||
|
||||
usbd_mtp_send_info((uint8_t *)&storage_id, sizeof(struct mtp_storage_id));
|
||||
}
|
||||
|
||||
static void usbd_mtp_get_storage_info(void)
|
||||
{
|
||||
struct mtp_storage_info storage_info;
|
||||
|
||||
storage_info.StorageType = MTP_STORAGE_REMOVABLE_RAM;
|
||||
storage_info.FilesystemType = MTP_FILESYSTEM_GENERIC_FLAT;
|
||||
storage_info.AccessCapability = MTP_ACCESS_CAP_RW;
|
||||
storage_info.MaxCapability = 0x0080DFA81A000000; // todo
|
||||
storage_info.FreeSpaceInBytes = 0x00007EEB0D000000; // todo
|
||||
storage_info.FreeSpaceInObjects = 0xFFFFFFFFU; /* not used */
|
||||
storage_info.StorageDescription = 0U;
|
||||
storage_info.VolumeLabel = 0U;
|
||||
|
||||
usbd_mtp_send_info((uint8_t *)&storage_info, sizeof(struct mtp_storage_info));
|
||||
}
|
||||
|
||||
static void usbd_mtp_get_object_handles(void)
|
||||
{
|
||||
struct mtp_object_handle object_handle;
|
||||
|
||||
// todo
|
||||
|
||||
usbd_mtp_send_info((uint8_t *)&object_handle, sizeof(struct mtp_object_handle));
|
||||
}
|
||||
|
||||
static void usbd_mtp_get_object_info(void)
|
||||
{
|
||||
struct mtp_object_info object_info;
|
||||
|
||||
object_info.Storage_id = MTP_STORAGE_ID;
|
||||
object_info.ObjectFormat = 0; // todo
|
||||
object_info.ObjectCompressedSize = 0; //todo
|
||||
object_info.ProtectionStatus = 0U;
|
||||
object_info.ThumbFormat = MTP_OBJ_FORMAT_UNDEFINED;
|
||||
object_info.ThumbCompressedSize = 0U;
|
||||
object_info.ThumbPixWidth = 0U; /* not supported or not an image */
|
||||
object_info.ThumbPixHeight = 0U;
|
||||
object_info.ImagePixWidth = 0U;
|
||||
object_info.ImagePixHeight = 0U;
|
||||
object_info.ImageBitDepth = 0U;
|
||||
object_info.ParentObject = 0; // todo
|
||||
object_info.AssociationType = 0U;
|
||||
object_info.AssociationDesc = 0U;
|
||||
object_info.SequenceNumber = 0U;
|
||||
|
||||
/* we have to get this value before object_info.Filename */
|
||||
object_info.Filename_len = sizeof(DefaultFileName);
|
||||
memcpy(object_info.Filename, DefaultFileName, (uint32_t)object_info.Filename_len + 1U);
|
||||
|
||||
object_info.CaptureDate = 0U;
|
||||
object_info.ModificationDate = 0U;
|
||||
object_info.Keywords = 0U;
|
||||
|
||||
usbd_mtp_send_info((uint8_t *)&object_info, sizeof(struct mtp_object_info));
|
||||
}
|
||||
|
||||
static void usbd_mtp_get_object_prop_desc(void)
|
||||
{
|
||||
struct mtp_object_prop_desc object_prop_desc;
|
||||
|
||||
uint16_t undef_format = MTP_OBJ_FORMAT_UNDEFINED;
|
||||
uint32_t storageid = MTP_STORAGE_ID;
|
||||
|
||||
switch (g_usbd_mtp.con_command.param1) /* switch obj prop code */
|
||||
{
|
||||
case MTP_OB_PROP_OBJECT_FORMAT:
|
||||
object_prop_desc.ObjectPropertyCode = (uint16_t)(g_usbd_mtp.con_command.param1);
|
||||
object_prop_desc.DataType = MTP_DATATYPE_UINT16;
|
||||
object_prop_desc.GetSet = MTP_PROP_GET;
|
||||
object_prop_desc.DefValue = (uint8_t *)&undef_format;
|
||||
object_prop_desc.GroupCode = 0U;
|
||||
object_prop_desc.FormFlag = 0U;
|
||||
break;
|
||||
|
||||
case MTP_OB_PROP_STORAGE_ID:
|
||||
object_prop_desc.ObjectPropertyCode = (uint16_t)(g_usbd_mtp.con_command.param1);
|
||||
object_prop_desc.DataType = MTP_DATATYPE_UINT32;
|
||||
object_prop_desc.GetSet = MTP_PROP_GET;
|
||||
object_prop_desc.DefValue = (uint8_t *)&storageid;
|
||||
object_prop_desc.GroupCode = 0U;
|
||||
object_prop_desc.FormFlag = 0U;
|
||||
break;
|
||||
|
||||
case MTP_OB_PROP_OBJ_FILE_NAME:
|
||||
object_prop_desc.ObjectPropertyCode = (uint16_t)(g_usbd_mtp.con_command.param1);
|
||||
object_prop_desc.DataType = MTP_DATATYPE_STR;
|
||||
object_prop_desc.GetSet = MTP_PROP_GET;
|
||||
object_prop_desc.DefValue = 0U;
|
||||
object_prop_desc.GroupCode = 0U;
|
||||
object_prop_desc.FormFlag = 0U;
|
||||
break;
|
||||
|
||||
case MTP_OB_PROP_PARENT_OBJECT:
|
||||
object_prop_desc.ObjectPropertyCode = (uint16_t)(g_usbd_mtp.con_command.param1);
|
||||
object_prop_desc.DataType = MTP_DATATYPE_STR;
|
||||
object_prop_desc.GetSet = MTP_PROP_GET;
|
||||
object_prop_desc.DefValue = 0U;
|
||||
object_prop_desc.GroupCode = 0U;
|
||||
object_prop_desc.FormFlag = 0U;
|
||||
break;
|
||||
|
||||
case MTP_OB_PROP_OBJECT_SIZE:
|
||||
object_prop_desc.ObjectPropertyCode = (uint16_t)(g_usbd_mtp.con_command.param1);
|
||||
object_prop_desc.DataType = MTP_DATATYPE_UINT64;
|
||||
object_prop_desc.GetSet = MTP_PROP_GET;
|
||||
object_prop_desc.DefValue = 0U;
|
||||
object_prop_desc.GroupCode = 0U;
|
||||
object_prop_desc.FormFlag = 0U;
|
||||
break;
|
||||
|
||||
case MTP_OB_PROP_NAME:
|
||||
object_prop_desc.ObjectPropertyCode = (uint16_t)(g_usbd_mtp.con_command.param1);
|
||||
object_prop_desc.DataType = MTP_DATATYPE_STR;
|
||||
object_prop_desc.GetSet = MTP_PROP_GET;
|
||||
object_prop_desc.DefValue = NULL;
|
||||
object_prop_desc.GroupCode = 0U;
|
||||
object_prop_desc.FormFlag = 0U;
|
||||
break;
|
||||
|
||||
case MTP_OB_PROP_PERS_UNIQ_OBJ_IDEN:
|
||||
object_prop_desc.ObjectPropertyCode = (uint16_t)(g_usbd_mtp.con_command.param1);
|
||||
object_prop_desc.DataType = MTP_DATATYPE_UINT128;
|
||||
object_prop_desc.GetSet = MTP_PROP_GET;
|
||||
object_prop_desc.DefValue = 0U;
|
||||
object_prop_desc.GroupCode = 0U;
|
||||
object_prop_desc.FormFlag = 0U;
|
||||
break;
|
||||
|
||||
case MTP_OB_PROP_PROTECTION_STATUS:
|
||||
object_prop_desc.ObjectPropertyCode = (uint16_t)(g_usbd_mtp.con_command.param1);
|
||||
object_prop_desc.DataType = MTP_DATATYPE_UINT16;
|
||||
object_prop_desc.GetSet = MTP_PROP_GET_SET;
|
||||
object_prop_desc.DefValue = 0U;
|
||||
object_prop_desc.GroupCode = 0U;
|
||||
object_prop_desc.FormFlag = 0U;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// todo
|
||||
usbd_mtp_send_info((uint8_t *)&object_prop_desc, sizeof(struct mtp_object_prop_desc));
|
||||
}
|
||||
|
||||
static void usbd_mtp_get_object_props_supported(void)
|
||||
{
|
||||
struct mtp_object_props_support object_props_support;
|
||||
uint32_t i;
|
||||
|
||||
object_props_support.ObjectPropCode_len = CONFIG_MTP_SUPP_OBJ_PROP_LEN;
|
||||
|
||||
for (i = 0U; i < CONFIG_MTP_SUPP_OBJ_PROP_LEN; i++) {
|
||||
object_props_support.ObjectPropCode[i] = ObjectPropCode[i];
|
||||
}
|
||||
usbd_mtp_send_info((uint8_t *)&object_props_support, sizeof(struct mtp_object_props_support));
|
||||
}
|
||||
|
||||
static void usbd_mtp_get_object_prop_list(void)
|
||||
{
|
||||
struct mtp_object_prop_list object_prop_list;
|
||||
|
||||
uint16_t filename[255];
|
||||
uint32_t storageid = MTP_STORAGE_ID;
|
||||
uint32_t default_val = 0U;
|
||||
uint32_t i;
|
||||
uint16_t format;
|
||||
uint64_t objsize;
|
||||
uint32_t parent_proval;
|
||||
|
||||
object_prop_list.Properties_len = CONFIG_MTP_SUPP_OBJ_PROP_LEN;
|
||||
|
||||
for (i = 0U; i < CONFIG_MTP_SUPP_OBJ_PROP_LEN; i++) {
|
||||
object_prop_list.Properties[i].ObjectHandle = g_usbd_mtp.con_command.param1;
|
||||
|
||||
switch (ObjectPropCode[i]) {
|
||||
case MTP_OB_PROP_STORAGE_ID:
|
||||
object_prop_list.Properties[i].PropertyCode = MTP_OB_PROP_STORAGE_ID;
|
||||
object_prop_list.Properties[i].Datatype = MTP_DATATYPE_UINT32;
|
||||
object_prop_list.Properties[i].propval = (uint8_t *)&storageid;
|
||||
break;
|
||||
|
||||
case MTP_OB_PROP_OBJECT_FORMAT:
|
||||
object_prop_list.Properties[i].PropertyCode = MTP_OB_PROP_OBJECT_FORMAT;
|
||||
object_prop_list.Properties[i].Datatype = MTP_DATATYPE_UINT16;
|
||||
object_prop_list.Properties[i].propval = (uint8_t *)&format;
|
||||
break;
|
||||
|
||||
case MTP_OB_PROP_OBJ_FILE_NAME:
|
||||
object_prop_list.Properties[i].PropertyCode = MTP_OB_PROP_OBJ_FILE_NAME;
|
||||
object_prop_list.Properties[i].Datatype = MTP_DATATYPE_STR;
|
||||
object_prop_list.Properties[i].propval = NULL;
|
||||
break;
|
||||
|
||||
case MTP_OB_PROP_PARENT_OBJECT:
|
||||
object_prop_list.Properties[i].PropertyCode = MTP_OB_PROP_PARENT_OBJECT;
|
||||
object_prop_list.Properties[i].Datatype = MTP_DATATYPE_UINT32;
|
||||
object_prop_list.Properties[i].propval = (uint8_t *)&parent_proval;
|
||||
break;
|
||||
|
||||
case MTP_OB_PROP_OBJECT_SIZE:
|
||||
object_prop_list.Properties[i].PropertyCode = MTP_OB_PROP_OBJECT_SIZE;
|
||||
object_prop_list.Properties[i].Datatype = MTP_DATATYPE_UINT64;
|
||||
object_prop_list.Properties[i].propval = (uint8_t *)&objsize;
|
||||
break;
|
||||
|
||||
case MTP_OB_PROP_NAME:
|
||||
object_prop_list.Properties[i].PropertyCode = MTP_OB_PROP_NAME;
|
||||
object_prop_list.Properties[i].Datatype = MTP_DATATYPE_STR;
|
||||
object_prop_list.Properties[i].propval = NULL;
|
||||
break;
|
||||
|
||||
case MTP_OB_PROP_PERS_UNIQ_OBJ_IDEN:
|
||||
object_prop_list.Properties[i].PropertyCode = MTP_OB_PROP_PERS_UNIQ_OBJ_IDEN;
|
||||
object_prop_list.Properties[i].Datatype = MTP_DATATYPE_UINT128;
|
||||
object_prop_list.Properties[i].propval = (uint8_t *)&g_usbd_mtp.con_command.param1;
|
||||
break;
|
||||
|
||||
case MTP_OB_PROP_PROTECTION_STATUS:
|
||||
object_prop_list.Properties[i].PropertyCode = MTP_OB_PROP_PROTECTION_STATUS;
|
||||
object_prop_list.Properties[i].Datatype = MTP_DATATYPE_UINT16;
|
||||
object_prop_list.Properties[i].propval = (uint8_t *)&default_val;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// todo
|
||||
usbd_mtp_send_info((uint8_t *)&object_prop_list, sizeof(struct mtp_object_prop_list));
|
||||
}
|
||||
|
||||
static void usbd_mtp_get_device_prop_desc(void)
|
||||
{
|
||||
struct mtp_device_prop_desc device_prop_desc;
|
||||
uint32_t i;
|
||||
|
||||
device_prop_desc.DevicePropertyCode = MTP_DEV_PROP_DEVICE_FRIENDLY_NAME;
|
||||
device_prop_desc.DataType = MTP_DATATYPE_STR;
|
||||
device_prop_desc.GetSet = MTP_PROP_GET_SET;
|
||||
device_prop_desc.DefaultValue_len = CONFIG_MTP_DEVICE_PROP_DESC_DEF_LEN;
|
||||
|
||||
for (i = 0U; i < (sizeof(DevicePropDefVal) / 2U); i++) {
|
||||
device_prop_desc.DefaultValue[i] = DevicePropDefVal[i];
|
||||
}
|
||||
|
||||
device_prop_desc.CurrentValue_len = CONFIG_MTP_DEVICE_PROP_DESC_CUR_LEN;
|
||||
|
||||
for (i = 0U; i < (sizeof(DevicePropCurDefVal) / 2U); i++) {
|
||||
device_prop_desc.CurrentValue[i] = DevicePropCurDefVal[i];
|
||||
}
|
||||
|
||||
device_prop_desc.FormFlag = 0U;
|
||||
|
||||
usbd_mtp_send_info((uint8_t *)&device_prop_desc, sizeof(struct mtp_device_prop_desc));
|
||||
}
|
||||
|
||||
static int usbd_mtp_decode_command(struct mtp_container_command *command)
|
||||
{
|
||||
printf("code:%04x\r\n", command->code);
|
||||
switch (command->code) {
|
||||
case MTP_OP_GET_DEVICE_INFO:
|
||||
usbd_mtp_get_device_info();
|
||||
break;
|
||||
case MTP_OP_OPEN_SESSION:
|
||||
usbd_mtp_open_session();
|
||||
break;
|
||||
case MTP_OP_CLOSE_SESSION:
|
||||
break;
|
||||
case MTP_OP_GET_STORAGE_IDS:
|
||||
usbd_mtp_get_storage_ids();
|
||||
break;
|
||||
case MTP_OP_GET_STORAGE_INFO:
|
||||
usbd_mtp_get_storage_info();
|
||||
break;
|
||||
case MTP_OP_GET_OBJECT_HANDLES:
|
||||
usbd_mtp_get_object_handles();
|
||||
break;
|
||||
case MTP_OP_GET_OBJECT_INFO:
|
||||
usbd_mtp_get_object_info();
|
||||
break;
|
||||
case MTP_OP_GET_OBJECT_PROP_REFERENCES:
|
||||
break;
|
||||
case MTP_OP_GET_OBJECT_PROPS_SUPPORTED:
|
||||
usbd_mtp_get_object_props_supported();
|
||||
break;
|
||||
case MTP_OP_GET_OBJECT_PROP_DESC:
|
||||
usbd_mtp_get_object_prop_desc();
|
||||
break;
|
||||
case MTP_OP_GET_OBJECT_PROPLIST:
|
||||
usbd_mtp_get_object_prop_list();
|
||||
break;
|
||||
case MTP_OP_GET_OBJECT_PROP_VALUE:
|
||||
break;
|
||||
case MTP_OP_GET_DEVICE_PROP_DESC:
|
||||
usbd_mtp_get_device_prop_desc();
|
||||
break;
|
||||
case MTP_OP_GET_OBJECT:
|
||||
break;
|
||||
case MTP_OP_SEND_OBJECT_INFO:
|
||||
break;
|
||||
case MTP_OP_SEND_OBJECT:
|
||||
break;
|
||||
case MTP_OP_DELETE_OBJECT:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void usbd_mtp_bulk_out(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
switch (g_usbd_mtp.stage) {
|
||||
case MTP_READ_COMMAND:
|
||||
usbd_mtp_decode_command(&g_usbd_mtp.con_command);
|
||||
break;
|
||||
case MTP_DATA_OUT:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void usbd_mtp_bulk_in(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
printf("send:%d\r\n", nbytes);
|
||||
switch (g_usbd_mtp.stage) {
|
||||
case MTP_DATA_IN:
|
||||
break;
|
||||
case MTP_SEND_RESPONSE:
|
||||
usbd_mtp_send_response(MTP_RESPONSE_OK);
|
||||
break;
|
||||
case MTP_WAIT_RESPONSE:
|
||||
USB_LOG_DBG("Start reading command\r\n");
|
||||
g_usbd_mtp.stage = MTP_READ_COMMAND;
|
||||
usbd_ep_start_read(mtp_ep_data[MTP_OUT_EP_IDX].ep_addr, (uint8_t *)&g_usbd_mtp.con_command, MTP_BULK_EP_MPS);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void mtp_notify_handler(uint8_t event, void *arg)
|
||||
@@ -64,8 +530,37 @@ static void mtp_notify_handler(uint8_t event, void *arg)
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
USB_LOG_DBG("Start reading command\r\n");
|
||||
g_usbd_mtp.stage = MTP_READ_COMMAND;
|
||||
usbd_ep_start_read(mtp_ep_data[MTP_OUT_EP_IDX].ep_addr, (uint8_t *)&g_usbd_mtp.con_command, MTP_BULK_EP_MPS);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
intf->class_interface_handler = mtp_class_interface_request_handler;
|
||||
intf->class_endpoint_handler = NULL;
|
||||
intf->vendor_handler = NULL;
|
||||
intf->notify_handler = mtp_notify_handler;
|
||||
|
||||
mtp_ep_data[MTP_OUT_EP_IDX].ep_addr = out_ep;
|
||||
mtp_ep_data[MTP_OUT_EP_IDX].ep_cb = usbd_mtp_bulk_out;
|
||||
mtp_ep_data[MTP_IN_EP_IDX].ep_addr = in_ep;
|
||||
mtp_ep_data[MTP_IN_EP_IDX].ep_cb = usbd_mtp_bulk_in;
|
||||
mtp_ep_data[MTP_INT_EP_IDX].ep_addr = int_ep;
|
||||
mtp_ep_data[MTP_INT_EP_IDX].ep_cb = NULL;
|
||||
|
||||
usbd_add_endpoint(&mtp_ep_data[MTP_OUT_EP_IDX]);
|
||||
usbd_add_endpoint(&mtp_ep_data[MTP_IN_EP_IDX]);
|
||||
usbd_add_endpoint(&mtp_ep_data[MTP_INT_EP_IDX]);
|
||||
|
||||
return intf;
|
||||
}
|
||||
@@ -12,6 +12,11 @@
|
||||
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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
179
class/mtp/usbd_mtp_config.h
Normal file
179
class/mtp/usbd_mtp_config.h
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (c) 2022, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef USB_MTP_CONFIG_H
|
||||
#define USB_MTP_CONFIG_H
|
||||
|
||||
#include "usb_mtp.h"
|
||||
|
||||
static const uint16_t VendExtDesc[] = { 'm', 'i', 'c', 'r', 'o', 's', 'o', 'f', 't', '.', 'c', 'o', 'm', ':', ' ', '1', '.', '0', ';', ' ', 0 }; /* last 2 bytes must be 0*/
|
||||
|
||||
static const uint16_t SuppOP[] = { MTP_OP_GET_DEVICE_INFO, MTP_OP_OPEN_SESSION, MTP_OP_CLOSE_SESSION,
|
||||
MTP_OP_GET_STORAGE_IDS, MTP_OP_GET_STORAGE_INFO, MTP_OP_GET_NUM_OBJECTS,
|
||||
MTP_OP_GET_OBJECT_HANDLES, MTP_OP_GET_OBJECT_INFO, MTP_OP_GET_OBJECT,
|
||||
MTP_OP_DELETE_OBJECT, MTP_OP_SEND_OBJECT_INFO, MTP_OP_SEND_OBJECT,
|
||||
MTP_OP_GET_DEVICE_PROP_DESC, MTP_OP_GET_DEVICE_PROP_VALUE,
|
||||
MTP_OP_SET_OBJECT_PROP_VALUE, MTP_OP_GET_OBJECT_PROP_VALUE,
|
||||
MTP_OP_GET_OBJECT_PROPS_SUPPORTED, MTP_OP_GET_OBJECT_PROPLIST,
|
||||
MTP_OP_GET_OBJECT_PROP_DESC, MTP_OP_GET_OBJECT_PROP_REFERENCES };
|
||||
|
||||
static const uint16_t SuppEvents[] = { MTP_EVENT_OBJECTADDED };
|
||||
|
||||
static const uint16_t DevicePropSupp[] = { MTP_DEV_PROP_DEVICE_FRIENDLY_NAME, MTP_DEV_PROP_BATTERY_LEVEL };
|
||||
|
||||
static const uint16_t SuppCaptFormat[] = { MTP_OBJ_FORMAT_UNDEFINED, MTP_OBJ_FORMAT_ASSOCIATION, MTP_OBJ_FORMAT_TEXT };
|
||||
|
||||
static const uint16_t SuppImgFormat[] = { MTP_OBJ_FORMAT_UNDEFINED, MTP_OBJ_FORMAT_TEXT, MTP_OBJ_FORMAT_ASSOCIATION,
|
||||
MTP_OBJ_FORMAT_EXECUTABLE, MTP_OBJ_FORMAT_WAV, MTP_OBJ_FORMAT_MP3,
|
||||
MTP_OBJ_FORMAT_EXIF_JPEG, MTP_OBJ_FORMAT_MPEG, MTP_OBJ_FORMAT_MP4_CONTAINER,
|
||||
MTP_OBJ_FORMAT_WINDOWS_IMAGE_FORMAT, MTP_OBJ_FORMAT_PNG, MTP_OBJ_FORMAT_WMA,
|
||||
MTP_OBJ_FORMAT_WMV };
|
||||
|
||||
static const uint16_t Manuf[] = { 'C', 'h', 'e', 'r', 'r', 'y', 'U', 'S', 'B', 0 }; /* last 2 bytes must be 0*/
|
||||
static const uint16_t Model[] = { 'C', 'h', 'e', 'r', 'r', 'y', 'U', 'S', 'B', 0 }; /* last 2 bytes must be 0*/
|
||||
static const uint16_t DeviceVers[] = { 'V', '1', '.', '0', '0', 0 }; /* last 2 bytes must be 0*/
|
||||
/*SerialNbr shall be 32 character hexadecimal string for legacy compatibility reasons */
|
||||
static const uint16_t SerialNbr[] = { '0', '0', '0', '0', '1', '0', '0', '0', '0', '1', '0', '0', '0', '0',
|
||||
'1', '0', '0', '0', '0', '1', '0', '0', '0', '0', '1', '0', '0', '0',
|
||||
'0', '1', '0', '0', 0 }; /* last 2 bytes must be 0*/
|
||||
|
||||
static const uint16_t DefaultFileName[] = { 'N', 'e', 'w', ' ', 'F', 'o', 'l', 'd', 'e', 'r', 0 };
|
||||
|
||||
static const uint16_t DevicePropDefVal[] = { 'C', 'h', 'e', 'r', 'r', 'y', 'U', 'S', 'B', 0 }; /* last 2 bytes must be 0*/
|
||||
static const uint16_t DevicePropCurDefVal[] = { 'C', 'h', 'e', 'r', 'r', 'y', 'U', 'S', 'B', 0 };
|
||||
|
||||
/* required for all object format : storageID, objectFormat, ObjectCompressedSize,
|
||||
persistent unique object identifier, name*/
|
||||
static const uint16_t ObjectPropCode[] = { MTP_OB_PROP_STORAGE_ID, MTP_OB_PROP_OBJECT_FORMAT, MTP_OB_PROP_OBJECT_SIZE,
|
||||
MTP_OB_PROP_OBJ_FILE_NAME, MTP_OB_PROP_PARENT_OBJECT, MTP_OB_PROP_NAME,
|
||||
MTP_OB_PROP_PERS_UNIQ_OBJ_IDEN, MTP_OB_PROP_PROTECTION_STATUS };
|
||||
|
||||
#define MTP_STORAGE_ID 0x00010001U /* SD card is inserted*/
|
||||
|
||||
#define CONFIG_MTP_VEND_EXT_DESC_LEN (sizeof(VendExtDesc) / 2U)
|
||||
#define CONFIG_MTP_SUPP_OP_LEN (sizeof(SuppOP) / 2U)
|
||||
#define CONFIG_MTP_SUPP_EVENTS_LEN (sizeof(SuppEvents) / 2U)
|
||||
#define CONFIG_MTP_SUPP_DEVICE_PROP_LEN (sizeof(DevicePropSupp) / 2U)
|
||||
#define CONFIG_MTP_SUPP_CAPT_FORMAT_LEN (sizeof(SuppCaptFormat) / 2U)
|
||||
#define CONFIG_MTP_SUPP_IMG_FORMAT_LEN (sizeof(SuppImgFormat) / 2U)
|
||||
#define CONFIG_MTP_MANUF_LEN (sizeof(Manuf) / 2U)
|
||||
#define CONFIG_MTP_MODEL_LEN (sizeof(Model) / 2U)
|
||||
#define CONFIG_MTP_DEVICE_VERSION_LEN (sizeof(DeviceVers) / 2U)
|
||||
#define CONFIG_MTP_SERIAL_NBR_LEN (sizeof(SerialNbr) / 2U)
|
||||
#define CONFIG_MTP_SUPP_OBJ_PROP_LEN (sizeof(ObjectPropCode) / 2U)
|
||||
#define CONFIG_MTP_DEVICE_PROP_DESC_DEF_LEN (sizeof(DevicePropDefVal) / 2U)
|
||||
#define CONFIG_MTP_DEVICE_PROP_DESC_CUR_LEN (sizeof(DevicePropCurDefVal) / 2U)
|
||||
#define CONFIG_MTP_STORAGE_ID_LEN 1
|
||||
#define CONFIG_MTP_OBJECT_HANDLE_LEN 100
|
||||
|
||||
struct mtp_device_info {
|
||||
uint16_t StandardVersion;
|
||||
uint32_t VendorExtensionID;
|
||||
uint16_t VendorExtensionVersion;
|
||||
uint8_t VendorExtensionDesc_len;
|
||||
uint16_t VendorExtensionDesc[CONFIG_MTP_VEND_EXT_DESC_LEN];
|
||||
uint16_t FunctionalMode;
|
||||
uint32_t OperationsSupported_len;
|
||||
uint16_t OperationsSupported[CONFIG_MTP_SUPP_OP_LEN];
|
||||
uint32_t EventsSupported_len;
|
||||
uint16_t EventsSupported[CONFIG_MTP_SUPP_EVENTS_LEN];
|
||||
uint32_t DevicePropertiesSupported_len;
|
||||
uint16_t DevicePropertiesSupported[CONFIG_MTP_SUPP_DEVICE_PROP_LEN];
|
||||
uint32_t CaptureFormats_len;
|
||||
uint16_t CaptureFormats[CONFIG_MTP_SUPP_CAPT_FORMAT_LEN];
|
||||
uint32_t ImageFormats_len;
|
||||
uint16_t ImageFormats[CONFIG_MTP_SUPP_IMG_FORMAT_LEN];
|
||||
uint8_t Manufacturer_len;
|
||||
uint16_t Manufacturer[CONFIG_MTP_MANUF_LEN];
|
||||
uint8_t Model_len;
|
||||
uint16_t Model[CONFIG_MTP_MODEL_LEN];
|
||||
uint8_t DeviceVersion_len;
|
||||
uint16_t DeviceVersion[CONFIG_MTP_DEVICE_VERSION_LEN];
|
||||
uint8_t SerialNumber_len;
|
||||
uint16_t SerialNumber[CONFIG_MTP_SERIAL_NBR_LEN];
|
||||
} __PACKED;
|
||||
|
||||
struct mtp_object_props_support {
|
||||
uint32_t ObjectPropCode_len;
|
||||
uint16_t ObjectPropCode[CONFIG_MTP_SUPP_OBJ_PROP_LEN];
|
||||
} __PACKED;
|
||||
|
||||
struct mtp_device_prop_desc {
|
||||
uint16_t DevicePropertyCode;
|
||||
uint16_t DataType;
|
||||
uint8_t GetSet;
|
||||
uint8_t DefaultValue_len;
|
||||
uint16_t DefaultValue[CONFIG_MTP_DEVICE_PROP_DESC_DEF_LEN];
|
||||
uint8_t CurrentValue_len;
|
||||
uint16_t CurrentValue[CONFIG_MTP_DEVICE_PROP_DESC_CUR_LEN];
|
||||
uint8_t FormFlag;
|
||||
} __PACKED;
|
||||
|
||||
struct mtp_storage_id {
|
||||
uint32_t StorageIDS_len;
|
||||
uint32_t StorageIDS[CONFIG_MTP_STORAGE_ID_LEN];
|
||||
} __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;
|
||||
uint8_t VolumeLabel;
|
||||
} __PACKED;
|
||||
|
||||
struct mtp_object_handle {
|
||||
uint32_t ObjectHandle_len;
|
||||
uint32_t ObjectHandle[CONFIG_MTP_OBJECT_HANDLE_LEN];
|
||||
} __PACKED;
|
||||
|
||||
struct mtp_object_info {
|
||||
uint32_t Storage_id;
|
||||
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[255];
|
||||
uint32_t CaptureDate;
|
||||
uint32_t ModificationDate;
|
||||
uint8_t Keywords;
|
||||
} __PACKED;
|
||||
|
||||
struct mtp_object_prop_desc {
|
||||
uint16_t ObjectPropertyCode;
|
||||
uint16_t DataType;
|
||||
uint8_t GetSet;
|
||||
uint8_t *DefValue;
|
||||
uint32_t GroupCode;
|
||||
uint8_t FormFlag;
|
||||
} __PACKED;
|
||||
|
||||
struct mtp_object_prop_element {
|
||||
uint32_t ObjectHandle;
|
||||
uint16_t PropertyCode;
|
||||
uint16_t Datatype;
|
||||
uint8_t *propval;
|
||||
} __PACKED;
|
||||
|
||||
struct mtp_object_prop_list {
|
||||
uint32_t Properties_len;
|
||||
struct mtp_object_prop_element Properties[CONFIG_MTP_SUPP_OBJ_PROP_LEN];
|
||||
} __PACKED;
|
||||
|
||||
#endif /* USB_MTP_CONFIG_H */
|
||||
55
class/vendor/usbh_air724.c
vendored
55
class/vendor/usbh_air724.c
vendored
@@ -7,15 +7,29 @@
|
||||
|
||||
#define DEV_FORMAT "/dev/air724"
|
||||
|
||||
static uint32_t g_devinuse = 0;
|
||||
|
||||
struct usbh_cdc_custom_air724 {
|
||||
struct usbh_hubport *hport;
|
||||
|
||||
usbh_pipe_t bulkin; /* Bulk IN endpoint */
|
||||
usbh_pipe_t bulkout; /* Bulk OUT endpoint */
|
||||
usbh_pipe_t bulkin; /* Bulk IN endpoint */
|
||||
usbh_pipe_t bulkout; /* Bulk OUT endpoint */
|
||||
struct usbh_urb bulkin_urb; /* Bulk IN urb */
|
||||
struct usbh_urb bulkout_urb; /* Bulk OUT urb */
|
||||
};
|
||||
|
||||
static inline int usbh_air724_bulk_out_transfer(struct usbh_cdc_custom_air724 *cdc_custom_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
|
||||
{
|
||||
int ret;
|
||||
struct usbh_urb *urb = &cdc_custom_class->bulkout_urb;
|
||||
memset(urb, 0, sizeof(struct usbh_urb));
|
||||
|
||||
usbh_bulk_urb_fill(urb, cdc_custom_class->bulkout, buffer, buflen, timeout, NULL, NULL);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret == 0) {
|
||||
ret = urb->actual_length;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usbh_air724_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
struct usbh_endpoint_cfg ep_cfg = { 0 };
|
||||
@@ -50,22 +64,23 @@ int usbh_air724_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
}
|
||||
|
||||
USB_LOG_INFO("Register air724 Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
// uint8_t cdc_buffer[32] = {0X41,0X54,0x0d,0x0a};
|
||||
// ret = usbh_ep_bulk_transfer(cdc_custom_class->bulkout, cdc_buffer, 4, 3000);
|
||||
// if (ret < 0) {
|
||||
// USB_LOG_ERR("bulk out error,ret:%d\r\n", ret);
|
||||
// } else {
|
||||
// USB_LOG_RAW("send over:%d\r\n", ret);
|
||||
// }
|
||||
// ret = usbh_ep_bulk_transfer(cdc_custom_class->bulkin, cdc_buffer, 10, 3000);
|
||||
// if (ret < 0) {
|
||||
// USB_LOG_ERR("bulk in error,ret:%d\r\n", ret);
|
||||
// } else {
|
||||
// USB_LOG_RAW("recv over:%d\r\n", ret);
|
||||
// for (size_t i = 0; i < ret; i++) {
|
||||
// USB_LOG_RAW("0x%02x ", cdc_buffer[i]);
|
||||
// }
|
||||
// }
|
||||
|
||||
uint8_t cdc_buffer[32] = { 0x41, 0x54, 0x0d, 0x0a };
|
||||
ret = usbh_air724_bulk_out_transfer(cdc_custom_class->bulkout, cdc_buffer, 4, 3000);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("bulk out error,ret:%d\r\n", ret);
|
||||
} else {
|
||||
USB_LOG_RAW("send over:%d\r\n", ret);
|
||||
}
|
||||
ret = usbh_air724_bulk_out_transfer(cdc_custom_class->bulkin, cdc_buffer, 10, 3000);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("bulk in error,ret:%d\r\n", ret);
|
||||
} else {
|
||||
USB_LOG_RAW("recv over:%d\r\n", ret);
|
||||
for (size_t i = 0; i < ret; i++) {
|
||||
USB_LOG_RAW("0x%02x ", cdc_buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ static int __s_b_1732446u[256] = { 0 };
|
||||
static int __s_g_337633u[256] = { 0 };
|
||||
static int __s_g_698001v[256] = { 0 };
|
||||
|
||||
static void inityuyv2rgb_table(void)
|
||||
void usbh_video_inityuyv2rgb_table(void)
|
||||
{
|
||||
for (int i = 0; i < 256; i++) {
|
||||
__s_r_1370705v[i] = (1.370705 * (i - 128));
|
||||
@@ -42,7 +42,7 @@ static void inityuyv2rgb_table(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void yuyv2rgb565(void *input, void *output, uint32_t len)
|
||||
void usbh_video_yuyv2rgb565(void *input, void *output, uint32_t len)
|
||||
{
|
||||
int y0, u, y1, v;
|
||||
uint8_t r, g, b;
|
||||
@@ -97,7 +97,7 @@ static void usbh_video_devno_free(struct usbh_video *video_class)
|
||||
|
||||
int usbh_video_get_cur(struct usbh_video *video_class, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
struct usb_setup_packet *setup = &video_class->hport->setup;
|
||||
struct usb_setup_packet *setup = video_class->hport->setup;
|
||||
int ret;
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
|
||||
@@ -116,7 +116,7 @@ int usbh_video_get_cur(struct usbh_video *video_class, uint8_t intf, uint8_t ent
|
||||
|
||||
int usbh_video_set_cur(struct usbh_video *video_class, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
struct usb_setup_packet *setup = &video_class->hport->setup;
|
||||
struct usb_setup_packet *setup = video_class->hport->setup;
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_CLASS | USB_REQUEST_RECIPIENT_INTERFACE;
|
||||
setup->bRequest = VIDEO_REQUEST_SET_CUR;
|
||||
@@ -134,40 +134,88 @@ int usbh_videostreaming_get_cur_probe(struct usbh_video *video_class)
|
||||
return usbh_video_get_cur(video_class, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, (uint8_t *)&video_class->probe, 26);
|
||||
}
|
||||
|
||||
int usbh_videostreaming_set_cur_probe(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex, uint32_t dwMaxVideoFrameSize, uint32_t dwMaxPayloadTransferSize)
|
||||
int usbh_videostreaming_set_cur_probe(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex)
|
||||
{
|
||||
video_class->probe.bFormatIndex = formatindex;
|
||||
video_class->probe.bFrameIndex = frameindex;
|
||||
video_class->probe.dwMaxVideoFrameSize = dwMaxVideoFrameSize;
|
||||
video_class->probe.dwMaxPayloadTransferSize = dwMaxPayloadTransferSize;
|
||||
video_class->probe.dwMaxPayloadTransferSize = 0;
|
||||
return usbh_video_set_cur(video_class, video_class->data_intf, 0x00, VIDEO_VS_PROBE_CONTROL, (uint8_t *)&video_class->probe, 26);
|
||||
}
|
||||
|
||||
int usbh_videostreaming_set_cur_commit(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex, uint32_t dwMaxVideoFrameSize, uint32_t dwMaxPayloadTransferSize)
|
||||
int usbh_videostreaming_set_cur_commit(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex)
|
||||
{
|
||||
memcpy(&video_class->commit, &video_class->probe, sizeof(struct video_probe_and_commit_controls));
|
||||
video_class->commit.bFormatIndex = formatindex;
|
||||
video_class->commit.bFrameIndex = frameindex;
|
||||
video_class->commit.dwMaxVideoFrameSize = dwMaxVideoFrameSize;
|
||||
video_class->commit.dwMaxPayloadTransferSize = dwMaxPayloadTransferSize;
|
||||
return usbh_video_set_cur(video_class, video_class->data_intf, 0x00, VIDEO_VS_COMMIT_CONTROL, (uint8_t *)&video_class->commit, 26);
|
||||
}
|
||||
|
||||
int usbh_video_open(struct usbh_video *video_class, uint8_t altsetting)
|
||||
int usbh_video_open(struct usbh_video *video_class,
|
||||
uint8_t format_type,
|
||||
uint16_t wWidth,
|
||||
uint16_t wHeight,
|
||||
uint8_t altsetting)
|
||||
{
|
||||
struct usb_setup_packet *setup = &video_class->hport->setup;
|
||||
struct usb_setup_packet *setup = video_class->hport->setup;
|
||||
struct usb_endpoint_descriptor *ep_desc;
|
||||
uint8_t mult;
|
||||
uint16_t mps;
|
||||
int ret;
|
||||
bool found = false;
|
||||
uint8_t formatidx = 0;
|
||||
uint8_t frameidx = 0;
|
||||
|
||||
if (video_class->is_opened) {
|
||||
return -EMFILE;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < video_class->num_of_formats; i++) {
|
||||
if (format_type == video_class->format[i].format_type) {
|
||||
formatidx = i + 1;
|
||||
for (uint8_t j = 0; j < video_class->format[i].num_of_frames; j++) {
|
||||
if ((wWidth == video_class->format[i].frame[j].wWidth) &&
|
||||
(wHeight == video_class->format[i].frame[j].wHeight)) {
|
||||
frameidx = j + 1;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found == false) {
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (altsetting > (video_class->num_of_intf_altsettings - 1)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = usbh_videostreaming_get_cur_probe(video_class);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = usbh_videostreaming_get_cur_probe(video_class);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = usbh_videostreaming_set_cur_probe(video_class, formatidx, frameidx);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = usbh_videostreaming_get_cur_probe(video_class);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = usbh_videostreaming_set_cur_commit(video_class, formatidx, frameidx);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
|
||||
setup->bRequest = USB_REQUEST_SET_INTERFACE;
|
||||
setup->wValue = altsetting;
|
||||
@@ -189,15 +237,31 @@ int usbh_video_open(struct usbh_video *video_class, uint8_t altsetting)
|
||||
video_class->isoout_mps = mps * (mult + 1);
|
||||
usbh_hport_activate_epx(&video_class->isoout, video_class->hport, ep_desc);
|
||||
}
|
||||
USB_LOG_INFO("Open video and select altsetting:%u\r\n", altsetting);
|
||||
|
||||
USB_LOG_INFO("Open video and select formatidx:%u, frameidx:%u, altsetting:%u\r\n", formatidx, frameidx, altsetting);
|
||||
video_class->is_opened = true;
|
||||
video_class->current_format = format_type;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usbh_video_close(struct usbh_video *video_class)
|
||||
{
|
||||
struct usb_setup_packet *setup = &video_class->hport->setup;
|
||||
int ret;
|
||||
struct usb_setup_packet *setup = video_class->hport->setup;
|
||||
int ret = 0;
|
||||
|
||||
USB_LOG_INFO("Close video device\r\n");
|
||||
|
||||
video_class->is_opened = false;
|
||||
|
||||
if (video_class->isoin) {
|
||||
usbh_pipe_free(video_class->isoin);
|
||||
video_class->isoin = NULL;
|
||||
}
|
||||
|
||||
if (video_class->isoout) {
|
||||
usbh_pipe_free(video_class->isoout);
|
||||
video_class->isoout = NULL;
|
||||
}
|
||||
|
||||
setup->bmRequestType = USB_REQUEST_DIR_OUT | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_INTERFACE;
|
||||
setup->bRequest = USB_REQUEST_SET_INTERFACE;
|
||||
@@ -209,35 +273,24 @@ int usbh_video_close(struct usbh_video *video_class)
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
if (video_class->isoin) {
|
||||
usbh_pipe_free(video_class->isoin);
|
||||
video_class->isoin = NULL;
|
||||
}
|
||||
|
||||
if (video_class->isoout) {
|
||||
usbh_pipe_free(video_class->isoout);
|
||||
video_class->isoout = NULL;
|
||||
}
|
||||
|
||||
USB_LOG_INFO("Close video device\r\n");
|
||||
video_class->is_opened = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void usbh_video_list_info(struct usbh_video *video_class)
|
||||
{
|
||||
struct usbh_hubport *hport;
|
||||
struct usb_endpoint_descriptor *ep_desc;
|
||||
uint8_t mult;
|
||||
uint16_t mps;
|
||||
|
||||
USB_LOG_INFO("============= Video device information ===================\r\n");
|
||||
USB_LOG_INFO("bcdVDC:%04x\r\n", video_class->bcdVDC);
|
||||
USB_LOG_INFO("Num of altsettings:%02x\r\n", video_class->num_of_intf_altsettings);
|
||||
USB_LOG_INFO("Num of altsettings:%u\r\n", video_class->num_of_intf_altsettings);
|
||||
|
||||
hport = video_class->hport;
|
||||
|
||||
for (uint8_t i = 1; i < video_class->num_of_intf_altsettings; i++) {
|
||||
for (uint8_t i = 0; i < video_class->num_of_intf_altsettings; i++) {
|
||||
if (i == 0) {
|
||||
USB_LOG_INFO("Ingore altsetting 0\r\n");
|
||||
continue;
|
||||
}
|
||||
ep_desc = &video_class->hport->config.intf[video_class->data_intf].altsetting[i].ep[0].ep_desc;
|
||||
|
||||
mult = (ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_MASK) >> USB_MAXPACKETSIZE_ADDITIONAL_TRANSCATION_SHIFT;
|
||||
@@ -266,18 +319,14 @@ void usbh_video_list_info(struct usbh_video *video_class)
|
||||
}
|
||||
}
|
||||
|
||||
usbh_videostreaming_get_cur_probe(video_class);
|
||||
|
||||
USB_LOG_INFO("dwMaxVideoFrameSize:%u,dwMaxPayloadTransferSize:%u\r\n", (int)video_class->probe.dwMaxVideoFrameSize, (int)video_class->probe.dwMaxPayloadTransferSize);
|
||||
|
||||
USB_LOG_INFO("============= Video device information ===================\r\n");
|
||||
}
|
||||
|
||||
static int usbh_video_ctrl_intf_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
static int usbh_video_ctrl_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
int ret;
|
||||
uint8_t cur_iface = 0xff;
|
||||
uint8_t cur_alt_setting = 0xff;
|
||||
// uint8_t cur_alt_setting = 0xff;
|
||||
uint8_t frame_index = 0xff;
|
||||
uint8_t format_index = 0xff;
|
||||
uint8_t num_of_frames = 0xff;
|
||||
@@ -378,14 +427,16 @@ static int usbh_video_ctrl_intf_connect(struct usbh_hubport *hport, uint8_t intf
|
||||
usbh_video_list_info(video_class);
|
||||
|
||||
snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, video_class->minor);
|
||||
|
||||
#ifdef CONFIG_USBHOST_UVC_YUV2RGB
|
||||
inityuyv2rgb_table();
|
||||
#endif
|
||||
USB_LOG_INFO("Register Video Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
|
||||
return 0;
|
||||
usbh_video_run(video_class);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int usbh_video_ctrl_intf_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
static int usbh_video_ctrl_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
@@ -402,6 +453,7 @@ static int usbh_video_ctrl_intf_disconnect(struct usbh_hubport *hport, uint8_t i
|
||||
usbh_pipe_free(video_class->isoout);
|
||||
}
|
||||
|
||||
usbh_video_stop(video_class);
|
||||
memset(video_class, 0, sizeof(struct usbh_video));
|
||||
usb_free(video_class);
|
||||
|
||||
@@ -412,13 +464,12 @@ static int usbh_video_ctrl_intf_disconnect(struct usbh_hubport *hport, uint8_t i
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int usbh_video_data_intf_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
static int usbh_video_streaming_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
USB_LOG_WRN("Ignore video data intf\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usbh_video_data_intf_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
static int usbh_video_streaming_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -427,9 +478,9 @@ void usbh_videostreaming_parse_mjpeg(struct usbh_urb *urb, struct usbh_videostre
|
||||
{
|
||||
struct usbh_iso_frame_packet *iso_packet;
|
||||
uint32_t num_of_iso_packets;
|
||||
uint8_t *tmp_buf;
|
||||
uint8_t data_offset;
|
||||
uint32_t data_len;
|
||||
uint8_t header_len = 0;
|
||||
|
||||
num_of_iso_packets = urb->num_of_iso_packets;
|
||||
iso_packet = urb->iso_packet;
|
||||
@@ -448,11 +499,10 @@ void usbh_videostreaming_parse_mjpeg(struct usbh_urb *urb, struct usbh_videostre
|
||||
if (iso_packet[i].actual_length == 0) { /* skip no data */
|
||||
continue;
|
||||
}
|
||||
if (iso_packet[i].actual_length < iso_packet[i].transfer_buffer[0]) { /* do not be illegal */
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
if ((iso_packet[i].transfer_buffer[0] > 12) || (iso_packet[i].transfer_buffer[0] == 0)) { /* do not be illegal */
|
||||
|
||||
header_len = iso_packet[i].transfer_buffer[0];
|
||||
|
||||
if ((header_len > 12) || (header_len == 0)) { /* do not be illegal */
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
@@ -461,20 +511,20 @@ void usbh_videostreaming_parse_mjpeg(struct usbh_urb *urb, struct usbh_videostre
|
||||
continue;
|
||||
}
|
||||
|
||||
data_offset = iso_packet[i].transfer_buffer[0];
|
||||
data_len = iso_packet[i].actual_length - iso_packet[i].transfer_buffer[0];
|
||||
|
||||
tmp_buf = stream->bufbase + stream->bufoffset;
|
||||
stream->bufoffset += data_len;
|
||||
|
||||
memcpy(tmp_buf, &iso_packet[i].transfer_buffer[data_offset], data_len);
|
||||
if ((stream->bufbase[0] != 0xff) && (stream->bufbase[1] != 0xd8)) {
|
||||
if ((stream->bufoffset == 0) && (iso_packet[i].transfer_buffer[header_len] != 0xff) && (iso_packet[i].transfer_buffer[header_len + 1] != 0xd8)) {
|
||||
stream->bufoffset = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
data_offset = iso_packet[i].transfer_buffer[0];
|
||||
data_len = iso_packet[i].actual_length - iso_packet[i].transfer_buffer[0];
|
||||
|
||||
usbh_videostreaming_output(&iso_packet[i].transfer_buffer[data_offset], data_len);
|
||||
|
||||
stream->bufoffset += data_len;
|
||||
|
||||
if (iso_packet[i].transfer_buffer[1] & (1 << 1)) {
|
||||
if ((stream->bufbase[stream->bufoffset - 2] != 0xff) && (stream->bufbase[stream->bufoffset - 1] != 0xd9)) {
|
||||
if ((iso_packet[i].transfer_buffer[iso_packet[i].actual_length - 2] != 0xff) && (iso_packet[i].transfer_buffer[iso_packet[i].actual_length - 1] != 0xd9)) {
|
||||
stream->bufoffset = 0;
|
||||
continue;
|
||||
}
|
||||
@@ -486,13 +536,13 @@ void usbh_videostreaming_parse_mjpeg(struct usbh_urb *urb, struct usbh_videostre
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_videostreaming_parse_yuyv2rgb565(struct usbh_urb *urb, struct usbh_videostreaming *stream)
|
||||
void usbh_videostreaming_parse_yuyv2(struct usbh_urb *urb, struct usbh_videostreaming *stream)
|
||||
{
|
||||
struct usbh_iso_frame_packet *iso_packet;
|
||||
uint32_t num_of_iso_packets;
|
||||
uint8_t *tmp_buf;
|
||||
uint8_t data_offset;
|
||||
uint32_t data_len;
|
||||
uint8_t header_len = 0;
|
||||
|
||||
num_of_iso_packets = urb->num_of_iso_packets;
|
||||
iso_packet = urb->iso_packet;
|
||||
@@ -512,11 +562,10 @@ void usbh_videostreaming_parse_yuyv2rgb565(struct usbh_urb *urb, struct usbh_vid
|
||||
if (iso_packet[i].actual_length == 0) { /* skip no data */
|
||||
continue;
|
||||
}
|
||||
if (iso_packet[i].actual_length < iso_packet[i].transfer_buffer[0]) { /* do not be illegal */
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
if ((iso_packet[i].transfer_buffer[0] > 12) || (iso_packet[i].transfer_buffer[0] == 0)) { /* do not be illegal */
|
||||
|
||||
header_len = iso_packet[i].transfer_buffer[0];
|
||||
|
||||
if ((header_len > 12) || (header_len == 0)) { /* do not be illegal */
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
@@ -528,10 +577,9 @@ void usbh_videostreaming_parse_yuyv2rgb565(struct usbh_urb *urb, struct usbh_vid
|
||||
data_offset = iso_packet[i].transfer_buffer[0];
|
||||
data_len = iso_packet[i].actual_length - iso_packet[i].transfer_buffer[0];
|
||||
|
||||
tmp_buf = stream->bufbase + stream->bufoffset;
|
||||
usbh_videostreaming_output(&iso_packet[i].transfer_buffer[data_offset], data_len);
|
||||
stream->bufoffset += data_len;
|
||||
|
||||
yuyv2rgb565(&iso_packet[i].transfer_buffer[data_offset], tmp_buf, data_len);
|
||||
if (iso_packet[i].transfer_buffer[1] & (1 << 1)) {
|
||||
if (stream->video_one_frame_callback) {
|
||||
stream->video_one_frame_callback(stream);
|
||||
@@ -541,34 +589,46 @@ void usbh_videostreaming_parse_yuyv2rgb565(struct usbh_urb *urb, struct usbh_vid
|
||||
}
|
||||
}
|
||||
|
||||
const struct usbh_class_driver video_class_ctrl_intf_driver = {
|
||||
.driver_name = "video",
|
||||
.connect = usbh_video_ctrl_intf_connect,
|
||||
.disconnect = usbh_video_ctrl_intf_disconnect
|
||||
__WEAK void usbh_video_run(struct usbh_video *video_class)
|
||||
{
|
||||
}
|
||||
|
||||
__WEAK void usbh_video_stop(struct usbh_video *video_class)
|
||||
{
|
||||
}
|
||||
|
||||
__WEAK void usbh_videostreaming_output(uint8_t *input, uint32_t input_len)
|
||||
{
|
||||
}
|
||||
|
||||
const struct usbh_class_driver video_ctrl_class_driver = {
|
||||
.driver_name = "video_ctrl",
|
||||
.connect = usbh_video_ctrl_connect,
|
||||
.disconnect = usbh_video_ctrl_disconnect
|
||||
};
|
||||
|
||||
const struct usbh_class_driver video_class_data_intf_driver = {
|
||||
.driver_name = "video",
|
||||
.connect = usbh_video_data_intf_connect,
|
||||
.disconnect = usbh_video_data_intf_disconnect
|
||||
const struct usbh_class_driver video_streaming_class_driver = {
|
||||
.driver_name = "video_streaming",
|
||||
.connect = usbh_video_streaming_connect,
|
||||
.disconnect = usbh_video_streaming_disconnect
|
||||
};
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info video_ctrl_intf_class_info = {
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info video_ctrl_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
|
||||
.class = USB_DEVICE_CLASS_VIDEO,
|
||||
.subclass = VIDEO_SC_VIDEOCONTROL,
|
||||
.protocol = VIDEO_PC_PROTOCOL_UNDEFINED,
|
||||
.vid = 0x00,
|
||||
.pid = 0x00,
|
||||
.class_driver = &video_class_ctrl_intf_driver
|
||||
.class_driver = &video_ctrl_class_driver
|
||||
};
|
||||
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info video_data_intf_class_info = {
|
||||
CLASS_INFO_DEFINE const struct usbh_class_info video_streaming_class_info = {
|
||||
.match_flags = USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
|
||||
.class = USB_DEVICE_CLASS_VIDEO,
|
||||
.subclass = VIDEO_SC_VIDEOSTREAMING,
|
||||
.protocol = VIDEO_PC_PROTOCOL_UNDEFINED,
|
||||
.vid = 0x00,
|
||||
.pid = 0x00,
|
||||
.class_driver = &video_class_data_intf_driver
|
||||
};
|
||||
.class_driver = &video_streaming_class_driver
|
||||
};
|
||||
|
||||
@@ -41,6 +41,7 @@ struct usbh_video {
|
||||
uint16_t isoin_mps;
|
||||
uint16_t isoout_mps;
|
||||
bool is_opened;
|
||||
uint8_t current_format;
|
||||
uint16_t bcdVDC;
|
||||
uint8_t num_of_intf_altsettings;
|
||||
uint8_t num_of_formats;
|
||||
@@ -51,19 +52,30 @@ struct usbh_video {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void usbh_video_inityuyv2rgb_table(void);
|
||||
void usbh_video_yuyv2rgb565(void *input, void *output, uint32_t len);
|
||||
|
||||
int usbh_video_get_cur(struct usbh_video *video_class, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len);
|
||||
int usbh_video_set_cur(struct usbh_video *video_class, uint8_t intf, uint8_t entity_id, uint8_t cs, uint8_t *buf, uint16_t len);
|
||||
int usbh_videostreaming_get_cur_probe(struct usbh_video *video_class);
|
||||
int usbh_videostreaming_set_cur_probe(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex, uint32_t dwMaxVideoFrameSize, uint32_t dwMaxPayloadTransferSize);
|
||||
int usbh_videostreaming_set_cur_commit(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex, uint32_t dwMaxVideoFrameSize, uint32_t dwMaxPayloadTransferSize);
|
||||
int usbh_videostreaming_set_cur_probe(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex);
|
||||
int usbh_videostreaming_set_cur_commit(struct usbh_video *video_class, uint8_t formatindex, uint8_t frameindex);
|
||||
|
||||
int usbh_video_open(struct usbh_video *video_class, uint8_t altsetting);
|
||||
int usbh_video_open(struct usbh_video *video_class,
|
||||
uint8_t format_type,
|
||||
uint16_t wWidth,
|
||||
uint16_t wHeight,
|
||||
uint8_t altsetting);
|
||||
int usbh_video_close(struct usbh_video *video_class);
|
||||
|
||||
void usbh_video_list_info(struct usbh_video *video_class);
|
||||
|
||||
void usbh_videostreaming_parse_mjpeg(struct usbh_urb *urb, struct usbh_videostreaming *stream);
|
||||
void usbh_videostreaming_parse_yuyv2rgb565(struct usbh_urb *urb, struct usbh_videostreaming *stream);
|
||||
void usbh_videostreaming_parse_yuyv2(struct usbh_urb *urb, struct usbh_videostreaming *stream);
|
||||
void usbh_videostreaming_output(uint8_t *input, uint32_t input_len);
|
||||
|
||||
void usbh_video_run(struct usbh_video *video_class);
|
||||
void usbh_video_stop(struct usbh_video *video_class);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_rx_buffer[CONFIG_USBDEV_R
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_tx_buffer[CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE + 44];
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t rndis_encapsulated_resp_buffer[CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t NOTIFY_RESPONSE_AVAILABLE[8] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t NOTIFY_RESPONSE_AVAILABLE[8];
|
||||
|
||||
volatile uint8_t *g_rndis_rx_data_buffer;
|
||||
volatile uint32_t g_rndis_rx_data_length;
|
||||
@@ -102,6 +102,8 @@ static int rndis_encapsulated_cmd_handler(uint8_t *data, uint32_t len);
|
||||
|
||||
static void rndis_notify_rsp(void)
|
||||
{
|
||||
memset(NOTIFY_RESPONSE_AVAILABLE, 0, 8);
|
||||
NOTIFY_RESPONSE_AVAILABLE[0] = 0x01;
|
||||
usbd_ep_start_write(rndis_ep_data[RNDIS_INT_EP_IDX].ep_addr, NOTIFY_RESPONSE_AVAILABLE, 8);
|
||||
}
|
||||
|
||||
@@ -469,6 +471,11 @@ void rndis_bulk_in(uint8_t ep, uint32_t nbytes)
|
||||
}
|
||||
}
|
||||
|
||||
void rndis_int_in(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
//USB_LOG_DBG("len:%d\r\n", nbytes);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USBDEV_RNDIS_USING_LWIP
|
||||
#include <lwip/pbuf.h>
|
||||
|
||||
@@ -486,6 +493,7 @@ struct pbuf *usbd_rndis_eth_rx(void)
|
||||
memcpy(p->payload, (uint8_t *)g_rndis_rx_data_buffer, g_rndis_rx_data_length);
|
||||
p->len = g_rndis_rx_data_length;
|
||||
|
||||
USB_LOG_DBG("rxlen:%d\r\n", g_rndis_rx_data_length);
|
||||
g_rndis_rx_data_length = 0;
|
||||
usbd_ep_start_read(rndis_ep_data[RNDIS_OUT_EP_IDX].ep_addr, g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
|
||||
|
||||
@@ -526,13 +534,14 @@ int usbd_rndis_eth_tx(struct pbuf *p)
|
||||
|
||||
g_rndis_tx_data_length = sizeof(rndis_data_packet_t) + p->tot_len;
|
||||
|
||||
USB_LOG_DBG("txlen:%d\r\n", g_rndis_tx_data_length);
|
||||
return usbd_ep_start_write(rndis_ep_data[RNDIS_IN_EP_IDX].ep_addr, g_rndis_tx_buffer, g_rndis_tx_data_length);
|
||||
}
|
||||
#endif
|
||||
struct usbd_interface *usbd_rndis_init_intf(struct usbd_interface *intf,
|
||||
const uint8_t out_ep,
|
||||
const uint8_t in_ep,
|
||||
const uint8_t int_ep, uint8_t mac[6])
|
||||
const uint8_t out_ep,
|
||||
const uint8_t in_ep,
|
||||
const uint8_t int_ep, uint8_t mac[6])
|
||||
{
|
||||
memcpy(usbd_rndis_cfg.mac, mac, 6);
|
||||
|
||||
@@ -541,7 +550,7 @@ struct usbd_interface *usbd_rndis_init_intf(struct usbd_interface *intf,
|
||||
rndis_ep_data[RNDIS_IN_EP_IDX].ep_addr = in_ep;
|
||||
rndis_ep_data[RNDIS_IN_EP_IDX].ep_cb = rndis_bulk_in;
|
||||
rndis_ep_data[RNDIS_INT_EP_IDX].ep_addr = int_ep;
|
||||
rndis_ep_data[RNDIS_INT_EP_IDX].ep_cb = NULL;
|
||||
rndis_ep_data[RNDIS_INT_EP_IDX].ep_cb = rndis_int_in;
|
||||
|
||||
usbd_add_endpoint(&rndis_ep_data[RNDIS_OUT_EP_IDX]);
|
||||
usbd_add_endpoint(&rndis_ep_data[RNDIS_IN_EP_IDX]);
|
||||
|
||||
@@ -13,7 +13,7 @@ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_buf[1024];
|
||||
|
||||
static int usbh_rndis_init_msg_transfer(struct usbh_rndis *rndis_class)
|
||||
{
|
||||
struct usb_setup_packet *setup = &rndis_class->hport->setup;
|
||||
struct usb_setup_packet *setup = rndis_class->hport->setup;
|
||||
int ret = 0;
|
||||
rndis_initialize_msg_t *cmd;
|
||||
rndis_initialize_cmplt_t *resp;
|
||||
@@ -60,7 +60,7 @@ static int usbh_rndis_init_msg_transfer(struct usbh_rndis *rndis_class)
|
||||
|
||||
int usbh_rndis_query_msg_transfer(struct usbh_rndis *rndis_class, uint32_t oid, uint32_t query_len, uint8_t *info, uint32_t *info_len)
|
||||
{
|
||||
struct usb_setup_packet *setup = &rndis_class->hport->setup;
|
||||
struct usb_setup_packet *setup = rndis_class->hport->setup;
|
||||
int ret = 0;
|
||||
rndis_query_msg_t *cmd;
|
||||
rndis_query_cmplt_t *resp;
|
||||
@@ -111,7 +111,7 @@ int usbh_rndis_query_msg_transfer(struct usbh_rndis *rndis_class, uint32_t oid,
|
||||
|
||||
static int usbh_rndis_set_msg_transfer(struct usbh_rndis *rndis_class, uint32_t oid, uint8_t *info, uint32_t info_len)
|
||||
{
|
||||
struct usb_setup_packet *setup = &rndis_class->hport->setup;
|
||||
struct usb_setup_packet *setup = rndis_class->hport->setup;
|
||||
int ret = 0;
|
||||
rndis_set_msg_t *cmd;
|
||||
rndis_set_cmplt_t *resp;
|
||||
@@ -158,9 +158,37 @@ static int usbh_rndis_set_msg_transfer(struct usbh_rndis *rndis_class, uint32_t
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usbh_rndis_bulk_out_transfer(struct usbh_rndis *rndis_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
|
||||
{
|
||||
int ret;
|
||||
struct usbh_urb *urb = &rndis_class->bulkout_urb;
|
||||
memset(urb, 0, sizeof(struct usbh_urb));
|
||||
|
||||
usbh_bulk_urb_fill(urb, rndis_class->bulkout, buffer, buflen, timeout, NULL, NULL);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret == 0) {
|
||||
ret = urb->actual_length;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usbh_rndis_bulk_in_transfer(struct usbh_rndis *rndis_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout)
|
||||
{
|
||||
int ret;
|
||||
struct usbh_urb *urb = &rndis_class->bulkin_urb;
|
||||
memset(urb, 0, sizeof(struct usbh_urb));
|
||||
|
||||
usbh_bulk_urb_fill(urb, rndis_class->bulkin, buffer, buflen, timeout, NULL, NULL);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret == 0) {
|
||||
ret = urb->actual_length;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usbh_rndis_keepalive(struct usbh_rndis *rndis_class)
|
||||
{
|
||||
struct usb_setup_packet *setup = &rndis_class->hport->setup;
|
||||
struct usb_setup_packet *setup = rndis_class->hport->setup;
|
||||
int ret = 0;
|
||||
rndis_keepalive_msg_t *cmd;
|
||||
rndis_keepalive_cmplt_t *resp;
|
||||
@@ -234,7 +262,7 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
ep_cfg.ep_addr = ep_desc->bEndpointAddress;
|
||||
ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
|
||||
ep_cfg.ep_mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
|
||||
;
|
||||
|
||||
ep_cfg.ep_interval = ep_desc->bInterval;
|
||||
ep_cfg.hport = hport;
|
||||
usbh_pipe_alloc(&rndis_class->intin, &ep_cfg);
|
||||
@@ -285,12 +313,19 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
if (ret < 0) {
|
||||
goto query_errorout;
|
||||
}
|
||||
|
||||
memcpy(&rndis_class->link_speed, data, 4);
|
||||
break;
|
||||
case OID_GEN_MEDIA_CONNECT_STATUS:
|
||||
ret = usbh_rndis_query_msg_transfer(rndis_class, OID_GEN_MEDIA_CONNECT_STATUS, 4, data, &data_len);
|
||||
if (ret < 0) {
|
||||
goto query_errorout;
|
||||
}
|
||||
if (NDIS_MEDIA_STATE_CONNECTED == data[0]) {
|
||||
rndis_class->link_status = true;
|
||||
} else {
|
||||
rndis_class->link_status = false;
|
||||
}
|
||||
break;
|
||||
case OID_802_3_MAXIMUM_LIST_SIZE:
|
||||
ret = usbh_rndis_query_msg_transfer(rndis_class, OID_802_3_MAXIMUM_LIST_SIZE, 4, data, &data_len);
|
||||
@@ -303,6 +338,10 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
if (ret < 0) {
|
||||
goto query_errorout;
|
||||
}
|
||||
|
||||
for (uint8_t j = 0; j < 6; j++) {
|
||||
rndis_class->mac[j] = data[j];
|
||||
}
|
||||
break;
|
||||
case OID_802_3_PERMANENT_ADDRESS:
|
||||
ret = usbh_rndis_query_msg_transfer(rndis_class, OID_802_3_PERMANENT_ADDRESS, 6, data, &data_len);
|
||||
@@ -334,6 +373,7 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
strncpy(hport->config.intf[intf].devname, DEV_FORMAT, CONFIG_USBHOST_DEV_NAMELEN);
|
||||
|
||||
USB_LOG_INFO("Register RNDIS Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
usbh_rndis_run(rndis_class);
|
||||
return ret;
|
||||
query_errorout:
|
||||
USB_LOG_ERR("rndis query iod:%08x error\r\n", oid);
|
||||
@@ -354,6 +394,8 @@ static int usbh_rndis_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
if (rndis_class->bulkout) {
|
||||
usbh_pipe_free(rndis_class->bulkout);
|
||||
}
|
||||
|
||||
usbh_rndis_stop(rndis_class);
|
||||
memset(rndis_class, 0, sizeof(struct usbh_rndis));
|
||||
usb_free(rndis_class);
|
||||
|
||||
@@ -364,6 +406,14 @@ static int usbh_rndis_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
||||
return ret;
|
||||
}
|
||||
|
||||
__WEAK void usbh_rndis_run(struct usbh_rndis *rndis_class)
|
||||
{
|
||||
}
|
||||
|
||||
__WEAK void usbh_rndis_stop(struct usbh_rndis *rndis_class)
|
||||
{
|
||||
}
|
||||
|
||||
static const struct usbh_class_driver rndis_class_driver = {
|
||||
.driver_name = "rndis",
|
||||
.connect = usbh_rndis_connect,
|
||||
|
||||
@@ -14,11 +14,15 @@ struct usbh_rndis {
|
||||
uint8_t ctrl_intf; /* Control interface number */
|
||||
uint8_t data_intf; /* Data interface number */
|
||||
|
||||
usbh_pipe_t bulkin; /* Bulk IN endpoint */
|
||||
usbh_pipe_t bulkout; /* Bulk OUT endpoint */
|
||||
usbh_pipe_t intin; /* Notify endpoint */
|
||||
|
||||
usbh_pipe_t bulkin; /* Bulk IN endpoint */
|
||||
usbh_pipe_t bulkout; /* Bulk OUT endpoint */
|
||||
usbh_pipe_t intin; /* Notify endpoint */
|
||||
struct usbh_urb bulkin_urb; /* Bulk IN urb */
|
||||
struct usbh_urb bulkout_urb; /* Bulk OUT urb */
|
||||
uint32_t request_id;
|
||||
|
||||
uint32_t link_speed;
|
||||
bool link_status;
|
||||
uint8_t mac[6];
|
||||
};
|
||||
|
||||
@@ -26,8 +30,14 @@ struct usbh_rndis {
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int usbh_rndis_bulk_out_transfer(struct usbh_rndis *rndis_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout);
|
||||
int usbh_rndis_bulk_in_transfer(struct usbh_rndis *rndis_class, uint8_t *buffer, uint32_t buflen, uint32_t timeout);
|
||||
|
||||
int usbh_rndis_keepalive(struct usbh_rndis *rndis_class);
|
||||
|
||||
void usbh_rndis_run(struct usbh_rndis *rndis_class);
|
||||
void usbh_rndis_stop(struct usbh_rndis *rndis_class);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -21,6 +21,7 @@ struct usbd_endpoint_cfg {
|
||||
uint8_t ep_addr; /* Endpoint addr with direction */
|
||||
uint8_t ep_type; /* Endpoint type */
|
||||
uint16_t ep_mps; /* Endpoint max packet size */
|
||||
uint8_t ep_mult; /* Endpoint additional transcations in micro frame */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -44,6 +45,15 @@ int usb_dc_deinit(void);
|
||||
*/
|
||||
int usbd_set_address(const uint8_t addr);
|
||||
|
||||
/**
|
||||
* @brief Get USB device speed
|
||||
*
|
||||
* @param[in] port port index
|
||||
*
|
||||
* @return port speed, USB_SPEED_LOW or USB_SPEED_FULL or USB_SPEED_HIGH
|
||||
*/
|
||||
uint8_t usbd_get_port_speed(const uint8_t port);
|
||||
|
||||
/**
|
||||
* @brief configure and enable endpoint.
|
||||
*
|
||||
|
||||
@@ -607,6 +607,12 @@ struct usb_webusb_url_descriptor {
|
||||
char URL[];
|
||||
} __PACKED;
|
||||
|
||||
struct usb_webusb_url_ex_descriptor {
|
||||
uint8_t vendor_code;
|
||||
uint8_t *string;
|
||||
uint32_t string_len;
|
||||
} __PACKED;
|
||||
|
||||
struct usb_bos_descriptor {
|
||||
uint8_t *string;
|
||||
uint32_t string_len;
|
||||
|
||||
@@ -56,6 +56,7 @@ struct usbh_urb {
|
||||
uint32_t timeout;
|
||||
int errorcode;
|
||||
uint32_t num_of_iso_packets;
|
||||
uint32_t start_frame;
|
||||
usbh_complete_callback_t complete;
|
||||
void *arg;
|
||||
struct usbh_iso_frame_packet iso_packet[0];
|
||||
@@ -68,6 +69,12 @@ struct usbh_urb {
|
||||
*/
|
||||
int usb_hc_init(void);
|
||||
|
||||
/**
|
||||
* @brief Get frame number.
|
||||
*
|
||||
* @return frame number.
|
||||
*/
|
||||
uint16_t usbh_get_frame_number(void);
|
||||
/**
|
||||
* @brief control roothub.
|
||||
*
|
||||
|
||||
@@ -44,12 +44,12 @@
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#elif defined(__ICCARM__)
|
||||
#elif defined(__ICCARM__) || defined(__ICCRX__)
|
||||
#ifndef __USED
|
||||
#if __ICCARM_V8
|
||||
#define __USED __attribute__((used))
|
||||
#else
|
||||
#define __USED _Pragma("__root")
|
||||
#define __USED __root
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
451
core/usbd_core.c
451
core/usbd_core.c
@@ -6,6 +6,9 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#if defined(CONFIG_USBDEV_TX_THREAD) || defined(CONFIG_USBDEV_RX_THREAD)
|
||||
#include "usb_osal.h"
|
||||
#endif
|
||||
|
||||
/* general descriptor field offsets */
|
||||
#define DESC_bLength 0 /** Length offset */
|
||||
@@ -23,6 +26,12 @@
|
||||
#define USB_EP_OUT_NUM 8
|
||||
#define USB_EP_IN_NUM 8
|
||||
|
||||
struct usbd_tx_rx_msg {
|
||||
uint8_t ep;
|
||||
uint32_t nbytes;
|
||||
usbd_endpoint_callback cb;
|
||||
};
|
||||
|
||||
USB_NOCACHE_RAM_SECTION struct usbd_core_cfg_priv {
|
||||
/** Setup packet */
|
||||
USB_MEM_ALIGNX struct usb_setup_packet setup;
|
||||
@@ -35,17 +44,19 @@ USB_NOCACHE_RAM_SECTION struct usbd_core_cfg_priv {
|
||||
/** Zero length packet flag of control transfer */
|
||||
bool zlp_flag;
|
||||
/** Pointer to registered descriptors */
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
struct usb_descriptor *descriptors;
|
||||
#else
|
||||
const uint8_t *descriptors;
|
||||
#endif
|
||||
/* Buffer used for storing standard, class and vendor request data */
|
||||
USB_MEM_ALIGNX uint8_t req_data[CONFIG_USBDEV_REQUEST_BUFFER_LEN];
|
||||
|
||||
usbd_endpoint_callback in_ep_cb[USB_EP_IN_NUM];
|
||||
usbd_endpoint_callback out_ep_cb[USB_EP_OUT_NUM];
|
||||
|
||||
/** Variable to check whether the usb has been configured */
|
||||
bool configured;
|
||||
/** Currently selected configuration */
|
||||
uint8_t configuration;
|
||||
uint8_t speed;
|
||||
#ifdef CONFIG_USBDEV_TEST_MODE
|
||||
bool test_mode;
|
||||
#endif
|
||||
@@ -58,6 +69,18 @@ static struct usb_msosv1_descriptor *msosv1_desc;
|
||||
static struct usb_msosv2_descriptor *msosv2_desc;
|
||||
static struct usb_bos_descriptor *bos_desc;
|
||||
|
||||
struct usbd_tx_rx_msg tx_msg[USB_EP_IN_NUM];
|
||||
struct usbd_tx_rx_msg rx_msg[USB_EP_OUT_NUM];
|
||||
|
||||
#if defined(CONFIG_USBDEV_TX_THREAD)
|
||||
usb_osal_mq_t usbd_tx_mq;
|
||||
usb_osal_thread_t usbd_tx_thread;
|
||||
#endif
|
||||
#if defined(CONFIG_USBDEV_RX_THREAD)
|
||||
usb_osal_mq_t usbd_rx_mq;
|
||||
usb_osal_thread_t usbd_rx_thread;
|
||||
#endif
|
||||
|
||||
static void usbd_class_event_notify_handler(uint8_t event, void *arg);
|
||||
|
||||
static void usbd_print_setup(struct usb_setup_packet *setup)
|
||||
@@ -94,7 +117,7 @@ static bool usbd_set_endpoint(const struct usb_endpoint_descriptor *ep_desc)
|
||||
ep_cfg.ep_mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
|
||||
ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
|
||||
|
||||
USB_LOG_INFO("Open endpoint:0x%x type:%u mps:%u\r\n",
|
||||
USB_LOG_INFO("Open ep:0x%02x type:%u mps:%u\r\n",
|
||||
ep_cfg.ep_addr, ep_cfg.ep_type, ep_cfg.ep_mps);
|
||||
|
||||
return usbd_ep_open(&ep_cfg) == 0 ? true : false;
|
||||
@@ -117,7 +140,7 @@ static bool usbd_reset_endpoint(const struct usb_endpoint_descriptor *ep_desc)
|
||||
ep_cfg.ep_mps = ep_desc->wMaxPacketSize & USB_MAXPACKETSIZE_MASK;
|
||||
ep_cfg.ep_type = ep_desc->bmAttributes & USB_ENDPOINT_TYPE_MASK;
|
||||
|
||||
USB_LOG_INFO("Close endpoint:0x%x type:%u\r\n",
|
||||
USB_LOG_INFO("Close ep:0x%02x type:%u\r\n",
|
||||
ep_cfg.ep_addr, ep_cfg.ep_type);
|
||||
|
||||
return usbd_ep_close(ep_cfg.ep_addr) == 0 ? true : false;
|
||||
@@ -135,6 +158,119 @@ static bool usbd_reset_endpoint(const struct usb_endpoint_descriptor *ep_desc)
|
||||
*
|
||||
* @return true if the descriptor was found, false otherwise
|
||||
*/
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static bool usbd_get_descriptor(uint16_t type_index, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
uint8_t type = 0U;
|
||||
uint8_t index = 0U;
|
||||
bool found = true;
|
||||
uint8_t str_len = 0;
|
||||
|
||||
type = HI_BYTE(type_index);
|
||||
index = LO_BYTE(type_index);
|
||||
|
||||
switch (type) {
|
||||
case USB_DESCRIPTOR_TYPE_DEVICE:
|
||||
*data = (uint8_t *)usbd_core_cfg.descriptors->device_descriptor;
|
||||
*len = usbd_core_cfg.descriptors->device_descriptor[0];
|
||||
break;
|
||||
case USB_DESCRIPTOR_TYPE_CONFIGURATION:
|
||||
usbd_core_cfg.speed = usbd_get_port_speed(0);
|
||||
if (usbd_core_cfg.speed == USB_SPEED_HIGH) {
|
||||
if (usbd_core_cfg.descriptors->hs_config_descriptor) {
|
||||
*data = (uint8_t *)usbd_core_cfg.descriptors->hs_config_descriptor;
|
||||
*len = (usbd_core_cfg.descriptors->hs_config_descriptor[CONF_DESC_wTotalLength] |
|
||||
(usbd_core_cfg.descriptors->hs_config_descriptor[CONF_DESC_wTotalLength + 1] << 8));
|
||||
} else {
|
||||
found = false;
|
||||
}
|
||||
} else {
|
||||
if (usbd_core_cfg.descriptors->fs_config_descriptor) {
|
||||
*data = (uint8_t *)usbd_core_cfg.descriptors->fs_config_descriptor;
|
||||
*len = (usbd_core_cfg.descriptors->fs_config_descriptor[CONF_DESC_wTotalLength] |
|
||||
(usbd_core_cfg.descriptors->fs_config_descriptor[CONF_DESC_wTotalLength + 1] << 8));
|
||||
} else {
|
||||
found = false;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case USB_DESCRIPTOR_TYPE_STRING:
|
||||
if (index == USB_STRING_LANGID_INDEX) {
|
||||
(*data)[0] = 0x04;
|
||||
(*data)[1] = 0x03;
|
||||
(*data)[2] = 0x09;
|
||||
(*data)[3] = 0x04;
|
||||
*len = 4;
|
||||
} else if (index == USB_OSDESC_STRING_DESC_INDEX) {
|
||||
if (usbd_core_cfg.descriptors->msosv1_descriptor) {
|
||||
USB_LOG_INFO("read MS OS 1.0 descriptor string\r\n");
|
||||
*data = usbd_core_cfg.descriptors->msosv1_descriptor->string;
|
||||
*len = usbd_core_cfg.descriptors->msosv1_descriptor->string_len;
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
if (usbd_core_cfg.descriptors->string_descriptor[index - 1]) {
|
||||
str_len = strlen((const char *)usbd_core_cfg.descriptors->string_descriptor[index - 1]);
|
||||
|
||||
(*data)[0] = str_len * 2 + 2;
|
||||
(*data)[1] = 0x03;
|
||||
for (uint16_t i = 0; i < str_len; i++) {
|
||||
(*data)[i * 2 + 2] = usbd_core_cfg.descriptors->string_descriptor[index - 1][i];
|
||||
(*data)[i * 2 + 3] = 0;
|
||||
}
|
||||
|
||||
*len = str_len * 2 + 2;
|
||||
} else {
|
||||
found = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER:
|
||||
if (usbd_core_cfg.descriptors->device_quality_descriptor) {
|
||||
*data = (uint8_t *)usbd_core_cfg.descriptors->device_quality_descriptor;
|
||||
*len = usbd_core_cfg.descriptors->device_quality_descriptor[0];
|
||||
} else {
|
||||
found = false;
|
||||
}
|
||||
|
||||
break;
|
||||
case USB_DESCRIPTOR_TYPE_OTHER_SPEED:
|
||||
if (usbd_core_cfg.speed == USB_SPEED_HIGH) {
|
||||
if (usbd_core_cfg.descriptors->fs_other_speed_descriptor) {
|
||||
*data = (uint8_t *)usbd_core_cfg.descriptors->fs_other_speed_descriptor;
|
||||
*len = (usbd_core_cfg.descriptors->fs_other_speed_descriptor[CONF_DESC_wTotalLength] |
|
||||
(usbd_core_cfg.descriptors->fs_other_speed_descriptor[CONF_DESC_wTotalLength] << 8));
|
||||
} else {
|
||||
found = false;
|
||||
}
|
||||
} else {
|
||||
if (usbd_core_cfg.descriptors->hs_other_speed_descriptor) {
|
||||
*data = (uint8_t *)usbd_core_cfg.descriptors->hs_other_speed_descriptor;
|
||||
*len = (usbd_core_cfg.descriptors->hs_other_speed_descriptor[CONF_DESC_wTotalLength] |
|
||||
(usbd_core_cfg.descriptors->hs_other_speed_descriptor[CONF_DESC_wTotalLength] << 8));
|
||||
} else {
|
||||
found = false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case USB_DESCRIPTOR_TYPE_BINARY_OBJECT_STORE:
|
||||
USB_LOG_INFO("read BOS descriptor string\r\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (found == false) {
|
||||
/* nothing found */
|
||||
USB_LOG_ERR("descriptor <type:%x,index:%x> not found!\r\n", type, index);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
#else
|
||||
static bool usbd_get_descriptor(uint16_t type_index, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
uint8_t type = 0U;
|
||||
@@ -200,9 +336,6 @@ static bool usbd_get_descriptor(uint16_t type_index, uint8_t **data, uint32_t *l
|
||||
}
|
||||
|
||||
if (found) {
|
||||
/* found descriptor, save descriptor premiere address */
|
||||
*data = p;
|
||||
|
||||
if ((type == USB_DESCRIPTOR_TYPE_CONFIGURATION) || ((type == USB_DESCRIPTOR_TYPE_OTHER_SPEED))) {
|
||||
/* configuration or other speed descriptor is an
|
||||
* exception, length is at offset 2 and 3
|
||||
@@ -213,6 +346,7 @@ static bool usbd_get_descriptor(uint16_t type_index, uint8_t **data, uint32_t *l
|
||||
/* normally length is at offset 0 */
|
||||
*len = p[DESC_bLength];
|
||||
}
|
||||
memcpy(*data, p, *len);
|
||||
} else {
|
||||
/* nothing found */
|
||||
USB_LOG_ERR("descriptor <type:%x,index:%x> not found!\r\n", type, index);
|
||||
@@ -220,6 +354,7 @@ static bool usbd_get_descriptor(uint16_t type_index, uint8_t **data, uint32_t *l
|
||||
|
||||
return found;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief set USB configuration
|
||||
@@ -235,11 +370,19 @@ static bool usbd_get_descriptor(uint16_t type_index, uint8_t **data, uint32_t *l
|
||||
*/
|
||||
static bool usbd_set_configuration(uint8_t config_index, uint8_t alt_setting)
|
||||
{
|
||||
uint8_t *p = (uint8_t *)usbd_core_cfg.descriptors;
|
||||
uint8_t cur_alt_setting = 0xFF;
|
||||
uint8_t cur_config = 0xFF;
|
||||
bool found = false;
|
||||
|
||||
uint8_t *p;
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
if (usbd_core_cfg.speed == USB_SPEED_HIGH) {
|
||||
p = (uint8_t *)usbd_core_cfg.descriptors->hs_config_descriptor;
|
||||
} else {
|
||||
p = (uint8_t *)usbd_core_cfg.descriptors->fs_config_descriptor;
|
||||
}
|
||||
#else
|
||||
p = (uint8_t *)usbd_core_cfg.descriptors;
|
||||
#endif
|
||||
/* configure endpoints for this configuration/altsetting */
|
||||
while (p[DESC_bLength] != 0U) {
|
||||
switch (p[DESC_bDescriptorType]) {
|
||||
@@ -289,13 +432,21 @@ static bool usbd_set_configuration(uint8_t config_index, uint8_t alt_setting)
|
||||
*/
|
||||
static bool usbd_set_interface(uint8_t iface, uint8_t alt_setting)
|
||||
{
|
||||
const uint8_t *p = usbd_core_cfg.descriptors;
|
||||
const uint8_t *if_desc = NULL;
|
||||
struct usb_endpoint_descriptor *ep_desc;
|
||||
uint8_t cur_alt_setting = 0xFF;
|
||||
uint8_t cur_iface = 0xFF;
|
||||
bool ret = false;
|
||||
|
||||
uint8_t *p;
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
if (usbd_core_cfg.speed == USB_SPEED_HIGH) {
|
||||
p = (uint8_t *)usbd_core_cfg.descriptors->hs_config_descriptor;
|
||||
} else {
|
||||
p = (uint8_t *)usbd_core_cfg.descriptors->fs_config_descriptor;
|
||||
}
|
||||
#else
|
||||
p = (uint8_t *)usbd_core_cfg.descriptors;
|
||||
#endif
|
||||
USB_LOG_DBG("iface %u alt_setting %u\r\n", iface, alt_setting);
|
||||
|
||||
while (p[DESC_bLength] != 0U) {
|
||||
@@ -638,6 +789,53 @@ static int usbd_class_request_handler(struct usb_setup_packet *setup, uint8_t **
|
||||
*/
|
||||
static int usbd_vendor_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
if (usbd_core_cfg.descriptors->msosv1_descriptor) {
|
||||
if (setup->bRequest == usbd_core_cfg.descriptors->msosv1_descriptor->vendor_code) {
|
||||
switch (setup->wIndex) {
|
||||
case 0x04:
|
||||
USB_LOG_INFO("get Compat ID\r\n");
|
||||
*data = (uint8_t *)usbd_core_cfg.descriptors->msosv1_descriptor->compat_id;
|
||||
*len = usbd_core_cfg.descriptors->msosv1_descriptor->compat_id_len;
|
||||
return 0;
|
||||
case 0x05:
|
||||
USB_LOG_INFO("get Compat id properties\r\n");
|
||||
*data = (uint8_t *)usbd_core_cfg.descriptors->msosv1_descriptor->comp_id_property;
|
||||
*len = usbd_core_cfg.descriptors->msosv1_descriptor->comp_id_property_len;
|
||||
return 0;
|
||||
default:
|
||||
USB_LOG_ERR("unknown vendor code\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else if (usbd_core_cfg.descriptors->msosv2_descriptor) {
|
||||
if (setup->bRequest == usbd_core_cfg.descriptors->msosv2_descriptor->vendor_code) {
|
||||
switch (setup->wIndex) {
|
||||
case WINUSB_REQUEST_GET_DESCRIPTOR_SET:
|
||||
USB_LOG_INFO("GET MS OS 2.0 Descriptor\r\n");
|
||||
*data = (uint8_t *)usbd_core_cfg.descriptors->msosv2_descriptor->compat_id;
|
||||
*len = usbd_core_cfg.descriptors->msosv2_descriptor->compat_id_len;
|
||||
return 0;
|
||||
default:
|
||||
USB_LOG_ERR("unknown vendor code\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else if (usbd_core_cfg.descriptors->webusb_url_descriptor) {
|
||||
if (setup->bRequest == usbd_core_cfg.descriptors->webusb_url_descriptor->vendor_code) {
|
||||
switch (setup->wIndex) {
|
||||
case WINUSB_REQUEST_GET_DESCRIPTOR_SET:
|
||||
USB_LOG_INFO("GET Webusb url Descriptor\r\n");
|
||||
*data = (uint8_t *)usbd_core_cfg.descriptors->webusb_url_descriptor->string;
|
||||
*len = usbd_core_cfg.descriptors->webusb_url_descriptor->string_len;
|
||||
return 0;
|
||||
default:
|
||||
USB_LOG_ERR("unknown vendor code\r\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (msosv1_desc) {
|
||||
if (setup->bRequest == msosv1_desc->vendor_code) {
|
||||
switch (setup->wIndex) {
|
||||
@@ -672,7 +870,7 @@ static int usbd_vendor_request_handler(struct usb_setup_packet *setup, uint8_t *
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
usb_slist_t *i;
|
||||
|
||||
usb_slist_for_each(i, &usbd_intf_head)
|
||||
@@ -701,6 +899,12 @@ static bool usbd_setup_request_handler(struct usb_setup_packet *setup, uint8_t *
|
||||
switch (setup->bmRequestType & USB_REQUEST_TYPE_MASK) {
|
||||
case USB_REQUEST_STANDARD:
|
||||
if (usbd_standard_request_handler(setup, data, len) < 0) {
|
||||
#ifndef CONFIG_USB_HS
|
||||
if ((setup->bRequest == 0x06) && (setup->wValue = 0x0600)) {
|
||||
USB_LOG_WRN("Ignore DQD in fs\r\n"); /* Device Qualifier Descriptor */
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
USB_LOG_ERR("standard request error\r\n");
|
||||
usbd_print_setup(setup);
|
||||
return false;
|
||||
@@ -766,6 +970,7 @@ void usbd_event_reset_handler(void)
|
||||
usbd_set_address(0);
|
||||
usbd_core_cfg.configured = 0;
|
||||
usbd_core_cfg.configuration = 0;
|
||||
|
||||
#ifdef CONFIG_USBDEV_TEST_MODE
|
||||
usbd_core_cfg.test_mode = false;
|
||||
#endif
|
||||
@@ -823,26 +1028,18 @@ void usbd_event_ep0_setup_complete_handler(uint8_t *psetup)
|
||||
}
|
||||
#endif
|
||||
/* Send smallest of requested and offered length */
|
||||
usbd_core_cfg.ep0_data_buf_residue = MIN(usbd_core_cfg.ep0_data_buf_len,
|
||||
setup->wLength);
|
||||
|
||||
/* check if the data buf addr matches align size,if not, copy into align buf */
|
||||
#ifndef CONFIG_USBDEV_ALIGN_CHECK_DISABLE
|
||||
if (((unsigned long)usbd_core_cfg.ep0_data_buf) & (CONFIG_USB_ALIGN_SIZE - 1)) {
|
||||
if (usbd_core_cfg.ep0_data_buf_residue > CONFIG_USBDEV_REQUEST_BUFFER_LEN) {
|
||||
USB_LOG_ERR("Request buffer too small\r\n");
|
||||
return;
|
||||
}
|
||||
/* copy data buf from misalignx addr to alignx addr */
|
||||
memcpy(usbd_core_cfg.req_data, usbd_core_cfg.ep0_data_buf, usbd_core_cfg.ep0_data_buf_residue);
|
||||
usbd_core_cfg.ep0_data_buf = usbd_core_cfg.req_data;
|
||||
usbd_core_cfg.ep0_data_buf_residue = MIN(usbd_core_cfg.ep0_data_buf_len, setup->wLength);
|
||||
if (usbd_core_cfg.ep0_data_buf_residue > CONFIG_USBDEV_REQUEST_BUFFER_LEN) {
|
||||
USB_LOG_ERR("Request buffer too small\r\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Send data or status to host */
|
||||
usbd_ep_start_write(USB_CONTROL_IN_EP0, usbd_core_cfg.ep0_data_buf, usbd_core_cfg.ep0_data_buf_residue);
|
||||
/*
|
||||
* Set ZLP flag when host asks for a bigger length and the data size is multiplier of USB_CTRL_EP_MPS,
|
||||
* to indicate the transfer done after zlp sent.
|
||||
* Set ZLP flag when host asks for a bigger length and the data size is
|
||||
* multiplier of USB_CTRL_EP_MPS, to indicate the transfer done after zlp
|
||||
* sent.
|
||||
*/
|
||||
if ((setup->wLength > usbd_core_cfg.ep0_data_buf_len) && (!(usbd_core_cfg.ep0_data_buf_len % USB_CTRL_EP_MPS))) {
|
||||
usbd_core_cfg.zlp_flag = true;
|
||||
@@ -850,84 +1047,149 @@ void usbd_event_ep0_setup_complete_handler(uint8_t *psetup)
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_event_ep_in_complete_handler(uint8_t ep, uint32_t nbytes)
|
||||
void usbd_event_ep0_in_complete_handler(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
if (ep == USB_CONTROL_IN_EP0) {
|
||||
struct usb_setup_packet *setup = &usbd_core_cfg.setup;
|
||||
struct usb_setup_packet *setup = &usbd_core_cfg.setup;
|
||||
|
||||
usbd_core_cfg.ep0_data_buf += nbytes;
|
||||
usbd_core_cfg.ep0_data_buf_residue -= nbytes;
|
||||
usbd_core_cfg.ep0_data_buf += nbytes;
|
||||
usbd_core_cfg.ep0_data_buf_residue -= nbytes;
|
||||
|
||||
USB_LOG_DBG("EP0 send %d bytes, %d remained\r\n", nbytes, usbd_core_cfg.ep0_data_buf_residue);
|
||||
USB_LOG_DBG("EP0 send %d bytes, %d remained\r\n", nbytes, usbd_core_cfg.ep0_data_buf_residue);
|
||||
|
||||
if (usbd_core_cfg.ep0_data_buf_residue != 0) {
|
||||
/* Start sending the remain data */
|
||||
usbd_ep_start_write(USB_CONTROL_IN_EP0, usbd_core_cfg.ep0_data_buf, usbd_core_cfg.ep0_data_buf_residue);
|
||||
if (usbd_core_cfg.ep0_data_buf_residue != 0) {
|
||||
/* Start sending the remain data */
|
||||
usbd_ep_start_write(USB_CONTROL_IN_EP0, usbd_core_cfg.ep0_data_buf, usbd_core_cfg.ep0_data_buf_residue);
|
||||
} else {
|
||||
if (usbd_core_cfg.zlp_flag == true) {
|
||||
usbd_core_cfg.zlp_flag = false;
|
||||
/* Send zlp to host */
|
||||
USB_LOG_DBG("EP0 Send zlp\r\n");
|
||||
usbd_ep_start_write(USB_CONTROL_IN_EP0, NULL, 0);
|
||||
} else {
|
||||
if (usbd_core_cfg.zlp_flag == true) {
|
||||
usbd_core_cfg.zlp_flag = false;
|
||||
/* Send zlp to host */
|
||||
USB_LOG_DBG("EP0 Send zlp\r\n");
|
||||
usbd_ep_start_write(USB_CONTROL_IN_EP0, NULL, 0);
|
||||
} else {
|
||||
/* Satisfying three conditions will jump here.
|
||||
/* Satisfying three conditions will jump here.
|
||||
* 1. send status completely
|
||||
* 2. send zlp completely
|
||||
* 3. send last data completely.
|
||||
*/
|
||||
if (setup->wLength && ((setup->bmRequestType & USB_REQUEST_DIR_MASK) == USB_REQUEST_DIR_IN)) {
|
||||
/* if all data has sent completely, start reading out status */
|
||||
usbd_ep_start_read(USB_CONTROL_OUT_EP0, NULL, 0);
|
||||
}
|
||||
if (setup->wLength && ((setup->bmRequestType & USB_REQUEST_DIR_MASK) == USB_REQUEST_DIR_IN)) {
|
||||
/* if all data has sent completely, start reading out status */
|
||||
usbd_ep_start_read(USB_CONTROL_OUT_EP0, NULL, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (usbd_core_cfg.in_ep_cb[ep & 0x7f]) {
|
||||
usbd_core_cfg.in_ep_cb[ep & 0x7f](ep, nbytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_event_ep0_out_complete_handler(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
struct usb_setup_packet *setup = &usbd_core_cfg.setup;
|
||||
|
||||
if (nbytes > 0) {
|
||||
usbd_core_cfg.ep0_data_buf += nbytes;
|
||||
usbd_core_cfg.ep0_data_buf_residue -= nbytes;
|
||||
|
||||
USB_LOG_DBG("EP0 recv %d bytes, %d remained\r\n", nbytes, usbd_core_cfg.ep0_data_buf_residue);
|
||||
|
||||
if (usbd_core_cfg.ep0_data_buf_residue == 0) {
|
||||
/* Received all, send data to handler */
|
||||
usbd_core_cfg.ep0_data_buf = usbd_core_cfg.req_data;
|
||||
if (!usbd_setup_request_handler(setup, &usbd_core_cfg.ep0_data_buf, &usbd_core_cfg.ep0_data_buf_len)) {
|
||||
usbd_ep_set_stall(USB_CONTROL_IN_EP0);
|
||||
return;
|
||||
}
|
||||
|
||||
/*Send status to host*/
|
||||
usbd_ep_start_write(USB_CONTROL_IN_EP0, NULL, 0);
|
||||
} else {
|
||||
/* Start reading the remain data */
|
||||
usbd_ep_start_read(USB_CONTROL_OUT_EP0, usbd_core_cfg.ep0_data_buf, usbd_core_cfg.ep0_data_buf_residue);
|
||||
}
|
||||
} else {
|
||||
/* Read out status completely, do nothing */
|
||||
USB_LOG_DBG("EP0 recv out status\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_event_ep_in_complete_handler(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
#ifndef CONFIG_USBDEV_TX_THREAD
|
||||
if (tx_msg[ep & 0x7f].cb) {
|
||||
tx_msg[ep & 0x7f].cb(ep, nbytes);
|
||||
}
|
||||
#else
|
||||
tx_msg[ep & 0x7f].nbytes = nbytes;
|
||||
usb_osal_mq_send(usbd_tx_mq, (uint32_t)&tx_msg[ep & 0x7f]);
|
||||
#endif
|
||||
}
|
||||
|
||||
void usbd_event_ep_out_complete_handler(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
if (ep == USB_CONTROL_OUT_EP0) {
|
||||
struct usb_setup_packet *setup = &usbd_core_cfg.setup;
|
||||
#ifndef CONFIG_USBDEV_RX_THREAD
|
||||
if (rx_msg[ep & 0x7f].cb) {
|
||||
rx_msg[ep & 0x7f].cb(ep, nbytes);
|
||||
}
|
||||
#else
|
||||
rx_msg[ep & 0x7f].nbytes = nbytes;
|
||||
usb_osal_mq_send(usbd_rx_mq, (uint32_t)&rx_msg[ep & 0x7f]);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (nbytes > 0) {
|
||||
usbd_core_cfg.ep0_data_buf += nbytes;
|
||||
usbd_core_cfg.ep0_data_buf_residue -= nbytes;
|
||||
#ifdef CONFIG_USBDEV_TX_THREAD
|
||||
static void usbdev_tx_thread(void *argument)
|
||||
{
|
||||
struct usbd_tx_rx_msg *msg;
|
||||
int ret;
|
||||
|
||||
USB_LOG_DBG("EP0 recv %d bytes, %d remained\r\n", nbytes, usbd_core_cfg.ep0_data_buf_residue);
|
||||
|
||||
if (usbd_core_cfg.ep0_data_buf_residue == 0) {
|
||||
/* Received all, send data to handler */
|
||||
usbd_core_cfg.ep0_data_buf = usbd_core_cfg.req_data;
|
||||
if (!usbd_setup_request_handler(setup, &usbd_core_cfg.ep0_data_buf, &usbd_core_cfg.ep0_data_buf_len)) {
|
||||
usbd_ep_set_stall(USB_CONTROL_IN_EP0);
|
||||
return;
|
||||
}
|
||||
|
||||
/*Send status to host*/
|
||||
usbd_ep_start_write(USB_CONTROL_IN_EP0, NULL, 0);
|
||||
} else {
|
||||
/* Start reading the remain data */
|
||||
usbd_ep_start_read(USB_CONTROL_OUT_EP0, usbd_core_cfg.ep0_data_buf, usbd_core_cfg.ep0_data_buf_residue);
|
||||
}
|
||||
} else {
|
||||
/* Read out status completely, do nothing */
|
||||
USB_LOG_DBG("EP0 recv out status\r\n");
|
||||
while (1) {
|
||||
ret = usb_osal_mq_recv(usbd_tx_mq, (uint32_t *)&msg, 0xffffffff);
|
||||
if (ret < 0) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (usbd_core_cfg.out_ep_cb[ep & 0x7f]) {
|
||||
usbd_core_cfg.out_ep_cb[ep & 0x7f](ep, nbytes);
|
||||
|
||||
if (msg->cb) {
|
||||
msg->cb(msg->ep, msg->nbytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_RX_THREAD
|
||||
static void usbdev_rx_thread(void *argument)
|
||||
{
|
||||
struct usbd_tx_rx_msg *msg;
|
||||
int ret;
|
||||
|
||||
while (1) {
|
||||
ret = usb_osal_mq_recv(usbd_rx_mq, (uint32_t *)&msg, 0xffffffff);
|
||||
if (ret < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (msg->cb) {
|
||||
msg->cb(msg->ep, msg->nbytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
void usbd_desc_register(struct usb_descriptor *desc)
|
||||
{
|
||||
usbd_core_cfg.descriptors = desc;
|
||||
usbd_core_cfg.intf_offset = 0;
|
||||
tx_msg[0].ep = 0x80;
|
||||
tx_msg[0].cb = usbd_event_ep0_in_complete_handler;
|
||||
rx_msg[0].ep = 0x00;
|
||||
rx_msg[0].cb = usbd_event_ep0_out_complete_handler;
|
||||
}
|
||||
#else
|
||||
void usbd_desc_register(const uint8_t *desc)
|
||||
{
|
||||
usbd_core_cfg.descriptors = desc;
|
||||
usbd_core_cfg.intf_offset = 0;
|
||||
tx_msg[0].ep = 0x80;
|
||||
tx_msg[0].cb = usbd_event_ep0_in_complete_handler;
|
||||
rx_msg[0].ep = 0x00;
|
||||
rx_msg[0].cb = usbd_event_ep0_out_complete_handler;
|
||||
}
|
||||
|
||||
/* Register MS OS Descriptors version 1 */
|
||||
@@ -946,6 +1208,7 @@ void usbd_bos_desc_register(struct usb_bos_descriptor *desc)
|
||||
{
|
||||
bos_desc = desc;
|
||||
}
|
||||
#endif
|
||||
|
||||
void usbd_add_interface(struct usbd_interface *intf)
|
||||
{
|
||||
@@ -957,9 +1220,11 @@ void usbd_add_interface(struct usbd_interface *intf)
|
||||
void usbd_add_endpoint(struct usbd_endpoint *ep)
|
||||
{
|
||||
if (ep->ep_addr & 0x80) {
|
||||
usbd_core_cfg.in_ep_cb[ep->ep_addr & 0x7f] = ep->ep_cb;
|
||||
tx_msg[ep->ep_addr & 0x7f].ep = ep->ep_addr;
|
||||
tx_msg[ep->ep_addr & 0x7f].cb = ep->ep_cb;
|
||||
} else {
|
||||
usbd_core_cfg.out_ep_cb[ep->ep_addr & 0x7f] = ep->ep_cb;
|
||||
rx_msg[ep->ep_addr & 0x7f].ep = ep->ep_addr;
|
||||
rx_msg[ep->ep_addr & 0x7f].cb = ep->ep_cb;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -970,6 +1235,26 @@ bool usb_device_is_configured(void)
|
||||
|
||||
int usbd_initialize(void)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_TX_THREAD
|
||||
usbd_tx_mq = usb_osal_mq_create(16);
|
||||
if (usbd_tx_mq == NULL) {
|
||||
return -1;
|
||||
}
|
||||
usbd_tx_thread = usb_osal_thread_create("usbd_tx", CONFIG_USBDEV_TX_STACKSIZE, CONFIG_USBDEV_TX_PRIO, usbdev_tx_thread, NULL);
|
||||
if (usbd_tx_thread == NULL) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_USBDEV_RX_THREAD
|
||||
usbd_rx_mq = usb_osal_mq_create(16);
|
||||
if (usbd_rx_mq == NULL) {
|
||||
return -1;
|
||||
}
|
||||
usbd_rx_thread = usb_osal_thread_create("usbd_rx", CONFIG_USBDEV_RX_STACKSIZE, CONFIG_USBDEV_RX_PRIO, usbdev_rx_thread, NULL);
|
||||
if (usbd_rx_thread == NULL) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return usb_dc_init();
|
||||
}
|
||||
|
||||
@@ -978,5 +1263,7 @@ int usbd_deinitialize(void)
|
||||
usbd_core_cfg.intf_offset = 0;
|
||||
usb_slist_init(&usbd_intf_head);
|
||||
usb_dc_deinit();
|
||||
#if defined(CONFIG_USBDEV_TX_THREAD) || defined(CONFIG_USBDEV_RX_THREAD)
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -62,10 +62,28 @@ struct usbd_interface {
|
||||
uint8_t intf_num;
|
||||
};
|
||||
|
||||
struct usb_descriptor {
|
||||
const uint8_t *device_descriptor;
|
||||
const uint8_t *fs_config_descriptor;
|
||||
const uint8_t *hs_config_descriptor;
|
||||
const uint8_t *device_quality_descriptor;
|
||||
const uint8_t *fs_other_speed_descriptor;
|
||||
const uint8_t *hs_other_speed_descriptor;
|
||||
const char **string_descriptor;
|
||||
struct usb_msosv1_descriptor *msosv1_descriptor;
|
||||
struct usb_msosv2_descriptor *msosv2_descriptor;
|
||||
struct usb_webusb_url_ex_descriptor *webusb_url_descriptor;
|
||||
struct usb_bos_descriptor *bos_descriptor;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
void usbd_desc_register(struct usb_descriptor *desc);
|
||||
#else
|
||||
void usbd_desc_register(const uint8_t *desc);
|
||||
void usbd_msosv1_desc_register(struct usb_msosv1_descriptor *desc);
|
||||
void usbd_msosv2_desc_register(struct usb_msosv2_descriptor *desc);
|
||||
void usbd_bos_desc_register(struct usb_bos_descriptor *desc);
|
||||
#endif
|
||||
|
||||
void usbd_add_interface(struct usbd_interface *intf);
|
||||
void usbd_add_endpoint(struct usbd_endpoint *ep);
|
||||
|
||||
@@ -10,6 +10,7 @@ struct usbh_class_info *usbh_class_info_table_begin = NULL;
|
||||
struct usbh_class_info *usbh_class_info_table_end = NULL;
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t ep0_request_buffer[CONFIG_USBHOST_REQUEST_BUFFER_LEN];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX struct usb_setup_packet g_setup[CONFIG_USBHOST_MAX_EXTHUBS + 1][CONFIG_USBHOST_MAX_EHPORTS];
|
||||
|
||||
/* general descriptor field offsets */
|
||||
#define DESC_bLength 0 /** Length offset */
|
||||
@@ -109,7 +110,11 @@ static const struct usbh_class_driver *usbh_find_class_driver(uint8_t class, uin
|
||||
if (index->vid == vid && index->pid == pid && index->class == class) {
|
||||
return index->class_driver;
|
||||
}
|
||||
} else if (index->match_flags & (USB_CLASS_MATCH_INTF_CLASS)) {
|
||||
} else if ((index->match_flags & (USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS)) == (USB_CLASS_MATCH_INTF_CLASS | USB_CLASS_MATCH_INTF_SUBCLASS)) {
|
||||
if (index->class == class && index->subclass == subclass) {
|
||||
return index->class_driver;
|
||||
}
|
||||
} else if ((index->match_flags & (USB_CLASS_MATCH_INTF_CLASS)) == USB_CLASS_MATCH_INTF_CLASS) {
|
||||
if (index->class == class) {
|
||||
return index->class_driver;
|
||||
}
|
||||
@@ -411,11 +416,8 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
uint16_t ep_mps;
|
||||
int ret;
|
||||
|
||||
#define USB_REQUEST_BUFFER_SIZE 256
|
||||
setup = &hport->setup;
|
||||
|
||||
/* Configure EP0 with the default maximum packet size */
|
||||
usbh_hport_activate_ep0(hport);
|
||||
hport->setup = &g_setup[hport->parent->index - 1][hport->port - 1];
|
||||
setup = hport->setup;
|
||||
|
||||
/* Read the first 8 bytes of the device descriptor */
|
||||
setup->bmRequestType = USB_REQUEST_DIR_IN | USB_REQUEST_STANDARD | USB_REQUEST_RECIPIENT_DEVICE;
|
||||
@@ -618,16 +620,12 @@ int usbh_enumerate(struct usbh_hubport *hport)
|
||||
USB_LOG_INFO("Loading %s class driver\r\n", class_driver->driver_name);
|
||||
ret = CLASS_CONNECT(hport, i);
|
||||
if (ret < 0) {
|
||||
ret = CLASS_DISCONNECT(hport, i);
|
||||
CLASS_DISCONNECT(hport, i);
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
|
||||
usbh_device_mount_done_callback(hport);
|
||||
errout:
|
||||
if (ret < 0) {
|
||||
usbh_hport_deactivate_ep0(hport);
|
||||
}
|
||||
if (hport->raw_config_desc) {
|
||||
usb_free(hport->raw_config_desc);
|
||||
hport->raw_config_desc = NULL;
|
||||
@@ -689,6 +687,9 @@ int usbh_initialize(void)
|
||||
extern uint32_t __usbh_class_info_end__;
|
||||
usbh_class_info_table_begin = (struct usbh_class_info *)&__usbh_class_info_start__;
|
||||
usbh_class_info_table_end = (struct usbh_class_info *)&__usbh_class_info_end__;
|
||||
#elif defined(__ICCARM__) || defined(__ICCRX__)
|
||||
usbh_class_info_table_begin = (struct usbh_class_info *)__section_begin("usbh_class_info");
|
||||
usbh_class_info_table_end = (struct usbh_class_info *)__section_end("usbh_class_info");
|
||||
#endif
|
||||
|
||||
/* devaddr 1 is for roothub */
|
||||
@@ -794,12 +795,4 @@ int lsusb(int argc, char **argv)
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
__WEAK void usbh_device_mount_done_callback(struct usbh_hubport *hport)
|
||||
{
|
||||
}
|
||||
|
||||
__WEAK void usbh_device_unmount_done_callback(struct usbh_hubport *hport)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,9 @@ extern "C" {
|
||||
#define CLASS_INFO_DEFINE __attribute__((section("usbh_class_info"))) __USED __ALIGNED(1)
|
||||
#elif defined(__GNUC__)
|
||||
#define CLASS_INFO_DEFINE __attribute__((section(".usbh_class_info"))) __USED __ALIGNED(1)
|
||||
#elif defined(__ICCARM__) || defined(__ICCRX__)
|
||||
#pragma section = "usbh_class_info"
|
||||
#define CLASS_INFO_DEFINE __attribute__((section("usbh_class_info"))) __USED __ALIGNED(1)
|
||||
#endif
|
||||
|
||||
static inline void usbh_control_urb_fill(struct usbh_urb *urb,
|
||||
@@ -120,11 +123,11 @@ struct usbh_interface_altsetting {
|
||||
};
|
||||
|
||||
struct usbh_interface {
|
||||
struct usbh_interface_altsetting altsetting[CONFIG_USBHOST_MAX_INTF_ALTSETTINGS];
|
||||
uint8_t altsetting_num;
|
||||
char devname[CONFIG_USBHOST_DEV_NAMELEN];
|
||||
struct usbh_class_driver *class_driver;
|
||||
void *priv;
|
||||
struct usbh_interface_altsetting altsetting[CONFIG_USBHOST_MAX_INTF_ALTSETTINGS];
|
||||
uint8_t altsetting_num;
|
||||
};
|
||||
|
||||
struct usbh_configuration {
|
||||
@@ -143,8 +146,8 @@ struct usbh_hubport {
|
||||
const char *iManufacturer;
|
||||
const char *iProduct;
|
||||
const char *iSerialNumber;
|
||||
uint8_t* raw_config_desc;
|
||||
USB_MEM_ALIGNX struct usb_setup_packet setup;
|
||||
uint8_t *raw_config_desc;
|
||||
struct usb_setup_packet *setup;
|
||||
struct usbh_hub *parent;
|
||||
};
|
||||
|
||||
@@ -155,12 +158,11 @@ struct usbh_hub {
|
||||
uint8_t index;
|
||||
uint8_t hub_addr;
|
||||
usbh_pipe_t intin;
|
||||
USB_MEM_ALIGNX uint8_t int_buffer[1];
|
||||
uint8_t *int_buffer;
|
||||
struct usbh_urb intin_urb;
|
||||
struct usb_hub_descriptor hub_desc;
|
||||
struct usbh_hubport child[CONFIG_USBHOST_MAX_EHPORTS];
|
||||
struct usbh_hubport *parent;
|
||||
usb_slist_t hub_event_list;
|
||||
};
|
||||
|
||||
int usbh_hport_activate_epx(usbh_pipe_t *pipe, struct usbh_hubport *hport, struct usb_endpoint_descriptor *ep_desc);
|
||||
@@ -181,10 +183,8 @@ int usbh_initialize(void);
|
||||
struct usbh_hubport *usbh_find_hubport(uint8_t dev_addr);
|
||||
void *usbh_find_class_instance(const char *devname);
|
||||
|
||||
void usbh_device_mount_done_callback(struct usbh_hubport *hport);
|
||||
void usbh_device_unmount_done_callback(struct usbh_hubport *hport);
|
||||
|
||||
int lsusb(int argc, char **argv);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -20,28 +20,28 @@
|
||||
#define IN_CHANNEL_NUM 1
|
||||
|
||||
#if IN_CHANNEL_NUM == 1
|
||||
#define INPUT_CTRL 0x03
|
||||
#define INPUT_CH_ENABLE 0x0001
|
||||
#elif IN_CHANNEL_NUM == 2
|
||||
#define INPUT_CTRL 0x03, 0x03
|
||||
#define INPUT_CH_ENABLE 0x0000
|
||||
#elif IN_CHANNEL_NUM == 2
|
||||
#define INPUT_CTRL 0x03, 0x03, 0x03
|
||||
#define INPUT_CH_ENABLE 0x0003
|
||||
#elif IN_CHANNEL_NUM == 3
|
||||
#define INPUT_CTRL 0x03, 0x03, 0x03
|
||||
#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03
|
||||
#define INPUT_CH_ENABLE 0x0007
|
||||
#elif IN_CHANNEL_NUM == 4
|
||||
#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03
|
||||
#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03
|
||||
#define INPUT_CH_ENABLE 0x000f
|
||||
#elif IN_CHANNEL_NUM == 5
|
||||
#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03
|
||||
#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
|
||||
#define INPUT_CH_ENABLE 0x001f
|
||||
#elif IN_CHANNEL_NUM == 6
|
||||
#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
|
||||
#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
|
||||
#define INPUT_CH_ENABLE 0x003F
|
||||
#elif IN_CHANNEL_NUM == 7
|
||||
#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
|
||||
#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
|
||||
#define INPUT_CH_ENABLE 0x007f
|
||||
#elif IN_CHANNEL_NUM == 8
|
||||
#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
|
||||
#define INPUT_CTRL 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03
|
||||
#define INPUT_CH_ENABLE 0x00ff
|
||||
#endif
|
||||
|
||||
@@ -52,13 +52,13 @@
|
||||
#define USB_AUDIO_CONFIG_DESC_SIZ (unsigned long)(9 + \
|
||||
AUDIO_AC_DESCRIPTOR_INIT_LEN(1) + \
|
||||
AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \
|
||||
AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(1, IN_CHANNEL_NUM) + \
|
||||
AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM, 1) + \
|
||||
AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
|
||||
AUDIO_AS_DESCRIPTOR_INIT_LEN(1))
|
||||
|
||||
#define AUDIO_AC_SIZ (AUDIO_SIZEOF_AC_HEADER_DESC(1) + \
|
||||
AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \
|
||||
AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(1, IN_CHANNEL_NUM) + \
|
||||
AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM, 1) + \
|
||||
AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC)
|
||||
|
||||
const uint8_t audio_descriptor[] = {
|
||||
@@ -68,7 +68,7 @@ const uint8_t audio_descriptor[] = {
|
||||
AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x01, AUDIO_INTERM_MIC, IN_CHANNEL_NUM, INPUT_CH_ENABLE),
|
||||
AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x02, 0x01, 0x01, INPUT_CTRL),
|
||||
AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x03, AUDIO_TERMINAL_STREAMING, 0x02),
|
||||
AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x03, IN_CHANNEL_NUM, AUDIO_IN_EP, AUDIO_IN_PACKET, EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_FREQ)),
|
||||
AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x03, IN_CHANNEL_NUM, 2, 16, AUDIO_IN_EP, AUDIO_IN_PACKET, EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_FREQ)),
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
///////////////////////////////////////
|
||||
|
||||
@@ -16,14 +16,19 @@
|
||||
#define AUDIO_OUT_EP 0x02
|
||||
|
||||
/* AUDIO Class Config */
|
||||
#define AUDIO_FREQ 16000U
|
||||
#define AUDIO_SPEAKER_FREQ 16000U
|
||||
#define AUDIO_SPEAKER_FRAME_SIZE_BYTE 2u
|
||||
#define AUDIO_SPEAKER_RESOLUTION_BIT 16u
|
||||
#define AUDIO_MIC_FREQ 16000U
|
||||
#define AUDIO_MIC_FRAME_SIZE_BYTE 2u
|
||||
#define AUDIO_MIC_RESOLUTION_BIT 16u
|
||||
|
||||
#define AUDIO_SAMPLE_FREQ(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16))
|
||||
|
||||
/* AudioFreq * DataSize (2 bytes) * NumChannels (Stereo: 2) */
|
||||
#define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_FREQ * 2 * 2) / 1000))
|
||||
#define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_SPEAKER_FREQ * AUDIO_SPEAKER_FRAME_SIZE_BYTE * 2) / 1000))
|
||||
/* 16bit(2 Bytes) 双声道(Mono:2) */
|
||||
#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_FREQ * 2 * 2) / 1000))
|
||||
#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_MIC_FREQ * AUDIO_MIC_FRAME_SIZE_BYTE * 2) / 1000))
|
||||
|
||||
#define USB_AUDIO_CONFIG_DESC_SIZ (unsigned long)(9 + \
|
||||
AUDIO_AC_DESCRIPTOR_INIT_LEN(2) + \
|
||||
@@ -49,13 +54,15 @@ const uint8_t audio_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
AUDIO_AC_DESCRIPTOR_INIT(0x00, 0x03, AUDIO_AC_SIZ, 0x00, 0x01, 0x02),
|
||||
AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x01, AUDIO_INTERM_MIC, 0x02, 0x0003),
|
||||
AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x02, 0x01, 0x01, 0x03, 0x00),
|
||||
AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x02, 0x01, 0x01, 0x03, 0x00, 0x00),
|
||||
AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x03, AUDIO_TERMINAL_STREAMING, 0x02),
|
||||
AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, 0x02, 0x0003),
|
||||
AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x05, 0x04, 0x01, 0x03, 0x00),
|
||||
AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x05, 0x04, 0x01, 0x03, 0x00, 0x00),
|
||||
AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_OUTTERM_SPEAKER, 0x05),
|
||||
AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x04, 0x02, AUDIO_OUT_EP, AUDIO_OUT_PACKET, EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_FREQ)),
|
||||
AUDIO_AS_DESCRIPTOR_INIT(0x02, 0x03, 0x02, AUDIO_IN_EP, AUDIO_IN_PACKET, EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_FREQ)),
|
||||
AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, AUDIO_OUT_PACKET,\
|
||||
EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)),
|
||||
AUDIO_AS_DESCRIPTOR_INIT(0x02, 0x03, 0x02, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, AUDIO_IN_PACKET,\
|
||||
EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_MIC_FREQ)),
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
///////////////////////////////////////
|
||||
@@ -130,6 +137,9 @@ const uint8_t audio_descriptor[] = {
|
||||
0x00
|
||||
};
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t out_buffer[AUDIO_OUT_PACKET];
|
||||
|
||||
volatile bool tx_flag = 0;
|
||||
volatile bool rx_flag = 0;
|
||||
|
||||
@@ -137,6 +147,8 @@ void usbd_audio_open(uint8_t intf)
|
||||
{
|
||||
if (intf == 1) {
|
||||
rx_flag = 1;
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(AUDIO_OUT_EP, out_buffer, AUDIO_OUT_PACKET);
|
||||
printf("OPEN1\r\n");
|
||||
} else {
|
||||
tx_flag = 1;
|
||||
@@ -160,15 +172,10 @@ void usbd_audio_close(uint8_t intf)
|
||||
#define AUDIO_OUT_EP_MPS 64
|
||||
#endif
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t out_buffer[AUDIO_OUT_PACKET];
|
||||
|
||||
volatile bool ep_tx_busy_flag = false;
|
||||
|
||||
void usbd_configure_done_callback(void)
|
||||
{
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(AUDIO_OUT_EP, out_buffer, AUDIO_OUT_PACKET);
|
||||
}
|
||||
|
||||
void usbd_audio_out_callback(uint8_t ep, uint32_t nbytes)
|
||||
@@ -216,11 +223,11 @@ void audio_test()
|
||||
{
|
||||
while (1) {
|
||||
if (tx_flag) {
|
||||
// memset(write_buffer, 'a', 2048);
|
||||
// ep_tx_busy_flag = true;
|
||||
// usbd_ep_start_write(AUDIO_IN_EP, write_buffer, 2048);
|
||||
// while (ep_tx_busy_flag) {
|
||||
// }
|
||||
// memset(write_buffer, 'a', 2048);
|
||||
// ep_tx_busy_flag = true;
|
||||
// usbd_ep_start_write(AUDIO_IN_EP, write_buffer, 2048);
|
||||
// while (ep_tx_busy_flag) {
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,43 +12,43 @@
|
||||
#define EP_INTERVAL 0x01
|
||||
#endif
|
||||
|
||||
#define AUDIO_IN_EP 0x01
|
||||
#define AUDIO_IN_EP 0x81
|
||||
|
||||
#define AUDIO_FREQ 48000
|
||||
#define HALF_WORD_BYTES 2 //2 half word (one channel)
|
||||
#define SAMPLE_BITS 16 //16 bit per channel
|
||||
|
||||
#define IN_CHANNEL_NUM 2
|
||||
#define BMCONTROL (AUDIO_V2_FU_CONTROL_MUTE | AUDIO_V2_FU_CONTROL_VOLUME)
|
||||
|
||||
#if IN_CHANNEL_NUM == 1
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL)
|
||||
#define INPUT_CH_ENABLE 0x00000001
|
||||
#elif IN_CHANNEL_NUM == 2
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CH_ENABLE 0x00000000
|
||||
#elif IN_CHANNEL_NUM == 2
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CH_ENABLE 0x00000003
|
||||
#elif IN_CHANNEL_NUM == 3
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CH_ENABLE 0x00000007
|
||||
#elif IN_CHANNEL_NUM == 4
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CH_ENABLE 0x0000000f
|
||||
#elif IN_CHANNEL_NUM == 5
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CH_ENABLE 0x0000001f
|
||||
#elif IN_CHANNEL_NUM == 6
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CH_ENABLE 0x0000003F
|
||||
#elif IN_CHANNEL_NUM == 7
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CH_ENABLE 0x0000007f
|
||||
#elif IN_CHANNEL_NUM == 8
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CH_ENABLE 0x000000ff
|
||||
#endif
|
||||
|
||||
#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_FREQ * HALF_WORD_BYTES * IN_CHANNEL_NUM) / 1000))
|
||||
|
||||
#define BMCONTROL (AUDIO_V2_FU_CONTROL_MUTE | AUDIO_V2_FU_CONTROL_VOLUME)
|
||||
|
||||
#define USB_AUDIO_CONFIG_DESC_SIZ (9 + \
|
||||
AUDIO_V2_AC_DESCRIPTOR_INIT_LEN + \
|
||||
@@ -72,7 +72,7 @@ const uint8_t audio_descriptor[] = {
|
||||
AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_INTERM_MIC, 0x01, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000),
|
||||
AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x03, 0x02, INPUT_CTRL),
|
||||
AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, 0x03, 0x01, 0x0000),
|
||||
AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x04, IN_CHANNEL_NUM, INPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_IN_EP, AUDIO_IN_PACKET, EP_INTERVAL),
|
||||
AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x04, IN_CHANNEL_NUM, INPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_IN_EP, (AUDIO_IN_PACKET + 4), EP_INTERVAL),
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
///////////////////////////////////////
|
||||
@@ -147,6 +147,13 @@ const uint8_t audio_descriptor[] = {
|
||||
0x00
|
||||
};
|
||||
|
||||
static const uint8_t mic_default_sampling_freq_table[] = {
|
||||
AUDIO_SAMPLE_FREQ_NUM(1),
|
||||
AUDIO_SAMPLE_FREQ_4B(16000),
|
||||
AUDIO_SAMPLE_FREQ_4B(16000),
|
||||
AUDIO_SAMPLE_FREQ_4B(0x00)
|
||||
};
|
||||
|
||||
volatile bool tx_flag = 0;
|
||||
|
||||
void usbd_audio_open(uint8_t intf)
|
||||
@@ -160,6 +167,13 @@ void usbd_audio_close(uint8_t intf)
|
||||
tx_flag = 0;
|
||||
}
|
||||
|
||||
void usbd_audio_get_sampling_freq_table(uint8_t entity_id, uint8_t **sampling_freq_table)
|
||||
{
|
||||
if (entity_id == 0x01) {
|
||||
*sampling_freq_table = (uint8_t *)mic_default_sampling_freq_table;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_configure_done_callback(void)
|
||||
{
|
||||
/* no out ep, do nothing */
|
||||
|
||||
@@ -22,59 +22,61 @@
|
||||
#define IN_CHANNEL_NUM 2
|
||||
|
||||
#if IN_CHANNEL_NUM == 1
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL)
|
||||
#define INPUT_CH_ENABLE 0x00000001
|
||||
#elif IN_CHANNEL_NUM == 2
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CH_ENABLE 0x00000000
|
||||
#elif IN_CHANNEL_NUM == 2
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CH_ENABLE 0x00000003
|
||||
#elif IN_CHANNEL_NUM == 3
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CH_ENABLE 0x00000007
|
||||
#elif IN_CHANNEL_NUM == 4
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CH_ENABLE 0x0000000f
|
||||
#elif IN_CHANNEL_NUM == 5
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CH_ENABLE 0x0000001f
|
||||
#elif IN_CHANNEL_NUM == 6
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CH_ENABLE 0x0000003F
|
||||
#elif IN_CHANNEL_NUM == 7
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CH_ENABLE 0x0000007f
|
||||
#elif IN_CHANNEL_NUM == 8
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define INPUT_CH_ENABLE 0x000000ff
|
||||
#endif
|
||||
|
||||
|
||||
#define OUT_CHANNEL_NUM 2
|
||||
|
||||
#if OUT_CHANNEL_NUM == 1
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x00000001
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x00000000
|
||||
#elif OUT_CHANNEL_NUM == 2
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x00000003
|
||||
#elif OUT_CHANNEL_NUM == 3
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x00000007
|
||||
#elif OUT_CHANNEL_NUM == 4
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x0000000f
|
||||
#elif OUT_CHANNEL_NUM == 5
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x0000001f
|
||||
#elif OUT_CHANNEL_NUM == 6
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x0000003F
|
||||
#elif OUT_CHANNEL_NUM == 7
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x0000007f
|
||||
#elif OUT_CHANNEL_NUM == 8
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x000000ff
|
||||
#endif
|
||||
|
||||
|
||||
/* AudioFreq * DataSize (2 bytes) * NumChannels */
|
||||
#define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_FREQ * HALF_WORD_BYTES * OUT_CHANNEL_NUM) / 1000))
|
||||
#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_FREQ * HALF_WORD_BYTES * IN_CHANNEL_NUM) / 1000))
|
||||
@@ -117,7 +119,7 @@ uint8_t audio_descriptor[] = {
|
||||
AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x07, 0x06, INPUT_CTRL),
|
||||
AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x08, AUDIO_TERMINAL_STREAMING, 0x07, 0x05, 0x0000),
|
||||
AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, AUDIO_OUT_PACKET, EP_INTERVAL),
|
||||
AUDIO_V2_AS_DESCRIPTOR_INIT(0x02, 0x08, IN_CHANNEL_NUM, INPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_IN_EP, AUDIO_IN_PACKET, EP_INTERVAL),
|
||||
AUDIO_V2_AS_DESCRIPTOR_INIT(0x02, 0x08, IN_CHANNEL_NUM, INPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_IN_EP, (AUDIO_IN_PACKET + 4), EP_INTERVAL),
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
///////////////////////////////////////
|
||||
@@ -192,6 +194,34 @@ uint8_t audio_descriptor[] = {
|
||||
0x00
|
||||
};
|
||||
|
||||
static const uint8_t speaker_default_sampling_freq_table[] = {
|
||||
AUDIO_SAMPLE_FREQ_NUM(5),
|
||||
AUDIO_SAMPLE_FREQ_4B(8000),
|
||||
AUDIO_SAMPLE_FREQ_4B(8000),
|
||||
AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||
AUDIO_SAMPLE_FREQ_4B(16000),
|
||||
AUDIO_SAMPLE_FREQ_4B(16000),
|
||||
AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||
AUDIO_SAMPLE_FREQ_4B(32000),
|
||||
AUDIO_SAMPLE_FREQ_4B(32000),
|
||||
AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||
AUDIO_SAMPLE_FREQ_4B(48000),
|
||||
AUDIO_SAMPLE_FREQ_4B(48000),
|
||||
AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||
AUDIO_SAMPLE_FREQ_4B(96000),
|
||||
AUDIO_SAMPLE_FREQ_4B(96000),
|
||||
AUDIO_SAMPLE_FREQ_4B(0x00)
|
||||
};
|
||||
|
||||
static const uint8_t mic_default_sampling_freq_table[] = {
|
||||
AUDIO_SAMPLE_FREQ_NUM(1),
|
||||
AUDIO_SAMPLE_FREQ_4B(16000),
|
||||
AUDIO_SAMPLE_FREQ_4B(16000),
|
||||
AUDIO_SAMPLE_FREQ_4B(0x00)
|
||||
};
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t out_buffer[AUDIO_OUT_PACKET];
|
||||
|
||||
volatile bool tx_flag = 0;
|
||||
volatile bool rx_flag = 0;
|
||||
|
||||
@@ -199,6 +229,8 @@ void usbd_audio_open(uint8_t intf)
|
||||
{
|
||||
if (intf == 1) {
|
||||
rx_flag = 1;
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(AUDIO_OUT_EP, out_buffer, AUDIO_OUT_PACKET);
|
||||
USB_LOG_RAW("OPEN1\r\n");
|
||||
} else {
|
||||
tx_flag = 1;
|
||||
@@ -216,6 +248,16 @@ void usbd_audio_close(uint8_t intf)
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_audio_get_sampling_freq_table(uint8_t entity_id, uint8_t **sampling_freq_table)
|
||||
{
|
||||
if (entity_id == 0x01) {
|
||||
*sampling_freq_table = (uint8_t *)speaker_default_sampling_freq_table;
|
||||
} else if (entity_id == 0x05) {
|
||||
*sampling_freq_table = (uint8_t *)mic_default_sampling_freq_table;
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_audio_set_sampling_freq(uint8_t entity_id, uint8_t ep_ch, uint32_t sampling_freq)
|
||||
{
|
||||
uint16_t packet_size = 0;
|
||||
@@ -230,18 +272,8 @@ void usbd_audio_set_sampling_freq(uint8_t entity_id, uint8_t ep_ch, uint32_t sam
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define AUDIO_OUT_EP_MPS 512
|
||||
#else
|
||||
#define AUDIO_OUT_EP_MPS 64
|
||||
#endif
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t out_buffer[AUDIO_OUT_EP_MPS];
|
||||
|
||||
void usbd_configure_done_callback(void)
|
||||
{
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(AUDIO_OUT_EP, out_buffer, AUDIO_OUT_EP_MPS);
|
||||
}
|
||||
|
||||
void usbd_audio_iso_out_callback(uint8_t ep, uint32_t nbytes)
|
||||
|
||||
@@ -14,35 +14,35 @@
|
||||
|
||||
#define AUDIO_OUT_EP 0x01
|
||||
|
||||
#define AUDIO_FREQ 48000
|
||||
#define AUDIO_FREQ 48000
|
||||
#define HALF_WORD_BYTES 2 //2 half word (one channel)
|
||||
#define SAMPLE_BITS 16 //16 bit per channel
|
||||
|
||||
#define OUT_CHANNEL_NUM 2
|
||||
|
||||
#if OUT_CHANNEL_NUM == 1
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x00000001
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x00000000
|
||||
#elif OUT_CHANNEL_NUM == 2
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x00000003
|
||||
#elif OUT_CHANNEL_NUM == 3
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x00000007
|
||||
#elif OUT_CHANNEL_NUM == 4
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x0000000f
|
||||
#elif OUT_CHANNEL_NUM == 5
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x0000001f
|
||||
#elif OUT_CHANNEL_NUM == 6
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x0000003F
|
||||
#elif OUT_CHANNEL_NUM == 7
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x0000007f
|
||||
#elif OUT_CHANNEL_NUM == 8
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CTRL DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL), DBVAL(BMCONTROL)
|
||||
#define OUTPUT_CH_ENABLE 0x000000ff
|
||||
#endif
|
||||
|
||||
@@ -146,11 +146,35 @@ const uint8_t audio_descriptor[] = {
|
||||
#endif
|
||||
0x00
|
||||
};
|
||||
|
||||
static const uint8_t default_sampling_freq_table[] = {
|
||||
AUDIO_SAMPLE_FREQ_NUM(5),
|
||||
AUDIO_SAMPLE_FREQ_4B(8000),
|
||||
AUDIO_SAMPLE_FREQ_4B(8000),
|
||||
AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||
AUDIO_SAMPLE_FREQ_4B(16000),
|
||||
AUDIO_SAMPLE_FREQ_4B(16000),
|
||||
AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||
AUDIO_SAMPLE_FREQ_4B(32000),
|
||||
AUDIO_SAMPLE_FREQ_4B(32000),
|
||||
AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||
AUDIO_SAMPLE_FREQ_4B(48000),
|
||||
AUDIO_SAMPLE_FREQ_4B(48000),
|
||||
AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||
AUDIO_SAMPLE_FREQ_4B(96000),
|
||||
AUDIO_SAMPLE_FREQ_4B(96000),
|
||||
AUDIO_SAMPLE_FREQ_4B(0x00),
|
||||
};
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t out_buffer[AUDIO_OUT_PACKET];
|
||||
|
||||
volatile bool rx_flag = 0;
|
||||
|
||||
void usbd_audio_open(uint8_t intf)
|
||||
{
|
||||
rx_flag = 1;
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(AUDIO_OUT_EP, out_buffer, AUDIO_OUT_PACKET);
|
||||
USB_LOG_RAW("OPEN\r\n");
|
||||
}
|
||||
void usbd_audio_close(uint8_t intf)
|
||||
@@ -159,18 +183,15 @@ void usbd_audio_close(uint8_t intf)
|
||||
rx_flag = 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define AUDIO_OUT_EP_MPS 512
|
||||
#else
|
||||
#define AUDIO_OUT_EP_MPS 64
|
||||
#endif
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t out_buffer[AUDIO_OUT_EP_MPS];
|
||||
void usbd_audio_get_sampling_freq_table(uint8_t entity_id, uint8_t **sampling_freq_table)
|
||||
{
|
||||
if (entity_id == 0x01) {
|
||||
*sampling_freq_table = (uint8_t *)default_sampling_freq_table;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_configure_done_callback(void)
|
||||
{
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(AUDIO_OUT_EP, out_buffer, AUDIO_OUT_EP_MPS);
|
||||
}
|
||||
|
||||
void usbd_audio_iso_out_callback(uint8_t ep, uint32_t nbytes)
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
[bl_mcu_sdk_usb_examples](https://github.com/bouffalolab/bl_mcu_sdk/tree/master/examples/usb)
|
||||
@@ -94,7 +94,7 @@ static const uint8_t cdc_descriptor[] = {
|
||||
};
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30 };
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
|
||||
|
||||
volatile bool ep_tx_busy_flag = false;
|
||||
|
||||
@@ -149,6 +149,11 @@ struct usbd_interface intf1;
|
||||
|
||||
void cdc_acm_init(void)
|
||||
{
|
||||
const uint8_t data[10] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30 };
|
||||
|
||||
memcpy(&write_buffer[0], data, 10);
|
||||
memset(&write_buffer[10], 'a', 2038);
|
||||
|
||||
usbd_desc_register(cdc_descriptor);
|
||||
usbd_add_interface(usbd_cdc_acm_init_intf(&intf0));
|
||||
usbd_add_interface(usbd_cdc_acm_init_intf(&intf1));
|
||||
@@ -171,7 +176,6 @@ void usbd_cdc_acm_set_dtr(uint8_t intf, bool dtr)
|
||||
void cdc_acm_data_send_with_dtr_test(void)
|
||||
{
|
||||
if (dtr_enable) {
|
||||
memset(&write_buffer[10], 'a', 2038);
|
||||
ep_tx_busy_flag = true;
|
||||
usbd_ep_start_write(CDC_IN_EP, write_buffer, 2048);
|
||||
while (ep_tx_busy_flag) {
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
# Copyright 2021 hpmicro
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
set(CONFIG_CHERRYUSB 1)
|
||||
set(CONFIG_USB_DEVICE 1)
|
||||
set(CONFIG_CHERRYUSB_DEVICE 1)
|
||||
set(CONFIG_CHERRYUSB_DEVICE_CDC 1)
|
||||
set(CONFIG_CHERRYUSB_DEVICE_HID 1)
|
||||
set(CONFIG_CHERRYUSB_DEVICE_MSC 1)
|
||||
set(CONFIG_CHERRYUSB_DEVICE_DEMO_CDC_MSC 1)
|
||||
|
||||
find_package(hpm-sdk REQUIRED HINTS $ENV{HPM_SDK_BASE})
|
||||
|
||||
project(cherryusb)
|
||||
|
||||
sdk_app_inc(src)
|
||||
sdk_app_src(src/hello_world.c)
|
||||
generate_ses_project()
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 hpmicro
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "board.h"
|
||||
#include "hpm_debug_console.h"
|
||||
|
||||
#define LED_FLASH_PERIOD_IN_MS 300
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int u;
|
||||
|
||||
board_init();
|
||||
board_init_led_pins();
|
||||
board_init_usb_pins();
|
||||
|
||||
board_timer_create(LED_FLASH_PERIOD_IN_MS, board_led_toggle);
|
||||
|
||||
printf("hello world\n");
|
||||
|
||||
extern void cdc_acm_msc_init(void);
|
||||
|
||||
cdc_acm_msc_init();
|
||||
while(1)
|
||||
{
|
||||
extern void cdc_acm_data_send_with_dtr_test(void);
|
||||
cdc_acm_data_send_with_dtr_test();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef CHERRYUSB_CONFIG_H
|
||||
#define CHERRYUSB_CONFIG_H
|
||||
|
||||
#define CHERRYUSB_VERSION 0x000700
|
||||
|
||||
/* ================ USB common Configuration ================ */
|
||||
|
||||
#define CONFIG_USB_PRINTF(...) printf(__VA_ARGS__)
|
||||
|
||||
#define usb_malloc(size) malloc(size)
|
||||
#define usb_free(ptr) free(ptr)
|
||||
|
||||
#ifndef CONFIG_USB_DBG_LEVEL
|
||||
#define CONFIG_USB_DBG_LEVEL USB_DBG_INFO
|
||||
#endif
|
||||
|
||||
/* Enable print with color */
|
||||
#define CONFIG_USB_PRINTF_COLOR_ENABLE
|
||||
|
||||
/* data align size when use dma */
|
||||
#ifndef CONFIG_USB_ALIGN_SIZE
|
||||
#define CONFIG_USB_ALIGN_SIZE 4
|
||||
#endif
|
||||
|
||||
/* attribute data into no cache ram */
|
||||
#define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable")))
|
||||
|
||||
/* ================= USB Device Stack Configuration ================ */
|
||||
|
||||
/* Ep0 max transfer buffer, specially for receiving data from ep0 out */
|
||||
#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 256
|
||||
|
||||
/* Setup packet log for debug */
|
||||
// #define CONFIG_USBDEV_SETUP_LOG_PRINT
|
||||
|
||||
/* Check if the input descriptor is correct */
|
||||
// #define CONFIG_USBDEV_DESC_CHECK
|
||||
|
||||
/* Enable test mode */
|
||||
// #define CONFIG_USBDEV_TEST_MODE
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_BLOCK_SIZE
|
||||
#define CONFIG_USBDEV_MSC_BLOCK_SIZE 512
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_MANUFACTURER_STRING
|
||||
#define CONFIG_USBDEV_MSC_MANUFACTURER_STRING ""
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_PRODUCT_STRING
|
||||
#define CONFIG_USBDEV_MSC_PRODUCT_STRING ""
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_VERSION_STRING
|
||||
#define CONFIG_USBDEV_MSC_VERSION_STRING "0.01"
|
||||
#endif
|
||||
|
||||
// #define CONFIG_USBDEV_MSC_THREAD
|
||||
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
#ifndef CONFIG_USBDEV_MSC_STACKSIZE
|
||||
#define CONFIG_USBDEV_MSC_STACKSIZE 2048
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_PRIO
|
||||
#define CONFIG_USBDEV_MSC_PRIO 4
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_AUDIO_VERSION
|
||||
#define CONFIG_USBDEV_AUDIO_VERSION 0x0100
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_AUDIO_MAX_CHANNEL
|
||||
#define CONFIG_USBDEV_AUDIO_MAX_CHANNEL 8
|
||||
#endif
|
||||
|
||||
/* ================ USB HOST Stack Configuration ================== */
|
||||
|
||||
#define CONFIG_USBHOST_MAX_RHPORTS 1
|
||||
#define CONFIG_USBHOST_MAX_EXTHUBS 1
|
||||
#define CONFIG_USBHOST_MAX_EHPORTS 4
|
||||
#define CONFIG_USBHOST_MAX_INTERFACES 6
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 1
|
||||
#define CONFIG_USBHOST_MAX_ENDPOINTS 4
|
||||
|
||||
#define CONFIG_USBHOST_DEV_NAMELEN 16
|
||||
|
||||
#ifndef CONFIG_USBHOST_PSC_PRIO
|
||||
#define CONFIG_USBHOST_PSC_PRIO 4
|
||||
#endif
|
||||
#ifndef CONFIG_USBHOST_PSC_STACKSIZE
|
||||
#define CONFIG_USBHOST_PSC_STACKSIZE 2048
|
||||
#endif
|
||||
|
||||
//#define CONFIG_USBHOST_GET_STRING_DESC
|
||||
|
||||
/* Ep0 max transfer buffer */
|
||||
#define CONFIG_USBHOST_REQUEST_BUFFER_LEN 512
|
||||
|
||||
#ifndef CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT
|
||||
#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 500
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBHOST_MSC_TIMEOUT
|
||||
#define CONFIG_USBHOST_MSC_TIMEOUT 5000
|
||||
#endif
|
||||
|
||||
/* ================ USB Device Port Configuration ================*/
|
||||
|
||||
//#define USBD_IRQHandler USBD_IRQHandler
|
||||
//#define USB_BASE (0x40080000UL)
|
||||
//#define USB_NUM_BIDIR_ENDPOINTS 4
|
||||
|
||||
/* ================ USB Host Port Configuration ==================*/
|
||||
|
||||
#define CONFIG_USBHOST_PIPE_NUM 10
|
||||
|
||||
/* ================ EHCI Configuration ================ */
|
||||
|
||||
#define CONFIG_USB_EHCI_HCCR_BASE (0)
|
||||
#define CONFIG_USB_EHCI_HCOR_BASE (0xF2020000UL + 0x140)
|
||||
#define CONFIG_EHCI_FRAME_LIST_SIZE 1024
|
||||
// #define CONFIG_USB_EHCI_INFO_ENABLE
|
||||
// #define CONFIG_USB_ECHI_HCOR_RESERVED_DISABLE
|
||||
// #define CONFIG_USB_EHCI_CONFIGFLAG
|
||||
#define CONFIG_USB_EHCI_PORT_POWER
|
||||
|
||||
#endif
|
||||
@@ -1,21 +0,0 @@
|
||||
# Copyright 2021 hpmicro
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
set(CONFIG_FREERTOS 1)
|
||||
set(CONFIG_CHERRYUSB 1)
|
||||
set(CONFIG_USB_HOST 1)
|
||||
set(CONFIG_CHERRYUSB_HOST 1)
|
||||
set(CONFIG_CHERRYUSB_HOST_DEMO 1)
|
||||
|
||||
find_package(hpm-sdk REQUIRED HINTS $ENV{HPM_SDK_BASE})
|
||||
project(cherryusb_host)
|
||||
sdk_compile_definitions(-DUSB_HOST_MCU_CORE=HPM_CORE0)
|
||||
sdk_inc(src)
|
||||
sdk_compile_definitions(-D__freertos_irq_stack_top=_stack)
|
||||
sdk_compile_definitions(-DCONFIG_FREERTOS=1)
|
||||
sdk_compile_definitions(-DUSE_NONVECTOR_MODE=1)
|
||||
sdk_compile_definitions(-DDISABLE_IRQ_PREEMPTIVE=1)
|
||||
sdk_app_src(src/main.c)
|
||||
generate_ses_project()
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 hpmicro
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
|
||||
define memory with size = 4G;
|
||||
|
||||
/* Regions */
|
||||
define region NOR_CFG_OPTION = [ from 0x80000400 size 0x1000 ];
|
||||
define region BOOT_HEADER = [ from 0x80001000 size 0x3000 ];
|
||||
define region XPI0 = [from 0x80003000 size _flash_size - 0x3000 ]; /* XPI0 */
|
||||
define region ILM_SLV = [from 0x1000000 size 256k]; /* ILM slave */
|
||||
define region DLM = [from 0x80000 size 256k]; /* DLM */
|
||||
define region AXI_SRAM = [from 0x1080000 size 700k]; /* reserve 256K for noncacheable region */
|
||||
define region SDRAM = [from 0x40000000 size _extram_size];
|
||||
define region NONCACHEABLE_RAM = [from 0x1140000 size 256k];
|
||||
define region CHERRYUSB_FLASH = [start(XPI0)+4096k size 72];
|
||||
|
||||
/* Blocks */
|
||||
define block vectors { section .isr_vector, section .vector_table };
|
||||
define block ctors { section .ctors, section .ctors.*, block with alphabetical order { init_array } };
|
||||
define block dtors { section .dtors, section .dtors.*, block with reverse alphabetical order { fini_array } };
|
||||
define block eh_frame { section .eh_frame, section .eh_frame.* };
|
||||
define block tbss { section .tbss, section .tbss.* };
|
||||
define block tdata { section .tdata, section .tdata.* };
|
||||
define block tls { block tbss, block tdata };
|
||||
define block tdata_load { copy of block tdata };
|
||||
define block heap with size = __HEAPSIZE__, alignment = 8, /* fill =0x00, */ readwrite access { };
|
||||
define block stack with size = __STACKSIZE__, alignment = 8, /* fill =0xCD, */ readwrite access { };
|
||||
|
||||
define block framebuffer with alignment = 8 { section .framebuffer };
|
||||
define block safe_stack with size = 512, readwrite access {};
|
||||
|
||||
define block boot_header with fixed order { section .boot_header, section .fw_info_table, section .dc_info };
|
||||
|
||||
/* Symbols */
|
||||
define exported symbol __nor_cfg_option_load_addr__ = start of region NOR_CFG_OPTION;
|
||||
define exported symbol __boot_header_load_addr__ = start of region BOOT_HEADER;
|
||||
define exported symbol __app_load_addr__ = start of region XPI0;
|
||||
define exported symbol __app_offset__ = __app_load_addr__ - __boot_header_load_addr__;
|
||||
define exported symbol __boot_header_length__ = size of block boot_header;
|
||||
define exported symbol __fw_size__ = 0x1000;
|
||||
|
||||
define exported symbol __noncacheable_start__ = start of region NONCACHEABLE_RAM;
|
||||
define exported symbol __noncacheable_end__ = end of region NONCACHEABLE_RAM + 1;
|
||||
|
||||
define exported symbol __usbh_class_info_start__ = start of region CHERRYUSB_FLASH;
|
||||
define exported symbol __usbh_class_info_end__ = end of region CHERRYUSB_FLASH + 1;
|
||||
|
||||
define exported symbol _stack_safe = end of block safe_stack + 1;
|
||||
define exported symbol _stack = end of block stack + 1;
|
||||
|
||||
do not initialize { section .noncacheable };
|
||||
do not initialize { section .non_init, section .non_init.*, section .*.non_init, section .*.non_init.* };
|
||||
do not initialize { section .no_init, section .no_init.*, section .*.no_init, section .*.no_init.* }; // Legacy sections, kept for backwards compatibility
|
||||
do not initialize { section .noinit, section .noinit.*, section .*.noinit, section .*.noinit.* }; // Legacy sections, used by some SDKs/HALs
|
||||
|
||||
initialize by copy with packing=auto { section .noncacheable.init };
|
||||
initialize by copy with packing=none { section .data, section .data.*, section .*.data, section .*.data.* }; // Static data sections
|
||||
initialize by copy with packing=auto { section .sdata, section .sdata.* };
|
||||
initialize by copy with packing=auto { section .fast, section .fast.*, section .*.fast, section .*.fast.* }; // "RAM Code" sections
|
||||
|
||||
initialize by symbol __SEGGER_init_heap { block heap }; // Init the heap if there is one
|
||||
initialize by symbol __SEGGER_init_ctors { block ctors }; // Call constructors for global objects which need to be constructed before reaching main (if any). Make sure this is done after setting up heap.
|
||||
|
||||
keep { section .nor_cfg_option, section .boot_header, section .fw_info_table, section .dc_info };
|
||||
place in NOR_CFG_OPTION { section .nor_cfg_option };
|
||||
place in BOOT_HEADER with fixed order { block boot_header };
|
||||
place at start of XPI0 with fixed order { symbol _start};
|
||||
|
||||
place at start of ILM_SLV with fixed order { block vectors };
|
||||
initialize by copy { block vectors };
|
||||
|
||||
place in XPI0 with minimum size order {
|
||||
block tdata_load, // Thread-local-storage load image
|
||||
block ctors, // Constructors block
|
||||
block dtors, // Destructors block
|
||||
block eh_frame, // Exception frames placed directly into flash overriding default placement (sections writable)
|
||||
readonly, // Catch-all for readonly data (e.g. .rodata, .srodata)
|
||||
readexec // Catch-all for (readonly) executable code (e.g. .text)
|
||||
};
|
||||
|
||||
//
|
||||
// The GNU compiler creates these exception-related sections as writeable.
|
||||
// Override the section header flag and make them readonly so they can be
|
||||
// placed into flash.
|
||||
//
|
||||
define access readonly { section .gcc_except_table, section .gcc_except_table.* };
|
||||
define access readonly { section .eh_frame, section .eh_frame.* };
|
||||
define access readonly { section .sdata.DW.* };
|
||||
|
||||
place in ILM_SLV {
|
||||
section .fast, section .fast.*, // "ramfunc" section
|
||||
};
|
||||
|
||||
place in DLM with auto order {
|
||||
block tls, // Thread-local-storage block
|
||||
readwrite, // Catch-all for initialized/uninitialized data sections (e.g. .data, .noinit)
|
||||
zeroinit // Catch-all for zero-initialized data sections (e.g. .bss)
|
||||
};
|
||||
|
||||
place in AXI_SRAM { block framebuffer };
|
||||
place in NONCACHEABLE_RAM { section .noncacheable, section .noncacheable.init, section .noncacheable.bss };
|
||||
place in AXI_SRAM { block heap }; // Heap reserved block
|
||||
place at end of AXI_SRAM { block stack }; // Stack reserved block at the end
|
||||
place at end of DLM { block safe_stack }; // Safe stack reserved block at the end
|
||||
place in CHERRYUSB_FLASH { section .usbh_class_info };
|
||||
keep { section .usbh_class_info};
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 hpmicro
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
|
||||
define memory with size = 4G;
|
||||
|
||||
/* Regions */
|
||||
define region CORE0_LM_SLV = [from 0x1000000 size 512k]; /* CORE0 LM slave */
|
||||
define region CORE1_LM_SLV = [from 0x1180000 size 512k]; /* CORE1 LM slave */
|
||||
define region AXI_SRAM = [from 0x1080000 size 700k]; /* reserve 256K for noncacheable region */
|
||||
define region CHERRYUSB_RAM = [from 0x1080000 + 700k size 72]; /* reserve 64B for cherryusb region */
|
||||
define region NONCACHEABLE_RAM = [from 0x1140000 size 256K];
|
||||
|
||||
define exported symbol __noncacheable_start__ = start of region NONCACHEABLE_RAM;
|
||||
define exported symbol __noncacheable_end__ = end of region NONCACHEABLE_RAM + 1;
|
||||
define exported symbol _stack = end of block stack + 1;
|
||||
|
||||
define exported symbol __usbh_class_info_start__ = start of region CHERRYUSB_RAM;
|
||||
define exported symbol __usbh_class_info_end__ = end of region CHERRYUSB_RAM + 1;
|
||||
|
||||
/* Blocks */
|
||||
define block vectors { section .isr_vector, section .vector_table };
|
||||
define block ctors { section .ctors, section .ctors.*, block with alphabetical order { init_array } };
|
||||
define block dtors { section .dtors, section .dtors.*, block with reverse alphabetical order { fini_array } };
|
||||
define block eh_frame { section .eh_frame, section .eh_frame.* };
|
||||
define block tbss { section .tbss, section .tbss.* };
|
||||
define block tdata { section .tdata, section .tdata.* };
|
||||
define block tls { block tbss, block tdata };
|
||||
define block tdata_load { copy of block tdata };
|
||||
define block heap with size = __HEAPSIZE__, alignment = 8, /* fill =0x00, */ readwrite access { };
|
||||
define block stack with size = __STACKSIZE__, alignment = 8, /* fill =0xCD, */ readwrite access { };
|
||||
define block framebuffer { section .framebuffer };
|
||||
define block safe_stack with size = 512, readwrite access {};
|
||||
define exported symbol _stack_safe = end of block safe_stack + 1;
|
||||
|
||||
do not initialize { section .noncacheable };
|
||||
do not initialize { section .non_init, section .non_init.*, section .*.non_init, section .*.non_init.* };
|
||||
do not initialize { section .no_init, section .no_init.*, section .*.no_init, section .*.no_init.* }; // Legacy sections, kept for backwards compatibility
|
||||
do not initialize { section .noinit, section .noinit.*, section .*.noinit, section .*.noinit.* }; // Legacy sections, used by some SDKs/HALs
|
||||
|
||||
initialize by copy with packing=auto { section .noncacheable.init };
|
||||
initialize by copy with packing=none { section .data, section .data.*, section .*.data, section .*.data.* }; // Static data sections
|
||||
initialize by copy with packing=auto { section .sdata, section .sdata.* };
|
||||
initialize by copy with packing=auto { section .fast, section .fast.*, section .*.fast, section .*.fast.* }; // "RAM Code" sections
|
||||
|
||||
initialize by symbol __SEGGER_init_heap { block heap }; // Init the heap if there is one
|
||||
initialize by symbol __SEGGER_init_ctors { block ctors }; // Call constructors for global objects which need to be constructed before reaching main (if any). Make sure this is done after setting up heap.
|
||||
|
||||
place at start of CORE0_LM_SLV { symbol _start };
|
||||
place in CORE0_LM_SLV { block vectors }; // Vector table section
|
||||
place in CORE0_LM_SLV with minimum size order {
|
||||
block tdata_load, // Thread-local-storage load image
|
||||
block ctors, // Constructors block
|
||||
block dtors, // Destructors block
|
||||
block eh_frame, // Exception frames placed directly into flash overriding default placement (sections writable)
|
||||
readonly, // Catch-all for readonly data (e.g. .rodata, .srodata)
|
||||
readexec, // Catch-all for (readonly) executable code (e.g. .text)
|
||||
section .fast, section .fast.*, // "ramfunc" section
|
||||
};
|
||||
|
||||
//
|
||||
// The GNU compiler creates these exception-related sections as writeable.
|
||||
// Override the section header flag and make them readonly so they can be
|
||||
// placed into flash.
|
||||
//
|
||||
define access readonly { section .gcc_except_table, section .gcc_except_table.* };
|
||||
define access readonly { section .eh_frame, section .eh_frame.* };
|
||||
define access readonly { section .sdata.DW.* };
|
||||
|
||||
/* Explicit placement in AXI_SRAM */
|
||||
place in AXI_SRAM { block framebuffer };
|
||||
|
||||
place in AXI_SRAM with auto order {
|
||||
block tls, // Thread-local-storage block
|
||||
readwrite, // Catch-all for initialized/uninitialized data sections (e.g. .data, .noinit)
|
||||
zeroinit, // Catch-all for zero-initialized data sections (e.g. .bss)
|
||||
};
|
||||
place in NONCACHEABLE_RAM { section .noncacheable, section .noncacheable.init, section .noncacheable.bss }; // Noncacheable
|
||||
place in AXI_SRAM { block heap }; // Heap reserved block
|
||||
place at end of AXI_SRAM { block stack, block safe_stack }; // Stack reserved block at the end
|
||||
place in CHERRYUSB_RAM { section .usbh_class_info };
|
||||
keep { section .usbh_class_info};
|
||||
@@ -1,147 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 hpmicro
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
|
||||
/*
|
||||
* Application specific definitions.
|
||||
*
|
||||
* These definitions should be adjusted for your particular hardware and
|
||||
* application requirements.
|
||||
*
|
||||
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||
*
|
||||
* See http://www.freertos.org/a00110.html.
|
||||
*/
|
||||
|
||||
#define configMTIME_BASE_ADDRESS (0xE6000000UL)
|
||||
#define configMTIMECMP_BASE_ADDRESS (0xE6000008UL)
|
||||
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configCPU_CLOCK_HZ ((uint32_t) 24000000)
|
||||
#define configTICK_RATE_HZ ((TickType_t) 1000)
|
||||
#define configMAX_PRIORITIES (7)
|
||||
#define configMINIMAL_STACK_SIZE (256)
|
||||
#define configMAX_TASK_NAME_LEN 16
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configIDLE_SHOULD_YIELD 0
|
||||
#define configUSE_APPLICATION_TASK_TAG 0
|
||||
#define configGENERATE_RUN_TIME_STATS 0
|
||||
|
||||
//为1时使用计数信号量
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
//使用互斥信号量
|
||||
#define configUSE_MUTEXES 1
|
||||
|
||||
/* Memory allocation definitions. */
|
||||
#define configSUPPORT_STATIC_ALLOCATION 0
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
#define configTOTAL_HEAP_SIZE ((size_t) (20 * 1024))
|
||||
|
||||
/* Hook function definitions. */
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 0
|
||||
#define configUSE_MALLOC_FAILED_HOOK 0
|
||||
#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
|
||||
|
||||
/* Run time and task stats gathering definitions. */
|
||||
#define configGENERATE_RUN_TIME_STATS 0
|
||||
#define configUSE_TRACE_FACILITY 1
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||
|
||||
/* Set the following definitions to 1 to include the API function, or zero to exclude the API function. */
|
||||
#define INCLUDE_vTaskPrioritySet 1
|
||||
#define INCLUDE_uxTaskPriorityGet 1
|
||||
#define INCLUDE_vTaskDelete 1
|
||||
#define INCLUDE_vTaskCleanUpResources 1
|
||||
#define INCLUDE_vTaskSuspend 1
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||
#define INCLUDE_xTimerPendFunctionCall 1
|
||||
#define INCLUDE_eTaskGetState 1
|
||||
#define INCLUDE_xTaskAbortDelay 1
|
||||
#define INCLUDE_xTaskGetHandle 1
|
||||
#define INCLUDE_xSemaphoreGetMutexHolder 1
|
||||
|
||||
/* Co-routine definitions. */
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES 2
|
||||
|
||||
/* Software timer definitions. */
|
||||
#define configUSE_TIMERS 1
|
||||
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1)
|
||||
#define configTIMER_QUEUE_LENGTH 4
|
||||
#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE)
|
||||
|
||||
/* Task priorities.*/
|
||||
#ifndef uartPRIMARY_PRIORITY
|
||||
#define uartPRIMARY_PRIORITY (configMAX_PRIORITIES - 3)
|
||||
#endif
|
||||
|
||||
/* Normal assert() semantics without relying on the provision of an assert.h header file. */
|
||||
#define configASSERT(x) if ((x) == 0) { taskDISABLE_INTERRUPTS(); __asm volatile("ebreak"); for (;;); }
|
||||
|
||||
/*
|
||||
* The size of the global output buffer that is available for use when there
|
||||
* are multiple command interpreters running at once (for example, one on a UART
|
||||
* and one on TCP/IP). This is done to prevent an output buffer being defined by
|
||||
* each implementation - which would waste RAM. In this case, there is only one
|
||||
* command interpreter running.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The buffer into which output generated by FreeRTOS+CLI is placed. This must
|
||||
* be at least big enough to contain the output of the task-stats command, as the
|
||||
* example implementation does not include buffer overlow checking.
|
||||
*/
|
||||
#define configCOMMAND_INT_MAX_OUTPUT_SIZE 2096
|
||||
#define configINCLUDE_QUERY_HEAP_COMMAND 1
|
||||
|
||||
/* This file is included from assembler files - make sure C code is not included in assembler files. */
|
||||
#ifndef __ASSEMBLER__
|
||||
void vAssertCalled(const char *pcFile, unsigned long ulLine);
|
||||
void vConfigureTickInterrupt(void);
|
||||
void vClearTickInterrupt(void);
|
||||
void vPreSleepProcessing(unsigned long uxExpectedIdleTime);
|
||||
void vPostSleepProcessing(unsigned long uxExpectedIdleTime);
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
/****** Hardware/compiler specific settings. *******/
|
||||
/*
|
||||
* The application must provide a function that configures a peripheral to
|
||||
* create the FreeRTOS tick interrupt, then define configSETUP_TICK_INTERRUPT()
|
||||
* in FreeRTOSConfig.h to call the function.
|
||||
*/
|
||||
#define configSETUP_TICK_INTERRUPT() vConfigureTickInterrupt()
|
||||
#define configCLEAR_TICK_INTERRUPT() vClearTickInterrupt()
|
||||
|
||||
/*
|
||||
* The configPRE_SLEEP_PROCESSING() and configPOST_SLEEP_PROCESSING() macros
|
||||
* allow the application writer to add additional code before and after the MCU is
|
||||
* placed into the low power state respectively. The empty implementations
|
||||
* provided in this demo can be extended to save even more power.
|
||||
*/
|
||||
#define configPRE_SLEEP_PROCESSING(uxExpectedIdleTime) vPreSleepProcessing(uxExpectedIdleTime);
|
||||
#define configPOST_SLEEP_PROCESSING(uxExpectedIdleTime) vPostSleepProcessing(uxExpectedIdleTime);
|
||||
|
||||
|
||||
/* Compiler specifics. */
|
||||
#define fabs(x) __builtin_fabs(x)
|
||||
|
||||
/* Enable Hardware Stack Protection and Recording mechanism. */
|
||||
#define configHSP_ENABLE 0
|
||||
|
||||
/* Record the highest address of stack. */
|
||||
#if (configHSP_ENABLE == 1 && configRECORD_STACK_HIGH_ADDRESS != 1)
|
||||
#define configRECORD_STACK_HIGH_ADDRESS 1
|
||||
#endif
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2021 hpmicro
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
/* FreeRTOS kernel includes. */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
|
||||
/* HPM example includes. */
|
||||
#include <stdio.h>
|
||||
#include "board.h"
|
||||
#include "hpm_gpio_drv.h"
|
||||
#include "usbh_core.h"
|
||||
|
||||
extern void usbh_class_test();
|
||||
|
||||
int main(void)
|
||||
{
|
||||
board_init();
|
||||
board_init_gpio_pins();
|
||||
board_init_usb_pins();
|
||||
#ifdef BOARD_LED_GPIO_CTRL
|
||||
gpio_set_pin_output(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX, BOARD_LED_GPIO_PIN);
|
||||
gpio_write_pin(BOARD_LED_GPIO_CTRL, BOARD_LED_GPIO_INDEX, BOARD_LED_GPIO_PIN, BOARD_LED_ON_LEVEL);
|
||||
#endif
|
||||
|
||||
printf("Start usb host task...\r\n");
|
||||
usbh_initialize();
|
||||
usbh_class_test();
|
||||
vTaskStartScheduler();
|
||||
for (;;) {
|
||||
;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,133 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2022, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef CHERRYUSB_CONFIG_H
|
||||
#define CHERRYUSB_CONFIG_H
|
||||
|
||||
#define CHERRYUSB_VERSION 0x000700
|
||||
|
||||
/* ================ USB common Configuration ================ */
|
||||
|
||||
#ifndef CONFIG_USB_DBG_LEVEL
|
||||
#define CONFIG_USB_DBG_LEVEL USB_DBG_INFO
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USB_PRINTF
|
||||
#define CONFIG_USB_PRINTF printf
|
||||
#endif
|
||||
|
||||
/* Enable print with color */
|
||||
#define CONFIG_USB_PRINTF_COLOR_ENABLE
|
||||
|
||||
/* data align size when use dma */
|
||||
#ifndef CONFIG_USB_ALIGN_SIZE
|
||||
#define CONFIG_USB_ALIGN_SIZE 4
|
||||
#endif
|
||||
|
||||
/* attribute data into no cache ram */
|
||||
#define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable")))
|
||||
|
||||
/* ================= USB Device Stack Configuration ================ */
|
||||
|
||||
/* Ep0 max transfer buffer, specially for receiving data from ep0 out */
|
||||
#define CONFIG_USBDEV_REQUEST_BUFFER_LEN 256
|
||||
|
||||
/* Setup packet log for debug */
|
||||
// #define CONFIG_USBDEV_SETUP_LOG_PRINT
|
||||
|
||||
/* Check if the input descriptor is correct */
|
||||
// #define CONFIG_USBDEV_DESC_CHECK
|
||||
|
||||
/* Enable test mode */
|
||||
// #define CONFIG_USBDEV_TEST_MODE
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_BLOCK_SIZE
|
||||
#define CONFIG_USBDEV_MSC_BLOCK_SIZE 512
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_MANUFACTURER_STRING
|
||||
#define CONFIG_USBDEV_MSC_MANUFACTURER_STRING ""
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_PRODUCT_STRING
|
||||
#define CONFIG_USBDEV_MSC_PRODUCT_STRING ""
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_VERSION_STRING
|
||||
#define CONFIG_USBDEV_MSC_VERSION_STRING "0.01"
|
||||
#endif
|
||||
|
||||
// #define CONFIG_USBDEV_MSC_THREAD
|
||||
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
#ifndef CONFIG_USBDEV_MSC_STACKSIZE
|
||||
#define CONFIG_USBDEV_MSC_STACKSIZE 2048
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_PRIO
|
||||
#define CONFIG_USBDEV_MSC_PRIO 4
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_AUDIO_VERSION
|
||||
#define CONFIG_USBDEV_AUDIO_VERSION 0x0100
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_AUDIO_MAX_CHANNEL
|
||||
#define CONFIG_USBDEV_AUDIO_MAX_CHANNEL 8
|
||||
#endif
|
||||
|
||||
/* ================ USB HOST Stack Configuration ================== */
|
||||
|
||||
#define CONFIG_USBHOST_MAX_RHPORTS 1
|
||||
#define CONFIG_USBHOST_MAX_EXTHUBS 1
|
||||
#define CONFIG_USBHOST_MAX_EHPORTS 4
|
||||
#define CONFIG_USBHOST_MAX_INTERFACES 6
|
||||
#define CONFIG_USBHOST_MAX_INTF_ALTSETTINGS 1
|
||||
#define CONFIG_USBHOST_MAX_ENDPOINTS 4
|
||||
|
||||
#define CONFIG_USBHOST_DEV_NAMELEN 16
|
||||
|
||||
#ifndef CONFIG_USBHOST_PSC_PRIO
|
||||
#define CONFIG_USBHOST_PSC_PRIO 4
|
||||
#endif
|
||||
#ifndef CONFIG_USBHOST_PSC_STACKSIZE
|
||||
#define CONFIG_USBHOST_PSC_STACKSIZE 2048
|
||||
#endif
|
||||
|
||||
//#define CONFIG_USBHOST_GET_STRING_DESC
|
||||
|
||||
/* Ep0 max transfer buffer */
|
||||
#define CONFIG_USBHOST_REQUEST_BUFFER_LEN 512
|
||||
|
||||
#ifndef CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT
|
||||
#define CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT 500
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBHOST_MSC_TIMEOUT
|
||||
#define CONFIG_USBHOST_MSC_TIMEOUT 5000
|
||||
#endif
|
||||
|
||||
/* ================ USB Device Port Configuration ================*/
|
||||
|
||||
//#define USBD_IRQHandler USBD_IRQHandler
|
||||
//#define USB_BASE (0x40080000UL)
|
||||
//#define USB_NUM_BIDIR_ENDPOINTS 4
|
||||
|
||||
/* ================ USB Host Port Configuration ==================*/
|
||||
|
||||
#define CONFIG_USBHOST_PIPE_NUM 10
|
||||
|
||||
/* ================ EHCI Configuration ================ */
|
||||
|
||||
#define CONFIG_USB_EHCI_HCCR_BASE (0)
|
||||
#define CONFIG_USB_EHCI_HCOR_BASE (0xF2020000UL + 0x140)
|
||||
#define CONFIG_EHCI_FRAME_LIST_SIZE 1024
|
||||
// #define CONFIG_USB_EHCI_INFO_ENABLE
|
||||
// #define CONFIG_USB_ECHI_HCOR_RESERVED_DISABLE
|
||||
// #define CONFIG_USB_EHCI_CONFIGFLAG
|
||||
#define CONFIG_USB_EHCI_PORT_POWER
|
||||
|
||||
#endif
|
||||
166
demo/mtp_template.c
Normal file
166
demo/mtp_template.c
Normal file
@@ -0,0 +1,166 @@
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_mtp.h"
|
||||
|
||||
#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 */
|
||||
};
|
||||
|
||||
struct usb_msosv1_descriptor msosv1_desc = {
|
||||
.string = (uint8_t *)WCID_StringDescriptor_MSOS,
|
||||
.string_len = 18,
|
||||
.vendor_code = WCID_VENDOR_CODE,
|
||||
.compat_id = (uint8_t *)WINUSB_WCIDDescriptor,
|
||||
.compat_id_len = sizeof(WINUSB_WCIDDescriptor),
|
||||
.comp_id_property = NULL,
|
||||
.comp_id_property_len = 0,
|
||||
};
|
||||
|
||||
/*!< endpoint address */
|
||||
#define CDC_IN_EP 0x81
|
||||
#define CDC_OUT_EP 0x02
|
||||
#define CDC_INT_EP 0x83
|
||||
|
||||
#define USBD_VID 0xFFFE
|
||||
#define USBD_PID 0xFFFF
|
||||
#define USBD_MAX_POWER 100
|
||||
#define USBD_LANGID_STRING 1033
|
||||
|
||||
/*!< config descriptor size */
|
||||
#define USB_CONFIG_SIZE (9 + MTP_DESCRIPTOR_LEN)
|
||||
|
||||
const uint8_t mtp_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0201, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
MTP_DESCRIPTOR_INIT(0x00, CDC_OUT_EP, CDC_IN_EP, CDC_INT_EP, 2),
|
||||
///////////////////////////////////////
|
||||
/// 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 */
|
||||
'M', 0x00, /* wcChar10 */
|
||||
'T', 0x00, /* wcChar11 */
|
||||
'P', 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 */
|
||||
'1', 0x00, /* wcChar3 */
|
||||
'0', 0x00, /* wcChar4 */
|
||||
'3', 0x00, /* wcChar5 */
|
||||
'1', 0x00, /* wcChar6 */
|
||||
'0', 0x00, /* wcChar7 */
|
||||
'0', 0x00, /* wcChar8 */
|
||||
'0', 0x00, /* wcChar9 */
|
||||
#ifdef CONFIG_USB_HS
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x02,
|
||||
0x02,
|
||||
0x01,
|
||||
0x40,
|
||||
0x01,
|
||||
0x00,
|
||||
#endif
|
||||
0x00
|
||||
};
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
void usbd_configure_done_callback(void)
|
||||
{
|
||||
}
|
||||
|
||||
struct usbd_interface intf0;
|
||||
|
||||
struct usb_bos_descriptor bos_desc = {
|
||||
.string = bos_descriptor,
|
||||
.string_len = 22
|
||||
};
|
||||
|
||||
void mtp_init(void)
|
||||
{
|
||||
usbd_desc_register(mtp_descriptor);
|
||||
usbd_msosv1_desc_register(&msosv1_desc);
|
||||
usbd_bos_desc_register(&bos_desc);
|
||||
usbd_add_interface(usbd_mtp_init_intf(&intf0, CDC_OUT_EP, CDC_IN_EP, CDC_INT_EP));
|
||||
usbd_initialize();
|
||||
}
|
||||
@@ -1,22 +1,22 @@
|
||||
/*
|
||||
* Copyright : (C) 2022 Phytium Information Technology, Inc.
|
||||
* Copyright : (C) 2022 Phytium Information Technology, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This program is OPEN SOURCE software: you can redistribute it and/or modify it
|
||||
* under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
|
||||
* either version 1.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
|
||||
*
|
||||
* This program is OPEN SOURCE software: you can redistribute it and/or modify it
|
||||
* under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
|
||||
* either version 1.0 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the Phytium Public License for more details.
|
||||
*
|
||||
*
|
||||
* See the Phytium Public License for more details.
|
||||
*
|
||||
*
|
||||
* FilePath: usb_config.h
|
||||
* Date: 2022-09-19 17:28:44
|
||||
* LastEditTime: 2022-09-19 17:28:45
|
||||
* Description: This files is for usb hc xhci configuration
|
||||
*
|
||||
* Modify History:
|
||||
*
|
||||
* Modify History:
|
||||
* Ver Who Date Changes
|
||||
* ----- ------ -------- --------------------------------------
|
||||
* 1.0 zhugengyu 2022/9/19 init commit
|
||||
@@ -28,14 +28,18 @@
|
||||
|
||||
/* ================ USB common Configuration ================ */
|
||||
|
||||
#define CONFIG_USB_PRINTF(...) printf(__VA_ARGS__)
|
||||
|
||||
extern void *usb_hc_malloc(size_t size);
|
||||
extern void *usb_hc_free(size_t size);
|
||||
|
||||
#define usb_malloc(size) usb_hc_malloc(size)
|
||||
#define usb_free(ptr) usb_hc_free(ptr)
|
||||
|
||||
#ifndef CONFIG_USB_DBG_LEVEL
|
||||
#define CONFIG_USB_DBG_LEVEL USB_DBG_INFO
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USB_PRINTF
|
||||
#define CONFIG_USB_PRINTF printf
|
||||
#endif
|
||||
|
||||
/* Enable print with color */
|
||||
#define CONFIG_USB_PRINTF_COLOR_ENABLE
|
||||
|
||||
@@ -140,6 +144,6 @@
|
||||
#define CONFIG_USBHOST_PIPE_NUM 10
|
||||
|
||||
/* ================ XHCI Configuration ================ */
|
||||
#define CONFIG_USBHOST_XHCI
|
||||
#define CONFIG_USBHOST_XHCI
|
||||
|
||||
#endif
|
||||
312
demo/stm32/usb_device/stm32f429igt6/Core/Inc/FreeRTOSConfig.h
Normal file
312
demo/stm32/usb_device/stm32f429igt6/Core/Inc/FreeRTOSConfig.h
Normal file
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
|
||||
#include "stm32f4xx_hal.h"
|
||||
|
||||
//针对不同的编译器调用不同的stdint.h文件
|
||||
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
|
||||
#include <stdint.h>
|
||||
extern uint32_t SystemCoreClock;
|
||||
#endif
|
||||
|
||||
//断言
|
||||
|
||||
#define configASSERT(x)
|
||||
/************************************************************************
|
||||
* FreeRTOS基础配置配置选项
|
||||
*********************************************************************/
|
||||
/* 置1:RTOS使用抢占式调度器;置0:RTOS使用协作式调度器(时间片)
|
||||
*
|
||||
* 注:在多任务管理机制上,操作系统可以分为抢占式和协作式两种。
|
||||
* 协作式操作系统是任务主动释放CPU后,切换到下一个任务。
|
||||
* 任务切换的时机完全取决于正在运行的任务。
|
||||
*/
|
||||
#define configUSE_PREEMPTION 1
|
||||
|
||||
//1使能时间片调度(默认式使能的)
|
||||
#define configUSE_TIME_SLICING 1
|
||||
|
||||
/* 某些运行FreeRTOS的硬件有两种方法选择下一个要执行的任务:
|
||||
* 通用方法和特定于硬件的方法(以下简称“特殊方法”)。
|
||||
*
|
||||
* 通用方法:
|
||||
* 1.configUSE_PORT_OPTIMISED_TASK_SELECTION 为 0 或者硬件不支持这种特殊方法。
|
||||
* 2.可以用于所有FreeRTOS支持的硬件
|
||||
* 3.完全用C实现,效率略低于特殊方法。
|
||||
* 4.不强制要求限制最大可用优先级数目
|
||||
* 特殊方法:
|
||||
* 1.必须将configUSE_PORT_OPTIMISED_TASK_SELECTION设置为1。
|
||||
* 2.依赖一个或多个特定架构的汇编指令(一般是类似计算前导零[CLZ]指令)。
|
||||
* 3.比通用方法更高效
|
||||
* 4.一般强制限定最大可用优先级数目为32
|
||||
* 一般是硬件计算前导零指令,如果所使用的,MCU没有这些硬件指令的话此宏应该设置为0!
|
||||
*/
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
|
||||
/* 置1:使能低功耗tickless模式;置0:保持系统节拍(tick)中断一直运行
|
||||
* 假设开启低功耗的话可能会导致下载出现问题,因为程序在睡眠中,可用以下办法解决
|
||||
*
|
||||
* 下载方法:
|
||||
* 1.将开发版正常连接好
|
||||
* 2.按住复位按键,点击下载瞬间松开复位按键
|
||||
*
|
||||
* 1.通过跳线帽将 BOOT 0 接高电平(3.3V)
|
||||
* 2.重新上电,下载
|
||||
*
|
||||
* 1.使用FlyMcu擦除一下芯片,然后进行下载
|
||||
* STMISP -> 清除芯片(z)
|
||||
*/
|
||||
#define configUSE_TICKLESS_IDLE 0
|
||||
|
||||
/*
|
||||
* 写入实际的CPU内核时钟频率,也就是CPU指令执行频率,通常称为Fclk
|
||||
* Fclk为供给CPU内核的时钟信号,我们所说的cpu主频为 XX MHz,
|
||||
* 就是指的这个时钟信号,相应的,1/Fclk即为cpu时钟周期;
|
||||
*/
|
||||
#define configCPU_CLOCK_HZ (SystemCoreClock)
|
||||
|
||||
//RTOS系统节拍中断的频率。即一秒中断的次数,每次中断RTOS都会进行任务调度
|
||||
#define configTICK_RATE_HZ (( TickType_t )1000)
|
||||
|
||||
//可使用的最大优先级
|
||||
#define configMAX_PRIORITIES (32)
|
||||
|
||||
//空闲任务使用的堆栈大小
|
||||
#define configMINIMAL_STACK_SIZE ((unsigned short)128)
|
||||
|
||||
//任务名字字符串长度
|
||||
#define configMAX_TASK_NAME_LEN (16)
|
||||
|
||||
//系统节拍计数器变量数据类型,1表示为16位无符号整形,0表示为32位无符号整形
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
|
||||
//空闲任务放弃CPU使用权给其他同优先级的用户任务
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
|
||||
//启用队列
|
||||
#define configUSE_QUEUE_SETS 1
|
||||
|
||||
//开启任务通知功能,默认开启
|
||||
#define configUSE_TASK_NOTIFICATIONS 1
|
||||
|
||||
//使用互斥信号量
|
||||
#define configUSE_MUTEXES 1
|
||||
|
||||
//使用递归互斥信号量
|
||||
#define configUSE_RECURSIVE_MUTEXES 0
|
||||
|
||||
//为1时使用计数信号量
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
|
||||
/* 设置可以注册的信号量和消息队列个数 */
|
||||
#define configQUEUE_REGISTRY_SIZE 10
|
||||
|
||||
#define configUSE_APPLICATION_TASK_TAG 0
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
FreeRTOS与内存申请有关配置选项
|
||||
*****************************************************************/
|
||||
//支持动态内存申请
|
||||
#define configSUPPORT_DYNAMIC_ALLOCATION 1
|
||||
//支持静态内存
|
||||
#define configSUPPORT_STATIC_ALLOCATION 0
|
||||
//系统所有总的堆大小
|
||||
#define configTOTAL_HEAP_SIZE ((size_t)(36*1024))
|
||||
|
||||
|
||||
/***************************************************************
|
||||
FreeRTOS与钩子函数有关的配置选项
|
||||
**************************************************************/
|
||||
/* 置1:使用空闲钩子(Idle Hook类似于回调函数);置0:忽略空闲钩子
|
||||
*
|
||||
* 空闲任务钩子是一个函数,这个函数由用户来实现,
|
||||
* FreeRTOS规定了函数的名字和参数:void vApplicationIdleHook(void ),
|
||||
* 这个函数在每个空闲任务周期都会被调用
|
||||
* 对于已经删除的RTOS任务,空闲任务可以释放分配给它们的堆栈内存。
|
||||
* 因此必须保证空闲任务可以被CPU执行
|
||||
* 使用空闲钩子函数设置CPU进入省电模式是很常见的
|
||||
* 不可以调用会引起空闲任务阻塞的API函数
|
||||
*/
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
|
||||
/* 置1:使用时间片钩子(Tick Hook);置0:忽略时间片钩子
|
||||
*
|
||||
*
|
||||
* 时间片钩子是一个函数,这个函数由用户来实现,
|
||||
* FreeRTOS规定了函数的名字和参数:void vApplicationTickHook(void )
|
||||
* 时间片中断可以周期性的调用
|
||||
* 函数必须非常短小,不能大量使用堆栈,
|
||||
* 不能调用以”FromISR" 或 "FROM_ISR”结尾的API函数
|
||||
*/
|
||||
/*xTaskIncrementTick函数是在xPortSysTickHandler中断函数中被调用的。因此,vApplicationTickHook()函数执行的时间必须很短才行*/
|
||||
#define configUSE_TICK_HOOK 0
|
||||
|
||||
//使用内存申请失败钩子函数
|
||||
#define configUSE_MALLOC_FAILED_HOOK 0
|
||||
|
||||
/*
|
||||
* 大于0时启用堆栈溢出检测功能,如果使用此功能
|
||||
* 用户必须提供一个栈溢出钩子函数,如果使用的话
|
||||
* 此值可以为1或者2,因为有两种栈溢出检测方法 */
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 0
|
||||
|
||||
|
||||
/********************************************************************
|
||||
FreeRTOS与运行时间和任务状态收集有关的配置选项
|
||||
**********************************************************************/
|
||||
//启用运行时间统计功能
|
||||
#define configGENERATE_RUN_TIME_STATS 0
|
||||
//启用可视化跟踪调试
|
||||
#define configUSE_TRACE_FACILITY 0
|
||||
/* 与宏configUSE_TRACE_FACILITY同时为1时会编译下面3个函数
|
||||
* prvWriteNameToBuffer()
|
||||
* vTaskList(),
|
||||
* vTaskGetRunTimeStats()
|
||||
*/
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
|
||||
|
||||
|
||||
/********************************************************************
|
||||
FreeRTOS与协程有关的配置选项
|
||||
*********************************************************************/
|
||||
//启用协程,启用协程以后必须添加文件croutine.c
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
//协程的有效优先级数目
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
FreeRTOS与软件定时器有关的配置选项
|
||||
**********************************************************************/
|
||||
//启用软件定时器
|
||||
#define configUSE_TIMERS 1
|
||||
//软件定时器优先级
|
||||
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-1)
|
||||
//软件定时器队列长度
|
||||
#define configTIMER_QUEUE_LENGTH 10
|
||||
//软件定时器任务堆栈大小
|
||||
#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE*2)
|
||||
|
||||
/************************************************************
|
||||
FreeRTOS可选函数配置选项
|
||||
************************************************************/
|
||||
#define INCLUDE_xTaskGetSchedulerState 1
|
||||
#define INCLUDE_vTaskPrioritySet 1
|
||||
#define INCLUDE_uxTaskPriorityGet 1
|
||||
#define INCLUDE_vTaskDelete 1
|
||||
#define INCLUDE_vTaskCleanUpResources 1
|
||||
#define INCLUDE_vTaskSuspend 1
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_eTaskGetState 1
|
||||
#define INCLUDE_xTimerPendFunctionCall 1
|
||||
//#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||
//#define INCLUDE_uxTaskGetStackHighWaterMark 0
|
||||
//#define INCLUDE_xTaskGetIdleTaskHandle 0
|
||||
|
||||
|
||||
/******************************************************************
|
||||
FreeRTOS与中断有关的配置选项
|
||||
******************************************************************/
|
||||
#ifdef __NVIC_PRIO_BITS
|
||||
#define configPRIO_BITS __NVIC_PRIO_BITS
|
||||
#else
|
||||
#define configPRIO_BITS 4
|
||||
#endif
|
||||
//中断最低优先级
|
||||
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
|
||||
|
||||
//系统可管理的最高中断优先级
|
||||
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
|
||||
|
||||
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* 240 */
|
||||
|
||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - 4) )
|
||||
|
||||
|
||||
/****************************************************************
|
||||
FreeRTOS与中断服务函数有关的配置选项
|
||||
****************************************************************/
|
||||
#define xPortPendSVHandler PendSV_Handler
|
||||
#define vPortSVCHandler SVC_Handler
|
||||
|
||||
|
||||
/* 以下为使用Percepio Tracealyzer需要的东西,不需要时将 configUSE_TRACE_FACILITY 定义为 0 */
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
#include "trcRecorder.h"
|
||||
#define INCLUDE_xTaskGetCurrentTaskHandle 1 // 启用一个可选函数(该函数被 Trace源码使用,默认该值为0 表示不用)
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
||||
|
||||
@@ -44,6 +44,27 @@
|
||||
/* Enable test mode */
|
||||
// #define CONFIG_USBDEV_TEST_MODE
|
||||
|
||||
//#define CONFIG_USBDEV_TX_THREAD
|
||||
//#define CONFIG_USBDEV_RX_THREAD
|
||||
|
||||
#ifdef CONFIG_USBDEV_TX_THREAD
|
||||
#ifndef CONFIG_USBDEV_TX_PRIO
|
||||
#define CONFIG_USBDEV_TX_PRIO 4
|
||||
#endif
|
||||
#ifndef CONFIG_USBDEV_TX_STACKSIZE
|
||||
#define CONFIG_USBDEV_TX_STACKSIZE 2048
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_RX_THREAD
|
||||
#ifndef CONFIG_USBDEV_RX_PRIO
|
||||
#define CONFIG_USBDEV_RX_PRIO 4
|
||||
#endif
|
||||
#ifndef CONFIG_USBDEV_RX_STACKSIZE
|
||||
#define CONFIG_USBDEV_RX_STACKSIZE 2048
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_BLOCK_SIZE
|
||||
#define CONFIG_USBDEV_MSC_BLOCK_SIZE 512
|
||||
#endif
|
||||
@@ -60,18 +81,6 @@
|
||||
#define CONFIG_USBDEV_MSC_VERSION_STRING "0.01"
|
||||
#endif
|
||||
|
||||
// #define CONFIG_USBDEV_MSC_THREAD
|
||||
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
#ifndef CONFIG_USBDEV_MSC_STACKSIZE
|
||||
#define CONFIG_USBDEV_MSC_STACKSIZE 2048
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_PRIO
|
||||
#define CONFIG_USBDEV_MSC_PRIO 4
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_AUDIO_VERSION
|
||||
#define CONFIG_USBDEV_AUDIO_VERSION 0x0100
|
||||
#endif
|
||||
@@ -80,6 +89,24 @@
|
||||
#define CONFIG_USBDEV_AUDIO_MAX_CHANNEL 8
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE
|
||||
#define CONFIG_USBDEV_RNDIS_RESP_BUFFER_SIZE 128
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE
|
||||
#define CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE 1536
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_RNDIS_VENDOR_ID
|
||||
#define CONFIG_USBDEV_RNDIS_VENDOR_ID 0x0000ffff
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_RNDIS_VENDOR_DESC
|
||||
#define CONFIG_USBDEV_RNDIS_VENDOR_DESC "CherryUSB"
|
||||
#endif
|
||||
|
||||
#define CONFIG_USBDEV_RNDIS_USING_LWIP
|
||||
|
||||
/* ================ USB HOST Stack Configuration ================== */
|
||||
|
||||
#define CONFIG_USBHOST_MAX_RHPORTS 1
|
||||
@@ -123,9 +150,9 @@
|
||||
|
||||
/* ================ EHCI Configuration ================ */
|
||||
|
||||
#define CONFIG_USB_EHCI_HCCR_BASE (0x20072000)
|
||||
#define CONFIG_USB_EHCI_HCOR_BASE (0x20072000 + 0x10)
|
||||
#define CONFIG_EHCI_FRAME_LIST_SIZE 1024
|
||||
#define CONFIG_USB_EHCI_HCCR_BASE (0x20072000)
|
||||
#define CONFIG_USB_EHCI_HCOR_BASE (0x20072000 + 0x10)
|
||||
#define CONFIG_USB_EHCI_FRAME_LIST_SIZE 1024
|
||||
// #define CONFIG_USB_EHCI_INFO_ENABLE
|
||||
// #define CONFIG_USB_ECHI_HCOR_RESERVED_DISABLE
|
||||
// #define CONFIG_USB_EHCI_CONFIGFLAG
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_cdc.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
@@ -126,10 +128,13 @@ int main(void)
|
||||
//MX_USB_OTG_HS_PCD_Init();
|
||||
MX_USART1_UART_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
|
||||
|
||||
extern void cdc_acm_msc_init(void);
|
||||
|
||||
cdc_acm_msc_init();
|
||||
#if defined(CONFIG_USBDEV_TX_THREAD) || defined(CONFIG_USBDEV_RX_THREAD)
|
||||
vTaskStartScheduler();
|
||||
#endif
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* Infinite loop */
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#include "stm32f4xx_it.h"
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
@@ -142,15 +144,15 @@ void UsageFault_Handler(void)
|
||||
/**
|
||||
* @brief This function handles System service call via SWI instruction.
|
||||
*/
|
||||
void SVC_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN SVCall_IRQn 0 */
|
||||
//void SVC_Handler(void)
|
||||
//{
|
||||
// /* USER CODE BEGIN SVCall_IRQn 0 */
|
||||
|
||||
/* USER CODE END SVCall_IRQn 0 */
|
||||
/* USER CODE BEGIN SVCall_IRQn 1 */
|
||||
// /* USER CODE END SVCall_IRQn 0 */
|
||||
// /* USER CODE BEGIN SVCall_IRQn 1 */
|
||||
|
||||
/* USER CODE END SVCall_IRQn 1 */
|
||||
}
|
||||
// /* USER CODE END SVCall_IRQn 1 */
|
||||
//}
|
||||
|
||||
/**
|
||||
* @brief This function handles Debug monitor.
|
||||
@@ -168,15 +170,15 @@ void DebugMon_Handler(void)
|
||||
/**
|
||||
* @brief This function handles Pendable request for system service.
|
||||
*/
|
||||
void PendSV_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN PendSV_IRQn 0 */
|
||||
//void PendSV_Handler(void)
|
||||
//{
|
||||
// /* USER CODE BEGIN PendSV_IRQn 0 */
|
||||
|
||||
/* USER CODE END PendSV_IRQn 0 */
|
||||
/* USER CODE BEGIN PendSV_IRQn 1 */
|
||||
// /* USER CODE END PendSV_IRQn 0 */
|
||||
// /* USER CODE BEGIN PendSV_IRQn 1 */
|
||||
|
||||
/* USER CODE END PendSV_IRQn 1 */
|
||||
}
|
||||
// /* USER CODE END PendSV_IRQn 1 */
|
||||
//}
|
||||
|
||||
/**
|
||||
* @brief This function handles System tick timer.
|
||||
@@ -184,7 +186,15 @@ void PendSV_Handler(void)
|
||||
void SysTick_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN SysTick_IRQn 0 */
|
||||
|
||||
extern void xPortSysTickHandler(void);
|
||||
#if (INCLUDE_xTaskGetSchedulerState == 1 )
|
||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
|
||||
{
|
||||
#endif /* INCLUDE_xTaskGetSchedulerState */
|
||||
xPortSysTickHandler();
|
||||
#if (INCLUDE_xTaskGetSchedulerState == 1 )
|
||||
}
|
||||
#endif /* INCLUDE_xTaskGetSchedulerState */
|
||||
/* USER CODE END SysTick_IRQn 0 */
|
||||
HAL_IncTick();
|
||||
/* USER CODE BEGIN SysTick_IRQn 1 */
|
||||
|
||||
@@ -157,6 +157,22 @@
|
||||
<Bp>
|
||||
<Number>0</Number>
|
||||
<Type>0</Type>
|
||||
<LineNumber>810</LineNumber>
|
||||
<EnabledFlag>1</EnabledFlag>
|
||||
<Address>0</Address>
|
||||
<ByteObject>0</ByteObject>
|
||||
<HtxType>0</HtxType>
|
||||
<ManyObjects>0</ManyObjects>
|
||||
<SizeOfObject>0</SizeOfObject>
|
||||
<BreakByAccess>0</BreakByAccess>
|
||||
<BreakIfRCount>0</BreakIfRCount>
|
||||
<Filename>..\..\..\..\..\class\msc\usbd_msc.c</Filename>
|
||||
<ExecCommand></ExecCommand>
|
||||
<Expression></Expression>
|
||||
</Bp>
|
||||
<Bp>
|
||||
<Number>1</Number>
|
||||
<Type>0</Type>
|
||||
<LineNumber>899</LineNumber>
|
||||
<EnabledFlag>1</EnabledFlag>
|
||||
<Address>0</Address>
|
||||
@@ -225,7 +241,7 @@
|
||||
|
||||
<Group>
|
||||
<GroupName>Application/MDK-ARM</GroupName>
|
||||
<tvExp>1</tvExp>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<cbSel>0</cbSel>
|
||||
<RteFlg>0</RteFlg>
|
||||
@@ -585,6 +601,134 @@
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>5</GroupNumber>
|
||||
<FileNumber>28</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\..\..\..\osal\usb_osal_freertos.c</PathWithFileName>
|
||||
<FilenameWithoutPath>usb_osal_freertos.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
</Group>
|
||||
|
||||
<Group>
|
||||
<GroupName>FreeRTOS</GroupName>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<cbSel>0</cbSel>
|
||||
<RteFlg>0</RteFlg>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>29</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\..\..\..\third_party\FreeRTOS-10.4\croutine.c</PathWithFileName>
|
||||
<FilenameWithoutPath>croutine.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>30</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\..\..\..\third_party\FreeRTOS-10.4\event_groups.c</PathWithFileName>
|
||||
<FilenameWithoutPath>event_groups.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>31</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\..\..\..\third_party\FreeRTOS-10.4\list.c</PathWithFileName>
|
||||
<FilenameWithoutPath>list.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>32</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\..\..\..\third_party\FreeRTOS-10.4\queue.c</PathWithFileName>
|
||||
<FilenameWithoutPath>queue.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>33</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\..\..\..\third_party\FreeRTOS-10.4\stream_buffer.c</PathWithFileName>
|
||||
<FilenameWithoutPath>stream_buffer.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>34</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\..\..\..\third_party\FreeRTOS-10.4\tasks.c</PathWithFileName>
|
||||
<FilenameWithoutPath>tasks.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>35</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\..\..\..\third_party\FreeRTOS-10.4\timers.c</PathWithFileName>
|
||||
<FilenameWithoutPath>timers.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>36</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\..\..\..\third_party\FreeRTOS-10.4\portable\MemMang\heap_4.c</PathWithFileName>
|
||||
<FilenameWithoutPath>heap_4.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>37</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\..\..\..\third_party\FreeRTOS-10.4\portable\GCC\ARM_CM4F\port.c</PathWithFileName>
|
||||
<FilenameWithoutPath>port.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
</Group>
|
||||
|
||||
<Group>
|
||||
|
||||
@@ -340,7 +340,7 @@
|
||||
<MiscControls></MiscControls>
|
||||
<Define>USE_HAL_DRIVER,STM32F429xx,CONFIG_USB_DWC2_PORT=HS_PORT</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>../Core/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;..\..\..\..\..\core;..\..\..\..\..\common;..\..\..\..\..\class\cdc;..\..\..\..\..\class\msc;..\..\..\..\..\class\hid;..\..\..\..\..\class\audio;..\..\..\..\..\class\video</IncludePath>
|
||||
<IncludePath>../Core/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;..\..\..\..\..\core;..\..\..\..\..\common;..\..\..\..\..\class\cdc;..\..\..\..\..\class\msc;..\..\..\..\..\class\hid;..\..\..\..\..\class\audio;..\..\..\..\..\class\video;..\..\..\..\..\third_party\FreeRTOS-10.4\include;..\..\..\..\..\third_party\FreeRTOS-10.4\portable\GCC\ARM_CM4F;..\..\..\..\..\osal</IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
<Aads>
|
||||
@@ -590,6 +590,61 @@
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\..\port\dwc2\usb_dc_dwc2.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>usb_osal_freertos.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\..\osal\usb_osal_freertos.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>FreeRTOS</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>croutine.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\..\third_party\FreeRTOS-10.4\croutine.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>event_groups.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\..\third_party\FreeRTOS-10.4\event_groups.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>list.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\..\third_party\FreeRTOS-10.4\list.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>queue.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\..\third_party\FreeRTOS-10.4\queue.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>stream_buffer.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\..\third_party\FreeRTOS-10.4\stream_buffer.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>tasks.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\..\third_party\FreeRTOS-10.4\tasks.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>timers.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\..\third_party\FreeRTOS-10.4\timers.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>heap_4.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\..\third_party\FreeRTOS-10.4\portable\MemMang\heap_4.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>port.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\..\third_party\FreeRTOS-10.4\portable\GCC\ARM_CM4F\port.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
|
||||
@@ -798,6 +798,18 @@
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\..\..\..\class\audio\usbh_audio.c</PathWithFileName>
|
||||
<FilenameWithoutPath>usbh_audio.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>41</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\..\..\..\class\video\usbh_video.c</PathWithFileName>
|
||||
<FilenameWithoutPath>usbh_video.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
@@ -805,7 +817,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>41</FileNumber>
|
||||
<FileNumber>42</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -817,7 +829,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>42</FileNumber>
|
||||
<FileNumber>43</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -837,7 +849,7 @@
|
||||
<RteFlg>0</RteFlg>
|
||||
<File>
|
||||
<GroupNumber>7</GroupNumber>
|
||||
<FileNumber>43</FileNumber>
|
||||
<FileNumber>44</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -849,7 +861,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>7</GroupNumber>
|
||||
<FileNumber>44</FileNumber>
|
||||
<FileNumber>45</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -861,7 +873,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>7</GroupNumber>
|
||||
<FileNumber>45</FileNumber>
|
||||
<FileNumber>46</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -873,7 +885,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>7</GroupNumber>
|
||||
<FileNumber>46</FileNumber>
|
||||
<FileNumber>47</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
@@ -885,7 +897,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>7</GroupNumber>
|
||||
<FileNumber>47</FileNumber>
|
||||
<FileNumber>48</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
|
||||
@@ -314,7 +314,7 @@
|
||||
</ArmAdsMisc>
|
||||
<Cads>
|
||||
<interw>1</interw>
|
||||
<Optim>1</Optim>
|
||||
<Optim>3</Optim>
|
||||
<oTime>0</oTime>
|
||||
<SplitLS>0</SplitLS>
|
||||
<OneElfS>1</OneElfS>
|
||||
@@ -340,7 +340,7 @@
|
||||
<MiscControls></MiscControls>
|
||||
<Define>USE_HAL_DRIVER,STM32F429xx</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>../Core/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;..\..\..\..\..\common;..\..\..\..\..\core;..\..\..\..\..\class\cdc;..\..\..\..\..\class\hub;..\..\..\..\..\class\hid;..\..\..\..\..\class\msc;..\..\..\..\..\class\wireless;..\..\..\..\..\class\video;..\..\..\..\..\osal;..\..\..\..\..\third_party\FreeRTOS-10.4\include;..\..\..\..\..\third_party\FreeRTOS-10.4\portable\GCC\ARM_CM4F;..\..\..\..\..\third_party\fatfs-0.14\source</IncludePath>
|
||||
<IncludePath>../Core/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;..\..\..\..\..\common;..\..\..\..\..\core;..\..\..\..\..\class\cdc;..\..\..\..\..\class\hub;..\..\..\..\..\class\hid;..\..\..\..\..\class\msc;..\..\..\..\..\class\wireless;..\..\..\..\..\class\video;..\..\..\..\..\class\audio;..\..\..\..\..\osal;..\..\..\..\..\third_party\FreeRTOS-10.4\include;..\..\..\..\..\third_party\FreeRTOS-10.4\portable\GCC\ARM_CM4F;..\..\..\..\..\third_party\fatfs-0.14\source</IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
<Aads>
|
||||
@@ -604,6 +604,11 @@
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\..\class\wireless\usbh_rndis.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>usbh_audio.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\..\class\audio\usbh_audio.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>usbh_video.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
|
||||
@@ -848,8 +848,8 @@
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\..\..\..\class\video\usbh_video.c</PathWithFileName>
|
||||
<FilenameWithoutPath>usbh_video.c</FilenameWithoutPath>
|
||||
<PathWithFileName>..\..\..\..\..\class\wireless\usbh_rndis.c</PathWithFileName>
|
||||
<FilenameWithoutPath>usbh_rndis.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
@@ -860,8 +860,8 @@
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\..\..\..\class\wireless\usbh_rndis.c</PathWithFileName>
|
||||
<FilenameWithoutPath>usbh_rndis.c</FilenameWithoutPath>
|
||||
<PathWithFileName>..\..\..\..\..\class\audio\usbh_audio.c</PathWithFileName>
|
||||
<FilenameWithoutPath>usbh_audio.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
@@ -872,6 +872,18 @@
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\..\..\..\class\video\usbh_video.c</PathWithFileName>
|
||||
<FilenameWithoutPath>usbh_video.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
<bShared>0</bShared>
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>45</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
<bDave2>0</bDave2>
|
||||
<PathWithFileName>..\..\..\..\..\osal\usb_osal_freertos.c</PathWithFileName>
|
||||
<FilenameWithoutPath>usb_osal_freertos.c</FilenameWithoutPath>
|
||||
<RteFlg>0</RteFlg>
|
||||
@@ -879,7 +891,7 @@
|
||||
</File>
|
||||
<File>
|
||||
<GroupNumber>6</GroupNumber>
|
||||
<FileNumber>45</FileNumber>
|
||||
<FileNumber>46</FileNumber>
|
||||
<FileType>1</FileType>
|
||||
<tvExp>0</tvExp>
|
||||
<tvExpOptDlg>0</tvExpOptDlg>
|
||||
|
||||
@@ -340,7 +340,7 @@
|
||||
<MiscControls></MiscControls>
|
||||
<Define>USE_HAL_DRIVER,STM32H743xx,STM32H7</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>../Core/Inc;../Drivers/STM32H7xx_HAL_Driver/Inc;../Drivers/STM32H7xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32H7xx/Include;../Drivers/CMSIS/Include;..\..\..\..\..\core;..\..\..\..\..\common;..\..\..\..\..\osal;..\..\..\..\..\class\cdc;..\..\..\..\..\class\hid;..\..\..\..\..\class\msc;..\..\..\..\..\class\hub;..\..\..\..\..\class\wireless;..\..\..\..\..\class\video;..\..\..\..\..\third_party\FreeRTOS-10.4\include;..\..\..\..\..\third_party\FreeRTOS-10.4\portable\GCC\ARM_CM7\r0p1</IncludePath>
|
||||
<IncludePath>../Core/Inc;../Drivers/STM32H7xx_HAL_Driver/Inc;../Drivers/STM32H7xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32H7xx/Include;../Drivers/CMSIS/Include;..\..\..\..\..\core;..\..\..\..\..\common;..\..\..\..\..\osal;..\..\..\..\..\class\cdc;..\..\..\..\..\class\hid;..\..\..\..\..\class\msc;..\..\..\..\..\class\hub;..\..\..\..\..\class\wireless;..\..\..\..\..\class\video;..\..\..\..\..\class\audio;..\..\..\..\..\third_party\FreeRTOS-10.4\include;..\..\..\..\..\third_party\FreeRTOS-10.4\portable\GCC\ARM_CM7\r0p1</IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
<Aads>
|
||||
@@ -614,16 +614,21 @@
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\..\class\msc\usbh_msc.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>usbh_video.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\..\class\video\usbh_video.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>usbh_rndis.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\..\class\wireless\usbh_rndis.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>usbh_audio.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\..\class\audio\usbh_audio.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>usbh_video.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\..\..\..\..\class\video\usbh_video.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>usb_osal_freertos.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
|
||||
351
demo/usb_host.c
351
demo/usb_host.c
@@ -3,7 +3,16 @@
|
||||
#include "usbh_hid.h"
|
||||
#include "usbh_msc.h"
|
||||
#include "usbh_video.h"
|
||||
#include "usbh_audio.h"
|
||||
|
||||
#define TEST_USBH_CDC_ACM 1
|
||||
#define TEST_USBH_HID 1
|
||||
#define TEST_USBH_MSC 1
|
||||
#define TEST_USBH_MSC_FATFS 0
|
||||
#define TEST_USBH_AUDIO 0
|
||||
#define TEST_USBH_VIDEO 0
|
||||
|
||||
#if TEST_USBH_CDC_ACM
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t cdc_buffer[512];
|
||||
|
||||
struct usbh_urb cdc_bulkin_urb;
|
||||
@@ -17,57 +26,122 @@ void usbh_cdc_acm_callback(void *arg, int nbytes)
|
||||
for (size_t i = 0; i < nbytes; i++) {
|
||||
USB_LOG_RAW("0x%02x ", cdc_buffer[i]);
|
||||
}
|
||||
USB_LOG_RAW("nbytes:%d\r\n", nbytes);
|
||||
}
|
||||
|
||||
USB_LOG_RAW("nbytes:%d\r\n", nbytes);
|
||||
}
|
||||
|
||||
int cdc_acm_test(void)
|
||||
static void usbh_cdc_acm_thread(void *argument)
|
||||
{
|
||||
int ret;
|
||||
struct usbh_cdc_acm *cdc_acm_class;
|
||||
|
||||
struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)usbh_find_class_instance("/dev/ttyACM0");
|
||||
while (1) {
|
||||
// clang-format off
|
||||
find_class:
|
||||
// clang-format on
|
||||
cdc_acm_class = (struct usbh_cdc_acm *)usbh_find_class_instance("/dev/ttyACM0");
|
||||
if (cdc_acm_class == NULL) {
|
||||
USB_LOG_RAW("do not find /dev/ttyACM0\r\n");
|
||||
usb_osal_msleep(1000);
|
||||
continue;
|
||||
}
|
||||
memset(cdc_buffer, 0, 512);
|
||||
|
||||
if (cdc_acm_class == NULL) {
|
||||
USB_LOG_RAW("do not find /dev/ttyACM0\r\n");
|
||||
return -1;
|
||||
}
|
||||
usbh_bulk_urb_fill(&cdc_bulkin_urb, cdc_acm_class->bulkin, cdc_buffer, 64, 3000, NULL, NULL);
|
||||
ret = usbh_submit_urb(&cdc_bulkin_urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_RAW("bulk in error,ret:%d\r\n", ret);
|
||||
} else {
|
||||
USB_LOG_RAW("recv over:%d\r\n", cdc_bulkin_urb.actual_length);
|
||||
for (size_t i = 0; i < cdc_bulkin_urb.actual_length; i++) {
|
||||
USB_LOG_RAW("0x%02x ", cdc_buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
memset(cdc_buffer, 0, 512);
|
||||
USB_LOG_RAW("\r\n");
|
||||
const uint8_t data1[10] = { 0x02, 0x00, 0x00, 0x00, 0x02, 0x02, 0x08, 0x14 };
|
||||
|
||||
usbh_bulk_urb_fill(&cdc_bulkin_urb, cdc_acm_class->bulkin, cdc_buffer, 64, 3000, NULL, NULL);
|
||||
ret = usbh_submit_urb(&cdc_bulkin_urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_RAW("bulk in error,ret:%d\r\n", ret);
|
||||
} else {
|
||||
USB_LOG_RAW("recv over:%d\r\n", cdc_bulkin_urb.actual_length);
|
||||
for (size_t i = 0; i < cdc_bulkin_urb.actual_length; i++) {
|
||||
USB_LOG_RAW("0x%02x ", cdc_buffer[i]);
|
||||
memcpy(cdc_buffer, data1, 8);
|
||||
usbh_bulk_urb_fill(&cdc_bulkout_urb, cdc_acm_class->bulkout, cdc_buffer, 8, 3000, NULL, NULL);
|
||||
ret = usbh_submit_urb(&cdc_bulkout_urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_RAW("bulk out error,ret:%d\r\n", ret);
|
||||
} else {
|
||||
USB_LOG_RAW("send over:%d\r\n", cdc_bulkout_urb.actual_length);
|
||||
}
|
||||
|
||||
usbh_bulk_urb_fill(&cdc_bulkin_urb, cdc_acm_class->bulkin, cdc_buffer, 64, 3000, usbh_cdc_acm_callback, cdc_acm_class);
|
||||
ret = usbh_submit_urb(&cdc_bulkin_urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_RAW("bulk in error,ret:%d\r\n", ret);
|
||||
} else {
|
||||
}
|
||||
|
||||
while (1) {
|
||||
cdc_acm_class = (struct usbh_cdc_acm *)usbh_find_class_instance("/dev/ttyACM0");
|
||||
if (cdc_acm_class == NULL) {
|
||||
goto find_class;
|
||||
}
|
||||
usb_osal_msleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
USB_LOG_RAW("\r\n");
|
||||
const uint8_t data1[10] = { 0x02, 0x00, 0x00, 0x00, 0x02, 0x02, 0x08, 0x14 };
|
||||
|
||||
memcpy(cdc_buffer, data1, 8);
|
||||
usbh_bulk_urb_fill(&cdc_bulkout_urb, cdc_acm_class->bulkout, cdc_buffer, 8, 3000, NULL, NULL);
|
||||
ret = usbh_submit_urb(&cdc_bulkout_urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_RAW("bulk out error,ret:%d\r\n", ret);
|
||||
} else {
|
||||
USB_LOG_RAW("send over:%d\r\n", cdc_bulkout_urb.actual_length);
|
||||
}
|
||||
|
||||
usbh_bulk_urb_fill(&cdc_bulkin_urb, cdc_acm_class->bulkin, cdc_buffer, 64, 3000, usbh_cdc_acm_callback, cdc_acm_class);
|
||||
ret = usbh_submit_urb(&cdc_bulkin_urb);
|
||||
if (ret < 0) {
|
||||
USB_LOG_RAW("bulk in error,ret:%d\r\n", ret);
|
||||
} else {
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#if 0
|
||||
#endif
|
||||
|
||||
#if TEST_USBH_HID
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t hid_buffer[128];
|
||||
|
||||
struct usbh_urb hid_intin_urb;
|
||||
|
||||
void usbh_hid_callback(void *arg, int nbytes)
|
||||
{
|
||||
//struct usbh_hid *hid_class = (struct usbh_hid *)arg;
|
||||
|
||||
if (nbytes > 0) {
|
||||
for (size_t i = 0; i < nbytes; i++) {
|
||||
USB_LOG_RAW("0x%02x ", hid_buffer[i]);
|
||||
}
|
||||
USB_LOG_RAW("nbytes:%d\r\n", nbytes);
|
||||
usbh_submit_urb(&hid_intin_urb);
|
||||
}
|
||||
}
|
||||
|
||||
static void usbh_hid_thread(void *argument)
|
||||
{
|
||||
int ret;
|
||||
struct usbh_hid *hid_class;
|
||||
|
||||
while (1) {
|
||||
// clang-format off
|
||||
find_class:
|
||||
// clang-format on
|
||||
hid_class = (struct usbh_hid *)usbh_find_class_instance("/dev/input0");
|
||||
if (hid_class == NULL) {
|
||||
USB_LOG_RAW("do not find /dev/input0\r\n");
|
||||
usb_osal_msleep(1500);
|
||||
continue;
|
||||
}
|
||||
usbh_int_urb_fill(&hid_intin_urb, hid_class->intin, hid_buffer, 8, 0, usbh_hid_callback, hid_class);
|
||||
ret = usbh_submit_urb(&hid_intin_urb);
|
||||
if (ret < 0) {
|
||||
usb_osal_msleep(1500);
|
||||
goto find_class;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
hid_class = (struct usbh_hid *)usbh_find_class_instance("/dev/input0");
|
||||
if (hid_class == NULL) {
|
||||
goto find_class;
|
||||
}
|
||||
usb_osal_msleep(1500);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TEST_USBH_MSC
|
||||
|
||||
#if TEST_USBH_MSC_FATFS
|
||||
#include "ff.h"
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_write_buffer[25 * 100];
|
||||
@@ -133,135 +207,110 @@ unmount:
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t partition_table[512];
|
||||
|
||||
int msc_test(void)
|
||||
static void usbh_msc_thread(void *argument)
|
||||
{
|
||||
int ret;
|
||||
struct usbh_msc *msc_class = (struct usbh_msc *)usbh_find_class_instance("/dev/sda");
|
||||
if (msc_class == NULL) {
|
||||
USB_LOG_RAW("do not find /dev/sda\r\n");
|
||||
return -1;
|
||||
}
|
||||
struct usbh_msc *msc_class;
|
||||
|
||||
while (1) {
|
||||
// clang-format off
|
||||
find_class:
|
||||
// clang-format on
|
||||
msc_class = (struct usbh_msc *)usbh_find_class_instance("/dev/sda");
|
||||
if (msc_class == NULL) {
|
||||
USB_LOG_RAW("do not find /dev/sda\r\n");
|
||||
usb_osal_msleep(2000);
|
||||
continue;
|
||||
}
|
||||
|
||||
#if 1
|
||||
/* get the partition table */
|
||||
ret = usbh_msc_scsi_read10(msc_class, 0, partition_table, 1);
|
||||
if (ret < 0) {
|
||||
USB_LOG_RAW("scsi_read10 error,ret:%d\r\n", ret);
|
||||
return ret;
|
||||
}
|
||||
for (uint32_t i = 0; i < 512; i++) {
|
||||
if (i % 16 == 0) {
|
||||
USB_LOG_RAW("\r\n");
|
||||
}
|
||||
USB_LOG_RAW("%02x ", partition_table[i]);
|
||||
}
|
||||
USB_LOG_RAW("\r\n");
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
usb_msc_fatfs_test();
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t hid_buffer[128];
|
||||
|
||||
struct usbh_urb hid_intin_urb;
|
||||
|
||||
void usbh_hid_callback(void *arg, int nbytes)
|
||||
{
|
||||
//struct usbh_hid *hid_class = (struct usbh_hid *)arg;
|
||||
|
||||
if (nbytes > 0) {
|
||||
for (size_t i = 0; i < nbytes; i++) {
|
||||
USB_LOG_RAW("0x%02x ", hid_buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
USB_LOG_RAW("nbytes:%d\r\n", nbytes);
|
||||
usbh_submit_urb(&hid_intin_urb);
|
||||
}
|
||||
|
||||
int hid_test(void)
|
||||
{
|
||||
int ret;
|
||||
struct usbh_hid *hid_class = (struct usbh_hid *)usbh_find_class_instance("/dev/input0");
|
||||
if (hid_class == NULL) {
|
||||
USB_LOG_RAW("do not find /dev/input0\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
usbh_int_urb_fill(&hid_intin_urb, hid_class->intin, hid_buffer, 8, 0, usbh_hid_callback, hid_class);
|
||||
ret = usbh_submit_urb(&hid_intin_urb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t video_buffer[10 * 1024]; /* just for reference , use ram larger than 4M */
|
||||
|
||||
#define VIDEO_ISO_PACKETS 512
|
||||
|
||||
int video_test(void)
|
||||
{
|
||||
int ret;
|
||||
struct usbh_video *video_class = (struct usbh_video *)usbh_find_class_instance("/dev/video0");
|
||||
if (video_class == NULL) {
|
||||
USB_LOG_RAW("do not find /dev/video0\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
usbh_videostreaming_set_cur_commit(video_class, 1, 1, 160 * 120 * 2, 512); /* select resolution from list ,just for reference now */
|
||||
|
||||
usbh_video_open(video_class, 7); /* select ep mps from altsettings ,just for reference now */
|
||||
usb_osal_msleep(100);
|
||||
|
||||
struct usbh_urb *video_urb = usb_malloc(sizeof(struct usbh_urb) + sizeof(struct usbh_iso_frame_packet) * VIDEO_ISO_PACKETS);
|
||||
if (video_urb == NULL) {
|
||||
USB_LOG_ERR("No memory to alloc urb\r\n");
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t *tmp_buf = video_buffer;
|
||||
memset(video_urb, 0, sizeof(struct usbh_urb) + sizeof(struct usbh_iso_frame_packet) * VIDEO_ISO_PACKETS);
|
||||
video_urb->pipe = video_class->isoin;
|
||||
video_urb->num_of_iso_packets = VIDEO_ISO_PACKETS;
|
||||
video_urb->timeout = 0xffffffff;
|
||||
for (uint32_t i = 0; i < VIDEO_ISO_PACKETS; i++) {
|
||||
video_urb->iso_packet[i].transfer_buffer = tmp_buf;
|
||||
video_urb->iso_packet[i].transfer_buffer_length = video_class->isoin_mps;
|
||||
//tmp_buf+=video_class->isoin_mps; /* enable this when use ram larger than 4M */
|
||||
}
|
||||
while (1) {
|
||||
ret = usbh_submit_urb(video_urb);
|
||||
/* get the partition table */
|
||||
ret = usbh_msc_scsi_read10(msc_class, 0, partition_table, 1);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Fail to submit urb:%d\r\n", ret);
|
||||
break;
|
||||
USB_LOG_RAW("scsi_read10 error,ret:%d\r\n", ret);
|
||||
usb_osal_msleep(2000);
|
||||
goto find_class;
|
||||
}
|
||||
for (uint32_t i = 0; i < 512; i++) {
|
||||
if (i % 16 == 0) {
|
||||
USB_LOG_RAW("\r\n");
|
||||
}
|
||||
USB_LOG_RAW("%02x ", partition_table[i]);
|
||||
}
|
||||
USB_LOG_RAW("\r\n");
|
||||
#endif
|
||||
|
||||
#if TEST_USBH_MSC_FATFS
|
||||
usb_msc_fatfs_test();
|
||||
#endif
|
||||
while (1) {
|
||||
msc_class = (struct usbh_msc *)usbh_find_class_instance("/dev/sda");
|
||||
if (msc_class == NULL) {
|
||||
goto find_class;
|
||||
}
|
||||
usb_osal_msleep(2000);
|
||||
}
|
||||
}
|
||||
usb_free(video_urb);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
void usbh_device_mount_done_callback(struct usbh_hubport *hport)
|
||||
void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class)
|
||||
{
|
||||
}
|
||||
|
||||
void usbh_device_unmount_done_callback(struct usbh_hubport *hport)
|
||||
void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class)
|
||||
{
|
||||
}
|
||||
|
||||
static void usbh_class_test_thread(void *argument)
|
||||
void usbh_hid_run(struct usbh_hid *hid_class)
|
||||
{
|
||||
}
|
||||
|
||||
void usbh_hid_stop(struct usbh_hid *hid_class)
|
||||
{
|
||||
}
|
||||
|
||||
void usbh_msc_run(struct usbh_msc *msc_class)
|
||||
{
|
||||
}
|
||||
|
||||
void usbh_msc_stop(struct usbh_msc *msc_class)
|
||||
{
|
||||
}
|
||||
|
||||
void usbh_audio_run(struct usbh_audio *audio_class)
|
||||
{
|
||||
}
|
||||
|
||||
void usbh_audio_stop(struct usbh_audio *audio_class)
|
||||
{
|
||||
}
|
||||
|
||||
void usbh_video_run(struct usbh_video *video_class)
|
||||
{
|
||||
}
|
||||
|
||||
void usbh_video_stop(struct usbh_video *video_class)
|
||||
{
|
||||
while (1) {
|
||||
printf("helloworld\r\n");
|
||||
usb_osal_msleep(1000);
|
||||
cdc_acm_test();
|
||||
msc_test();
|
||||
hid_test();
|
||||
video_test();
|
||||
}
|
||||
}
|
||||
|
||||
void usbh_class_test(void)
|
||||
{
|
||||
usb_osal_thread_create("usbh_test", 4096, CONFIG_USBHOST_PSC_PRIO + 1, usbh_class_test_thread, NULL);
|
||||
#if TEST_USBH_CDC_ACM
|
||||
usb_osal_thread_create("usbh_cdc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_acm_thread, NULL);
|
||||
#endif
|
||||
#if TEST_USBH_HID
|
||||
usb_osal_thread_create("usbh_hid", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_hid_thread, NULL);
|
||||
#endif
|
||||
#if TEST_USBH_MSC
|
||||
usb_osal_thread_create("usbh_msc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_msc_thread, NULL);
|
||||
#endif
|
||||
#if TEST_USBH_AUDIO
|
||||
#error "if you want to use iso, please contact with me"
|
||||
usb_osal_thread_create("usbh_audio", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_audio_thread, NULL);
|
||||
#endif
|
||||
#if TEST_USBH_VIDEO
|
||||
#error "if you want to use iso, please contact with me"
|
||||
usb_osal_thread_create("usbh_video", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_video_thread, NULL);
|
||||
#endif
|
||||
}
|
||||
71
demo/webusb_template.c
Normal file
71
demo/webusb_template.c
Normal file
@@ -0,0 +1,71 @@
|
||||
#include "usbd_core.h"
|
||||
|
||||
#define MS_OS_20_DESCRIPTOR_LENGTH (0xB2)
|
||||
|
||||
#define WEBUSB_URL_STRINGS \
|
||||
'd', 'e', 'v', 'a', 'n', 'l', 'a', 'i', '.', 'g', 'i', 't', 'h', 'u', 'b', '.', 'i', 'o', '/', 'w', 'e', 'b', 'd', 'f', 'u', '/', 'd', 'f', 'u', '-', 'u', 't', 'i', 'l'
|
||||
|
||||
#define WL_REQUEST_WEBUSB (0x22)
|
||||
#define WL_REQUEST_WINUSB (0x21)
|
||||
|
||||
#define URL_DESCRIPTOR_LENGTH 0x2C
|
||||
|
||||
// 描述符集信息
|
||||
const uint8_t MS_OS_20_DESCRIPTOR_SET[MS_OS_20_DESCRIPTOR_LENGTH] = {
|
||||
// Microsoft OS 2.0 描述符集标头
|
||||
0x0A, 0x00, // Descriptor size (10 bytes)
|
||||
0x00, 0x00, // MS OS 2.0 descriptor set header
|
||||
0x00, 0x00, 0x03, 0x06, // Windows version (8.1) (0x06030000)
|
||||
MS_OS_20_DESCRIPTOR_LENGTH, 0x00, // Size, MS OS 2.0 descriptor set
|
||||
|
||||
// Microsoft OS 2.0 配置子集标头
|
||||
0x08, 0x00, // wLength
|
||||
0x01, 0x00, // wDescriptorType
|
||||
0x00, // 适用于配置 1
|
||||
0x00, // bReserved
|
||||
0XA8, 0X00, // Size, MS OS 2.0 configuration subset
|
||||
|
||||
// Microsoft OS 2.0 功能子集头
|
||||
0x08, 0x00, // Descriptor size (8 bytes)
|
||||
0x02, 0x00, // MS OS 2.0 function subset header
|
||||
0x01, // 第2个接口
|
||||
0x00, // 必须设置为 0
|
||||
0xA0, 0x00,
|
||||
|
||||
// Microsoft OS 2.0 兼容 ID 描述符
|
||||
// 兼容 ID 描述符告诉 Windows 此设备与 WinUSB 驱动程序兼容
|
||||
0x14, 0x00, // wLength 20
|
||||
0x03, 0x00, // MS_OS_20_FEATURE_COMPATIBLE_ID
|
||||
'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
// Microsoft OS 2.0 注册表属性描述符
|
||||
// 注册表属性分配设备接口 GUID
|
||||
0x84, 0x00, //wLength: 132
|
||||
0x04, 0x00, // wDescriptorType: MS_OS_20_FEATURE_REG_PROPERTY: 0x04 (Table 9)
|
||||
0x07, 0x00, //wPropertyDataType: REG_MULTI_SZ (Table 15)
|
||||
0x2a, 0x00, //wPropertyNameLength:
|
||||
//bPropertyName: “DeviceInterfaceGUID”
|
||||
'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00,
|
||||
'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00,
|
||||
0x00, 0x00,
|
||||
0x50, 0x00, // wPropertyDataLength
|
||||
//bPropertyData: “{975F44D9-0D08-43FD-8B3E-127CA8AFFF9D}”.
|
||||
'{', 0x00, '9', 0x00, 'd', 0x00, '7', 0x00, 'd', 0x00, 'e', 0x00, 'b', 0x00, 'b', 0x00, 'c', 0x00, '-', 0x00,
|
||||
'c', 0x00, '8', 0x00, '5', 0x00, 'd', 0x00, '-', 0x00, '1', 0x00, '1', 0x00, 'd', 0x00, '1', 0x00, '-', 0x00,
|
||||
'9', 0x00, 'e', 0x00, 'b', 0x00, '4', 0x00, '-', 0x00, '0', 0x00, '0', 0x00, '6', 0x00, '0', 0x00, '0', 0x00,
|
||||
'8', 0x00, 'c', 0x00, '3', 0x00, 'a', 0x00, '1', 0x00, '9', 0x00, 'a', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
const uint8_t USBD_WebUSBURLDescriptor[URL_DESCRIPTOR_LENGTH] = {
|
||||
URL_DESCRIPTOR_LENGTH,
|
||||
WEBUSB_URL_TYPE,
|
||||
WEBUSB_URL_SCHEME_HTTPS,
|
||||
WEBUSB_URL_STRINGS
|
||||
};
|
||||
|
||||
struct usb_webusb_url_ex_descriptor webusb_url_desc = {
|
||||
.vendor_code = WL_REQUEST_WEBUSB,
|
||||
.string = MS_OS_20_DESCRIPTOR_SET,
|
||||
.string_len = MS_OS_20_DESCRIPTOR_LENGTH
|
||||
};
|
||||
@@ -93,39 +93,18 @@ struct usb_msosv1_descriptor msosv1_desc = {
|
||||
|
||||
#define USB_CONFIG_SIZE (9 + 9 + 7 + 7)
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define WINUSB_EP_MPS 512
|
||||
#else
|
||||
#define WINUSB_EP_MPS 64
|
||||
#endif
|
||||
|
||||
const uint8_t winusb_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xff, 0xff, 0xff, USBD_VID, USBD_PID, 0x0001, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
///////////////////////////////////////
|
||||
/// interface descriptor
|
||||
///////////////////////////////////////
|
||||
0x09, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */
|
||||
0x00, /* bInterfaceNumber */
|
||||
0x00, /* bAlternateSetting */
|
||||
0x02, /* bNumEndpoints */
|
||||
0xff, /* bInterfaceClass */
|
||||
0x01, /* bInterfaceSubClass */
|
||||
0x00, /* bInterfaceProtocol */
|
||||
0x02, /* iInterface */
|
||||
///////////////////////////////////////
|
||||
/// endpoint descriptor
|
||||
///////////////////////////////////////
|
||||
0x07, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */
|
||||
WINUSB_OUT_EP, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes */
|
||||
0x00, 0x02, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
///////////////////////////////////////
|
||||
/// endpoint descriptor
|
||||
///////////////////////////////////////
|
||||
0x07, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */
|
||||
WINUSB_IN_EP, /* bEndpointAddress */
|
||||
0x02, /* bmAttributes */
|
||||
0x00, 0x02, /* wMaxPacketSize */
|
||||
0x00, /* bInterval */
|
||||
USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xff, 0x01, 0x00, 0x02),
|
||||
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, 0x02, WINUSB_EP_MPS, 0x00),
|
||||
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, 0x02, WINUSB_EP_MPS, 0x00),
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
///////////////////////////////////////
|
||||
@@ -147,10 +126,29 @@ const uint8_t winusb_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// string2 descriptor
|
||||
///////////////////////////////////////
|
||||
26,
|
||||
0x03,
|
||||
'C', 0, 'M', 0, 'S', 0, 'I', 0, 'S', 0, '-', 0, 'D', 0, 'A', 0,
|
||||
'P', 0, ' ', 0, 'v', 0, '2', 0,
|
||||
0x2C, /* 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 */
|
||||
'W', 0x00, /* wcChar10 */
|
||||
'I', 0x00, /* wcChar11 */
|
||||
'N', 0x00, /* wcChar12 */
|
||||
'U', 0x00, /* wcChar13 */
|
||||
'S', 0x00, /* wcChar14 */
|
||||
'B', 0x00, /* wcChar15 */
|
||||
' ', 0x00, /* wcChar16 */
|
||||
'D', 0x00, /* wcChar17 */
|
||||
'E', 0x00, /* wcChar18 */
|
||||
'M', 0x00, /* wcChar19 */
|
||||
'O', 0x00, /* wcChar20 */
|
||||
///////////////////////////////////////
|
||||
/// string3 descriptor
|
||||
///////////////////////////////////////
|
||||
@@ -184,13 +182,10 @@ const uint8_t winusb_descriptor[] = {
|
||||
0x00
|
||||
};
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define WINUSB_OUT_EP_MPS 512
|
||||
#else
|
||||
#define WINUSB_OUT_EP_MPS 64
|
||||
#endif
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
|
||||
|
||||
volatile bool ep_tx_busy_flag = false;
|
||||
|
||||
void usbd_configure_done_callback(void)
|
||||
{
|
||||
@@ -200,10 +195,25 @@ void usbd_configure_done_callback(void)
|
||||
|
||||
void usbd_winusb_out(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
USB_LOG_RAW("actual out len:%d\r\n", nbytes);
|
||||
// for (int i = 0; i < 100; i++) {
|
||||
// printf("%02x ", read_buffer[i]);
|
||||
// }
|
||||
// printf("\r\n");
|
||||
/* setup next out ep read transfer */
|
||||
usbd_ep_start_read(CDC_OUT_EP, read_buffer, 2048);
|
||||
}
|
||||
|
||||
void usbd_winusb_in(uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
USB_LOG_RAW("actual in len:%d\r\n", nbytes);
|
||||
|
||||
if ((nbytes % CDC_MAX_MPS) == 0 && nbytes) {
|
||||
/* send zlp */
|
||||
usbd_ep_start_write(CDC_IN_EP, NULL, 0);
|
||||
} else {
|
||||
ep_tx_busy_flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
struct usbd_endpoint winusb_out_ep = {
|
||||
@@ -218,7 +228,7 @@ struct usbd_endpoint winusb_in_ep = {
|
||||
|
||||
struct usbd_interface intf0;
|
||||
|
||||
void daplink_winusb_init(void)
|
||||
void winusb_init(void)
|
||||
{
|
||||
usbd_desc_register(winusb_descriptor);
|
||||
usbd_msosv1_desc_register(&msosv1_desc);
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 19 KiB |
@@ -6,8 +6,8 @@ project = 'CherryUSB'
|
||||
copyright = '2022, sakumisu'
|
||||
author = 'sakumisu'
|
||||
|
||||
release = '0.4'
|
||||
version = '0.4.0'
|
||||
release = '0.8'
|
||||
version = '0.8.0'
|
||||
|
||||
# -- General configuration
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统的
|
||||
|
||||
其他相关链接:
|
||||
|
||||
- **CherryUSB 大纲** https://www.bilibili.com/video/BV1st4y1H7K2
|
||||
- **从机协议栈视频教程** https://www.bilibili.com/video/BV1Ef4y1t73d
|
||||
- **主机协议栈视频教程** TODO
|
||||
- **github** https://github.com/sakumisu/CherryUSB
|
||||
@@ -36,6 +37,7 @@ CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统的
|
||||
|
||||
quick_start/bl702
|
||||
quick_start/stm32
|
||||
quick_start/hpm
|
||||
quick_start/es32
|
||||
quick_start/rt-thread/rtthread
|
||||
quick_start/other_chip
|
||||
|
||||
@@ -1,12 +1,24 @@
|
||||
Porting 如何编写
|
||||
==============================
|
||||
|
||||
|
||||
本节主要介绍没有支持的芯片如何做 porting。
|
||||
|
||||
从机 porting
|
||||
----------------------------
|
||||
|
||||
|
||||
- 首先复制一份从 `port/template` 复制一份 `usb_dc.c` 并参与编译,保证能编译过。
|
||||
- 实现 ``usb_dc_init`` 保证能进入中断
|
||||
- 在中断中判断 reset 中断并能够正常触发 reset 中断,在 reset 中断中调用 ``usbd_event_reset_handler``,如果可能,还需要启动读取 setup 包。
|
||||
- 在中断中判断 setup 中断并能够正常触发 setup 中断,然后将读取的数据传入 ``usbd_event_ep0_setup_complete_handler``
|
||||
- 实现 ``usbd_ep_start_write`` 并能够触发发送完成中断
|
||||
- 实现 ``usbd_ep_start_read`` 并能够触发接收完成中断
|
||||
- 分包处理
|
||||
|
||||
主机 porting
|
||||
----------------------------
|
||||
----------------------------
|
||||
|
||||
- 首先复制一份从 `port/template` 复制一份 `usb_hc.c` 并参与编译,保证能编译过。
|
||||
- 实现 ``usb_hc_init`` 保证能进入中断
|
||||
- 能够进入插拔中断,比如 ``connect`` 和 ``disconnect``,并调用 ``usbh_roothub_thread_wakeup`` 能够唤醒 hub 线程
|
||||
- 实现 ``usbh_roothub_control`` 并根据第三个条件,能够完成 ``usbh_hub_events`` 中 ``usbh_enumerate`` 之前的流程
|
||||
- 实现 ``usbh_submit_urb``
|
||||
@@ -155,6 +155,8 @@ DWC2
|
||||
|
||||
DWC2 IP 支持主从,并且由 **synopsys** 定义了一套标准的寄存器偏移。大部分厂家都使用标准的寄存器偏移,所以如果是从机仅需要修改 `USBD_IRQHandler` 、 `USB_BASE` 、 `USB_NUM_BIDIR_ENDPOINTS` ,主机仅需要修改 `USBH_IRQHandler` 、 `USB_BASE` 即可。
|
||||
|
||||
其次还有需要注意 VBUS SENSING 这个项,也会影响 USB 的正常枚举,如何修改参考 `GD32 dwc2驱动的GCCFG_NOVBUSSENS寄存器兼容性和stm32存在区别 <https://github.com/sakumisu/CherryUSB/issues/64>`_。
|
||||
|
||||
.. caution:: 主机 port 仅支持有高速功能的 dwc2 ip, 因为他支持 dma 模式,如果厂家买的 ip 不支持 dma 模式,则无法使用。
|
||||
|
||||
下表为具体芯片从机相关宏的修改值:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
基于 BL 系列开发指南
|
||||
=========================
|
||||
|
||||
BL 系列 USB 的开发主要使用 bl_mcu_sdk,关于 bl_mcu_sdk 的环境搭建,参考 `bl_mcu_sdk 环境搭建 <https://dev.bouffalolab.com/media/doc/sdk/bl_mcu_sdk_zh/get_started/index.html>`_。
|
||||
BL 系列 USB 的开发主要使用 bl_mcu_sdk,参考 `bl_mcu_sdk <https://github.com/bouffalolab/bl_mcu_sdk>`_。
|
||||
|
||||
USB 的相关应用位于 `examples/usb` 目录下,环境搭建完成后,即可编译使用。
|
||||
USB 的相关应用位于 `examples/usbdev` 和 `examples/usbhost` 目录下,环境搭建完成后,即可编译使用。
|
||||
6
docs/source/quick_start/hpm.rst
Normal file
6
docs/source/quick_start/hpm.rst
Normal file
@@ -0,0 +1,6 @@
|
||||
基于 HPM 系列开发指南
|
||||
=========================
|
||||
|
||||
HPM 系列 USB 的开发主要使用 hpm_sdk ,参考 `hpm sdk <https://github.com/hpmicro/hpm_sdk>`_。
|
||||
|
||||
USB 的相关应用位于 `samples/cherryusb` 目录下,环境搭建完成后,即可编译使用。
|
||||
@@ -38,12 +38,12 @@ USB Host 移植要点
|
||||
|
||||
.. code-block:: C
|
||||
|
||||
define region CHERRYUSB_RAM = [from 0x1080000 + 700k size 68k]; /* reserve for cherryusb region */
|
||||
define block cherryusb_usbh_class_info { section .usbh_class_info };
|
||||
|
||||
define exported symbol __usbh_class_info_start__ = start of region CHERRYUSB_RAM;
|
||||
define exported symbol __usbh_class_info_end__ = end of region CHERRYUSB_RAM + 1;
|
||||
define exported symbol __usbh_class_info_start__ = start of block cherryusb_usbh_class_info;
|
||||
define exported symbol __usbh_class_info_end__ = end of block cherryusb_usbh_class_info + 1;
|
||||
|
||||
place in CHERRYUSB_RAM { section .usbh_class_info };
|
||||
place in AXI_SRAM { block cherryusb_usbh_class_info };
|
||||
keep { section .usbh_class_info};
|
||||
|
||||
- 编译使用。各个 class 如何使用,参考 demo 下的 `usb_host.c` 文件
|
||||
|
||||
@@ -84,8 +84,4 @@
|
||||
|
||||
其次将 `main.c` 中的 `SystemClock_Config` 替换掉 `board.c` 中的配置
|
||||
|
||||
.. figure:: img/stm32_init2.png
|
||||
|
||||
其他小伙伴的移植笔记
|
||||
-------------------------
|
||||
- @kylongmu `stm32h743-st-nucleo移植CherryUSB- CDC串口 <https://club.rt-thread.org/ask/article/3719.html>`_。
|
||||
.. figure:: img/stm32_init2.png
|
||||
@@ -4,7 +4,7 @@
|
||||
本节是基于 STM32 三个系列芯片的使用,涵盖 F1/F4/H7,其余芯片基本类似,不再赘述,具体区别有:
|
||||
|
||||
- usb ip 区别:F1使用 fsdev,F4/H7使用 dwc2
|
||||
- dwc2 ip 区别: fs port 和 hs port(带 dma 和不带 dma 功能)
|
||||
- dwc2 ip 区别: fs port(引脚是 PA11/PA12) 和 hs port(引脚是 PB14/PB15), 其中 hs port 默认全速,可以接外部PHY 形成高速主机,并且带 dma 功能
|
||||
- F4 与 H7 cache 区别、USB BASE 区别
|
||||
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.. caution :: 如果使用 STM32F7 或者 STM32H7, 请在 CFLAG 中添加 STM32F7 或者 STM32H7 宏定义,否则无法枚举
|
||||
|
||||
工程样例试用
|
||||
-----------------------
|
||||
|
||||
@@ -103,7 +106,7 @@ USB Device 移植要点
|
||||
USB Host 移植要点
|
||||
-----------------------
|
||||
|
||||
前面 7 步与 Device 一样。需要注意,host 驱动只支持带 dma 的 hs port,所以 fs port 不做支持(没有 dma 你玩什么主机)。
|
||||
前面 7 步与 Device 一样。需要注意,host 驱动只支持带 dma 的 hs port (引脚是 PB14/PB15),所以 fs port (引脚是 PA11/PA12)不做支持(没有 dma 你玩什么主机)。
|
||||
|
||||
- 添加 CherryUSB 必须要的源码( **usbh_core.c** 、 **usbh_hub.c** 、 **usb_hc_dwc2.c** 、以及 **osal** 目录下的适配层文件),以及想要使用的 class 驱动,并且可以将对应的 **usb host.c** 添加方便测试。
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
typedef void *usb_osal_thread_t;
|
||||
typedef void *usb_osal_sem_t;
|
||||
typedef void *usb_osal_mutex_t;
|
||||
typedef void *usb_osal_mq_t;
|
||||
typedef void (*usb_thread_entry_t)(void *argument);
|
||||
|
||||
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);
|
||||
@@ -26,10 +27,13 @@ void usb_osal_mutex_delete(usb_osal_mutex_t mutex);
|
||||
int usb_osal_mutex_take(usb_osal_mutex_t mutex);
|
||||
int usb_osal_mutex_give(usb_osal_mutex_t mutex);
|
||||
|
||||
usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs);
|
||||
int usb_osal_mq_send(usb_osal_mq_t mq, uint32_t addr);
|
||||
int usb_osal_mq_recv(usb_osal_mq_t mq, uint32_t *addr, uint32_t timeout);
|
||||
|
||||
size_t usb_osal_enter_critical_section(void);
|
||||
void usb_osal_leave_critical_section(size_t flag);
|
||||
|
||||
void usb_osal_msleep(uint32_t delay);
|
||||
|
||||
#endif /* USB_OSAL_H */
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ int usb_osal_sem_give(usb_osal_sem_t sem)
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
return (ret == pdPASS) ? 0 : -EINVAL;
|
||||
return (ret == pdPASS) ? 0 : -ETIMEDOUT;
|
||||
}
|
||||
|
||||
usb_osal_mutex_t usb_osal_mutex_create(void)
|
||||
@@ -63,7 +63,30 @@ int usb_osal_mutex_take(usb_osal_mutex_t mutex)
|
||||
|
||||
int usb_osal_mutex_give(usb_osal_mutex_t mutex)
|
||||
{
|
||||
return (xSemaphoreGive((SemaphoreHandle_t)mutex) == pdPASS) ? 0 : -EINVAL;
|
||||
return (xSemaphoreGive((SemaphoreHandle_t)mutex) == pdPASS) ? 0 : -ETIMEDOUT;
|
||||
}
|
||||
|
||||
usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs)
|
||||
{
|
||||
return (usb_osal_mq_t)xQueueCreate(max_msgs, 4);
|
||||
}
|
||||
|
||||
int usb_osal_mq_send(usb_osal_mq_t mq, uint32_t addr)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||
int ret;
|
||||
|
||||
ret = xQueueSendFromISR((usb_osal_mq_t)mq, &addr, &xHigherPriorityTaskWoken);
|
||||
if (ret == pdPASS) {
|
||||
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
||||
}
|
||||
|
||||
return (ret == pdPASS) ? 0 : -ETIMEDOUT;
|
||||
}
|
||||
|
||||
int usb_osal_mq_recv(usb_osal_mq_t mq, uint32_t *addr, uint32_t timeout)
|
||||
{
|
||||
return (xQueueReceive((usb_osal_mq_t)mq, addr, timeout) == pdPASS) ? 0 : -ETIMEDOUT;
|
||||
}
|
||||
|
||||
size_t usb_osal_enter_critical_section(void)
|
||||
|
||||
@@ -68,6 +68,33 @@ int usb_osal_mutex_give(usb_osal_mutex_t mutex)
|
||||
return (int)rt_mutex_release((rt_mutex_t)mutex);
|
||||
}
|
||||
|
||||
usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs)
|
||||
{
|
||||
return (usb_osal_mq_t)rt_mq_create("usbh_mq", 4, max_msgs, RT_IPC_FLAG_FIFO);
|
||||
}
|
||||
|
||||
int usb_osal_mq_send(usb_osal_mq_t mq, uint32_t addr)
|
||||
{
|
||||
return rt_mq_send((rt_mq_t)mq, &addr, 4);
|
||||
}
|
||||
|
||||
int usb_osal_mq_recv(usb_osal_mq_t mq, uint32_t *addr, uint32_t timeout)
|
||||
{
|
||||
int ret = 0;
|
||||
rt_err_t result = RT_EOK;
|
||||
|
||||
result = rt_mq_recv((rt_mq_t)mq, addr, 4, rt_tick_from_millisecond(timeout));
|
||||
if (result == -RT_ETIMEOUT) {
|
||||
ret = -ETIMEDOUT;
|
||||
} else if (result == -RT_ERROR) {
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return (int)ret;
|
||||
}
|
||||
|
||||
size_t usb_osal_enter_critical_section(void)
|
||||
{
|
||||
return rt_hw_interrupt_disable();
|
||||
|
||||
@@ -1,122 +0,0 @@
|
||||
#include "usb_osal.h"
|
||||
#include "usb_errno.h"
|
||||
#include "stdlib.h"
|
||||
#include "RTL.h"
|
||||
|
||||
uint32_t enter_critical(void);
|
||||
uint32_t exit_critical(uint32_t sr);
|
||||
|
||||
//延时=timeout/os_tick, os tick设置为1ms,延时=timeout
|
||||
//移植为arm9,其他版本可能需要调整汇编代码
|
||||
|
||||
//按最大端点数量设置,这里设为8
|
||||
_declare_box8(sem_mpool, sizeof(OS_SEM), 8);
|
||||
_declare_box8(mut_mpool, sizeof(OS_MUT), 8);
|
||||
|
||||
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 *stk = malloc(stack_size);
|
||||
_init_box8(sem_mpool, sizeof(sem_mpool), sizeof(OS_SEM));
|
||||
_init_box8(mut_mpool, sizeof(mut_mpool), sizeof(OS_MUT));
|
||||
|
||||
return (usb_osal_thread_t)os_tsk_create_user_ex (entry, prio,
|
||||
stk, stack_size,
|
||||
args);
|
||||
}
|
||||
|
||||
usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count)
|
||||
{
|
||||
void *sem = _alloc_box(sem_mpool);
|
||||
if(sem != NULL) os_sem_init(sem, initial_count);
|
||||
return (usb_osal_sem_t)sem;
|
||||
}
|
||||
|
||||
//删除os同步量,并不简单 //不能有无限等待的信号量,否则不能删除
|
||||
void usb_osal_sem_delete(usb_osal_sem_t sem)
|
||||
{
|
||||
_free_box(sem_mpool, sem);
|
||||
}
|
||||
|
||||
int usb_osal_sem_take(usb_osal_sem_t sem, uint32_t timeout)
|
||||
{
|
||||
return (os_sem_wait(sem, timeout) != OS_R_TMO) ? 0 : -ETIMEDOUT;
|
||||
}
|
||||
|
||||
//在线程,中断均调用
|
||||
int usb_osal_sem_give(usb_osal_sem_t sem)
|
||||
{
|
||||
uint32_t intstatus = 0;
|
||||
/* Obtain the number of the currently executing interrupt. */
|
||||
__asm volatile ( "mrs intstatus, cpsr" );
|
||||
if ((intstatus & 0xf) == 0) { //user mode
|
||||
os_sem_send(sem);
|
||||
} else {
|
||||
isr_sem_send(sem);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
usb_osal_mutex_t usb_osal_mutex_create(void)
|
||||
{
|
||||
void *mut = _alloc_box(mut_mpool);
|
||||
if(mut != NULL) os_mut_init(mut);
|
||||
return (usb_osal_mutex_t)mut;
|
||||
}
|
||||
|
||||
void usb_osal_mutex_delete(usb_osal_mutex_t mutex)
|
||||
{
|
||||
_free_box(mut_mpool, mutex);
|
||||
}
|
||||
|
||||
int usb_osal_mutex_take(usb_osal_mutex_t mutex)
|
||||
{
|
||||
os_mut_wait(mutex, 0xffff);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_osal_mutex_give(usb_osal_mutex_t mutex)
|
||||
{
|
||||
return (os_mut_release(mutex) == OS_R_OK) ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
//这两个函数只在线程调用,可以改为tsk_lock和tsk_unlock版本
|
||||
size_t usb_osal_enter_critical_section(void)
|
||||
{
|
||||
return enter_critical();
|
||||
}
|
||||
|
||||
void usb_osal_leave_critical_section(size_t flag)
|
||||
{
|
||||
exit_critical(flag);
|
||||
}
|
||||
|
||||
void usb_osal_msleep(uint32_t delay)
|
||||
{
|
||||
os_dly_wait(delay);
|
||||
}
|
||||
|
||||
#pragma arm
|
||||
|
||||
__asm uint32_t __builtin_ctz(uint32_t val)
|
||||
{
|
||||
rsb r3, r0, #0
|
||||
and r0, r3, r0
|
||||
clz r0, r0
|
||||
rsb r0, r0, #31
|
||||
bx lr
|
||||
}
|
||||
|
||||
__asm uint32_t enter_critical(void)
|
||||
{
|
||||
mrs R0, CPSR
|
||||
orr R1, R0, #0xC0 ; Disable IRQ and FIQ
|
||||
msr CPSR_c, R1
|
||||
bx lr
|
||||
}
|
||||
|
||||
__asm uint32_t exit_critical(uint32_t sr)
|
||||
{
|
||||
msr CPSR_c, R0
|
||||
bx lr
|
||||
}
|
||||
2
port/bouffalolab/README.md
Normal file
2
port/bouffalolab/README.md
Normal file
@@ -0,0 +1,2 @@
|
||||
[BL702](https://github.com/bouffalolab/bl_mcu_sdk/blob/master/drivers/lhal/src/bflb_usb_v1.c)
|
||||
[BL616/BL808](https://github.com/bouffalolab/bl_mcu_sdk/blob/master/drivers/lhal/src/bflb_usb_v2.c)
|
||||
@@ -1,2 +0,0 @@
|
||||
[bl_mcu_sdk_usb_dc](https://github.com/bouffalolab/bl_mcu_sdk/blob/master/bsp/bsp_common/usb/usb_dc.c)
|
||||
[bl_mcu_sdk_hal_usb](https://github.com/bouffalolab/bl_mcu_sdk/blob/master/drivers/bl702_driver/hal_drv/src/hal_usb.c)
|
||||
@@ -98,6 +98,71 @@ typedef struct __attribute__((packed)) {
|
||||
__IO uint32_t OTG_SR;
|
||||
} USBOTGH_FS_TypeDef;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
__IO uint8_t BASE_CTRL; /*!< 0x40008000 */
|
||||
__IO uint8_t HOST_CTRL; /*!< 0x40008001 */
|
||||
__IO uint8_t INT_EN; /*!< 0x40008002 */
|
||||
__IO uint8_t DEV_ADDR; /*!< 0x40008003 */
|
||||
__IO uint8_t USB_STATUS0; /*!< 0x40008004 */
|
||||
__IO uint8_t MIS_ST; /*!< 0x40008005 */
|
||||
__IO uint8_t INT_FG; /*!< 0x40008006 */
|
||||
__IO uint8_t INT_ST; /*!< 0x40008007 */
|
||||
__IO uint8_t RX_LEN; /*!< 0x40008008 */
|
||||
__IO uint8_t Reserve1; /*!< 0x40008009 */
|
||||
__IO uint8_t Reserve2; /*!< 0x4000800a */
|
||||
__IO uint8_t Reserve3; /*!< 0x4000800b */
|
||||
__IO uint8_t UEP4_1_MOD; /*!< 0x4000800c */
|
||||
__IO uint8_t HOST_EP_MOD; /*!< 0x4000800d */
|
||||
__IO uint8_t UEP567_MOD; /*!< 0x4000800e */
|
||||
__IO uint8_t Reserve4; /*!< 0x4000800f */
|
||||
__IO uint16_t UEP0_DMA; /*!< 0x40008010 */
|
||||
__IO uint16_t Reserve5; /*!< 0x40008012 */
|
||||
__IO uint16_t UEP1_DMA; /*!< 0x40008014 */
|
||||
__IO uint16_t Reserve6; /*!< 0x40008016 */
|
||||
__IO uint16_t HOST_RX_DMA; /*!< 0x40008018 */
|
||||
__IO uint16_t Reserve7; /*!< 0x4000801a */
|
||||
__IO uint16_t HOST_TX_DMA; /*!< 0x4000801c */
|
||||
__IO uint16_t Reserve8; /*!< 0x4000801e */
|
||||
__IO uint8_t UEP0_T_LEN; /*!< 0x40008020 */
|
||||
__IO uint8_t Reserve9; /*!< 0x40008021 */
|
||||
__IO uint8_t UEP0_CTRL; /*!< 0x40008022 */
|
||||
__IO uint8_t Reserve10; /*!< 0x40008023 */
|
||||
__IO uint8_t UEP1_T_LEN; /*!< 0x40008024 */
|
||||
__IO uint8_t Reserve11; /*!< 0x40008025 */
|
||||
__IO uint8_t HOST_SETUP; /*!< 0x40008026 */
|
||||
__IO uint8_t Reserve12; /*!< 0x40008027 */
|
||||
__IO uint8_t HOST_EP_PID; /*!< 0x40008028 */
|
||||
__IO uint8_t Reserve13; /*!< 0x40008029 */
|
||||
__IO uint8_t HOST_RX_CTRL; /*!< 0x4000802a */
|
||||
__IO uint8_t Reserve14; /*!< 0x4000802b */
|
||||
__IO uint8_t HOST_TX_LEN; /*!< 0x4000802c */
|
||||
__IO uint8_t Reserve15; /*!< 0x4000802d */
|
||||
__IO uint8_t HOST_TX_CTRL; /*!< 0x4000802e */
|
||||
__IO uint8_t Reserve16; /*!< 0x4000802f */
|
||||
__IO uint8_t UEP4_T_LEN; /*!< 0x40008030 */
|
||||
__IO uint8_t Reserve17; /*!< 0x40008031 */
|
||||
__IO uint8_t UEP4_CTRL; /*!< 0x40008032 */
|
||||
__IO uint8_t Reserve18[33]; /*!< 0x40008033 */
|
||||
__IO uint16_t UEP5_DMA; /*!< 0x40008054 */
|
||||
__IO uint16_t Reserve19; /*!< 0x40008056 */
|
||||
__IO uint16_t UEP6_DMA; /*!< 0x40008058 */
|
||||
__IO uint16_t Reserve20; /*!< 0x4000805a */
|
||||
__IO uint16_t UEP7_DMA; /*!< 0x4000805c */
|
||||
__IO uint8_t Reserve21[6]; /*!< 0x4000805e */
|
||||
__IO uint8_t UEP5_T_LEN; /*!< 0x40008064 */
|
||||
__IO uint8_t Reserve22; /*!< 0x40008065 */
|
||||
__IO uint8_t UEP5_CTRL; /*!< 0x40008066 */
|
||||
__IO uint8_t Reserve23; /*!< 0x40008067 */
|
||||
__IO uint8_t UEP6_T_LEN; /*!< 0x40008068 */
|
||||
__IO uint8_t Reserve24; /*!< 0x40008069 */
|
||||
__IO uint8_t UEP6_CTRL; /*!< 0x4000806a */
|
||||
__IO uint8_t Reserve25; /*!< 0x4000806b */
|
||||
__IO uint8_t UEP7_T_LEN; /*!< 0x4000806c */
|
||||
__IO uint8_t Reserve26; /*!< 0x4000806d */
|
||||
__IO uint8_t UEP7_CTRL; /*!< 0x4000806e */
|
||||
} USB_FS_TypeDef;
|
||||
|
||||
#define USBFS_BASE ((uint32_t)0x50000000)
|
||||
|
||||
#define USBFS_DEVICE ((USBOTG_FS_TypeDef *)USBFS_BASE)
|
||||
|
||||
@@ -29,12 +29,18 @@
|
||||
#define GET_SETUP_PACKET(data_add) \
|
||||
*(struct usb_setup_packet *)data_add
|
||||
|
||||
/*!< Set epid ep tx valid */
|
||||
/*!< Set epid ep tx valid // Not an isochronous endpoint */
|
||||
#define EPn_SET_TX_VALID(epid) \
|
||||
EPn_CTRL(epid) = (EPn_CTRL(epid) & ~MASK_UEP_T_RES) | UEP_T_RES_ACK;
|
||||
/*!< Set epid ep rx valid */
|
||||
/*!< Set epid ep rx valid // Not an isochronous endpoint */
|
||||
#define EPn_SET_RX_VALID(epid) \
|
||||
EPn_CTRL(epid) = (EPn_CTRL(epid) & ~MASK_UEP_R_RES) | UEP_R_RES_ACK;
|
||||
/*!< Set epid ep tx valid // Isochronous endpoint */
|
||||
#define EPn_SET_TX_ISO_VALID(epid) \
|
||||
EPn_CTRL(epid) = (EPn_CTRL(epid) & ~MASK_UEP_T_RES) | UEP_T_RES_TOUT;
|
||||
/*!< Set epid ep rx valid // Isochronous endpoint */
|
||||
#define EPn_SET_RX_ISO_VALID(epid) \
|
||||
EPn_CTRL(epid) = (EPn_CTRL(epid) & ~MASK_UEP_R_RES) | UEP_R_RES_TOUT;
|
||||
/*!< Set epid ep tx nak */
|
||||
#define EPn_SET_TX_NAK(epid) \
|
||||
EPn_CTRL(epid) = (EPn_CTRL(epid) & ~MASK_UEP_T_RES) | UEP_T_RES_NAK;
|
||||
@@ -47,12 +53,18 @@
|
||||
/*!< Set epid ep rx stall */
|
||||
#define EPn_SET_RX_STALL(epid) \
|
||||
EPn_CTRL(epid) = (EPn_CTRL(epid) & ~MASK_UEP_R_RES) | UEP_R_RES_STALL
|
||||
/*!< Clear epid ep tx stall */
|
||||
#define EPn_CLR_TX_STALL(epid) \
|
||||
EPn_CTRL(epid) = (EPn_CTRL(epid) & ~(RB_UEP_T_TOG | MASK_UEP_T_RES)) | UEP_T_RES_NAK
|
||||
/*!< Clear epid ep rx stall */
|
||||
#define EPn_CLR_RX_STALL(epid) \
|
||||
EPn_CTRL(epid) = (EPn_CTRL(epid) & ~(RB_UEP_R_TOG | MASK_UEP_R_RES)) | UEP_R_RES_ACK
|
||||
/*!< Set epid ep tx len */
|
||||
#define EPn_SET_TX_LEN(epid, len) \
|
||||
EPn_TX_LEN(epid) = len
|
||||
/*!< Get epid ep rx len */
|
||||
#define EPn_GET_RX_LEN(epid) \
|
||||
R8_USB_RX_LEN
|
||||
CH58x_USBFS_DEV->USB_RX_LEN
|
||||
|
||||
/*!< ep nums */
|
||||
#ifndef USB_NUM_BIDIR_ENDPOINTS
|
||||
@@ -124,6 +136,11 @@ int usbd_set_address(const uint8_t address)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t usbd_get_port_speed(const uint8_t port)
|
||||
{
|
||||
return USB_SPEED_FULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Open endpoint
|
||||
* @pre None
|
||||
@@ -147,12 +164,14 @@ int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg)
|
||||
/*!< update ep max packet length */
|
||||
if (USB_EP_DIR_IS_IN(ep_cfg->ep_addr)) {
|
||||
/*!< in */
|
||||
usb_dc_cfg.ep_in[epid].mps = mps;
|
||||
usb_dc_cfg.ep_in[epid].ep_enable = true;
|
||||
usb_dc_cfg.ep_in[epid].mps = mps;
|
||||
usb_dc_cfg.ep_in[epid].eptype = ep_cfg->ep_type;
|
||||
} else if (USB_EP_DIR_IS_OUT(ep_cfg->ep_addr)) {
|
||||
/*!< out */
|
||||
usb_dc_cfg.ep_out[epid].ep_enable = true;
|
||||
usb_dc_cfg.ep_out[epid].mps = mps;
|
||||
usb_dc_cfg.ep_out[epid].eptype = ep_cfg->ep_type;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -216,7 +235,11 @@ int usbd_ep_start_write(const uint8_t ep, const uint8_t *data, uint32_t data_len
|
||||
/*!< write 0 len data */
|
||||
EPn_SET_TX_LEN(ep_idx, 0);
|
||||
/*!< enable tx */
|
||||
EPn_SET_TX_VALID(ep_idx);
|
||||
if (usb_dc_cfg.ep_in[ep_idx].eptype != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
|
||||
EPn_SET_TX_VALID(ep_idx);
|
||||
} else {
|
||||
EPn_SET_TX_ISO_VALID(ep_idx);
|
||||
}
|
||||
/*!< return */
|
||||
return 0;
|
||||
} else {
|
||||
@@ -227,7 +250,11 @@ int usbd_ep_start_write(const uint8_t ep, const uint8_t *data, uint32_t data_len
|
||||
/*!< write real_wt_nums len data */
|
||||
EPn_SET_TX_LEN(ep_idx, data_len);
|
||||
/*!< enable tx */
|
||||
EPn_SET_TX_VALID(ep_idx);
|
||||
if (usb_dc_cfg.ep_in[ep_idx].eptype != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
|
||||
EPn_SET_TX_VALID(ep_idx);
|
||||
} else {
|
||||
EPn_SET_TX_ISO_VALID(ep_idx);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -271,7 +298,12 @@ int usbd_ep_start_read(const uint8_t ep, uint8_t *data, uint32_t data_len)
|
||||
} else {
|
||||
data_len = MIN(data_len, usb_dc_cfg.ep_out[ep_idx].mps);
|
||||
}
|
||||
EPn_SET_RX_VALID(ep_idx);
|
||||
|
||||
if (usb_dc_cfg.ep_out[ep_idx].eptype != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
|
||||
EPn_SET_RX_VALID(ep_idx);
|
||||
} else {
|
||||
EPn_SET_RX_ISO_VALID(ep_idx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -285,8 +317,11 @@ int usbd_ep_set_stall(const uint8_t ep)
|
||||
{
|
||||
/*!< ep id */
|
||||
uint8_t epid = USB_EP_GET_IDX(ep);
|
||||
EPn_SET_RX_STALL(epid);
|
||||
EPn_SET_TX_STALL(epid);
|
||||
if (USB_EP_DIR_IS_OUT(ep)) {
|
||||
EPn_SET_RX_STALL(epid);
|
||||
} else {
|
||||
EPn_SET_TX_STALL(epid);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -298,30 +333,13 @@ int usbd_ep_set_stall(const uint8_t ep)
|
||||
*/
|
||||
int usbd_ep_clear_stall(const uint8_t ep)
|
||||
{
|
||||
int ret;
|
||||
switch (ep) {
|
||||
case 0x82:
|
||||
CH58x_USBFS_DEV->UEP2_CTRL = (CH58x_USBFS_DEV->UEP2_CTRL & ~(RB_UEP_T_TOG | MASK_UEP_T_RES)) | UEP_T_RES_NAK;
|
||||
ret = 0;
|
||||
break;
|
||||
case 0x02:
|
||||
CH58x_USBFS_DEV->UEP2_CTRL = (CH58x_USBFS_DEV->UEP2_CTRL & ~(RB_UEP_R_TOG | MASK_UEP_R_RES)) | UEP_R_RES_ACK;
|
||||
ret = 0;
|
||||
break;
|
||||
case 0x81:
|
||||
CH58x_USBFS_DEV->UEP1_CTRL = (CH58x_USBFS_DEV->UEP1_CTRL & ~(RB_UEP_T_TOG | MASK_UEP_T_RES)) | UEP_T_RES_NAK;
|
||||
ret = 0;
|
||||
break;
|
||||
case 0x01:
|
||||
CH58x_USBFS_DEV->UEP1_CTRL = (CH58x_USBFS_DEV->UEP1_CTRL & ~(RB_UEP_R_TOG | MASK_UEP_R_RES)) | UEP_R_RES_ACK;
|
||||
ret = 0;
|
||||
break;
|
||||
default:
|
||||
/*!< Unsupported endpoint */
|
||||
ret = -1;
|
||||
break;
|
||||
uint8_t epid = USB_EP_GET_IDX(ep);
|
||||
if (USB_EP_DIR_IS_OUT(ep)) {
|
||||
EPn_CLR_RX_STALL(epid);
|
||||
} else {
|
||||
EPn_CLR_TX_STALL(epid);
|
||||
}
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -331,8 +349,11 @@ int usbd_ep_clear_stall(const uint8_t ep)
|
||||
* @param[out] stalled : Outgoing endpoint status
|
||||
* @retval >=0 success otherwise failure
|
||||
*/
|
||||
int usbd_ep_get_stall(const uint8_t ep, uint8_t *stalled)
|
||||
int usbd_ep_is_stalled(const uint8_t ep, uint8_t *stalled)
|
||||
{
|
||||
if (USB_EP_DIR_IS_OUT(ep)) {
|
||||
} else {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -498,7 +519,11 @@ USBD_IRQHandler(void)
|
||||
} else {
|
||||
memcpy(usb_dc_cfg.ep_in[epid].ep_ram_addr, usb_dc_cfg.ep_in[epid].xfer_buf, usb_dc_cfg.ep_in[epid].xfer_len);
|
||||
}
|
||||
EPn_SET_TX_VALID(epid);
|
||||
if (usb_dc_cfg.ep_in[epid].eptype != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
|
||||
EPn_SET_TX_VALID(epid);
|
||||
} else {
|
||||
EPn_SET_TX_ISO_VALID(epid);
|
||||
}
|
||||
} else {
|
||||
usb_dc_cfg.ep_in[epid].actual_xfer_len += usb_dc_cfg.ep_in[epid].xfer_len;
|
||||
usb_dc_cfg.ep_in[epid].xfer_len = 0;
|
||||
@@ -534,7 +559,11 @@ USBD_IRQHandler(void)
|
||||
if ((read_count < usb_dc_cfg.ep_out[epid].mps) || (usb_dc_cfg.ep_out[epid].xfer_len == 0)) {
|
||||
usbd_event_ep_out_complete_handler(((epid)&0x7f), usb_dc_cfg.ep_out[epid].actual_xfer_len);
|
||||
} else {
|
||||
EPn_SET_RX_VALID(epid);
|
||||
if (usb_dc_cfg.ep_out[epid].eptype != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
|
||||
EPn_SET_RX_VALID(epid);
|
||||
} else {
|
||||
EPn_SET_RX_ISO_VALID(epid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -554,16 +583,16 @@ USBD_IRQHandler(void)
|
||||
* If it is in, the host will send the data1 out packet to complete the status phase after the in completes.
|
||||
* If it is out, the host will send the data1 in packet to complete the status phase after the out completes.
|
||||
*/
|
||||
CH58x_USBFS_DEV->UEP0_CTRL = RB_UEP_R_TOG | RB_UEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_NAK;
|
||||
CH58x_USBFS_DEV->UEP0_CTRL = RB_UEP_R_TOG | RB_UEP_T_TOG | UEP_T_RES_NAK;
|
||||
/*!< get setup packet */
|
||||
usb_dc_cfg.setup = GET_SETUP_PACKET(usb_dc_cfg.ep_out[0].ep_ram_addr);
|
||||
if (usb_dc_cfg.setup.bmRequestType >> USB_REQUEST_DIR_SHIFT == 0) {
|
||||
/**
|
||||
* Ep0 The next in must be the status stage.
|
||||
* The device must reply to the host data 0 length packet.
|
||||
* Here, set the transmission length to 0 and the transmission status to ACK,
|
||||
* and wait for the host to send the in token to retrieve
|
||||
*/
|
||||
* Ep0 The next in must be the status stage.
|
||||
* The device must reply to the host data 0 length packet.
|
||||
* Here, set the transmission length to 0 and the transmission status to ACK,
|
||||
* and wait for the host to send the in token to retrieve
|
||||
*/
|
||||
EPn_SET_TX_LEN(0, 0);
|
||||
EPn_SET_TX_VALID(0);
|
||||
}
|
||||
@@ -574,10 +603,10 @@ USBD_IRQHandler(void)
|
||||
} else if (intflag & RB_UIF_BUS_RST) {
|
||||
/*!< Reset */
|
||||
CH58x_USBFS_DEV->USB_DEV_AD = 0;
|
||||
CH58x_USBFS_DEV->USB_INT_FG = RB_UIF_BUS_RST;
|
||||
usbd_event_reset_handler();
|
||||
/*!< Set ep0 rx vaild to start receive setup packet */
|
||||
EPn_SET_RX_VALID(0);
|
||||
CH58x_USBFS_DEV->USB_INT_FG = RB_UIF_BUS_RST;
|
||||
} else if (intflag & RB_UIF_SUSPEND) {
|
||||
if (CH58x_USBFS_DEV->USB_MIS_ST & RB_UMS_SUSPEND) {
|
||||
/*!< Suspend */
|
||||
|
||||
@@ -4,9 +4,6 @@
|
||||
#ifdef CONFIG_USB_HS
|
||||
#error "usb fs do not support hs"
|
||||
#endif
|
||||
#ifndef CONFIG_USBDEV_ALIGN_CHECK_DISABLE
|
||||
#error "ch32 ip must disable align check"
|
||||
#endif
|
||||
|
||||
#ifndef USBD_IRQHandler
|
||||
#define USBD_IRQHandler OTG_FS_IRQHandler //use actual usb irq name instead
|
||||
@@ -99,6 +96,11 @@ int usbd_set_address(const uint8_t addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t usbd_get_port_speed(const uint8_t port)
|
||||
{
|
||||
return USB_SPEED_FULL;
|
||||
}
|
||||
|
||||
int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg)
|
||||
{
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep_cfg->ep_addr);
|
||||
|
||||
@@ -96,6 +96,11 @@ int usbd_set_address(const uint8_t addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t usbd_get_port_speed(const uint8_t port)
|
||||
{
|
||||
return USB_SPEED_HIGH;
|
||||
}
|
||||
|
||||
int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg)
|
||||
{
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep_cfg->ep_addr);
|
||||
|
||||
1302
port/ch32/usb_hc_usbfs.c
Normal file
1302
port/ch32/usb_hc_usbfs.c
Normal file
File diff suppressed because it is too large
Load Diff
1341
port/ch32/usb_hc_usbhs.c
Normal file
1341
port/ch32/usb_hc_usbhs.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -26,6 +26,10 @@
|
||||
|
||||
- HC32F4A0
|
||||
|
||||
## Espressif
|
||||
|
||||
- ESP32S2、ESP32S3
|
||||
|
||||
## Before Use
|
||||
|
||||
Your should implement `usb_dc_low_level_init` and `usb_dc_low_level_deinit`.
|
||||
|
||||
@@ -675,6 +675,23 @@ int usbd_set_address(const uint8_t addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t usbd_get_port_speed(const uint8_t port)
|
||||
{
|
||||
uint8_t speed;
|
||||
uint32_t DevEnumSpeed = USB_OTG_DEV->DSTS & USB_OTG_DSTS_ENUMSPD;
|
||||
|
||||
if (DevEnumSpeed == DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ) {
|
||||
speed = USB_SPEED_HIGH;
|
||||
} else if ((DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ) ||
|
||||
(DevEnumSpeed == DSTS_ENUMSPD_FS_PHY_48MHZ)) {
|
||||
speed = USB_SPEED_FULL;
|
||||
} else {
|
||||
speed = USB_SPEED_FULL;
|
||||
}
|
||||
|
||||
return speed;
|
||||
}
|
||||
|
||||
int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg)
|
||||
{
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep_cfg->ep_addr);
|
||||
@@ -734,7 +751,7 @@ int usbd_ep_close(const uint8_t ep)
|
||||
|
||||
if (USB_EP_DIR_IS_OUT(ep)) {
|
||||
USB_OTG_OUTEP(ep_idx)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
|
||||
USB_OTG_OUTEP(ep_idx)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
|
||||
// USB_OTG_OUTEP(ep_idx)->DOEPCTL |= USB_OTG_DOEPCTL_EPDIS;
|
||||
|
||||
USB_OTG_DEV->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep_idx & 0x07)) << 16));
|
||||
USB_OTG_DEV->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((uint32_t)(1UL << (ep_idx & 0x07)) << 16));
|
||||
@@ -744,13 +761,13 @@ int usbd_ep_close(const uint8_t ep)
|
||||
USB_OTG_DOEPCTL_EPTYP);
|
||||
} else {
|
||||
USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
|
||||
USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
|
||||
// USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_EPDIS;
|
||||
|
||||
USB_OTG_DEV->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep_idx & 0x07)));
|
||||
USB_OTG_DEV->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & (uint32_t)(1UL << (ep_idx & 0x07)));
|
||||
USB_OTG_INEP(ep_idx)->DIEPCTL &= ~(USB_OTG_DIEPCTL_USBAEP |
|
||||
USB_OTG_DIEPCTL_MPSIZ |
|
||||
USB_OTG_DIEPCTL_TXFNUM |
|
||||
// USB_OTG_DIEPCTL_TXFNUM |
|
||||
USB_OTG_DIEPCTL_SD0PID_SEVNFRM |
|
||||
USB_OTG_DIEPCTL_EPTYP);
|
||||
}
|
||||
@@ -852,9 +869,6 @@ int usbd_ep_start_write(const uint8_t ep, const uint8_t *data, uint32_t data_len
|
||||
USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_XFRSIZ & data_len);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
|
||||
USB_OTG_INEP(ep_idx)->DIEPDMA = (uint32_t)data;
|
||||
|
||||
if (g_dwc2_udc.in_ep[ep_idx].ep_type == 0x01) {
|
||||
if ((USB_OTG_DEV->DSTS & (1U << 8)) == 0U) {
|
||||
USB_OTG_INEP(ep_idx)->DIEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
|
||||
@@ -864,6 +878,10 @@ int usbd_ep_start_write(const uint8_t ep, const uint8_t *data, uint32_t data_len
|
||||
USB_OTG_INEP(ep_idx)->DIEPTSIZ &= ~(USB_OTG_DIEPTSIZ_MULCNT);
|
||||
USB_OTG_INEP(ep_idx)->DIEPTSIZ |= (USB_OTG_DIEPTSIZ_MULCNT & (1U << 29));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
|
||||
USB_OTG_INEP(ep_idx)->DIEPDMA = (uint32_t)data;
|
||||
|
||||
USB_OTG_INEP(ep_idx)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
|
||||
#else
|
||||
USB_OTG_INEP(ep_idx)->DIEPCTL |= (USB_OTG_DIEPCTL_CNAK | USB_OTG_DIEPCTL_EPENA);
|
||||
@@ -921,7 +939,7 @@ int usbd_ep_start_read(const uint8_t ep, uint8_t *data, uint32_t data_len)
|
||||
|
||||
#ifdef CONFIG_USB_DWC2_DMA_ENABLE
|
||||
USB_OTG_OUTEP(ep_idx)->DOEPDMA = (uint32_t)data;
|
||||
|
||||
#endif
|
||||
if (g_dwc2_udc.out_ep[ep_idx].ep_type == 0x01) {
|
||||
if ((USB_OTG_DEV->DSTS & (1U << 8)) == 0U) {
|
||||
USB_OTG_OUTEP(ep_idx)->DOEPCTL |= USB_OTG_DIEPCTL_SODDFRM;
|
||||
@@ -929,8 +947,6 @@ int usbd_ep_start_read(const uint8_t ep, uint8_t *data, uint32_t data_len)
|
||||
USB_OTG_OUTEP(ep_idx)->DOEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
USB_OTG_OUTEP(ep_idx)->DOEPCTL |= (USB_OTG_DOEPCTL_CNAK | USB_OTG_DOEPCTL_EPENA);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -192,6 +192,7 @@ static void dwc2_pipe_init(uint8_t ch_num, uint8_t devaddr, uint8_t ep_addr, uin
|
||||
|
||||
switch (ep_type) {
|
||||
case USB_ENDPOINT_TYPE_CONTROL:
|
||||
regval |= USB_OTG_HCINTMSK_NAKM;
|
||||
case USB_ENDPOINT_TYPE_BULK:
|
||||
break;
|
||||
case USB_ENDPOINT_TYPE_INTERRUPT:
|
||||
@@ -347,11 +348,6 @@ static inline uint32_t dwc2_get_glb_intstatus(void)
|
||||
return tmpreg;
|
||||
}
|
||||
|
||||
static inline uint32_t dwc2_get_current_frame(void)
|
||||
{
|
||||
return (USB_OTG_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
|
||||
}
|
||||
|
||||
static int dwc2_pipe_alloc(void)
|
||||
{
|
||||
int chidx;
|
||||
@@ -468,6 +464,12 @@ int usb_hc_init(void)
|
||||
|
||||
usb_hc_low_level_init();
|
||||
|
||||
if ((USB_OTG_GLB->CID & (0x1U << 8)) == 0U) {
|
||||
USB_LOG_ERR("This dwc2 version does not support dma, so stop working\r\n");
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
USB_OTG_GLB->GAHBCFG &= ~USB_OTG_GAHBCFG_GINT;
|
||||
|
||||
ret = dwc2_core_init();
|
||||
@@ -533,6 +535,11 @@ int usb_hc_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t usbh_get_frame_number(void)
|
||||
{
|
||||
return (USB_OTG_HOST->HFNUM & USB_OTG_HFNUM_FRNUM);
|
||||
}
|
||||
|
||||
int usbh_roothub_control(struct usb_setup_packet *setup, uint8_t *buf)
|
||||
{
|
||||
__IO uint32_t hprt0;
|
||||
@@ -769,8 +776,6 @@ int usbh_submit_urb(struct usbh_urb *urb)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
|
||||
if (!chan->hport->connected) {
|
||||
return -ENODEV;
|
||||
}
|
||||
@@ -779,6 +784,8 @@ int usbh_submit_urb(struct usbh_urb *urb)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
|
||||
chan->waiter = false;
|
||||
chan->xfrd = 0;
|
||||
chan->urb = urb;
|
||||
@@ -836,6 +843,7 @@ int usbh_kill_urb(struct usbh_urb *urb)
|
||||
flags = usb_osal_enter_critical_section();
|
||||
|
||||
dwc2_halt(pipe->chidx);
|
||||
CLEAR_HC_INT(pipe->chidx, USB_OTG_HCINT_CHH);
|
||||
pipe->urb = NULL;
|
||||
|
||||
usb_osal_leave_critical_section(flags);
|
||||
@@ -875,8 +883,6 @@ static void dwc2_inchan_irq_handler(uint8_t ch_num)
|
||||
chan = &g_dwc2_hcd.pipe_pool[ch_num];
|
||||
urb = chan->urb;
|
||||
//printf("s1:%08x\r\n", chan_intstatus);
|
||||
for (uint32_t i = 0; i < 0xf; i++) {
|
||||
}
|
||||
|
||||
if ((chan_intstatus & USB_OTG_HCINT_XFRC) == USB_OTG_HCINT_XFRC) {
|
||||
urb->errorcode = 0;
|
||||
@@ -887,6 +893,7 @@ static void dwc2_inchan_irq_handler(uint8_t ch_num)
|
||||
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_NAK);
|
||||
} else if ((chan_intstatus & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR) {
|
||||
USB_UNMASK_HALT_HC_INT(ch_num);
|
||||
dwc2_halt(ch_num);
|
||||
urb->errorcode = -EIO;
|
||||
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR);
|
||||
} else if ((chan_intstatus & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL) {
|
||||
@@ -971,7 +978,13 @@ static void dwc2_inchan_irq_handler(uint8_t ch_num)
|
||||
}
|
||||
} else if (urb->errorcode == -EAGAIN) {
|
||||
/* re-activate the channel */
|
||||
dwc2_bulk_intr_pipe_init(chan, urb->transfer_buffer, urb->transfer_buffer_length);
|
||||
if (chan->ep_type == 0x00) {
|
||||
dwc2_control_pipe_init(chan, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
|
||||
} else if (chan->ep_type == 0x03) {
|
||||
dwc2_bulk_intr_pipe_init(chan, urb->transfer_buffer, urb->transfer_buffer_length);
|
||||
} else {
|
||||
}
|
||||
|
||||
} else {
|
||||
dwc2_pipe_waitup(chan);
|
||||
}
|
||||
@@ -999,6 +1012,7 @@ static void dwc2_outchan_irq_handler(uint8_t ch_num)
|
||||
USB_UNMASK_HALT_HC_INT(ch_num);
|
||||
} else if ((chan_intstatus & USB_OTG_HCINT_AHBERR) == USB_OTG_HCINT_AHBERR) {
|
||||
USB_UNMASK_HALT_HC_INT(ch_num);
|
||||
dwc2_halt(ch_num);
|
||||
urb->errorcode = -EIO;
|
||||
CLEAR_HC_INT(ch_num, USB_OTG_HCINT_AHBERR);
|
||||
} else if ((chan_intstatus & USB_OTG_HCINT_STALL) == USB_OTG_HCINT_STALL) {
|
||||
@@ -1093,7 +1107,13 @@ static void dwc2_outchan_irq_handler(uint8_t ch_num)
|
||||
}
|
||||
} else if (urb->errorcode == -EAGAIN) {
|
||||
/* re-activate the channel */
|
||||
dwc2_bulk_intr_pipe_init(chan, urb->transfer_buffer, urb->transfer_buffer_length);
|
||||
if (chan->ep_type == 0x00) {
|
||||
dwc2_control_pipe_init(chan, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
|
||||
} else if (chan->ep_type == 0x03) {
|
||||
dwc2_bulk_intr_pipe_init(chan, urb->transfer_buffer, urb->transfer_buffer_length);
|
||||
} else {
|
||||
}
|
||||
|
||||
} else {
|
||||
dwc2_pipe_waitup(chan);
|
||||
}
|
||||
|
||||
92
port/ehci/usb_ehci_priv.h
Normal file
92
port/ehci/usb_ehci_priv.h
Normal file
@@ -0,0 +1,92 @@
|
||||
#ifndef _USB_EHCI_PRIV_H
|
||||
#define _USB_EHCI_PRIV_H
|
||||
|
||||
#include "usbh_core.h"
|
||||
#include "usbh_hub.h"
|
||||
#include "usb_hc_ehci.h"
|
||||
|
||||
#ifndef USBH_IRQHandler
|
||||
#define USBH_IRQHandler USBH_IRQHandler
|
||||
#endif
|
||||
|
||||
#define EHCI_HCCR ((struct ehci_hccr *)CONFIG_USB_EHCI_HCCR_BASE)
|
||||
#define EHCI_HCOR ((struct ehci_hcor *)CONFIG_USB_EHCI_HCOR_BASE)
|
||||
|
||||
#define EHCI_PTR2ADDR(x) ((uint32_t)x)
|
||||
#define EHCI_ADDRALIGN32(x) ((uint32_t)(x) & ~0x1F)
|
||||
#define EHCI_ADDR2QH(x) ((struct ehci_qh_hw *)((uint32_t)(x) & ~0x1F))
|
||||
#define EHCI_ADDR2ITD(x) ((struct ehci_itd_hw *)((uint32_t)(x) & ~0x1F))
|
||||
|
||||
#if CONFIG_USB_EHCI_FRAME_LIST_SIZE == 1024
|
||||
#define EHCI_PERIOIDIC_QH_NUM 11
|
||||
#elif CONFIG_USB_EHCI_FRAME_LIST_SIZE == 512
|
||||
#define EHCI_PERIOIDIC_QH_NUM 10
|
||||
#elif CONFIG_USB_EHCI_FRAME_LIST_SIZE == 256
|
||||
#define EHCI_PERIOIDIC_QH_NUM 9
|
||||
#else
|
||||
#error Unsupported frame size list size
|
||||
#endif
|
||||
|
||||
#define CONFIG_USB_EHCI_QH_NUM CONFIG_USBHOST_PIPE_NUM
|
||||
#define CONFIG_USB_EHCI_QTD_NUM (CONFIG_USBHOST_PIPE_NUM * 3)
|
||||
#define CONFIG_USB_EHCI_ITD_NUM 10
|
||||
#define CONFIG_USB_EHCI_ITD_POOL_NUM 2
|
||||
|
||||
extern uint8_t usbh_get_port_speed(const uint8_t port);
|
||||
|
||||
struct ehci_qh_hw;
|
||||
struct ehci_itd_hw;
|
||||
struct ehci_pipe {
|
||||
uint8_t dev_addr;
|
||||
uint8_t ep_addr;
|
||||
uint8_t ep_type;
|
||||
uint8_t ep_interval;
|
||||
uint8_t speed;
|
||||
uint8_t mult;
|
||||
uint16_t ep_mps;
|
||||
bool toggle;
|
||||
bool inuse;
|
||||
uint32_t xfrd;
|
||||
bool waiter;
|
||||
usb_osal_sem_t waitsem;
|
||||
struct usbh_hubport *hport;
|
||||
struct ehci_qh_hw *qh;
|
||||
struct usbh_urb *urb;
|
||||
uint8_t used_itd_num;
|
||||
uint8_t id;
|
||||
uint8_t mf_unmask;
|
||||
uint8_t mf_valid;
|
||||
usb_slist_t iso_list;
|
||||
};
|
||||
|
||||
struct ehci_qh_hw {
|
||||
struct ehci_qh hw;
|
||||
uint32_t first_qtd;
|
||||
struct ehci_pipe *pipe;
|
||||
} __attribute__((aligned(32)));
|
||||
|
||||
struct ehci_qtd_hw {
|
||||
struct ehci_qtd hw;
|
||||
} __attribute__((aligned(32)));
|
||||
|
||||
struct ehci_itd_hw {
|
||||
struct ehci_itd hw;
|
||||
} __attribute__((aligned(32)));
|
||||
|
||||
struct ehci_hcd {
|
||||
bool ehci_qh_used[CONFIG_USB_EHCI_QH_NUM];
|
||||
bool ehci_qtd_used[CONFIG_USB_EHCI_QTD_NUM];
|
||||
bool ehci_itd_pool_used[CONFIG_USB_EHCI_ITD_POOL_NUM];
|
||||
struct ehci_pipe pipe_pool[CONFIG_USB_EHCI_QH_NUM];
|
||||
};
|
||||
|
||||
extern struct ehci_hcd g_ehci_hcd;
|
||||
extern uint32_t g_framelist[];
|
||||
|
||||
int ehci_itd_pool_alloc(void);
|
||||
void ehci_itd_pool_free(uint8_t id);
|
||||
int ehci_iso_pipe_init(struct ehci_pipe *pipe, struct usbh_iso_frame_packet *iso_packet, uint32_t num_of_iso_packets);
|
||||
void ehci_remove_itd_urb(struct usbh_urb *urb);
|
||||
void ehci_scan_isochronous_list(void);
|
||||
|
||||
#endif
|
||||
1280
port/ehci/usb_hc_ehci.c
Normal file
1280
port/ehci/usb_hc_ehci.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -247,7 +247,7 @@
|
||||
#define ITD_TSCL_STATUS_XACTERR (1 << 28) /* Bit 28: Transaction error */
|
||||
#define ITD_TSCL_STATUS_BABBLE (1 << 29) /* Bit 29: Babble Detected */
|
||||
#define ITD_TSCL_STATUS_DBERROR (1 << 30) /* Bit 30: Data Buffer Error */
|
||||
#define ITD_TSCL_STATUS_ACTIVE (1 << 31) /* Bit 28: Transaction error */
|
||||
#define ITD_TSCL_STATUS_ACTIVE (1 << 31) /* Bit 31: Active error */
|
||||
|
||||
/* iTD Buffer Page Pointer List. Paragraph 3.3.4 */
|
||||
|
||||
|
||||
@@ -116,6 +116,11 @@ int usbd_set_address(const uint8_t addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t usbd_get_port_speed(const uint8_t port)
|
||||
{
|
||||
return USB_SPEED_FULL;
|
||||
}
|
||||
|
||||
int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg)
|
||||
{
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep_cfg->ep_addr);
|
||||
|
||||
@@ -87,6 +87,25 @@ int usbd_set_address(const uint8_t addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t usbd_get_port_speed(const uint8_t port)
|
||||
{
|
||||
uint8_t speed;
|
||||
|
||||
speed = usb_get_port_speed(g_hpm_udc.handle->regs);
|
||||
|
||||
if (speed == 0x00) {
|
||||
return USB_SPEED_FULL;
|
||||
}
|
||||
if (speed == 0x01) {
|
||||
return USB_SPEED_LOW;
|
||||
}
|
||||
if (speed == 0x02) {
|
||||
return USB_SPEED_HIGH;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg)
|
||||
{
|
||||
usb_endpoint_config_t tmp_ep_cfg;
|
||||
@@ -114,6 +133,9 @@ int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg)
|
||||
|
||||
int usbd_ep_close(const uint8_t ep)
|
||||
{
|
||||
usb_device_handle_t *handle = g_hpm_udc.handle;
|
||||
|
||||
usb_device_edpt_close(handle, ep);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -154,7 +176,7 @@ int usbd_ep_start_write(const uint8_t ep, const uint8_t *data, uint32_t data_len
|
||||
g_hpm_udc.in_ep[ep_idx].xfer_len = data_len;
|
||||
g_hpm_udc.in_ep[ep_idx].actual_xfer_len = 0;
|
||||
|
||||
usb_device_edpt_xfer(handle, ep, data, data_len);
|
||||
usb_device_edpt_xfer(handle, ep, (uint8_t *)data, data_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -183,7 +205,6 @@ int usbd_ep_start_read(const uint8_t ep, uint8_t *data, uint32_t data_len)
|
||||
void USBD_IRQHandler(void)
|
||||
{
|
||||
uint32_t int_status;
|
||||
uint32_t speed;
|
||||
usb_device_handle_t *handle = g_hpm_udc.handle;
|
||||
uint32_t transfer_len;
|
||||
|
||||
@@ -198,7 +219,6 @@ void USBD_IRQHandler(void)
|
||||
}
|
||||
|
||||
if (int_status & intr_reset) {
|
||||
speed = usb_device_get_port_speed(handle);
|
||||
memset(g_hpm_udc.in_ep, 0, sizeof(struct hpm_ep_state) * USB_NUM_BIDIR_ENDPOINTS);
|
||||
memset(g_hpm_udc.out_ep, 0, sizeof(struct hpm_ep_state) * USB_NUM_BIDIR_ENDPOINTS);
|
||||
usbd_event_reset_handler();
|
||||
@@ -218,7 +238,6 @@ void USBD_IRQHandler(void)
|
||||
if (!usb_device_get_port_ccs(handle)) {
|
||||
} else {
|
||||
if (usb_device_get_port_reset_status(handle) == 0) {
|
||||
uint32_t speed = usb_device_get_port_speed(handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
## Support Chip List
|
||||
|
||||
### HEZHOU
|
||||
|
||||
- AIR105
|
||||
|
||||
### ES32
|
||||
|
||||
@@ -268,6 +268,26 @@ int usbd_set_address(const uint8_t addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t usbd_get_port_speed(const uint8_t port)
|
||||
{
|
||||
uint8_t speed;
|
||||
|
||||
if (HWREGB(USB_BASE + MUSB_POWER_OFFSET) & USB_POWER_HSMODE)
|
||||
speed = USB_SPEED_HIGH;
|
||||
else if (HWREGB(USB_BASE + MUSB_DEVCTL_OFFSET) & USB_DEVCTL_FSDEV)
|
||||
speed = USB_SPEED_FULL;
|
||||
else if (HWREGB(USB_BASE + MUSB_DEVCTL_OFFSET) & USB_DEVCTL_LSDEV)
|
||||
speed = USB_SPEED_LOW;
|
||||
|
||||
return speed;
|
||||
}
|
||||
|
||||
uint8_t usbd_force_full_speed(const uint8_t port)
|
||||
{
|
||||
HWREGB(USB_BASE + MUSB_POWER_OFFSET) &= ~USB_POWER_HSENAB;
|
||||
return (HWREGB(USB_BASE + MUSB_POWER_OFFSET) & USB_POWER_HSENAB);
|
||||
}
|
||||
|
||||
int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg)
|
||||
{
|
||||
uint16_t used = 0;
|
||||
@@ -351,8 +371,6 @@ int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg)
|
||||
g_musb_udc.in_ep[ep_idx].ep_type = ep_cfg->ep_type;
|
||||
g_musb_udc.in_ep[ep_idx].ep_enable = true;
|
||||
|
||||
HWREGH(USB_BASE + MUSB_TXIE_OFFSET) |= (1 << ep_idx);
|
||||
|
||||
HWREGH(USB_BASE + MUSB_IND_TXMAP_OFFSET) = ep_cfg->ep_mps;
|
||||
|
||||
//
|
||||
@@ -470,6 +488,133 @@ int usbd_ep_is_stalled(const uint8_t ep, uint8_t *stalled)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_ep_out_data_avail(uint8_t ep_addr)
|
||||
{
|
||||
uint16_t old_ep_idx, length;
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep_addr);
|
||||
|
||||
old_ep_idx = musb_get_active_ep();
|
||||
musb_set_active_ep(ep_idx);
|
||||
|
||||
if (ep_idx == 0){
|
||||
if (!(HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) & USB_CSRL0_RXRDY)){
|
||||
musb_set_active_ep(old_ep_idx);
|
||||
return 0;
|
||||
}
|
||||
length = HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET);
|
||||
musb_set_active_ep(old_ep_idx);
|
||||
return length;
|
||||
}
|
||||
else{
|
||||
if (!(HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) & USB_RXCSRL1_RXRDY)){
|
||||
musb_set_active_ep(old_ep_idx);
|
||||
return 0;
|
||||
}
|
||||
length = HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET);
|
||||
musb_set_active_ep(old_ep_idx);
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
int usb_ep_in_data_avail(uint8_t ep_addr)
|
||||
{
|
||||
uint16_t old_ep_idx, length;
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep_addr);
|
||||
|
||||
old_ep_idx = musb_get_active_ep();
|
||||
musb_set_active_ep(ep_idx);
|
||||
|
||||
if (ep_idx == 0){
|
||||
if (HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) & USB_CSRL0_TXRDY){
|
||||
musb_set_active_ep(old_ep_idx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) & USB_TXCSRL1_TXRDY){
|
||||
musb_set_active_ep(old_ep_idx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
length = HWREGH(USB_BASE + MUSB_IND_TXMAP_OFFSET);
|
||||
musb_set_active_ep(old_ep_idx);
|
||||
return length;
|
||||
}
|
||||
|
||||
int usb_ep_wait_in_data_avail(uint8_t ep_addr)
|
||||
{
|
||||
uint32_t cnt;
|
||||
|
||||
for (cnt = 0; cnt < 3000; cnt++){
|
||||
if (usb_ep_in_data_avail(ep_addr))
|
||||
return cnt;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_read_packet(uint8_t ep_addr, uint8_t *buffer, uint16_t len)
|
||||
{
|
||||
uint16_t old_ep_idx, cnt;
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep_addr);
|
||||
|
||||
old_ep_idx = musb_get_active_ep();
|
||||
musb_set_active_ep(ep_idx);
|
||||
if (ep_idx == 0){
|
||||
if (!(HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) & USB_CSRL0_RXRDY)){
|
||||
musb_set_active_ep(old_ep_idx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (!(HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) & USB_RXCSRL1_RXRDY)){
|
||||
musb_set_active_ep(old_ep_idx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
cnt = usb_ep_out_data_avail(ep_idx);
|
||||
if (cnt){
|
||||
musb_read_packet(ep_idx, buffer, cnt);
|
||||
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) &= ~(USB_RXCSRL1_OVER | USB_RXCSRL1_ERROR | USB_RXCSRL1_STALL| USB_RXCSRL1_STALLED);
|
||||
HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) &= ~(USB_RXCSRL1_RXRDY);
|
||||
musb_set_active_ep(old_ep_idx);
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int usbd_write_packet(uint8_t ep_addr, uint8_t *buffer, uint16_t len)
|
||||
{
|
||||
uint16_t old_ep_idx, cnt;
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep_addr);
|
||||
|
||||
old_ep_idx = musb_get_active_ep();
|
||||
musb_set_active_ep(ep_idx);
|
||||
if (HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) & USB_TXCSRL1_UNDRN){
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_TXCSRL1_UNDRN;
|
||||
}
|
||||
if (HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) & USB_TXCSRL1_TXRDY){
|
||||
musb_set_active_ep(old_ep_idx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!buffer && len){
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (!len){
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) |= USB_TXCSRL1_TXRDY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
cnt = usb_ep_in_data_avail(ep_idx);
|
||||
if (cnt){
|
||||
cnt = MIN(cnt, len);
|
||||
musb_write_packet(ep_idx, buffer, cnt);
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) |= USB_TXCSRL1_TXRDY;
|
||||
musb_set_active_ep(old_ep_idx);
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int usbd_ep_start_write(const uint8_t ep, const uint8_t *data, uint32_t data_len)
|
||||
{
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep);
|
||||
@@ -511,6 +656,7 @@ int usbd_ep_start_write(const uint8_t ep, const uint8_t *data, uint32_t data_len
|
||||
data_len = MIN(data_len, g_musb_udc.in_ep[ep_idx].ep_mps);
|
||||
|
||||
musb_write_packet(ep_idx, (uint8_t *)data, data_len);
|
||||
HWREGH(USB_BASE + MUSB_TXIE_OFFSET) |= (1 << ep_idx);
|
||||
|
||||
if (ep_idx == 0x00) {
|
||||
usb_ep0_state = USB_EP0_STATE_IN_DATA;
|
||||
@@ -712,6 +858,7 @@ void USBD_IRQHandler(void)
|
||||
}
|
||||
|
||||
if (g_musb_udc.in_ep[ep_idx].xfer_len == 0) {
|
||||
HWREGH(USB_BASE + MUSB_TXIE_OFFSET) &= ~(1 << ep_idx);
|
||||
usbd_event_ep_in_complete_handler(ep_idx | 0x80, g_musb_udc.in_ep[ep_idx].actual_xfer_len);
|
||||
} else {
|
||||
write_count = MIN(g_musb_udc.in_ep[ep_idx].xfer_len, g_musb_udc.in_ep[ep_idx].ep_mps);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user