mirror of https://github.com/RT-Thread/rt-thread
update(cherryusb): update to v1.4.3
Signed-off-by: sakumisu <1203593632@qq.com>
This commit is contained in:
parent
180fb2bd4c
commit
de30bd1105
|
@ -125,7 +125,9 @@ if RT_USING_CHERRYUSB
|
|||
config RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM
|
||||
bool "cdc_acm"
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_MSC
|
||||
bool "msc"
|
||||
bool "msc_ram"
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV
|
||||
bool "msc_blkdev"
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_KEYBOARD
|
||||
bool "hid_keyboard"
|
||||
config RT_CHERRYUSB_DEVICE_TEMPLATE_HID_MOUSE
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<a href="./README.md">English</a>
|
||||
</p>
|
||||
|
||||
CherryUSB is a tiny, beautiful and portable USB host and device stack for embedded system with USB IP.
|
||||
CherryUSB is a tiny and beautiful, high performance and portable USB host and device stack for embedded system with USB IP.
|
||||
|
||||

|
||||
|
||||
|
@ -103,7 +103,7 @@ CherryUSB Host Stack has the following functions:
|
|||
- Automatic loading of supported Class drivers
|
||||
- Support blocking transfers and asynchronous transfers
|
||||
- Support Composite Device
|
||||
- Multi-level HUB support, expandable up to 7 levels(Testing hub with 10 ports works well,only support dwc2 and ehci now)
|
||||
- Multi-level HUB support, expandable up to 7 levels(Testing hub with 10 ports works well,only support dwc2/ehci/xhci/rp2040)
|
||||
- Support Communication Device Class (CDC_ACM, CDC_ECM)
|
||||
- Support Human Interface Device (HID)
|
||||
- Support Mass Storage Class (MSC)
|
||||
|
@ -197,12 +197,12 @@ USB basic concepts and how the CherryUSB Device stack is implemented, see [Cherr
|
|||
|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Long-term |
|
||||
|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Long-term |
|
||||
|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Long-term |
|
||||
|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/canmv_k230)|v1.2.0 | Long-term |
|
||||
|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Long-term |
|
||||
|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= latest | Long-term |
|
||||
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with musb |
|
||||
|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with musb |
|
||||
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | TBD |
|
||||
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2 | TBD |
|
||||
|Raspberry pi | rp2040 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= v0.10.2 | No more updated |
|
||||
|
||||
## Package Support
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<a href="./README.md">English</a>
|
||||
</p>
|
||||
|
||||
CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统(带 USB IP)的 USB 主从协议栈。
|
||||
CherryUSB 是一个小而美的、可移植性高的、用于嵌入式系统(带 USB IP)的高性能 USB 主从协议栈。
|
||||
|
||||

|
||||
|
||||
|
@ -103,7 +103,7 @@ CherryUSB Host 协议栈当前实现以下功能:
|
|||
- 自动加载支持的Class 驱动
|
||||
- 支持阻塞式传输和异步传输
|
||||
- 支持复合设备
|
||||
- 支持多级 HUB,最高可拓展到 7 级(目前测试 1拖 10 没有问题,当前仅支持 dwc2 和 ehci)
|
||||
- 支持多级 HUB,最高可拓展到 7 级(目前测试 1拖 10 没有问题,仅支持 dwc2/ehci/xhci/rp2040)
|
||||
- 支持 Communication Device Class (CDC_ACM, CDC_ECM)
|
||||
- 支持 Human Interface Device (HID)
|
||||
- 支持 Mass Storage Class (MSC)
|
||||
|
@ -198,12 +198,12 @@ CherryUSB 快速入门、USB 基本概念,API 手册,Class 基本概念和
|
|||
|Artinchip | d12x/d13x/d21x | aic/ehci/ohci |[luban-lite](https://gitee.com/artinchip/luban-lite)|<= latest | Long-term |
|
||||
|Espressif | esp32s2/esp32s3/esp32p4 | dwc2 |[esp32_repo](https://github.com/CherryUSB/cherryusb_esp32)|<= latest | Long-term |
|
||||
|NXP | mcx | kinetis/chipidea/ehci |[nxp_mcx_repo](https://github.com/CherryUSB/cherryusb_mcx)|<= latest | Long-term |
|
||||
|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/canmv_k230)|v1.2.0 | Long-term |
|
||||
|Kendryte | k230 | dwc2 |[k230_repo](https://github.com/CherryUSB/k230_sdk)|v1.2.0 | Long-term |
|
||||
|Raspberry pi | rp2040/rp2350 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= latest | Long-term |
|
||||
|AllwinnerTech | F1C100S/F1C200S | musb |[cherryusb_rtt_f1c100s](https://github.com/CherryUSB/cherryusb_rtt_f1c100s)|<= latest | the same with musb |
|
||||
|Bekencorp | bk7256/bk7258 | musb |[bk_idk](https://github.com/CherryUSB/bk_idk)| v0.7.0 | the same with musb |
|
||||
|Sophgo | cv18xx | dwc2 |[cvi_alios_open](https://github.com/CherryUSB/cvi_alios_open)| v0.7.0 | TBD |
|
||||
|WCH | CH32V307/ch58x | ch32_usbfs/ch32_usbhs/ch58x |[wch_repo](https://github.com/CherryUSB/cherryusb_wch)|<= v0.10.2 | TBD |
|
||||
|Raspberry pi | rp2040 | rp2040 |[pico-examples](https://github.com/CherryUSB/pico-examples)|<= v0.10.2 | No more updated |
|
||||
|
||||
## 软件包支持
|
||||
|
||||
|
|
|
@ -1,18 +1,23 @@
|
|||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
path = [cwd + '/common']
|
||||
path = [cwd]
|
||||
path += [cwd + '/common']
|
||||
path += [cwd + '/core']
|
||||
path += [cwd + '/class/hub']
|
||||
path += [cwd + '/class/cdc']
|
||||
path += [cwd + '/class/msc']
|
||||
path += [cwd + '/class/hid']
|
||||
path += [cwd + '/class/audio']
|
||||
path += [cwd + '/class/video']
|
||||
path += [cwd + '/class/wireless']
|
||||
path += [cwd + '/class/midi']
|
||||
path += [cwd + '/class/adb']
|
||||
path += [cwd + '/class/dfu']
|
||||
path += [cwd + '/class/midi']
|
||||
path += [cwd + '/class/vendor/net']
|
||||
path += [cwd + '/class/vendor/serial']
|
||||
path += [cwd + '/class/vendor/wifi']
|
||||
src = []
|
||||
|
||||
LIBS = []
|
||||
|
@ -109,13 +114,15 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']):
|
|||
src += Glob('class/cdc/usbd_cdc_ecm.c')
|
||||
if GetDepend(['RT_CHERRYUSB_DEVICE_CDC_NCM']):
|
||||
src += Glob('class/cdc/usbd_cdc_ncm.c')
|
||||
if GetDepend(['RT_CHERRYUSB_USING_DFU']):
|
||||
if GetDepend(['RT_CHERRYUSB_DEVICE_DFU']):
|
||||
src += Glob('class/dfu/usbd_dfu.c')
|
||||
|
||||
if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_CDC_ACM']):
|
||||
src += Glob('demo/cdc_acm_template.c')
|
||||
if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_MSC']):
|
||||
src += Glob('demo/msc_ram_template.c')
|
||||
if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_MSC_BLKDEV']):
|
||||
src += Glob('platform/rtthread/usbd_msc_blkdev.c')
|
||||
if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_HID_MOUSE']):
|
||||
src += Glob('demo/hid_mouse_template.c')
|
||||
if GetDepend(['RT_CHERRYUSB_DEVICE_TEMPLATE_HID_KEYBOARD']):
|
||||
|
@ -147,7 +154,6 @@ if GetDepend(['RT_CHERRYUSB_DEVICE']):
|
|||
|
||||
# USB HOST
|
||||
if GetDepend(['RT_CHERRYUSB_HOST']):
|
||||
path += [cwd + '/class/hub']
|
||||
src += Glob('core/usbh_core.c')
|
||||
src += Glob('class/hub/usbh_hub.c')
|
||||
src += Glob('osal/usb_osal_rtthread.c')
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
VERSION_MAJOR = 1
|
||||
VERSION_MINOR = 4
|
||||
PATCHLEVEL = 2
|
||||
PATCHLEVEL = 3
|
||||
VERSION_TWEAK = 0
|
||||
EXTRAVERSION = 0
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
# set(CONFIG_CHERRYUSB_HOST_HCD "ehci_xxx")
|
||||
|
||||
list(APPEND cherryusb_incs
|
||||
${CMAKE_CURRENT_LIST_DIR}
|
||||
${CMAKE_CURRENT_LIST_DIR}/common
|
||||
${CMAKE_CURRENT_LIST_DIR}/core
|
||||
${CMAKE_CURRENT_LIST_DIR}/class/hub
|
||||
|
@ -37,6 +38,7 @@ ${CMAKE_CURRENT_LIST_DIR}/class/video
|
|||
${CMAKE_CURRENT_LIST_DIR}/class/wireless
|
||||
${CMAKE_CURRENT_LIST_DIR}/class/midi
|
||||
${CMAKE_CURRENT_LIST_DIR}/class/adb
|
||||
${CMAKE_CURRENT_LIST_DIR}/class/dfu
|
||||
${CMAKE_CURRENT_LIST_DIR}/class/vendor/net
|
||||
${CMAKE_CURRENT_LIST_DIR}/class/vendor/serial
|
||||
${CMAKE_CURRENT_LIST_DIR}/class/vendor/wifi
|
||||
|
@ -116,6 +118,8 @@ if(CONFIG_CHERRYUSB_DEVICE)
|
|||
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "aic")
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/aic/usb_dc_aic.c)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/aic/usb_dc_aic_ll.c)
|
||||
elseif("${CONFIG_CHERRYUSB_DEVICE_DCD}" STREQUAL "rp2040")
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/rp2040/usb_dc_rp2040.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@ -270,6 +274,8 @@ if(CONFIG_CHERRYUSB_HOST)
|
|||
elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "kinetis_mcx")
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/kinetis/usb_hc_kinetis.c)
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/kinetis/usb_glue_mcx.c)
|
||||
elseif("${CONFIG_CHERRYUSB_HOST_HCD}" STREQUAL "rp2040")
|
||||
list(APPEND cherryusb_srcs ${CMAKE_CURRENT_LIST_DIR}/port/rp2040/usb_hc_rp2040.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
|
@ -17,11 +17,13 @@
|
|||
/* Enable print with color */
|
||||
#define CONFIG_USB_PRINTF_COLOR_ENABLE
|
||||
|
||||
/* data align size when use dma */
|
||||
/* data align size when use dma or use dcache */
|
||||
#ifndef CONFIG_USB_ALIGN_SIZE
|
||||
#define CONFIG_USB_ALIGN_SIZE 4
|
||||
#endif
|
||||
|
||||
//#define CONFIG_USB_DCACHE_ENABLE
|
||||
|
||||
/* attribute data into no cache ram */
|
||||
#define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable")))
|
||||
|
||||
|
@ -46,6 +48,20 @@
|
|||
/* Enable test mode */
|
||||
// #define CONFIG_USBDEV_TEST_MODE
|
||||
|
||||
/* enable advance desc register api */
|
||||
// CONFIG_USBDEV_ADVANCE_DESC
|
||||
|
||||
/* move ep0 setup handler from isr to thread */
|
||||
// #define CONFIG_USBDEV_EP0_THREAD
|
||||
|
||||
#ifndef CONFIG_USBDEV_EP0_PRIO
|
||||
#define CONFIG_USBDEV_EP0_PRIO 4
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_EP0_STACKSIZE
|
||||
#define CONFIG_USBDEV_EP0_STACKSIZE 2048
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_USBDEV_MSC_MAX_LUN
|
||||
#define CONFIG_USBDEV_MSC_MAX_LUN 1
|
||||
#endif
|
||||
|
@ -276,4 +292,26 @@
|
|||
/* ---------------- MUSB Configuration ---------------- */
|
||||
// #define CONFIG_USB_MUSB_SUNXI
|
||||
|
||||
/* ================ USB Dcache Configuration ==================*/
|
||||
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
/* style 1*/
|
||||
// void usb_dcache_clean(uintptr_t addr, uint32_t size);
|
||||
// void usb_dcache_invalidate(uintptr_t addr, uint32_t size);
|
||||
// void usb_dcache_flush(uintptr_t addr, uint32_t size);
|
||||
|
||||
/* style 2*/
|
||||
// #define usb_dcache_clean(addr, size)
|
||||
// #define usb_dcache_invalidate(addr, size)
|
||||
// #define usb_dcache_flush(addr, size)
|
||||
#endif
|
||||
|
||||
#ifndef usb_phyaddr2ramaddr
|
||||
#define usb_phyaddr2ramaddr(addr) (addr)
|
||||
#endif
|
||||
|
||||
#ifndef usb_ramaddr2phyaddr
|
||||
#define usb_ramaddr2phyaddr(addr) (addr)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -822,7 +822,66 @@ struct audio_cs_ep_ep_general_descriptor {
|
|||
0x00, /* wLockDelay */ \
|
||||
0x00
|
||||
|
||||
#define AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT(bInterfaceNumber, bTerminalLink, bNrChannels, bSubFrameSize, bBitResolution, bEndpointAddress, wMaxPacketSize, bInterval, bFeedbackEndpointAddress, ...) \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
bInterfaceNumber, /* bInterfaceNumber */ \
|
||||
0x00, /* bAlternateSetting */ \
|
||||
0x00, /* bNumEndpoints */ \
|
||||
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \
|
||||
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ \
|
||||
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ \
|
||||
0x00, /* iInterface */ \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */ \
|
||||
bInterfaceNumber, /* bInterfaceNumber */ \
|
||||
0x01, /* bAlternateSetting */ \
|
||||
0x02, /* bNumEndpoints */ \
|
||||
USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ \
|
||||
AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ \
|
||||
AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ \
|
||||
0x00, /* iInterface */ \
|
||||
0x07, /* bLength */ \
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \
|
||||
AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */ \
|
||||
bTerminalLink, /* bTerminalLink : Unit ID of the Output Terminal*/ \
|
||||
0x01, /* bDelay */ \
|
||||
WBVAL(AUDIO_FORMAT_PCM), /* wFormatTag : AUDIO_FORMAT_PCM */ \
|
||||
0x08 + PP_NARG(__VA_ARGS__), /* bLength */ \
|
||||
AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ \
|
||||
AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ \
|
||||
AUDIO_FORMAT_TYPE_I, /* bFormatType */ \
|
||||
bNrChannels, /* bNrChannels */ \
|
||||
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 */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
bEndpointAddress, /* bEndpointAddress : IN endpoint 1 */ \
|
||||
0x05, /* bmAttributes */ \
|
||||
WBVAL(wMaxPacketSize), /* wMaxPacketSize */ \
|
||||
bInterval, /* bInterval : one packet per frame */ \
|
||||
0x00, /* bRefresh */ \
|
||||
bFeedbackEndpointAddress, /* bSynchAddress */ \
|
||||
0x07, /* bLength */ \
|
||||
AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ \
|
||||
AUDIO_ENDPOINT_GENERAL, /* bDescriptor */ \
|
||||
AUDIO_EP_CONTROL_SAMPLING_FEQ, /* bmAttributes AUDIO_SAMPLING_FREQ_CONTROL */ \
|
||||
0x00, /* bLockDelayUnits */ \
|
||||
0x00, /* wLockDelay */ \
|
||||
0x00, \
|
||||
0x09, /* bLength */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType */ \
|
||||
bFeedbackEndpointAddress, /* bFeedbackEndpointAddress Revise Dir to bEndpointAddress */ \
|
||||
0x11, /* bmAttributes: TransferType=Isochronous SyncType=None EndpointType=Feedback */ \
|
||||
WBVAL(4), /* XXXX wMaxPacketSize in Bytes */ \
|
||||
bInterval, /* bInterval */ \
|
||||
0x03, /* bRefresh, 8ms */ \
|
||||
0x00 /* bSynchAddress */
|
||||
|
||||
#define AUDIO_AS_DESCRIPTOR_INIT_LEN(n) (0x09 + 0x09 + 0x07 + 0x08 + 3 * n + 0x09 + 0x07)
|
||||
#define AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT_LEN(n) (0x09 + 0x09 + 0x07 + 0x08 + 3 * n + 0x09 + 0x07 + 0x09)
|
||||
|
||||
#define AUDIO_AS_ALTSETTING_DESCRIPTOR_INIT(bInterfaceNumber, bAlternateSetting, bTerminalLink, bNrChannels, bSubFrameSize, bBitResolution, bEndpointAddress, bmAttributes, wMaxPacketSize, bInterval, ...) \
|
||||
0x09, /* bLength */ \
|
||||
|
@ -1281,4 +1340,19 @@ struct audio_v2_control_range3_param_block {
|
|||
#define AUDIO_SAMPLE_FREQ_4B(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), \
|
||||
(uint8_t)((frq >> 16)), (uint8_t)((frq >> 24))
|
||||
|
||||
/* format 10.14 */
|
||||
#define AUDIO_FREQ_TO_FEEDBACK_FS(freq) ((freq << 10) / 1000)
|
||||
#define AUDIO_FEEDBACK_TO_BUF_FS(buf, feedback) \
|
||||
buf[0] = ((feedback << 4) & 0xFFU); \
|
||||
buf[1] = (((feedback << 4) >> 8U) & 0xFFU); \
|
||||
buf[2] = (((feedback << 4) >> 16U) & 0xFFU)
|
||||
|
||||
/* format 16.16 */
|
||||
#define AUDIO_FREQ_TO_FEEDBACK_HS(freq) ((freq << 13) / 1000)
|
||||
#define AUDIO_FEEDBACK_TO_BUF_HS(buf, feedback) \
|
||||
buf[0] = (((feedback & 0x00001FFFu) << 3) & 0xFFu); \
|
||||
buf[1] = ((((feedback & 0x00001FFFu) << 3) >> 8) & 0xFFu); \
|
||||
buf[2] = (((feedback & 0x01FFE000u) >> 13) & 0xFFu); \
|
||||
buf[3] = (((feedback & 0x01FFE000u) >> 21) & 0xFFu)
|
||||
|
||||
#endif /* USB_AUDIO_H */
|
||||
|
|
|
@ -231,12 +231,12 @@ static int usbh_cdc_ecm_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void usbh_cdc_ecm_rx_thread(void *argument)
|
||||
void usbh_cdc_ecm_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
|
||||
{
|
||||
uint32_t g_cdc_ecm_rx_length;
|
||||
int ret;
|
||||
|
||||
(void)argument;
|
||||
(void)CONFIG_USB_OSAL_THREAD_GET_ARGV;
|
||||
USB_LOG_INFO("Create cdc ecm rx thread\r\n");
|
||||
// clang-format off
|
||||
find_class:
|
||||
|
|
|
@ -41,7 +41,7 @@ void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class);
|
|||
uint8_t *usbh_cdc_ecm_get_eth_txbuf(void);
|
||||
int usbh_cdc_ecm_eth_output(uint32_t buflen);
|
||||
void usbh_cdc_ecm_eth_input(uint8_t *buf, uint32_t buflen);
|
||||
void usbh_cdc_ecm_rx_thread(void *argument);
|
||||
void usbh_cdc_ecm_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -62,12 +62,12 @@ static void print_ntb_parameters(struct cdc_ncm_ntb_parameters *param)
|
|||
USB_LOG_RAW("wLength: 0x%02x \r\n", param->wLength);
|
||||
USB_LOG_RAW("bmNtbFormatsSupported: %s \r\n", param->bmNtbFormatsSupported ? "NTB16" : "NTB32");
|
||||
|
||||
USB_LOG_RAW("dwNtbInMaxSize: 0x%04x \r\n", param->dwNtbInMaxSize);
|
||||
USB_LOG_RAW("dwNtbInMaxSize: 0x%08lx \r\n", param->dwNtbInMaxSize);
|
||||
USB_LOG_RAW("wNdbInDivisor: 0x%02x \r\n", param->wNdbInDivisor);
|
||||
USB_LOG_RAW("wNdbInPayloadRemainder: 0x%02x \r\n", param->wNdbInPayloadRemainder);
|
||||
USB_LOG_RAW("wNdbInAlignment: 0x%02x \r\n", param->wNdbInAlignment);
|
||||
|
||||
USB_LOG_RAW("dwNtbOutMaxSize: 0x%04x \r\n", param->dwNtbOutMaxSize);
|
||||
USB_LOG_RAW("dwNtbOutMaxSize: 0x%08lx \r\n", param->dwNtbOutMaxSize);
|
||||
USB_LOG_RAW("wNdbOutDivisor: 0x%02x \r\n", param->wNdbOutDivisor);
|
||||
USB_LOG_RAW("wNdbOutPayloadRemainder: 0x%02x \r\n", param->wNdbOutPayloadRemainder);
|
||||
USB_LOG_RAW("wNdbOutAlignment: 0x%02x \r\n", param->wNdbOutAlignment);
|
||||
|
@ -249,7 +249,7 @@ static int usbh_cdc_ncm_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void usbh_cdc_ncm_rx_thread(void *argument)
|
||||
void usbh_cdc_ncm_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
|
||||
{
|
||||
uint32_t g_cdc_ncm_rx_length;
|
||||
int ret;
|
||||
|
@ -259,7 +259,7 @@ void usbh_cdc_ncm_rx_thread(void *argument)
|
|||
uint32_t transfer_size = (16 * 1024);
|
||||
#endif
|
||||
|
||||
(void)argument;
|
||||
(void)CONFIG_USB_OSAL_THREAD_GET_ARGV;
|
||||
USB_LOG_INFO("Create cdc ncm rx thread\r\n");
|
||||
// clang-format off
|
||||
find_class:
|
||||
|
|
|
@ -45,7 +45,7 @@ void usbh_cdc_ncm_stop(struct usbh_cdc_ncm *cdc_ncm_class);
|
|||
uint8_t *usbh_cdc_ncm_get_eth_txbuf(void);
|
||||
int usbh_cdc_ncm_eth_output(uint32_t buflen);
|
||||
void usbh_cdc_ncm_eth_input(uint8_t *buf, uint32_t buflen);
|
||||
void usbh_cdc_ncm_rx_thread(void *argument);
|
||||
void usbh_cdc_ncm_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -191,11 +191,11 @@
|
|||
#define HID_MOUSE_INPUT_REPORT_BUTTON3 (1 << 2)
|
||||
#define HID_MOUSE_INPUT_REPORT_BUTTON_MASK (7)
|
||||
|
||||
#define HID_MOUSE_INPUT_BUTTON_LEFT (1 << 0)
|
||||
#define HID_MOUSE_INPUT_BUTTON_RIGHT (1 << 1)
|
||||
#define HID_MOUSE_INPUT_BUTTON_MIDDLE (1 << 2)
|
||||
#define HID_MOUSE_INPUT_BUTTON_BACKWARD (1 << 3)
|
||||
#define HID_MOUSE_INPUT_BUTTON_FORWARD (1 << 4)
|
||||
#define HID_MOUSE_INPUT_BUTTON_LEFT (1 << 0)
|
||||
#define HID_MOUSE_INPUT_BUTTON_RIGHT (1 << 1)
|
||||
#define HID_MOUSE_INPUT_BUTTON_MIDDLE (1 << 2)
|
||||
#define HID_MOUSE_INPUT_BUTTON_BACKWARD (1 << 3)
|
||||
#define HID_MOUSE_INPUT_BUTTON_FORWARD (1 << 4)
|
||||
|
||||
/* Joystick input report (4 bytes) (HID D.1) */
|
||||
#define HID_JS_INPUT_REPORT_HATSWITCH_SHIFT (0)
|
||||
|
@ -241,14 +241,14 @@
|
|||
#define HID_DESKTOP_USAGE_UNDEFINED 0x00 /* Undefined */
|
||||
#define HID_DESKTOP_USAGE_POINTER 0x01 /* Pointer */
|
||||
#define HID_DESKTOP_USAGE_MOUSE 0x02 /* Mouse */
|
||||
/* 0x03 Reserved */
|
||||
/* 0x03 Reserved */
|
||||
#define HID_DESKTOP_USAGE_JOYSTICK 0x04 /* Joystick */
|
||||
#define HID_DESKTOP_USAGE_GAMEPAD 0x05 /* Game Pad */
|
||||
#define HID_DESKTOP_USAGE_KEYBOARD 0x06 /* Keyboard */
|
||||
#define HID_DESKTOP_USAGE_KEYPAD 0x07 /* Keypad */
|
||||
#define HID_DESKTOP_USAGE_MULTIAXIS 0x08 /* Multi-axis Controller */
|
||||
#define HID_DESKTOP_USAGE_TABLET 0x09 /* Tablet PC System Controls */
|
||||
/* 0x0a-2f Reserved */
|
||||
/* 0x0a-2f Reserved */
|
||||
#define HID_DESKTOP_USAGE_X 0x30 /* X */
|
||||
#define HID_DESKTOP_USAGE_Y 0x31 /* Y */
|
||||
#define HID_DESKTOP_USAGE_Z 0x32 /* Z */
|
||||
|
@ -264,7 +264,7 @@
|
|||
#define HID_DESKTOP_USAGE_MOTION 0x3c /* Motion Wakeup */
|
||||
#define HID_DESKTOP_USAGE_START 0x3d /* Start */
|
||||
#define HID_DESKTOP_USAGE_SELECT 0x3e /* Select */
|
||||
/* 0x3f Reserved */
|
||||
/* 0x3f Reserved */
|
||||
#define HID_DESKTOP_USAGE_VX 0x40 /* Vx */
|
||||
#define HID_DESKTOP_USAGE_VY 0x41 /* Vy */
|
||||
#define HID_DESKTOP_USAGE_VZ 0x42 /* Vz */
|
||||
|
@ -274,7 +274,7 @@
|
|||
#define HID_DESKTOP_USAGE_VNO 0x46 /* Vno */
|
||||
#define HID_DESKTOP_USAGE_FEATURE 0x47 /* Feature Notification */
|
||||
#define HID_DESKTOP_USAGE_RESOLUTION 0x48 /* Resolution Multiplier */
|
||||
/* 0x49-7f Reserved */
|
||||
/* 0x49-7f Reserved */
|
||||
#define HID_DESKTOP_USAGE_CONTROL 0x80 /* System Control */
|
||||
#define HID_DESKTOP_USAGE_POWERDOWN 0x81 /* System Power Down */
|
||||
#define HID_DESKTOP_USAGE_SLEEP 0x82 /* System Sleep */
|
||||
|
@ -295,7 +295,7 @@
|
|||
#define HID_DESKTOP_USAGE_DPAD_DOWN 0x91 /* D-pad Down */
|
||||
#define HID_DESKTOP_USAGE_DPAD_RIGHT 0x92 /* D-pad Right */
|
||||
#define HID_DESKTOP_USAGE_DPAD_LEFT 0x93 /* D-pad Left */
|
||||
/* 0x94-9f Reserved */
|
||||
/* 0x94-9f Reserved */
|
||||
#define HID_DESKTOP_USAGE_DOCK 0xa0 /* System Dock */
|
||||
#define HID_DESKTOP_USAGE_UNDOCK 0xa1 /* System Undock */
|
||||
#define HID_DESKTOP_USAGE_SETUP 0xa2 /* System Setup */
|
||||
|
@ -305,7 +305,7 @@
|
|||
#define HID_DESKTOP_USAGE_APP_DEBUG_BREAK 0xa6 /* Application Debugger Break */
|
||||
#define HID_DESKTOP_USAGE_MUTE 0xa7 /* System Speaker Mute */
|
||||
#define HID_DESKTOP_USAGE_HIBERNATE 0xa8 /* System Hibernate */
|
||||
/* 0xa9-af Reserved */
|
||||
/* 0xa9-af Reserved */
|
||||
#define HID_DESKTOP_USAGE_DISPLAY_INVERT 0xb0 /* System Display Invert */
|
||||
#define HID_DESKTOP_USAGE_DISPALY_INTERNAL 0xb1 /* System Display Internal */
|
||||
#define HID_DESKTOP_USAGE_DISPLAY_EXTERNAL 0xb2 /* System Display External */
|
||||
|
@ -314,7 +314,7 @@
|
|||
#define HID_DESKTOP_USAGE_DISPLAY_TOGGLE 0xb5 /* System Display Toggle Int/Ext */
|
||||
#define HID_DESKTOP_USAGE_DISPLAY_SWAP 0xb6 /* System Display Swap */
|
||||
#define HID_DESKTOP_USAGE_ 0xb7 /* System Display LCD Autoscale */
|
||||
/* 0xb8-ffff Reserved */
|
||||
/* 0xb8-ffff Reserved */
|
||||
|
||||
/* Keyboard usage IDs (HuT 10) */
|
||||
#define HID_KBD_USAGE_NONE 0x00 /* Reserved (no event indicated) */
|
||||
|
@ -529,16 +529,16 @@
|
|||
|
||||
/* HID Report Definitions */
|
||||
struct usb_hid_class_subdescriptor {
|
||||
uint8_t bDescriptorType;/* Class descriptor type (See 7.1) */
|
||||
uint16_t wDescriptorLength;/* Size of the report descriptor */
|
||||
uint8_t bDescriptorType; /* Class descriptor type (See 7.1) */
|
||||
uint16_t wDescriptorLength; /* Size of the report descriptor */
|
||||
} __PACKED;
|
||||
|
||||
struct usb_hid_descriptor {
|
||||
uint8_t bLength; /* Size of the HID descriptor */
|
||||
uint8_t bDescriptorType;/* HID descriptor type */
|
||||
uint16_t bcdHID;/* HID class specification release */
|
||||
uint8_t bCountryCode;/* Country code */
|
||||
uint8_t bNumDescriptors;/* Number of descriptors (>=1) */
|
||||
uint8_t bLength; /* Size of the HID descriptor */
|
||||
uint8_t bDescriptorType; /* HID descriptor type */
|
||||
uint16_t bcdHID; /* HID class specification release */
|
||||
uint8_t bCountryCode; /* Country code */
|
||||
uint8_t bNumDescriptors; /* Number of descriptors (>=1) */
|
||||
|
||||
/*
|
||||
* Specification says at least one Class Descriptor needs to
|
||||
|
@ -550,11 +550,10 @@ struct usb_hid_descriptor {
|
|||
/* Standard Reports *********************************************************/
|
||||
|
||||
/* Keyboard input report (8 bytes) (HID B.1) */
|
||||
struct usb_hid_kbd_report
|
||||
{
|
||||
uint8_t modifier; /* Modifier keys. See HID_MODIFER_* definitions */
|
||||
uint8_t reserved;
|
||||
uint8_t key[6]; /* Keycode 1-6 */
|
||||
struct usb_hid_kbd_report {
|
||||
uint8_t modifier; /* Modifier keys. See HID_MODIFER_* definitions */
|
||||
uint8_t reserved;
|
||||
uint8_t key[6]; /* Keycode 1-6 */
|
||||
};
|
||||
|
||||
/* Keyboard output report (1 byte) (HID B.1),
|
||||
|
@ -562,22 +561,109 @@ struct usb_hid_kbd_report
|
|||
*/
|
||||
|
||||
/* Mouse input report (HID B.2) */
|
||||
struct usb_hid_mouse_report
|
||||
{
|
||||
uint8_t buttons; /* See HID_MOUSE_INPUT_BUTTON_* definitions */
|
||||
int8_t xdisp; /* X displacement */
|
||||
int8_t ydisp; /* y displacement */
|
||||
struct usb_hid_mouse_report {
|
||||
uint8_t buttons; /* See HID_MOUSE_INPUT_BUTTON_* definitions */
|
||||
int8_t xdisp; /* X displacement */
|
||||
int8_t ydisp; /* y displacement */
|
||||
/* Device specific additional bytes may follow */
|
||||
uint8_t wdisp; /* Wheel displacement */
|
||||
uint8_t wdisp; /* Wheel displacement */
|
||||
};
|
||||
|
||||
/* Joystick input report (1 bytes) (HID D.1) */
|
||||
struct usb_hid_js_report
|
||||
{
|
||||
int8_t xpos; /* X position */
|
||||
int8_t ypos; /* X position */
|
||||
uint8_t buttons; /* See USBHID_JSIN_* definitions */
|
||||
uint8_t throttle; /* Throttle */
|
||||
struct usb_hid_js_report {
|
||||
int8_t xpos; /* X position */
|
||||
int8_t ypos; /* X position */
|
||||
uint8_t buttons; /* See USBHID_JSIN_* definitions */
|
||||
uint8_t throttle; /* Throttle */
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
#define HID_MOUSE_DESCRIPTOR_LEN (9 + 9 + 7)
|
||||
|
||||
#define HID_MOUSE_DESCRIPTOR_INIT(bInterfaceNumber, bInterfaceSubClass, wItemLength, int_ep, wMaxPacketSize, bInterval) \
|
||||
0x09, /* bLength: Interface Descriptor size */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ \
|
||||
bInterfaceNumber, /* bInterfaceNumber: Number of Interface */ \
|
||||
0x00, /* bAlternateSetting: Alternate setting */ \
|
||||
0x01, /* bNumEndpoints */ \
|
||||
0x03, /* bInterfaceClass: HID */ \
|
||||
bInterfaceSubClass, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ \
|
||||
0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ \
|
||||
0x00, /* iInterface: Index of string descriptor */ \
|
||||
0x09, /* bLength: HID Descriptor size */ \
|
||||
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ \
|
||||
0x11, /* bcdHID: HID Class Spec release number */ \
|
||||
0x01, \
|
||||
0x00, /* bCountryCode: Hardware target country */ \
|
||||
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ \
|
||||
0x22, /* bDescriptorType */ \
|
||||
WBVAL(wItemLength), /* wItemLength: Total length of Report descriptor */ \
|
||||
0x07, /* bLength: Endpoint Descriptor size */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ \
|
||||
int_ep, /* bEndpointAddress: Endpoint Address (IN) */ \
|
||||
0x03, /* bmAttributes: Interrupt endpoint */ \
|
||||
WBVAL(wMaxPacketSize), /* wMaxPacketSize: x Byte max */ \
|
||||
bInterval /* bInterval: Polling Interval */
|
||||
|
||||
#define HID_KEYBOARD_DESCRIPTOR_LEN (9 + 9 + 7)
|
||||
|
||||
#define HID_KEYBOARD_DESCRIPTOR_INIT(bInterfaceNumber, bInterfaceSubClass, wItemLength, int_ep, wMaxPacketSize, bInterval) \
|
||||
0x09, /* bLength: Interface Descriptor size */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ \
|
||||
bInterfaceNumber, /* bInterfaceNumber: Number of Interface */ \
|
||||
0x00, /* bAlternateSetting: Alternate setting */ \
|
||||
0x01, /* bNumEndpoints */ \
|
||||
0x03, /* bInterfaceClass: HID */ \
|
||||
bInterfaceSubClass, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ \
|
||||
0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ \
|
||||
0x00, /* iInterface: Index of string descriptor */ \
|
||||
0x09, /* bLength: HID Descriptor size */ \
|
||||
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ \
|
||||
0x11, /* bcdHID: HID Class Spec release number */ \
|
||||
0x01, \
|
||||
0x00, /* bCountryCode: Hardware target country */ \
|
||||
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ \
|
||||
0x22, /* bDescriptorType */ \
|
||||
WBVAL(wItemLength), /* wItemLength: Total length of Report descriptor */ \
|
||||
0x07, /* bLength: Endpoint Descriptor size */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ \
|
||||
int_ep, /* bEndpointAddress: Endpoint Address (IN) */ \
|
||||
0x03, /* bmAttributes: Interrupt endpoint */ \
|
||||
WBVAL(wMaxPacketSize), /* wMaxPacketSize: x Byte max */ \
|
||||
bInterval /* bInterval: Polling Interval */
|
||||
|
||||
#define HID_CUSTOM_INOUT_DESCRIPTOR_LEN (9 + 9 + 7 + 7)
|
||||
|
||||
#define HID_CUSTOM_INOUT_DESCRIPTOR_INIT(bInterfaceNumber, bInterfaceSubClass, wItemLength, in_ep, out_ep,wMaxPacketSize, bInterval) \
|
||||
0x09, /* bLength: Interface Descriptor size */ \
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */ \
|
||||
bInterfaceNumber, /* bInterfaceNumber: Number of Interface */ \
|
||||
0x00, /* bAlternateSetting: Alternate setting */ \
|
||||
0x02, /* bNumEndpoints */ \
|
||||
0x03, /* bInterfaceClass: HID */ \
|
||||
bInterfaceSubClass, /* bInterfaceSubClass : 1=BOOT, 0=no boot */ \
|
||||
0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */ \
|
||||
0x00, /* iInterface: Index of string descriptor */ \
|
||||
0x09, /* bLength: HID Descriptor size */ \
|
||||
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */ \
|
||||
0x11, /* bcdHID: HID Class Spec release number */ \
|
||||
0x01, \
|
||||
0x00, /* bCountryCode: Hardware target country */ \
|
||||
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */ \
|
||||
0x22, /* bDescriptorType */ \
|
||||
WBVAL(wItemLength), /* wItemLength: Total length of Report descriptor */ \
|
||||
0x07, /* bLength: Endpoint Descriptor size */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ \
|
||||
in_ep, /* bEndpointAddress: Endpoint Address (IN) */ \
|
||||
0x03, /* bmAttributes: Interrupt endpoint */ \
|
||||
WBVAL(wMaxPacketSize), /* wMaxPacketSize: x Byte max */ \
|
||||
bInterval, /* bInterval: Polling Interval */ \
|
||||
0x07, /* bLength: Endpoint Descriptor size */ \
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */ \
|
||||
out_ep, /* bEndpointAddress: Endpoint Address (IN) */ \
|
||||
0x03, /* bmAttributes: Interrupt endpoint */ \
|
||||
WBVAL(wMaxPacketSize), /* wMaxPacketSize: x Byte max */ \
|
||||
bInterval /* bInterval: Polling Interval */
|
||||
// clang-format on
|
||||
|
||||
#endif /* USB_HID_H */
|
||||
|
|
|
@ -648,12 +648,12 @@ static void usbh_hub_events(struct usbh_hub *hub)
|
|||
}
|
||||
}
|
||||
|
||||
static void usbh_hub_thread(void *argument)
|
||||
static void usbh_hub_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
|
||||
{
|
||||
struct usbh_hub *hub;
|
||||
int ret = 0;
|
||||
|
||||
struct usbh_bus *bus = (struct usbh_bus *)argument;
|
||||
struct usbh_bus *bus = (struct usbh_bus *)CONFIG_USB_OSAL_THREAD_GET_ARGV;
|
||||
|
||||
usb_hc_init(bus);
|
||||
while (1) {
|
||||
|
|
|
@ -60,7 +60,7 @@ USB_NOCACHE_RAM_SECTION struct usbd_msc_priv {
|
|||
} g_usbd_msc[CONFIG_USBDEV_MAX_BUS];
|
||||
|
||||
#ifdef CONFIG_USBDEV_MSC_THREAD
|
||||
static void usbdev_msc_thread(void *argument);
|
||||
static void usbdev_msc_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
|
||||
#endif
|
||||
|
||||
static void usdb_msc_set_max_lun(uint8_t busid)
|
||||
|
@ -911,11 +911,11 @@ void mass_storage_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
|||
}
|
||||
|
||||
#if defined(CONFIG_USBDEV_MSC_THREAD)
|
||||
static void usbdev_msc_thread(void *argument)
|
||||
static void usbdev_msc_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
|
||||
{
|
||||
uintptr_t event;
|
||||
int ret;
|
||||
uint8_t busid = (uint8_t)(uint32_t)argument;
|
||||
uint8_t busid = (uint8_t)CONFIG_USB_OSAL_THREAD_GET_ARGV;
|
||||
|
||||
while (1) {
|
||||
ret = usb_osal_mq_recv(g_usbd_msc[busid].usbd_msc_mq, (uintptr_t *)&event, USB_OSAL_WAITING_FOREVER);
|
||||
|
|
|
@ -13,8 +13,11 @@
|
|||
|
||||
#define DEV_FORMAT "/dev/sd%c"
|
||||
|
||||
#define MSC_INQUIRY_TIMEOUT 500
|
||||
#ifndef CONFIG_USBHOST_MSC_READY_CHECK_TIMES
|
||||
#define CONFIG_USBHOST_MSC_READY_CHECK_TIMES 10
|
||||
#endif
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_msc_cbw_csw[CONFIG_USBHOST_MAX_MSC_CLASS][USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_msc_buf[CONFIG_USBHOST_MAX_MSC_CLASS][USB_ALIGN_UP(64, CONFIG_USB_ALIGN_SIZE)];
|
||||
|
||||
static struct usbh_msc g_msc_class[CONFIG_USBHOST_MAX_MSC_CLASS];
|
||||
|
@ -131,7 +134,7 @@ static int usbh_bulk_cbw_csw_xfer(struct usbh_msc *msc_class, struct CBW *cbw, s
|
|||
/* Send the CBW */
|
||||
nbytes = usbh_msc_bulk_out_transfer(msc_class, (uint8_t *)cbw, USB_SIZEOF_MSC_CBW, timeout);
|
||||
if (nbytes < 0) {
|
||||
USB_LOG_ERR("cbw transfer error\r\n");
|
||||
USB_LOG_ERR("cbw transfer error: %d\r\n", nbytes);
|
||||
goto __err_exit;
|
||||
}
|
||||
|
||||
|
@ -150,7 +153,7 @@ static int usbh_bulk_cbw_csw_xfer(struct usbh_msc *msc_class, struct CBW *cbw, s
|
|||
}
|
||||
|
||||
if (nbytes < 0) {
|
||||
USB_LOG_ERR("msc data transfer error\r\n");
|
||||
USB_LOG_ERR("msc data transfer error: %d\r\n", nbytes);
|
||||
goto __err_exit;
|
||||
}
|
||||
}
|
||||
|
@ -159,7 +162,7 @@ static int usbh_bulk_cbw_csw_xfer(struct usbh_msc *msc_class, struct CBW *cbw, s
|
|||
memset(csw, 0, USB_SIZEOF_MSC_CSW);
|
||||
nbytes = usbh_msc_bulk_in_transfer(msc_class, (uint8_t *)csw, USB_SIZEOF_MSC_CSW, timeout);
|
||||
if (nbytes < 0) {
|
||||
USB_LOG_ERR("csw transfer error\r\n");
|
||||
USB_LOG_ERR("csw transfer error: %d\r\n", nbytes);
|
||||
goto __err_exit;
|
||||
}
|
||||
|
||||
|
@ -184,14 +187,14 @@ static inline int usbh_msc_scsi_testunitready(struct usbh_msc *msc_class)
|
|||
struct CBW *cbw;
|
||||
|
||||
/* Construct the CBW */
|
||||
cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
|
||||
cbw = (struct CBW *)g_msc_cbw_csw[msc_class->sdchar - 'a'];
|
||||
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
|
||||
cbw->dSignature = MSC_CBW_Signature;
|
||||
|
||||
cbw->bCBLength = SCSICMD_TESTUNITREADY_SIZEOF;
|
||||
cbw->CB[0] = SCSI_CMD_TESTUNITREADY;
|
||||
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], NULL, MSC_INQUIRY_TIMEOUT);
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_cbw_csw[msc_class->sdchar - 'a'], NULL, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
}
|
||||
|
||||
static inline int usbh_msc_scsi_requestsense(struct usbh_msc *msc_class)
|
||||
|
@ -199,7 +202,7 @@ static inline int usbh_msc_scsi_requestsense(struct usbh_msc *msc_class)
|
|||
struct CBW *cbw;
|
||||
|
||||
/* Construct the CBW */
|
||||
cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
|
||||
cbw = (struct CBW *)g_msc_cbw_csw[msc_class->sdchar - 'a'];
|
||||
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
|
||||
cbw->dSignature = MSC_CBW_Signature;
|
||||
|
||||
|
@ -209,7 +212,7 @@ static inline int usbh_msc_scsi_requestsense(struct usbh_msc *msc_class)
|
|||
cbw->CB[0] = SCSI_CMD_REQUESTSENSE;
|
||||
cbw->CB[4] = SCSIRESP_FIXEDSENSEDATA_SIZEOF;
|
||||
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], MSC_INQUIRY_TIMEOUT);
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_cbw_csw[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
}
|
||||
|
||||
static inline int usbh_msc_scsi_inquiry(struct usbh_msc *msc_class)
|
||||
|
@ -217,7 +220,7 @@ static inline int usbh_msc_scsi_inquiry(struct usbh_msc *msc_class)
|
|||
struct CBW *cbw;
|
||||
|
||||
/* Construct the CBW */
|
||||
cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
|
||||
cbw = (struct CBW *)g_msc_cbw_csw[msc_class->sdchar - 'a'];
|
||||
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
|
||||
cbw->dSignature = MSC_CBW_Signature;
|
||||
|
||||
|
@ -227,7 +230,7 @@ static inline int usbh_msc_scsi_inquiry(struct usbh_msc *msc_class)
|
|||
cbw->CB[0] = SCSI_CMD_INQUIRY;
|
||||
cbw->CB[4] = SCSIRESP_INQUIRY_SIZEOF;
|
||||
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], MSC_INQUIRY_TIMEOUT);
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_cbw_csw[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
}
|
||||
|
||||
static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class)
|
||||
|
@ -235,7 +238,7 @@ static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class)
|
|||
struct CBW *cbw;
|
||||
|
||||
/* Construct the CBW */
|
||||
cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
|
||||
cbw = (struct CBW *)g_msc_cbw_csw[msc_class->sdchar - 'a'];
|
||||
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
|
||||
cbw->dSignature = MSC_CBW_Signature;
|
||||
|
||||
|
@ -244,7 +247,7 @@ static inline int usbh_msc_scsi_readcapacity10(struct usbh_msc *msc_class)
|
|||
cbw->bCBLength = SCSICMD_READCAPACITY10_SIZEOF;
|
||||
cbw->CB[0] = SCSI_CMD_READCAPACITY10;
|
||||
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], MSC_INQUIRY_TIMEOUT);
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_cbw_csw[msc_class->sdchar - 'a'], g_msc_buf[msc_class->sdchar - 'a'], CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
}
|
||||
|
||||
static inline void usbh_msc_modeswitch(struct usbh_msc *msc_class, const uint8_t *message)
|
||||
|
@ -252,18 +255,18 @@ static inline void usbh_msc_modeswitch(struct usbh_msc *msc_class, const uint8_t
|
|||
struct CBW *cbw;
|
||||
|
||||
/* Construct the CBW */
|
||||
cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
|
||||
cbw = (struct CBW *)g_msc_cbw_csw[msc_class->sdchar - 'a'];
|
||||
|
||||
memcpy(g_msc_buf[msc_class->sdchar - 'a'], message, 31);
|
||||
memcpy(g_msc_cbw_csw[msc_class->sdchar - 'a'], message, 31);
|
||||
|
||||
usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], NULL, MSC_INQUIRY_TIMEOUT);
|
||||
usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_cbw_csw[msc_class->sdchar - 'a'], NULL, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
}
|
||||
|
||||
static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf)
|
||||
{
|
||||
struct usb_endpoint_descriptor *ep_desc;
|
||||
int ret;
|
||||
struct usbh_msc_modeswitch_config *config;
|
||||
int ret;
|
||||
|
||||
struct usbh_msc *msc_class = usbh_msc_class_alloc();
|
||||
if (msc_class == NULL) {
|
||||
|
@ -315,34 +318,6 @@ static int usbh_msc_connect(struct usbh_hubport *hport, uint8_t intf)
|
|||
}
|
||||
}
|
||||
|
||||
ret = usbh_msc_scsi_testunitready(msc_class);
|
||||
if (ret < 0) {
|
||||
ret = usbh_msc_scsi_requestsense(msc_class);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Fail to scsi_testunitready\r\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = usbh_msc_scsi_inquiry(msc_class);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Fail to scsi_inquiry\r\n");
|
||||
return ret;
|
||||
}
|
||||
ret = usbh_msc_scsi_readcapacity10(msc_class);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Fail to scsi_readcapacity10\r\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (msc_class->blocksize > 0) {
|
||||
USB_LOG_INFO("Capacity info:\r\n");
|
||||
USB_LOG_INFO("Block num:%d,block size:%d\r\n", (unsigned int)msc_class->blocknum, (unsigned int)msc_class->blocksize);
|
||||
} else {
|
||||
USB_LOG_ERR("Invalid block size\r\n");
|
||||
return -USB_ERR_RANGE;
|
||||
}
|
||||
|
||||
snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, msc_class->sdchar);
|
||||
|
||||
USB_LOG_INFO("Register MSC Class:%s\r\n", hport->config.intf[intf].devname);
|
||||
|
@ -377,12 +352,52 @@ static int usbh_msc_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int usbh_msc_scsi_init(struct usbh_msc *msc_class)
|
||||
{
|
||||
int ret;
|
||||
uint16_t cnt;
|
||||
|
||||
cnt = 0;
|
||||
while (usbh_msc_scsi_testunitready(msc_class) < 0) {
|
||||
USB_LOG_WRN("Device not ready, try again...\r\n");
|
||||
ret = usbh_msc_scsi_requestsense(msc_class);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Fail to scsi_testunitready\r\n");
|
||||
}
|
||||
cnt++;
|
||||
if (cnt > CONFIG_USBHOST_MSC_READY_CHECK_TIMES) {
|
||||
return -USB_ERR_NODEV;
|
||||
}
|
||||
}
|
||||
ret = usbh_msc_scsi_inquiry(msc_class);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Fail to scsi_inquiry\r\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = usbh_msc_scsi_readcapacity10(msc_class);
|
||||
if (ret < 0) {
|
||||
USB_LOG_ERR("Fail to scsi_readcapacity10\r\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (msc_class->blocksize > 0) {
|
||||
USB_LOG_INFO("Capacity info:\r\n");
|
||||
USB_LOG_INFO("Block num:%d,block size:%d\r\n", (unsigned int)msc_class->blocknum, (unsigned int)msc_class->blocksize);
|
||||
} else {
|
||||
USB_LOG_ERR("Invalid block size\r\n");
|
||||
return -USB_ERR_RANGE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors)
|
||||
{
|
||||
struct CBW *cbw;
|
||||
|
||||
/* Construct the CBW */
|
||||
cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
|
||||
cbw = (struct CBW *)g_msc_cbw_csw[msc_class->sdchar - 'a'];
|
||||
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
|
||||
cbw->dSignature = MSC_CBW_Signature;
|
||||
|
||||
|
@ -393,7 +408,7 @@ int usbh_msc_scsi_write10(struct usbh_msc *msc_class, uint32_t start_sector, con
|
|||
SET_BE32(&cbw->CB[2], start_sector);
|
||||
SET_BE16(&cbw->CB[7], nsectors);
|
||||
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_cbw_csw[msc_class->sdchar - 'a'], (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
}
|
||||
|
||||
int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, const uint8_t *buffer, uint32_t nsectors)
|
||||
|
@ -401,7 +416,7 @@ int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, cons
|
|||
struct CBW *cbw;
|
||||
|
||||
/* Construct the CBW */
|
||||
cbw = (struct CBW *)g_msc_buf[msc_class->sdchar - 'a'];
|
||||
cbw = (struct CBW *)g_msc_cbw_csw[msc_class->sdchar - 'a'];
|
||||
memset(cbw, 0, USB_SIZEOF_MSC_CBW);
|
||||
cbw->dSignature = MSC_CBW_Signature;
|
||||
|
||||
|
@ -413,7 +428,7 @@ int usbh_msc_scsi_read10(struct usbh_msc *msc_class, uint32_t start_sector, cons
|
|||
SET_BE32(&cbw->CB[2], start_sector);
|
||||
SET_BE16(&cbw->CB[7], nsectors);
|
||||
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_buf[msc_class->sdchar - 'a'], (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
return usbh_bulk_cbw_csw_xfer(msc_class, cbw, (struct CSW *)g_msc_cbw_csw[msc_class->sdchar - 'a'], (uint8_t *)buffer, CONFIG_USBHOST_MSC_TIMEOUT);
|
||||
}
|
||||
|
||||
void usbh_msc_modeswitch_enable(struct usbh_msc_modeswitch_config *config)
|
||||
|
|
|
@ -32,6 +32,7 @@ struct usbh_msc_modeswitch_config {
|
|||
};
|
||||
|
||||
void usbh_msc_modeswitch_enable(struct usbh_msc_modeswitch_config *config);
|
||||
int usbh_msc_scsi_init(struct usbh_msc *msc_class);
|
||||
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);
|
||||
|
||||
|
|
|
@ -670,7 +670,7 @@ int usbh_asix_get_connect_status(struct usbh_asix *asix_class)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void usbh_asix_rx_thread(void *argument)
|
||||
void usbh_asix_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
|
||||
{
|
||||
uint32_t g_asix_rx_length;
|
||||
int ret;
|
||||
|
@ -683,7 +683,7 @@ void usbh_asix_rx_thread(void *argument)
|
|||
uint32_t transfer_size = (16 * 1024);
|
||||
#endif
|
||||
|
||||
(void)argument;
|
||||
(void)CONFIG_USB_OSAL_THREAD_GET_ARGV;
|
||||
USB_LOG_INFO("Create asix rx thread\r\n");
|
||||
// clang-format off
|
||||
find_class:
|
||||
|
|
|
@ -168,7 +168,7 @@ void usbh_asix_stop(struct usbh_asix *asix_class);
|
|||
uint8_t *usbh_asix_get_eth_txbuf(void);
|
||||
int usbh_asix_eth_output(uint32_t buflen);
|
||||
void usbh_asix_eth_input(uint8_t *buf, uint32_t buflen);
|
||||
void usbh_asix_rx_thread(void *argument);
|
||||
void usbh_asix_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -2130,7 +2130,7 @@ static int usbh_rtl8152_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void usbh_rtl8152_rx_thread(void *argument)
|
||||
void usbh_rtl8152_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
|
||||
{
|
||||
uint32_t g_rtl8152_rx_length;
|
||||
int ret;
|
||||
|
@ -2142,7 +2142,7 @@ void usbh_rtl8152_rx_thread(void *argument)
|
|||
uint32_t transfer_size = (16 * 1024);
|
||||
#endif
|
||||
|
||||
(void)argument;
|
||||
(void)CONFIG_USB_OSAL_THREAD_GET_ARGV;
|
||||
USB_LOG_INFO("Create rtl8152 rx thread\r\n");
|
||||
// clang-format off
|
||||
find_class:
|
||||
|
|
|
@ -59,7 +59,7 @@ void usbh_rtl8152_stop(struct usbh_rtl8152 *rtl8152_class);
|
|||
uint8_t *usbh_rtl8152_get_eth_txbuf(void);
|
||||
int usbh_rtl8152_eth_output(uint32_t buflen);
|
||||
void usbh_rtl8152_eth_input(uint8_t *buf, uint32_t buflen);
|
||||
void usbh_rtl8152_rx_thread(void *argument);
|
||||
void usbh_rtl8152_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -347,7 +347,7 @@ static int usbh_bl616_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void usbh_bl616_rx_thread(void *argument)
|
||||
void usbh_bl616_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
|
||||
{
|
||||
int ret;
|
||||
usb_data_t *usb_hdr;
|
||||
|
@ -356,7 +356,7 @@ void usbh_bl616_rx_thread(void *argument)
|
|||
rnm_scan_ind_msg_t *scanmsg;
|
||||
uint8_t *data;
|
||||
|
||||
(void)argument;
|
||||
(void)CONFIG_USB_OSAL_THREAD_GET_ARGV;
|
||||
USB_LOG_INFO("Create bl616 wifi rx thread\r\n");
|
||||
|
||||
while (1) {
|
||||
|
|
|
@ -205,7 +205,7 @@ void usbh_bl616_sta_update_ip(uint8_t ip4_addr[4], uint8_t ip4_mask[4], uint8_t
|
|||
uint8_t *usbh_bl616_get_eth_txbuf(void);
|
||||
int usbh_bl616_eth_output(uint32_t buflen);
|
||||
void usbh_bl616_eth_input(uint8_t *buf, uint32_t buflen);
|
||||
void usbh_bl616_rx_thread(void *argument);
|
||||
void usbh_bl616_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
|
||||
|
||||
void usbh_bl616_run(struct usbh_bl616 *bl616_class);
|
||||
void usbh_bl616_stop(struct usbh_bl616 *bl616_class);
|
||||
|
|
|
@ -37,14 +37,17 @@ struct usbd_rndis_priv {
|
|||
#define CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE 1580
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_RNDIS_USING_LWIP
|
||||
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_rx_buffer[CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE];
|
||||
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_rndis_tx_buffer[CONFIG_USBDEV_RNDIS_ETH_MAX_FRAME_SIZE];
|
||||
#endif
|
||||
|
||||
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];
|
||||
|
||||
volatile uint8_t *g_rndis_rx_data_buffer;
|
||||
volatile uint32_t g_rndis_rx_data_length;
|
||||
volatile uint32_t g_rndis_rx_total_length;
|
||||
volatile uint32_t g_rndis_tx_data_length;
|
||||
|
||||
/* RNDIS options list */
|
||||
|
@ -447,12 +450,14 @@ static void rndis_notify_handler(uint8_t busid, uint8_t event, void *arg)
|
|||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
g_usbd_rndis.link_status = NDIS_MEDIA_STATE_DISCONNECTED;
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
g_rndis_rx_data_length = 0;
|
||||
g_rndis_tx_data_length = 0;
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
#ifdef CONFIG_USBDEV_RNDIS_USING_LWIP
|
||||
g_usbd_rndis.link_status = NDIS_MEDIA_STATE_CONNECTED;
|
||||
usbd_ep_start_read(0, rndis_ep_data[RNDIS_OUT_EP_IDX].ep_addr, g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
|
||||
usbd_rndis_start_read(g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -467,10 +472,9 @@ void rndis_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
|||
(void)busid;
|
||||
(void)ep;
|
||||
|
||||
hdr = (rndis_data_packet_t *)g_rndis_rx_buffer;
|
||||
g_rndis_rx_data_buffer = g_rndis_rx_buffer;
|
||||
hdr = (rndis_data_packet_t *)g_rndis_rx_data_buffer;
|
||||
if ((hdr->MessageType != REMOTE_NDIS_PACKET_MSG) || (nbytes < hdr->MessageLength)) {
|
||||
usbd_ep_start_read(0, rndis_ep_data[RNDIS_OUT_EP_IDX].ep_addr, g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
|
||||
usbd_rndis_start_read((uint8_t *)g_rndis_rx_data_buffer, g_rndis_rx_total_length);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -503,6 +507,34 @@ void rndis_int_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
|||
//USB_LOG_DBG("len:%d\r\n", nbytes);
|
||||
}
|
||||
|
||||
int usbd_rndis_start_write(uint8_t *buf, uint32_t len)
|
||||
{
|
||||
if (!usb_device_is_configured(0)) {
|
||||
return -USB_ERR_NODEV;
|
||||
}
|
||||
|
||||
if (g_rndis_tx_data_length > 0) {
|
||||
return -USB_ERR_BUSY;
|
||||
}
|
||||
|
||||
g_rndis_tx_data_length = len;
|
||||
|
||||
USB_LOG_DBG("txlen:%d\r\n", g_rndis_tx_data_length);
|
||||
return usbd_ep_start_write(0, rndis_ep_data[RNDIS_IN_EP_IDX].ep_addr, buf, len);
|
||||
}
|
||||
|
||||
int usbd_rndis_start_read(uint8_t *buf, uint32_t len)
|
||||
{
|
||||
if (!usb_device_is_configured(0)) {
|
||||
return -USB_ERR_NODEV;
|
||||
}
|
||||
|
||||
g_rndis_rx_data_buffer = buf;
|
||||
g_rndis_rx_total_length = len;
|
||||
g_rndis_rx_data_length = 0;
|
||||
return usbd_ep_start_read(0, rndis_ep_data[RNDIS_OUT_EP_IDX].ep_addr, buf, len);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USBDEV_RNDIS_USING_LWIP
|
||||
#include <lwip/pbuf.h>
|
||||
|
||||
|
@ -515,15 +547,14 @@ struct pbuf *usbd_rndis_eth_rx(void)
|
|||
}
|
||||
p = pbuf_alloc(PBUF_RAW, g_rndis_rx_data_length, PBUF_POOL);
|
||||
if (p == NULL) {
|
||||
usbd_rndis_start_read(g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
|
||||
return NULL;
|
||||
}
|
||||
usb_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(0, rndis_ep_data[RNDIS_OUT_EP_IDX].ep_addr, g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
|
||||
|
||||
usbd_rndis_start_read(g_rndis_rx_buffer, sizeof(g_rndis_rx_buffer));
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -594,6 +625,11 @@ struct usbd_interface *usbd_rndis_init_intf(struct usbd_interface *intf,
|
|||
return intf;
|
||||
}
|
||||
|
||||
void usbd_rndis_set_connect(bool connect)
|
||||
{
|
||||
g_usbd_rndis.link_status = connect ? NDIS_MEDIA_STATE_CONNECTED : NDIS_MEDIA_STATE_DISCONNECTED;
|
||||
}
|
||||
|
||||
__WEAK void usbd_rndis_data_recv_done(uint32_t len)
|
||||
{
|
||||
(void)len;
|
||||
|
@ -602,4 +638,4 @@ __WEAK void usbd_rndis_data_recv_done(uint32_t len)
|
|||
__WEAK void usbd_rndis_data_send_done(uint32_t len)
|
||||
{
|
||||
(void)len;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,8 +18,12 @@ struct usbd_interface *usbd_rndis_init_intf(struct usbd_interface *intf,
|
|||
const uint8_t in_ep,
|
||||
const uint8_t int_ep, uint8_t mac[6]);
|
||||
|
||||
void usbd_rndis_set_connect(bool connect);
|
||||
|
||||
void usbd_rndis_data_recv_done(uint32_t len);
|
||||
void usbd_rndis_data_send_done(uint32_t len);
|
||||
int usbd_rndis_start_write(uint8_t *buf, uint32_t len);
|
||||
int usbd_rndis_start_read(uint8_t *buf, uint32_t len);
|
||||
|
||||
#ifdef CONFIG_USBDEV_RNDIS_USING_LWIP
|
||||
struct pbuf *usbd_rndis_eth_rx(void);
|
||||
|
|
|
@ -189,7 +189,7 @@ int usbh_bluetooth_hci_write(uint8_t hci_type, uint8_t *buffer, uint32_t buflen)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void usbh_bluetooth_hci_rx_thread(void *argument)
|
||||
void usbh_bluetooth_hci_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
|
||||
{
|
||||
int ret;
|
||||
uint32_t ep_mps;
|
||||
|
@ -271,7 +271,7 @@ int usbh_bluetooth_hci_write(uint8_t hci_type, uint8_t *buffer, uint32_t buflen)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void usbh_bluetooth_hci_evt_rx_thread(void *argument)
|
||||
void usbh_bluetooth_hci_evt_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
|
||||
{
|
||||
int ret;
|
||||
uint32_t ep_mps;
|
||||
|
@ -320,7 +320,7 @@ delete :
|
|||
// clang-format on
|
||||
}
|
||||
|
||||
void usbh_bluetooth_hci_acl_rx_thread(void *argument)
|
||||
void usbh_bluetooth_hci_acl_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
|
||||
{
|
||||
int ret;
|
||||
uint32_t ep_mps;
|
||||
|
|
|
@ -40,10 +40,10 @@ extern "C" {
|
|||
int usbh_bluetooth_hci_write(uint8_t hci_type, uint8_t *buffer, uint32_t buflen);
|
||||
void usbh_bluetooth_hci_read_callback(uint8_t *data, uint32_t len);
|
||||
#ifdef CONFIG_USBHOST_BLUETOOTH_HCI_H4
|
||||
void usbh_bluetooth_hci_rx_thread(void *argument);
|
||||
void usbh_bluetooth_hci_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
|
||||
#else
|
||||
void usbh_bluetooth_hci_evt_rx_thread(void *argument);
|
||||
void usbh_bluetooth_hci_acl_rx_thread(void *argument);
|
||||
void usbh_bluetooth_hci_evt_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
|
||||
void usbh_bluetooth_hci_acl_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
|
||||
#endif
|
||||
|
||||
void usbh_bluetooth_run(struct usbh_bluetooth *bluetooth_class);
|
||||
|
|
|
@ -90,8 +90,8 @@ static int usbh_rndis_init_msg_transfer(struct usbh_rndis *rndis_class)
|
|||
|
||||
rndis_class->max_transfer_pkts = resp->MaxPacketsPerTransfer;
|
||||
rndis_class->max_transfer_size = resp->MaxTransferSize;
|
||||
USB_LOG_INFO("MaxPacketsPerTransfer:%d\r\n", resp->MaxPacketsPerTransfer);
|
||||
USB_LOG_INFO("MaxTransferSize:%d\r\n", resp->MaxTransferSize);
|
||||
USB_LOG_INFO("MaxPacketsPerTransfer:%ld\r\n", resp->MaxPacketsPerTransfer);
|
||||
USB_LOG_INFO("MaxTransferSize:%ld\r\n", resp->MaxTransferSize);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -278,8 +278,8 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
|
|||
struct usb_endpoint_descriptor *ep_desc;
|
||||
int ret;
|
||||
uint32_t *oid_support_list;
|
||||
unsigned int oid = 0;
|
||||
unsigned int oid_num = 0;
|
||||
uint32_t oid = 0;
|
||||
uint32_t oid_num = 0;
|
||||
uint32_t data_len;
|
||||
uint8_t tmp_buffer[512];
|
||||
uint8_t data[32];
|
||||
|
@ -319,7 +319,7 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
|
|||
return ret;
|
||||
}
|
||||
oid_num = (data_len / 4);
|
||||
USB_LOG_INFO("rndis query OID_GEN_SUPPORTED_LIST success,oid num :%d\r\n", oid_num);
|
||||
USB_LOG_INFO("rndis query OID_GEN_SUPPORTED_LIST success,oid num :%ld\r\n", oid_num);
|
||||
|
||||
oid_support_list = (uint32_t *)tmp_buffer;
|
||||
|
||||
|
@ -380,10 +380,10 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
|
|||
}
|
||||
break;
|
||||
default:
|
||||
USB_LOG_WRN("Ignore rndis query iod:%08x\r\n", oid);
|
||||
USB_LOG_WRN("Ignore rndis query iod:%08lx\r\n", oid);
|
||||
continue;
|
||||
}
|
||||
USB_LOG_INFO("rndis query iod:%08x success\r\n", oid);
|
||||
USB_LOG_INFO("rndis query iod:%08lx success\r\n", oid);
|
||||
}
|
||||
|
||||
uint32_t packet_filter = 0x0f;
|
||||
|
@ -414,7 +414,7 @@ static int usbh_rndis_connect(struct usbh_hubport *hport, uint8_t intf)
|
|||
usbh_rndis_run(rndis_class);
|
||||
return ret;
|
||||
query_errorout:
|
||||
USB_LOG_ERR("rndis query iod:%08x error\r\n", oid);
|
||||
USB_LOG_ERR("rndis query iod:%08lx error\r\n", oid);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -448,7 +448,7 @@ static int usbh_rndis_disconnect(struct usbh_hubport *hport, uint8_t intf)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void usbh_rndis_rx_thread(void *argument)
|
||||
void usbh_rndis_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
|
||||
{
|
||||
uint32_t g_rndis_rx_length;
|
||||
int ret;
|
||||
|
@ -461,7 +461,7 @@ void usbh_rndis_rx_thread(void *argument)
|
|||
uint32_t transfer_size = (16 * 1024);
|
||||
#endif
|
||||
|
||||
(void)argument;
|
||||
(void)CONFIG_USB_OSAL_THREAD_GET_ARGV;
|
||||
|
||||
USB_LOG_INFO("Create rndis rx thread\r\n");
|
||||
// clang-format off
|
||||
|
@ -501,7 +501,7 @@ find_class:
|
|||
uint32_t total_len = g_rndis_rx_length;
|
||||
|
||||
while (g_rndis_rx_length > 0) {
|
||||
USB_LOG_DBG("rxlen:%d\r\n", g_rndis_rx_length);
|
||||
USB_LOG_DBG("rxlen:%ld\r\n", g_rndis_rx_length);
|
||||
|
||||
pmsg = (rndis_data_packet_t *)(g_rndis_rx_buffer + pmg_offset);
|
||||
|
||||
|
@ -523,7 +523,7 @@ find_class:
|
|||
g_rndis_rx_length = 0;
|
||||
}
|
||||
} else {
|
||||
USB_LOG_ERR("offset:%d,remain:%d,total:%d\r\n", pmg_offset, g_rndis_rx_length, total_len);
|
||||
USB_LOG_ERR("offset:%ld,remain:%ld,total:%ld\r\n", pmg_offset, g_rndis_rx_length, total_len);
|
||||
g_rndis_rx_length = 0;
|
||||
USB_LOG_ERR("Error rndis packet message\r\n");
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ void usbh_rndis_stop(struct usbh_rndis *rndis_class);
|
|||
uint8_t *usbh_rndis_get_eth_txbuf(void);
|
||||
int usbh_rndis_eth_output(uint32_t buflen);
|
||||
void usbh_rndis_eth_input(uint8_t *buf, uint32_t buflen);
|
||||
void usbh_rndis_rx_thread(void *argument);
|
||||
void usbh_rndis_rx_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -136,7 +136,7 @@ int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, ui
|
|||
*/
|
||||
int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len);
|
||||
|
||||
/* usb dcd irq callback */
|
||||
/* usb dcd irq callback, called by user */
|
||||
|
||||
/**
|
||||
* @brief Usb connect irq callback.
|
||||
|
@ -194,6 +194,9 @@ void usbd_event_ep_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbyt
|
|||
void usbd_execute_test_mode(uint8_t busid, uint8_t test_mode);
|
||||
#endif
|
||||
|
||||
/* called by user */
|
||||
void USBD_IRQHandler(uint8_t busid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#ifndef USB_DCACHE_H
|
||||
#define USB_DCACHE_H
|
||||
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
#if CONFIG_USB_ALIGN_SIZE % 32
|
||||
#error "CONFIG_USB_ALIGN_SIZE must be multiple of 32"
|
||||
#endif
|
||||
#else
|
||||
#define usb_dcache_clean(addr, size)
|
||||
#define usb_dcache_invalidate(addr, size)
|
||||
#define usb_dcache_flush(addr, size)
|
||||
#endif
|
||||
|
||||
#endif /* USB_DCACHE_H */
|
|
@ -108,6 +108,9 @@ int usbh_submit_urb(struct usbh_urb *urb);
|
|||
*/
|
||||
int usbh_kill_urb(struct usbh_urb *urb);
|
||||
|
||||
/* called by user */
|
||||
void USBH_IRQHandler(uint8_t busid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -86,12 +86,12 @@ void usb_assert(const char *filename, int linenum);
|
|||
static inline void usb_hexdump(const void *ptr, uint32_t buflen)
|
||||
{
|
||||
unsigned char *buf = (unsigned char *)ptr;
|
||||
uint32_t i, j;
|
||||
unsigned int i, j;
|
||||
|
||||
(void)buf;
|
||||
|
||||
for (i = 0; i < buflen; i += 16) {
|
||||
CONFIG_USB_PRINTF("%08X:", i);
|
||||
CONFIG_USB_PRINTF("%08x:", i);
|
||||
|
||||
for (j = 0; j < 16; j++)
|
||||
if (i + j < buflen) {
|
||||
|
|
|
@ -10,13 +10,21 @@
|
|||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __INCLUDE_NUTTX_CONFIG_H
|
||||
#define CONFIG_USB_OSAL_THREAD_SET_ARGV int argc, char **argv
|
||||
#define CONFIG_USB_OSAL_THREAD_GET_ARGV ((uintptr_t)strtoul(argv[1], NULL, 16))
|
||||
#else
|
||||
#define CONFIG_USB_OSAL_THREAD_SET_ARGV void *argument
|
||||
#define CONFIG_USB_OSAL_THREAD_GET_ARGV ((uintptr_t)argument)
|
||||
#endif
|
||||
|
||||
#define USB_OSAL_WAITING_FOREVER (0xFFFFFFFFU)
|
||||
|
||||
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);
|
||||
typedef void (*usb_thread_entry_t)(CONFIG_USB_OSAL_THREAD_SET_ARGV);
|
||||
typedef void (*usb_timer_handler_t)(void *argument);
|
||||
struct usb_osal_timer {
|
||||
usb_timer_handler_t handler;
|
||||
|
|
|
@ -207,4 +207,12 @@
|
|||
|
||||
#define USB_ALIGN_UP(size, align) (((size) + (align)-1) & ~((align)-1))
|
||||
|
||||
#ifndef usb_phyaddr2ramaddr
|
||||
#define usb_phyaddr2ramaddr(addr) (addr)
|
||||
#endif
|
||||
|
||||
#ifndef usb_ramaddr2phyaddr
|
||||
#define usb_ramaddr2phyaddr(addr) (addr)
|
||||
#endif
|
||||
|
||||
#endif /* USB_UTIL_H */
|
||||
|
|
|
@ -4,6 +4,17 @@
|
|||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#ifdef CONFIG_USBDEV_EP0_THREAD
|
||||
#include "usb_osal.h"
|
||||
|
||||
#define USB_EP0_STATE_SETUP 0
|
||||
#define USB_EP0_STATE_IN 1
|
||||
#define USB_EP0_STATE_OUT 2
|
||||
#endif
|
||||
|
||||
#undef USB_DBG_TAG
|
||||
#define USB_DBG_TAG "usbd_core"
|
||||
#include "usb_log.h"
|
||||
|
||||
/* general descriptor field offsets */
|
||||
#define DESC_bLength 0 /** Length offset */
|
||||
|
@ -62,6 +73,10 @@ USB_NOCACHE_RAM_SECTION struct usbd_core_priv {
|
|||
#endif
|
||||
#ifdef CONFIG_USBDEV_TEST_MODE
|
||||
bool test_req;
|
||||
#endif
|
||||
#ifdef CONFIG_USBDEV_EP0_THREAD
|
||||
usb_osal_mq_t usbd_ep0_mq;
|
||||
usb_osal_thread_t usbd_ep0_thread;
|
||||
#endif
|
||||
struct usbd_interface *intf[16];
|
||||
uint8_t intf_altsetting[16];
|
||||
|
@ -431,8 +446,8 @@ static bool usbd_set_configuration(uint8_t busid, uint8_t config_index, uint8_t
|
|||
}
|
||||
|
||||
/* skip to next descriptor */
|
||||
p += p[DESC_bLength];
|
||||
current_desc_len += p[DESC_bLength];
|
||||
p += p[DESC_bLength];
|
||||
if (current_desc_len >= desc_len && desc_len) {
|
||||
break;
|
||||
}
|
||||
|
@ -497,7 +512,6 @@ static bool usbd_set_interface(uint8_t busid, uint8_t iface, uint8_t alt_setting
|
|||
|
||||
if (alt_setting == 0) {
|
||||
ret = usbd_reset_endpoint(busid, ep_desc);
|
||||
goto find_end;
|
||||
} else if (cur_alt_setting == alt_setting) {
|
||||
ret = usbd_set_endpoint(busid, ep_desc);
|
||||
} else {
|
||||
|
@ -511,14 +525,13 @@ static bool usbd_set_interface(uint8_t busid, uint8_t iface, uint8_t alt_setting
|
|||
}
|
||||
|
||||
/* skip to next descriptor */
|
||||
p += p[DESC_bLength];
|
||||
current_desc_len += p[DESC_bLength];
|
||||
p += p[DESC_bLength];
|
||||
if (current_desc_len >= desc_len && desc_len) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
find_end:
|
||||
usbd_class_event_notify_handler(busid, USBD_EVENT_SET_INTERFACE, (void *)if_desc);
|
||||
|
||||
return ret;
|
||||
|
@ -685,8 +698,8 @@ static bool usbd_std_interface_req_handler(uint8_t busid, struct usb_setup_packe
|
|||
}
|
||||
|
||||
/* skip to next descriptor */
|
||||
p += p[DESC_bLength];
|
||||
current_desc_len += p[DESC_bLength];
|
||||
p += p[DESC_bLength];
|
||||
if (current_desc_len >= desc_len && desc_len) {
|
||||
break;
|
||||
}
|
||||
|
@ -1125,12 +1138,10 @@ void usbd_event_reset_handler(uint8_t busid)
|
|||
g_usbd_core[busid].event_handler(busid, USBD_EVENT_RESET);
|
||||
}
|
||||
|
||||
void usbd_event_ep0_setup_complete_handler(uint8_t busid, uint8_t *psetup)
|
||||
static void __usbd_event_ep0_setup_complete_handler(uint8_t busid, struct usb_setup_packet *setup)
|
||||
{
|
||||
struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
|
||||
uint8_t *buf;
|
||||
|
||||
memcpy(setup, psetup, 8);
|
||||
#ifdef CONFIG_USBDEV_SETUP_LOG_PRINT
|
||||
usbd_print_setup(setup);
|
||||
#endif
|
||||
|
@ -1195,7 +1206,20 @@ void usbd_event_ep0_setup_complete_handler(uint8_t busid, uint8_t *psetup)
|
|||
}
|
||||
}
|
||||
|
||||
void usbd_event_ep0_in_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
void usbd_event_ep0_setup_complete_handler(uint8_t busid, uint8_t *psetup)
|
||||
{
|
||||
struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
|
||||
|
||||
memcpy(setup, psetup, 8);
|
||||
|
||||
#ifdef CONFIG_USBDEV_EP0_THREAD
|
||||
usb_osal_mq_send(g_usbd_core[busid].usbd_ep0_mq, USB_EP0_STATE_SETUP);
|
||||
#else
|
||||
__usbd_event_ep0_setup_complete_handler(busid, setup);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void usbd_event_ep0_in_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
|
||||
|
||||
|
@ -1236,11 +1260,12 @@ void usbd_event_ep0_in_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbyt
|
|||
}
|
||||
}
|
||||
|
||||
void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
static void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
|
||||
|
||||
(void)ep;
|
||||
(void)setup;
|
||||
|
||||
if (nbytes > 0) {
|
||||
g_usbd_core[busid].ep0_data_buf += nbytes;
|
||||
|
@ -1249,6 +1274,9 @@ void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nby
|
|||
USB_LOG_DBG("EP0 recv %d bytes, %d remained\r\n", nbytes, g_usbd_core[busid].ep0_data_buf_residue);
|
||||
|
||||
if (g_usbd_core[busid].ep0_data_buf_residue == 0) {
|
||||
#ifdef CONFIG_USBDEV_EP0_THREAD
|
||||
usb_osal_mq_send(g_usbd_core[busid].usbd_ep0_mq, USB_EP0_STATE_OUT);
|
||||
#else
|
||||
/* Received all, send data to handler */
|
||||
g_usbd_core[busid].ep0_data_buf = g_usbd_core[busid].req_data;
|
||||
if (!usbd_setup_request_handler(busid, setup, &g_usbd_core[busid].ep0_data_buf, &g_usbd_core[busid].ep0_data_buf_len)) {
|
||||
|
@ -1258,6 +1286,7 @@ void usbd_event_ep0_out_complete_handler(uint8_t busid, uint8_t ep, uint32_t nby
|
|||
|
||||
/*Send status to host*/
|
||||
usbd_ep_start_write(busid, USB_CONTROL_IN_EP0, NULL, 0);
|
||||
#endif
|
||||
} else {
|
||||
/* Start reading the remain data */
|
||||
usbd_ep_start_read(busid, USB_CONTROL_OUT_EP0, g_usbd_core[busid].ep0_data_buf, g_usbd_core[busid].ep0_data_buf_residue);
|
||||
|
@ -1396,6 +1425,47 @@ int usbd_send_remote_wakeup(uint8_t busid)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USBDEV_EP0_THREAD
|
||||
static void usbdev_ep0_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
|
||||
{
|
||||
uintptr_t event;
|
||||
int ret;
|
||||
uint8_t busid = (uint8_t)CONFIG_USB_OSAL_THREAD_GET_ARGV;
|
||||
struct usb_setup_packet *setup = &g_usbd_core[busid].setup;
|
||||
|
||||
while (1) {
|
||||
ret = usb_osal_mq_recv(g_usbd_core[busid].usbd_ep0_mq, (uintptr_t *)&event, USB_OSAL_WAITING_FOREVER);
|
||||
if (ret < 0) {
|
||||
continue;
|
||||
}
|
||||
USB_LOG_DBG("event:%d\r\n", event);
|
||||
|
||||
switch (event) {
|
||||
case USB_EP0_STATE_SETUP:
|
||||
__usbd_event_ep0_setup_complete_handler(busid, setup);
|
||||
break;
|
||||
case USB_EP0_STATE_IN:
|
||||
// do nothing
|
||||
break;
|
||||
case USB_EP0_STATE_OUT:
|
||||
/* Received all, send data to handler */
|
||||
g_usbd_core[busid].ep0_data_buf = g_usbd_core[busid].req_data;
|
||||
if (!usbd_setup_request_handler(busid, setup, &g_usbd_core[busid].ep0_data_buf, &g_usbd_core[busid].ep0_data_buf_len)) {
|
||||
usbd_ep_set_stall(busid, USB_CONTROL_IN_EP0);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*Send status to host*/
|
||||
usbd_ep_start_write(busid, USB_CONTROL_IN_EP0, NULL, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uint8_t busid, uint8_t event))
|
||||
{
|
||||
int ret;
|
||||
|
@ -1410,6 +1480,21 @@ int usbd_initialize(uint8_t busid, uintptr_t reg_base, void (*event_handler)(uin
|
|||
bus = &g_usbdev_bus[busid];
|
||||
bus->reg_base = reg_base;
|
||||
|
||||
#ifdef CONFIG_USBDEV_EP0_THREAD
|
||||
g_usbd_core[busid].usbd_ep0_mq = usb_osal_mq_create(1);
|
||||
if (g_usbd_core[busid].usbd_ep0_mq == NULL) {
|
||||
USB_LOG_ERR("No memory to alloc for g_usbd_core[busid].usbd_ep0_mq\r\n");
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
g_usbd_core[busid].usbd_ep0_thread = usb_osal_thread_create("usbd_ep0", CONFIG_USBDEV_EP0_STACKSIZE, CONFIG_USBDEV_EP0_PRIO, usbdev_ep0_thread, (void *)(uint32_t)busid);
|
||||
if (g_usbd_core[busid].usbd_ep0_thread == NULL) {
|
||||
USB_LOG_ERR("No memory to alloc for g_usbd_core[busid].usbd_ep0_thread\r\n");
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
g_usbd_core[busid].event_handler = event_handler;
|
||||
ret = usb_dc_init(busid);
|
||||
usbd_class_event_notify_handler(busid, USBD_EVENT_INIT, NULL);
|
||||
|
@ -1429,5 +1514,14 @@ int usbd_deinitialize(uint8_t busid)
|
|||
usbd_class_event_notify_handler(busid, USBD_EVENT_DEINIT, NULL);
|
||||
usb_dc_deinit(busid);
|
||||
g_usbd_core[busid].intf_offset = 0;
|
||||
#ifdef CONFIG_USBDEV_EP0_THREAD
|
||||
if (g_usbd_core[busid].usbd_ep0_mq) {
|
||||
usb_osal_mq_delete(g_usbd_core[busid].usbd_ep0_mq);
|
||||
}
|
||||
if (g_usbd_core[busid].usbd_ep0_thread) {
|
||||
usb_osal_thread_delete(g_usbd_core[busid].usbd_ep0_thread);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -324,6 +324,17 @@ static void usbh_print_hubport_info(struct usbh_hubport *hport)
|
|||
}
|
||||
}
|
||||
|
||||
static void usbh_print_setup(struct usb_setup_packet *setup)
|
||||
{
|
||||
USB_LOG_DBG("Setup: "
|
||||
"bmRequestType 0x%02x, bRequest 0x%02x, wValue 0x%04x, wIndex 0x%04x, wLength 0x%04x\r\n",
|
||||
setup->bmRequestType,
|
||||
setup->bRequest,
|
||||
setup->wValue,
|
||||
setup->wIndex,
|
||||
setup->wLength);
|
||||
}
|
||||
|
||||
static int usbh_get_default_mps(int speed)
|
||||
{
|
||||
switch (speed) {
|
||||
|
@ -674,10 +685,16 @@ int usbh_control_transfer(struct usbh_hubport *hport, struct usb_setup_packet *s
|
|||
struct usbh_urb *urb;
|
||||
int ret;
|
||||
|
||||
if (!hport || !setup) {
|
||||
return -USB_ERR_INVAL;
|
||||
}
|
||||
|
||||
urb = &hport->ep0_urb;
|
||||
|
||||
usb_osal_mutex_take(hport->mutex);
|
||||
|
||||
usbh_print_setup(setup);
|
||||
|
||||
usbh_control_urb_fill(urb, hport, setup, buffer, setup->wLength, CONFIG_USBHOST_CONTROL_TRANSFER_TIMEOUT, NULL, NULL);
|
||||
ret = usbh_submit_urb(urb);
|
||||
if (ret == 0) {
|
||||
|
@ -841,7 +858,11 @@ static struct usbh_hubport *usbh_list_all_hubport(struct usbh_hub *hub, uint8_t
|
|||
|
||||
if (hub->index == hub_index) {
|
||||
hport = &hub->child[hub_port - 1];
|
||||
return hport;
|
||||
if (hport->connected) {
|
||||
return hport;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
for (uint8_t port = 0; port < hub->nports; port++) {
|
||||
hport = &hub->child[port];
|
||||
|
@ -865,6 +886,7 @@ static struct usbh_hubport *usbh_list_all_hubport(struct usbh_hub *hub, uint8_t
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *usbh_find_class_instance(const char *devname)
|
||||
{
|
||||
usb_slist_t *bus_list;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "usb_osal.h"
|
||||
#include "usbh_hub.h"
|
||||
#include "usb_memcpy.h"
|
||||
#include "usb_dcache.h"
|
||||
#include "usb_version.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -108,6 +108,70 @@ struct usb_msosv1_descriptor msosv1_desc = {
|
|||
.comp_id_property = WINUSB_IFx_WCIDProperties,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0100, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
ADB_DESCRIPTOR_INIT(ADB_INTF_NUM, WINUSB_IN_EP, WINUSB_OUT_EP, WINUSB_MAX_MPS)
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryADB", /* Product */
|
||||
"CherryADB2024", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor msc_bootuf2_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback,
|
||||
.msosv1_descriptor = &msosv1_desc
|
||||
};
|
||||
#else
|
||||
/*!< global descriptor */
|
||||
static const uint8_t adb_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
|
@ -171,15 +235,16 @@ static const uint8_t adb_descriptor[] = {
|
|||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x02,
|
||||
0x02,
|
||||
0x01,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
static void usbd_event_handler(uint8_t busid, uint8_t event)
|
||||
{
|
||||
|
@ -222,7 +287,14 @@ void cherryadb_init(uint8_t busid, uint32_t reg_base)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &adb_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, adb_descriptor);
|
||||
#endif
|
||||
#ifndef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_msosv1_desc_register(busid, &msosv1_desc);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_adb_init_intf(busid, &intf0, WINUSB_IN_EP, WINUSB_OUT_EP));
|
||||
usbd_initialize(busid, reg_base, usbd_event_handler);
|
||||
}
|
|
@ -68,6 +68,73 @@
|
|||
AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM, 1) + \
|
||||
AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC)
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
AUDIO_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, 0x00, 0x01),
|
||||
AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x01, AUDIO_INTERM_MIC, IN_CHANNEL_NUM, INPUT_CH_ENABLE),
|
||||
AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_IN_FU_ID, 0x01, 0x01, INPUT_CTRL),
|
||||
AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x03, AUDIO_TERMINAL_STREAMING, AUDIO_IN_FU_ID),
|
||||
AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x03, IN_CHANNEL_NUM, 2, 16, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET, EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_FREQ))
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB UAC DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor audio_v1_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
const uint8_t audio_v1_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
|
@ -125,12 +192,12 @@ const uint8_t audio_v1_descriptor[] = {
|
|||
'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 */
|
||||
'2', 0x00, /* wcChar3 */
|
||||
'1', 0x00, /* wcChar4 */
|
||||
'2', 0x00, /* wcChar5 */
|
||||
'3', 0x00, /* wcChar6 */
|
||||
'4', 0x00, /* wcChar7 */
|
||||
'5', 0x00, /* wcChar8 */
|
||||
'0' + IN_CHANNEL_NUM, 0x00, /* wcChar9 */
|
||||
#ifdef CONFIG_USB_HS
|
||||
///////////////////////////////////////
|
||||
|
@ -149,6 +216,7 @@ const uint8_t audio_v1_descriptor[] = {
|
|||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
volatile bool tx_flag = 0;
|
||||
volatile bool ep_tx_busy_flag = false;
|
||||
|
@ -214,7 +282,11 @@ struct audio_entity_info audio_entity_table[] = {
|
|||
|
||||
void audio_v1_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &audio_v1_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, audio_v1_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0100, audio_entity_table, 1));
|
||||
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf1, 0x0100, audio_entity_table, 1));
|
||||
usbd_add_endpoint(busid, &audio_in_ep);
|
||||
|
|
|
@ -6,19 +6,24 @@
|
|||
#include "usbd_core.h"
|
||||
#include "usbd_audio.h"
|
||||
|
||||
#define USING_FEEDBACK 0
|
||||
|
||||
#define USBD_VID 0xffff
|
||||
#define USBD_PID 0xffff
|
||||
#define USBD_MAX_POWER 100
|
||||
#define USBD_LANGID_STRING 1033
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define EP_INTERVAL 0x04
|
||||
#define EP_INTERVAL 0x04
|
||||
#define FEEDBACK_ENDP_PACKET_SIZE 0x04
|
||||
#else
|
||||
#define EP_INTERVAL 0x01
|
||||
#define EP_INTERVAL 0x01
|
||||
#define FEEDBACK_ENDP_PACKET_SIZE 0x03
|
||||
#endif
|
||||
|
||||
#define AUDIO_IN_EP 0x81
|
||||
#define AUDIO_OUT_EP 0x02
|
||||
#define AUDIO_OUT_FEEDBACK_EP 0x83
|
||||
|
||||
#define AUDIO_IN_FU_ID 0x02
|
||||
#define AUDIO_OUT_FU_ID 0x05
|
||||
|
@ -38,6 +43,7 @@
|
|||
/* 16bit(2 Bytes) 双声道(Mono:2) */
|
||||
#define AUDIO_IN_PACKET ((uint32_t)((AUDIO_MIC_FREQ * AUDIO_MIC_FRAME_SIZE_BYTE * 2) / 1000))
|
||||
|
||||
#if USING_FEEDBACK == 0
|
||||
#define USB_AUDIO_CONFIG_DESC_SIZ (unsigned long)(9 + \
|
||||
AUDIO_AC_DESCRIPTOR_INIT_LEN(2) + \
|
||||
AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \
|
||||
|
@ -48,6 +54,18 @@
|
|||
AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
|
||||
AUDIO_AS_DESCRIPTOR_INIT_LEN(1) + \
|
||||
AUDIO_AS_DESCRIPTOR_INIT_LEN(1))
|
||||
#else
|
||||
#define USB_AUDIO_CONFIG_DESC_SIZ (unsigned long)(9 + \
|
||||
AUDIO_AC_DESCRIPTOR_INIT_LEN(2) + \
|
||||
AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \
|
||||
AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \
|
||||
AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
|
||||
AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \
|
||||
AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \
|
||||
AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
|
||||
AUDIO_AS_DESCRIPTOR_INIT_LEN(1) + \
|
||||
AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT_LEN(1))
|
||||
#endif
|
||||
|
||||
#define AUDIO_AC_SIZ (AUDIO_SIZEOF_AC_HEADER_DESC(2) + \
|
||||
AUDIO_SIZEOF_AC_INPUT_TERMINAL_DESC + \
|
||||
|
@ -57,6 +75,84 @@
|
|||
AUDIO_SIZEOF_AC_FEATURE_UNIT_DESC(2, 1) + \
|
||||
AUDIO_SIZEOF_AC_OUTPUT_TERMINAL_DESC)
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_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, 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, 0x00),
|
||||
AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_OUTTERM_SPEAKER, 0x05),
|
||||
#if USING_FEEDBACK == 0
|
||||
AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET,
|
||||
EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)),
|
||||
#else
|
||||
AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, AUDIO_OUT_PACKET,
|
||||
EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)),
|
||||
#endif
|
||||
AUDIO_AS_DESCRIPTOR_INIT(0x02, 0x03, 0x02, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET,
|
||||
EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_MIC_FREQ))
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB UAC DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor audio_v1_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
const uint8_t audio_v1_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
|
@ -67,8 +163,13 @@ const uint8_t audio_v1_descriptor[] = {
|
|||
AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_TERMINAL_STREAMING, 0x02, 0x0003),
|
||||
AUDIO_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x05, 0x04, 0x01, 0x03, 0x00, 0x00),
|
||||
AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_OUTTERM_SPEAKER, 0x05),
|
||||
#if USING_FEEDBACK == 0
|
||||
AUDIO_AS_DESCRIPTOR_INIT(0x01, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET,
|
||||
EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)),
|
||||
#else
|
||||
AUDIO_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, AUDIO_OUT_PACKET,
|
||||
EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)),
|
||||
#endif
|
||||
AUDIO_AS_DESCRIPTOR_INIT(0x02, 0x03, 0x02, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET,
|
||||
EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_MIC_FREQ)),
|
||||
///////////////////////////////////////
|
||||
|
@ -120,13 +221,17 @@ const uint8_t audio_v1_descriptor[] = {
|
|||
'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 */
|
||||
'2', 0x00, /* wcChar3 */
|
||||
'1', 0x00, /* wcChar4 */
|
||||
'2', 0x00, /* wcChar5 */
|
||||
'3', 0x00, /* wcChar6 */
|
||||
'4', 0x00, /* wcChar7 */
|
||||
'5', 0x00, /* wcChar8 */
|
||||
#if USING_FEEDBACK == 0
|
||||
'1', 0x00, /* wcChar9 */
|
||||
#else
|
||||
'2', 0x00, /* wcChar9 */
|
||||
#endif
|
||||
#ifdef CONFIG_USB_HS
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
|
@ -144,9 +249,11 @@ const uint8_t audio_v1_descriptor[] = {
|
|||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[AUDIO_OUT_PACKET];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[AUDIO_IN_PACKET];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t s_speaker_feedback_buffer[4];
|
||||
|
||||
volatile bool tx_flag = 0;
|
||||
volatile bool rx_flag = 0;
|
||||
|
@ -183,6 +290,9 @@ void usbd_audio_open(uint8_t busid, uint8_t intf)
|
|||
rx_flag = 1;
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(busid, AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET);
|
||||
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(AUDIO_SPEAKER_FREQ);
|
||||
AUDIO_FEEDBACK_TO_BUF_FS(s_speaker_feedback_buffer, feedback_value); /* uac1 can only use 10.14 */
|
||||
usbd_ep_start_write(busid, AUDIO_OUT_FEEDBACK_EP, s_speaker_feedback_buffer, FEEDBACK_ENDP_PACKET_SIZE);
|
||||
printf("OPEN1\r\n");
|
||||
} else {
|
||||
tx_flag = 1;
|
||||
|
@ -215,6 +325,16 @@ void usbd_audio_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
|||
ep_tx_busy_flag = false;
|
||||
}
|
||||
|
||||
#if USING_FEEDBACK == 1
|
||||
void usbd_audio_iso_out_feedback_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
USB_LOG_RAW("actual feedback len:%d\r\n", nbytes);
|
||||
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(AUDIO_SPEAKER_FREQ);
|
||||
AUDIO_FEEDBACK_TO_BUF_FS(s_speaker_feedback_buffer, feedback_value);
|
||||
usbd_ep_start_write(busid, AUDIO_OUT_FEEDBACK_EP, s_speaker_feedback_buffer, FEEDBACK_ENDP_PACKET_SIZE);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct usbd_endpoint audio_in_ep = {
|
||||
.ep_cb = usbd_audio_in_callback,
|
||||
.ep_addr = AUDIO_IN_EP
|
||||
|
@ -225,6 +345,13 @@ static struct usbd_endpoint audio_out_ep = {
|
|||
.ep_addr = AUDIO_OUT_EP
|
||||
};
|
||||
|
||||
#if USING_FEEDBACK == 1
|
||||
static struct usbd_endpoint audio_out_feedback_ep = {
|
||||
.ep_cb = usbd_audio_iso_out_feedback_callback,
|
||||
.ep_addr = AUDIO_OUT_FEEDBACK_EP
|
||||
};
|
||||
#endif
|
||||
|
||||
struct usbd_interface intf0;
|
||||
struct usbd_interface intf1;
|
||||
struct usbd_interface intf2;
|
||||
|
@ -240,13 +367,19 @@ struct audio_entity_info audio_entity_table[] = {
|
|||
|
||||
void audio_v1_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &audio_v1_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, audio_v1_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0100, audio_entity_table, 2));
|
||||
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf1, 0x0100, audio_entity_table, 2));
|
||||
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf2, 0x0100, audio_entity_table, 2));
|
||||
usbd_add_endpoint(busid, &audio_in_ep);
|
||||
usbd_add_endpoint(busid, &audio_out_ep);
|
||||
|
||||
#if USING_FEEDBACK == 1
|
||||
usbd_add_endpoint(busid, &audio_out_feedback_ep);
|
||||
#endif
|
||||
usbd_initialize(busid, reg_base, usbd_event_handler);
|
||||
}
|
||||
|
||||
|
|
|
@ -72,6 +72,74 @@
|
|||
AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \
|
||||
AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC)
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, AUDIO_CATEGORY_MICROPHONE, 0x00, 0x00),
|
||||
AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x01, 0x03, 0x03),
|
||||
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, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL)
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB UAC DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor audio_v2_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
const uint8_t audio_v2_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
|
@ -154,6 +222,7 @@ const uint8_t audio_v2_descriptor[] = {
|
|||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
static const uint8_t mic_default_sampling_freq_table[] = {
|
||||
AUDIO_SAMPLE_FREQ_NUM(1),
|
||||
|
@ -162,7 +231,10 @@ static const uint8_t mic_default_sampling_freq_table[] = {
|
|||
AUDIO_SAMPLE_FREQ_4B(0x00)
|
||||
};
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[AUDIO_IN_PACKET];
|
||||
|
||||
volatile bool tx_flag = 0;
|
||||
volatile bool ep_tx_busy_flag = false;
|
||||
|
||||
static void usbd_event_handler(uint8_t busid, uint8_t event)
|
||||
{
|
||||
|
@ -210,6 +282,7 @@ void usbd_audio_get_sampling_freq_table(uint8_t busid, uint8_t ep, uint8_t **sam
|
|||
|
||||
void usbd_audio_iso_in_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
ep_tx_busy_flag = false;
|
||||
}
|
||||
|
||||
static struct usbd_endpoint audio_in_ep = {
|
||||
|
@ -231,7 +304,11 @@ struct audio_entity_info audio_entity_table[] = {
|
|||
|
||||
void audio_v2_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &audio_v2_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, audio_v2_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0200, audio_entity_table, 2));
|
||||
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf1, 0x0200, audio_entity_table, 2));
|
||||
usbd_add_endpoint(busid, &audio_in_ep);
|
||||
|
@ -242,5 +319,13 @@ void audio_v2_init(uint8_t busid, uintptr_t reg_base)
|
|||
void audio_v2_test(uint8_t busid)
|
||||
{
|
||||
if (tx_flag) {
|
||||
memset(write_buffer, 'a', AUDIO_IN_PACKET);
|
||||
ep_tx_busy_flag = true;
|
||||
usbd_ep_start_write(busid, AUDIO_IN_EP, write_buffer, AUDIO_IN_PACKET);
|
||||
while (ep_tx_busy_flag) {
|
||||
if (tx_flag == false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,6 +114,79 @@
|
|||
AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(IN_CHANNEL_NUM) + \
|
||||
AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC)
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x03, AUDIO_AC_SIZ, AUDIO_CATEGORY_UNDEF, 0x00, 0x00),
|
||||
AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x01, 0x03, 0x03),
|
||||
AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, 0x01, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, 0x0000),
|
||||
AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(0x03, 0x02, OUTPUT_CTRL),
|
||||
AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, 0x03, 0x01, 0x0000),
|
||||
AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(0x05, 0x03, 0x03),
|
||||
AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_INTERM_MIC, 0x05, IN_CHANNEL_NUM, INPUT_CH_ENABLE, 0x0000),
|
||||
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, 0x09, 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, 0x05, (AUDIO_IN_PACKET + 4), EP_INTERVAL)
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB UAC DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor audio_v2_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
uint8_t audio_v2_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x03, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
|
@ -201,6 +274,7 @@ uint8_t audio_v2_descriptor[] = {
|
|||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
static const uint8_t speaker_default_sampling_freq_table[] = {
|
||||
AUDIO_SAMPLE_FREQ_NUM(5),
|
||||
|
@ -233,6 +307,7 @@ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[AUDIO_IN_PACKET];
|
|||
|
||||
volatile bool tx_flag = 0;
|
||||
volatile bool rx_flag = 0;
|
||||
volatile bool ep_tx_busy_flag = false;
|
||||
|
||||
static void usbd_event_handler(uint8_t busid, uint8_t event)
|
||||
{
|
||||
|
@ -293,20 +368,6 @@ void usbd_audio_get_sampling_freq_table(uint8_t busid, uint8_t ep, uint8_t **sam
|
|||
}
|
||||
}
|
||||
|
||||
void usbd_audio_set_sampling_freq(uint8_t busid, uint8_t ep, uint32_t sampling_freq)
|
||||
{
|
||||
uint16_t packet_size = 0;
|
||||
if (ep == AUDIO_OUT_EP) {
|
||||
packet_size = ((sampling_freq * 2 * OUT_CHANNEL_NUM) / 1000);
|
||||
audio_v2_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - AUDIO_V2_AS_DESCRIPTOR_INIT_LEN - 11] = packet_size;
|
||||
audio_v2_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - AUDIO_V2_AS_DESCRIPTOR_INIT_LEN - 10] = packet_size >> 8;
|
||||
} else if (ep == AUDIO_IN_EP) {
|
||||
packet_size = ((sampling_freq * 2 * IN_CHANNEL_NUM) / 1000);
|
||||
audio_v2_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - 11] = packet_size;
|
||||
audio_v2_descriptor[18 + USB_AUDIO_CONFIG_DESC_SIZ - 10] = packet_size >> 8;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_audio_iso_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
USB_LOG_RAW("actual out len:%d\r\n", nbytes);
|
||||
|
@ -348,7 +409,11 @@ struct audio_entity_info audio_entity_table[] = {
|
|||
|
||||
void audio_v2_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &audio_v2_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, audio_v2_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0200, audio_entity_table, 4));
|
||||
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf1, 0x0200, audio_entity_table, 4));
|
||||
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf2, 0x0200, audio_entity_table, 4));
|
||||
|
@ -361,6 +426,14 @@ void audio_v2_init(uint8_t busid, uintptr_t reg_base)
|
|||
void audio_v2_test(uint8_t busid)
|
||||
{
|
||||
if (tx_flag) {
|
||||
memset(write_buffer, 'a', AUDIO_IN_PACKET);
|
||||
ep_tx_busy_flag = true;
|
||||
usbd_ep_start_write(busid, AUDIO_IN_EP, write_buffer, AUDIO_IN_PACKET);
|
||||
while (ep_tx_busy_flag) {
|
||||
if (tx_flag == false) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rx_flag) {
|
||||
}
|
||||
|
|
|
@ -6,18 +6,23 @@
|
|||
#include "usbd_core.h"
|
||||
#include "usbd_audio.h"
|
||||
|
||||
#define USING_FEEDBACK 0
|
||||
|
||||
#define USBD_VID 0xffff
|
||||
#define USBD_PID 0xffff
|
||||
#define USBD_MAX_POWER 100
|
||||
#define USBD_LANGID_STRING 1033
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define EP_INTERVAL 0x04
|
||||
#define EP_INTERVAL 0x04
|
||||
#define FEEDBACK_ENDP_PACKET_SIZE 0x04
|
||||
#else
|
||||
#define EP_INTERVAL 0x01
|
||||
#define EP_INTERVAL 0x01
|
||||
#define FEEDBACK_ENDP_PACKET_SIZE 0x03
|
||||
#endif
|
||||
|
||||
#define AUDIO_OUT_EP 0x01
|
||||
#define AUDIO_OUT_EP 0x01
|
||||
#define AUDIO_OUT_FEEDBACK_EP 0x82
|
||||
|
||||
#define AUDIO_OUT_CLOCK_ID 0x01
|
||||
#define AUDIO_OUT_FU_ID 0x03
|
||||
|
@ -58,6 +63,7 @@
|
|||
|
||||
#define AUDIO_OUT_PACKET ((uint32_t)((AUDIO_FREQ * HALF_WORD_BYTES * OUT_CHANNEL_NUM) / 1000))
|
||||
|
||||
#if USING_FEEDBACK == 0
|
||||
#define USB_AUDIO_CONFIG_DESC_SIZ (9 + \
|
||||
AUDIO_V2_AC_DESCRIPTOR_INIT_LEN + \
|
||||
AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \
|
||||
|
@ -65,6 +71,15 @@
|
|||
AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \
|
||||
AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
|
||||
AUDIO_V2_AS_DESCRIPTOR_INIT_LEN)
|
||||
#else
|
||||
#define USB_AUDIO_CONFIG_DESC_SIZ (9 + \
|
||||
AUDIO_V2_AC_DESCRIPTOR_INIT_LEN + \
|
||||
AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \
|
||||
AUDIO_V2_SIZEOF_AC_INPUT_TERMINAL_DESC + \
|
||||
AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \
|
||||
AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC + \
|
||||
AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT_LEN)
|
||||
#endif
|
||||
|
||||
#define AUDIO_AC_SIZ (AUDIO_V2_SIZEOF_AC_HEADER_DESC + \
|
||||
AUDIO_V2_SIZEOF_AC_CLOCK_SOURCE_DESC + \
|
||||
|
@ -72,6 +87,78 @@
|
|||
AUDIO_V2_SIZEOF_AC_FEATURE_UNIT_DESC(OUT_CHANNEL_NUM) + \
|
||||
AUDIO_V2_SIZEOF_AC_OUTPUT_TERMINAL_DESC)
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
AUDIO_V2_AC_DESCRIPTOR_INIT(0x00, 0x02, AUDIO_AC_SIZ, AUDIO_CATEGORY_SPEAKER, 0x00, 0x00),
|
||||
AUDIO_V2_AC_CLOCK_SOURCE_DESCRIPTOR_INIT(AUDIO_OUT_CLOCK_ID, 0x03, 0x03),
|
||||
AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, 0x01, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, 0x0000),
|
||||
AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_OUT_FU_ID, 0x02, OUTPUT_CTRL),
|
||||
AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, 0x03, 0x01, 0x0000),
|
||||
#if USING_FEEDBACK == 0
|
||||
AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL),
|
||||
#else
|
||||
AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, AUDIO_OUT_PACKET, EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP),
|
||||
#endif
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB UAC DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor audio_v2_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
const uint8_t audio_v2_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_AUDIO_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
|
@ -80,7 +167,11 @@ const uint8_t audio_v2_descriptor[] = {
|
|||
AUDIO_V2_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x02, AUDIO_TERMINAL_STREAMING, 0x01, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, 0x0000),
|
||||
AUDIO_V2_AC_FEATURE_UNIT_DESCRIPTOR_INIT(AUDIO_OUT_FU_ID, 0x02, OUTPUT_CTRL),
|
||||
AUDIO_V2_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x04, AUDIO_OUTTERM_SPEAKER, 0x03, 0x01, 0x0000),
|
||||
#if USING_FEEDBACK == 0
|
||||
AUDIO_V2_AS_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET, EP_INTERVAL),
|
||||
#else
|
||||
AUDIO_V2_AS_FEEDBACK_DESCRIPTOR_INIT(0x01, 0x02, OUT_CHANNEL_NUM, OUTPUT_CH_ENABLE, HALF_WORD_BYTES, SAMPLE_BITS, AUDIO_OUT_EP, AUDIO_OUT_PACKET, EP_INTERVAL, AUDIO_OUT_FEEDBACK_EP),
|
||||
#endif
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
///////////////////////////////////////
|
||||
|
@ -136,7 +227,11 @@ const uint8_t audio_v2_descriptor[] = {
|
|||
'1', 0x00, /* wcChar6 */
|
||||
'0', 0x00, /* wcChar7 */
|
||||
'0', 0x00, /* wcChar8 */
|
||||
'3', 0x00, /* wcChar9 */
|
||||
#if USING_FEEDBACK == 0
|
||||
'3', 0x00, /* wcChar9 */
|
||||
#else
|
||||
'4', 0x00, /* wcChar9 */
|
||||
#endif
|
||||
#ifdef CONFIG_USB_HS
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
|
@ -154,6 +249,7 @@ const uint8_t audio_v2_descriptor[] = {
|
|||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
static const uint8_t default_sampling_freq_table[] = {
|
||||
AUDIO_SAMPLE_FREQ_NUM(5),
|
||||
|
@ -175,6 +271,7 @@ static const uint8_t default_sampling_freq_table[] = {
|
|||
};
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[AUDIO_OUT_PACKET];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t s_speaker_feedback_buffer[4];
|
||||
|
||||
volatile bool rx_flag = 0;
|
||||
|
||||
|
@ -208,6 +305,14 @@ void usbd_audio_open(uint8_t busid, uint8_t intf)
|
|||
rx_flag = 1;
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(busid, AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET);
|
||||
#ifdef CONFIG_USB_HS
|
||||
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_HS(AUDIO_FREQ);
|
||||
AUDIO_FEEDBACK_TO_BUF_HS(s_speaker_feedback_buffer, feedback_value);
|
||||
#else
|
||||
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(AUDIO_FREQ);
|
||||
AUDIO_FEEDBACK_TO_BUF_FS(s_speaker_feedback_buffer, feedback_value);
|
||||
#endif
|
||||
usbd_ep_start_write(busid, AUDIO_OUT_FEEDBACK_EP, s_speaker_feedback_buffer, FEEDBACK_ENDP_PACKET_SIZE);
|
||||
USB_LOG_RAW("OPEN\r\n");
|
||||
}
|
||||
|
||||
|
@ -230,11 +335,33 @@ void usbd_audio_iso_out_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
|||
usbd_ep_start_read(busid, AUDIO_OUT_EP, read_buffer, AUDIO_OUT_PACKET);
|
||||
}
|
||||
|
||||
#if USING_FEEDBACK == 1
|
||||
void usbd_audio_iso_out_feedback_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
USB_LOG_RAW("actual feedback len:%d\r\n", nbytes);
|
||||
#ifdef CONFIG_USB_HS
|
||||
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_HS(AUDIO_FREQ);
|
||||
AUDIO_FEEDBACK_TO_BUF_HS(s_speaker_feedback_buffer, feedback_value);
|
||||
#else
|
||||
uint32_t feedback_value = AUDIO_FREQ_TO_FEEDBACK_FS(AUDIO_FREQ);
|
||||
AUDIO_FEEDBACK_TO_BUF_FS(s_speaker_feedback_buffer, feedback_value);
|
||||
#endif
|
||||
usbd_ep_start_write(busid, AUDIO_OUT_FEEDBACK_EP, s_speaker_feedback_buffer, FEEDBACK_ENDP_PACKET_SIZE);
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct usbd_endpoint audio_out_ep = {
|
||||
.ep_cb = usbd_audio_iso_out_callback,
|
||||
.ep_addr = AUDIO_OUT_EP
|
||||
};
|
||||
|
||||
#if USING_FEEDBACK == 1
|
||||
static struct usbd_endpoint audio_out_feedback_ep = {
|
||||
.ep_cb = usbd_audio_iso_out_feedback_callback,
|
||||
.ep_addr = AUDIO_OUT_FEEDBACK_EP
|
||||
};
|
||||
#endif
|
||||
|
||||
struct usbd_interface intf0;
|
||||
struct usbd_interface intf1;
|
||||
|
||||
|
@ -249,11 +376,17 @@ struct audio_entity_info audio_entity_table[] = {
|
|||
|
||||
void audio_v2_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &audio_v2_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, audio_v2_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0200, audio_entity_table, 2));
|
||||
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf1, 0x0200, audio_entity_table, 2));
|
||||
usbd_add_endpoint(busid, &audio_out_ep);
|
||||
|
||||
#if USING_FEEDBACK == 1
|
||||
usbd_add_endpoint(busid, &audio_out_feedback_ep);
|
||||
#endif
|
||||
usbd_initialize(busid, reg_base, usbd_event_handler);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,69 @@
|
|||
#define MSC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
MSC_DESCRIPTOR_INIT(0x00, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x02)
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB UF2 DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor msc_bootuf2_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
const uint8_t msc_bootuf2_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
|
@ -100,6 +163,7 @@ const uint8_t msc_bootuf2_descriptor[] = {
|
|||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
static void usbd_event_handler(uint8_t busid, uint8_t event)
|
||||
{
|
||||
|
@ -151,7 +215,11 @@ static struct usbd_interface intf0;
|
|||
void msc_bootuf2_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
boot2uf2_flash_init();
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &msc_bootuf2_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, msc_bootuf2_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_msc_init_intf(busid, &intf0, MSC_OUT_EP, MSC_IN_EP));
|
||||
|
||||
usbd_initialize(busid, reg_base, usbd_event_handler);
|
||||
|
|
|
@ -43,6 +43,101 @@
|
|||
#define MSC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x04, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
|
||||
MSC_DESCRIPTOR_INIT(0x02, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x02),
|
||||
/************** Descriptor of Joystick Mouse interface ****************/
|
||||
/* 09 */
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
|
||||
0x03, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x01, /* bNumEndpoints */
|
||||
0x03, /* bInterfaceClass: HID */
|
||||
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
|
||||
0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
|
||||
0, /* iInterface: Index of string descriptor */
|
||||
/******************** Descriptor of Joystick Mouse HID ********************/
|
||||
/* 18 */
|
||||
0x09, /* bLength: HID Descriptor size */
|
||||
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
|
||||
0x11, /* bcdHID: HID Class Spec release number */
|
||||
0x01,
|
||||
0x00, /* bCountryCode: Hardware target country */
|
||||
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
|
||||
0x22, /* bDescriptorType */
|
||||
HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
|
||||
0x00,
|
||||
/******************** Descriptor of Mouse endpoint ********************/
|
||||
/* 27 */
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
|
||||
HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
|
||||
0x03, /* bmAttributes: Interrupt endpoint */
|
||||
HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */
|
||||
0x00,
|
||||
HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB CDC MSC HID DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor cdc_acm_hid_msc_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
const uint8_t cdc_acm_hid_msc_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x04, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
|
@ -152,6 +247,7 @@ const uint8_t cdc_acm_hid_msc_descriptor[] = {
|
|||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
/*!< hid mouse report descriptor */
|
||||
static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = {
|
||||
|
@ -303,8 +399,11 @@ struct usbd_interface intf3;
|
|||
|
||||
void cdc_acm_hid_msc_descriptor_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &cdc_acm_hid_msc_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, cdc_acm_hid_msc_descriptor);
|
||||
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf0));
|
||||
usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1));
|
||||
usbd_add_endpoint(busid, &cdc_out_ep);
|
||||
|
|
|
@ -54,9 +54,9 @@ static const uint8_t device_quality_descriptor[] = {
|
|||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x02,
|
||||
0x02,
|
||||
0x01,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
|
@ -169,9 +169,9 @@ static const uint8_t cdc_msc_descriptor[] = {
|
|||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x02,
|
||||
0x02,
|
||||
0x01,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
|
|
|
@ -37,8 +37,74 @@
|
|||
#define CDC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x08, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x02, CDC_INT_EP2, CDC_OUT_EP2, CDC_IN_EP2, CDC_MAX_MPS, 0x02),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x04, CDC_INT_EP3, CDC_OUT_EP3, CDC_IN_EP3, CDC_MAX_MPS, 0x02),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x06, CDC_INT_EP4, CDC_OUT_EP4, CDC_IN_EP4, CDC_MAX_MPS, 0x02)
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB CDC MULTI DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor cdc_multi_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
/*!< global descriptor */
|
||||
static const uint8_t cdc_descriptor[] = {
|
||||
static const uint8_t cdc_multi_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x08, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
|
||||
|
@ -109,15 +175,16 @@ static const uint8_t cdc_descriptor[] = {
|
|||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x02,
|
||||
0x02,
|
||||
0x01,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[4][2048];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[4][2048];
|
||||
|
@ -225,8 +292,11 @@ struct usbd_interface intf7;
|
|||
|
||||
void cdc_acm_multi_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
usbd_desc_register(busid, cdc_descriptor);
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &cdc_multi_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, cdc_multi_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf0));
|
||||
usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1));
|
||||
usbd_add_endpoint(busid, &cdc_out_ep1);
|
||||
|
|
|
@ -25,6 +25,69 @@
|
|||
#define CDC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02)
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB CDC DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor cdc_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
/*!< global descriptor */
|
||||
static const uint8_t cdc_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
|
@ -94,15 +157,16 @@ static const uint8_t cdc_descriptor[] = {
|
|||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x02,
|
||||
0x02,
|
||||
0x01,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048]; /* 2048 is only for test speed , please use CDC_MAX_MPS for common*/
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048];
|
||||
|
@ -181,7 +245,11 @@ void cdc_acm_init(uint8_t busid, uintptr_t reg_base)
|
|||
memcpy(&write_buffer[0], data, 10);
|
||||
memset(&write_buffer[10], 'a', 2038);
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &cdc_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, cdc_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf0));
|
||||
usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1));
|
||||
usbd_add_endpoint(busid, &cdc_out_ep);
|
||||
|
|
|
@ -34,6 +34,69 @@
|
|||
/* str idx = 4 is for mac address: aa:bb:cc:dd:ee:ff*/
|
||||
#define CDC_ECM_MAC_STRING_INDEX 4
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_ECM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, CDC_ECM_ETH_STATISTICS_BITMAP, CONFIG_CDC_ECM_ETH_MAX_SEGSZE, 0, 0, CDC_ECM_MAC_STRING_INDEX)
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB CDC ECM DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor cdc_ecm_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
/*!< global descriptor */
|
||||
static const uint8_t cdc_ecm_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
|
@ -124,15 +187,16 @@ static const uint8_t cdc_ecm_descriptor[] = {
|
|||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x02,
|
||||
0x02,
|
||||
0x01,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
const uint8_t mac[6] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
|
||||
|
||||
|
@ -277,7 +341,11 @@ void cdc_ecm_init(uint8_t busid, uintptr_t reg_base)
|
|||
{
|
||||
cdc_ecm_lwip_init();
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &cdc_ecm_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, cdc_ecm_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_cdc_ecm_init_intf(&intf0, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP));
|
||||
usbd_add_interface(busid, usbd_cdc_ecm_init_intf(&intf1, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP));
|
||||
usbd_initialize(busid, reg_base, usbd_event_handler);
|
||||
|
|
|
@ -29,8 +29,71 @@
|
|||
#define CDC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_RNDIS_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02)
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB RNDIS DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor cdc_rndis_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
/*!< global descriptor */
|
||||
static const uint8_t cdc_descriptor[] = {
|
||||
static const uint8_t cdc_rndis_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
CDC_RNDIS_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_MAX_MPS, 0x02),
|
||||
|
@ -100,15 +163,16 @@ static const uint8_t cdc_descriptor[] = {
|
|||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x02,
|
||||
0x02,
|
||||
0x01,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
const uint8_t mac[6] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
|
||||
/*Static IP ADDRESS: IP_ADDR0.IP_ADDR1.IP_ADDR2.IP_ADDR3 */
|
||||
|
@ -315,7 +379,11 @@ void cdc_rndis_init(uint8_t busid, uintptr_t reg_base)
|
|||
#else
|
||||
rndis_lwip_init();
|
||||
#endif
|
||||
usbd_desc_register(busid, cdc_descriptor);
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &cdc_rndis_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, cdc_rndis_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_rndis_init_intf(&intf0, CDC_OUT_EP, CDC_IN_EP, CDC_INT_EP, mac));
|
||||
usbd_add_interface(busid, usbd_rndis_init_intf(&intf1, CDC_OUT_EP, CDC_IN_EP, CDC_INT_EP, mac));
|
||||
usbd_initialize(busid, reg_base, usbd_event_handler);
|
||||
|
|
|
@ -15,6 +15,69 @@
|
|||
|
||||
#define USB_CONFIG_SIZE (9 + 9 + 9)
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
DFU_DESCRIPTOR_INIT()
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB DFU DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor dfu_flash_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
const uint8_t dfu_flash_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
|
@ -141,6 +204,7 @@ const uint8_t dfu_flash_descriptor[] = {
|
|||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
static void usbd_event_handler(uint8_t busid, uint8_t event)
|
||||
{
|
||||
|
@ -171,7 +235,11 @@ struct usbd_interface intf0;
|
|||
|
||||
void dfu_flash_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &dfu_flash_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, dfu_flash_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_dfu_init_intf(&intf0));
|
||||
usbd_initialize(busid, reg_base, usbd_event_handler);
|
||||
}
|
||||
|
|
|
@ -39,6 +39,103 @@
|
|||
/*!< custom hid report descriptor size */
|
||||
#define HID_CUSTOM_REPORT_DESC_SIZE 38
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
/************** Descriptor of Custom interface *****************/
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
|
||||
0x00, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x02, /* bNumEndpoints */
|
||||
0x03, /* bInterfaceClass: HID */
|
||||
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
|
||||
0x00, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
|
||||
0, /* iInterface: Index of string descriptor */
|
||||
/******************** Descriptor of Custom HID ********************/
|
||||
0x09, /* bLength: HID Descriptor size */
|
||||
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
|
||||
0x11, /* bcdHID: HID Class Spec release number */
|
||||
0x01,
|
||||
0x00, /* bCountryCode: Hardware target country */
|
||||
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
|
||||
0x22, /* bDescriptorType */
|
||||
HID_CUSTOM_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
|
||||
0x00,
|
||||
/******************** Descriptor of Custom in endpoint ********************/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
|
||||
HIDRAW_IN_EP, /* bEndpointAddress: Endpoint Address (IN) */
|
||||
0x03, /* bmAttributes: Interrupt endpoint */
|
||||
WBVAL(HIDRAW_IN_EP_SIZE), /* wMaxPacketSize: 4 Byte max */
|
||||
HIDRAW_IN_INTERVAL, /* bInterval: Polling Interval */
|
||||
/******************** Descriptor of Custom out endpoint ********************/
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
|
||||
HIDRAW_OUT_EP, /* bEndpointAddress: Endpoint Address (IN) */
|
||||
0x03, /* bmAttributes: Interrupt endpoint */
|
||||
WBVAL(HIDRAW_OUT_EP_SIZE), /* wMaxPacketSize: 4 Byte max */
|
||||
HIDRAW_OUT_EP_INTERVAL, /* bInterval: Polling Interval */
|
||||
/* 73 */
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB HID DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor hid_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
/*!< global descriptor */
|
||||
static const uint8_t hid_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01),
|
||||
|
@ -151,6 +248,7 @@ static const uint8_t hid_descriptor[] = {
|
|||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
/*!< custom hid report descriptor */
|
||||
static const uint8_t hid_custom_report_desc[HID_CUSTOM_REPORT_DESC_SIZE] = {
|
||||
|
@ -274,7 +372,11 @@ struct usbd_interface intf0;
|
|||
|
||||
void hid_custom_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &hid_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, hid_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_custom_report_desc, HID_CUSTOM_REPORT_DESC_SIZE));
|
||||
usbd_add_endpoint(busid, &custom_in_ep);
|
||||
usbd_add_endpoint(busid, &custom_out_ep);
|
||||
|
|
|
@ -18,6 +18,101 @@
|
|||
#define USB_HID_CONFIG_DESC_SIZ 34
|
||||
#define HID_KEYBOARD_REPORT_DESC_SIZE 63
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
|
||||
/************** Descriptor of Joystick Mouse interface ****************/
|
||||
/* 09 */
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
|
||||
0x00, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x01, /* bNumEndpoints */
|
||||
0x03, /* bInterfaceClass: HID */
|
||||
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
|
||||
0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
|
||||
0, /* iInterface: Index of string descriptor */
|
||||
/******************** Descriptor of Joystick Mouse HID ********************/
|
||||
/* 18 */
|
||||
0x09, /* bLength: HID Descriptor size */
|
||||
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
|
||||
0x11, /* bcdHID: HID Class Spec release number */
|
||||
0x01,
|
||||
0x00, /* bCountryCode: Hardware target country */
|
||||
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
|
||||
0x22, /* bDescriptorType */
|
||||
HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
|
||||
0x00,
|
||||
/******************** Descriptor of Mouse endpoint ********************/
|
||||
/* 27 */
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
|
||||
HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
|
||||
0x03, /* bmAttributes: Interrupt endpoint */
|
||||
HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */
|
||||
0x00,
|
||||
HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
|
||||
/* 34 */
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB HID DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor hid_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
static const uint8_t hid_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
|
@ -127,6 +222,7 @@ static const uint8_t hid_descriptor[] = {
|
|||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
/* USB HID device Configuration Descriptor */
|
||||
static uint8_t hid_desc[9] __ALIGN_END = {
|
||||
|
@ -223,7 +319,11 @@ struct usbd_interface intf0;
|
|||
|
||||
void hid_keyboard_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &hid_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, hid_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_keyboard_report_desc, HID_KEYBOARD_REPORT_DESC_SIZE));
|
||||
usbd_add_endpoint(busid, &hid_in_ep);
|
||||
|
||||
|
|
|
@ -21,6 +21,101 @@
|
|||
/*!< report descriptor size */
|
||||
#define HID_MOUSE_REPORT_DESC_SIZE 74
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
|
||||
/************** Descriptor of Joystick Mouse interface ****************/
|
||||
/* 09 */
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
|
||||
0x00, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x01, /* bNumEndpoints */
|
||||
0x03, /* bInterfaceClass: HID */
|
||||
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
|
||||
0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
|
||||
0, /* iInterface: Index of string descriptor */
|
||||
/******************** Descriptor of Joystick Mouse HID ********************/
|
||||
/* 18 */
|
||||
0x09, /* bLength: HID Descriptor size */
|
||||
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
|
||||
0x11, /* bcdHID: HID Class Spec release number */
|
||||
0x01,
|
||||
0x00, /* bCountryCode: Hardware target country */
|
||||
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
|
||||
0x22, /* bDescriptorType */
|
||||
HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
|
||||
0x00,
|
||||
/******************** Descriptor of Mouse endpoint ********************/
|
||||
/* 27 */
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
|
||||
HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
|
||||
0x03, /* bmAttributes: Interrupt endpoint */
|
||||
HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */
|
||||
0x00,
|
||||
HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
|
||||
/* 34 */
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB HID DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor hid_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
/*!< global descriptor */
|
||||
const uint8_t hid_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01),
|
||||
|
@ -131,6 +226,7 @@ const uint8_t hid_descriptor[] = {
|
|||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
/*!< hid mouse report descriptor */
|
||||
static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = {
|
||||
|
@ -241,7 +337,11 @@ struct usbd_interface intf0;
|
|||
|
||||
void hid_mouse_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &hid_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, hid_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_mouse_report_desc, HID_MOUSE_REPORT_DESC_SIZE));
|
||||
usbd_add_endpoint(busid, &hid_in_ep);
|
||||
|
||||
|
|
|
@ -21,6 +21,101 @@
|
|||
/*!< report descriptor size */
|
||||
#define HID_MOUSE_REPORT_DESC_SIZE 74
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_REMOTE_WAKEUP | USB_CONFIG_SELF_POWERED, USBD_MAX_POWER),
|
||||
|
||||
/************** Descriptor of Joystick Mouse interface ****************/
|
||||
/* 09 */
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
|
||||
0x00, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x01, /* bNumEndpoints */
|
||||
0x03, /* bInterfaceClass: HID */
|
||||
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
|
||||
0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
|
||||
0, /* iInterface: Index of string descriptor */
|
||||
/******************** Descriptor of Joystick Mouse HID ********************/
|
||||
/* 18 */
|
||||
0x09, /* bLength: HID Descriptor size */
|
||||
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
|
||||
0x11, /* bcdHID: HID Class Spec release number */
|
||||
0x01,
|
||||
0x00, /* bCountryCode: Hardware target country */
|
||||
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
|
||||
0x22, /* bDescriptorType */
|
||||
HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
|
||||
0x00,
|
||||
/******************** Descriptor of Mouse endpoint ********************/
|
||||
/* 27 */
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
|
||||
HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
|
||||
0x03, /* bmAttributes: Interrupt endpoint */
|
||||
HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */
|
||||
0x00,
|
||||
HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
|
||||
/* 34 */
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB HID DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor hid_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
/*!< global descriptor */
|
||||
const uint8_t hid_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01),
|
||||
|
@ -131,6 +226,7 @@ const uint8_t hid_descriptor[] = {
|
|||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
/*!< hid mouse report descriptor */
|
||||
static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = {
|
||||
|
@ -241,7 +337,11 @@ static struct usbd_interface intf0;
|
|||
|
||||
void hid_mouse_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &hid_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, hid_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_mouse_report_desc, HID_MOUSE_REPORT_DESC_SIZE));
|
||||
usbd_add_endpoint(busid, &hid_in_ep);
|
||||
|
||||
|
|
|
@ -22,6 +22,118 @@
|
|||
#define MIDI_EP_MPS 64
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0100, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
// Standard AC Interface Descriptor
|
||||
0x09,
|
||||
0x04,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x01,
|
||||
0x01,
|
||||
0x00,
|
||||
0x00,
|
||||
// Class-specific AC Interface Descriptor
|
||||
0x09,
|
||||
0x24,
|
||||
0x01,
|
||||
0x00,
|
||||
0x01,
|
||||
0x09,
|
||||
0x00,
|
||||
0x01,
|
||||
0x01,
|
||||
// MIDIStreaming Interface Descriptors
|
||||
0x09,
|
||||
0x04,
|
||||
0x01,
|
||||
0x00,
|
||||
0x02,
|
||||
0x01,
|
||||
0x03,
|
||||
0x00,
|
||||
0x00,
|
||||
// Class-Specific MS Interface Header Descriptor
|
||||
0x07,
|
||||
0x24,
|
||||
0x01,
|
||||
0x00,
|
||||
0x01,
|
||||
WBVAL(65),
|
||||
|
||||
// MIDI_IN_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EMBEDDED, 0x01),
|
||||
// MIDI_IN_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EXTERNAL, 0x02),
|
||||
// MIDI_OUT_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EMBEDDED, 0x03, 0x02),
|
||||
// MIDI_OUT_JACK_DESCRIPTOR_INIT(MIDI_JACK_TYPE_EXTERNAL, 0x04, 0x01),
|
||||
MIDI_JACK_DESCRIPTOR_INIT(0x01),
|
||||
// OUT endpoint descriptor
|
||||
0x09, 0x05, MIDI_OUT_EP, 0x02, WBVAL(MIDI_EP_MPS), 0x00, 0x00, 0x00,
|
||||
0x05, 0x25, 0x01, 0x01, 0x01,
|
||||
|
||||
// IN endpoint descriptor
|
||||
0x09, 0x05, MIDI_IN_EP, 0x02, WBVAL(MIDI_EP_MPS), 0x00, 0x00, 0x00,
|
||||
0x05, 0x25, 0x01, 0x01, 0x03
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB MIDI DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor midi_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
const uint8_t midi_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
|
@ -141,15 +253,16 @@ const uint8_t midi_descriptor[] = {
|
|||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x02,
|
||||
0x02,
|
||||
0x01,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[MIDI_EP_MPS];
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[MIDI_EP_MPS];
|
||||
|
@ -204,7 +317,11 @@ struct usbd_endpoint midi_in_ep = {
|
|||
|
||||
void midi_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &midi_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, midi_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, &intf0);
|
||||
usbd_add_interface(busid, &intf1);
|
||||
usbd_add_endpoint(busid, &midi_out_ep);
|
||||
|
|
|
@ -22,6 +22,69 @@
|
|||
#define MSC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
MSC_DESCRIPTOR_INIT(0x00, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x02)
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB MSC DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor msc_ram_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
const uint8_t msc_ram_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
|
@ -99,6 +162,7 @@ const uint8_t msc_ram_descriptor[] = {
|
|||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
static void usbd_event_handler(uint8_t busid, uint8_t event)
|
||||
{
|
||||
|
@ -158,7 +222,11 @@ static struct usbd_interface intf0;
|
|||
|
||||
void msc_ram_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &msc_ram_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, msc_ram_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_msc_init_intf(busid, &intf0, MSC_OUT_EP, MSC_IN_EP));
|
||||
|
||||
usbd_initialize(busid, reg_base, usbd_event_handler);
|
||||
|
|
|
@ -1,172 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2024, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usbd_msc.h"
|
||||
|
||||
#ifdef __RT_THREAD_H__
|
||||
|
||||
#define MSC_IN_EP 0x81
|
||||
#define MSC_OUT_EP 0x02
|
||||
|
||||
#define USBD_VID 0xFFFF
|
||||
#define USBD_PID 0xFFFF
|
||||
#define USBD_MAX_POWER 100
|
||||
#define USBD_LANGID_STRING 1033
|
||||
|
||||
#define USB_CONFIG_SIZE (9 + MSC_DESCRIPTOR_LEN)
|
||||
|
||||
#ifdef CONFIG_USB_HS
|
||||
#define MSC_MAX_MPS 512
|
||||
#else
|
||||
#define MSC_MAX_MPS 64
|
||||
#endif
|
||||
|
||||
|
||||
const uint8_t msc_storage_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_1_1, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
MSC_DESCRIPTOR_INIT(0x00, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x02),
|
||||
///////////////////////////////////////
|
||||
/// string0 descriptor
|
||||
///////////////////////////////////////
|
||||
USB_LANGID_INIT(USBD_LANGID_STRING),
|
||||
///////////////////////////////////////
|
||||
/// string1 descriptor
|
||||
///////////////////////////////////////
|
||||
0x14, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'C', 0x00, /* wcChar0 */
|
||||
'h', 0x00, /* wcChar1 */
|
||||
'e', 0x00, /* wcChar2 */
|
||||
'r', 0x00, /* wcChar3 */
|
||||
'r', 0x00, /* wcChar4 */
|
||||
'y', 0x00, /* wcChar5 */
|
||||
'U', 0x00, /* wcChar6 */
|
||||
'S', 0x00, /* wcChar7 */
|
||||
'B', 0x00, /* wcChar8 */
|
||||
///////////////////////////////////////
|
||||
/// string2 descriptor
|
||||
///////////////////////////////////////
|
||||
0x26, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'C', 0x00, /* wcChar0 */
|
||||
'h', 0x00, /* wcChar1 */
|
||||
'e', 0x00, /* wcChar2 */
|
||||
'r', 0x00, /* wcChar3 */
|
||||
'r', 0x00, /* wcChar4 */
|
||||
'y', 0x00, /* wcChar5 */
|
||||
'U', 0x00, /* wcChar6 */
|
||||
'S', 0x00, /* wcChar7 */
|
||||
'B', 0x00, /* wcChar8 */
|
||||
' ', 0x00, /* wcChar9 */
|
||||
'M', 0x00, /* wcChar10 */
|
||||
'S', 0x00, /* wcChar11 */
|
||||
'C', 0x00, /* wcChar12 */
|
||||
' ', 0x00, /* wcChar13 */
|
||||
'D', 0x00, /* wcChar14 */
|
||||
'E', 0x00, /* wcChar15 */
|
||||
'M', 0x00, /* wcChar16 */
|
||||
'O', 0x00, /* wcChar17 */
|
||||
///////////////////////////////////////
|
||||
/// string3 descriptor
|
||||
///////////////////////////////////////
|
||||
0x16, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'2', 0x00, /* wcChar0 */
|
||||
'0', 0x00, /* wcChar1 */
|
||||
'2', 0x00, /* wcChar2 */
|
||||
'2', 0x00, /* wcChar3 */
|
||||
'1', 0x00, /* wcChar4 */
|
||||
'2', 0x00, /* wcChar5 */
|
||||
'3', 0x00, /* wcChar6 */
|
||||
'4', 0x00, /* wcChar7 */
|
||||
'5', 0x00, /* wcChar8 */
|
||||
'6', 0x00, /* wcChar9 */
|
||||
#ifdef CONFIG_USB_HS
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
#endif
|
||||
0x00
|
||||
};
|
||||
|
||||
struct usbd_interface intf0;
|
||||
|
||||
/* assume the block device is 512M */
|
||||
#define BLOCK_DEV_NAME "sd0"
|
||||
#define BLOCK_SIZE 512U
|
||||
#define BLOCK_COUNT 0x1024U * 0x1024U
|
||||
static rt_device_t blk_dev = RT_NULL;
|
||||
|
||||
static void usbd_event_handler(uint8_t busid, uint8_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case USBD_EVENT_RESET:
|
||||
break;
|
||||
case USBD_EVENT_CONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_DISCONNECTED:
|
||||
break;
|
||||
case USBD_EVENT_RESUME:
|
||||
break;
|
||||
case USBD_EVENT_SUSPEND:
|
||||
break;
|
||||
case USBD_EVENT_CONFIGURED:
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
case USBD_EVENT_CLR_REMOTE_WAKEUP:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void usbd_msc_get_cap(uint8_t busid, uint8_t lun, uint32_t *block_num, uint32_t *block_size)
|
||||
{
|
||||
*block_num = BLOCK_COUNT;
|
||||
*block_size = BLOCK_SIZE;
|
||||
}
|
||||
|
||||
int usbd_msc_sector_read(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length)
|
||||
{
|
||||
rt_device_read(blk_dev, sector, buffer, length / BLOCK_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_msc_sector_write(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length)
|
||||
{
|
||||
rt_device_write(blk_dev, sector, buffer, length / BLOCK_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void msc_storage_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
rt_err_t res;
|
||||
|
||||
blk_dev = rt_device_find(BLOCK_DEV_NAME);
|
||||
RT_ASSERT(blk_dev);
|
||||
|
||||
res = rt_device_open(blk_dev, RT_DEVICE_OFLAG_RDWR);
|
||||
RT_ASSERT(res == RT_EOK);
|
||||
|
||||
usbd_desc_register(busid, msc_storage_descriptor);
|
||||
usbd_add_interface(busid, usbd_msc_init_intf(busid, &intf0, MSC_OUT_EP, MSC_IN_EP));
|
||||
|
||||
usbd_initialize(busid, reg_base, usbd_event_handler);
|
||||
}
|
||||
#endif
|
|
@ -58,10 +58,10 @@ void usbh_cdc_acm_callback(void *arg, int nbytes)
|
|||
}
|
||||
}
|
||||
|
||||
static void usbh_cdc_acm_thread(void *argument)
|
||||
static void usbh_cdc_acm_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
|
||||
{
|
||||
int ret;
|
||||
struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)argument;
|
||||
struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)CONFIG_USB_OSAL_THREAD_GET_ARGV;
|
||||
|
||||
/* test with only one buffer, if you have more cdc acm class, modify by yourself */
|
||||
#if TEST_USBH_CDC_SPEED
|
||||
|
@ -133,10 +133,10 @@ void usbh_hid_callback(void *arg, int nbytes)
|
|||
}
|
||||
}
|
||||
|
||||
static void usbh_hid_thread(void *argument)
|
||||
static void usbh_hid_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
|
||||
{
|
||||
int ret;
|
||||
struct usbh_hid *hid_class = (struct usbh_hid *)argument;
|
||||
struct usbh_hid *hid_class = (struct usbh_hid *)CONFIG_USB_OSAL_THREAD_GET_ARGV;
|
||||
;
|
||||
|
||||
/* test with only one buffer, if you have more hid class, modify by yourself */
|
||||
|
@ -222,13 +222,18 @@ unmount:
|
|||
|
||||
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t partition_table[512];
|
||||
|
||||
static void usbh_msc_thread(void *argument)
|
||||
static void usbh_msc_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
|
||||
{
|
||||
int ret;
|
||||
struct usbh_msc *msc_class = (struct usbh_msc *)argument;
|
||||
struct usbh_msc *msc_class = (struct usbh_msc *)CONFIG_USB_OSAL_THREAD_GET_ARGV;
|
||||
|
||||
/* test with only one buffer, if you have more msc class, modify by yourself */
|
||||
#if 1
|
||||
#if TEST_USBH_MSC_FATFS == 0
|
||||
ret = usbh_msc_scsi_init(msc_class);
|
||||
if (ret < 0) {
|
||||
USB_LOG_RAW("scsi_init error,ret:%d\r\n", ret);
|
||||
goto delete;
|
||||
}
|
||||
/* get the partition table */
|
||||
ret = usbh_msc_scsi_read10(msc_class, 0, partition_table, 1);
|
||||
if (ret < 0) {
|
||||
|
@ -242,11 +247,10 @@ static void usbh_msc_thread(void *argument)
|
|||
USB_LOG_RAW("%02x ", partition_table[i]);
|
||||
}
|
||||
USB_LOG_RAW("\r\n");
|
||||
#endif
|
||||
|
||||
#if TEST_USBH_MSC_FATFS
|
||||
#else
|
||||
usb_msc_fatfs_test();
|
||||
#endif
|
||||
|
||||
// clang-format off
|
||||
delete:
|
||||
usb_osal_thread_delete(NULL);
|
||||
|
|
|
@ -103,6 +103,120 @@
|
|||
|
||||
#define HID_KEYBOARD_REPORT_DESC_SIZE 63
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x06, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
//VIDEO_VC_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
|
||||
VIDEO_VC_NOEP_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
|
||||
VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x00, 0x00),
|
||||
VIDEO_VS_INPUT_HEADER_DESCRIPTOR_INIT(0x01, VS_HEADER_SIZ, VIDEO_IN_EP, 0x00),
|
||||
VIDEO_VS_FORMAT_MJPEG_DESCRIPTOR_INIT(0x01, 0x01),
|
||||
VIDEO_VS_FRAME_MJPEG_DESCRIPTOR_INIT(0x01, WIDTH, HEIGHT, MIN_BIT_RATE, MAX_BIT_RATE, MAX_FRAME_SIZE, DBVAL(INTERVAL), 0x01, DBVAL(INTERVAL)),
|
||||
VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x01, 0x01),
|
||||
/* 1.2.2.2 Standard VideoStream Isochronous Video Data Endpoint Descriptor */
|
||||
USB_ENDPOINT_DESCRIPTOR_INIT(VIDEO_IN_EP, 0x05, VIDEO_PACKET_SIZE, 0x01),
|
||||
AUDIO_AC_DESCRIPTOR_INIT(0x02, 0x03, AUDIO_AC_SIZ, 0x00, 0x03, 0x04),
|
||||
AUDIO_AC_INPUT_TERMINAL_DESCRIPTOR_INIT(0x01, AUDIO_INTERM_MIC, 0x02, 0x0003),
|
||||
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, 0x00),
|
||||
AUDIO_AC_OUTPUT_TERMINAL_DESCRIPTOR_INIT(0x06, AUDIO_OUTTERM_SPEAKER, 0x05),
|
||||
AUDIO_AS_DESCRIPTOR_INIT(0x03, 0x04, 0x02, AUDIO_SPEAKER_FRAME_SIZE_BYTE, AUDIO_SPEAKER_RESOLUTION_BIT, AUDIO_OUT_EP, 0x09, AUDIO_OUT_PACKET,
|
||||
EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_SPEAKER_FREQ)),
|
||||
AUDIO_AS_DESCRIPTOR_INIT(0x04, 0x03, 0x02, AUDIO_MIC_FRAME_SIZE_BYTE, AUDIO_MIC_RESOLUTION_BIT, AUDIO_IN_EP, 0x05, AUDIO_IN_PACKET,
|
||||
EP_INTERVAL, AUDIO_SAMPLE_FREQ_3B(AUDIO_MIC_FREQ)),
|
||||
/************** Descriptor of Joystick Mouse interface ****************/
|
||||
/* 09 */
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
|
||||
0x05, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x01, /* bNumEndpoints */
|
||||
0x03, /* bInterfaceClass: HID */
|
||||
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
|
||||
0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
|
||||
0, /* iInterface: Index of string descriptor */
|
||||
/******************** Descriptor of Joystick Mouse HID ********************/
|
||||
/* 18 */
|
||||
0x09, /* bLength: HID Descriptor size */
|
||||
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
|
||||
0x11, /* bcdHID: HID Class Spec release number */
|
||||
0x01,
|
||||
0x00, /* bCountryCode: Hardware target country */
|
||||
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
|
||||
0x22, /* bDescriptorType */
|
||||
HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
|
||||
0x00,
|
||||
/******************** Descriptor of Mouse endpoint ********************/
|
||||
/* 27 */
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
|
||||
HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
|
||||
0x03, /* bmAttributes: Interrupt endpoint */
|
||||
HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */
|
||||
0x00,
|
||||
HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
|
||||
/* 34 */
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB UVC UAC HID DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor video_audio_hid_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
const uint8_t video_audio_hid_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x06, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
|
@ -231,6 +345,7 @@ const uint8_t video_audio_hid_descriptor[] = {
|
|||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
static const uint8_t hid_keyboard_report_desc[HID_KEYBOARD_REPORT_DESC_SIZE] = {
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
|
@ -422,7 +537,11 @@ struct audio_entity_info audio_entity_table[] = {
|
|||
|
||||
void composite_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &video_audio_hid_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, video_audio_hid_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
|
||||
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf1, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
|
||||
usbd_add_endpoint(busid, &video_in_ep);
|
||||
|
|
|
@ -50,6 +50,77 @@
|
|||
#define USBD_MAX_POWER 100
|
||||
#define USBD_LANGID_STRING 1033
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
//VIDEO_VC_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
|
||||
VIDEO_VC_NOEP_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
|
||||
VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x00, 0x00),
|
||||
VIDEO_VS_INPUT_HEADER_DESCRIPTOR_INIT(0x01, VS_HEADER_SIZ, VIDEO_IN_EP, 0x00),
|
||||
VIDEO_VS_FORMAT_H264_DESCRIPTOR_INIT(0x01, 0x01),
|
||||
VIDEO_VS_FRAME_H264_DESCRIPTOR_INIT(0x01, WIDTH, HEIGHT, MIN_BIT_RATE, MAX_BIT_RATE, DBVAL(INTERVAL), 0x01, DBVAL(INTERVAL)),
|
||||
VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x01, 0x01),
|
||||
/* 1.2.2.2 Standard VideoStream Isochronous Video Data Endpoint Descriptor */
|
||||
USB_ENDPOINT_DESCRIPTOR_INIT(VIDEO_IN_EP, 0x05, VIDEO_PACKET_SIZE, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB UVC DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor video_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
const uint8_t video_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
|
@ -136,6 +207,7 @@ const uint8_t video_descriptor[] = {
|
|||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
volatile bool tx_flag = 0;
|
||||
volatile bool iso_tx_busy = false;
|
||||
|
@ -198,7 +270,11 @@ struct usbd_interface intf1;
|
|||
|
||||
void video_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &video_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, video_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
|
||||
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf1, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
|
||||
usbd_add_endpoint(busid, &video_in_ep);
|
||||
|
|
|
@ -50,6 +50,77 @@
|
|||
#define USBD_MAX_POWER 100
|
||||
#define USBD_LANGID_STRING 1033
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
//VIDEO_VC_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
|
||||
VIDEO_VC_NOEP_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
|
||||
VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x00, 0x00),
|
||||
VIDEO_VS_INPUT_HEADER_DESCRIPTOR_INIT(0x01, VS_HEADER_SIZ, VIDEO_IN_EP, 0x00),
|
||||
VIDEO_VS_FORMAT_MJPEG_DESCRIPTOR_INIT(0x01, 0x01),
|
||||
VIDEO_VS_FRAME_MJPEG_DESCRIPTOR_INIT(0x01, WIDTH, HEIGHT, MIN_BIT_RATE, MAX_BIT_RATE, MAX_FRAME_SIZE, DBVAL(INTERVAL), 0x01, DBVAL(INTERVAL)),
|
||||
VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x01, 0x01),
|
||||
/* 1.2.2.2 Standard VideoStream Isochronous Video Data Endpoint Descriptor */
|
||||
USB_ENDPOINT_DESCRIPTOR_INIT(VIDEO_IN_EP, 0x05, VIDEO_PACKET_SIZE, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB UVC DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor video_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
const uint8_t video_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
|
@ -136,6 +207,7 @@ const uint8_t video_descriptor[] = {
|
|||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
volatile bool tx_flag = 0;
|
||||
volatile bool iso_tx_busy = false;
|
||||
|
@ -198,7 +270,11 @@ struct usbd_interface intf1;
|
|||
|
||||
void video_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &video_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, video_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
|
||||
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf1, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
|
||||
usbd_add_endpoint(busid, &video_in_ep);
|
||||
|
|
|
@ -51,6 +51,79 @@
|
|||
#define USBD_MAX_POWER 100
|
||||
#define USBD_LANGID_STRING 1033
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
//VIDEO_VC_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
|
||||
VIDEO_VC_NOEP_DESCRIPTOR_INIT(0x00, VIDEO_INT_EP, 0x0100, VIDEO_VC_TERMINAL_LEN, 48000000, 0x02),
|
||||
VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x00, 0x00),
|
||||
VIDEO_VS_INPUT_HEADER_DESCRIPTOR_INIT(0x01, VS_HEADER_SIZ, VIDEO_IN_EP, 0x00),
|
||||
VIDEO_VS_FORMAT_UNCOMPRESSED_DESCRIPTOR_INIT(0x01, 0x01, VIDEO_GUID_YUY2),
|
||||
VIDEO_VS_FRAME_UNCOMPRESSED_DESCRIPTOR_INIT(0x01, WIDTH, HEIGHT, MIN_BIT_RATE, MAX_BIT_RATE, MAX_FRAME_SIZE, DBVAL(INTERVAL), 0x01, DBVAL(INTERVAL)),
|
||||
VIDEO_VS_COLOR_MATCHING_DESCRIPTOR_INIT(),
|
||||
VIDEO_VS_DESCRIPTOR_INIT(0x01, 0x01, 0x01),
|
||||
/* 1.2.2.2 Standard VideoStream Isochronous Video Data Endpoint Descriptor */
|
||||
USB_ENDPOINT_DESCRIPTOR_INIT(VIDEO_IN_EP, 0x05, VIDEO_PACKET_SIZE, 0x01),
|
||||
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB UVC DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor video_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback
|
||||
};
|
||||
#else
|
||||
const uint8_t video_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xef, 0x02, 0x01, USBD_VID, USBD_PID, 0x0001, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_VIDEO_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
|
@ -138,6 +211,7 @@ const uint8_t video_descriptor[] = {
|
|||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
volatile bool tx_flag = 0;
|
||||
volatile bool iso_tx_busy = false;
|
||||
|
@ -200,7 +274,11 @@ struct usbd_interface intf1;
|
|||
|
||||
void video_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &video_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, video_descriptor);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
|
||||
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf1, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
|
||||
usbd_add_endpoint(busid, &video_in_ep);
|
||||
|
|
|
@ -149,6 +149,105 @@ struct usb_bos_descriptor bos_desc = {
|
|||
.string_len = USBD_BOS_WTOTALLENGTH
|
||||
};
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
|
||||
/************** Descriptor of Joystick Mouse interface ****************/
|
||||
/* 09 */
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
|
||||
0x00, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x01, /* bNumEndpoints */
|
||||
0x03, /* bInterfaceClass: HID */
|
||||
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
|
||||
0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
|
||||
0, /* iInterface: Index of string descriptor */
|
||||
/******************** Descriptor of Joystick Mouse HID ********************/
|
||||
/* 18 */
|
||||
0x09, /* bLength: HID Descriptor size */
|
||||
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
|
||||
0x11, /* bcdHID: HID Class Spec release number */
|
||||
0x01,
|
||||
0x00, /* bCountryCode: Hardware target country */
|
||||
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
|
||||
0x22, /* bDescriptorType */
|
||||
HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
|
||||
0x00,
|
||||
/******************** Descriptor of Mouse endpoint ********************/
|
||||
/* 27 */
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
|
||||
HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
|
||||
0x03, /* bmAttributes: Interrupt endpoint */
|
||||
HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */
|
||||
0x00,
|
||||
HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
|
||||
/* 34 */
|
||||
USB_INTERFACE_DESCRIPTOR_INIT(USBD_WEBUSB_INTF_NUM, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00)
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB WEBUSB HID DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor webusb_hid_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback,
|
||||
.msosv2_descriptor = &msosv2_desc,
|
||||
.webusb_url_descriptor = &webusb_url_desc,
|
||||
.bos_descriptor = &bos_desc
|
||||
};
|
||||
#else
|
||||
static const uint8_t webusb_hid_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
|
@ -207,7 +306,7 @@ static const uint8_t webusb_hid_descriptor[] = {
|
|||
///////////////////////////////////////
|
||||
/// string2 descriptor
|
||||
///////////////////////////////////////
|
||||
0x26, /* bLength */
|
||||
0x2C, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'C', 0x00, /* wcChar0 */
|
||||
'h', 0x00, /* wcChar1 */
|
||||
|
@ -219,14 +318,17 @@ static const uint8_t webusb_hid_descriptor[] = {
|
|||
'S', 0x00, /* wcChar7 */
|
||||
'B', 0x00, /* wcChar8 */
|
||||
' ', 0x00, /* wcChar9 */
|
||||
'H', 0x00, /* wcChar10 */
|
||||
'I', 0x00, /* wcChar11 */
|
||||
'D', 0x00, /* wcChar12 */
|
||||
' ', 0x00, /* wcChar13 */
|
||||
'D', 0x00, /* wcChar14 */
|
||||
'E', 0x00, /* wcChar15 */
|
||||
'M', 0x00, /* wcChar16 */
|
||||
'O', 0x00, /* wcChar17 */
|
||||
'W', 0x00, /* wcChar10 */
|
||||
'E', 0x00, /* wcChar11 */
|
||||
'B', 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
|
||||
///////////////////////////////////////
|
||||
|
@ -259,6 +361,7 @@ static const uint8_t webusb_hid_descriptor[] = {
|
|||
#endif
|
||||
0x00
|
||||
};
|
||||
#endif
|
||||
|
||||
/* USB HID device Configuration Descriptor */
|
||||
static uint8_t hid_desc[9] __ALIGN_END = {
|
||||
|
@ -355,10 +458,16 @@ static struct usbd_interface intf0;
|
|||
|
||||
void webusb_hid_keyboard_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &webusb_hid_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, webusb_hid_descriptor);
|
||||
#endif
|
||||
#ifndef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_bos_desc_register(busid, &bos_desc);
|
||||
usbd_msosv2_desc_register(busid, &msosv2_desc);
|
||||
usbd_webusb_desc_register(busid, &webusb_url_desc);
|
||||
#endif
|
||||
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_keyboard_report_desc, HID_KEYBOARD_REPORT_DESC_SIZE));
|
||||
usbd_add_endpoint(busid, &hid_in_ep);
|
||||
|
||||
|
|
|
@ -188,6 +188,79 @@ struct usb_msosv1_descriptor msosv1_desc = {
|
|||
#define WINUSB_EP_MPS 64
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xff, 0xff, 0x00, 0x04),
|
||||
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, 0x02, WINUSB_EP_MPS, 0x00),
|
||||
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, 0x02, WINUSB_EP_MPS, 0x00),
|
||||
#if DOUBLE_WINUSB == 1
|
||||
USB_INTERFACE_DESCRIPTOR_INIT(0x01, 0x00, 0x02, 0xff, 0xff, 0x00, 0x05),
|
||||
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP2, 0x02, WINUSB_EP_MPS, 0x00),
|
||||
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP2, 0x02, WINUSB_EP_MPS, 0x00),
|
||||
#endif
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB WINUSB DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
"CherryUSB WINUSB DEMO 1", /* STRING4 */
|
||||
"CherryUSB WINUSB DEMO 2", /* STRING5 */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 5) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor winusb_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback,
|
||||
.msosv1_descriptor = &msosv1_desc
|
||||
};
|
||||
#else
|
||||
const uint8_t winusb_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0001, 0x01),
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
|
@ -252,12 +325,12 @@ const uint8_t winusb_descriptor[] = {
|
|||
'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 */
|
||||
'1', 0x00, /* wcChar4 */
|
||||
'2', 0x00, /* wcChar5 */
|
||||
'3', 0x00, /* wcChar6 */
|
||||
'4', 0x00, /* wcChar7 */
|
||||
'5', 0x00, /* wcChar8 */
|
||||
'6', 0x00, /* wcChar9 */
|
||||
///////////////////////////////////////
|
||||
/// string4 descriptor
|
||||
///////////////////////////////////////
|
||||
|
@ -322,15 +395,16 @@ const uint8_t winusb_descriptor[] = {
|
|||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x00,
|
||||
0x02,
|
||||
0x02,
|
||||
0x02,
|
||||
0x01,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
#endif
|
||||
0x00
|
||||
};
|
||||
#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];
|
||||
|
@ -446,8 +520,14 @@ struct usbd_interface intf1;
|
|||
|
||||
void winusb_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &winusb_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, winusb_descriptor);
|
||||
#endif
|
||||
#ifndef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_msosv1_desc_register(busid, &msosv1_desc);
|
||||
#endif
|
||||
usbd_add_interface(busid, &intf0);
|
||||
usbd_add_endpoint(busid, &winusb_out_ep1);
|
||||
usbd_add_endpoint(busid, &winusb_in_ep1);
|
||||
|
|
|
@ -145,6 +145,89 @@ __ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = {
|
|||
#endif
|
||||
};
|
||||
|
||||
struct usb_msosv2_descriptor msosv2_desc = {
|
||||
.vendor_code = USBD_WINUSB_VENDOR_CODE,
|
||||
.compat_id = USBD_WinUSBDescriptorSetDescriptor,
|
||||
.compat_id_len = USBD_WINUSB_DESC_SET_LEN,
|
||||
};
|
||||
|
||||
struct usb_bos_descriptor bos_desc = {
|
||||
.string = USBD_BinaryObjectStoreDescriptor,
|
||||
.string_len = USBD_BOS_WTOTALLENGTH
|
||||
};
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
/* Configuration 0 */
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
/* Interface 0 */
|
||||
USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02),
|
||||
/* Endpoint OUT 2 */
|
||||
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00),
|
||||
/* Endpoint IN 1 */
|
||||
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00),
|
||||
CDC_ACM_DESCRIPTOR_INIT(0x01, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, WINUSB_EP_MPS, 0x00)
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x10,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB WINUSB DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor winusbv2_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback,
|
||||
.msosv2_descriptor = &msosv2_desc,
|
||||
.bos_descriptor = &bos_desc
|
||||
};
|
||||
#else
|
||||
const uint8_t winusbv2_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
/* Configuration 0 */
|
||||
|
@ -170,7 +253,9 @@ const uint8_t winusbv2_descriptor[] = {
|
|||
'U', 0x00, /* wcChar6 */
|
||||
'S', 0x00, /* wcChar7 */
|
||||
'B', 0x00, /* wcChar8 */
|
||||
/* String 2 (Product) */
|
||||
///////////////////////////////////////
|
||||
/// string2 descriptor
|
||||
///////////////////////////////////////
|
||||
0x2C, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'C', 0x00, /* wcChar0 */
|
||||
|
@ -194,21 +279,21 @@ const uint8_t winusbv2_descriptor[] = {
|
|||
'E', 0x00, /* wcChar18 */
|
||||
'M', 0x00, /* wcChar19 */
|
||||
'O', 0x00, /* wcChar20 */
|
||||
/* String 3 (Serial Number) */
|
||||
0x1A, // bLength
|
||||
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
|
||||
'0', 0, // wcChar0
|
||||
'1', 0, // wcChar1
|
||||
'2', 0, // wcChar2
|
||||
'3', 0, // wcChar3
|
||||
'4', 0, // wcChar4
|
||||
'5', 0, // wcChar5
|
||||
'A', 0, // wcChar6
|
||||
'B', 0, // wcChar7
|
||||
'C', 0, // wcChar8
|
||||
'D', 0, // wcChar9
|
||||
'E', 0, // wcChar10
|
||||
'F', 0, // wcChar11
|
||||
///////////////////////////////////////
|
||||
/// string3 descriptor
|
||||
///////////////////////////////////////
|
||||
0x16, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'2', 0x00, /* wcChar0 */
|
||||
'0', 0x00, /* wcChar1 */
|
||||
'2', 0x00, /* wcChar2 */
|
||||
'2', 0x00, /* wcChar3 */
|
||||
'1', 0x00, /* wcChar4 */
|
||||
'2', 0x00, /* wcChar5 */
|
||||
'3', 0x00, /* wcChar6 */
|
||||
'4', 0x00, /* wcChar7 */
|
||||
'5', 0x00, /* wcChar8 */
|
||||
'6', 0x00, /* wcChar9 */
|
||||
#ifdef CONFIG_USB_HS
|
||||
/* Device Qualifier */
|
||||
0x0a,
|
||||
|
@ -225,6 +310,7 @@ const uint8_t winusbv2_descriptor[] = {
|
|||
/* End */
|
||||
0x00
|
||||
};
|
||||
#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];
|
||||
|
@ -248,6 +334,7 @@ static void usbd_event_handler(uint8_t busid, uint8_t event)
|
|||
ep_tx_busy_flag = false;
|
||||
/* setup first out ep read transfer */
|
||||
usbd_ep_start_read(busid, WINUSB_OUT_EP, read_buffer, 2048);
|
||||
usbd_ep_start_read(busid, CDC_OUT_EP, read_buffer, 2048);
|
||||
break;
|
||||
case USBD_EVENT_SET_REMOTE_WAKEUP:
|
||||
break;
|
||||
|
@ -283,6 +370,30 @@ void usbd_winusb_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
|||
}
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_out(uint8_t busid, 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");
|
||||
usbd_ep_start_write(busid, CDC_IN_EP, read_buffer, nbytes);
|
||||
/* setup next out ep read transfer */
|
||||
usbd_ep_start_read(busid, CDC_OUT_EP, read_buffer, 2048);
|
||||
}
|
||||
|
||||
void usbd_cdc_acm_in(uint8_t busid, uint8_t ep, uint32_t nbytes)
|
||||
{
|
||||
USB_LOG_RAW("actual in len:%d\r\n", nbytes);
|
||||
|
||||
if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) {
|
||||
/* send zlp */
|
||||
usbd_ep_start_write(busid, CDC_IN_EP, NULL, 0);
|
||||
} else {
|
||||
ep_tx_busy_flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
struct usbd_endpoint winusb_out_ep1 = {
|
||||
.ep_addr = WINUSB_OUT_EP,
|
||||
.ep_cb = usbd_winusb_out
|
||||
|
@ -295,35 +406,29 @@ struct usbd_endpoint winusb_in_ep1 = {
|
|||
|
||||
static struct usbd_endpoint cdc_out_ep = {
|
||||
.ep_addr = CDC_OUT_EP,
|
||||
.ep_cb = NULL
|
||||
.ep_cb = usbd_cdc_acm_out
|
||||
};
|
||||
|
||||
static struct usbd_endpoint cdc_in_ep = {
|
||||
.ep_addr = CDC_IN_EP,
|
||||
.ep_cb = NULL
|
||||
.ep_cb = usbd_cdc_acm_in
|
||||
};
|
||||
|
||||
struct usbd_interface winusb_intf;
|
||||
struct usbd_interface intf1;
|
||||
struct usbd_interface intf2;
|
||||
|
||||
struct usb_msosv2_descriptor msosv2_desc = {
|
||||
.vendor_code = USBD_WINUSB_VENDOR_CODE,
|
||||
.compat_id = USBD_WinUSBDescriptorSetDescriptor,
|
||||
.compat_id_len = USBD_WINUSB_DESC_SET_LEN,
|
||||
};
|
||||
|
||||
struct usb_bos_descriptor bos_desc = {
|
||||
.string = USBD_BinaryObjectStoreDescriptor,
|
||||
.string_len = USBD_BOS_WTOTALLENGTH
|
||||
};
|
||||
|
||||
void winusbv2_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &winusbv2_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, winusbv2_descriptor);
|
||||
#endif
|
||||
#ifndef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_bos_desc_register(busid, &bos_desc);
|
||||
usbd_msosv2_desc_register(busid, &msosv2_desc);
|
||||
|
||||
#endif
|
||||
/*!< winusb */
|
||||
usbd_add_interface(busid, &winusb_intf);
|
||||
usbd_add_endpoint(busid, &winusb_out_ep1);
|
||||
|
@ -336,4 +441,26 @@ void winusbv2_init(uint8_t busid, uintptr_t reg_base)
|
|||
usbd_add_endpoint(busid, &cdc_in_ep);
|
||||
|
||||
usbd_initialize(busid, reg_base, usbd_event_handler);
|
||||
}
|
||||
|
||||
volatile uint8_t dtr_enable = 0;
|
||||
|
||||
void usbd_cdc_acm_set_dtr(uint8_t busid, uint8_t intf, bool dtr)
|
||||
{
|
||||
if (dtr) {
|
||||
dtr_enable = 1;
|
||||
} else {
|
||||
dtr_enable = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void cdc_acm_data_send_with_dtr_test(uint8_t busid)
|
||||
{
|
||||
if (dtr_enable) {
|
||||
memset(&write_buffer[10], 'a', 2038);
|
||||
ep_tx_busy_flag = true;
|
||||
usbd_ep_start_write(busid, CDC_IN_EP, write_buffer, 2048);
|
||||
while (ep_tx_busy_flag) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -151,6 +151,119 @@ __ALIGN_BEGIN const uint8_t USBD_BinaryObjectStoreDescriptor[] = {
|
|||
#endif
|
||||
};
|
||||
|
||||
struct usb_msosv2_descriptor msosv2_desc = {
|
||||
.vendor_code = USBD_WINUSB_VENDOR_CODE,
|
||||
.compat_id = USBD_WinUSBDescriptorSetDescriptor,
|
||||
.compat_id_len = USBD_WINUSB_DESC_SET_LEN,
|
||||
};
|
||||
|
||||
struct usb_bos_descriptor bos_desc = {
|
||||
.string = USBD_BinaryObjectStoreDescriptor,
|
||||
.string_len = USBD_BOS_WTOTALLENGTH
|
||||
};
|
||||
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
static const uint8_t device_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01)
|
||||
};
|
||||
|
||||
static const uint8_t config_descriptor[] = {
|
||||
/* Configuration 0 */
|
||||
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, INTF_NUM, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
|
||||
/* Interface 0 */
|
||||
USB_INTERFACE_DESCRIPTOR_INIT(0x00, 0x00, 0x02, 0xFF, 0x00, 0x00, 0x02),
|
||||
/* Endpoint OUT 2 */
|
||||
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_OUT_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00),
|
||||
/* Endpoint IN 1 */
|
||||
USB_ENDPOINT_DESCRIPTOR_INIT(WINUSB_IN_EP, USB_ENDPOINT_TYPE_BULK, WINUSB_EP_MPS, 0x00),
|
||||
/************** Descriptor of Joystick Mouse interface ****************/
|
||||
/* 09 */
|
||||
0x09, /* bLength: Interface Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
|
||||
0x01, /* bInterfaceNumber: Number of Interface */
|
||||
0x00, /* bAlternateSetting: Alternate setting */
|
||||
0x01, /* bNumEndpoints */
|
||||
0x03, /* bInterfaceClass: HID */
|
||||
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
|
||||
0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
|
||||
0, /* iInterface: Index of string descriptor */
|
||||
/******************** Descriptor of Joystick Mouse HID ********************/
|
||||
/* 18 */
|
||||
0x09, /* bLength: HID Descriptor size */
|
||||
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
|
||||
0x11, /* bcdHID: HID Class Spec release number */
|
||||
0x01,
|
||||
0x00, /* bCountryCode: Hardware target country */
|
||||
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
|
||||
0x22, /* bDescriptorType */
|
||||
HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
|
||||
0x00,
|
||||
/******************** Descriptor of Mouse endpoint ********************/
|
||||
/* 27 */
|
||||
0x07, /* bLength: Endpoint Descriptor size */
|
||||
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
|
||||
HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
|
||||
0x03, /* bmAttributes: Interrupt endpoint */
|
||||
HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */
|
||||
0x00,
|
||||
HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
|
||||
};
|
||||
|
||||
static const uint8_t device_quality_descriptor[] = {
|
||||
///////////////////////////////////////
|
||||
/// device qualifier descriptor
|
||||
///////////////////////////////////////
|
||||
0x0a,
|
||||
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
|
||||
0x10,
|
||||
0x02,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x40,
|
||||
0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
static const char *string_descriptors[] = {
|
||||
(const char[]){ 0x09, 0x04 }, /* Langid */
|
||||
"CherryUSB", /* Manufacturer */
|
||||
"CherryUSB WINUSB DEMO", /* Product */
|
||||
"2022123456", /* Serial Number */
|
||||
};
|
||||
|
||||
static const uint8_t *device_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *config_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return config_descriptor;
|
||||
}
|
||||
|
||||
static const uint8_t *device_quality_descriptor_callback(uint8_t speed)
|
||||
{
|
||||
return device_quality_descriptor;
|
||||
}
|
||||
|
||||
static const char *string_descriptor_callback(uint8_t speed, uint8_t index)
|
||||
{
|
||||
if (index > 3) {
|
||||
return NULL;
|
||||
}
|
||||
return string_descriptors[index];
|
||||
}
|
||||
|
||||
const struct usb_descriptor winusbv2_descriptor = {
|
||||
.device_descriptor_callback = device_descriptor_callback,
|
||||
.config_descriptor_callback = config_descriptor_callback,
|
||||
.device_quality_descriptor_callback = device_quality_descriptor_callback,
|
||||
.string_descriptor_callback = string_descriptor_callback,
|
||||
.msosv2_descriptor = &msosv2_desc,
|
||||
.bos_descriptor = &bos_desc
|
||||
};
|
||||
#else
|
||||
const uint8_t winusbv2_descriptor[] = {
|
||||
USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01),
|
||||
/* Configuration 0 */
|
||||
|
@ -206,7 +319,9 @@ const uint8_t winusbv2_descriptor[] = {
|
|||
'U', 0x00, /* wcChar6 */
|
||||
'S', 0x00, /* wcChar7 */
|
||||
'B', 0x00, /* wcChar8 */
|
||||
/* String 2 (Product) */
|
||||
///////////////////////////////////////
|
||||
/// string2 descriptor
|
||||
///////////////////////////////////////
|
||||
0x2C, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'C', 0x00, /* wcChar0 */
|
||||
|
@ -230,21 +345,21 @@ const uint8_t winusbv2_descriptor[] = {
|
|||
'E', 0x00, /* wcChar18 */
|
||||
'M', 0x00, /* wcChar19 */
|
||||
'O', 0x00, /* wcChar20 */
|
||||
/* String 3 (Serial Number) */
|
||||
0x1A, // bLength
|
||||
USB_DESCRIPTOR_TYPE_STRING, // bDescriptorType
|
||||
'0', 0, // wcChar0
|
||||
'1', 0, // wcChar1
|
||||
'2', 0, // wcChar2
|
||||
'3', 0, // wcChar3
|
||||
'4', 0, // wcChar4
|
||||
'5', 0, // wcChar5
|
||||
'A', 0, // wcChar6
|
||||
'B', 0, // wcChar7
|
||||
'C', 0, // wcChar8
|
||||
'D', 0, // wcChar9
|
||||
'E', 0, // wcChar10
|
||||
'F', 0, // wcChar11
|
||||
///////////////////////////////////////
|
||||
/// string3 descriptor
|
||||
///////////////////////////////////////
|
||||
0x16, /* bLength */
|
||||
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
|
||||
'2', 0x00, /* wcChar0 */
|
||||
'0', 0x00, /* wcChar1 */
|
||||
'2', 0x00, /* wcChar2 */
|
||||
'2', 0x00, /* wcChar3 */
|
||||
'1', 0x00, /* wcChar4 */
|
||||
'2', 0x00, /* wcChar5 */
|
||||
'3', 0x00, /* wcChar6 */
|
||||
'4', 0x00, /* wcChar7 */
|
||||
'5', 0x00, /* wcChar8 */
|
||||
'6', 0x00, /* wcChar9 */
|
||||
#ifdef CONFIG_USB_HS
|
||||
/* Device Qualifier */
|
||||
0x0a,
|
||||
|
@ -261,6 +376,7 @@ const uint8_t winusbv2_descriptor[] = {
|
|||
/* End */
|
||||
0x00
|
||||
};
|
||||
#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];
|
||||
|
@ -411,23 +527,17 @@ static struct usbd_endpoint hid_in_ep = {
|
|||
struct usbd_interface winusb_intf;
|
||||
struct usbd_interface intf1;
|
||||
|
||||
struct usb_msosv2_descriptor msosv2_desc = {
|
||||
.vendor_code = USBD_WINUSB_VENDOR_CODE,
|
||||
.compat_id = USBD_WinUSBDescriptorSetDescriptor,
|
||||
.compat_id_len = USBD_WINUSB_DESC_SET_LEN,
|
||||
};
|
||||
|
||||
struct usb_bos_descriptor bos_desc = {
|
||||
.string = USBD_BinaryObjectStoreDescriptor,
|
||||
.string_len = USBD_BOS_WTOTALLENGTH
|
||||
};
|
||||
|
||||
void winusbv2_init(uint8_t busid, uintptr_t reg_base)
|
||||
{
|
||||
#ifdef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_desc_register(busid, &winusbv2_descriptor);
|
||||
#else
|
||||
usbd_desc_register(busid, winusbv2_descriptor);
|
||||
#endif
|
||||
#ifndef CONFIG_USBDEV_ADVANCE_DESC
|
||||
usbd_bos_desc_register(busid, &bos_desc);
|
||||
usbd_msosv2_desc_register(busid, &msosv2_desc);
|
||||
|
||||
#endif
|
||||
/*!< winusb */
|
||||
usbd_add_interface(busid, &winusb_intf);
|
||||
usbd_add_endpoint(busid, &winusb_out_ep1);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
version: "1.4.2"
|
||||
version: "1.4.3"
|
||||
description: CherryUSB is a tiny and portable USB Stack (device & host) for embedded system with USB IP
|
||||
tags:
|
||||
- usb
|
||||
|
|
|
@ -26,6 +26,8 @@ usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size,
|
|||
void usb_osal_thread_delete(usb_osal_thread_t thread)
|
||||
{
|
||||
if (thread == NULL) {
|
||||
rt_thread_t self = rt_thread_self();
|
||||
rt_thread_control(self, RT_THREAD_CTRL_CLOSE, RT_NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,12 @@ USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t msc_sector[512];
|
|||
|
||||
static rt_err_t rt_udisk_init(rt_device_t dev)
|
||||
{
|
||||
struct usbh_msc *msc_class = (struct usbh_msc *)dev->user_data;
|
||||
|
||||
if (usbh_msc_scsi_init(msc_class) < 0) {
|
||||
return -RT_ERROR;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
|
@ -157,39 +163,35 @@ const static struct rt_device_ops udisk_device_ops = {
|
|||
};
|
||||
#endif
|
||||
|
||||
int udisk_init(struct usbh_msc *msc_class)
|
||||
static void usbh_msc_thread(CONFIG_USB_OSAL_THREAD_SET_ARGV)
|
||||
{
|
||||
rt_err_t ret = 0;
|
||||
rt_uint8_t i;
|
||||
struct dfs_partition part0;
|
||||
struct rt_device *dev;
|
||||
struct usbh_msc *msc_class = (struct usbh_msc *)CONFIG_USB_OSAL_THREAD_GET_ARGV;
|
||||
char name[CONFIG_USBHOST_DEV_NAMELEN];
|
||||
char mount_point[CONFIG_USBHOST_DEV_NAMELEN];
|
||||
int ret;
|
||||
|
||||
snprintf(name, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, msc_class->sdchar);
|
||||
snprintf(mount_point, CONFIG_USBHOST_DEV_NAMELEN, CONFIG_USB_DFS_MOUNT_POINT, msc_class->sdchar);
|
||||
|
||||
ret = dfs_mount(name, mount_point, "elm", 0, 0);
|
||||
if (ret == 0) {
|
||||
rt_kprintf("udisk: %s mount successfully\n", name);
|
||||
} else {
|
||||
rt_kprintf("udisk: %s mount failed, ret = %d\n", name, ret);
|
||||
}
|
||||
|
||||
usb_osal_thread_delete(NULL);
|
||||
}
|
||||
|
||||
void usbh_msc_run(struct usbh_msc *msc_class)
|
||||
{
|
||||
struct rt_device *dev;
|
||||
char name[CONFIG_USBHOST_DEV_NAMELEN];
|
||||
|
||||
dev = rt_malloc(sizeof(struct rt_device));
|
||||
memset(dev, 0, sizeof(struct rt_device));
|
||||
|
||||
snprintf(name, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, msc_class->sdchar);
|
||||
snprintf(mount_point, CONFIG_USBHOST_DEV_NAMELEN, CONFIG_USB_DFS_MOUNT_POINT, msc_class->sdchar);
|
||||
|
||||
ret = usbh_msc_scsi_read10(msc_class, 0, msc_sector, 1);
|
||||
if (ret != RT_EOK) {
|
||||
rt_kprintf("usb mass_storage read failed\n");
|
||||
rt_free(dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
/* Get the first partition */
|
||||
ret = dfs_filesystem_get_partition(&part0, msc_sector, i);
|
||||
if (ret == RT_EOK) {
|
||||
rt_kprintf("Found partition %d: type = %d, offet=0x%x, size=0x%x\n",
|
||||
i, part0.type, part0.offset, part0.size);
|
||||
break;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dev->type = RT_Device_Class_Block;
|
||||
#ifdef RT_USING_DEVICE_OPS
|
||||
|
@ -204,19 +206,7 @@ int udisk_init(struct usbh_msc *msc_class)
|
|||
|
||||
rt_device_register(dev, name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
|
||||
|
||||
ret = dfs_mount(name, mount_point, "elm", 0, 0);
|
||||
if (ret == 0) {
|
||||
rt_kprintf("udisk: %s mount successfully\n", name);
|
||||
} else {
|
||||
rt_kprintf("udisk: %s mount failed, ret = %d\n", name, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void usbh_msc_run(struct usbh_msc *msc_class)
|
||||
{
|
||||
udisk_init(msc_class);
|
||||
usb_osal_thread_create("usbh_msc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_msc_thread, msc_class);
|
||||
}
|
||||
|
||||
void usbh_msc_stop(struct usbh_msc *msc_class)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Artinchip Technology Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <aic_core.h>
|
||||
#include <aic_hal.h>
|
||||
#include <hal_syscfg.h>
|
||||
#include "usbd_core.h"
|
||||
#include "usb_dc_aic_reg.h"
|
||||
|
||||
extern irqreturn_t USBD_IRQHandler(int irq, void * data);
|
||||
|
||||
uint32_t usbd_clk;
|
||||
|
||||
void usb_dc_low_level_init(void)
|
||||
{
|
||||
/* set usb0 phy switch: Host/Device */
|
||||
#ifdef AIC_USING_USB0_DEVICE
|
||||
syscfg_usb_phy0_sw_host(0);
|
||||
#endif
|
||||
/* set pin-mux */
|
||||
|
||||
/* enable clock */
|
||||
hal_clk_enable(CONFIG_USB_AIC_DC_PHY_CLK);
|
||||
hal_clk_enable(CONFIG_USB_AIC_DC_CLK);
|
||||
aicos_udelay(300);
|
||||
hal_reset_assert(CONFIG_USB_AIC_DC_PHY_RESET);
|
||||
hal_reset_assert(CONFIG_USB_AIC_DC_RESET);
|
||||
aicos_udelay(300);
|
||||
hal_reset_deassert(CONFIG_USB_AIC_DC_PHY_RESET);
|
||||
hal_reset_deassert(CONFIG_USB_AIC_DC_RESET);
|
||||
aicos_udelay(300);
|
||||
|
||||
usbd_clk = hal_clk_get_freq(CONFIG_USB_AIC_DC_CLK);
|
||||
|
||||
/* register interrupt callback */
|
||||
aicos_request_irq(CONFIG_USB_AIC_DC_IRQ_NUM, USBD_IRQHandler,
|
||||
0, "usb_device", NULL);
|
||||
aicos_irq_enable(CONFIG_USB_AIC_DC_IRQ_NUM);
|
||||
}
|
||||
|
|
@ -0,0 +1,301 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Artinchip Technology Co., Ltd
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef __USB_DC_AIC_REG_H__
|
||||
#define __USB_DC_AIC_REG_H__
|
||||
|
||||
#define __IO volatile /*!< Defines 'read / write' permissions */
|
||||
|
||||
typedef struct {
|
||||
__IO uint32_t ahbbasic; /* 0x0000: AHBBASIC */
|
||||
__IO uint32_t usbdevinit; /* 0x0004: USBDEVINIT */
|
||||
__IO uint32_t usbphyif; /* 0x0008: USBPHYIF */
|
||||
__IO uint32_t usbulpiphy; /* 0x000C: USBULPIPHY */
|
||||
__IO uint32_t usbintsts; /* 0x0010: USBINTSTS */
|
||||
__IO uint32_t usbintmsk; /* 0x0014: USBINTMSK */
|
||||
__IO uint32_t rxfifosiz; /* 0x0018: RXFIFOSIZ */
|
||||
__IO uint32_t rxfifosts_pop; /* 0x001C: RXFIFOSTS pop */
|
||||
__IO uint32_t nptxfifosiz; /* 0x0020: NPTXFIFOSIZ */
|
||||
__IO uint32_t nptxfifosts; /* 0x0024: NPTXFIFOSTS */
|
||||
__IO uint32_t txfifosiz[2]; /* 0x0028 - 0x002C: TXFIFOSIZ() */
|
||||
__IO uint32_t rxfifosts_dbg; /* 0x0030: RXFIFOSTS_DBG */
|
||||
uint8_t res0[0x1cc];
|
||||
__IO uint32_t usbdevconf; /* 0x0200: USBDEVCONF */
|
||||
__IO uint32_t usbdevfunc; /* 0x0204: USBDEVFUNC */
|
||||
__IO uint32_t usblinests; /* 0x0208: USBLINESTS */
|
||||
__IO uint32_t inepintmsk; /* 0x020C: INEPINTMSK */
|
||||
__IO uint32_t outepintmsk; /* 0x0210: OUTEPINTMSK */
|
||||
__IO uint32_t usbepint; /* 0x0214: USBEPINT */
|
||||
__IO uint32_t usbepintmsk; /* 0x0218: USBEPINTMSK */
|
||||
uint8_t res1[4];
|
||||
__IO uint32_t inepcfg[5]; /* 0x0220 - 0x0230: INEPCFG() */
|
||||
uint8_t res2[0xc];
|
||||
__IO uint32_t outepcfg[5]; /* 0x0240 - 0x0250: OUTEPCFG() */
|
||||
uint8_t res3[0xc];
|
||||
__IO uint32_t inepint[5]; /* 0x0260 - 0x0270: INEPINT() */
|
||||
uint8_t res4[0xc];
|
||||
__IO uint32_t outepint[5]; /* 0x0280 - 0x0290: OUTEPINT() */
|
||||
uint8_t res5[0xc];
|
||||
__IO uint32_t ineptsfsiz[5]; /* 0x02A0 - 0x02B0: INEPTSFSIZ() */
|
||||
uint8_t res6[0xc];
|
||||
__IO uint32_t outeptsfsiz[5]; /* 0x02C0 - 0x02D0: OUTEPTSFSIZ() */
|
||||
uint8_t res7[0x2c];
|
||||
__IO uint32_t inepdmaaddr[5]; /* 0x0300 - 0x0310: INEPDMAADDR() */
|
||||
uint8_t res8[0xc];
|
||||
__IO uint32_t outepdmaaddr[5]; /* 0x0320 - 0x0330: OUTEPDMAADDR() */
|
||||
uint8_t res9[0xc];
|
||||
__IO uint32_t ineptxsts[5]; /* 0x0340 - 0x0350: INEPTXSTS() */
|
||||
uint8_t res10[0xc];
|
||||
__IO uint32_t dtknqr1; /* 0x0360: DTKNQR1 */
|
||||
__IO uint32_t dtknqr2; /* 0x0364: DTKNQR2 */
|
||||
__IO uint32_t dtknqr3; /* 0x0368: DTKNQR3 */
|
||||
__IO uint32_t dtknqr4; /* 0x036C: DTKNQR4 */
|
||||
}AIC_UDC_RegDef;
|
||||
|
||||
/*===================================================================== */
|
||||
/*definitions related to CSR setting */
|
||||
|
||||
/* AHBBASIC */
|
||||
#define AHBBASIC_NOTI_ALL_DMA_WRIT (1 << 8)
|
||||
#define AHBBASIC_REM_MEM_SUPP (1 << 7)
|
||||
#define AHBBASIC_INV_DESC_ENDIANNESS (1 << 6)
|
||||
#define AHBBASIC_AHB_SINGLE (1 << 5)
|
||||
#define AHBBASIC_TXENDDELAY (1 << 3)
|
||||
#define AHBBASIC_AHBIDLE (1 << 2)
|
||||
#define AHBBASIC_DMAREQ (1 << 1)
|
||||
|
||||
/* USBDEVINIT */
|
||||
#define USBDEVINIT_HBSTLEN_MASK (0xf << 12)
|
||||
#define USBDEVINIT_HBSTLEN_SHIFT 12
|
||||
#define USBDEVINIT_HBSTLEN_SINGLE 0
|
||||
#define USBDEVINIT_HBSTLEN_INCR 1
|
||||
#define USBDEVINIT_HBSTLEN_INCR4 3
|
||||
#define USBDEVINIT_HBSTLEN_INCR8 5
|
||||
#define USBDEVINIT_HBSTLEN_INCR16 7
|
||||
#define USBDEVINIT_DMA_EN (1 << 11)
|
||||
#define USBDEVINIT_NP_TXF_EMP_LVL (1 << 10)
|
||||
#define USBDEVINIT_GLBL_INTR_EN (1 << 9)
|
||||
#define USBDEVINIT_CTRL_MASK (USBDEVINIT_NP_TXF_EMP_LVL | \
|
||||
USBDEVINIT_DMA_EN | \
|
||||
USBDEVINIT_GLBL_INTR_EN)
|
||||
#define USBDEVINIT_IN_TKNQ_FLSH (1 << 8)
|
||||
#define USBDEVINIT_TXFNUM_MASK (0x1f << 3)
|
||||
#define USBDEVINIT_TXFNUM_SHIFT 3
|
||||
#define USBDEVINIT_TXFNUM_LIMIT 0x1f
|
||||
#define USBDEVINIT_TXFNUM(_x) ((_x) << 3)
|
||||
#define USBDEVINIT_TXFFLSH (1 << 2)
|
||||
#define USBDEVINIT_RXFFLSH (1 << 1)
|
||||
#define USBDEVINIT_CSFTRST (1 << 0)
|
||||
|
||||
/* USBPHYIF */
|
||||
#define USBPHYIF_ULPI_CLK_SUSP_M (1 << 19)
|
||||
#define USBPHYIF_ULPI_AUTO_RES (1 << 18)
|
||||
#define USBPHYIF_PHY_LP_CLK_SEL (1 << 15)
|
||||
#define USBPHYIF_USBTRDTIM_MASK (0xf << 10)
|
||||
#define USBPHYIF_USBTRDTIM_SHIFT 10
|
||||
#ifndef USBPHYIF_HS_TRDT_VALUE
|
||||
#define USBPHYIF_HS_TRDT_VALUE 9U
|
||||
#endif /* USBD_HS_TRDT_VALUE */
|
||||
#ifndef USBPHYIF_FS_TRDT_VALUE
|
||||
#define USBPHYIF_FS_TRDT_VALUE 5U
|
||||
#define USBPHYIF_DEFAULT_TRDT_VALUE 9U
|
||||
#endif /* USBD_HS_TRDT_VALUE */
|
||||
#define USBPHYIF_DDRSEL (1 << 7)
|
||||
#define USBPHYIF_ULPI_UTMI_SEL (1 << 4)
|
||||
#define USBPHYIF_PHYIF16 (1 << 3)
|
||||
#define USBPHYIF_PHYIF8 (0 << 3)
|
||||
#define USBPHYIF_TOUTCAL_MASK (0x7 << 0)
|
||||
#define USBPHYIF_TOUTCAL_SHIFT 0
|
||||
#define USBPHYIF_TOUTCAL_LIMIT 0x7
|
||||
#define USBPHYIF_TOUTCAL(_x) ((_x) << 0)
|
||||
|
||||
/* USBINTSTS/USBINTMSK interrupt register */
|
||||
#define INT_RESUME (1u << 31)
|
||||
#define INT_INCOMP_ISO_OUT_INT (0x1 << 21)
|
||||
#define INT_INCOMP_ISO_IN_INT (0x1 << 20)
|
||||
#define INT_OUT_EP (0x1 << 19)
|
||||
#define INT_IN_EP (0x1 << 18)
|
||||
#define INT_ENUMDONE (0x1 << 13)
|
||||
#define INT_RESET (0x1 << 12)
|
||||
#define INT_SUSPEND (0x1 << 11)
|
||||
#define INT_EARLY_SUSPEND (0x1 << 10)
|
||||
#define INT_GOUTNAKEFF (0x1 << 7)
|
||||
#define INT_GINNAKEFF (0x1 << 6)
|
||||
#define INT_NP_TX_FIFO_EMPTY (0x1 << 5)
|
||||
#define INT_RX_FIFO_NOT_EMPTY (0x1 << 4)
|
||||
#define INT_SOF (0x1 << 3)
|
||||
|
||||
#define FULL_SPEED_CONTROL_PKT_SIZE 8
|
||||
#define FULL_SPEED_BULK_PKT_SIZE 64
|
||||
|
||||
#define HIGH_SPEED_CONTROL_PKT_SIZE 64
|
||||
#define HIGH_SPEED_BULK_PKT_SIZE 512
|
||||
|
||||
#define RX_FIFO_SIZE (1024)
|
||||
#define NPTX_FIFO_SIZE (1024)
|
||||
#define PTX_FIFO_SIZE (384)
|
||||
|
||||
/* fifo size configure */
|
||||
#define EPS_NUM 5
|
||||
#define PERIOD_IN_EP_NUM 2
|
||||
#define TOTAL_FIFO_SIZE 0x3f6
|
||||
#define AIC_RX_FIFO_SIZE 0x119
|
||||
#define AIC_NP_TX_FIFO_SIZE 0x100
|
||||
#define AIC_PERIOD_TX_FIFO1_SIZE 0x100
|
||||
#define AIC_PERIOD_TX_FIFO2_SIZE 0xDD
|
||||
|
||||
#define DEPCTL_TXFNUM_0 (0x0 << 22)
|
||||
#define DEPCTL_TXFNUM_1 (0x1 << 22)
|
||||
#define DEPCTL_TXFNUM_2 (0x2 << 22)
|
||||
#define DEPCTL_TXFNUM_3 (0x3 << 22)
|
||||
#define DEPCTL_TXFNUM_4 (0x4 << 22)
|
||||
|
||||
/* RXFIFOSTS */
|
||||
#define RXFIFOSTS_EPNUM_MASK (0xFU << 0)
|
||||
#define RXFIFOSTS_BCNT_MASK (0x7FFU << 4)
|
||||
#define RXFIFOSTS_DPID_MASK (0x3U << 15)
|
||||
#define RXFIFOSTS_PKTSTS_SHIFT (17)
|
||||
#define RXFIFOSTS_PKTSTS_MASK (0xFU << RXFIFOSTS_PKTSTS_SHIFT)
|
||||
#define PKTSTS_GLOBAL_OUT_NAK (0x1 << RXFIFOSTS_PKTSTS_SHIFT)
|
||||
#define PKTSTS_OUT_DATA_PKT_REC (0x2 << RXFIFOSTS_PKTSTS_SHIFT)
|
||||
#define PKTSTS_OUT_TRANSFER_COMP (0x3 << RXFIFOSTS_PKTSTS_SHIFT)
|
||||
#define PKTSTS_SETUP_TRANSACTION_COMP (0x4 << RXFIFOSTS_PKTSTS_SHIFT)
|
||||
#define PKTSTS_SETUP_DATA_PKT_REC (0x6 << RXFIFOSTS_PKTSTS_SHIFT)
|
||||
#define RXFIFOSTS_FN_MASK (0xFU << 21)
|
||||
|
||||
/* USBDEVCONF */
|
||||
#define DEV_SPEED_HIGH_SPEED_20 (0x0 << 0)
|
||||
#define DEV_SPEED_FULL_SPEED_20 (0x1 << 0)
|
||||
#define DEV_SPEED_LOW_SPEED_11 (0x2 << 0)
|
||||
#define DEV_SPEED_FULL_SPEED_11 (0x3 << 0)
|
||||
#define EP_MISS_CNT(x) (x << 18)
|
||||
#define DEVICE_ADDRESS_MASK (0x7F << 4)
|
||||
#define DEVICE_ADDRESS(x) (x << 4)
|
||||
#define PERIOD_FRAME_INTERVAL_80 (0 << 11)
|
||||
#define PERIOD_FRAME_INTERVAL_85 (1 << 11)
|
||||
#define PERIOD_FRAME_INTERVAL_90 (2 << 11)
|
||||
#define PERIOD_FRAME_INTERVAL_95 (3 << 11)
|
||||
|
||||
/* USBDEVFUNC */
|
||||
#define NORMAL_OPERATION (0x1 << 0)
|
||||
#define SOFT_DISCONNECT (0x1 << 1)
|
||||
#define USBDEVFUNC_SERVICE_INTERVAL_SUPPORTED (1 << 19)
|
||||
#define USBDEVFUNC_PWRONPRGDONE (1 << 11)
|
||||
#define USBDEVFUNC_CGOUTNAK (1 << 10)
|
||||
#define USBDEVFUNC_SGOUTNAK (1 << 9)
|
||||
#define USBDEVFUNC_CGNPINNAK (1 << 8)
|
||||
#define USBDEVFUNC_SGNPINNAK (1 << 7)
|
||||
#define USBDEVFUNC_TSTCTL_MASK (0x7 << 4)
|
||||
#define USBDEVFUNC_TSTCTL_SHIFT (4)
|
||||
#define USBDEVFUNC_GOUTNAKSTS (1 << 3)
|
||||
#define USBDEVFUNC_GNPINNAKSTS (1 << 2)
|
||||
#define USBDEVFUNC_SFTDISCON (1 << 1)
|
||||
#define USBDEVFUNC_RMTWKUPSIG (1 << 0)
|
||||
|
||||
/* USBLINESTS: Enumeration speed */
|
||||
#define USB_ENUM_SPEED_SHIFT 1
|
||||
#define USB_ENUM_SPEED_MASK (0x3 << USB_ENUM_SPEED_SHIFT)
|
||||
#define USB_ENUM_SPEED_HIGH 0
|
||||
#define USB_ENUM_SPEED_FULL 1
|
||||
#define USB_HIGH_30_60MHZ (0x0 << USB_ENUM_SPEED_SHIFT)
|
||||
#define USB_FULL_30_60MHZ (0x1 << USB_ENUM_SPEED_SHIFT)
|
||||
#define USB_LOW_6MHZ (0x2 << USB_ENUM_SPEED_SHIFT)
|
||||
#define USB_FULL_48MHZ (0x3 << USB_ENUM_SPEED_SHIFT)
|
||||
|
||||
/* USBEPINT endpoint interrupt register */
|
||||
#define DAINT_OUT_BIT (16)
|
||||
#define DAINT_IN_MASK (0xFFFF)
|
||||
#define DAINT_OUT_MASK (0xFFFFU << DAINT_OUT_BIT)
|
||||
|
||||
/* INEPCFG()/OUTEPCFG()
|
||||
* devicecontrol IN/OUT endpoint 0 control register
|
||||
*/
|
||||
#define DEPCTL_EPENA (1u << 31)
|
||||
#define DEPCTL_EPDIS (0x1 << 30)
|
||||
#define DEPCTL_SETD1PID (0x1 << 29)
|
||||
#define DEPCTL_SETD0PID (0x1 << 28)
|
||||
#define DEPCTL_SNAK (0x1 << 27)
|
||||
#define DEPCTL_CNAK (0x1 << 26)
|
||||
#define DEPCTL_TXFIFONUM_SHIFT 22
|
||||
#define DEPCTL_TXFIFONUM_MASK (0xF << 22)
|
||||
#define DEPCTL_STALL (0x1 << 21)
|
||||
#define DEPCTL_TYPE_BIT (18)
|
||||
#define DEPCTL_TYPE_MASK (0x3 << 18)
|
||||
#define DEPCTL_CTRL_TYPE (0x0 << 18)
|
||||
#define DEPCTL_ISO_TYPE (0x1 << 18)
|
||||
#define DEPCTL_BULK_TYPE (0x2 << 18)
|
||||
#define DEPCTL_INTR_TYPE (0x3 << 18)
|
||||
#define DEPCTL_USBACTEP (0x1 << 15)
|
||||
#define DEPCTL_NEXT_EP_BIT (11)
|
||||
#define DEPCTL_NEXT_EP_MASK (0xFU << DEPCTL_NEXT_EP_BIT)
|
||||
#define DEPCTL_MPS_BIT (0)
|
||||
#define DEPCTL_MPS_MASK (0x7FF)
|
||||
|
||||
#define DEPCTL0_MPS_64 (0x0 << 0)
|
||||
#define DEPCTL0_MPS_32 (0x1 << 0)
|
||||
#define DEPCTL0_MPS_16 (0x2 << 0)
|
||||
#define DEPCTL0_MPS_8 (0x3 << 0)
|
||||
#define DEPCTL_MPS_BULK_512 (512 << 0)
|
||||
#define DEPCTL_MPS_INT_MPS_16 (16 << 0)
|
||||
|
||||
#define DIEPCTL0_NEXT_EP_BIT (11)
|
||||
|
||||
/* INEPINT/OUTEPINT device IN/OUT endpoint interrupt register */
|
||||
#define TXFIFO_EMP_INT (0x1 << 7)
|
||||
#define INEP_NAKEFF (0x1 << 6)
|
||||
#define BACK2BACK_SETUP_RECEIVED (0x1 << 6)
|
||||
#define INTKNEPMIS (0x1 << 5)
|
||||
#define INTKN_TXFEMP (0x1 << 4)
|
||||
#define NON_ISO_IN_EP_TIMEOUT (0x1 << 3)
|
||||
#define CTRL_OUT_EP_SETUP_PHASE_DONE (0x1 << 3)
|
||||
#define AHB_ERROR (0x1 << 2)
|
||||
#define EPDISBLD (0x1 << 1)
|
||||
#define TRANSFER_DONE (0x1 << 0)
|
||||
|
||||
/* Masks definitions */
|
||||
#define GINTMSK_INIT (INT_OUT_EP | INT_IN_EP | INT_RESUME | INT_ENUMDONE\
|
||||
| INT_RESET | INT_SUSPEND)
|
||||
#define DOEPMSK_INIT (CTRL_OUT_EP_SETUP_PHASE_DONE |\
|
||||
AHB_ERROR | TRANSFER_DONE)
|
||||
#define DIEPMSK_INIT (NON_ISO_IN_EP_TIMEOUT | AHB_ERROR | TRANSFER_DONE)
|
||||
#define GAHBCFG_INIT (USBDEVINIT_DMA_EN | USBDEVINIT_GLBL_INTR_EN\
|
||||
| (USBDEVINIT_HBSTLEN_INCR4 <<\
|
||||
USBDEVINIT_HBSTLEN_SHIFT))
|
||||
|
||||
/* INEPTSFSIZ/OUTEPTSFSIZ */
|
||||
#define DXEPTSIZ_MULCNT_SHIFT 29
|
||||
#define DXEPTSIZ_MULCNT_MASK (0x3U << DXEPTSIZ_MULCNT_SHIFT)
|
||||
#define DXEPTSIZ_PKT_CNT_SHIFT 19
|
||||
#define DXEPTSIZ_PKT_CNT_MASK (0x3FFU << DXEPTSIZ_PKT_CNT_SHIFT)
|
||||
#define DXEPTSIZ_XFER_SIZE_SHIFT 0
|
||||
#define DXEPTSIZ_XFER_SIZE_MASK (0x7FFFFU << DXEPTSIZ_XFER_SIZE_SHIFT)
|
||||
|
||||
/* Device Endpoint X Transfer Size Register INEPTSFSIZ() */
|
||||
#define DIEPT_SIZ_PKT_CNT(x) (x << 19)
|
||||
#define DIEPT_SIZ_XFER_SIZE(x) (x << 0)
|
||||
|
||||
/* Device OUT Endpoint X Transfer Size Register OUTEPTSFSIZ() */
|
||||
#define DOEPT_SIZ_PKT_CNT(x) (x << 19)
|
||||
#define DOEPT_SIZ_XFER_SIZE(x) (x << 0)
|
||||
#define DOEPT_SIZ_XFER_SIZE_MAX_EP0 (0x7F << 0)
|
||||
#define DOEPT_SIZ_XFER_SIZE_MAX_EP (0x7FFF << 0)
|
||||
|
||||
/* Device Endpoint-N Control Register INEPCFG()/OUTEPCFG() */
|
||||
#define DIEPCTL_TX_FIFO_NUM(x) (x << 22)
|
||||
#define DIEPCTL_TX_FIFO_NUM_MASK (~DIEPCTL_TX_FIFO_NUM(0xF))
|
||||
|
||||
/* Device ALL Endpoints Interrupt Register (USBEPINT) */
|
||||
#define DAINT_IN_EP_INT(x) (x << 0)
|
||||
#define DAINT_OUT_EP_INT(x) (x << 16)
|
||||
|
||||
#define AIC_EP_FIFO_BASE 0x1000UL
|
||||
#define AIC_EP_FIFO_SIZE 0x1000UL
|
||||
|
||||
/* In EPn Txfifo Status (INEPTXSTS) */
|
||||
#define INEPTXSTS_IN_EP_TXFIFO_STS (0xFFFFU << 0)
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,525 @@
|
|||
#include "usbd_core.h"
|
||||
#include "ch585_usbhs_reg.h"
|
||||
|
||||
/**
|
||||
* @brief Related register macro
|
||||
*/
|
||||
#define USB_BASE 0x40009000u
|
||||
#define CH585_USBHS_DEV ((USBHSD_TypeDef *)USB_BASE)
|
||||
|
||||
#ifndef USBD_IRQHandler
|
||||
#define USBD_IRQHandler USB2_DEVICE_IRQHandler //use actual usb irq name instead
|
||||
#endif
|
||||
|
||||
#define R16_PIN_CONFIG (*((PUINT16V)0x4000101A))
|
||||
#define R32_PIN_CONFIG (*((PUINT32V)0x40001018)) // RW, I/O pin configuration
|
||||
#define RB_PIN_USB2_EN 0x20
|
||||
|
||||
#define USB_SET_RX_DMA(ep_idx, addr) (*(volatile uint32_t *)((uint32_t)(&CH585_USBHS_DEV->UEP1_RX_DMA) + 4 * (ep_idx - 1)) = addr)
|
||||
#define USB_SET_TX_DMA(ep_idx, addr) (*(volatile uint32_t *)((uint32_t)(&CH585_USBHS_DEV->UEP1_TX_DMA) + 4 * (ep_idx - 1)) = addr)
|
||||
|
||||
#define USB_SET_MAX_LEN(ep_idx, len) (*(volatile uint16_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_MAX_LEN) + 4 * ep_idx) = len)
|
||||
#define USB_SET_TX_LEN(ep_idx, len) (*(volatile uint16_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_TX_LEN) + 4 * ep_idx) = len)
|
||||
#define USB_GET_TX_LEN(ep_idx) (*(volatile uint16_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_TX_LEN) + 4 * ep_idx))
|
||||
#define USB_SET_TX_CTRL(ep_idx, val) (*(volatile uint8_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_TX_CTRL) + 4 * ep_idx) = val)
|
||||
#define USB_GET_TX_CTRL(ep_idx) (*(volatile uint8_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_TX_CTRL) + 4 * ep_idx))
|
||||
#define USB_SET_RX_CTRL(ep_idx, val) (*(volatile uint8_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_RX_CTRL) + 4 * ep_idx) = val)
|
||||
#define USB_GET_RX_CTRL(ep_idx) (*(volatile uint8_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_RX_CTRL) + 4 * ep_idx))
|
||||
#define EPn_SET_TX_NAK(ep_idx) USB_SET_TX_CTRL(ep_idx, (USB_GET_TX_CTRL(ep_idx) & ~USBHS_UEP_T_RES_MASK) | USBHS_UEP_T_RES_NAK)
|
||||
#define EPn_SET_TX_VALID(ep_idx) USB_SET_TX_CTRL(ep_idx, (USB_GET_TX_CTRL(ep_idx) & ~USBHS_UEP_T_RES_MASK) | USBHS_UEP_T_RES_ACK)
|
||||
#define EPn_SET_RX_NAK(ep_idx) USB_SET_RX_CTRL(ep_idx, (USB_GET_RX_CTRL(ep_idx) & ~USBHS_UEP_R_RES_MASK) | USBHS_UEP_R_RES_NAK)
|
||||
#define EPn_SET_RX_VALID(ep_idx) USB_SET_RX_CTRL(ep_idx, (USB_GET_RX_CTRL(ep_idx) & ~USBHS_UEP_R_RES_MASK) | USBHS_UEP_R_RES_ACK)
|
||||
#define EPn_GET_RX_LEN(ep_idx) (*(volatile uint16_t *)((uint32_t)(&CH585_USBHS_DEV->USB_EP0_RX_LEN) + 4 * ep_idx))
|
||||
#define EPn_SET_TX_LEN(ep_idx, len) (*(volatile uint16_t *)((uint32_t)(&CH585_USBHS_DEV->UEP0_TX_LEN) + 4 * ep_idx) = len)
|
||||
#define EPn_CLEAR_TX_DONE(ep_idx) USB_SET_TX_CTRL(ep_idx, USB_GET_TX_CTRL(ep_idx) & ~USBHS_UEP_T_DONE)
|
||||
#define EPn_CLEAR_RX_DONE(ep_idx) USB_SET_RX_CTRL(ep_idx, USB_GET_RX_CTRL(ep_idx) & ~USBHS_UEP_R_DONE)
|
||||
#define EPn_SET_TX_ISO_VALID(ep_idx)
|
||||
#define EPn_SET_RX_ISO_VALID(ep_idx)
|
||||
|
||||
/* ep nums */
|
||||
#ifndef CONFIG_USBDEV_EP_NUM
|
||||
#define CONFIG_USBDEV_EP_NUM 8
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Endpoint information structure
|
||||
*/
|
||||
typedef struct _usbd_ep_info {
|
||||
uint8_t mps; /* Maximum packet length of endpoint */
|
||||
uint8_t eptype; /* Endpoint Type */
|
||||
uint8_t ep_enable; /* Endpoint enable */
|
||||
uint8_t *xfer_buf;
|
||||
uint32_t xfer_len;
|
||||
uint32_t actual_xfer_len;
|
||||
} usbd_ep_info;
|
||||
|
||||
/* ch58x usb */
|
||||
static struct _ch58x_core_prvi {
|
||||
uint8_t address; /* Address */
|
||||
usbd_ep_info ep_in[CONFIG_USBDEV_EP_NUM];
|
||||
usbd_ep_info ep_out[CONFIG_USBDEV_EP_NUM];
|
||||
struct usb_setup_packet setup;
|
||||
} usb_dc_cfg;
|
||||
|
||||
__WEAK void usb_dc_low_level_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
__WEAK void usb_dc_low_level_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USB initialization
|
||||
* @pre None
|
||||
* @param[in] None
|
||||
* @retval >=0 success otherwise failure
|
||||
*/
|
||||
int usb_dc_init(uint8_t busid)
|
||||
{
|
||||
R8_USBHS_PLL_CTRL = USBHS_PLL_EN;
|
||||
R16_PIN_CONFIG |= RB_PIN_USB2_EN;
|
||||
CH585_USBHS_DEV->CONTROL = USBHS_UD_RST_LINK | USBHS_UD_PHY_SUSPENDM;
|
||||
CH585_USBHS_DEV->INT_EN = USBHS_UDIE_BUS_RST | USBHS_UDIE_SUSPEND | USBHS_UDIE_BUS_SLEEP | USBHS_UDIE_LPM_ACT | USBHS_UDIE_TRANSFER | USBHS_UDIE_LINK_RDY;
|
||||
/* Enable all end points */
|
||||
CH585_USBHS_DEV->UEP_TX_EN = 0xffff;
|
||||
CH585_USBHS_DEV->UEP_RX_EN = 0xffff;
|
||||
|
||||
CH585_USBHS_DEV->BASE_MODE = USBHS_UD_SPEED_HIGH;
|
||||
CH585_USBHS_DEV->CONTROL = USBHS_UD_DEV_EN | USBHS_UD_DMA_EN | USBHS_UD_LPM_EN | USBHS_UD_PHY_SUSPENDM;
|
||||
|
||||
CH585_USBHS_DEV->UEP_T_TOG_AUTO = 0xfe;
|
||||
CH585_USBHS_DEV->UEP_R_TOG_AUTO = 0xfe;
|
||||
usb_dc_low_level_init();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_dc_deinit(uint8_t busid)
|
||||
{
|
||||
R8_USBHS_PLL_CTRL &= ~USBHS_PLL_EN;
|
||||
R32_PIN_CONFIG &= ~RB_PIN_USB2_EN;
|
||||
|
||||
CH585_USBHS_DEV->CONTROL |= USBHS_UD_RST_SIE;
|
||||
CH585_USBHS_DEV->CONTROL &= ~USBHS_UD_RST_SIE;
|
||||
usb_dc_low_level_deinit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set address
|
||||
* @pre None
|
||||
* @param[in] address :8-bit valid address
|
||||
* @retval >=0 success otherwise failure
|
||||
*/
|
||||
int usbd_set_address(uint8_t busid, const uint8_t address)
|
||||
{
|
||||
if (address == 0) {
|
||||
CH585_USBHS_DEV->DEV_AD = (CH585_USBHS_DEV->DEV_AD & 0x80) | address;
|
||||
}
|
||||
usb_dc_cfg.address = address;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_set_remote_wakeup(uint8_t busid)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t usbd_get_port_speed(uint8_t busid)
|
||||
{
|
||||
return USB_SPEED_HIGH;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Open endpoint
|
||||
* @pre None
|
||||
* @param[in] ep_cfg : Endpoint configuration structure pointer
|
||||
* @retval >=0 success otherwise failure
|
||||
*/
|
||||
int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
|
||||
{
|
||||
uint8_t epid = USB_EP_GET_IDX(ep->bEndpointAddress);
|
||||
if (epid > (CONFIG_USBDEV_EP_NUM - 1)) {
|
||||
/**
|
||||
* If you use ch58x, you can change the CONFIG_USBDEV_EP_NUM set to 8
|
||||
*/
|
||||
USB_LOG_ERR("Ep addr %02x overflow\r\n", ep->bEndpointAddress);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
|
||||
USB_SET_MAX_LEN(epid, mps);
|
||||
|
||||
if (USB_EP_DIR_IS_IN(ep->bEndpointAddress)) {
|
||||
usb_dc_cfg.ep_in[epid].ep_enable = true;
|
||||
usb_dc_cfg.ep_in[epid].mps = mps;
|
||||
usb_dc_cfg.ep_in[epid].eptype = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
|
||||
USB_SET_TX_CTRL(epid, USBHS_UEP_T_RES_NAK);
|
||||
EPn_CLEAR_TX_DONE(epid);
|
||||
} else if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) {
|
||||
usb_dc_cfg.ep_out[epid].ep_enable = true;
|
||||
usb_dc_cfg.ep_out[epid].mps = mps;
|
||||
usb_dc_cfg.ep_out[epid].eptype = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
|
||||
USB_SET_RX_CTRL(epid, USBHS_UEP_R_RES_NAK);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Close endpoint
|
||||
* @pre None
|
||||
* @param[in] ep : Endpoint address
|
||||
* @retval >=0 success otherwise failure
|
||||
*/
|
||||
int usbd_ep_close(uint8_t busid, const uint8_t ep)
|
||||
{
|
||||
uint8_t epid = USB_EP_GET_IDX(ep);
|
||||
if (USB_EP_DIR_IS_IN(ep)) {
|
||||
usb_dc_cfg.ep_in[epid].ep_enable = false;
|
||||
} else if (USB_EP_DIR_IS_OUT(ep)) {
|
||||
usb_dc_cfg.ep_out[epid].ep_enable = false;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Endpoint setting stall
|
||||
* @pre None
|
||||
* @param[in] ep : Endpoint address
|
||||
* @retval >=0 success otherwise failure
|
||||
*/
|
||||
int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
|
||||
{
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep);
|
||||
if (USB_EP_DIR_IS_OUT(ep)) {
|
||||
if (ep_idx == 0) {
|
||||
CH585_USBHS_DEV->UEP0_RX_CTRL = USBHS_UEP_R_RES_STALL;
|
||||
} else {
|
||||
USB_SET_RX_CTRL(ep_idx, (USB_GET_RX_CTRL(ep_idx) & ~USBHS_UEP_R_RES_MASK) | USBHS_UEP_R_RES_STALL);
|
||||
}
|
||||
} else {
|
||||
if (ep_idx == 0) {
|
||||
CH585_USBHS_DEV->UEP0_TX_CTRL = USBHS_UEP_T_RES_STALL;
|
||||
} else {
|
||||
USB_SET_TX_CTRL(ep_idx, (USB_GET_TX_CTRL(ep_idx) & ~USBHS_UEP_T_RES_MASK) | USBHS_UEP_T_RES_STALL);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Endpoint clear stall
|
||||
* @pre None
|
||||
* @param[in] ep : Endpoint address
|
||||
* @retval >=0 success otherwise failure
|
||||
*/
|
||||
int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
|
||||
{
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep);
|
||||
|
||||
if (USB_EP_DIR_IS_OUT(ep)) {
|
||||
USB_SET_RX_CTRL(ep_idx, USBHS_UEP_R_RES_ACK | USBHS_UEP_R_TOG_DATA0);
|
||||
} else {
|
||||
USB_SET_TX_CTRL(ep_idx, USBHS_UEP_T_RES_NAK | USBHS_UEP_T_TOG_DATA0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check endpoint status
|
||||
* @pre None
|
||||
* @param[in] ep : Endpoint address
|
||||
* @param[out] stalled : Outgoing endpoint status
|
||||
* @retval >=0 success otherwise failure
|
||||
*/
|
||||
int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
|
||||
{
|
||||
if (USB_EP_DIR_IS_OUT(ep)) {
|
||||
} else {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Setup in ep transfer setting and start transfer.
|
||||
*
|
||||
* This function is asynchronous.
|
||||
* This function is similar to uart with tx dma.
|
||||
*
|
||||
* This function is called to write data to the specified endpoint. The
|
||||
* supplied usbd_endpoint_callback function will be called when data is transmitted
|
||||
* out.
|
||||
*
|
||||
* @param[in] ep Endpoint address corresponding to the one
|
||||
* listed in the device configuration table
|
||||
* @param[in] data Pointer to data to write
|
||||
* @param[in] data_len Length of the data requested to write. This may
|
||||
* be zero for a zero length status packet.
|
||||
* @return 0 on success, negative errno code on fail.
|
||||
*/
|
||||
int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, uint32_t data_len)
|
||||
{
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep);
|
||||
|
||||
if (!data && data_len) {
|
||||
return -1;
|
||||
}
|
||||
if (!usb_dc_cfg.ep_in[ep_idx].ep_enable) {
|
||||
return -2;
|
||||
}
|
||||
if ((uint32_t)data & 0x03) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
usb_dc_cfg.ep_in[ep_idx].xfer_buf = (uint8_t *)data;
|
||||
usb_dc_cfg.ep_in[ep_idx].xfer_len = data_len;
|
||||
usb_dc_cfg.ep_in[ep_idx].actual_xfer_len = 0;
|
||||
|
||||
if (ep_idx == 0) {
|
||||
if (data_len == 0) {
|
||||
USB_SET_TX_LEN(ep_idx, 0);
|
||||
} else {
|
||||
data_len = MIN(data_len, usb_dc_cfg.ep_in[ep_idx].mps);
|
||||
USB_SET_TX_LEN(ep_idx, data_len);
|
||||
CH585_USBHS_DEV->UEP0_DMA = (uint32_t)data;
|
||||
}
|
||||
} else {
|
||||
if (data_len == 0) {
|
||||
USB_SET_TX_LEN(ep_idx, 0);
|
||||
} else {
|
||||
data_len = MIN(data_len, usb_dc_cfg.ep_in[ep_idx].mps);
|
||||
USB_SET_TX_LEN(ep_idx, data_len);
|
||||
USB_SET_TX_DMA(ep_idx, (uint32_t)data);
|
||||
}
|
||||
}
|
||||
|
||||
EPn_SET_TX_VALID(ep_idx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Setup out ep transfer setting and start transfer.
|
||||
*
|
||||
* This function is asynchronous.
|
||||
* This function is similar to uart with rx dma.
|
||||
*
|
||||
* This function is called to read data to the specified endpoint. The
|
||||
* supplied usbd_endpoint_callback function will be called when data is received
|
||||
* in.
|
||||
*
|
||||
* @param[in] ep Endpoint address corresponding to the one
|
||||
* listed in the device configuration table
|
||||
* @param[in] data Pointer to data to read
|
||||
* @param[in] data_len Max length of the data requested to read.
|
||||
*
|
||||
* @return 0 on success, negative errno code on fail.
|
||||
*/
|
||||
int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len)
|
||||
{
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep);
|
||||
|
||||
if (!data && data_len) {
|
||||
return -1;
|
||||
}
|
||||
if (!usb_dc_cfg.ep_out[ep_idx].ep_enable) {
|
||||
return -2;
|
||||
}
|
||||
if ((uint32_t)data & 0x03) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
usb_dc_cfg.ep_out[ep_idx].xfer_buf = (uint8_t *)data;
|
||||
usb_dc_cfg.ep_out[ep_idx].xfer_len = data_len;
|
||||
usb_dc_cfg.ep_out[ep_idx].actual_xfer_len = 0;
|
||||
|
||||
if (ep_idx == 0) {
|
||||
if (data_len == 0) {
|
||||
} else {
|
||||
CH585_USBHS_DEV->UEP0_DMA = (uint32_t)data;
|
||||
}
|
||||
} else {
|
||||
USB_SET_RX_DMA(ep_idx, (uint32_t)data);
|
||||
}
|
||||
|
||||
EPn_SET_RX_VALID(ep_idx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void handle_ep0_in(void)
|
||||
{
|
||||
switch (usb_dc_cfg.setup.bmRequestType >> USB_REQUEST_DIR_SHIFT) {
|
||||
case 1:
|
||||
CH585_USBHS_DEV->UEP0_TX_CTRL ^= USBHS_UEP_T_TOG_DATA1;
|
||||
EPn_SET_TX_NAK(0);
|
||||
if (usb_dc_cfg.ep_in[0].xfer_len > usb_dc_cfg.ep_in[0].mps) {
|
||||
usb_dc_cfg.ep_in[0].xfer_len -= usb_dc_cfg.ep_in[0].mps;
|
||||
usb_dc_cfg.ep_in[0].actual_xfer_len += usb_dc_cfg.ep_in[0].mps;
|
||||
usbd_event_ep_in_complete_handler(0, 0 | 0x80, usb_dc_cfg.ep_in[0].actual_xfer_len);
|
||||
} else {
|
||||
usb_dc_cfg.ep_in[0].actual_xfer_len += usb_dc_cfg.ep_in[0].xfer_len;
|
||||
usb_dc_cfg.ep_in[0].xfer_len = 0;
|
||||
usbd_event_ep_in_complete_handler(0, 0 | 0x80, usb_dc_cfg.ep_in[0].actual_xfer_len);
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
/* Set */
|
||||
switch (usb_dc_cfg.setup.bRequest) {
|
||||
case USB_REQUEST_SET_ADDRESS:
|
||||
/* Fill in the equipment address */
|
||||
CH585_USBHS_DEV->DEV_AD = usb_dc_cfg.address;
|
||||
CH585_USBHS_DEV->UEP0_DMA = (uint32_t)&usb_dc_cfg.setup;
|
||||
EPn_SET_TX_NAK(0);
|
||||
EPn_SET_RX_VALID(0);
|
||||
break;
|
||||
default:
|
||||
/* Normal out state phase */
|
||||
CH585_USBHS_DEV->UEP0_DMA = (uint32_t)&usb_dc_cfg.setup;
|
||||
EPn_SET_TX_NAK(0);
|
||||
EPn_SET_RX_VALID(0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void handle_non_ep0_in(uint8_t epid)
|
||||
{
|
||||
EPn_SET_TX_NAK(epid);
|
||||
if (usb_dc_cfg.ep_in[epid].xfer_len > usb_dc_cfg.ep_in[epid].mps) {
|
||||
/* Need start in again */
|
||||
usb_dc_cfg.ep_in[epid].xfer_buf += usb_dc_cfg.ep_in[epid].mps;
|
||||
usb_dc_cfg.ep_in[epid].xfer_len -= usb_dc_cfg.ep_in[epid].mps;
|
||||
usb_dc_cfg.ep_in[epid].actual_xfer_len += usb_dc_cfg.ep_in[epid].mps;
|
||||
|
||||
uint32_t write_count = MIN(usb_dc_cfg.ep_in[epid].xfer_len, usb_dc_cfg.ep_in[epid].mps);
|
||||
USB_SET_TX_LEN(epid, write_count);
|
||||
USB_SET_TX_DMA(epid, (uint32_t)usb_dc_cfg.ep_in[epid].xfer_buf);
|
||||
|
||||
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;
|
||||
usbd_event_ep_in_complete_handler(0, epid | 0x80, usb_dc_cfg.ep_in[epid].actual_xfer_len);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void usb_process_ep_in(uint8_t epid)
|
||||
{
|
||||
if (epid == 0) {
|
||||
handle_ep0_in();
|
||||
} else {
|
||||
handle_non_ep0_in(epid);
|
||||
}
|
||||
|
||||
EPn_CLEAR_TX_DONE(epid);
|
||||
}
|
||||
|
||||
static inline void usb_process_ep_out(uint8_t epid)
|
||||
{
|
||||
EPn_SET_RX_NAK(epid);
|
||||
if (epid == 0) {
|
||||
if (CH585_USBHS_DEV->UEP0_RX_CTRL & USBHS_UEP_R_SETUP_IS) {
|
||||
CH585_USBHS_DEV->UEP0_RX_CTRL |= USBHS_UEP_R_TOG_DATA1;
|
||||
CH585_USBHS_DEV->UEP0_TX_CTRL |= USBHS_UEP_T_TOG_DATA1;
|
||||
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
|
||||
*/
|
||||
EPn_SET_TX_LEN(0, 0);
|
||||
EPn_SET_TX_VALID(0);
|
||||
}
|
||||
usbd_event_ep0_setup_complete_handler(0, (uint8_t *)&usb_dc_cfg.setup);
|
||||
} else {
|
||||
CH585_USBHS_DEV->UEP0_RX_CTRL ^= USBHS_UEP_R_TOG_DATA1;
|
||||
uint32_t read_count = EPn_GET_RX_LEN(0);
|
||||
usb_dc_cfg.ep_out[0].actual_xfer_len += read_count;
|
||||
usb_dc_cfg.ep_out[0].xfer_len -= read_count;
|
||||
usbd_event_ep_out_complete_handler(0, 0x00, usb_dc_cfg.ep_out[0].actual_xfer_len);
|
||||
if (read_count == 0) {
|
||||
/* Out status, start reading setup */
|
||||
CH585_USBHS_DEV->UEP0_DMA = (uint32_t)&usb_dc_cfg.setup;
|
||||
EPn_SET_RX_VALID(0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (USB_GET_RX_CTRL(epid) & USBHS_UEP_R_TOG_MATCH) {
|
||||
uint32_t read_count = EPn_GET_RX_LEN(epid);
|
||||
usb_dc_cfg.ep_out[epid].xfer_buf += read_count;
|
||||
usb_dc_cfg.ep_out[epid].actual_xfer_len += read_count;
|
||||
usb_dc_cfg.ep_out[epid].xfer_len -= read_count;
|
||||
|
||||
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(0, ((epid) & 0x7f), usb_dc_cfg.ep_out[epid].actual_xfer_len);
|
||||
} else {
|
||||
USB_SET_RX_DMA(epid, (uint32_t)usb_dc_cfg.ep_out[epid].xfer_buf);
|
||||
if (usb_dc_cfg.ep_out[epid].eptype != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
|
||||
EPn_SET_RX_VALID(epid);
|
||||
} else {
|
||||
EPn_SET_RX_ISO_VALID(epid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EPn_CLEAR_RX_DONE(epid);
|
||||
}
|
||||
|
||||
static inline void usb_trans_end_process(void)
|
||||
{
|
||||
uint8_t epid = (CH585_USBHS_DEV->INT_ST & USBHS_UDIS_EP_ID_MASK);
|
||||
switch (CH585_USBHS_DEV->INT_ST & USBHS_UDIS_EP_DIR) {
|
||||
case USBHS_UDIS_EP_DIR: /* in */
|
||||
usb_process_ep_in(epid);
|
||||
break;
|
||||
case 0: /* setup or out */
|
||||
usb_process_ep_out(epid);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USB interrupt processing function
|
||||
* @pre None
|
||||
* @param[in] None
|
||||
* @retval None
|
||||
*/
|
||||
__attribute__((interrupt("WCH-Interrupt-fast")))
|
||||
__attribute__((section(".highcode"))) void
|
||||
USBD_IRQHandler(void)
|
||||
{
|
||||
volatile uint8_t intflag = 0;
|
||||
intflag = CH585_USBHS_DEV->INT_FG;
|
||||
|
||||
if (intflag & USBHS_UDIF_TRANSFER) {
|
||||
usb_trans_end_process();
|
||||
} else if (intflag & USBHS_UDIF_BUS_RST) {
|
||||
/* Reset */
|
||||
CH585_USBHS_DEV->DEV_AD = 0;
|
||||
usbd_event_reset_handler(0);
|
||||
/* Set ep0 rx vaild to start receive setup packet */
|
||||
CH585_USBHS_DEV->UEP0_DMA = (uint32_t)&usb_dc_cfg.setup;
|
||||
// EPn_SET_RX_VALID(0);
|
||||
R8_U2EP0_TX_CTRL = USBHS_UEP_T_RES_NAK;
|
||||
R8_U2EP0_RX_CTRL = USBHS_UEP_R_RES_ACK;
|
||||
CH585_USBHS_DEV->INT_FG = USBHS_UDIF_BUS_RST;
|
||||
} else if (intflag & USBHS_UDIF_SUSPEND) {
|
||||
if (CH585_USBHS_DEV->MIS_ST & 0x04) {
|
||||
/* Suspend */
|
||||
} else {
|
||||
/* Wake up */
|
||||
}
|
||||
CH585_USBHS_DEV->INT_FG = USBHS_UDIF_SUSPEND;
|
||||
} else {
|
||||
CH585_USBHS_DEV->INT_FG = intflag;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,450 @@
|
|||
#pragma once
|
||||
|
||||
/**********************************/
|
||||
/*********USB high speed**********/
|
||||
/**********************************/
|
||||
typedef volatile unsigned short *PUINT16V;
|
||||
typedef volatile unsigned long *PUINT32V;
|
||||
typedef volatile unsigned char *PUINT8V;
|
||||
|
||||
/* USB high speed device register */
|
||||
#define R8_USB2_CTRL (*((PUINT8V)0x40009000)) // RW, USB_high_speed control register
|
||||
#define USBHS_UD_LPM_EN 0x80 // RW, enable LPM
|
||||
#define USBHS_UD_DEV_EN 0x20 // RW, enable USB equipment
|
||||
#define USBHS_UD_DMA_EN 0x10 // RW, enable DMA transmit
|
||||
#define USBHS_UD_PHY_SUSPENDM 0x08 // RW, suspeng USB PHY
|
||||
#define USBHS_UD_CLR_ALL 0x04 // RW, clear all interupt flag
|
||||
#define USBHS_UD_RST_SIE 0x02 // RW, reset USB protocol processor,including end point register
|
||||
#define USBHS_UD_RST_LINK 0x01 // RW, enable LNK layer reset
|
||||
#define R8_USB2_BASE_MODE (*((PUINT8V)0x40009001)) // RW, USB_high_speed mode control register
|
||||
#define USBHS_UD_SPEED_FULL 0x00
|
||||
#define USBHS_UD_SPEED_HIGH 0x01
|
||||
#define USBHS_UD_SPEED_LOW 0x02
|
||||
#define USBHS_UD_SPEED_TYPE 0x03 // RW, speed mode excpeted by the equipment,00:full speed, 01:high speed, 10:low speed
|
||||
#define R8_USB2_INT_EN (*((PUINT8V)0x40009002)) // RW, USB_high_speed intreurpt enable register
|
||||
#define USBHS_UDIE_FIFO_OVER 0x80 // RW, enable fifo overflow interupt
|
||||
#define USBHS_UDIE_LINK_RDY 0x40 // RW, enable USB conect interupt
|
||||
#define USBHS_UDIE_SOF_ACT 0x20 // RW, enable SOF package received interupt
|
||||
#define USBHS_UDIE_TRANSFER 0x10 // RW, enable USB transmit end interupt
|
||||
#define USBHS_UDIE_LPM_ACT 0x08 // RW, enable lpm transmit end interupt
|
||||
#define USBHS_UDIE_BUS_SLEEP 0x04 // RW, enable usb bus sleep interupt
|
||||
#define USBHS_UDIE_SUSPEND 0x02 // RW, enable usb bus suspend interupt
|
||||
#define USBHS_UDIE_BUS_RST 0x01 // RW, enable usb bus reset interupt
|
||||
#define R8_USB2_DEV_AD (*((PUINT8V)0x40009003)) // RW, USB_high_speed device adress register
|
||||
#define USBHS_UD_DEV_ADDR 0x7F // RW, adress of usb equipment
|
||||
#define R8_USB2_WAKE_CTRL (*((PUINT8V)0x40009004)) // RW, USB_high_speed wake up remotely register
|
||||
#define USBHS_UD_UD_REMOTE_WKUP 0x01 // RW1, wake up remotely and auto reset hardware
|
||||
#define R8_USB2_TEST_MODE (*((PUINT8V)0x40009005)) // RW, USB_high_speed test mode register
|
||||
#define USBHS_UD_TEST_EN 0x80 // RW, enable test mode
|
||||
#define USBHS_UD_TEST_SE0NAK 0x08 // RW, output SE0 when in test mode
|
||||
#define USBHS_UD_TEST_PKT 0x04 // RW, output one package(including DATA0,data and length of end pont4) when in test mode,not work on virtual equipment
|
||||
#define USBHS_UD_TEST_K 0x02 // RW, output K when in test mode
|
||||
#define USBHS_UD_TEST_J 0x01 // RW, output J when in test mode
|
||||
#define R16_USB2_LPM_DATA (*((PUINT16V)0x40009006)) // RW, USB_high_speed power control register
|
||||
#define USBHS_UD_LPM_BUSY 0x8000 // RW, power control busy
|
||||
#define USBHS_UD_LPM_DATA 0x07FF // RO, power control data
|
||||
#define R8_USB2_INT_FG (*((PUINT8V)0x40009008)) // RW, USB_high_speed interupt flag register
|
||||
#define USBHS_UDIF_FIFO_OV 0x80 // RW1, clear fifo overflow interupt flag
|
||||
#define USBHS_UDIF_LINK_RDY 0x40 // RW1, clear USB conect interupt flag
|
||||
#define USBHS_UDIF_RX_SOF 0x20 // RW1, clear SOF package received interupt flag
|
||||
#define USBHS_UDIF_TRANSFER 0x10 // RO, USB transmit end interupt flag,cleared by USBHS_UDMS_HS_MOD
|
||||
#define USBHS_UDIF_LPM_ACT 0x08 // RW1, clear lpm transmit end interupt flag
|
||||
#define USBHS_UDIF_BUS_SLEEP 0x04 // RW1, clear usb bus sleep interupt flag
|
||||
#define USBHS_UDIF_SUSPEND 0x02 // RW1, clear usb bus suspend interupt flag
|
||||
#define USBHS_UDIF_BUS_RST 0x01 // RW1, clear usb bus reset interupt flag
|
||||
#define R8_USB2_INT_ST (*((PUINT8V)0x40009009)) // RW, USB_high_speed interupt status register
|
||||
#define USBHS_UDIS_EP_DIR 0x10 // RO, end point tranfer diector of data
|
||||
#define USBHS_UDIS_EP_ID_MASK 0x07 // RO, number of end point which data transmission occured
|
||||
#define R8_USB2_MIS_ST (*((PUINT8V)0x4000900A)) // RW, USB_high_speed miscellaneous register
|
||||
#define USBHS_UDMS_HS_MOD 0x80 // RO, host with high speed
|
||||
#define USBHS_UDMS_SUSP_REQ 0x10 // RO, requirment of suspending USB
|
||||
#define USBHS_UDMS_SIE_FREE 0x08 // RO, USB free state
|
||||
#define USBHS_UDMS_SLEEP 0x04 // RO, USB sleep state
|
||||
#define USBHS_UDMS_SUSPEND 0x02 // RO, USB in suspend state
|
||||
#define USBHS_UDMS_READY 0x01 // RO, USB in connected state
|
||||
#define R16_USB2_FRAME_NO (*((PUINT16V)0x4000900C)) // RW, USB_high_speed frame number register
|
||||
#define USBHS_UD_MFRAME_NO 0xE000
|
||||
#define USBHS_UD_FRAME_NO 0x07FF
|
||||
#define R16_USB2_BUS (*((PUINT16V)0x4000900E)) // RW, USB_high_speed bus status register
|
||||
#define USBHS_USB_DM_ST 0x08
|
||||
#define USBHS_USB_DP_ST 0x04
|
||||
#define USB_WAKEUP 0x01
|
||||
#define R16_U2EP_TX_EN (*((PUINT16V)0x40009010)) // RW, USB_high_speed end point transmit enable register
|
||||
/* Bit definition for R16_U2EP_TX_EN & R16_U2EP_RX_EN register */
|
||||
#define RB_EP0_EN 0x0001
|
||||
#define RB_EP1_EN 0x0002
|
||||
#define RB_EP2_EN 0x0004
|
||||
#define RB_EP3_EN 0x0008
|
||||
#define RB_EP4_EN 0x0010
|
||||
#define RB_EP5_EN 0x0020
|
||||
#define RB_EP6_EN 0x0040
|
||||
#define RB_EP7_EN 0x0080
|
||||
#define RB_EP8_EN 0x0100
|
||||
#define RB_EP9_EN 0x0200
|
||||
#define RB_EP10_EN 0x0400
|
||||
#define RB_EP11_EN 0x0800
|
||||
#define RB_EP12_EN 0x1000
|
||||
#define RB_EP13_EN 0x2000
|
||||
#define RB_EP14_EN 0x4000
|
||||
#define RB_EP15_EN 0x8000
|
||||
|
||||
#define R16_U2EP_RX_EN (*((PUINT16V)0x40009012)) // RW, USB_high_speed end point receive enableregister
|
||||
#define USBHS_UEP_RX_EN 0xFFFF
|
||||
#define R16_U2EP_T_TOG_AUTO (*((PUINT16V)0x40009014)) // RW, USB_high_speed end point transmit auto toggle enable register
|
||||
#define USBHS_UEP_T_TOG_AUTO 0xFF
|
||||
#define R16_U2EP_R_TOG_AUTO (*((PUINT16V)0x40009016)) // RW, USB_high_speed end point receive auto toggle enable register
|
||||
#define USBHS_UEP_R_TOG_AUTO 0xFF
|
||||
#define R8_U2EP_T_BURST (*((PUINT8V)0x40009018)) // RW, USB_high_speed end point transmit burst register
|
||||
#define USBHS_UEP_T_BURST_EN 0xFF
|
||||
#define R8_U2EP_T_BURST_MODE (*((PUINT8V)0x40009019)) // RW, USB_high_speed end point transmit burst mode register
|
||||
#define USBHS_UEP_T_BURST_MODE 0xFF
|
||||
#define R8_U2EP_R_BURST (*((PUINT8V)0x4000901A)) // RW, USB_high_speed end point receive burst register
|
||||
#define USBHS_UEP_R_BURST_EN 0xFF
|
||||
#define R8_U2EP_R_RES_MODE (*((PUINT8V)0x4000901B)) // RW, USB_high_speed end point transmit reply mode register
|
||||
#define USBHS_UEP_R_RES_MODE 0xFF
|
||||
#define R32_U2EP_AF_MODE (*((PUINT32V)0x4000901C)) // RW, USB_high_speed end point multiplexing register
|
||||
#define USBHS_UEP_T_AF 0xFE
|
||||
#define R32_U2EP0_DMA (*((PUINT32V)0x40009020)) // RW, USB_high_speed end point0 begin adress of DMA buffer register
|
||||
#define UEPn_DMA 0x01FFFF
|
||||
#define R32_U2EP1_RX_DMA (*((PUINT32V)0x40009024)) // RW, USB_high_speed end point1 begin adress of DMA receive buffer register
|
||||
#define R32_U2EP2_RX_DMA (*((PUINT32V)0x40009028)) // RW, USB_high_speed end point2 begin adress of DMA receive buffer register
|
||||
#define R32_U2EP3_RX_DMA (*((PUINT32V)0x4000902C)) // RW, USB_high_speed end point3 begin adress of DMA receive buffer register
|
||||
#define R32_U2EP4_RX_DMA (*((PUINT32V)0x40009030)) // RW, USB_high_speed end point4 begin adress of DMA receive buffer register
|
||||
#define R32_U2EP5_RX_DMA (*((PUINT32V)0x40009034)) // RW, USB_high_speed end point5 begin adress of DMA receive buffer register
|
||||
#define R32_U2EP6_RX_DMA (*((PUINT32V)0x40009038)) // RW, USB_high_speed end point6 begin adress of DMA receive buffer register
|
||||
#define R32_U2EP7_RX_DMA (*((PUINT32V)0x4000903C)) // RW, USB_high_speed end point7 begin adress of DMA receive buffer register
|
||||
#define UEPn_RX_DMA 0x01FFFF
|
||||
#define R32_U2EP1_TX_DMA (*((PUINT32V)0x40009040)) // RW, USB_high_speed end point1 begin adress of DMA transmit buffer register
|
||||
#define R32_U2EP2_TX_DMA (*((PUINT32V)0x40009044)) // RW, USB_high_speed end point2 begin adress of DMA transmit buffer register
|
||||
#define R32_U2EP3_TX_DMA (*((PUINT32V)0x40009048)) // RW, USB_high_speed end point3 begin adress of DMA transmit buffer register
|
||||
#define R32_U2EP4_TX_DMA (*((PUINT32V)0x4000904C)) // RW, USB_high_speed end point4 begin adress of DMA transmit buffer register
|
||||
#define R32_U2EP5_TX_DMA (*((PUINT32V)0x40009050)) // RW, USB_high_speed end point5 begin adress of DMA transmit buffer register
|
||||
#define R32_U2EP6_TX_DMA (*((PUINT32V)0x40009054)) // RW, USB_high_speed end point6 begin adress of DMA transmit buffer register
|
||||
#define R32_U2EP7_TX_DMA (*((PUINT32V)0x40009058)) // RW, USB_high_speed end point7 begin adress of DMA transmit buffer register
|
||||
#define UEPn_TX_DMA 0x01FFFF
|
||||
#define R32_U2EP0_MAX_LEN (*((PUINT32V)0x4000905C)) // RW, USB_high_speed end point0 max length package register
|
||||
#define R32_U2EP1_MAX_LEN (*((PUINT32V)0x40009060)) // RW, USB_high_speed end point1 max length package register
|
||||
#define R32_U2EP2_MAX_LEN (*((PUINT32V)0x40009064)) // RW, USB_high_speed end point2 max length package register
|
||||
#define R32_U2EP3_MAX_LEN (*((PUINT32V)0x40009068)) // RW, USB_high_speed end point3 max length package register
|
||||
#define R32_U2EP4_MAX_LEN (*((PUINT32V)0x4000906C)) // RW, USB_high_speed end point4 max length package register
|
||||
#define R32_U2EP5_MAX_LEN (*((PUINT32V)0x40009070)) // RW, USB_high_speed end point5 max length package register
|
||||
#define R32_U2EP6_MAX_LEN (*((PUINT32V)0x40009074)) // RW, USB_high_speed end point6 max length package register
|
||||
#define R32_U2EP7_MAX_LEN (*((PUINT32V)0x40009078)) // RW, USB_high_speed end point7 max length package register
|
||||
#define UEPn_MAX_LEN 0x007F
|
||||
#define R16_U2EP0_RX_LEN (*((PUINT16V)0x4000907C)) // RW, USB_high_speed end point0 length of receive register
|
||||
#define UEP0_RX_LEN 0x007F
|
||||
#define R16_U2EP1_RX_LEN (*((PUINT16V)0x40009080)) // RW, USB_high_speed end point1 single received length register
|
||||
#define R16_U2EP1_R_SIZE (*((PUINT16V)0x40009082)) // RW, USB_high_speed end point1 total received length register
|
||||
#define R16_U2EP2_RX_LEN (*((PUINT16V)0x40009084)) // RW, USB_high_speed end point2 single received length register
|
||||
#define R16_U2EP2_R_SIZE (*((PUINT16V)0x40009086)) // RW, USB_high_speed end point2 total received length register
|
||||
#define R16_U2EP3_RX_LEN (*((PUINT16V)0x40009088)) // RW, USB_high_speed end point3 single received length register
|
||||
#define R16_U2EP3_R_SIZE (*((PUINT16V)0x4000908A)) // RW, USB_high_speed end point3 total received length register
|
||||
#define R16_U2EP4_RX_LEN (*((PUINT16V)0x4000908C)) // RW, USB_high_speed end point4 single received length register
|
||||
#define R16_U2EP4_R_SIZE (*((PUINT16V)0x4000908E)) // RW, USB_high_speed end point4 total received length register
|
||||
#define R16_U2EP5_RX_LEN (*((PUINT16V)0x40009090)) // RW, USB_high_speed end point5 single received length register
|
||||
#define R16_U2EP5_R_SIZE (*((PUINT16V)0x40009092)) // RW, USB_high_speed end point5 total received length register
|
||||
#define R16_U2EP6_RX_LEN (*((PUINT16V)0x40009094)) // RW, USB_high_speed end point6 single received length register
|
||||
#define R16_U2EP6_R_SIZE (*((PUINT16V)0x40009096)) // RW, USB_high_speed end point6 total received length register
|
||||
#define R16_U2EP7_RX_LEN (*((PUINT16V)0x40009098)) // RW, USB_high_speed end point7 single received length register
|
||||
#define R16_U2EP7_R_SIZE (*((PUINT16V)0x4000909A)) // RW, USB_high_speed end point7 total received length register
|
||||
#define UEPn_RX_LEN 0xFFFF
|
||||
#define UEPn_R_SIZE 0xFFFF
|
||||
#define R16_U2EP0_T_LEN (*((PUINT16V)0x4000909C)) // RW, USB_high_speed end point0 length of transmission register
|
||||
#define UEP0_T_LEN 0x7F
|
||||
#define R8_U2EP0_TX_CTRL (*((PUINT8V)0x4000909E)) // RW, USB_high_speed end point0 transmit control register
|
||||
#define R8_U2EP0_RX_CTRL (*((PUINT8V)0x4000909F)) // RW, USB_high_speed end point0 receive control register
|
||||
#define R16_U2EP1_T_LEN (*((PUINT16V)0x400090A0)) // RW, USB_high_speed end point1 length of transmission register
|
||||
#define R8_U2EP1_TX_CTRL (*((PUINT8V)0x400090A2)) // RW, USB_high_speed end point1 transmit control register
|
||||
#define R8_U2EP1_RX_CTRL (*((PUINT8V)0x400090A3)) // RW, USB_high_speed end point1 receive control register
|
||||
#define R16_U2EP2_T_LEN (*((PUINT16V)0x400090A4)) // RW, USB_high_speed end point2 length of transmission register
|
||||
#define R8_U2EP2_TX_CTRL (*((PUINT8V)0x400090A6)) // RW, USB_high_speed end point2 transmit control register
|
||||
#define R8_U2EP2_RX_CTRL (*((PUINT8V)0x400090A7)) // RW, USB_high_speed end point2 receive control register
|
||||
#define R16_U2EP3_T_LEN (*((PUINT16V)0x400090A8)) // RW, USB_high_speed end point3 length of transmission register
|
||||
#define R8_U2EP3_TX_CTRL (*((PUINT8V)0x400090AA)) // RW, USB_high_speed end point3 transmit control register
|
||||
#define R8_U2EP3_RX_CTRL (*((PUINT8V)0x400090AB)) // RW, USB_high_speed end point3 receive control register
|
||||
#define R16_U2EP4_T_LEN (*((PUINT16V)0x400090AC)) // RW, USB_high_speed end point4 length of transmission register
|
||||
#define R8_U2EP4_TX_CTRL (*((PUINT8V)0x400090AE)) // RW, USB_high_speed end point4 transmit control register
|
||||
#define R8_U2EP4_RX_CTRL (*((PUINT8V)0x400090AF)) // RW, USB_high_speed end point4 receive control register
|
||||
#define R16_U2EP5_T_LEN (*((PUINT16V)0x400090B0)) // RW, USB_high_speed end point5 length of transmission register
|
||||
#define R8_U2EP5_TX_CTRL (*((PUINT8V)0x400090B2)) // RW, USB_high_speed end point5 transmit control register
|
||||
#define R8_U2EP5_RX_CTRL (*((PUINT8V)0x400090B3)) // RW, USB_high_speed end point5 receive control register
|
||||
#define R16_U2EP6_T_LEN (*((PUINT16V)0x400090B4)) // RW, USB_high_speed end point6 length of transmission register
|
||||
#define R8_U2EP6_TX_CTRL (*((PUINT8V)0x400090B6)) // RW, USB_high_speed end point6 transmit control register
|
||||
#define R8_U2EP6_RX_CTRL (*((PUINT8V)0x400090B7)) // RW, USB_high_speed end point6 receive control register
|
||||
#define R16_U2EP7_T_LEN (*((PUINT16V)0x400090B8)) // RW, USB_high_speed end point7 length of transmission register
|
||||
#define R8_U2EP7_TX_CTRL (*((PUINT8V)0x400090BA)) // RW, USB_high_speed end point7 transmit control register
|
||||
#define R8_U2EP7_RX_CTRL (*((PUINT8V)0x400090BB)) // RW, USB_high_speed end point7 receive control register
|
||||
/**R16_UEPn_T_LEN**/
|
||||
#define UEPn_T_LEN 0xFFFF
|
||||
/**R8_UEPn_TX_CTRL**/
|
||||
#define USBHS_UEP_T_DONE 0x80
|
||||
#define USBHS_UEP_T_NAK_ACT 0x40
|
||||
#define USBHS_UEP_T_TOG_MASK 0x0C
|
||||
#define USBHS_UEP_T_TOG_MDATA 0x0C
|
||||
#define USBHS_UEP_T_TOG_DATA2 0x08
|
||||
#define USBHS_UEP_T_TOG_DATA1 0x04
|
||||
#define USBHS_UEP_T_TOG_DATA0 0x00
|
||||
#define USBHS_UEP_T_RES_MASK 0x03
|
||||
#define USBHS_UEP_T_RES_ACK 0x02
|
||||
#define USBHS_UEP_T_RES_STALL 0x01
|
||||
#define USBHS_UEP_T_RES_NAK 0x00
|
||||
|
||||
/**R8_UEPn_RX_CTRL**/
|
||||
#define USBHS_UEP_R_DONE 0x80
|
||||
#define USBHS_UEP_R_NAK_ACT 0x40
|
||||
#define USBHS_UEP_R_NAK_TOG 0x20
|
||||
#define USBHS_UEP_R_TOG_MATCH 0x10
|
||||
#define USBHS_UEP_R_SETUP_IS 0x08
|
||||
#define USBHS_UEP_R_TOG_MASK 0x0C
|
||||
#define USBHS_UEP_R_TOG_MDATA 0x0C
|
||||
#define USBHS_UEP_R_TOG_DATA2 0x08
|
||||
#define USBHS_UEP_R_TOG_DATA1 0x04
|
||||
#define USBHS_UEP_R_TOG_DATA0 0x00
|
||||
#define USBHS_UEP_R_RES_MASK 0x03
|
||||
#define USBHS_UEP_R_RES_ACK 0x02
|
||||
#define USBHS_UEP_R_RES_STALL 0x01
|
||||
#define USBHS_UEP_R_RES_NAK 0x00
|
||||
|
||||
#define R16_U2EP_T_ISO (*((PUINT16V)0x400090BC)) // RW, USB_high_speed end point transmit sync mode register
|
||||
#define USBHS_UEP1_T_ISO_EN 0x02
|
||||
#define USBHS_UEP2_T_ISO_EN 0x04
|
||||
#define USBHS_UEP3_T_ISO_EN 0x08
|
||||
#define USBHS_UEP4_T_ISO_EN 0x10
|
||||
#define USBHS_UEP5_T_ISO_EN 0x20
|
||||
#define USBHS_UEP6_T_ISO_EN 0x40
|
||||
#define USBHS_UEP7_T_ISO_EN 0x80
|
||||
#define R16_U2EP_R_ISO (*((PUINT16V)0x400090BE)) // RW, USB_high_speed end point receive sync mode register
|
||||
#define USBHS_UEP1_R_ISO_EN 0x02
|
||||
#define USBHS_UEP2_R_ISO_EN 0x04
|
||||
#define USBHS_UEP3_R_ISO_EN 0x08
|
||||
#define USBHS_UEP4_R_ISO_EN 0x10
|
||||
#define USBHS_UEP5_R_ISO_EN 0x20
|
||||
#define USBHS_UEP6_R_ISO_EN 0x40
|
||||
#define USBHS_UEP7_R_ISO_EN 0x80
|
||||
|
||||
/* USB high speed host register */
|
||||
#define R8_U2H_CFG (*((PUINT8V)0x40009100)) // RW, USB_high_speed register
|
||||
#define USBHS_UH_LPM_EN 0x80
|
||||
#define USBHS_UH_FORCE_FS 0x40
|
||||
#define USBHS_UH_SOF_EN 0x20
|
||||
#define USBHS_UH_DMA_EN 0x10
|
||||
#define USBHS_UH_PHY_SUSPENDM 0x08
|
||||
#define USBHS_UH_CLR_ALL 0x04
|
||||
#define USBHS_RST_SIE 0x02
|
||||
#define USBHS_RST_LINK 0x01
|
||||
#define R8_U2H_INT_EN (*((PUINT8V)0x40009102)) // RW, USB_high_speed register
|
||||
#define USBHS_UHIE_FIFO_OVER 0x80
|
||||
#define USBHS_UHIE_TX_HALT 0x40
|
||||
#define USBHS_UHIE_SOF_ACT 0x20
|
||||
#define USBHS_UHIE_TRANSFER 0x10
|
||||
#define USBHS_UHIE_RESUME_ACT 0x08
|
||||
#define USBHS_UHIE_WKUP_ACT 0x04
|
||||
#define R8_U2H_DEV_AD (*((PUINT8V)0x40009103)) // RW, USB_high_speed register
|
||||
#define USBHS_UH_DEV_ADDR 0xFF
|
||||
#define R32_U2H_CONTROL (*((PUINT32V)0x40009104)) // RW, USB_high_speed register
|
||||
#define USBHS_UH_RX_NO_RES 0x800000
|
||||
#define USBHS_UH_TX_NO_RES 0x400000
|
||||
#define USBHS_UH_RX_NO_DATA 0x200000
|
||||
#define USBHS_UH_TX_NO_DATA 0x100000
|
||||
#define USBHS_UH_PRE_PID_EN 0x080000
|
||||
#define USBHS_UH_SPLIT_VALID 0x040000
|
||||
#define USBHS_UH_LPM_VALID 0x020000
|
||||
#define USBHS_UH_HOST_ACTION 0x010000
|
||||
#define USBHS_UH_BUF_MODE 0x0400
|
||||
#define USBHS_UH_T_TOG_MASK 0x0300
|
||||
#define USBHS_UH_T_TOG_MDATA 0x0300
|
||||
#define USBHS_UH_T_TOG_DATA2 0x0200
|
||||
#define USBHS_UH_T_TOG_DATA1 0x0100
|
||||
#define USBHS_UH_T_TOG_DATA0 0x0000
|
||||
#define USBHS_UH_T_ENDP_MASK 0xF0
|
||||
#define USBHS_UH_T_TOKEN_MASK 0x0F
|
||||
|
||||
#define R8_U2H_INT_FLAG (*((PUINT8V)0x40009108)) // RW, USB_high_speed register
|
||||
#define USBHS_UHIF_FIFO_OVER 0x80
|
||||
#define USBHS_UHIF_TX_HALT 0x40
|
||||
#define USBHS_UHIF_SOF_ACT 0x20
|
||||
#define USBHS_UHIF_TRANSFER 0x10
|
||||
#define USBHS_UHIF_RESUME_ACT 0x08
|
||||
#define USBHS_UHIF_WKUP_ACT 0x04
|
||||
#define R8_U2H_INT_ST (*((PUINT8V)0x40009109)) // RW, USB_high_speed register
|
||||
#define USBHS_UHIF_PORT_RX_RESUME 0x10
|
||||
#define USBHS_UH_R_TOKEN_MASK 0x0F
|
||||
#define R8_U2H_MIS_ST (*((PUINT8V)0x4000910A)) // RW, USB_high_speed register
|
||||
#define USBHS_UHMS_BUS_SE0 0x80
|
||||
#define USBHS_UHMS_BUS_J 0x40
|
||||
#define USBHS_UHMS_LINESTATE 0x30
|
||||
#define USBHS_UHMS_USB_WAKEUP 0x08
|
||||
#define USBHS_UHMS_SOF_ACT 0x04
|
||||
#define USBHS_UHMS_SOF_PRE 0x02
|
||||
#define USBHS_UHMS_SOF_FREE 0x01
|
||||
#define R32_U2H_LPM_DATA (*((PUINT32V)0x4000910C)) // RW, USB_high_speed register
|
||||
#define USBHS_UH_LPM_DATA 0x07FF
|
||||
#define R32_U2H_SPLIT_DATA (*((PUINT32V)0x40009110)) // RW, USB_high_speed register
|
||||
#define USBHS_UH_SPLIT_DATA 0x07FFFF
|
||||
#define R32_U2H_FRAME (*((PUINT32V)0x40009114)) // RW, USB_high_speed register
|
||||
#define USBHS_UH_SOF_CNT_CLR 0x02000000
|
||||
#define USBHS_UH_SOF_CNT_EN 0x01000000
|
||||
#define USBHS_UH_MFRAME_NO 0x070000
|
||||
#define USBHS_UH_FRAME_NO 0x07FF
|
||||
#define R32_U2H_TX_LEN (*((PUINT32V)0x40009118)) // RW, USB_high_speed register
|
||||
#define USBHS_UH_TX_LEN 0x07FF
|
||||
#define R32_U2H_RX_LEN (*((PUINT32V)0x4000911C)) // RW, USB_high_speed register
|
||||
#define USBHS_UH_RX_LEN 0x07FF
|
||||
#define R32_U2H_RX_MAX_LEN (*((PUINT32V)0x40009120)) // RW, USB_high_speed register
|
||||
#define USBHS_UH_RX_MAX_LEN 0x07FF
|
||||
#define R32_U2H_RX_DMA (*((PUINT32V)0x40009124)) // RW, USB_high_speed register
|
||||
#define USBHS_R32_UH_RX_DMA 0x01FFFF
|
||||
#define R32_U2H_TX_DMA (*((PUINT32V)0x40009128)) // RW, USB_high_speed register
|
||||
#define USBHS_R32_UH_TX_DMA 0x01FFFF
|
||||
#define R32_U2H_PORT_CTRL (*((PUINT32V)0x4000912C)) // RW, USB_high_speed register
|
||||
#define USBHS_UH_BUS_RST_LONG 0x010000
|
||||
#define USBHS_UH_PORT_SLEEP_BESL 0xF000
|
||||
#define USBHS_UH_CLR_PORT_SLEEP 0x0100
|
||||
#define USBHS_UH_CLR_PORT_CONNECT 0x20
|
||||
#define USBHS_UH_CLR_PORT_EN 0x10
|
||||
#define USBHS_UH_SET_PORT_SLEEP 0x08
|
||||
#define USBHS_UH_CLR_PORT_SUSP 0x04
|
||||
#define USBHS_UH_SET_PORT_SUSP 0x02
|
||||
#define USBHS_UH_SET_PORT_RESET 0x01
|
||||
#define R8_U2H_PORT_CFG (*((PUINT8V)0x40009130)) // RW, USB_high_speed register
|
||||
#define USBHS_UH_PD_EN 0x80
|
||||
#define USBHS_UH_HOST_EN 0x01
|
||||
#define R8_U2H_PORT_INT_EN (*((PUINT8V)0x40009132)) // RW, USB_high_speed register
|
||||
#define USBHS_UHIE_PORT_SLP 0x20
|
||||
#define USBHS_UHIE_PORT_RESET 0x10
|
||||
#define USBHS_UHIE_PORT_SUSP 0x04
|
||||
#define USBHS_UHIE_PORT_EN 0x02
|
||||
#define USBHS_UHIE_PORT_CONNECT 0x01
|
||||
#define R8_U2H_PORT_TEST_CT (*((PUINT8V)0x40009133)) // RW, USB_high_speed register
|
||||
#define USBHS_UH_TEST_FORCE_EN 0x04
|
||||
#define USBHS_UH_TEST_K 0x02
|
||||
#define USBHS_UH_TEST_J 0x01
|
||||
#define R16_U2H_PORT_ST (*((PUINT16V)0x40009134)) // RW, USB_high_speed register
|
||||
#define USBHS_UHIS_PORT_TEST 0x0800
|
||||
#define USBHS_UHIS_PORT_SPEED_MASK 0x0600
|
||||
#define USBHS_UHIS_PORT_HS 0x0400
|
||||
#define USBHS_UHIS_PORT_LS 0x0200
|
||||
#define USBHS_UHIS_PORT_FS 0x0000
|
||||
#define USBHS_UHIS_PORT_SLP 0x20
|
||||
#define USBHS_UHIS_PORT_RST 0x10
|
||||
#define USBHS_UHIS_PORT_SUSP 0x04
|
||||
#define USBHS_UHIS_PORT_EN 0x02
|
||||
#define USBHS_UHIS_PORT_CONNECT 0x01
|
||||
#define R8_U2H_PORT_CHG (*((PUINT8V)0x40009136))
|
||||
#define USBHS_UHIF_PORT_SLP 0x20
|
||||
#define USBHS_UHIF_PORT_RESET 0x10
|
||||
#define USBHS_UHIF_PORT_SUSP 0x04
|
||||
#define USBHS_UHIF_PORT_EN 0x02
|
||||
#define USBHS_UHIF_PORT_CONNECT 0x01
|
||||
#define R32_U2H_BC_CTRL (*((PUINT32V)0x4000913C))
|
||||
#define UDM_VSRC_ACT 0x0400
|
||||
#define UDM_BC_VSRC 0x0200
|
||||
#define UDP_BC_VSRC 0x0100
|
||||
#define BC_AUTO_MODE 0x40
|
||||
#define UDM_BC_CMPE 0x20
|
||||
#define UDP_BC_CMPE 0x10
|
||||
#define UDM_BC_CMPO 0x02
|
||||
#define UDP_BC_CMPO 0x01
|
||||
#define R8_USBHS_PLL_CTRL (*((PUINT8V)0x40009200))
|
||||
#define USBHS_PLL_EN 0x04
|
||||
#define USBHS_PLL_LOWPOW 0x02
|
||||
#define USBHS_PLL_CKSEL 0x01
|
||||
|
||||
#define __IO volatile /* defines 'read / write' permissions */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
__IO uint8_t CONTROL; /* 0x40009000 */
|
||||
__IO uint8_t BASE_MODE; /* 0x40009001 */
|
||||
__IO uint8_t INT_EN; /* 0x40009002 */
|
||||
__IO uint8_t DEV_AD; /* 0x40009003 */
|
||||
__IO uint8_t WAKE_CTRL; /* 0x40009004 远程唤醒寄存器 */
|
||||
__IO uint8_t TEST_MODE; /* 0x40009005 测试模式寄存器 */
|
||||
__IO uint16_t LPM_DATA; /* 0x40009006 */
|
||||
__IO uint8_t INT_FG; /* 0x40009008 */
|
||||
__IO uint8_t INT_ST; /* 0x40009009 */
|
||||
__IO uint8_t MIS_ST; /* 0x4000900a */
|
||||
__IO uint8_t RESERVE0; /* 0x4000900b */
|
||||
__IO uint16_t FRAME_NO; /* 0x4000900c */
|
||||
__IO uint16_t USB_BUS; /* 0x4000900e */
|
||||
__IO uint16_t UEP_TX_EN; /* 0x40009010 */
|
||||
__IO uint16_t UEP_RX_EN; /* 0x40009012 */
|
||||
|
||||
__IO uint16_t UEP_T_TOG_AUTO; /* 0x40009014 */
|
||||
__IO uint16_t UEP_R_TOG_AUTO; /* 0x40009016 */
|
||||
__IO uint8_t UEP_T_BURST; /* 0x40009018 */
|
||||
__IO uint8_t UEP_T_BURST_MODE; /* 0x40009019 */
|
||||
__IO uint8_t UEP_R_BURST; /* 0x4000901a */
|
||||
__IO uint8_t UEP_R_RES_MODE; /* 0x4000901b */
|
||||
__IO uint32_t UEP_AF_MODE; /* 0x4000901c */
|
||||
|
||||
__IO uint32_t UEP0_DMA; /* 0x40009020 */
|
||||
__IO uint32_t UEP1_RX_DMA; /* 0x40009024 */
|
||||
__IO uint32_t UEP2_RX_DMA; /* 0x40009028 */
|
||||
__IO uint32_t UEP3_RX_DMA; /* 0x4000902c */
|
||||
__IO uint32_t UEP4_RX_DMA; /* 0x40009030 */
|
||||
__IO uint32_t UEP5_RX_DMA; /* 0x40009034 */
|
||||
__IO uint32_t UEP6_RX_DMA; /* 0x40009038 */
|
||||
__IO uint32_t UEP7_RX_DMA; /* 0x4000903c */
|
||||
|
||||
__IO uint32_t UEP1_TX_DMA; /* 0x40009040 */
|
||||
__IO uint32_t UEP2_TX_DMA; /* 0x40009044 */
|
||||
__IO uint32_t UEP3_TX_DMA; /* 0x40009048 */
|
||||
__IO uint32_t UEP4_TX_DMA; /* 0x4000904c */
|
||||
__IO uint32_t UEP5_TX_DMA; /* 0x40009050 */
|
||||
__IO uint32_t UEP6_TX_DMA; /* 0x40009054 */
|
||||
__IO uint32_t UEP7_TX_DMA; /* 0x40009058 */
|
||||
|
||||
__IO uint32_t UEP0_MAX_LEN; /* 0x4000905c */
|
||||
__IO uint32_t UEP1_MAX_LEN; /* 0x40009060 */
|
||||
__IO uint32_t UEP2_MAX_LEN; /* 0x40009064 */
|
||||
__IO uint32_t UEP3_MAX_LEN; /* 0x40009068 */
|
||||
__IO uint32_t UEP4_MAX_LEN; /* 0x4000906c */
|
||||
__IO uint32_t UEP5_MAX_LEN; /* 0x40009070 */
|
||||
__IO uint32_t UEP6_MAX_LEN; /* 0x40009074 */
|
||||
__IO uint32_t UEP7_MAX_LEN; /* 0x40009078 */
|
||||
|
||||
__IO uint16_t USB_EP0_RX_LEN; /* 0x4000907c */
|
||||
__IO uint16_t RESERVE1; /* 0x4000907e */
|
||||
__IO uint16_t UEP1_RX_LEN; /* 0x40009080 */
|
||||
__IO uint16_t UEP1_R_SIZE; /* 0x40009082 */
|
||||
__IO uint16_t UEP2_RX_LEN; /* 0x40009084 */
|
||||
__IO uint16_t UEP2_R_SIZE; /* 0x40009086 */
|
||||
__IO uint16_t UEP3_RX_LEN; /* 0x40009088 */
|
||||
__IO uint16_t UEP3_R_SIZE; /* 0x4000908a */
|
||||
__IO uint16_t UEP4_RX_LEN; /* 0x4000908c */
|
||||
__IO uint16_t UEP4_R_SIZE; /* 0x4000908e */
|
||||
__IO uint16_t UEP5_RX_LEN; /* 0x40009090 */
|
||||
__IO uint16_t UEP5_R_SIZE; /* 0x40009092 */
|
||||
__IO uint16_t UEP6_RX_LEN; /* 0x40009094 */
|
||||
__IO uint16_t UEP6_R_SIZE; /* 0x40009096 */
|
||||
__IO uint16_t UEP7_RX_LEN; /* 0x40009098 */
|
||||
__IO uint16_t UEP7_R_SIZE; /* 0x4000909a */
|
||||
|
||||
__IO uint16_t UEP0_TX_LEN; /* 0x4000909c */
|
||||
__IO uint8_t UEP0_TX_CTRL; /* 0x4000909e */
|
||||
__IO uint8_t UEP0_RX_CTRL; /* 0x4000909f */
|
||||
__IO uint16_t UEP1_TX_LEN; /* 0x400090a0 */
|
||||
__IO uint8_t UEP1_TX_CTRL; /* 0x400090a2 */
|
||||
__IO uint8_t UEP1_RX_CTRL; /* 0x400090a3 */
|
||||
__IO uint16_t UEP2_TX_LEN; /* 0x400090a4 */
|
||||
__IO uint8_t UEP2_TX_CTRL; /* 0x400090a6 */
|
||||
__IO uint8_t UEP2_RX_CTRL; /* 0x400090a7 */
|
||||
__IO uint16_t UEP3_TX_LEN; /* 0x400090a8 */
|
||||
__IO uint8_t UEP3_TX_CTRL; /* 0x400090aa */
|
||||
__IO uint8_t UEP3_RX_CTRL; /* 0x400090ab */
|
||||
__IO uint16_t UEP4_TX_LEN; /* 0x400090ac */
|
||||
__IO uint8_t UEP4_TX_CTRL; /* 0x400090ae */
|
||||
__IO uint8_t UEP4_RX_CTRL; /* 0x400090af */
|
||||
__IO uint16_t UEP5_TX_LEN; /* 0x400090b0 */
|
||||
__IO uint8_t UEP5_TX_CTRL; /* 0x400090b2 */
|
||||
__IO uint8_t UEP5_RX_CTRL; /* 0x400090b3 */
|
||||
__IO uint16_t UEP6_TX_LEN; /* 0x400090b4 */
|
||||
__IO uint8_t UEP6_TX_CTRL; /* 0x400090b6 */
|
||||
__IO uint8_t UEP6_RX_CTRL; /* 0x400090b7 */
|
||||
__IO uint16_t UEP7_TX_LEN; /* 0x400090b8 */
|
||||
__IO uint8_t UEP7_TX_CTRL; /* 0x400090ba */
|
||||
__IO uint8_t UEP7_RX_CTRL; /* 0x400090bb */
|
||||
__IO uint16_t UEP_TX_ISO; /* 0x400090bc */
|
||||
__IO uint16_t UEP_RX_ISO; /* 0x400090be */
|
||||
} USBHSD_TypeDef;
|
|
@ -0,0 +1,639 @@
|
|||
/*
|
||||
* Copyright (c) 2022, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "usb_ch58x_usbfs_reg.h"
|
||||
|
||||
/**
|
||||
* @brief Related register macro
|
||||
*/
|
||||
#define USB0_BASE 0x40008000u
|
||||
#define USB1_BASE 0x40008400u
|
||||
|
||||
#ifndef USBD
|
||||
#define USBD USB0_BASE
|
||||
#endif
|
||||
#define CH58x_USBFS_DEV ((USB_FS_TypeDef *)USBD)
|
||||
|
||||
#ifndef USBD_IRQHandler
|
||||
#define USBD_IRQHandler USB_IRQHandler //use actual usb irq name instead
|
||||
#endif
|
||||
|
||||
/*!< 8-bit value of endpoint control register */
|
||||
#define EPn_CTRL(epid) \
|
||||
*(volatile uint8_t *)(&(CH58x_USBFS_DEV->UEP0_CTRL) + epid * 4 + (epid / 5) * 48)
|
||||
|
||||
/*!< The length register value of the endpoint send buffer */
|
||||
#define EPn_TX_LEN(epid) \
|
||||
*(volatile uint8_t *)(&(CH58x_USBFS_DEV->UEP0_T_LEN) + epid * 4 + (epid / 5) * 48)
|
||||
|
||||
/*!< Read setup packet to use in ep0 in */
|
||||
#define GET_SETUP_PACKET(data_add) \
|
||||
*(struct usb_setup_packet *)data_add
|
||||
|
||||
/*!< 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 // 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;
|
||||
/*!< Set epid ep rx nak */
|
||||
#define EPn_SET_RX_NAK(epid) \
|
||||
EPn_CTRL(epid) = (EPn_CTRL(epid) & ~MASK_UEP_R_RES) | UEP_R_RES_NAK;
|
||||
/*!< Set epid ep tx stall */
|
||||
#define EPn_SET_TX_STALL(epid) \
|
||||
EPn_CTRL(epid) = (EPn_CTRL(epid) & ~MASK_UEP_T_RES) | UEP_T_RES_STALL
|
||||
/*!< 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) \
|
||||
CH58x_USBFS_DEV->USB_RX_LEN
|
||||
|
||||
/*!< ep nums */
|
||||
#ifndef CONFIG_USBDEV_EP_NUM
|
||||
#define CONFIG_USBDEV_EP_NUM 5
|
||||
#endif
|
||||
/*!< ep mps */
|
||||
#define EP_MPS 64
|
||||
/*!< set ep4 in mps 64 */
|
||||
#define EP4_IN_MPS EP_MPS
|
||||
/*!< set ep4 out mps 64 */
|
||||
#define EP4_OUT_MPS EP_MPS
|
||||
|
||||
/*!< User defined assignment endpoint RAM */
|
||||
__attribute__((aligned(4))) uint8_t ep0_data_buff[64 + EP4_OUT_MPS + EP4_IN_MPS]; /*!< ep0(64)+ep4_out(64)+ep4_in(64) */
|
||||
__attribute__((aligned(4))) uint8_t ep1_data_buff[64 + 64]; /*!< ep1_out(64)+ep1_in(64) */
|
||||
__attribute__((aligned(4))) uint8_t ep2_data_buff[64 + 64]; /*!< ep2_out(64)+ep2_in(64) */
|
||||
__attribute__((aligned(4))) uint8_t ep3_data_buff[64 + 64]; /*!< ep3_out(64)+ep3_in(64) */
|
||||
#if (CONFIG_USBDEV_EP_NUM == 8)
|
||||
/**
|
||||
* This dcd porting can be used on ch581, ch582, ch583,
|
||||
* and also on ch571, ch572, and ch573. Note that only five endpoints are available for ch571, ch572, and ch573.
|
||||
*/
|
||||
__attribute__((aligned(4))) uint8_t ep5_data_buff[64 + 64]; /*!< ep5_out(64)+ep5_in(64) */
|
||||
__attribute__((aligned(4))) uint8_t ep6_data_buff[64 + 64]; /*!< ep6_out(64)+ep6_in(64) */
|
||||
__attribute__((aligned(4))) uint8_t ep7_data_buff[64 + 64]; /*!< ep7_out(64)+ep7_in(64) */
|
||||
#endif
|
||||
/**
|
||||
* @brief Endpoint information structure
|
||||
*/
|
||||
typedef struct _usbd_ep_info {
|
||||
uint8_t mps; /*!< Maximum packet length of endpoint */
|
||||
uint8_t eptype; /*!< Endpoint Type */
|
||||
uint8_t *ep_ram_addr; /*!< Endpoint buffer address */
|
||||
|
||||
uint8_t ep_enable; /* Endpoint enable */
|
||||
uint8_t *xfer_buf;
|
||||
uint32_t xfer_len;
|
||||
uint32_t actual_xfer_len;
|
||||
} usbd_ep_info;
|
||||
|
||||
/*!< ch58x usb */
|
||||
static struct _ch58x_core_prvi {
|
||||
uint8_t address; /*!< Address */
|
||||
usbd_ep_info ep_in[CONFIG_USBDEV_EP_NUM];
|
||||
usbd_ep_info ep_out[CONFIG_USBDEV_EP_NUM];
|
||||
struct usb_setup_packet setup;
|
||||
} usb_dc_cfg;
|
||||
|
||||
__WEAK void usb_dc_low_level_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
__WEAK void usb_dc_low_level_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USB initialization
|
||||
* @pre None
|
||||
* @param[in] None
|
||||
* @retval >=0 success otherwise failure
|
||||
*/
|
||||
int usb_dc_init(uint8_t busid)
|
||||
{
|
||||
usb_dc_cfg.ep_in[0].ep_ram_addr = ep0_data_buff;
|
||||
usb_dc_cfg.ep_out[0].ep_ram_addr = ep0_data_buff;
|
||||
|
||||
usb_dc_cfg.ep_in[1].ep_ram_addr = ep1_data_buff + 64;
|
||||
usb_dc_cfg.ep_out[1].ep_ram_addr = ep1_data_buff;
|
||||
|
||||
usb_dc_cfg.ep_in[2].ep_ram_addr = ep2_data_buff + 64;
|
||||
usb_dc_cfg.ep_out[2].ep_ram_addr = ep2_data_buff;
|
||||
|
||||
usb_dc_cfg.ep_in[3].ep_ram_addr = ep3_data_buff + 64;
|
||||
usb_dc_cfg.ep_out[3].ep_ram_addr = ep3_data_buff;
|
||||
|
||||
usb_dc_cfg.ep_in[4].ep_ram_addr = ep0_data_buff + 64 + EP4_OUT_MPS;
|
||||
usb_dc_cfg.ep_out[4].ep_ram_addr = ep0_data_buff + 64;
|
||||
#if (CONFIG_USBDEV_EP_NUM == 8)
|
||||
usb_dc_cfg.ep_in[5].ep_ram_addr = ep5_data_buff + 64;
|
||||
usb_dc_cfg.ep_out[5].ep_ram_addr = ep5_data_buff;
|
||||
|
||||
usb_dc_cfg.ep_in[6].ep_ram_addr = ep6_data_buff + 64;
|
||||
usb_dc_cfg.ep_out[6].ep_ram_addr = ep6_data_buff;
|
||||
|
||||
usb_dc_cfg.ep_in[7].ep_ram_addr = ep7_data_buff + 64;
|
||||
usb_dc_cfg.ep_out[7].ep_ram_addr = ep7_data_buff;
|
||||
#endif
|
||||
/*!< Set the mode first and cancel RB_UC_CLR_ALL */
|
||||
CH58x_USBFS_DEV->USB_CTRL = 0x00;
|
||||
CH58x_USBFS_DEV->UEP4_1_MOD = RB_UEP4_RX_EN | RB_UEP4_TX_EN | RB_UEP1_RX_EN | RB_UEP1_TX_EN; /*!< EP4 OUT+IN EP1 OUT+IN */
|
||||
CH58x_USBFS_DEV->UEP2_3_MOD = RB_UEP2_RX_EN | RB_UEP2_TX_EN | RB_UEP3_RX_EN | RB_UEP3_TX_EN; /*!< EP2 OUT+IN EP3 OUT+IN */
|
||||
#if (CONFIG_USBDEV_EP_NUM == 8)
|
||||
CH58x_USBFS_DEV->UEP567_MOD = RB_UEP5_RX_EN | RB_UEP5_TX_EN | RB_UEP6_RX_EN | RB_UEP6_TX_EN | RB_UEP7_RX_EN | RB_UEP7_TX_EN; /*!< EP5 EP6 EP7 OUT+IN */
|
||||
#endif
|
||||
CH58x_USBFS_DEV->UEP0_DMA = (uint16_t)(uint32_t)ep0_data_buff;
|
||||
CH58x_USBFS_DEV->UEP1_DMA = (uint16_t)(uint32_t)ep1_data_buff;
|
||||
CH58x_USBFS_DEV->UEP2_DMA = (uint16_t)(uint32_t)ep2_data_buff;
|
||||
CH58x_USBFS_DEV->UEP3_DMA = (uint16_t)(uint32_t)ep3_data_buff;
|
||||
#if (CONFIG_USBDEV_EP_NUM == 8)
|
||||
CH58x_USBFS_DEV->UEP5_DMA = (uint16_t)(uint32_t)ep5_data_buff;
|
||||
CH58x_USBFS_DEV->UEP6_DMA = (uint16_t)(uint32_t)ep6_data_buff;
|
||||
CH58x_USBFS_DEV->UEP7_DMA = (uint16_t)(uint32_t)ep7_data_buff;
|
||||
#endif
|
||||
CH58x_USBFS_DEV->UEP0_CTRL = UEP_R_RES_NAK | UEP_T_RES_NAK;
|
||||
CH58x_USBFS_DEV->UEP1_CTRL = UEP_R_RES_NAK | UEP_T_RES_NAK | RB_UEP_AUTO_TOG;
|
||||
CH58x_USBFS_DEV->UEP2_CTRL = UEP_R_RES_NAK | UEP_T_RES_NAK | RB_UEP_AUTO_TOG;
|
||||
CH58x_USBFS_DEV->UEP3_CTRL = UEP_R_RES_NAK | UEP_T_RES_NAK | RB_UEP_AUTO_TOG;
|
||||
CH58x_USBFS_DEV->UEP4_CTRL = UEP_R_RES_NAK | UEP_T_RES_NAK;
|
||||
#if (CONFIG_USBDEV_EP_NUM == 8)
|
||||
CH58x_USBFS_DEV->UEP5_CTRL = UEP_R_RES_NAK | UEP_T_RES_NAK | RB_UEP_AUTO_TOG;
|
||||
CH58x_USBFS_DEV->UEP6_CTRL = UEP_R_RES_NAK | UEP_T_RES_NAK | RB_UEP_AUTO_TOG;
|
||||
CH58x_USBFS_DEV->UEP7_CTRL = UEP_R_RES_NAK | UEP_T_RES_NAK | RB_UEP_AUTO_TOG;
|
||||
#endif
|
||||
CH58x_USBFS_DEV->USB_DEV_AD = 0x00;
|
||||
|
||||
/*!< Start the USB device and DMA, and automatically return to NAK before the interrupt flag is cleared during the interrupt */
|
||||
CH58x_USBFS_DEV->USB_CTRL = RB_UC_DEV_PU_EN | RB_UC_INT_BUSY | RB_UC_DMA_EN;
|
||||
if ((uint32_t) & (CH58x_USBFS_DEV->USB_CTRL) == (uint32_t)USB0_BASE) {
|
||||
/*!< USB0 */
|
||||
R16_PIN_ANALOG_IE |= RB_PIN_USB_IE | RB_PIN_USB_DP_PU;
|
||||
} else if ((uint32_t) & (CH58x_USBFS_DEV->USB_CTRL) == (uint32_t)USB1_BASE) {
|
||||
/*!< USB1 */
|
||||
R16_PIN_ANALOG_IE |= RB_PIN_USB2_IE | RB_PIN_USB2_DP_PU;
|
||||
}
|
||||
|
||||
CH58x_USBFS_DEV->USB_INT_FG = 0xff; /*!< Clear interrupt flag */
|
||||
CH58x_USBFS_DEV->UDEV_CTRL = RB_UD_PD_DIS | RB_UD_PORT_EN; /*!< Allow USB port */
|
||||
CH58x_USBFS_DEV->USB_INT_EN = RB_UIE_SUSPEND | RB_UIE_BUS_RST | RB_UIE_TRANSFER;
|
||||
|
||||
usb_dc_low_level_init();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_dc_deinit(uint8_t busid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set address
|
||||
* @pre None
|
||||
* @param[in] address :8-bit valid address
|
||||
* @retval >=0 success otherwise failure
|
||||
*/
|
||||
int usbd_set_address(uint8_t busid, const uint8_t address)
|
||||
{
|
||||
if (address == 0) {
|
||||
CH58x_USBFS_DEV->USB_DEV_AD = (CH58x_USBFS_DEV->USB_DEV_AD & 0x80) | address;
|
||||
}
|
||||
usb_dc_cfg.address = address;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_set_remote_wakeup(uint8_t busid)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t usbd_get_port_speed(uint8_t busid)
|
||||
{
|
||||
return USB_SPEED_FULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Open endpoint
|
||||
* @pre None
|
||||
* @param[in] ep_cfg : Endpoint configuration structure pointer
|
||||
* @retval >=0 success otherwise failure
|
||||
*/
|
||||
int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
|
||||
{
|
||||
/*!< ep id */
|
||||
uint8_t epid = USB_EP_GET_IDX(ep->bEndpointAddress);
|
||||
if (epid > (CONFIG_USBDEV_EP_NUM - 1)) {
|
||||
/**
|
||||
* If you use ch58x, you can change the CONFIG_USBDEV_EP_NUM set to 8
|
||||
*/
|
||||
USB_LOG_ERR("Ep addr %02x overflow\r\n", ep->bEndpointAddress);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*!< ep max packet length */
|
||||
uint8_t mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
|
||||
/*!< update ep max packet length */
|
||||
if (USB_EP_DIR_IS_IN(ep->bEndpointAddress)) {
|
||||
/*!< in */
|
||||
usb_dc_cfg.ep_in[epid].ep_enable = true;
|
||||
usb_dc_cfg.ep_in[epid].mps = mps;
|
||||
usb_dc_cfg.ep_in[epid].eptype = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
|
||||
} else if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) {
|
||||
/*!< 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 = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Close endpoint
|
||||
* @pre None
|
||||
* @param[in] ep : Endpoint address
|
||||
* @retval >=0 success otherwise failure
|
||||
*/
|
||||
int usbd_ep_close(uint8_t busid, const uint8_t ep)
|
||||
{
|
||||
/*!< ep id */
|
||||
uint8_t epid = USB_EP_GET_IDX(ep);
|
||||
if (USB_EP_DIR_IS_IN(ep)) {
|
||||
/*!< in */
|
||||
usb_dc_cfg.ep_in[epid].ep_enable = false;
|
||||
} else if (USB_EP_DIR_IS_OUT(ep)) {
|
||||
/*!< out */
|
||||
usb_dc_cfg.ep_out[epid].ep_enable = false;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Endpoint setting stall
|
||||
* @pre None
|
||||
* @param[in] ep : Endpoint address
|
||||
* @retval >=0 success otherwise failure
|
||||
*/
|
||||
int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
|
||||
{
|
||||
/*!< ep id */
|
||||
uint8_t epid = USB_EP_GET_IDX(ep);
|
||||
if (USB_EP_DIR_IS_OUT(ep)) {
|
||||
EPn_SET_RX_STALL(epid);
|
||||
} else {
|
||||
EPn_SET_TX_STALL(epid);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Endpoint clear stall
|
||||
* @pre None
|
||||
* @param[in] ep : Endpoint address
|
||||
* @retval >=0 success otherwise failure
|
||||
*/
|
||||
int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
|
||||
{
|
||||
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 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check endpoint status
|
||||
* @pre None
|
||||
* @param[in] ep : Endpoint address
|
||||
* @param[out] stalled : Outgoing endpoint status
|
||||
* @retval >=0 success otherwise failure
|
||||
*/
|
||||
int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
|
||||
{
|
||||
if (USB_EP_DIR_IS_OUT(ep)) {
|
||||
} else {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Setup in ep transfer setting and start transfer.
|
||||
*
|
||||
* This function is asynchronous.
|
||||
* This function is similar to uart with tx dma.
|
||||
*
|
||||
* This function is called to write data to the specified endpoint. The
|
||||
* supplied usbd_endpoint_callback function will be called when data is transmitted
|
||||
* out.
|
||||
*
|
||||
* @param[in] ep Endpoint address corresponding to the one
|
||||
* listed in the device configuration table
|
||||
* @param[in] data Pointer to data to write
|
||||
* @param[in] data_len Length of the data requested to write. This may
|
||||
* be zero for a zero length status packet.
|
||||
* @return 0 on success, negative errno code on fail.
|
||||
*/
|
||||
int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, uint32_t data_len)
|
||||
{
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep);
|
||||
|
||||
if (!data && data_len) {
|
||||
return -1;
|
||||
}
|
||||
if (!usb_dc_cfg.ep_in[ep_idx].ep_enable) {
|
||||
return -2;
|
||||
}
|
||||
if ((uint32_t)data & 0x03) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
usb_dc_cfg.ep_in[ep_idx].xfer_buf = (uint8_t *)data;
|
||||
usb_dc_cfg.ep_in[ep_idx].xfer_len = data_len;
|
||||
usb_dc_cfg.ep_in[ep_idx].actual_xfer_len = 0;
|
||||
|
||||
if (data_len == 0) {
|
||||
/*!< write 0 len data */
|
||||
EPn_SET_TX_LEN(ep_idx, 0);
|
||||
/*!< enable tx */
|
||||
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 {
|
||||
/*!< Not zlp */
|
||||
data_len = MIN(data_len, usb_dc_cfg.ep_in[ep_idx].mps);
|
||||
/*!< write buff */
|
||||
memcpy(usb_dc_cfg.ep_in[ep_idx].ep_ram_addr, data, data_len);
|
||||
/*!< write real_wt_nums len data */
|
||||
EPn_SET_TX_LEN(ep_idx, data_len);
|
||||
/*!< enable tx */
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Setup out ep transfer setting and start transfer.
|
||||
*
|
||||
* This function is asynchronous.
|
||||
* This function is similar to uart with rx dma.
|
||||
*
|
||||
* This function is called to read data to the specified endpoint. The
|
||||
* supplied usbd_endpoint_callback function will be called when data is received
|
||||
* in.
|
||||
*
|
||||
* @param[in] ep Endpoint address corresponding to the one
|
||||
* listed in the device configuration table
|
||||
* @param[in] data Pointer to data to read
|
||||
* @param[in] data_len Max length of the data requested to read.
|
||||
*
|
||||
* @return 0 on success, negative errno code on fail.
|
||||
*/
|
||||
int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len)
|
||||
{
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep);
|
||||
|
||||
if (!data && data_len) {
|
||||
return -1;
|
||||
}
|
||||
if (!usb_dc_cfg.ep_out[ep_idx].ep_enable) {
|
||||
return -2;
|
||||
}
|
||||
if ((uint32_t)data & 0x03) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
usb_dc_cfg.ep_out[ep_idx].xfer_buf = (uint8_t *)data;
|
||||
usb_dc_cfg.ep_out[ep_idx].xfer_len = data_len;
|
||||
usb_dc_cfg.ep_out[ep_idx].actual_xfer_len = 0;
|
||||
|
||||
if (data_len == 0) {
|
||||
} else {
|
||||
data_len = MIN(data_len, usb_dc_cfg.ep_out[ep_idx].mps);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USB interrupt processing function
|
||||
* @pre None
|
||||
* @param[in] None
|
||||
* @retval None
|
||||
*/
|
||||
__attribute__((interrupt("WCH-Interrupt-fast")))
|
||||
__attribute__((section(".highcode"))) void
|
||||
USBD_IRQHandler(void)
|
||||
{
|
||||
volatile uint8_t intflag = 0;
|
||||
intflag = CH58x_USBFS_DEV->USB_INT_FG;
|
||||
|
||||
if (intflag & RB_UIF_TRANSFER) {
|
||||
if ((CH58x_USBFS_DEV->USB_INT_ST & MASK_UIS_TOKEN) != MASK_UIS_TOKEN) {
|
||||
uint8_t epid = ((CH58x_USBFS_DEV->USB_INT_ST & (MASK_UIS_TOKEN | MASK_UIS_ENDP)) & 0x0f);
|
||||
switch ((CH58x_USBFS_DEV->USB_INT_ST & (MASK_UIS_TOKEN | MASK_UIS_ENDP)) & 0xf0) {
|
||||
case UIS_TOKEN_IN:
|
||||
if (epid == 0) {
|
||||
/**
|
||||
* IN The host takes away the data that has been stored in FIFO
|
||||
*/
|
||||
switch (usb_dc_cfg.setup.bmRequestType >> USB_REQUEST_DIR_SHIFT) {
|
||||
case 1:
|
||||
/*!< Get */
|
||||
CH58x_USBFS_DEV->UEP0_CTRL ^= RB_UEP_T_TOG;
|
||||
/**
|
||||
* Here is to take away the last data, and the IN interrupt will be triggered only after it is successfully taken away.
|
||||
* Therefore, the status of the in endpoint is set to NAK here. If there is data transmission,
|
||||
* the endpoint status will be set to ack again in the in handler of EP0.
|
||||
*/
|
||||
EPn_SET_TX_NAK(0);
|
||||
|
||||
/*!< IN */
|
||||
if (usb_dc_cfg.ep_in[0].xfer_len > usb_dc_cfg.ep_in[0].mps) {
|
||||
usb_dc_cfg.ep_in[0].xfer_len -= usb_dc_cfg.ep_in[0].mps;
|
||||
usb_dc_cfg.ep_in[0].actual_xfer_len += usb_dc_cfg.ep_in[0].mps;
|
||||
usbd_event_ep_in_complete_handler(0, 0 | 0x80, usb_dc_cfg.ep_in[0].actual_xfer_len);
|
||||
} else {
|
||||
usb_dc_cfg.ep_in[0].actual_xfer_len += usb_dc_cfg.ep_in[0].xfer_len;
|
||||
usb_dc_cfg.ep_in[0].xfer_len = 0;
|
||||
usbd_event_ep_in_complete_handler(0, 0 | 0x80, usb_dc_cfg.ep_in[0].actual_xfer_len);
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
/*!< Set */
|
||||
switch (usb_dc_cfg.setup.bRequest) {
|
||||
case USB_REQUEST_SET_ADDRESS:
|
||||
/*!< Fill in the equipment address */
|
||||
CH58x_USBFS_DEV->USB_DEV_AD = (CH58x_USBFS_DEV->USB_DEV_AD & RB_UDA_GP_BIT) | usb_dc_cfg.address;
|
||||
/**
|
||||
* In the state phase after setting the address, the host has sent an in token packet of data1 to take the packet of 0 length,
|
||||
* Ch58x USB IP needs to manually set the status of the in endpoint to NAK
|
||||
*/
|
||||
EPn_SET_TX_NAK(0);
|
||||
EPn_SET_RX_VALID(0);
|
||||
break;
|
||||
default:
|
||||
/*!< Normal out state phase */
|
||||
/**
|
||||
* The host has sent an in token packet of data1 and taken the packet of 0 length.
|
||||
* Here, you only need to set the status of the in endpoint to NAK and out endpoint ACK
|
||||
*/
|
||||
EPn_SET_TX_NAK(0);
|
||||
EPn_SET_RX_VALID(0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (epid == 4) {
|
||||
CH58x_USBFS_DEV->UEP4_CTRL ^= RB_UEP_T_TOG;
|
||||
}
|
||||
EPn_SET_TX_NAK(epid);
|
||||
if (usb_dc_cfg.ep_in[epid].xfer_len > usb_dc_cfg.ep_in[epid].mps) {
|
||||
/*!< Need start in again */
|
||||
usb_dc_cfg.ep_in[epid].xfer_buf += usb_dc_cfg.ep_in[epid].mps;
|
||||
usb_dc_cfg.ep_in[epid].xfer_len -= usb_dc_cfg.ep_in[epid].mps;
|
||||
usb_dc_cfg.ep_in[epid].actual_xfer_len += usb_dc_cfg.ep_in[epid].mps;
|
||||
if (usb_dc_cfg.ep_in[epid].xfer_len > usb_dc_cfg.ep_in[epid].mps) {
|
||||
memcpy(usb_dc_cfg.ep_in[epid].ep_ram_addr, usb_dc_cfg.ep_in[epid].xfer_buf, usb_dc_cfg.ep_in[epid].mps);
|
||||
EPn_SET_TX_LEN(epid, usb_dc_cfg.ep_in[epid].mps);
|
||||
} 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_LEN(epid, usb_dc_cfg.ep_in[epid].xfer_len);
|
||||
}
|
||||
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;
|
||||
usbd_event_ep_in_complete_handler(0, epid | 0x80, usb_dc_cfg.ep_in[epid].actual_xfer_len);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UIS_TOKEN_OUT:
|
||||
EPn_SET_RX_NAK(epid);
|
||||
|
||||
if (epid == 0) {
|
||||
/*!< ep0 out */
|
||||
CH58x_USBFS_DEV->UEP0_CTRL ^= RB_UEP_R_TOG;
|
||||
uint32_t read_count = EPn_GET_RX_LEN(0);
|
||||
memcpy(usb_dc_cfg.ep_out[epid].xfer_buf, usb_dc_cfg.ep_out[epid].ep_ram_addr, read_count);
|
||||
|
||||
usb_dc_cfg.ep_out[0].actual_xfer_len += read_count;
|
||||
usb_dc_cfg.ep_out[0].xfer_len -= read_count;
|
||||
usbd_event_ep_out_complete_handler(0, 0x00, usb_dc_cfg.ep_out[0].actual_xfer_len);
|
||||
if (read_count == 0) {
|
||||
/*!< Out status, start reading setup */
|
||||
EPn_SET_RX_VALID(0);
|
||||
}
|
||||
} else {
|
||||
if ((CH58x_USBFS_DEV->USB_INT_ST) & RB_UIS_TOG_OK) {
|
||||
if (epid == 4) {
|
||||
CH58x_USBFS_DEV->UEP4_CTRL ^= RB_UEP_R_TOG;
|
||||
}
|
||||
uint32_t read_count = EPn_GET_RX_LEN(epid);
|
||||
memcpy(usb_dc_cfg.ep_out[epid].xfer_buf, usb_dc_cfg.ep_out[epid].ep_ram_addr, read_count);
|
||||
usb_dc_cfg.ep_out[epid].xfer_buf += read_count;
|
||||
usb_dc_cfg.ep_out[epid].actual_xfer_len += read_count;
|
||||
usb_dc_cfg.ep_out[epid].xfer_len -= read_count;
|
||||
|
||||
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(0, ((epid)&0x7f), usb_dc_cfg.ep_out[epid].actual_xfer_len);
|
||||
} else {
|
||||
if (usb_dc_cfg.ep_out[epid].eptype != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
|
||||
EPn_SET_RX_VALID(epid);
|
||||
} else {
|
||||
EPn_SET_RX_ISO_VALID(epid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
CH58x_USBFS_DEV->USB_INT_FG = RB_UIF_TRANSFER;
|
||||
}
|
||||
|
||||
if (CH58x_USBFS_DEV->USB_INT_ST & RB_UIS_SETUP_ACT) {
|
||||
/*!< Setup */
|
||||
/**
|
||||
* Setup the device must respond with ACK, and the next data phase is DATA1
|
||||
* If it is sent, the data1 packet will be sent.
|
||||
* If it is received, the data1 packet is expected to be received.
|
||||
* 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_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
|
||||
*/
|
||||
EPn_SET_TX_LEN(0, 0);
|
||||
EPn_SET_TX_VALID(0);
|
||||
}
|
||||
EPn_SET_RX_NAK(0);
|
||||
usbd_event_ep0_setup_complete_handler(0, (uint8_t *)&(usb_dc_cfg.setup));
|
||||
CH58x_USBFS_DEV->USB_INT_FG = RB_UIF_TRANSFER;
|
||||
}
|
||||
} else if (intflag & RB_UIF_BUS_RST) {
|
||||
/*!< Reset */
|
||||
CH58x_USBFS_DEV->USB_DEV_AD = 0;
|
||||
usbd_event_reset_handler(0);
|
||||
/*!< 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 */
|
||||
} else {
|
||||
/*!< Wake up */
|
||||
}
|
||||
CH58x_USBFS_DEV->USB_INT_FG = RB_UIF_SUSPEND;
|
||||
} else {
|
||||
CH58x_USBFS_DEV->USB_INT_FG = intflag;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
* Copyright (c) 2022, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#define __IO volatile
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RB_UC_HOST_MODE 0x80 // enable USB host mode: 0=device mode, 1=host mode
|
||||
#define RB_UC_LOW_SPEED 0x40 // enable USB low speed: 0=12Mbps, 1=1.5Mbps
|
||||
#define RB_UC_DEV_PU_EN 0x20 // USB device enable and internal pullup resistance enable
|
||||
#define RB_UC_SYS_CTRL1 0x20 // USB system control high bit
|
||||
#define RB_UC_SYS_CTRL0 0x10 // USB system control low bit
|
||||
#define MASK_UC_SYS_CTRL 0x30 // bit mask of USB system control
|
||||
#define RB_UC_INT_BUSY 0x08 // enable automatic responding busy for device mode or automatic pause for host mode during interrupt flag UIF_TRANSFER valid
|
||||
#define RB_UC_RESET_SIE 0x04 // force reset USB SIE, need software clear
|
||||
#define RB_UC_CLR_ALL 0x02 // force clear FIFO and count of USB
|
||||
#define RB_UC_DMA_EN 0x01 // DMA enable and DMA interrupt enable for USB
|
||||
|
||||
#define RB_UD_PD_DIS 0x80 // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable
|
||||
#define RB_UD_DP_PIN 0x20 // ReadOnly: indicate current UDP pin level
|
||||
#define RB_UD_DM_PIN 0x10 // ReadOnly: indicate current UDM pin level
|
||||
#define RB_UD_LOW_SPEED 0x04 // enable USB physical port low speed: 0=full speed, 1=low speed
|
||||
#define RB_UD_GP_BIT 0x02 // general purpose bit
|
||||
#define RB_UD_PORT_EN 0x01 // enable USB physical port I/O: 0=disable, 1=enable
|
||||
|
||||
#define RB_UH_PD_DIS 0x80 // disable USB UDP/UDM pulldown resistance: 0=enable pulldown, 1=disable
|
||||
#define RB_UH_DP_PIN 0x20 // ReadOnly: indicate current UDP pin level
|
||||
#define RB_UH_DM_PIN 0x10 // ReadOnly: indicate current UDM pin level
|
||||
#define RB_UH_LOW_SPEED 0x04 // enable USB port low speed: 0=full speed, 1=low speed
|
||||
#define RB_UH_BUS_RESET 0x02 // control USB bus reset: 0=normal, 1=force bus reset
|
||||
#define RB_UH_PORT_EN 0x01 // enable USB port: 0=disable, 1=enable port, automatic disabled if USB device detached
|
||||
|
||||
#define RB_UIE_DEV_SOF 0x80 // enable interrupt for SOF received for USB device mode
|
||||
#define RB_UIE_DEV_NAK 0x40 // enable interrupt for NAK responded for USB device mode
|
||||
#define RB_UIE_FIFO_OV 0x10 // enable interrupt for FIFO overflow
|
||||
#define RB_UIE_HST_SOF 0x08 // enable interrupt for host SOF timer action for USB host mode
|
||||
#define RB_UIE_SUSPEND 0x04 // enable interrupt for USB suspend or resume event
|
||||
#define RB_UIE_TRANSFER 0x02 // enable interrupt for USB transfer completion
|
||||
#define RB_UIE_DETECT 0x01 // enable interrupt for USB device detected event for USB host mode
|
||||
#define RB_UIE_BUS_RST 0x01 // enable interrupt for USB bus reset event for USB device mode
|
||||
|
||||
#define RB_UDA_GP_BIT 0x80 // general purpose bit
|
||||
#define MASK_USB_ADDR 0x7F // bit mask for USB device address
|
||||
|
||||
#define RB_UMS_SOF_PRES 0x80 // RO, indicate host SOF timer presage status
|
||||
#define RB_UMS_SOF_ACT 0x40 // RO, indicate host SOF timer action status for USB host
|
||||
#define RB_UMS_SIE_FREE 0x20 // RO, indicate USB SIE free status
|
||||
#define RB_UMS_R_FIFO_RDY 0x10 // RO, indicate USB receiving FIFO ready status (not empty)
|
||||
#define RB_UMS_BUS_RESET 0x08 // RO, indicate USB bus reset status
|
||||
#define RB_UMS_SUSPEND 0x04 // RO, indicate USB suspend status
|
||||
#define RB_UMS_DM_LEVEL 0x02 // RO, indicate UDM level saved at device attached to USB host
|
||||
#define RB_UMS_DEV_ATTACH 0x01 // RO, indicate device attached status on USB host
|
||||
|
||||
#define RB_U_IS_NAK 0x80 // RO, indicate current USB transfer is NAK received
|
||||
#define RB_U_TOG_OK 0x40 // RO, indicate current USB transfer toggle is OK
|
||||
#define RB_U_SIE_FREE 0x20 // RO, indicate USB SIE free status
|
||||
#define RB_UIF_FIFO_OV 0x10 // FIFO overflow interrupt flag for USB, direct bit address clear or write 1 to clear
|
||||
#define RB_UIF_HST_SOF 0x08 // host SOF timer interrupt flag for USB host, direct bit address clear or write 1 to clear
|
||||
#define RB_UIF_SUSPEND 0x04 // USB suspend or resume event interrupt flag, direct bit address clear or write 1 to clear
|
||||
#define RB_UIF_TRANSFER 0x02 // USB transfer completion interrupt flag, direct bit address clear or write 1 to clear
|
||||
#define RB_UIF_DETECT 0x01 // device detected event interrupt flag for USB host mode, direct bit address clear or write 1 to clear
|
||||
#define RB_UIF_BUS_RST 0x01 // bus reset event interrupt flag for USB device mode, direct bit address clear or write 1 to clear
|
||||
|
||||
#define RB_UIS_SETUP_ACT 0x80 // RO, indicate SETUP token & 8 bytes setup request received for USB device mode
|
||||
#define RB_UIS_TOG_OK 0x40 // RO, indicate current USB transfer toggle is OK
|
||||
#define RB_UIS_TOKEN1 0x20 // RO, current token PID code bit 1 received for USB device mode
|
||||
#define RB_UIS_TOKEN0 0x10 // RO, current token PID code bit 0 received for USB device mode
|
||||
#define MASK_UIS_TOKEN 0x30 // RO, bit mask of current token PID code received for USB device mode
|
||||
#define UIS_TOKEN_OUT 0x00
|
||||
#define UIS_TOKEN_SOF 0x10
|
||||
#define UIS_TOKEN_IN 0x20
|
||||
#define UIS_TOKEN_SETUP 0x30
|
||||
|
||||
#define MASK_UIS_ENDP 0x0F // RO, bit mask of current transfer endpoint number for USB device mode
|
||||
#define MASK_UIS_H_RES 0x0F // RO, bit mask of current transfer handshake response for USB host mode: 0000=no response, time out from device, others=handshake response PID received
|
||||
|
||||
#define R8_USB_RX_LEN (*((uint8_t *)0x40008008)) // USB receiving length
|
||||
#define RB_UEP1_RX_EN 0x80 // enable USB endpoint 1 receiving (OUT)
|
||||
#define RB_UEP1_TX_EN 0x40 // enable USB endpoint 1 transmittal (IN)
|
||||
#define RB_UEP1_BUF_MOD 0x10 // buffer mode of USB endpoint 1
|
||||
|
||||
#define RB_UEP4_RX_EN 0x08 // enable USB endpoint 4 receiving (OUT)
|
||||
#define RB_UEP4_TX_EN 0x04 // enable USB endpoint 4 transmittal (IN)
|
||||
|
||||
#define RB_UEP3_RX_EN 0x80 // enable USB endpoint 3 receiving (OUT)
|
||||
#define RB_UEP3_TX_EN 0x40 // enable USB endpoint 3 transmittal (IN)
|
||||
#define RB_UEP3_BUF_MOD 0x10 // buffer mode of USB endpoint 3
|
||||
#define RB_UEP2_RX_EN 0x08 // enable USB endpoint 2 receiving (OUT)
|
||||
#define RB_UEP2_TX_EN 0x04 // enable USB endpoint 2 transmittal (IN)
|
||||
#define RB_UEP2_BUF_MOD 0x01 // buffer mode of USB endpoint 2
|
||||
|
||||
#define RB_UEP7_RX_EN 0x20 // enable USB endpoint 7 receiving (OUT)
|
||||
#define RB_UEP7_TX_EN 0x10 // enable USB endpoint 7 transmittal (IN)
|
||||
#define RB_UEP6_RX_EN 0x08 // enable USB endpoint 6 receiving (OUT)
|
||||
#define RB_UEP6_TX_EN 0x04 // enable USB endpoint 6 transmittal (IN)
|
||||
#define RB_UEP5_RX_EN 0x02 // enable USB endpoint 5 receiving (OUT)
|
||||
#define RB_UEP5_TX_EN 0x01 // enable USB endpoint 5 transmittal (IN)
|
||||
|
||||
#define RB_UH_EP_TX_EN 0x40 // enable USB host OUT endpoint transmittal
|
||||
#define RB_UH_EP_TBUF_MOD 0x10 // buffer mode of USB host OUT endpoint
|
||||
|
||||
#define RB_UH_EP_RX_EN 0x08 // enable USB host IN endpoint receiving
|
||||
#define RB_UH_EP_RBUF_MOD 0x01 // buffer mode of USB host IN endpoint
|
||||
|
||||
#define RB_UEP_R_TOG 0x80 // expected data toggle flag of USB endpoint X receiving (OUT): 0=DATA0, 1=DATA1
|
||||
#define RB_UEP_T_TOG 0x40 // prepared data toggle flag of USB endpoint X transmittal (IN): 0=DATA0, 1=DATA1
|
||||
#define RB_UEP_AUTO_TOG 0x10 // enable automatic toggle after successful transfer completion on endpoint 1/2/3: 0=manual toggle, 1=automatic toggle
|
||||
#define RB_UEP_R_RES1 0x08 // handshake response type high bit for USB endpoint X receiving (OUT)
|
||||
#define RB_UEP_R_RES0 0x04 // handshake response type low bit for USB endpoint X receiving (OUT)
|
||||
#define MASK_UEP_R_RES 0x0C // bit mask of handshake response type for USB endpoint X receiving (OUT)
|
||||
#define UEP_R_RES_ACK 0x00
|
||||
#define UEP_R_RES_TOUT 0x04
|
||||
#define UEP_R_RES_NAK 0x08
|
||||
#define UEP_R_RES_STALL 0x0C
|
||||
|
||||
#define RB_UEP_T_RES1 0x02 // handshake response type high bit for USB endpoint X transmittal (IN)
|
||||
#define RB_UEP_T_RES0 0x01 // handshake response type low bit for USB endpoint X transmittal (IN)
|
||||
#define MASK_UEP_T_RES 0x03 // bit mask of handshake response type for USB endpoint X transmittal (IN)
|
||||
#define UEP_T_RES_ACK 0x00
|
||||
#define UEP_T_RES_TOUT 0x01
|
||||
#define UEP_T_RES_NAK 0x02
|
||||
#define UEP_T_RES_STALL 0x03
|
||||
|
||||
#define RB_UH_PRE_PID_EN 0x80 // USB host PRE PID enable for low speed device via hub
|
||||
#define RB_UH_SOF_EN 0x40 // USB host automatic SOF enable
|
||||
|
||||
#define R8_UH_EP_PID R8_UEP2_T_LEN // host endpoint and PID
|
||||
#define MASK_UH_TOKEN 0xF0 // bit mask of token PID for USB host transfer
|
||||
#define MASK_UH_ENDP 0x0F // bit mask of endpoint number for USB host transfer
|
||||
|
||||
#define R8_UH_RX_CTRL R8_UEP2_CTRL // host receiver endpoint control
|
||||
#define RB_UH_R_TOG 0x80 // expected data toggle flag of host receiving (IN): 0=DATA0, 1=DATA1
|
||||
#define RB_UH_R_AUTO_TOG 0x10 // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle
|
||||
#define RB_UH_R_RES 0x04 // prepared handshake response type for host receiving (IN): 0=ACK (ready), 1=no response, time out to device, for isochronous transactions
|
||||
|
||||
#define R8_UH_TX_LEN R8_UEP3_T_LEN // host transmittal endpoint transmittal length
|
||||
|
||||
#define RB_UH_T_TOG 0x40 // prepared data toggle flag of host transmittal (SETUP/OUT): 0=DATA0, 1=DATA1
|
||||
#define RB_UH_T_AUTO_TOG 0x10 // enable automatic toggle after successful transfer completion: 0=manual toggle, 1=automatic toggle
|
||||
#define RB_UH_T_RES 0x01 // expected handshake response type for host transmittal (SETUP/OUT): 0=ACK (ready), 1=no response, time out from device, for isochronous transactions
|
||||
|
||||
#define R16_PIN_ANALOG_IE (*((uint16_t *)0x4000101A)) // RW, analog pin enable and digital input disable
|
||||
#define RB_PIN_USB_IE 0x80 // RW, USB analog I/O enable: 0=analog I/O disable, 1=analog I/O enable
|
||||
#define RB_PIN_USB_DP_PU 0x40 // RW, USB UDP internal pullup resistance enable: 0=enable/disable by RB_UC_DEV_PU_EN, 1=enable pullup, replace RB_UC_DEV_PU_EN under sleep mode
|
||||
#define RB_PIN_USB2_IE 0x20 // RW, USB2 analog I/O enable: 0=analog I/O disable, 1=analog I/O enable
|
||||
#define RB_PIN_USB2_DP_PU 0x10 // RW, USB2 UDP internal pullup resistance enable: 0=enable/disable by RB_UC_DEV_PU_EN, 1=enable pullup, replace RB_UC_DEV_PU_EN under sleep mode
|
||||
/*!< USB Regs */
|
||||
typedef struct
|
||||
{
|
||||
__IO uint8_t USB_CTRL; /*!< 0x40008000 */
|
||||
union {
|
||||
__IO uint8_t UDEV_CTRL; /*!< 0x40008001 */
|
||||
__IO uint8_t UHOST_CTRL; /*!< 0x40008001 */
|
||||
};
|
||||
__IO uint8_t USB_INT_EN; /*!< 0x40008002 */
|
||||
__IO uint8_t USB_DEV_AD; /*!< 0x40008003 */
|
||||
__IO uint8_t USB_STATUS0; /*!< 0x40008004 */
|
||||
__IO uint8_t USB_MIS_ST; /*!< 0x40008005 */
|
||||
__IO uint8_t USB_INT_FG; /*!< 0x40008006 */
|
||||
__IO uint8_t USB_INT_ST; /*!< 0x40008007 */
|
||||
__IO uint8_t USB_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 */
|
||||
union {
|
||||
__IO uint8_t UEP2_3_MOD; /*!< 0x4000800d */
|
||||
__IO uint8_t UH_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 */
|
||||
union {
|
||||
__IO uint16_t UEP2_DMA; /*!< 0x40008018 */
|
||||
__IO uint16_t UH_RX_DMA; /*!< 0x40008018 */
|
||||
};
|
||||
__IO uint16_t Reserve7; /*!< 0x4000801a */
|
||||
union {
|
||||
__IO uint16_t UEP3_DMA; /*!< 0x4000801c */
|
||||
__IO uint16_t UH_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 */
|
||||
union {
|
||||
__IO uint8_t UEP1_CTRL; /*!< 0x40008026 */
|
||||
__IO uint8_t UH_SETUP; /*!< 0x40008026 */
|
||||
};
|
||||
__IO uint8_t Reserve12; /*!< 0x40008027 */
|
||||
union {
|
||||
__IO uint8_t UEP2_T_LEN; /*!< 0x40008028 */
|
||||
__IO uint8_t UH_EP_PID; /*!< 0x40008028 */
|
||||
};
|
||||
__IO uint8_t Reserve13; /*!< 0x40008029 */
|
||||
union {
|
||||
__IO uint8_t UEP2_CTRL; /*!< 0x4000802a */
|
||||
__IO uint8_t UH_RX_CTRL; /*!< 0x4000802a */
|
||||
};
|
||||
__IO uint8_t Reserve14; /*!< 0x4000802b */
|
||||
union {
|
||||
__IO uint8_t UEP3_T_LEN; /*!< 0x4000802c */
|
||||
__IO uint8_t UH_TX_LEN; /*!< 0x4000802c */
|
||||
};
|
||||
__IO uint8_t Reserve15; /*!< 0x4000802d */
|
||||
union {
|
||||
__IO uint8_t UEP3_CTRL; /*!< 0x4000802e */
|
||||
__IO uint8_t UH_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;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -27,7 +27,7 @@ CONFIG_USBDEV_EP_NUM 必须为4 或者 6,并删除 usb_dc_dwc2.c 中 while(1){
|
|||
|
||||
- GD32F30X_CL
|
||||
- GD32F405、GD32F407
|
||||
- GD32F450
|
||||
- GD32F350、GD32F450
|
||||
|
||||
## HC32
|
||||
|
||||
|
@ -35,7 +35,7 @@ CONFIG_USBDEV_EP_NUM 必须为4 或者 6,并删除 usb_dc_dwc2.c 中 while(1){
|
|||
|
||||
## Espressif
|
||||
|
||||
- ESP32S2、ESP32S3
|
||||
- ESP32S2、ESP32S3、ESP32P4
|
||||
|
||||
## Sophgo
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "esp_private/usb_phy.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "usbd_core.h"
|
||||
#include "usbh_core.h"
|
||||
|
||||
|
|
|
@ -194,8 +194,6 @@ uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base)
|
|||
USB_OTG_GLB->GCCFG = (1 << 23);
|
||||
usb_hsphy_init(25000000U);
|
||||
return (1 << 23); /* Enable USB HS PHY USBx->GCCFG |= USB_OTG_GCCFG_PHYHSEN;*/
|
||||
#elif __has_include("stm32h7rsxx.h")
|
||||
return (1 << 21);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
|
|
@ -41,6 +41,7 @@ struct dwc2_chan {
|
|||
uint32_t xferlen;
|
||||
uint8_t chidx;
|
||||
bool inuse;
|
||||
bool dir_in;
|
||||
usb_osal_sem_t waitsem;
|
||||
struct usbh_urb *urb;
|
||||
uint32_t iso_frame_idx;
|
||||
|
@ -256,16 +257,26 @@ static void dwc2_chan_init(struct usbh_bus *bus, uint8_t ch_num, uint8_t devaddr
|
|||
}
|
||||
|
||||
/* For IN channel HCTSIZ.XferSize is expected to be an integer multiple of ep_mps size.*/
|
||||
static inline void dwc2_chan_transfer(struct usbh_bus *bus, uint8_t ch_num, uint8_t ep_addr, uint32_t *buf, uint32_t size, uint8_t num_packets, uint8_t pid)
|
||||
static inline void dwc2_chan_transfer(struct usbh_bus *bus, uint8_t ch_num, uint8_t ep_addr, uint8_t *buf, uint32_t size, uint8_t num_packets, uint8_t pid)
|
||||
{
|
||||
__IO uint32_t tmpreg;
|
||||
uint8_t is_oddframe;
|
||||
struct dwc2_chan *chan;
|
||||
|
||||
chan = &g_dwc2_hcd[bus->hcd.hcd_id].chan_pool[ch_num];
|
||||
|
||||
/* Initialize the HCTSIZn register */
|
||||
USB_OTG_HC(ch_num)->HCTSIZ = (size & USB_OTG_HCTSIZ_XFRSIZ) |
|
||||
(((uint32_t)num_packets << 19) & USB_OTG_HCTSIZ_PKTCNT) |
|
||||
(((uint32_t)pid << 29) & USB_OTG_HCTSIZ_DPID);
|
||||
|
||||
if (!(ep_addr & 0x80)) {
|
||||
chan->dir_in = false;
|
||||
usb_dcache_clean((uintptr_t)buf, USB_ALIGN_UP(size, CONFIG_USB_ALIGN_SIZE));
|
||||
} else {
|
||||
chan->dir_in = true;
|
||||
}
|
||||
|
||||
/* xfer_buff MUST be 32-bits aligned */
|
||||
USB_OTG_HC(ch_num)->HCDMA = (uint32_t)buf;
|
||||
|
||||
|
@ -400,17 +411,17 @@ static void dwc2_control_urb_init(struct usbh_bus *bus, uint8_t chidx, struct us
|
|||
{
|
||||
chan->num_packets = dwc2_calculate_packet_num(8, 0x00, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
|
||||
dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
|
||||
dwc2_chan_transfer(bus, chidx, 0x00, (uint32_t *)setup, chan->xferlen, chan->num_packets, HC_PID_SETUP);
|
||||
dwc2_chan_transfer(bus, chidx, 0x00, (uint8_t *)setup, chan->xferlen, chan->num_packets, HC_PID_SETUP);
|
||||
} else if (chan->ep0_state == DWC2_EP0_STATE_INDATA) /* fill in data */
|
||||
{
|
||||
chan->num_packets = dwc2_calculate_packet_num(setup->wLength, 0x80, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
|
||||
dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x80, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
|
||||
dwc2_chan_transfer(bus, chidx, 0x80, (uint32_t *)buffer, chan->xferlen, chan->num_packets, HC_PID_DATA1);
|
||||
dwc2_chan_transfer(bus, chidx, 0x80, buffer, chan->xferlen, chan->num_packets, HC_PID_DATA1);
|
||||
} else if (chan->ep0_state == DWC2_EP0_STATE_OUTDATA) /* fill out data */
|
||||
{
|
||||
chan->num_packets = dwc2_calculate_packet_num(setup->wLength, 0x00, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
|
||||
dwc2_chan_init(bus, chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
|
||||
dwc2_chan_transfer(bus, chidx, 0x00, (uint32_t *)buffer, chan->xferlen, chan->num_packets, HC_PID_DATA1);
|
||||
dwc2_chan_transfer(bus, chidx, 0x00, buffer, chan->xferlen, chan->num_packets, HC_PID_DATA1);
|
||||
} else if (chan->ep0_state == DWC2_EP0_STATE_INSTATUS) /* fill in status */
|
||||
{
|
||||
chan->num_packets = dwc2_calculate_packet_num(0, 0x80, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
|
||||
|
@ -432,9 +443,10 @@ static void dwc2_bulk_intr_urb_init(struct usbh_bus *bus, uint8_t chidx, struct
|
|||
|
||||
chan->num_packets = dwc2_calculate_packet_num(buflen, urb->ep->bEndpointAddress, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
|
||||
dwc2_chan_init(bus, chidx, urb->hport->dev_addr, urb->ep->bEndpointAddress, USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes), USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
|
||||
dwc2_chan_transfer(bus, chidx, urb->ep->bEndpointAddress, (uint32_t *)buffer, chan->xferlen, chan->num_packets, urb->data_toggle == 0 ? HC_PID_DATA0 : HC_PID_DATA1);
|
||||
dwc2_chan_transfer(bus, chidx, urb->ep->bEndpointAddress, buffer, chan->xferlen, chan->num_packets, urb->data_toggle == 0 ? HC_PID_DATA0 : HC_PID_DATA1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void dwc2_iso_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb, struct usbh_iso_frame_packet *iso_packet)
|
||||
{
|
||||
struct dwc2_chan *chan;
|
||||
|
@ -443,8 +455,9 @@ static void dwc2_iso_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_u
|
|||
|
||||
chan->num_packets = dwc2_calculate_packet_num(iso_packet->transfer_buffer_length, urb->ep->bEndpointAddress, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), &chan->xferlen);
|
||||
dwc2_chan_init(bus, chidx, urb->hport->dev_addr, urb->ep->bEndpointAddress, USB_ENDPOINT_TYPE_ISOCHRONOUS, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize), urb->hport->speed);
|
||||
dwc2_chan_transfer(bus, chidx, urb->ep->bEndpointAddress, (uint32_t *)iso_packet->transfer_buffer, chan->xferlen, chan->num_packets, HC_PID_DATA0);
|
||||
dwc2_chan_transfer(bus, chidx, urb->ep->bEndpointAddress, iso_packet->transfer_buffer, chan->xferlen, chan->num_packets, HC_PID_DATA0);
|
||||
}
|
||||
#endif
|
||||
|
||||
__WEAK void usb_hc_low_level_init(struct usbh_bus *bus)
|
||||
{
|
||||
|
@ -754,6 +767,13 @@ int usbh_submit_urb(struct usbh_urb *urb)
|
|||
return -USB_ERR_INVAL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
if (((uintptr_t)urb->setup % CONFIG_USB_ALIGN_SIZE) || ((uintptr_t)urb->transfer_buffer % CONFIG_USB_ALIGN_SIZE)) {
|
||||
USB_LOG_ERR("urb buffer is not align with %d\r\n", CONFIG_USB_ALIGN_SIZE);
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
bus = urb->hport->bus;
|
||||
|
||||
if (!(USB_OTG_HPRT & USB_OTG_HPRT_PCSTS) || !urb->hport->connected) {
|
||||
|
@ -907,7 +927,7 @@ static void dwc2_inchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num)
|
|||
urb->errorcode = 0;
|
||||
|
||||
uint32_t count = chan->xferlen - (USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ); /* how many size has received */
|
||||
uint32_t has_used_packets = chan->num_packets - ((USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) >> 19); /* how many packets have used */
|
||||
//uint32_t has_used_packets = chan->num_packets - ((USB_OTG_HC(ch_num)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) >> 19); /* how many packets have used */
|
||||
|
||||
urb->actual_length += count;
|
||||
|
||||
|
@ -919,6 +939,10 @@ static void dwc2_inchan_irq_handler(struct usbh_bus *bus, uint8_t ch_num)
|
|||
urb->data_toggle = 1;
|
||||
}
|
||||
|
||||
if (chan->dir_in) {
|
||||
usb_dcache_invalidate((uintptr_t)urb->transfer_buffer, USB_ALIGN_UP(count, CONFIG_USB_ALIGN_SIZE));
|
||||
}
|
||||
|
||||
if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_CONTROL) {
|
||||
if (chan->ep0_state == DWC2_EP0_STATE_INDATA) {
|
||||
chan->ep0_state = DWC2_EP0_STATE_OUTSTATUS;
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
### AllwinnerTech
|
||||
|
||||
- F133
|
||||
- F133/T113
|
||||
|
||||
### Nuvoton
|
||||
|
||||
|
|
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
* Copyright (c) 2025, YC113
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbh_core.h"
|
||||
#include "usb_hc_ehci.h"
|
||||
#include "usb_hc_ohci.h"
|
||||
|
||||
#include "interrupt.h"
|
||||
#include "drv_reg_base.h"
|
||||
#include "drv_clock.h"
|
||||
|
||||
#if !defined(CONFIG_USB_EHCI_WITH_OHCI)
|
||||
#error "t113 must define CONFIG_USB_EHCI_WITH_OHCI for ls/fs device"
|
||||
#endif
|
||||
|
||||
#if CONFIG_USBHOST_MAX_BUS != 2
|
||||
#error "t113 has 2 usb host controller"
|
||||
#endif
|
||||
|
||||
#if CONFIG_USB_OHCI_HCOR_OFFSET != 0x400
|
||||
#error "t113 CONFIG_USB_OHCI_HCOR_OFFSET must be 0x400"
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_USB_EHCI_HCOR_RESERVED_DISABLE)
|
||||
#error "t113 usb ehci register need reserved"
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_USB_EHCI_CONFIGFLAG)
|
||||
#error "t113 usb ehci has configflag register"
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_USB_EHCI_ISO)
|
||||
#error "t113 usb ehci no iso register"
|
||||
#endif
|
||||
|
||||
void usb_select_phyTohci(void)
|
||||
{
|
||||
*(volatile rt_uint32_t *)(USB0_OTG_BASE_ADDR + 0x420) &= ~(1 << 0);
|
||||
}
|
||||
|
||||
void usb_gate_open(rt_uint8_t busid)
|
||||
{
|
||||
rt_uint32_t addr;
|
||||
|
||||
/* otg bus reset and gate open */
|
||||
if (busid == 0)
|
||||
usb_select_phyTohci();
|
||||
|
||||
/* reset phy */
|
||||
addr = (rt_uint32_t)&CCU->usb0_clk + busid * 4;
|
||||
*(volatile rt_uint32_t *)addr &= ~(1 << 30);
|
||||
sdelay(10);
|
||||
*(volatile rt_uint32_t *)addr |= 1 << 30;
|
||||
sdelay(10);
|
||||
|
||||
/* ehci bus reset */
|
||||
CCU->usb_bgr &= ~((1 << 20) << busid);
|
||||
sdelay(10);
|
||||
CCU->usb_bgr |= (1 << 20) << busid;
|
||||
sdelay(10);
|
||||
|
||||
/* ehci gate open */
|
||||
CCU->usb_bgr |= (1 << 4) << busid;
|
||||
|
||||
/* ohci bus reset */
|
||||
CCU->usb_bgr &= ~((1 << 16) << busid);
|
||||
sdelay(10);
|
||||
CCU->usb_bgr |= (1 << 16) << busid;
|
||||
sdelay(10);
|
||||
|
||||
/* ohci gate open */
|
||||
CCU->usb_bgr |= 1 << busid;
|
||||
|
||||
sdelay(10);
|
||||
|
||||
/* clock enable */
|
||||
*(volatile rt_uint32_t *)addr &= ~(3 << 24);
|
||||
*(volatile rt_uint32_t *)addr |= (1 << 31) | (1 << 24);
|
||||
|
||||
USB_LOG_DBG("usb%d gate : %X, clock : %X\n", busid, CCU->usb_bgr, *(volatile rt_uint32_t *)addr);
|
||||
}
|
||||
|
||||
void usb_clean_siddp(struct usbh_bus *bus)
|
||||
{
|
||||
*(volatile rt_uint32_t *)(bus->hcd.reg_base + 0x810) &= ~(1 << 3);
|
||||
}
|
||||
|
||||
static void usb_new_phyx_tp_write(struct usbh_bus *bus, int addr, int data, int len)
|
||||
{
|
||||
rt_uint32_t base = bus->hcd.reg_base;
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
*(volatile rt_uint8_t *)(base + 0x810) |= 1 << 1;
|
||||
|
||||
*(volatile rt_uint8_t *)(base + 0x810 + 1) = addr + i;
|
||||
|
||||
*(volatile rt_uint8_t *)(base + 0x810) &= ~(1 << 0);
|
||||
|
||||
*(volatile rt_uint8_t *)(base + 0x810) &= ~(1 << 7);
|
||||
*(volatile rt_uint8_t *)(base + 0x810) |= (data & 0x1) << 7;
|
||||
|
||||
*(volatile rt_uint8_t *)(base + 0x810) |= 1 << 0;
|
||||
|
||||
*(volatile rt_uint8_t *)(base + 0x810) &= ~(1 << 0);
|
||||
|
||||
*(volatile rt_uint8_t *)(base + 0x810) &= ~(1 << 1);
|
||||
|
||||
data >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
void usb_new_phy_init(struct usbh_bus *bus)
|
||||
{
|
||||
rt_int32_t value = 0;
|
||||
rt_uint32_t efuse_val = 0x1E5080F;
|
||||
|
||||
usb_new_phyx_tp_write(bus, 0x1C, 0x0, 0x03);
|
||||
|
||||
/* vref mode */
|
||||
usb_new_phyx_tp_write(bus, 0x60, 0x0, 0x01);
|
||||
|
||||
value = (efuse_val & 0x3C0000) >> 18;
|
||||
usb_new_phyx_tp_write(bus, 0x44, value, 0x04);
|
||||
|
||||
value = (efuse_val & 0x1C00000) >> 22;
|
||||
usb_new_phyx_tp_write(bus, 0x36, value, 0x03);
|
||||
}
|
||||
|
||||
void usb_hci_set_passby(struct usbh_bus *bus)
|
||||
{
|
||||
/* AHB Master interface INCR16 enable */
|
||||
/* AHB Master interface INCR8 enable */
|
||||
/* AHB Master interface burst type INCR4 enable */
|
||||
/* AHB Master interface INCRX align enable */
|
||||
/* ULPI bypass enable */
|
||||
*(volatile rt_uint32_t *)(bus->hcd.reg_base + 0x800) |= (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 0);
|
||||
}
|
||||
|
||||
void t113_ehci_isr(int vector, void *arg)
|
||||
{
|
||||
struct usbh_bus *bus = (struct usbh_bus *)arg;
|
||||
|
||||
USB_LOG_DBG("t113_ehci_isr");
|
||||
|
||||
extern void USBH_IRQHandler(uint8_t busid);
|
||||
USBH_IRQHandler(bus->hcd.hcd_id);
|
||||
}
|
||||
|
||||
void t113_ohci_isr(int vector, void *arg)
|
||||
{
|
||||
struct usbh_bus *bus = (struct usbh_bus *)arg;
|
||||
|
||||
USB_LOG_DBG("t113_ohci_isr");
|
||||
|
||||
extern void OHCI_IRQHandler(uint8_t busid);
|
||||
OHCI_IRQHandler(bus->hcd.hcd_id);
|
||||
}
|
||||
|
||||
void usb_hc_low_level_init(struct usbh_bus *bus)
|
||||
{
|
||||
int vector;
|
||||
RT_ASSERT(bus->busid <= 1);
|
||||
|
||||
usb_gate_open(bus->busid);
|
||||
usb_clean_siddp(bus);
|
||||
usb_hci_set_passby(bus);
|
||||
|
||||
/* register EHCI interrupt callback */
|
||||
vector = T113_IRQ_USB0_EHCI + (bus->busid > 0 ? 3 : 0);
|
||||
rt_hw_interrupt_install(vector, t113_ehci_isr, bus, RT_NULL);
|
||||
rt_hw_interrupt_umask(vector);
|
||||
|
||||
/* register OHCI interrupt callback */
|
||||
rt_hw_interrupt_install(vector + 1, t113_ohci_isr, bus, RT_NULL);
|
||||
rt_hw_interrupt_umask(vector + 1);
|
||||
|
||||
USB_LOG_DBG("usb%d vector : %d, phy : %X\n", bus->busid, vector, *(volatile rt_uint32_t *)(bus->hcd.reg_base + 0x810));
|
||||
USB_LOG_DBG("usb%d hc low level init success\n", bus->busid);
|
||||
}
|
||||
|
||||
uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port)
|
||||
{
|
||||
/* Defined by individual manufacturers */
|
||||
uint32_t regval;
|
||||
|
||||
regval = EHCI_HCOR->portsc[port - 1];
|
||||
if ((regval & EHCI_PORTSC_LSTATUS_MASK) == EHCI_PORTSC_LSTATUS_KSTATE)
|
||||
return USB_SPEED_LOW;
|
||||
|
||||
if (regval & EHCI_PORTSC_PE)
|
||||
return USB_SPEED_HIGH;
|
||||
else
|
||||
return USB_SPEED_FULL;
|
||||
}
|
||||
|
||||
int __usbh_init(void)
|
||||
{
|
||||
#ifdef T113_USING_USB0_HOST
|
||||
/* USB0 MSC test OK */
|
||||
usbh_initialize(0, USB0_BASE_ADDR);
|
||||
#endif
|
||||
|
||||
#ifdef T113_USING_USB1_HOST
|
||||
/* USB1 MSC test OK */
|
||||
usbh_initialize(1, USB1_BASE_ADDR);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef PKG_CHERRYUSB_HOST
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
INIT_ENV_EXPORT(__usbh_init);
|
||||
|
||||
#endif
|
|
@ -76,10 +76,36 @@ static void ehci_qh_free(struct usbh_bus *bus, struct ehci_qh_hw *qh)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
static inline void usb_ehci_qh_qtd_flush(struct ehci_qh_hw *qh)
|
||||
{
|
||||
struct ehci_qtd_hw *qtd;
|
||||
|
||||
qtd = EHCI_ADDR2QTD(qh->first_qtd);
|
||||
|
||||
while (qtd) {
|
||||
usb_dcache_clean((uintptr_t)&qtd->hw, USB_ALIGN_UP(SIZEOF_EHCI_QTD, CONFIG_USB_EHCI_ALIGN_SIZE));
|
||||
|
||||
if (!qtd->dir_in) {
|
||||
usb_dcache_clean(qtd->bufaddr, USB_ALIGN_UP(qtd->length, CONFIG_USB_ALIGN_SIZE));
|
||||
}
|
||||
qtd = EHCI_ADDR2QTD(qtd->hw.next_qtd);
|
||||
}
|
||||
|
||||
usb_dcache_clean((uintptr_t)&qh->hw, USB_ALIGN_UP(SIZEOF_EHCI_QH, CONFIG_USB_EHCI_ALIGN_SIZE));
|
||||
}
|
||||
#else
|
||||
#define usb_ehci_qh_qtd_flush(qh)
|
||||
#endif
|
||||
|
||||
static inline void ehci_qh_add_head(struct ehci_qh_hw *head, struct ehci_qh_hw *n)
|
||||
{
|
||||
n->hw.hlp = head->hw.hlp;
|
||||
usb_ehci_qh_qtd_flush(n);
|
||||
|
||||
head->hw.hlp = QH_HLP_QH(n);
|
||||
|
||||
usb_dcache_clean((uintptr_t)&head->hw, USB_ALIGN_UP(SIZEOF_EHCI_QH, CONFIG_USB_EHCI_ALIGN_SIZE));
|
||||
}
|
||||
|
||||
static inline void ehci_qh_remove(struct ehci_qh_hw *head, struct ehci_qh_hw *n)
|
||||
|
@ -92,6 +118,7 @@ static inline void ehci_qh_remove(struct ehci_qh_hw *head, struct ehci_qh_hw *n)
|
|||
|
||||
if (tmp) {
|
||||
tmp->hw.hlp = n->hw.hlp;
|
||||
usb_dcache_clean((uintptr_t)&tmp->hw, USB_ALIGN_UP(SIZEOF_EHCI_QH, CONFIG_USB_EHCI_ALIGN_SIZE));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,7 +281,9 @@ static void ehci_qtd_fill(struct ehci_qtd_hw *qtd, uint32_t bufaddr, size_t bufl
|
|||
|
||||
qtd->hw.token = token;
|
||||
|
||||
ehci_qtd_bpl_fill(qtd, bufaddr, buflen);
|
||||
ehci_qtd_bpl_fill(qtd, usb_phyaddr2ramaddr(bufaddr), buflen);
|
||||
qtd->dir_in = ((token & QTD_TOKEN_PID_MASK) == QTD_TOKEN_PID_IN) ? true : false;
|
||||
qtd->bufaddr = bufaddr;
|
||||
qtd->length = buflen;
|
||||
}
|
||||
|
||||
|
@ -591,6 +620,9 @@ static void ehci_qh_scan_qtds(struct usbh_bus *bus, struct ehci_qh_hw *qhead, st
|
|||
qtd = EHCI_ADDR2QTD(qh->first_qtd);
|
||||
|
||||
while (qtd) {
|
||||
if (qtd->dir_in) {
|
||||
usb_dcache_invalidate(qtd->bufaddr, USB_ALIGN_UP(qtd->length - ((qtd->hw.token & QTD_TOKEN_NBYTES_MASK) >> QTD_TOKEN_NBYTES_SHIFT), CONFIG_USB_ALIGN_SIZE));
|
||||
}
|
||||
qtd->urb->actual_length += (qtd->length - ((qtd->hw.token & QTD_TOKEN_NBYTES_MASK) >> QTD_TOKEN_NBYTES_SHIFT));
|
||||
|
||||
qh->first_qtd = qtd->hw.next_qtd;
|
||||
|
@ -611,6 +643,7 @@ static void ehci_check_qh(struct usbh_bus *bus, struct ehci_qh_hw *qhead, struct
|
|||
}
|
||||
|
||||
while (qtd) {
|
||||
usb_dcache_invalidate((uintptr_t)&qtd->hw, USB_ALIGN_UP(SIZEOF_EHCI_QTD, CONFIG_USB_EHCI_ALIGN_SIZE));
|
||||
token = qtd->hw.token;
|
||||
|
||||
if (token & QTD_TOKEN_STATUS_ERRORS) {
|
||||
|
@ -766,6 +799,10 @@ int usb_hc_init(struct usbh_bus *bus)
|
|||
g_framelist[bus->hcd.hcd_id][i] = QH_HLP_QH(&g_periodic_qh_head[bus->hcd.hcd_id]);
|
||||
}
|
||||
|
||||
usb_dcache_clean((uintptr_t)&g_async_qh_head[bus->hcd.hcd_id].hw, USB_ALIGN_UP(SIZEOF_EHCI_QH, CONFIG_USB_EHCI_ALIGN_SIZE));
|
||||
usb_dcache_clean((uintptr_t)&g_periodic_qh_head[bus->hcd.hcd_id].hw, USB_ALIGN_UP(SIZEOF_EHCI_QH, CONFIG_USB_EHCI_ALIGN_SIZE));
|
||||
usb_dcache_clean((uintptr_t)g_framelist[bus->hcd.hcd_id], sizeof(uint32_t) * CONFIG_USB_EHCI_FRAME_LIST_SIZE);
|
||||
|
||||
usb_hc_low_level_init(bus);
|
||||
|
||||
USB_LOG_INFO("EHCI HCIVERSION:0x%04x\r\n", (unsigned int)EHCI_HCCR->hciversion);
|
||||
|
@ -1138,6 +1175,13 @@ int usbh_submit_urb(struct usbh_urb *urb)
|
|||
return -USB_ERR_INVAL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USB_DCACHE_ENABLE
|
||||
if (((uintptr_t)urb->setup % CONFIG_USB_ALIGN_SIZE) || ((uintptr_t)urb->transfer_buffer % CONFIG_USB_ALIGN_SIZE)) {
|
||||
USB_LOG_ERR("urb buffer is not align with %d\r\n", CONFIG_USB_ALIGN_SIZE);
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
bus = urb->hport->bus;
|
||||
|
||||
/* find active hubport in roothub */
|
||||
|
|
|
@ -30,14 +30,19 @@
|
|||
#ifndef CONFIG_USB_EHCI_ISO_NUM
|
||||
#define CONFIG_USB_EHCI_ISO_NUM 4
|
||||
#endif
|
||||
#ifndef CONFIG_USB_EHCI_ALIGN_SIZE
|
||||
#define CONFIG_USB_EHCI_ALIGN_SIZE 64
|
||||
#endif
|
||||
|
||||
extern uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port);
|
||||
|
||||
struct ehci_qtd_hw {
|
||||
struct ehci_qtd hw;
|
||||
struct usbh_urb *urb;
|
||||
bool dir_in;
|
||||
uintptr_t bufaddr;
|
||||
uint32_t length;
|
||||
} __attribute__((aligned(32)));
|
||||
} __attribute__((aligned(CONFIG_USB_EHCI_ALIGN_SIZE)));
|
||||
|
||||
struct ehci_qh_hw {
|
||||
struct ehci_qh hw;
|
||||
|
@ -46,7 +51,7 @@ struct ehci_qh_hw {
|
|||
struct usbh_urb *urb;
|
||||
usb_osal_sem_t waitsem;
|
||||
uint8_t remove_in_iaad;
|
||||
} __attribute__((aligned(32)));
|
||||
} __attribute__((aligned(CONFIG_USB_EHCI_ALIGN_SIZE)));
|
||||
|
||||
struct ehci_itd_hw {
|
||||
struct ehci_itd hw;
|
||||
|
@ -55,7 +60,8 @@ struct ehci_itd_hw {
|
|||
uint8_t mf_unmask;
|
||||
uint8_t mf_valid;
|
||||
uint32_t pkt_idx[8];
|
||||
} __attribute__((aligned(32)));
|
||||
bool dir_in;
|
||||
} __attribute__((aligned(CONFIG_USB_EHCI_ALIGN_SIZE)));
|
||||
|
||||
struct ehci_iso_hw
|
||||
{
|
||||
|
|
|
@ -23,10 +23,7 @@
|
|||
|
||||
## GD32
|
||||
|
||||
- GD32F10X_MD、GD32F10X_HD、GD32F10X_XD
|
||||
- GD32F30X_HD、GD32F30X_XD
|
||||
- GD32F350
|
||||
- GD32F407
|
||||
- GD32F10X
|
||||
|
||||
## CH32
|
||||
|
||||
|
|
|
@ -869,12 +869,7 @@ void handle_ep0(struct usbh_bus *bus)
|
|||
break;
|
||||
case USB_EP0_STATE_IN_DATA:
|
||||
if (ep0_status & USB_CSRL0_RXRDY) {
|
||||
size = urb->transfer_buffer_length;
|
||||
if (size > USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) {
|
||||
size = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize);
|
||||
}
|
||||
|
||||
size = MIN(size, HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET));
|
||||
size = HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET);
|
||||
musb_read_packet(bus, 0, urb->transfer_buffer, size);
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_CSRL0_RXRDY;
|
||||
urb->transfer_buffer += size;
|
||||
|
@ -933,6 +928,7 @@ void USBH_IRQHandler(uint8_t busid)
|
|||
uint8_t ep_idx;
|
||||
uint8_t old_ep_idx;
|
||||
struct usbh_bus *bus;
|
||||
uint32_t size;
|
||||
|
||||
bus = &g_usbhost_bus[busid];
|
||||
|
||||
|
@ -1024,7 +1020,7 @@ void USBH_IRQHandler(uint8_t busid)
|
|||
urb->errorcode = 0;
|
||||
musb_urb_waitup(urb);
|
||||
} else {
|
||||
musb_write_packet(bus, ep_idx, urb->transfer_buffer, size);
|
||||
musb_write_packet(bus, ep_idx, urb->transfer_buffer, MIN(urb->transfer_buffer_length, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)));
|
||||
HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
|
||||
}
|
||||
}
|
||||
|
@ -1056,11 +1052,7 @@ void USBH_IRQHandler(uint8_t busid)
|
|||
urb->errorcode = -USB_ERR_STALL;
|
||||
musb_urb_waitup(urb);
|
||||
} else if (ep_csrl_status & USB_RXCSRL1_RXRDY) {
|
||||
uint32_t size = urb->transfer_buffer_length;
|
||||
if (size > USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) {
|
||||
size = USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize);
|
||||
}
|
||||
size = MIN(size, HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET));
|
||||
size = HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET);
|
||||
|
||||
musb_read_packet(bus, ep_idx, urb->transfer_buffer, size);
|
||||
|
||||
|
|
|
@ -22,14 +22,18 @@
|
|||
#ifndef CONFIG_USB_OHCI_TD_NUM
|
||||
#define CONFIG_USB_OHCI_TD_NUM 3
|
||||
#endif
|
||||
#ifndef CONFIG_USB_OHCI_ALIGN_SIZE
|
||||
#define CONFIG_USB_OHCI_ALIGN_SIZE 64
|
||||
#endif
|
||||
|
||||
struct ohci_ed_hw;
|
||||
struct ohci_td_hw {
|
||||
struct ohci_gtd hw;
|
||||
struct usbh_urb *urb;
|
||||
bool dir_in;
|
||||
uint32_t buf_start;
|
||||
uint32_t length;
|
||||
} __attribute__((aligned(32))); /* min is 16bytes, we use 32 for cacheline */
|
||||
} __attribute__((aligned(CONFIG_USB_OHCI_ALIGN_SIZE))); /* min is 16bytes, we use CONFIG_USB_OHCI_ALIGN_SIZE for cacheline */
|
||||
|
||||
struct ohci_ed_hw {
|
||||
struct ohci_ed hw;
|
||||
|
@ -37,7 +41,7 @@ struct ohci_ed_hw {
|
|||
uint32_t td_count;
|
||||
uint8_t ed_type;
|
||||
usb_osal_sem_t waitsem;
|
||||
} __attribute__((aligned(32))); /* min is 16bytes, we use 32 for cacheline */
|
||||
} __attribute__((aligned(CONFIG_USB_OHCI_ALIGN_SIZE))); /* min is 16bytes, we use CONFIG_USB_OHCI_ALIGN_SIZE for cacheline */
|
||||
|
||||
struct ohci_hcd {
|
||||
bool ohci_ed_used[CONFIG_USB_OHCI_ED_NUM];
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# Note
|
||||
|
||||
## Support Chip List
|
||||
|
||||
- RP2040/RP2350
|
|
@ -0,0 +1,588 @@
|
|||
/*
|
||||
* Copyright (c) 2022, HaiMianBBao
|
||||
* Copyright (c) 2025, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbd_core.h"
|
||||
#include "hardware/resets.h"
|
||||
#include "hardware/irq.h"
|
||||
#include "hardware/structs/usb.h"
|
||||
#if CHERRYUSB_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX
|
||||
#include "pico/fix/rp2040_usb_device_enumeration.h"
|
||||
#endif
|
||||
|
||||
#define usb_hw_set hw_set_alias(usb_hw)
|
||||
#define usb_hw_clear hw_clear_alias(usb_hw)
|
||||
|
||||
#ifndef CONFIG_USBDEV_EP_NUM
|
||||
#define CONFIG_USBDEV_EP_NUM 16
|
||||
#endif
|
||||
|
||||
#ifndef FORCE_VBUS_DETECT
|
||||
#define FORCE_VBUS_DETECT 1
|
||||
#endif
|
||||
|
||||
/* Endpoint state */
|
||||
struct rp2040_ep_state {
|
||||
uint16_t ep_mps; /* Endpoint max packet size */
|
||||
uint8_t ep_type; /* Endpoint type */
|
||||
uint8_t ep_stalled; /* Endpoint stall flag */
|
||||
uint8_t ep_enable; /* Endpoint enable */
|
||||
uint8_t ep_addr; /* Endpoint address */
|
||||
uint8_t *xfer_buf;
|
||||
uint32_t xfer_len;
|
||||
uint32_t actual_xfer_len;
|
||||
|
||||
volatile uint32_t *endpoint_control; /*!< Endpoint control register */
|
||||
volatile uint32_t *buffer_control; /*!< Buffer control register */
|
||||
uint8_t *data_buffer; /*!< Buffer pointer in usb dpram */
|
||||
uint8_t next_pid; /*!< Toggle after each packet (unless replying to a SETUP) */
|
||||
};
|
||||
|
||||
/* Driver state */
|
||||
struct rp2040_udc {
|
||||
volatile uint8_t dev_addr;
|
||||
struct rp2040_ep_state in_ep[CONFIG_USBDEV_EP_NUM]; /*!< IN endpoint parameters*/
|
||||
struct rp2040_ep_state out_ep[CONFIG_USBDEV_EP_NUM]; /*!< OUT endpoint parameters */
|
||||
struct usb_setup_packet setup; /*!< Setup package that may be used in interrupt processing (outside the protocol stack) */
|
||||
} g_rp2040_udc;
|
||||
|
||||
void rp2040_usbd_irq(void);
|
||||
|
||||
/**
|
||||
* @brief Take a buffer pointer located in the USB RAM and return as an offset of the RAM.
|
||||
*
|
||||
* @param buf
|
||||
* @return uint32_t
|
||||
*/
|
||||
static inline uint32_t usb_buffer_offset(volatile uint8_t *buf)
|
||||
{
|
||||
return (uint32_t)buf ^ (uint32_t)usb_dpram;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set up the endpoint control register for an endpoint (if applicable. Not valid for EP0).
|
||||
*
|
||||
* @param ep
|
||||
*/
|
||||
void usb_setup_endpoint(const struct rp2040_ep_state *ep)
|
||||
{
|
||||
// EP0 doesn't have one so return if that is the case
|
||||
if (!ep->endpoint_control) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the data buffer as an offset of the USB controller's DPRAM
|
||||
uint32_t dpram_offset = usb_buffer_offset(ep->data_buffer);
|
||||
uint32_t reg = EP_CTRL_ENABLE_BITS |
|
||||
EP_CTRL_INTERRUPT_PER_BUFFER |
|
||||
(ep->ep_type << EP_CTRL_BUFFER_TYPE_LSB) |
|
||||
dpram_offset;
|
||||
*ep->endpoint_control = reg;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts a transfer on a given endpoint.
|
||||
*
|
||||
* @param ep, the endpoint configuration.
|
||||
* @param buf, the data buffer to send. Only applicable if the endpoint is TX
|
||||
* @param len, the length of the data in buf (this example limits max len to one packet - 64 bytes)
|
||||
*/
|
||||
static void usb_start_transfer(struct rp2040_ep_state *ep, uint8_t *buf, uint16_t len)
|
||||
{
|
||||
/*!< Prepare buffer control register value */
|
||||
uint32_t val = len | USB_BUF_CTRL_AVAIL;
|
||||
|
||||
if (len < ep->ep_mps) {
|
||||
val |= USB_BUF_CTRL_LAST;
|
||||
}
|
||||
|
||||
if (USB_EP_DIR_IS_IN(ep->ep_addr)) {
|
||||
/*!< Need to copy the data from the user buffer to the usb memory */
|
||||
if (buf != NULL) {
|
||||
memcpy((void *)ep->data_buffer, (void *)buf, len);
|
||||
}
|
||||
/*!< Mark as full */
|
||||
val |= USB_BUF_CTRL_FULL;
|
||||
}
|
||||
|
||||
/*!< Set pid and flip for next transfer */
|
||||
val |= ep->next_pid ? USB_BUF_CTRL_DATA1_PID : USB_BUF_CTRL_DATA0_PID;
|
||||
ep->next_pid ^= 1u;
|
||||
|
||||
*ep->buffer_control = val;
|
||||
}
|
||||
|
||||
int usb_dc_init(uint8_t busid)
|
||||
{
|
||||
uint8_t *next_buffer_ptr;
|
||||
|
||||
memset(&g_rp2040_udc, 0, sizeof(struct rp2040_udc));
|
||||
|
||||
g_rp2040_udc.in_ep[0].endpoint_control = NULL;
|
||||
g_rp2040_udc.in_ep[0].data_buffer = &usb_dpram->ep0_buf_a[0];
|
||||
g_rp2040_udc.out_ep[0].endpoint_control = NULL;
|
||||
g_rp2040_udc.out_ep[0].data_buffer = &usb_dpram->ep0_buf_a[0];
|
||||
|
||||
for (uint32_t i = 0; i < CONFIG_USBDEV_EP_NUM; i++) {
|
||||
g_rp2040_udc.in_ep[i].buffer_control = &usb_dpram->ep_buf_ctrl[i].in;
|
||||
g_rp2040_udc.out_ep[i].buffer_control = &usb_dpram->ep_buf_ctrl[i].out;
|
||||
|
||||
if (i != 0) {
|
||||
g_rp2040_udc.in_ep[i].endpoint_control = &usb_dpram->ep_ctrl[i - 1].in;
|
||||
g_rp2040_udc.out_ep[i].endpoint_control = &usb_dpram->ep_ctrl[i - 1].out;
|
||||
}
|
||||
}
|
||||
|
||||
next_buffer_ptr = &usb_dpram->epx_data[0];
|
||||
|
||||
for (uint32_t i = 1; i < CONFIG_USBDEV_EP_NUM; i++) {
|
||||
g_rp2040_udc.in_ep[i].data_buffer = next_buffer_ptr;
|
||||
if (i == 1) {
|
||||
next_buffer_ptr += 1024; /* for iso video */
|
||||
} else {
|
||||
next_buffer_ptr += 64;
|
||||
}
|
||||
|
||||
g_rp2040_udc.out_ep[i].data_buffer = next_buffer_ptr;
|
||||
next_buffer_ptr += 64;
|
||||
}
|
||||
|
||||
// Remove shared irq if it was previously added so as not to fill up shared irq slots
|
||||
irq_remove_handler(USBCTRL_IRQ, rp2040_usbd_irq);
|
||||
|
||||
irq_add_shared_handler(USBCTRL_IRQ, rp2040_usbd_irq, PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY);
|
||||
|
||||
// Reset usb controller
|
||||
reset_unreset_block_num_wait_blocking(RESET_USBCTRL);
|
||||
|
||||
/*!< Clear any previous state just in case */
|
||||
memset(usb_hw, 0, sizeof(*usb_hw));
|
||||
memset(usb_dpram, 0, sizeof(*usb_dpram));
|
||||
|
||||
/*!< Mux the controller to the onboard usb phy */
|
||||
usb_hw->muxing = USB_USB_MUXING_TO_PHY_BITS | USB_USB_MUXING_SOFTCON_BITS;
|
||||
|
||||
#if FORCE_VBUS_DETECT
|
||||
// Force VBUS detect so the device thinks it is plugged into a host
|
||||
usb_hw->pwr = USB_USB_PWR_VBUS_DETECT_BITS | USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS;
|
||||
#endif
|
||||
|
||||
// Enable the USB controller in device mode.
|
||||
usb_hw->main_ctrl = USB_MAIN_CTRL_CONTROLLER_EN_BITS;
|
||||
|
||||
// Enable an interrupt per EP0 transaction
|
||||
usb_hw->sie_ctrl = USB_SIE_CTRL_EP0_INT_1BUF_BITS; // <2>
|
||||
|
||||
// Enable interrupts for when a buffer is done, when the bus is reset,
|
||||
// and when a setup packet is received
|
||||
usb_hw->inte = USB_INTS_BUFF_STATUS_BITS | USB_INTS_BUS_RESET_BITS | USB_INTS_SETUP_REQ_BITS |
|
||||
USB_INTS_DEV_SUSPEND_BITS | USB_INTS_DEV_RESUME_FROM_HOST_BITS |
|
||||
(FORCE_VBUS_DETECT ? 0 : USB_INTS_DEV_CONN_DIS_BITS);
|
||||
|
||||
// Enable USB interrupt at processor
|
||||
irq_set_enabled(USBCTRL_IRQ, true);
|
||||
|
||||
usb_hw_set->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_dc_deinit(uint8_t busid)
|
||||
{
|
||||
irq_set_enabled(USBCTRL_IRQ, false);
|
||||
// Remove shared irq if it was previously added so as not to fill up shared irq slots
|
||||
irq_remove_handler(USBCTRL_IRQ, rp2040_usbd_irq);
|
||||
|
||||
usb_hw_clear->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS;
|
||||
memset(&g_rp2040_udc, 0, sizeof(struct rp2040_udc));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_set_address(uint8_t busid, const uint8_t addr)
|
||||
{
|
||||
g_rp2040_udc.dev_addr = addr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_set_remote_wakeup(uint8_t busid)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t usbd_get_port_speed(uint8_t busid)
|
||||
{
|
||||
return USB_SPEED_FULL;
|
||||
}
|
||||
|
||||
int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
|
||||
{
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress);
|
||||
|
||||
if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) {
|
||||
g_rp2040_udc.out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
|
||||
g_rp2040_udc.out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
|
||||
g_rp2040_udc.out_ep[ep_idx].ep_addr = ep->bEndpointAddress;
|
||||
g_rp2040_udc.out_ep[ep_idx].ep_enable = true;
|
||||
/*!< Clear control reg */
|
||||
*(g_rp2040_udc.out_ep[ep_idx].buffer_control) = 0;
|
||||
|
||||
usb_setup_endpoint(&g_rp2040_udc.out_ep[ep_idx]);
|
||||
} else {
|
||||
g_rp2040_udc.in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
|
||||
g_rp2040_udc.in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
|
||||
g_rp2040_udc.in_ep[ep_idx].ep_addr = ep->bEndpointAddress;
|
||||
g_rp2040_udc.in_ep[ep_idx].ep_enable = true;
|
||||
/*!< Clear control reg */
|
||||
*(g_rp2040_udc.in_ep[ep_idx].buffer_control) = 0;
|
||||
|
||||
usb_setup_endpoint(&g_rp2040_udc.in_ep[ep_idx]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_ep_close(uint8_t busid, const uint8_t ep)
|
||||
{
|
||||
if (USB_EP_DIR_IS_IN(ep)) {
|
||||
} else if (USB_EP_DIR_IS_OUT(ep)) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
|
||||
{
|
||||
if (USB_EP_GET_IDX(ep) == 0) {
|
||||
/**
|
||||
* A stall on EP0 has to be armed so it can be cleared on the next setup packet
|
||||
*/
|
||||
usb_hw_set->ep_stall_arm = (USB_EP_DIR_IS_IN(ep)) ? USB_EP_STALL_ARM_EP0_IN_BITS : USB_EP_STALL_ARM_EP0_OUT_BITS;
|
||||
}
|
||||
|
||||
if (USB_EP_DIR_IS_OUT(ep)) {
|
||||
*(g_rp2040_udc.out_ep[USB_EP_GET_IDX(ep)].buffer_control) = USB_BUF_CTRL_STALL;
|
||||
} else {
|
||||
*(g_rp2040_udc.in_ep[USB_EP_GET_IDX(ep)].buffer_control) = USB_BUF_CTRL_STALL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
|
||||
{
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep);
|
||||
|
||||
if (ep_idx != 0) {
|
||||
if (USB_EP_DIR_IS_OUT(ep)) {
|
||||
g_rp2040_udc.out_ep[USB_EP_GET_IDX(ep)].next_pid = 0;
|
||||
*(g_rp2040_udc.out_ep[USB_EP_GET_IDX(ep)].buffer_control) = ~USB_BUF_CTRL_STALL;
|
||||
} else {
|
||||
g_rp2040_udc.in_ep[USB_EP_GET_IDX(ep)].next_pid = 0;
|
||||
*(g_rp2040_udc.in_ep[USB_EP_GET_IDX(ep)].buffer_control) = ~USB_BUF_CTRL_STALL;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
|
||||
{
|
||||
if (USB_EP_DIR_IS_OUT(ep)) {
|
||||
if (*(g_rp2040_udc.out_ep[USB_EP_GET_IDX(ep)].buffer_control) & USB_BUF_CTRL_STALL) {
|
||||
*stalled = 1;
|
||||
} else {
|
||||
*stalled = 0;
|
||||
}
|
||||
} else {
|
||||
if (*(g_rp2040_udc.in_ep[USB_EP_GET_IDX(ep)].buffer_control) & USB_BUF_CTRL_STALL) {
|
||||
*stalled = 1;
|
||||
} else {
|
||||
*stalled = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, uint32_t data_len)
|
||||
{
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep);
|
||||
|
||||
if (!data && data_len) {
|
||||
return -1;
|
||||
}
|
||||
if (!g_rp2040_udc.in_ep[ep_idx].ep_enable) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
g_rp2040_udc.in_ep[ep_idx].xfer_buf = (uint8_t *)data;
|
||||
g_rp2040_udc.in_ep[ep_idx].xfer_len = data_len;
|
||||
g_rp2040_udc.in_ep[ep_idx].actual_xfer_len = 0;
|
||||
|
||||
if (data_len == 0) {
|
||||
usb_start_transfer(&g_rp2040_udc.in_ep[ep_idx], NULL, 0);
|
||||
} else {
|
||||
data_len = MIN(data_len, g_rp2040_udc.in_ep[ep_idx].ep_mps);
|
||||
usb_start_transfer(&g_rp2040_udc.in_ep[ep_idx], g_rp2040_udc.in_ep[ep_idx].xfer_buf, data_len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len)
|
||||
{
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep);
|
||||
|
||||
if (!data && data_len) {
|
||||
return -1;
|
||||
}
|
||||
if (!g_rp2040_udc.out_ep[ep_idx].ep_enable) {
|
||||
return -2;
|
||||
}
|
||||
g_rp2040_udc.out_ep[ep_idx].xfer_buf = (uint8_t *)data;
|
||||
g_rp2040_udc.out_ep[ep_idx].xfer_len = data_len;
|
||||
g_rp2040_udc.out_ep[ep_idx].actual_xfer_len = 0;
|
||||
|
||||
if (data_len == 0) {
|
||||
usb_start_transfer(&g_rp2040_udc.out_ep[ep_idx], NULL, 0);
|
||||
} else {
|
||||
/*!< Not zlp */
|
||||
data_len = MIN(data_len, g_rp2040_udc.out_ep[ep_idx].ep_mps);
|
||||
usb_start_transfer(&g_rp2040_udc.out_ep[ep_idx], g_rp2040_udc.out_ep[ep_idx].xfer_buf, data_len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Notify an endpoint that a transfer has completed.
|
||||
*
|
||||
* @param ep, the endpoint to notify.
|
||||
*/
|
||||
static void usb_handle_ep_buff_done(struct rp2040_ep_state *ep)
|
||||
{
|
||||
uint32_t buffer_control = *ep->buffer_control;
|
||||
/*!< Get the transfer length for this endpoint */
|
||||
uint16_t read_count = buffer_control & USB_BUF_CTRL_LEN_MASK;
|
||||
/*!< Call that endpoints buffer done handler */
|
||||
if (ep->ep_addr == 0x80) {
|
||||
/*!< EP0 In */
|
||||
/**
|
||||
* Determine the current setup direction
|
||||
*/
|
||||
switch (g_rp2040_udc.setup.bmRequestType >> USB_REQUEST_DIR_SHIFT) {
|
||||
case 1:
|
||||
/*!< Get */
|
||||
if (g_rp2040_udc.in_ep[0].xfer_len > g_rp2040_udc.in_ep[0].ep_mps) {
|
||||
g_rp2040_udc.in_ep[0].xfer_len -= g_rp2040_udc.in_ep[0].ep_mps;
|
||||
g_rp2040_udc.in_ep[0].actual_xfer_len += g_rp2040_udc.in_ep[0].ep_mps;
|
||||
usbd_event_ep_in_complete_handler(0, 0 | 0x80, g_rp2040_udc.in_ep[0].actual_xfer_len);
|
||||
} else {
|
||||
g_rp2040_udc.in_ep[0].actual_xfer_len += g_rp2040_udc.in_ep[0].xfer_len;
|
||||
g_rp2040_udc.in_ep[0].xfer_len = 0;
|
||||
/**
|
||||
* EP0 In complete and host will send a out token to get 0 length packet
|
||||
* In the next usbd_event_ep_in_complete_handler, stack will start read 0 length packet
|
||||
* and host must send data1 packet.We resest the ep0 next_pid = 1 in setup interrupt head.
|
||||
*/
|
||||
usbd_event_ep_in_complete_handler(0, 0 | 0x80, g_rp2040_udc.in_ep[0].actual_xfer_len);
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
/*!< Set */
|
||||
if (g_rp2040_udc.dev_addr > 0) {
|
||||
usb_hw->dev_addr_ctrl = g_rp2040_udc.dev_addr;
|
||||
g_rp2040_udc.dev_addr = 0;
|
||||
} else {
|
||||
/*!< Normal status stage // Setup out...out in */
|
||||
/**
|
||||
* Perpar for next setup
|
||||
*/
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (ep->ep_addr == 0x00) {
|
||||
/*!< EP0 Out */
|
||||
memcpy(g_rp2040_udc.out_ep[0].xfer_buf, g_rp2040_udc.out_ep[0].data_buffer, read_count);
|
||||
if (read_count == 0) {
|
||||
/*!< Normal status stage // Setup in...in out */
|
||||
/**
|
||||
* Perpar for next setup
|
||||
*/
|
||||
}
|
||||
|
||||
g_rp2040_udc.out_ep[0].actual_xfer_len += read_count;
|
||||
g_rp2040_udc.out_ep[0].xfer_len -= read_count;
|
||||
|
||||
usbd_event_ep_out_complete_handler(0, 0x00, g_rp2040_udc.out_ep[0].actual_xfer_len);
|
||||
} else {
|
||||
/*!< Others ep */
|
||||
uint16_t data_len = 0;
|
||||
if (USB_EP_DIR_IS_OUT(ep->ep_addr)) {
|
||||
/*!< flip the pid */
|
||||
memcpy(g_rp2040_udc.out_ep[(ep->ep_addr) & 0x0f].xfer_buf, g_rp2040_udc.out_ep[(ep->ep_addr) & 0x0f].data_buffer, read_count);
|
||||
g_rp2040_udc.out_ep[(ep->ep_addr) & 0x0f].xfer_buf += read_count;
|
||||
g_rp2040_udc.out_ep[(ep->ep_addr) & 0x0f].actual_xfer_len += read_count;
|
||||
g_rp2040_udc.out_ep[(ep->ep_addr) & 0x0f].xfer_len -= read_count;
|
||||
|
||||
if (read_count < g_rp2040_udc.out_ep[(ep->ep_addr) & 0x0f].ep_mps || g_rp2040_udc.out_ep[(ep->ep_addr) & 0x0f].xfer_len == 0) {
|
||||
/*!< Out complete */
|
||||
usbd_event_ep_out_complete_handler(0, ep->ep_addr, g_rp2040_udc.out_ep[(ep->ep_addr) & 0x0f].actual_xfer_len);
|
||||
} else {
|
||||
/*!< Need read again */
|
||||
data_len = MIN(g_rp2040_udc.out_ep[(ep->ep_addr) & 0x0f].xfer_len, g_rp2040_udc.out_ep[(ep->ep_addr) & 0x0f].ep_mps);
|
||||
usb_start_transfer(&g_rp2040_udc.out_ep[(ep->ep_addr) & 0x0f], NULL, data_len);
|
||||
}
|
||||
} else {
|
||||
if (g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].xfer_len > g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].ep_mps) {
|
||||
/*!< Need tx again */
|
||||
g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].xfer_len -= g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].ep_mps;
|
||||
g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].xfer_buf += g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].ep_mps;
|
||||
g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].actual_xfer_len += g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].ep_mps;
|
||||
data_len = MIN(g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].xfer_len, g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].ep_mps);
|
||||
usb_start_transfer(&g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f], g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].xfer_buf, data_len);
|
||||
} else {
|
||||
/*!< In complete */
|
||||
g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].actual_xfer_len += g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].xfer_len;
|
||||
g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].xfer_len = 0;
|
||||
usbd_event_ep_in_complete_handler(0, ep->ep_addr, g_rp2040_udc.in_ep[(ep->ep_addr) & 0x0f].actual_xfer_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find the endpoint configuration for a specified endpoint number and
|
||||
* direction and notify it that a transfer has completed.
|
||||
*
|
||||
* @param ep_num
|
||||
* @param in
|
||||
*/
|
||||
static void usb_handle_buff_done(uint8_t ep_num, bool in)
|
||||
{
|
||||
uint8_t ep_addr = ep_num | (in ? USB_EP_DIR_IN : 0);
|
||||
if (USB_EP_DIR_IS_OUT(ep_addr)) {
|
||||
usb_handle_ep_buff_done(&g_rp2040_udc.out_ep[ep_num]);
|
||||
} else {
|
||||
usb_handle_ep_buff_done(&g_rp2040_udc.in_ep[ep_num]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle a "buffer status" irq. This means that one or more
|
||||
* buffers have been sent / received. Notify each endpoint where this
|
||||
* is the case.
|
||||
*/
|
||||
static void usb_handle_buff_status(void)
|
||||
{
|
||||
uint32_t remaining_buffers = usb_hw->buf_status;
|
||||
|
||||
uint32_t bit = 1u;
|
||||
for (uint8_t i = 0; remaining_buffers && i < USB_NUM_ENDPOINTS * 2; i++) {
|
||||
if (remaining_buffers & bit) {
|
||||
/*!< clear this in advance */
|
||||
usb_hw_clear->buf_status = bit;
|
||||
/*!< IN transfer for even i, OUT transfer for odd i */
|
||||
usb_handle_buff_done(i >> 1u, !(i & 1u));
|
||||
remaining_buffers &= ~bit;
|
||||
}
|
||||
bit <<= 1u;
|
||||
}
|
||||
}
|
||||
|
||||
void USBD_IRQHandler(uint8_t busid)
|
||||
{
|
||||
uint32_t const status = usb_hw->ints;
|
||||
uint32_t handled = 0;
|
||||
|
||||
if (status & USB_INTS_BUFF_STATUS_BITS) {
|
||||
handled |= USB_INTS_BUFF_STATUS_BITS;
|
||||
usb_handle_buff_status();
|
||||
}
|
||||
|
||||
if (status & USB_INTS_SETUP_REQ_BITS) {
|
||||
handled |= USB_INTS_SETUP_REQ_BITS;
|
||||
memcpy((uint8_t *)&g_rp2040_udc.setup, (uint8_t const *)&usb_dpram->setup_packet, 8);
|
||||
/**
|
||||
* reset pid to both 1 (data and ack)
|
||||
*/
|
||||
g_rp2040_udc.in_ep[0].next_pid = 1;
|
||||
g_rp2040_udc.out_ep[0].next_pid = 1;
|
||||
usbd_event_ep0_setup_complete_handler(0, (uint8_t *)&g_rp2040_udc.setup);
|
||||
usb_hw_clear->sie_status = USB_SIE_STATUS_SETUP_REC_BITS;
|
||||
}
|
||||
|
||||
#if FORCE_VBUS_DETECT == 0
|
||||
/**
|
||||
* Since we force VBUS detect On, device will always think it is connected and
|
||||
* couldn't distinguish between disconnect and suspend
|
||||
*/
|
||||
if (status & USB_INTS_DEV_CONN_DIS_BITS) {
|
||||
handled |= USB_INTS_DEV_CONN_DIS_BITS;
|
||||
if (usb_hw->sie_status & USB_SIE_STATUS_CONNECTED_BITS) {
|
||||
/*!< Connected: nothing to do */
|
||||
usbd_event_connect_handler(0);
|
||||
} else {
|
||||
/*!< Disconnected */
|
||||
usbd_event_disconnect_handler(0);
|
||||
}
|
||||
usb_hw_clear->sie_status = USB_SIE_STATUS_CONNECTED_BITS;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* SE0 for 2.5 us or more (will last at least 10ms)
|
||||
*/
|
||||
if (status & USB_INTS_BUS_RESET_BITS) {
|
||||
handled |= USB_INTS_BUS_RESET_BITS;
|
||||
usb_hw_clear->sie_status = USB_SIE_STATUS_BUS_RESET_BITS;
|
||||
|
||||
usb_hw->dev_addr_ctrl = 0;
|
||||
|
||||
for (uint8_t i = 0; i < CONFIG_USBDEV_EP_NUM - 1; i++) {
|
||||
/*!< Start at ep1 */
|
||||
usb_dpram->ep_ctrl[i].in = 0;
|
||||
usb_dpram->ep_ctrl[i].out = 0;
|
||||
}
|
||||
|
||||
usbd_event_reset_handler(0);
|
||||
|
||||
#if CHERRYUSB_OPT_RP2040_USB_DEVICE_ENUMERATION_FIX
|
||||
/**
|
||||
* Only run enumeration walk-around if pull up is enabled
|
||||
*/
|
||||
if (usb_hw->sie_ctrl & USB_SIE_CTRL_PULLUP_EN_BITS)
|
||||
rp2040_usb_device_enumeration_fix();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Note from pico datasheet 4.1.2.6.4 (v1.2)
|
||||
* If you enable the suspend interrupt, it is likely you will see a suspend interrupt when
|
||||
* the device is first connected but the bus is idle. The bus can be idle for a few ms before
|
||||
* the host begins sending start of frame packets. You will also see a suspend interrupt
|
||||
* when the device is disconnected if you do not have a VBUS detect circuit connected. This is
|
||||
* because without VBUS detection, it is impossible to tell the difference between
|
||||
* being disconnected and suspended.
|
||||
*/
|
||||
if (status & USB_INTS_DEV_SUSPEND_BITS) {
|
||||
handled |= USB_INTS_DEV_SUSPEND_BITS;
|
||||
/*!< Suspend */
|
||||
usb_hw_clear->sie_status = USB_SIE_STATUS_SUSPENDED_BITS;
|
||||
usbd_event_suspend_handler(0);
|
||||
}
|
||||
|
||||
if (status & USB_INTS_DEV_RESUME_FROM_HOST_BITS) {
|
||||
handled |= USB_INTS_DEV_RESUME_FROM_HOST_BITS;
|
||||
/*!< Resume */
|
||||
usb_hw_clear->sie_status = USB_SIE_STATUS_RESUME_BITS;
|
||||
usbd_event_resume_handler(0);
|
||||
}
|
||||
|
||||
if (status ^ handled) {
|
||||
USB_LOG_INFO("Unhandled IRQ 0x%x\n", (uint32_t)(status ^ handled));
|
||||
}
|
||||
}
|
||||
|
||||
void rp2040_usbd_irq(void)
|
||||
{
|
||||
USBD_IRQHandler(0);
|
||||
}
|
|
@ -0,0 +1,824 @@
|
|||
/*
|
||||
* Copyright (c) 2025, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbh_core.h"
|
||||
#include "usbh_hub.h"
|
||||
#include "hardware/resets.h"
|
||||
#include "hardware/irq.h"
|
||||
#include "hardware/structs/usb.h"
|
||||
|
||||
#define usb_hw_set hw_set_alias(usb_hw)
|
||||
#define usb_hw_clear hw_clear_alias(usb_hw)
|
||||
|
||||
#define SIE_CTRL_COMMON (USB_SIE_CTRL_SOF_EN_BITS | \
|
||||
USB_SIE_CTRL_KEEP_ALIVE_EN_BITS | \
|
||||
USB_SIE_CTRL_PULLDOWN_EN_BITS | \
|
||||
USB_SIE_CTRL_EP0_INT_1BUF_BITS)
|
||||
|
||||
typedef enum {
|
||||
USB_EP0_STATE_SETUP = 0x0, /**< SETUP DATA */
|
||||
USB_EP0_STATE_IN_DATA, /**< IN DATA */
|
||||
USB_EP0_STATE_IN_STATUS, /**< IN status*/
|
||||
USB_EP0_STATE_OUT_DATA, /**< OUT DATA */
|
||||
USB_EP0_STATE_OUT_STATUS, /**< OUT status */
|
||||
} ep0_state_t;
|
||||
|
||||
struct rp2040_pipe {
|
||||
uint8_t chidx;
|
||||
bool inuse;
|
||||
volatile uint8_t ep0_state;
|
||||
volatile uint32_t *endpoint_control; /*!< Endpoint control register */
|
||||
volatile uint32_t *buffer_control; /*!< Buffer control register */
|
||||
uint8_t *data_buffer; /*!< Buffer pointer in usb dpram */
|
||||
uint32_t buffer_size; /*!< Buffer size */
|
||||
usb_osal_sem_t waitsem;
|
||||
struct usbh_urb *urb;
|
||||
};
|
||||
|
||||
struct rp2040_hcd {
|
||||
volatile bool port_csc;
|
||||
volatile bool port_pec;
|
||||
volatile bool port_pe;
|
||||
usb_osal_mutex_t ep0_mutex;
|
||||
struct rp2040_pipe pipe_pool[1 + CONFIG_USBHOST_PIPE_NUM];
|
||||
} g_rp2040_hcd[CONFIG_USBHOST_MAX_BUS];
|
||||
|
||||
void rp2040_usbh_irq(void);
|
||||
|
||||
static int rp2040_pipe_alloc(struct usbh_bus *bus)
|
||||
{
|
||||
size_t flags;
|
||||
int chidx;
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
for (chidx = 1; chidx <= CONFIG_USBHOST_PIPE_NUM; chidx++) {
|
||||
if (!g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[chidx].inuse) {
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[chidx].inuse = true;
|
||||
usb_osal_leave_critical_section(flags);
|
||||
return chidx;
|
||||
}
|
||||
}
|
||||
usb_osal_leave_critical_section(flags);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void rp2040_pipe_free(struct rp2040_pipe *pipe)
|
||||
{
|
||||
size_t flags;
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
pipe->inuse = false;
|
||||
usb_osal_leave_critical_section(flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Take a buffer pointer located in the USB RAM and return as an offset of the RAM.
|
||||
*
|
||||
* @param buf
|
||||
* @return uint32_t
|
||||
*/
|
||||
static inline uint32_t usb_buffer_offset(volatile uint8_t *buf)
|
||||
{
|
||||
return (uint32_t)buf ^ (uint32_t)usbh_dpram;
|
||||
}
|
||||
|
||||
static inline uint8_t usbh_get_port_speed(void)
|
||||
{
|
||||
return (usb_hw->sie_status & USB_SIE_STATUS_SPEED_BITS) >> USB_SIE_STATUS_SPEED_LSB;
|
||||
}
|
||||
|
||||
static inline void rp2040_init_endpoint(struct usbh_bus *bus,
|
||||
uint8_t chidx,
|
||||
uint8_t dev_addr,
|
||||
uint8_t ep_addr,
|
||||
uint8_t ep_type,
|
||||
uint8_t ep_interval,
|
||||
uint8_t speed)
|
||||
{
|
||||
struct rp2040_pipe *pipe;
|
||||
uint32_t regval;
|
||||
|
||||
pipe = &g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[chidx];
|
||||
|
||||
// Get the data buffer as an offset of the USB controller's DPRAM
|
||||
uint32_t dpram_offset = usb_buffer_offset(pipe->data_buffer);
|
||||
regval = EP_CTRL_ENABLE_BITS |
|
||||
EP_CTRL_INTERRUPT_PER_BUFFER |
|
||||
(ep_type << EP_CTRL_BUFFER_TYPE_LSB) |
|
||||
dpram_offset;
|
||||
|
||||
if (ep_interval) {
|
||||
regval |= (uint32_t)((ep_interval - 1) << EP_CTRL_HOST_INTERRUPT_INTERVAL_LSB);
|
||||
}
|
||||
|
||||
*pipe->endpoint_control = regval;
|
||||
|
||||
if (chidx != 0) {
|
||||
regval = (uint32_t)(dev_addr | ((ep_addr & 0x0f) << USB_ADDR_ENDP1_ENDPOINT_LSB));
|
||||
|
||||
if (!(ep_addr & 0x80)) {
|
||||
regval |= USB_ADDR_ENDP1_INTEP_DIR_BITS;
|
||||
}
|
||||
|
||||
// ls device plugged to hub
|
||||
if ((usbh_get_port_speed() == USB_SPEED_FULL) && (speed == USB_SPEED_LOW)) {
|
||||
regval |= USB_ADDR_ENDP1_INTEP_PREAMBLE_BITS;
|
||||
}
|
||||
|
||||
usb_hw->int_ep_addr_ctrl[(chidx - 1)] = regval;
|
||||
|
||||
// Finally, enable interrupt that endpoint
|
||||
usb_hw_set->int_ep_ctrl = 1 << chidx;
|
||||
} else {
|
||||
usb_hw->dev_addr_ctrl = dev_addr;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint32_t usb_buf_ctrl_fill(struct usbh_bus *bus, uint8_t chidx, uint8_t ep_addr, uint8_t buf_id)
|
||||
{
|
||||
struct rp2040_pipe *pipe;
|
||||
struct usbh_urb *urb;
|
||||
uint32_t len;
|
||||
uint32_t buf_ctrl;
|
||||
|
||||
pipe = &g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[chidx];
|
||||
urb = pipe->urb;
|
||||
|
||||
len = MIN(urb->transfer_buffer_length, USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize));
|
||||
urb->transfer_buffer_length -= len;
|
||||
|
||||
buf_ctrl = len | USB_BUF_CTRL_AVAIL;
|
||||
buf_ctrl |= urb->data_toggle ? USB_BUF_CTRL_DATA1_PID : USB_BUF_CTRL_DATA0_PID;
|
||||
|
||||
if (USB_EP_DIR_IS_OUT(ep_addr)) {
|
||||
/*!< Need to copy the data from the user buffer to the usb memory */
|
||||
if (urb->transfer_buffer != NULL) {
|
||||
memcpy((void *)pipe->data_buffer + buf_id * 64, (void *)urb->transfer_buffer, len);
|
||||
urb->transfer_buffer += len;
|
||||
}
|
||||
/*!< Mark as full */
|
||||
buf_ctrl |= USB_BUF_CTRL_FULL;
|
||||
}
|
||||
|
||||
if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) != USB_ENDPOINT_TYPE_ISOCHRONOUS) {
|
||||
if (urb->transfer_buffer_length == 0) {
|
||||
buf_ctrl |= USB_BUF_CTRL_LAST;
|
||||
}
|
||||
} else {
|
||||
//TODO: handle isochronous transfer
|
||||
}
|
||||
|
||||
if (buf_id)
|
||||
buf_ctrl = buf_ctrl << 16;
|
||||
|
||||
return buf_ctrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Starts a transfer on a given endpoint.
|
||||
*
|
||||
* @param ep, the endpoint configuration.
|
||||
* @param buf, the data buffer to send. Only applicable if the endpoint is TX
|
||||
* @param len, the length of the data in buf (this example limits max len to one packet - 64 bytes)
|
||||
*/
|
||||
static void usb_start_transfer(struct usbh_bus *bus, uint8_t chidx, uint8_t ep_addr)
|
||||
{
|
||||
struct rp2040_pipe *pipe;
|
||||
struct usbh_urb *urb;
|
||||
uint32_t buf_ctrl;
|
||||
uint32_t ep_ctrl;
|
||||
|
||||
pipe = &g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[chidx];
|
||||
urb = pipe->urb;
|
||||
|
||||
ep_ctrl = *pipe->endpoint_control;
|
||||
buf_ctrl = usb_buf_ctrl_fill(bus, chidx, ep_addr, 0);
|
||||
|
||||
if (urb->transfer_buffer_length && (ep_addr & 0x0f) == 0x00) {
|
||||
urb->data_toggle ^= 1;
|
||||
buf_ctrl |= usb_buf_ctrl_fill(bus, chidx, ep_addr, 1);
|
||||
|
||||
// Set endpoint control double buffered bit if needed
|
||||
ep_ctrl &= ~EP_CTRL_INTERRUPT_PER_BUFFER;
|
||||
ep_ctrl |= EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER;
|
||||
} else {
|
||||
// Single buffered since 1 is enough
|
||||
ep_ctrl &= ~(EP_CTRL_DOUBLE_BUFFERED_BITS | EP_CTRL_INTERRUPT_PER_DOUBLE_BUFFER);
|
||||
ep_ctrl |= EP_CTRL_INTERRUPT_PER_BUFFER;
|
||||
}
|
||||
*pipe->endpoint_control = ep_ctrl;
|
||||
*pipe->buffer_control = buf_ctrl;
|
||||
}
|
||||
|
||||
static inline void rp2040_control_transfer_start(bool dir_in, bool isetup, uint8_t speed)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
regval = SIE_CTRL_COMMON | USB_SIE_CTRL_START_TRANS_BITS;
|
||||
|
||||
if ((usbh_get_port_speed() == USB_SPEED_FULL) && (speed == USB_SPEED_LOW)) {
|
||||
regval |= USB_SIE_CTRL_PREAMBLE_EN_BITS;
|
||||
}
|
||||
|
||||
if (isetup) {
|
||||
regval |= USB_SIE_CTRL_SEND_SETUP_BITS;
|
||||
} else {
|
||||
if (dir_in) {
|
||||
regval |= USB_SIE_CTRL_RECEIVE_DATA_BITS;
|
||||
} else {
|
||||
regval |= USB_SIE_CTRL_SEND_DATA_BITS;
|
||||
}
|
||||
}
|
||||
|
||||
usb_hw->sie_ctrl = regval & ~USB_SIE_CTRL_START_TRANS_BITS;
|
||||
busy_wait_at_least_cycles(12);
|
||||
usb_hw->sie_ctrl = regval;
|
||||
}
|
||||
|
||||
static void rp2040_control_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb, struct usb_setup_packet *setup, uint8_t *buffer, uint32_t buflen)
|
||||
{
|
||||
struct rp2040_pipe *pipe;
|
||||
|
||||
pipe = &g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[chidx];
|
||||
|
||||
if (pipe->ep0_state == USB_EP0_STATE_SETUP) /* fill setup */
|
||||
{
|
||||
pipe->urb->data_toggle = 1;
|
||||
memcpy((uint8_t *)usbh_dpram->setup_packet, (uint8_t *)setup, 8);
|
||||
rp2040_init_endpoint(bus, chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, 0, urb->hport->speed);
|
||||
rp2040_control_transfer_start(false, true, urb->hport->speed);
|
||||
} else if (pipe->ep0_state == USB_EP0_STATE_IN_DATA) /* fill in data */
|
||||
{
|
||||
rp2040_init_endpoint(bus, chidx, urb->hport->dev_addr, 0x80, USB_ENDPOINT_TYPE_CONTROL, 0, urb->hport->speed);
|
||||
usb_start_transfer(bus, chidx, 0x80);
|
||||
rp2040_control_transfer_start(true, false, urb->hport->speed);
|
||||
} else if (pipe->ep0_state == USB_EP0_STATE_OUT_DATA) /* fill out data */
|
||||
{
|
||||
rp2040_init_endpoint(bus, chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, 0, urb->hport->speed);
|
||||
usb_start_transfer(bus, chidx, 0x00);
|
||||
rp2040_control_transfer_start(false, false, urb->hport->speed);
|
||||
} else if (pipe->ep0_state == USB_EP0_STATE_IN_STATUS) /* fill in status */
|
||||
{
|
||||
urb->data_toggle = 1;
|
||||
rp2040_init_endpoint(bus, chidx, urb->hport->dev_addr, 0x80, USB_ENDPOINT_TYPE_CONTROL, 0, urb->hport->speed);
|
||||
usb_start_transfer(bus, chidx, 0x80);
|
||||
rp2040_control_transfer_start(true, false, urb->hport->speed);
|
||||
} else if (pipe->ep0_state == USB_EP0_STATE_OUT_STATUS) /* fill out status */
|
||||
{
|
||||
urb->data_toggle = 1;
|
||||
rp2040_init_endpoint(bus, chidx, urb->hport->dev_addr, 0x00, USB_ENDPOINT_TYPE_CONTROL, 0, urb->hport->speed);
|
||||
usb_start_transfer(bus, chidx, 0x00);
|
||||
rp2040_control_transfer_start(false, false, urb->hport->speed);
|
||||
}
|
||||
}
|
||||
|
||||
static void rp2040_bulk_int_urb_init(struct usbh_bus *bus, uint8_t chidx, struct usbh_urb *urb, uint8_t *buffer, uint32_t buflen)
|
||||
{
|
||||
rp2040_init_endpoint(bus, chidx, urb->hport->dev_addr, urb->ep->bEndpointAddress, USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes), urb->ep->bInterval, urb->hport->speed);
|
||||
usb_start_transfer(bus, chidx, urb->ep->bEndpointAddress);
|
||||
}
|
||||
|
||||
int usb_hc_init(struct usbh_bus *bus)
|
||||
{
|
||||
uint8_t *next_buffer_ptr;
|
||||
|
||||
memset(&g_rp2040_hcd[bus->hcd.hcd_id], 0, sizeof(struct rp2040_hcd));
|
||||
|
||||
for (uint8_t i = 0; i <= CONFIG_USBHOST_PIPE_NUM; i++) {
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i].waitsem = usb_osal_sem_create(0);
|
||||
if (g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i].waitsem == NULL) {
|
||||
USB_LOG_ERR("Failed to create waitsem\r\n");
|
||||
return -USB_ERR_NOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].ep0_mutex = usb_osal_mutex_create();
|
||||
if (g_rp2040_hcd[bus->hcd.hcd_id].ep0_mutex == NULL) {
|
||||
USB_LOG_ERR("Failed to create ep0_mutex\r\n");
|
||||
return -USB_ERR_NOMEM;
|
||||
}
|
||||
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[0].endpoint_control = &usbh_dpram->epx_ctrl;
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[0].buffer_control = &usbh_dpram->epx_buf_ctrl;
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[0].data_buffer = &usbh_dpram->epx_data[0];
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[0].buffer_size = (64 * 2);
|
||||
|
||||
next_buffer_ptr = &usb_dpram->epx_data[64 * 2];
|
||||
|
||||
for (uint8_t i = 1; i <= CONFIG_USBHOST_PIPE_NUM; i++) {
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i].chidx = i;
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i].endpoint_control = &usbh_dpram->int_ep_ctrl[i - 1].ctrl;
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i].buffer_control = &usbh_dpram->int_ep_buffer_ctrl[i - 1].ctrl;
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i].data_buffer = next_buffer_ptr;
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i].buffer_size = (64 * 2);
|
||||
next_buffer_ptr += (64 * 2);
|
||||
}
|
||||
|
||||
// Reset usb controller
|
||||
reset_unreset_block_num_wait_blocking(RESET_USBCTRL);
|
||||
|
||||
// Remove shared irq if it was previously added so as not to fill up shared irq slots
|
||||
irq_remove_handler(USBCTRL_IRQ, rp2040_usbh_irq);
|
||||
|
||||
irq_add_shared_handler(USBCTRL_IRQ, rp2040_usbh_irq, PICO_SHARED_IRQ_HANDLER_HIGHEST_ORDER_PRIORITY);
|
||||
|
||||
/*!< Clear any previous state just in case */
|
||||
memset(usb_hw, 0, sizeof(*usb_hw));
|
||||
memset(usbh_dpram, 0, sizeof(*usbh_dpram));
|
||||
|
||||
/*!< Mux the controller to the onboard usb phy */
|
||||
usb_hw->muxing = USB_USB_MUXING_TO_PHY_BITS | USB_USB_MUXING_SOFTCON_BITS;
|
||||
|
||||
// Force VBUS detect so the device thinks it is plugged into a host
|
||||
usb_hw->pwr = USB_USB_PWR_VBUS_DETECT_BITS | USB_USB_PWR_VBUS_DETECT_OVERRIDE_EN_BITS;
|
||||
|
||||
// Enable the USB controller in device mode.
|
||||
usb_hw->main_ctrl = USB_MAIN_CTRL_CONTROLLER_EN_BITS | USB_MAIN_CTRL_HOST_NDEVICE_BITS;
|
||||
|
||||
usb_hw->sie_ctrl = SIE_CTRL_COMMON;
|
||||
|
||||
// Enable USB interrupt at processor
|
||||
irq_set_enabled(USBCTRL_IRQ, true);
|
||||
|
||||
usb_hw->inte = USB_INTE_BUFF_STATUS_BITS |
|
||||
USB_INTE_HOST_CONN_DIS_BITS |
|
||||
USB_INTE_STALL_BITS |
|
||||
USB_INTE_TRANS_COMPLETE_BITS |
|
||||
USB_INTE_ERROR_RX_TIMEOUT_BITS |
|
||||
USB_INTE_ERROR_DATA_SEQ_BITS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_hc_deinit(struct usbh_bus *bus)
|
||||
{
|
||||
// Enable USB interrupt at processor
|
||||
irq_set_enabled(USBCTRL_IRQ, false);
|
||||
|
||||
// Remove shared irq if it was previously added so as not to fill up shared irq slots
|
||||
irq_remove_handler(USBCTRL_IRQ, rp2040_usbh_irq);
|
||||
|
||||
for (uint8_t i = 0; i <= CONFIG_USBHOST_PIPE_NUM; i++) {
|
||||
usb_osal_sem_delete(g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i].waitsem);
|
||||
}
|
||||
|
||||
usb_osal_mutex_delete(g_rp2040_hcd[bus->hcd.hcd_id].ep0_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t usbh_get_frame_number(struct usbh_bus *bus)
|
||||
{
|
||||
return usb_hw->sof_rd;
|
||||
}
|
||||
|
||||
int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, uint8_t *buf)
|
||||
{
|
||||
uint8_t nports;
|
||||
uint8_t port;
|
||||
uint32_t status;
|
||||
|
||||
nports = CONFIG_USBHOST_MAX_RHPORTS;
|
||||
port = setup->wIndex;
|
||||
if (setup->bmRequestType & USB_REQUEST_RECIPIENT_DEVICE) {
|
||||
switch (setup->bRequest) {
|
||||
case HUB_REQUEST_CLEAR_FEATURE:
|
||||
switch (setup->wValue) {
|
||||
case HUB_FEATURE_HUB_C_LOCALPOWER:
|
||||
break;
|
||||
case HUB_FEATURE_HUB_C_OVERCURRENT:
|
||||
break;
|
||||
default:
|
||||
return -USB_ERR_INVAL;
|
||||
}
|
||||
break;
|
||||
case HUB_REQUEST_SET_FEATURE:
|
||||
switch (setup->wValue) {
|
||||
case HUB_FEATURE_HUB_C_LOCALPOWER:
|
||||
break;
|
||||
case HUB_FEATURE_HUB_C_OVERCURRENT:
|
||||
break;
|
||||
default:
|
||||
return -USB_ERR_INVAL;
|
||||
}
|
||||
break;
|
||||
case HUB_REQUEST_GET_DESCRIPTOR:
|
||||
break;
|
||||
case HUB_REQUEST_GET_STATUS:
|
||||
memset(buf, 0, 4);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (setup->bmRequestType & USB_REQUEST_RECIPIENT_OTHER) {
|
||||
switch (setup->bRequest) {
|
||||
case HUB_REQUEST_CLEAR_FEATURE:
|
||||
if (!port || port > nports) {
|
||||
return -USB_ERR_INVAL;
|
||||
}
|
||||
|
||||
switch (setup->wValue) {
|
||||
case HUB_PORT_FEATURE_ENABLE:
|
||||
break;
|
||||
case HUB_PORT_FEATURE_SUSPEND:
|
||||
case HUB_PORT_FEATURE_C_SUSPEND:
|
||||
break;
|
||||
case HUB_PORT_FEATURE_POWER:
|
||||
break;
|
||||
case HUB_PORT_FEATURE_C_CONNECTION:
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].port_csc = 0;
|
||||
break;
|
||||
case HUB_PORT_FEATURE_C_ENABLE:
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].port_pec = 0;
|
||||
break;
|
||||
case HUB_PORT_FEATURE_C_OVER_CURREN:
|
||||
break;
|
||||
case HUB_PORT_FEATURE_C_RESET:
|
||||
break;
|
||||
default:
|
||||
return -USB_ERR_INVAL;
|
||||
}
|
||||
break;
|
||||
case HUB_REQUEST_SET_FEATURE:
|
||||
if (!port || port > nports) {
|
||||
return -USB_ERR_INVAL;
|
||||
}
|
||||
|
||||
switch (setup->wValue) {
|
||||
case HUB_PORT_FEATURE_SUSPEND:
|
||||
break;
|
||||
case HUB_PORT_FEATURE_POWER:
|
||||
break;
|
||||
case HUB_PORT_FEATURE_RESET:
|
||||
break;
|
||||
|
||||
default:
|
||||
return -USB_ERR_INVAL;
|
||||
}
|
||||
break;
|
||||
case HUB_REQUEST_GET_STATUS:
|
||||
if (!port || port > nports) {
|
||||
return -USB_ERR_INVAL;
|
||||
}
|
||||
|
||||
status = 0;
|
||||
if (g_rp2040_hcd[bus->hcd.hcd_id].port_csc) {
|
||||
status |= (1 << HUB_PORT_FEATURE_C_CONNECTION);
|
||||
}
|
||||
if (g_rp2040_hcd[bus->hcd.hcd_id].port_pec) {
|
||||
status |= (1 << HUB_PORT_FEATURE_C_ENABLE);
|
||||
}
|
||||
|
||||
if (g_rp2040_hcd[bus->hcd.hcd_id].port_pe) {
|
||||
status |= (1 << HUB_PORT_FEATURE_CONNECTION);
|
||||
status |= (1 << HUB_PORT_FEATURE_ENABLE);
|
||||
if (usbh_get_port_speed() == USB_SPEED_LOW) {
|
||||
status |= (1 << HUB_PORT_FEATURE_LOWSPEED);
|
||||
}
|
||||
}
|
||||
|
||||
status |= (1 << HUB_PORT_FEATURE_POWER);
|
||||
memcpy(buf, &status, 4);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbh_submit_urb(struct usbh_urb *urb)
|
||||
{
|
||||
struct rp2040_pipe *pipe;
|
||||
struct usbh_bus *bus;
|
||||
int chidx;
|
||||
size_t flags;
|
||||
int ret = 0;
|
||||
|
||||
if (!urb || !urb->hport || !urb->ep || !urb->hport->bus) {
|
||||
return -USB_ERR_INVAL;
|
||||
}
|
||||
|
||||
if (!urb->hport->connected || !(usb_hw->sie_status & USB_SIE_STATUS_SPEED_BITS)) {
|
||||
return -USB_ERR_NOTCONN;
|
||||
}
|
||||
|
||||
if (urb->errorcode == -USB_ERR_BUSY) {
|
||||
return -USB_ERR_BUSY;
|
||||
}
|
||||
|
||||
bus = urb->hport->bus;
|
||||
|
||||
if (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes) == USB_ENDPOINT_TYPE_CONTROL) {
|
||||
chidx = 0;
|
||||
/* all the control transfers use the only one ep0 register, we need to lock */
|
||||
usb_osal_mutex_take(g_rp2040_hcd[bus->hcd.hcd_id].ep0_mutex);
|
||||
} else {
|
||||
chidx = rp2040_pipe_alloc(bus);
|
||||
if (chidx == -1) {
|
||||
return -USB_ERR_NOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
|
||||
pipe = &g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[chidx];
|
||||
pipe->chidx = chidx;
|
||||
pipe->urb = urb;
|
||||
|
||||
urb->hcpriv = pipe;
|
||||
urb->errorcode = -USB_ERR_BUSY;
|
||||
urb->actual_length = 0;
|
||||
usb_osal_leave_critical_section(flags);
|
||||
|
||||
switch (USB_GET_ENDPOINT_TYPE(urb->ep->bmAttributes)) {
|
||||
case USB_ENDPOINT_TYPE_CONTROL:
|
||||
pipe->ep0_state = USB_EP0_STATE_SETUP;
|
||||
rp2040_control_urb_init(bus, 0, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
|
||||
break;
|
||||
case USB_ENDPOINT_TYPE_BULK:
|
||||
case USB_ENDPOINT_TYPE_INTERRUPT:
|
||||
rp2040_bulk_int_urb_init(bus, chidx, urb, urb->transfer_buffer, urb->transfer_buffer_length);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (urb->timeout > 0) {
|
||||
/* wait until timeout or sem give */
|
||||
ret = usb_osal_sem_take(pipe->waitsem, urb->timeout);
|
||||
if (ret < 0) {
|
||||
goto errout_timeout;
|
||||
}
|
||||
urb->timeout = 0;
|
||||
ret = urb->errorcode;
|
||||
/* we can free pipe when waitsem is done */
|
||||
rp2040_pipe_free(pipe);
|
||||
|
||||
if (chidx == 0) {
|
||||
usb_osal_mutex_give(g_rp2040_hcd[bus->hcd.hcd_id].ep0_mutex);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
errout_timeout:
|
||||
if (chidx == 0) {
|
||||
usb_osal_mutex_give(g_rp2040_hcd[bus->hcd.hcd_id].ep0_mutex);
|
||||
}
|
||||
urb->timeout = 0;
|
||||
usbh_kill_urb(urb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int usbh_kill_urb(struct usbh_urb *urb)
|
||||
{
|
||||
struct rp2040_pipe *pipe;
|
||||
struct usbh_bus *bus;
|
||||
size_t flags;
|
||||
|
||||
if (!urb || !urb->hcpriv || !urb->hport->bus) {
|
||||
return -USB_ERR_INVAL;
|
||||
}
|
||||
|
||||
bus = urb->hport->bus;
|
||||
|
||||
ARG_UNUSED(bus);
|
||||
|
||||
flags = usb_osal_enter_critical_section();
|
||||
|
||||
pipe = (struct rp2040_pipe *)urb->hcpriv;
|
||||
urb->hcpriv = NULL;
|
||||
urb->errorcode = -USB_ERR_SHUTDOWN;
|
||||
pipe->urb = NULL;
|
||||
usb_hw_clear->int_ep_ctrl = 1 << pipe->chidx;
|
||||
usb_hw_clear->buf_status = 1 << (pipe->chidx * 2 + 0);
|
||||
usb_hw_clear->buf_status = 1 << (pipe->chidx * 2 + 1);
|
||||
*pipe->endpoint_control = 0;
|
||||
*pipe->buffer_control = 0;
|
||||
|
||||
if (urb->timeout) {
|
||||
usb_osal_sem_give(pipe->waitsem);
|
||||
} else {
|
||||
rp2040_pipe_free(pipe);
|
||||
}
|
||||
|
||||
usb_osal_leave_critical_section(flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rp2040_urb_waitup(struct usbh_urb *urb)
|
||||
{
|
||||
struct rp2040_pipe *pipe;
|
||||
|
||||
pipe = (struct rp2040_pipe *)urb->hcpriv;
|
||||
pipe->urb = NULL;
|
||||
urb->hcpriv = NULL;
|
||||
|
||||
if (urb->timeout) {
|
||||
usb_osal_sem_give(pipe->waitsem);
|
||||
} else {
|
||||
rp2040_pipe_free(pipe);
|
||||
}
|
||||
|
||||
if (urb->complete) {
|
||||
if (urb->errorcode < 0) {
|
||||
urb->complete(urb->arg, urb->errorcode);
|
||||
} else {
|
||||
urb->complete(urb->arg, urb->actual_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void rp2040_handle_buffer_status(struct usbh_bus *bus)
|
||||
{
|
||||
struct rp2040_pipe *pipe;
|
||||
struct usbh_urb *urb;
|
||||
uint32_t remaining_buffers;
|
||||
uint32_t size;
|
||||
|
||||
remaining_buffers = usb_hw->buf_status;
|
||||
|
||||
uint32_t bit = 1u;
|
||||
if (remaining_buffers & bit) {
|
||||
remaining_buffers &= ~bit;
|
||||
usb_hw_clear->buf_status = bit;
|
||||
|
||||
pipe = &g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[0];
|
||||
urb = pipe->urb;
|
||||
switch (pipe->ep0_state) {
|
||||
case USB_EP0_STATE_IN_DATA:
|
||||
size = *pipe->buffer_control & USB_BUF_CTRL_LEN_MASK;
|
||||
memcpy(urb->transfer_buffer, (uint8_t *)pipe->data_buffer, size);
|
||||
|
||||
urb->transfer_buffer += size;
|
||||
urb->actual_length += size;
|
||||
|
||||
if (*pipe->endpoint_control & EP_CTRL_DOUBLE_BUFFERED_BITS) {
|
||||
if (size == USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) {
|
||||
size = (*pipe->buffer_control >> 16) & USB_BUF_CTRL_LEN_MASK;
|
||||
memcpy(urb->transfer_buffer, (uint8_t *)pipe->data_buffer + 64, size);
|
||||
|
||||
urb->transfer_buffer += size;
|
||||
urb->actual_length += size;
|
||||
}
|
||||
}
|
||||
|
||||
if ((size < USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize)) || (urb->transfer_buffer_length == 0)) {
|
||||
pipe->ep0_state = USB_EP0_STATE_OUT_STATUS;
|
||||
rp2040_control_urb_init(bus, 0, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
|
||||
} else {
|
||||
urb->data_toggle ^= 1;
|
||||
usb_start_transfer(bus, 0, 0x80);
|
||||
}
|
||||
break;
|
||||
case USB_EP0_STATE_OUT_DATA:
|
||||
urb->actual_length += *pipe->buffer_control & USB_BUF_CTRL_LEN_MASK;
|
||||
|
||||
if (*pipe->endpoint_control & EP_CTRL_DOUBLE_BUFFERED_BITS) {
|
||||
urb->actual_length += (*pipe->buffer_control >> 16) & USB_BUF_CTRL_LEN_MASK;
|
||||
}
|
||||
|
||||
if (urb->transfer_buffer_length == 0) {
|
||||
pipe->ep0_state = USB_EP0_STATE_IN_STATUS;
|
||||
rp2040_control_urb_init(bus, 0, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
|
||||
} else {
|
||||
urb->data_toggle ^= 1;
|
||||
usb_start_transfer(bus, 0, 0x00);
|
||||
}
|
||||
break;
|
||||
case USB_EP0_STATE_IN_STATUS:
|
||||
case USB_EP0_STATE_OUT_STATUS:
|
||||
urb->errorcode = 0;
|
||||
rp2040_urb_waitup(urb);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t i = 1; remaining_buffers && i <= CONFIG_USBHOST_PIPE_NUM; i++) {
|
||||
for (uint8_t j = 0; j < 2; j++) {
|
||||
bit = 1 << (i * 2 + j);
|
||||
if (remaining_buffers & bit) {
|
||||
remaining_buffers &= ~bit;
|
||||
usb_hw_clear->buf_status = bit;
|
||||
|
||||
pipe = &g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[i];
|
||||
urb = pipe->urb;
|
||||
if (urb == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (j == 0) { //IN
|
||||
size = *pipe->buffer_control & USB_BUF_CTRL_LEN_MASK;
|
||||
memcpy(urb->transfer_buffer, (uint8_t *)pipe->data_buffer, size);
|
||||
|
||||
urb->transfer_buffer += size;
|
||||
urb->actual_length += size;
|
||||
|
||||
urb->data_toggle ^= 1;
|
||||
if (size < USB_GET_MAXPACKETSIZE(urb->ep->wMaxPacketSize) || urb->transfer_buffer_length == 0) {
|
||||
urb->errorcode = 0;
|
||||
rp2040_urb_waitup(urb);
|
||||
} else {
|
||||
usb_start_transfer(bus, i, urb->ep->bEndpointAddress);
|
||||
}
|
||||
} else { //OUT
|
||||
urb->data_toggle ^= 1;
|
||||
|
||||
urb->actual_length += *pipe->buffer_control & USB_BUF_CTRL_LEN_MASK;
|
||||
|
||||
if (urb->transfer_buffer_length == 0) {
|
||||
urb->errorcode = 0;
|
||||
rp2040_urb_waitup(urb);
|
||||
} else {
|
||||
usb_start_transfer(bus, i, urb->ep->bEndpointAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void USBH_IRQHandler(uint8_t busid)
|
||||
{
|
||||
uint32_t status;
|
||||
uint32_t handled = 0;
|
||||
struct usbh_bus *bus;
|
||||
struct rp2040_pipe *pipe;
|
||||
struct usbh_urb *urb;
|
||||
|
||||
bus = &g_usbhost_bus[busid];
|
||||
status = usb_hw->ints;
|
||||
|
||||
if (status & USB_INTS_HOST_CONN_DIS_BITS) {
|
||||
handled |= USB_INTS_HOST_CONN_DIS_BITS;
|
||||
usb_hw_clear->sie_status = USB_SIE_STATUS_SPEED_BITS;
|
||||
if (usbh_get_port_speed()) {
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].port_csc = 1;
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].port_pec = 1;
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].port_pe = 1;
|
||||
bus->hcd.roothub.int_buffer[0] = (1 << 1);
|
||||
usbh_hub_thread_wakeup(&bus->hcd.roothub);
|
||||
} else {
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].port_csc = 1;
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].port_pec = 1;
|
||||
g_rp2040_hcd[bus->hcd.hcd_id].port_pe = 0;
|
||||
bus->hcd.roothub.int_buffer[0] = (1 << 1);
|
||||
usbh_hub_thread_wakeup(&bus->hcd.roothub);
|
||||
}
|
||||
}
|
||||
|
||||
if (status & USB_INTS_STALL_BITS) {
|
||||
handled |= USB_INTS_STALL_BITS;
|
||||
usb_hw_clear->sie_status = USB_SIE_STATUS_STALL_REC_BITS;
|
||||
}
|
||||
|
||||
if (status & USB_INTS_BUFF_STATUS_BITS) {
|
||||
handled |= USB_INTS_BUFF_STATUS_BITS;
|
||||
rp2040_handle_buffer_status(bus);
|
||||
}
|
||||
|
||||
if (status & USB_INTS_TRANS_COMPLETE_BITS) {
|
||||
handled |= USB_INTS_TRANS_COMPLETE_BITS;
|
||||
usb_hw_clear->sie_status = USB_SIE_STATUS_TRANS_COMPLETE_BITS;
|
||||
if (usb_hw->sie_ctrl & USB_SIE_CTRL_SEND_SETUP_BITS) {
|
||||
pipe = (struct rp2040_pipe *)&g_rp2040_hcd[bus->hcd.hcd_id].pipe_pool[0];
|
||||
urb = pipe->urb;
|
||||
if (urb) {
|
||||
if (urb->setup->wLength) {
|
||||
if (urb->setup->bmRequestType & 0x80) {
|
||||
pipe->ep0_state = USB_EP0_STATE_IN_DATA;
|
||||
} else {
|
||||
pipe->ep0_state = USB_EP0_STATE_OUT_DATA;
|
||||
}
|
||||
} else {
|
||||
pipe->ep0_state = USB_EP0_STATE_IN_STATUS;
|
||||
}
|
||||
urb->actual_length = 8;
|
||||
rp2040_control_urb_init(bus, 0, urb, urb->setup, urb->transfer_buffer, urb->transfer_buffer_length);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
if (status & USB_INTS_ERROR_RX_TIMEOUT_BITS) {
|
||||
handled |= USB_INTS_ERROR_RX_TIMEOUT_BITS;
|
||||
usb_hw_clear->sie_status = USB_SIE_STATUS_RX_TIMEOUT_BITS;
|
||||
}
|
||||
|
||||
if (status & USB_INTS_ERROR_DATA_SEQ_BITS) {
|
||||
handled |= USB_INTS_ERROR_DATA_SEQ_BITS;
|
||||
usb_hw_clear->sie_status = USB_SIE_STATUS_DATA_SEQ_ERROR_BITS;
|
||||
}
|
||||
|
||||
if (status ^ handled) {
|
||||
USB_LOG_ERR("Unhandled IRQ 0x%x\n", (uint)(status ^ handled));
|
||||
}
|
||||
}
|
||||
|
||||
void rp2040_usbh_irq(void)
|
||||
{
|
||||
USBH_IRQHandler(0);
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
#include "usbd_core.h"
|
||||
|
||||
/* Endpoint state */
|
||||
struct usb_dc_ep_state {
|
||||
uint16_t ep_mps; /* Endpoint max packet size */
|
||||
uint8_t ep_type; /* Endpoint type */
|
||||
uint8_t ep_stalled; /* Endpoint stall flag */
|
||||
uint8_t *xfer_buf;
|
||||
uint32_t xfer_len;
|
||||
uint32_t actual_xfer_len;
|
||||
};
|
||||
|
||||
/* Driver state */
|
||||
struct xxx_udc {
|
||||
volatile uint8_t dev_addr;
|
||||
struct usb_dc_ep_state in_ep[CONFIG_USBDEV_EP_NUM]; /*!< IN endpoint parameters*/
|
||||
struct usb_dc_ep_state out_ep[CONFIG_USBDEV_EP_NUM]; /*!< OUT endpoint parameters */
|
||||
} g_xxx_udc;
|
||||
|
||||
__WEAK void usb_dc_low_level_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
__WEAK void usb_dc_low_level_deinit(void)
|
||||
{
|
||||
}
|
||||
|
||||
int usb_dc_init(uint8_t busid)
|
||||
{
|
||||
memset(&g_xxx_udc, 0, sizeof(struct xxx_udc));
|
||||
|
||||
usb_dc_low_level_init();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_dc_deinit(uint8_t busid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_set_address(uint8_t busid, const uint8_t addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_set_remote_wakeup(uint8_t busid)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t usbd_get_port_speed(uint8_t busid)
|
||||
{
|
||||
return USB_SPEED_FULL;
|
||||
}
|
||||
|
||||
int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
|
||||
{
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress);
|
||||
|
||||
if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) {
|
||||
g_xxx_udc.out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
|
||||
g_xxx_udc.out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
|
||||
g_xxx_udc.out_ep[ep_idx].ep_enable = true;
|
||||
} else {
|
||||
g_xxx_udc.in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
|
||||
g_xxx_udc.in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
|
||||
g_xxx_udc.in_ep[ep_idx].ep_enable = true;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_ep_close(uint8_t busid, const uint8_t ep)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, uint32_t data_len)
|
||||
{
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep);
|
||||
uint32_t tmp;
|
||||
|
||||
if (!data && data_len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_xxx_udc.in_ep[ep_idx].xfer_buf = (uint8_t *)data;
|
||||
g_xxx_udc.in_ep[ep_idx].xfer_len = data_len;
|
||||
g_xxx_udc.in_ep[ep_idx].actual_xfer_len = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len)
|
||||
{
|
||||
uint8_t ep_idx = USB_EP_GET_IDX(ep);
|
||||
|
||||
if (!data && data_len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_xxx_udc.out_ep[ep_idx].xfer_buf = (uint8_t *)data;
|
||||
g_xxx_udc.out_ep[ep_idx].xfer_len = data_len;
|
||||
g_xxx_udc.out_ep[ep_idx].actual_xfer_len = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void USBD_IRQHandler(uint8_t busid)
|
||||
{
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright (c) 2025, sakumisu
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include "usbh_core.h"
|
||||
#include "usbh_hub.h"
|
||||
|
||||
int usb_hc_init(struct usbh_bus *bus)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usb_hc_deinit(struct usbh_bus *bus)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t usbh_get_frame_number(struct usbh_bus *bus)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbh_roothub_control(struct usbh_bus *bus, struct usb_setup_packet *setup, uint8_t *buf)
|
||||
{
|
||||
uint8_t nports;
|
||||
uint8_t port;
|
||||
uint32_t status;
|
||||
|
||||
nports = CONFIG_USBHOST_MAX_RHPORTS;
|
||||
port = setup->wIndex;
|
||||
if (setup->bmRequestType & USB_REQUEST_RECIPIENT_DEVICE) {
|
||||
switch (setup->bRequest) {
|
||||
case HUB_REQUEST_CLEAR_FEATURE:
|
||||
switch (setup->wValue) {
|
||||
case HUB_FEATURE_HUB_C_LOCALPOWER:
|
||||
break;
|
||||
case HUB_FEATURE_HUB_C_OVERCURRENT:
|
||||
break;
|
||||
default:
|
||||
return -USB_ERR_NOTSUPP;
|
||||
}
|
||||
break;
|
||||
case HUB_REQUEST_SET_FEATURE:
|
||||
switch (setup->wValue) {
|
||||
case HUB_FEATURE_HUB_C_LOCALPOWER:
|
||||
break;
|
||||
case HUB_FEATURE_HUB_C_OVERCURRENT:
|
||||
break;
|
||||
default:
|
||||
return -USB_ERR_NOTSUPP;
|
||||
}
|
||||
break;
|
||||
case HUB_REQUEST_GET_DESCRIPTOR:
|
||||
break;
|
||||
case HUB_REQUEST_GET_STATUS:
|
||||
memset(buf, 0, 4);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (setup->bmRequestType & USB_REQUEST_RECIPIENT_OTHER) {
|
||||
switch (setup->bRequest) {
|
||||
case HUB_REQUEST_CLEAR_FEATURE:
|
||||
if (!port || port > nports) {
|
||||
return -USB_ERR_INVAL;
|
||||
}
|
||||
|
||||
switch (setup->wValue) {
|
||||
case HUB_PORT_FEATURE_ENABLE:
|
||||
break;
|
||||
case HUB_PORT_FEATURE_SUSPEND:
|
||||
break;
|
||||
case HUB_PORT_FEATURE_C_SUSPEND:
|
||||
break;
|
||||
case HUB_PORT_FEATURE_POWER:
|
||||
break;
|
||||
case HUB_PORT_FEATURE_C_CONNECTION:
|
||||
break;
|
||||
case HUB_PORT_FEATURE_C_ENABLE:
|
||||
break;
|
||||
case HUB_PORT_FEATURE_C_OVER_CURREN:
|
||||
break;
|
||||
case HUB_PORT_FEATURE_C_RESET:
|
||||
break;
|
||||
default:
|
||||
return -USB_ERR_NOTSUPP;
|
||||
}
|
||||
break;
|
||||
case HUB_REQUEST_SET_FEATURE:
|
||||
if (!port || port > nports) {
|
||||
return -USB_ERR_INVAL;
|
||||
}
|
||||
|
||||
switch (setup->wValue) {
|
||||
case HUB_PORT_FEATURE_SUSPEND:
|
||||
break;
|
||||
case HUB_PORT_FEATURE_POWER:
|
||||
break;
|
||||
case HUB_PORT_FEATURE_RESET:
|
||||
break;
|
||||
|
||||
default:
|
||||
return -USB_ERR_NOTSUPP;
|
||||
}
|
||||
break;
|
||||
case HUB_REQUEST_GET_STATUS:
|
||||
if (!port || port > nports) {
|
||||
return -USB_ERR_INVAL;
|
||||
}
|
||||
|
||||
memcpy(buf, &status, 4);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usbh_submit_urb(struct usbh_urb *urb)
|
||||
{
|
||||
return -USB_ERR_NOTSUPP;
|
||||
}
|
||||
|
||||
int usbh_kill_urb(struct usbh_urb *urb)
|
||||
{
|
||||
return -USB_ERR_NOTSUPP;
|
||||
}
|
||||
|
||||
void USBH_IRQHandler(uint8_t busid)
|
||||
{
|
||||
}
|
Loading…
Reference in New Issue