From 9a818b1ef4fb70f3107b8ff28dc787122d4a11fa Mon Sep 17 00:00:00 2001 From: Liu_Weichao Date: Tue, 8 Nov 2022 14:15:23 +0800 Subject: [PATCH] feat add third_party_driver/usb for hc32f4a0 board, compile OK --- Ubiquitous/XiZi_IIoT/board/hc32f4a0/board.c | 7 + .../board/hc32f4a0/third_party_driver/Kconfig | 8 + .../hc32f4a0/third_party_driver/Makefile | 4 + .../common/hc32_ll_driver/inc/hc32f4xx_conf.h | 2 +- .../common/hc32_ll_driver/src/Makefile | 4 + .../third_party_driver/include/connect_usb.h | 54 ++ .../hc32f4a0/third_party_driver/usb/Kconfig | 15 + .../hc32f4a0/third_party_driver/usb/Makefile | 5 + .../third_party_driver/usb/connect_usb.c | 227 +++++++ .../usb/hc32_usb_driver/Makefile | 5 + .../usb/hc32_usb_driver/usb_app_conf.h | 104 ++++ .../usb/hc32_usb_driver/usb_bsp.c | 156 +++++ .../usb/hc32_usb_driver/usb_bsp.h | 104 ++++ .../usb/hc32_usb_driver/usb_host_lib/Makefile | 3 + .../usb_host_lib/host_class/Makefile | 3 + .../usb_host_lib/host_class/msc/Makefile | 3 + .../host_class/msc/usb_host_msc_bot.c | 449 ++++++++++++++ .../host_class/msc/usb_host_msc_bot.h | 162 +++++ .../host_class/msc/usb_host_msc_class.c | 395 ++++++++++++ .../host_class/msc/usb_host_msc_class.h | 113 ++++ .../host_class/msc/usb_host_msc_fatfs.c | 241 ++++++++ .../host_class/msc/usb_host_msc_scsi.c | 528 ++++++++++++++++ .../host_class/msc/usb_host_msc_scsi.h | 136 +++++ .../usb_host_lib/host_core/Makefile | 3 + .../usb_host_lib/host_core/usb_host_cfgch.c | 202 ++++++ .../usb_host_lib/host_core/usb_host_cfgch.h | 103 ++++ .../usb_host_lib/host_core/usb_host_core.c | 539 ++++++++++++++++ .../usb_host_lib/host_core/usb_host_core.h | 95 +++ .../host_core/usb_host_ctrltrans.c | 320 ++++++++++ .../host_core/usb_host_ctrltrans.h | 86 +++ .../usb_host_lib/host_core/usb_host_def.h | 430 +++++++++++++ .../usb_host_lib/host_core/usb_host_driver.c | 231 +++++++ .../usb_host_lib/host_core/usb_host_driver.h | 90 +++ .../usb_host_lib/host_core/usb_host_int.c | 575 ++++++++++++++++++ .../usb_host_lib/host_core/usb_host_int.h | 128 ++++ .../usb_host_lib/host_core/usb_host_stdreq.c | 482 +++++++++++++++ .../usb_host_lib/host_core/usb_host_stdreq.h | 107 ++++ .../hc32_usb_driver/usb_host_lib/usb_lib.h | 199 ++++++ .../usb/hc32_usb_driver/usb_host_user.c | 333 ++++++++++ .../usb/hc32_usb_driver/usb_host_user.h | 109 ++++ Ubiquitous/XiZi_IIoT/path_kernel.mk | 4 + .../XiZi_IIoT/resources/include/device.h | 2 + 42 files changed, 6765 insertions(+), 1 deletion(-) create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_usb.h create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/Kconfig create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/Makefile create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/connect_usb.c create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/Makefile create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_app_conf.h create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_bsp.c create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_bsp.h create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/Makefile create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/Makefile create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/Makefile create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_bot.c create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_bot.h create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_class.c create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_class.h create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_fatfs.c create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_scsi.c create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_scsi.h create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/Makefile create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_cfgch.c create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_cfgch.h create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_core.c create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_core.h create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_ctrltrans.c create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_ctrltrans.h create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_def.h create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_driver.c create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_driver.h create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_int.c create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_int.h create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_stdreq.c create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_stdreq.h create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/usb_lib.h create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_user.c create mode 100644 Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_user.h diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/board.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/board.c index 08c3cf46e..de55bbf25 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/board.c +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/board.c @@ -42,6 +42,10 @@ Modification: #include #endif +#ifdef BSP_USING_USB +#include +#endif + extern void entry(void); extern int HwUsartInit(); @@ -132,6 +136,9 @@ struct InitSequenceDesc _board_init[] = #endif #ifdef BSP_USING_SPI { "spi", HwSpiInit }, +#endif +#ifdef BSP_USING_USB + { "usb", HwUsbHostInit }, #endif { " NONE ", NONE }, }; diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Kconfig b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Kconfig index e698947ec..e5462cf8e 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Kconfig @@ -21,3 +21,11 @@ menuconfig BSP_USING_SDIO if BSP_USING_SDIO source "$BSP_DIR/third_party_driver/sdio/Kconfig" endif + +menuconfig BSP_USING_USB + bool "Using USB device" + default n + select RESOURCES_USB + if BSP_USING_USB + source "$BSP_DIR/third_party_driver/usb/Kconfig" + endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Makefile index e91db2f3b..b075a1a82 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Makefile @@ -12,4 +12,8 @@ ifeq ($(CONFIG_BSP_USING_SDIO),y) SRC_DIR += sdio endif +ifeq ($(CONFIG_BSP_USING_USB),y) + SRC_DIR += usb +endif + include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/common/hc32_ll_driver/inc/hc32f4xx_conf.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/common/hc32_ll_driver/inc/hc32f4xx_conf.h index a4dfcda0d..52184d4ec 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/common/hc32_ll_driver/inc/hc32f4xx_conf.h +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/common/hc32_ll_driver/inc/hc32f4xx_conf.h @@ -101,7 +101,7 @@ extern "C" #define LL_TMRA_ENABLE (DDL_ON) #define LL_TRNG_ENABLE (DDL_ON) #define LL_USART_ENABLE (DDL_ON) -#define LL_USB_ENABLE (DDL_OFF) +#define LL_USB_ENABLE (DDL_ON) #define LL_VREF_ENABLE (DDL_OFF) #define LL_WDT_ENABLE (DDL_ON) diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/common/hc32_ll_driver/src/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/common/hc32_ll_driver/src/Makefile index 2bbdb2648..9a62fee3e 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/common/hc32_ll_driver/src/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/common/hc32_ll_driver/src/Makefile @@ -12,4 +12,8 @@ ifeq ($(CONFIG_BSP_USING_SPI),y) SRC_FILES += hc32_ll_spi.c endif +ifeq ($(CONFIG_BSP_USING_USB),y) + SRC_FILES += hc32_ll_usb.c +endif + include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_usb.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_usb.h new file mode 100644 index 000000000..71c58a043 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_usb.h @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_usb.h +* @brief define hc32f4a0-board usb function and struct +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-11-07 +*/ + +#ifndef CONNECT_USB_H +#define CONNECT_USB_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(FS_VFS) +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define USB_HOST_STACK_SIZE 4096 + +#define USB_SINGLE_BLOCK_SIZE 512 + +int HwUsbHostInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/Kconfig b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/Kconfig new file mode 100644 index 000000000..65894670c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/Kconfig @@ -0,0 +1,15 @@ +config BSP_USING_HC32_USBH + bool "Using usb host by HC32 library" + default y + if BSP_USING_HC32_USBH + config USB_BUS_NAME + string "usb bus name" + default "usb" + config USB_DRIVER_NAME + string "usb bus driver name" + default "usb_drv" + config USB_DEVICE_NAME + string "usb bus device name" + default "usb_dev" + endif + diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/Makefile new file mode 100644 index 000000000..b24203a36 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/Makefile @@ -0,0 +1,5 @@ +SRC_DIR := hc32_usb_driver + +SRC_FILES := connect_usb.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/connect_usb.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/connect_usb.c new file mode 100644 index 000000000..523e6839a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/connect_usb.c @@ -0,0 +1,227 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_usb.c +* @brief support hc32f4a0-board usb function and register to bus framework +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-11-07 +*/ + +/************************************************* +File name: connect_usb.c +Description: support hc32f4a0-board usb function and register to bus framework +Others: +History: +1. Date: 2022-11-07 +Author: AIIT XUOS Lab +Modification: +1. support hc32f4a0-board usb configure, write and read +2. support hc32f4a0-board usb bus device and driver register +*************************************************/ + +#include + +usb_core_instance usb_app_instance; +USBH_HOST usb_app_host; + +#if defined(FS_VFS) +void UsbMountFileSystem() +{ + if (MountFilesystem(USB_BUS_NAME, USB_DEVICE_NAME, USB_DRIVER_NAME, FSTYPE_FATFS, UDISK_MOUNTPOINT) == 0) + KPrintf("Mount FAT on Udisk successful.\n"); + else + KPrintf("Mount FAT on Udisk failed.\n"); +} + +void UsbUnmountFileSystem() +{ + UnmountFileSystem(UDISK_MOUNTPOINT); +} +#endif + +static uint32 UsbHostOpen(void *dev) +{ + return EOK; +} + +static uint32 UsbHostClose(void *dev) +{ + return EOK; +} + +static uint32 UsbHostRead(void *dev, struct BusBlockReadParam *read_param) +{ + USB_HOST_MSC_STATUS status = USB_HOST_MSC_OK; + + if (host_driver_ifdevconnected(&usb_app_instance) != 0UL) { + + do { + status = usb_host_msc_Read10(&usb_app_instance, (uint8 *)read_param->buffer, read_param->pos, USB_SINGLE_BLOCK_SIZE * (uint32_t)read_param->size); + usb_host_msc_botxferprocess(&usb_app_instance, &usb_app_host); + + if (host_driver_ifdevconnected(&usb_app_instance) == 0UL) { + return 0; + } + } while (USB_HOST_MSC_BUSY == status); + } + + if (USB_HOST_MSC_OK == status) { + return read_param->size; + } + + return 0; +} + +static uint32 UsbHostWrite(void *dev, struct BusBlockWriteParam *write_param) +{ + USB_HOST_MSC_STATUS status = USB_HOST_MSC_OK; + + if (host_driver_ifdevconnected(&usb_app_instance) != 0UL) { + do { + status = usb_host_msc_Write10(&usb_app_instance, (uint8 *)write_param->buffer, write_param->pos, USB_SINGLE_BLOCK_SIZE * (uint32_t)write_param->size); + usb_host_msc_botxferprocess(&usb_app_instance, &usb_app_host); + + if (host_driver_ifdevconnected(&usb_app_instance) == 0UL) { + return 0; + } + } while (USB_HOST_MSC_BUSY == status); + } + + if (USB_HOST_MSC_OK == status) { + return write_param->size; + } + + return 0; +} + +static int UsbControl(struct HardwareDev *dev, struct HalDevBlockParam *block_param) +{ + NULL_PARAM_CHECK(dev); + + if (OPER_BLK_GETGEOME == block_param->cmd) { + block_param->dev_block.size_perbank = USB_SINGLE_BLOCK_SIZE; + block_param->dev_block.block_size = USB_SINGLE_BLOCK_SIZE; + block_param->dev_block.bank_num = USB_HOST_MSC_Param.MSC_Capacity; + } + + return EOK; +} + +/*manage the usb device operations*/ +static const struct UsbDevDone dev_done = +{ + .open = UsbHostOpen, + .close = UsbHostClose, + .write = UsbHostWrite, + .read = UsbHostRead, +}; + +static void UsbHostTask(void* parameter) +{ + while (1) { + usb_host_mainprocess(&usb_app_instance, &usb_app_host); + } +} + +/*Init usb host bus、driver*/ +static int BoardUsbBusInit(struct UsbBus *usb_bus, struct UsbDriver *usb_driver) +{ + x_err_t ret = EOK; + + /*Init the usb bus */ + ret = UsbBusInit(usb_bus, USB_BUS_NAME); + if (EOK != ret) { + KPrintf("board_usb_init UsbBusInit error %d\n", ret); + return ERROR; + } + + /*Init the usb driver*/ + ret = UsbDriverInit(usb_driver, USB_DRIVER_NAME); + if (EOK != ret){ + KPrintf("board_usb_init UsbDriverInit error %d\n", ret); + return ERROR; + } + + /*Attach the usb driver to the usb bus*/ + ret = UsbDriverAttachToBus(USB_DRIVER_NAME, USB_BUS_NAME); + if (EOK != ret) { + KPrintf("board_usb_init USEDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +/*Attach the usb device to the usb bus*/ +static int BoardUsbDevBend(void) +{ + x_err_t ret = EOK; + static struct UsbHardwareDevice usb_device; + memset(&usb_device, 0, sizeof(struct UsbHardwareDevice)); + + usb_device.dev_done = &dev_done; + usb_device.haldev.dev_block_control = UsbControl; + + ret = USBDeviceRegister(&usb_device, NONE, USB_DEVICE_NAME); + if (EOK != ret) { + KPrintf("USBDeviceRegister device %s error %d\n", USB_DEVICE_NAME, ret); + return ERROR; + } + + ret = USBDeviceAttachToBus(USB_DEVICE_NAME, USB_BUS_NAME); + if (EOK != ret) { + KPrintf("USBDeviceAttachToBus device %s error %d\n", USB_DEVICE_NAME, ret); + return ERROR; + } + + return ret; +} + +int HwUsbHostInit(void) +{ + x_err_t ret = EOK; + int32 usb_host_task = 0; + + static struct UsbBus usb_bus; + memset(&usb_bus, 0, sizeof(struct UsbBus)); + + static struct UsbDriver usb_driver; + memset(&usb_driver, 0, sizeof(struct UsbDriver)); + + usb_host_init(&usb_app_instance, &usb_app_host, &USBH_MSC_cb, &USR_cb); + + ret = BoardUsbBusInit(&usb_bus, &usb_driver); + if (EOK != ret) { + KPrintf("BoardUsbBusInit error ret %u\n", ret); + return ERROR; + } + + ret = BoardUsbDevBend(); + if (EOK != ret) { + KPrintf("BoardUsbDevBend error ret %u\n", ret); + return ERROR; + } + + usb_host_task = KTaskCreate("usbh", UsbHostTask, NONE, + USB_HOST_STACK_SIZE, 8); + if(usb_host_task < 0) { + KPrintf("usb_host_task create failed ...%s %d.\n", __FUNCTION__, __LINE__); + return ERROR; + } + + StartupKTask(usb_host_task); + + return ret; +} + diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/Makefile new file mode 100644 index 000000000..be76fe492 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/Makefile @@ -0,0 +1,5 @@ +SRC_FILES := usb_host_user.c usb_bsp.c + +SRC_DIR := usb_host_lib + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_app_conf.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_app_conf.h new file mode 100644 index 000000000..6ae6f00c4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_app_conf.h @@ -0,0 +1,104 @@ +/** + ******************************************************************************* + * @file usb/usb_host_msc/source/usb_app_conf.h + * @brief low level driver configuration + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ +#ifndef __USB_APP_CONF_H__ +#define __USB_APP_CONF_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ + +/* USB MODE CONFIGURATION */ +/* +USB_FS_MODE, USB_HS_MODE, USB_HS_EXTERNAL_PHY defined comment +(1) If only defined USB_FS_MODE: + MCU USBFS core work in full speed using internal PHY. +(2) If only defined USB_HS_MODE: + MCU USBHS core work in full speed using internal PHY. +(3) If both defined USB_HS_MODE && USB_HS_EXTERNAL_PHY + MCU USBHS core work in high speed using external PHY. +(4) Other combination: + Not support, forbid!! +*/ + +//#define USB_HS_MODE +#define USB_FS_MODE + +#define USE_HOST_MODE + +#ifdef USB_HS_MODE +#define USB_HS_EXTERNAL_PHY +#endif + +#ifndef USB_HS_MODE +#ifndef USB_FS_MODE +#error "USB_HS_MODE or USB_FS_MODE should be defined" +#endif +#endif + +#ifndef USE_DEVICE_MODE +#ifndef USE_HOST_MODE +#error "USE_DEVICE_MODE or USE_HOST_MODE should be defined" +#endif +#endif + +/* USB FIFO CONFIGURATION */ +#ifdef USB_FS_MODE +#define RX_FIFO_FS_SIZE (128U) +#define TXH_NP_FS_FIFOSIZ (32U) +#define TXH_P_FS_FIFOSIZ (64U) + +#if ((RX_FIFO_FS_SIZE + TXH_NP_FS_FIFOSIZ + TXH_P_FS_FIFOSIZ) > 640U) +#error "The USB max FIFO size is 640 x 4 Bytes!" +#endif +#endif + +#ifdef USB_HS_MODE +#define RX_FIFO_HS_SIZE (512U) +#define TXH_NP_HS_FIFOSIZ (128U) +#define TXH_P_HS_FIFOSIZ (256U) + +#if ((RX_FIFO_FS_SIZE + TXH_NP_FS_FIFOSIZ + TXH_P_FS_FIFOSIZ) > 2048U) +#error "The USB max FIFO size is 2048 x 4 Bytes!" +#endif +#endif + +/* FUNCTION CONFIGURATION */ +#define USBH_MAX_NUM_INTERFACES (3U) +#define USBH_MAX_NUM_ENDPOINTS (2U) + +/* CONFIGURATION FOR MSC */ +#define USBH_MSC_MPS_SIZE (0x40U) +//#define USB_MSC_FAT_VALID + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_APP_CONF_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_bsp.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_bsp.c new file mode 100644 index 000000000..03698dc26 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_bsp.c @@ -0,0 +1,156 @@ +/** + ******************************************************************************* + * @file usb/usb_host_msc/source/usb_bsp.c + * @brief BSP function for USB example + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +/** +* @file usb_bsp.c +* @brief support hc32f4a0-board usb bsp function +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-11-08 +*/ + +/************************************************* +File name: usb_bsp.c +Description: support hc32f4a0-board usb bsp function +Others: +History: +1. Date: 2022-11-08 +Author: AIIT XUOS Lab +Modification: +1. support hc32f4a0-board usb IO configure +2. support hc32f4a0-board usb irq define +*************************************************/ +#include +#include "usb_bsp.h" +#include + +extern usb_core_instance usb_app_instance; + +/* USBFS Core*/ +#define USB_DP_PORT (GPIO_PORT_A) +#define USB_DP_PIN (GPIO_PIN_12) + +#define USB_DM_PORT (GPIO_PORT_A) +#define USB_DM_PIN (GPIO_PIN_11) + +#define USB_DRVVBUS_PORT (GPIO_PORT_C) +#define USB_DRVVBUS_PIN (GPIO_PIN_09) + +#define USB_VBUSDET_PORT (GPIO_PORT_A) +#define USB_VBUSDET_PIN (GPIO_PIN_09) + +#define USB_OC_PORT (GPIO_PORT_D) +#define USB_OC_PIN (GPIO_PIN_15) + +//USB HOST ISR +static void USB_IRQ_Handler(void) +{ + x_base lock = 0; + lock = DISABLE_INTERRUPT(); + + usb_host_isr(&usb_app_instance); + + ENABLE_INTERRUPT(lock); +} + +void usb_bsp_init(usb_core_instance *pdev) +{ + stc_gpio_init_t stcGpioCfg; + + /* SysTick configuration */ + (void)SysTick_Init(1000U); + NVIC_SetPriority(SysTick_IRQn, DDL_IRQ_PRIO_14); + + /* USB clock source configurate */ + CLK_SetUSBClockSrc(CLK_USBCLK_SYSCLK_DIV5); + + (void)GPIO_StructInit(&stcGpioCfg); + +#ifdef USB_FS_MODE + stcGpioCfg.u16PinAttr = PIN_ATTR_ANALOG; + (void)GPIO_Init(USB_DM_PORT, USB_DM_PIN, &stcGpioCfg); + (void)GPIO_Init(USB_DP_PORT, USB_DP_PIN, &stcGpioCfg); + + // stcGpioInit.u16PinState = PIN_STAT_RST; + // stcGpioInit.u16PinDir = PIN_DIR_OUT; + // (void)GPIO_Init(USB_DRVVBUS_PORT, USB_DRVVBUS_PIN, &stcGpioInit); + // GPIO_SetPins(USB_DRVVBUS_PORT, USB_DRVVBUS_PIN); + + GPIO_SetFunc(USB_DRVVBUS_PORT, USB_DRVVBUS_PIN, GPIO_FUNC_10); /* VBUS */ + + FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_USBFS, ENABLE); +#endif +} + +void usb_bsp_nvicconfig(void) +{ + stc_irq_signin_config_t stcIrqRegiConf; + /* Register INT_SRC_USBFS_GLB Int to Vect.No.030 */ + stcIrqRegiConf.enIRQn = INT030_IRQn; + /* Select interrupt function */ +#ifdef USB_FS_MODE + stcIrqRegiConf.enIntSrc = INT_SRC_USBFS_GLB; +#else + stcIrqRegiConf.enIntSrc = INT_SRC_USBHS_GLB; +#endif + /* Callback function */ + stcIrqRegiConf.pfnCallback = &USB_IRQ_Handler; + /* Registration IRQ */ + (void)INTC_IrqSignIn(&stcIrqRegiConf); + /* Clear Pending */ + NVIC_ClearPendingIRQ(stcIrqRegiConf.enIRQn); + /* Set priority */ + NVIC_SetPriority(stcIrqRegiConf.enIRQn, DDL_IRQ_PRIO_15); + /* Enable NVIC */ + NVIC_EnableIRQ(stcIrqRegiConf.enIRQn); +} + +void usb_udelay(const uint32_t usec) +{ + __IO uint32_t i; + uint32_t j; + j = (HCLK_VALUE + 1000000UL - 1UL) / 1000000UL * usec; + for (i = 0UL; i < j; i++) { + } +} + +void usb_mdelay(const uint32_t msec) +{ + SysTick_Delay(msec); +} + +/** + * @brief Configures the IO for the Vbus and OverCurrent + * @param [in] pdev device instance + * @retval None + */ +void usb_bsp_cfgvbus(LL_USB_TypeDef *USBx) +{ +} + +/** + * @brief Drive vbus + * @param [in] pdev device instance + * @param [in] state the vbus state it would be. + * @retval None + */ +void usb_bsp_drivevbus(LL_USB_TypeDef *USBx, uint8_t state) +{ +} diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_bsp.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_bsp.h new file mode 100644 index 000000000..d09cd20a3 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_bsp.h @@ -0,0 +1,104 @@ +/** + ******************************************************************************* + * @file usb/usb_host_msc/source/usb_bsp.h + * @brief Head file for usb_bsp.c + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +/** +* @file usb_bsp.h +* @brief support hc32f4a0-board usb bsp function +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-11-08 +*/ + +/************************************************* +File name: usb_bsp.h +Description: support hc32f4a0-board usb bsp function +Others: +History: +1. Date: 2022-11-08 +Author: AIIT XUOS Lab +Modification: +*************************************************/ + +#ifndef USB_BSP_H +#define USB_BSP_H + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include + +/** + * @addtogroup HC32F4A0_DDL_Applications + * @{ + */ + +/** + * @addtogroup USB_Host_Msc + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ + + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +extern void usb_bsp_init(usb_core_instance *pdev); +extern void usb_udelay(const uint32_t usec); +extern void usb_mdelay(const uint32_t msec); +extern void usb_bsp_nvicconfig(void); +#ifdef USE_HOST_MODE +extern void usb_bsp_cfgvbus(LL_USB_TypeDef *USBx); +extern void usb_bsp_drivevbus(LL_USB_TypeDef *USBx, uint8_t state); +#endif + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_BSP_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/Makefile new file mode 100644 index 000000000..e55e5e056 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/Makefile @@ -0,0 +1,3 @@ +SRC_DIR := host_class host_core + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/Makefile new file mode 100644 index 000000000..947ef2d88 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/Makefile @@ -0,0 +1,3 @@ +SRC_DIR := msc + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/Makefile new file mode 100644 index 000000000..901d58c18 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := usb_host_msc_bot.c usb_host_msc_class.c usb_host_msc_scsi.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_bot.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_bot.c new file mode 100644 index 000000000..d8509ac8a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_bot.c @@ -0,0 +1,449 @@ +/** + ******************************************************************************* + * @file usb_host_msc_bot.c + * @brief mass storage related functions + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_msc_class.h" +#include "usb_host_msc_scsi.h" +#include "usb_host_msc_bot.h" +#include "usb_host_ctrltrans.h" +#include "usb_host_def.h" +#include "usb_host_int.h" +#include "usb_host_driver.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CLASS + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_MSC USB Host MSC + * @{ + */ + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ +#ifdef USB_INTERNAL_DMA_ENABLED +#if defined ( __ICCARM__ ) /*!< IAR Compiler */ +#pragma data_alignment=4 +#endif +#endif /* USB_INTERNAL_DMA_ENABLED */ +__USB_ALIGN_BEGIN HOST_CSW_PACKET_TypeDef USBH_MSC_CSWData; + +USB_HOST_BOTXFER_TypeDef USBH_MSC_BOTXferParam; + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ +#ifdef USB_INTERNAL_DMA_ENABLED +#if defined ( __ICCARM__ ) /*!< IAR Compiler */ +#pragma data_alignment=4 +#endif +#endif /* USB_INTERNAL_DMA_ENABLED */ +__USB_ALIGN_BEGIN HostCBWPkt_TypeDef USBH_MSC_CBWData; + +static uint32_t BOTStallErrorCount; /* Keeps count of STALL Error Cases*/ + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ + +/** + * @brief initializes original state of the mass storage parameters + * @param [in] pdev device instance + * @retval None + */ +void usb_host_msc_init(usb_core_instance *pdev) +{ + if (host_driver_ifdevconnected(pdev) != 0UL) { + USBH_MSC_CBWData.field.CBWSignature = HOST_MSC_BOT_CBW_SIGNATURE; + USBH_MSC_CBWData.field.CBWTag = HOST_MSC_BOT_CBW_TAG; + USBH_MSC_CBWData.field.CBWLUN = 0U; + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + } + BOTStallErrorCount = 0UL; + MSCErrorCount = 0U; +} + +/** + * @brief manages the different states of BOT transfer and updates the + * status for the upper layer. + * @param [in] pdev device instance + * @param [in] phost host state set + * @retval None + */ +void usb_host_msc_botxferprocess(usb_core_instance *pdev, USBH_HOST *phost) +{ + uint8_t xferDirection, index; + static uint32_t remainingDataLength; + static uint8_t *datapointer, *datapointer_prev; + static uint8_t error_direction; + HOST_STATUS status; + + HOST_CH_XFER_STATE URB_Status; + + if (host_driver_ifdevconnected(pdev) != 0UL) { + + switch (USBH_MSC_BOTXferParam.BOTState) { + case HOST_MSC_SEND_CBW: + /* send a CBW */ + usb_host_sendbulkdata(pdev, + &USBH_MSC_CBWData.CBWArray[0], + HOST_MSC_BOT_CBW_PACKET_LENGTH, + MSC_Machine.hc_num_out); + USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_SEND_CBW; + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_SENT_CBW; + break; + case HOST_MSC_SENT_CBW: + URB_Status = host_driver_getxferstate(pdev, MSC_Machine.hc_num_out); + switch (URB_Status) { + case HOST_CH_XFER_DONE: + BOTStallErrorCount = 0U; + USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_SENT_CBW; + /* If the CBW packet is sent successful, then update the state */ + xferDirection = (USBH_MSC_CBWData.field.CBWFlags & USB_REQ_DIR_MASK); + if (USBH_MSC_CBWData.field.CBWTransferLength != 0UL) { + remainingDataLength = USBH_MSC_CBWData.field.CBWTransferLength ; + datapointer = USBH_MSC_BOTXferParam.pRxTxBuff; + datapointer_prev = datapointer; + /* If there has data transfer stage, update the direction whether it is D2H or H2D */ + if (xferDirection == USB_D2H) { + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_BOT_DATAIN_STATE; + } else { + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_BOT_DATAOUT_STATE; + } + } else { + /* If there has not data transfer stage also update the state */ + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_RECEIVE_CSW_STATE; + } + break; + case HOST_CH_XFER_UNREADY: + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp; + break; + case HOST_CH_XFER_STALL: + error_direction = HOST_MSC_DIR_OUT; + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_BOT_ERROR_OUT; + break; + default: + break; + } + break; + + case HOST_MSC_BOT_DATAIN_STATE: + URB_Status = host_driver_getxferstate(pdev, MSC_Machine.hc_num_in); + if ((URB_Status == HOST_CH_XFER_DONE) \ + || (USBH_MSC_BOTXferParam.BOTStateBkp != HOST_MSC_BOT_DATAIN_STATE)) { + BOTStallErrorCount = 0U; + USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_BOT_DATAIN_STATE; + + if (remainingDataLength > MSC_Machine.MSC_BulkInEpSize) { + usb_host_recvbulkdata(pdev, + datapointer, + MSC_Machine.MSC_BulkInEpSize, + MSC_Machine.hc_num_in); + remainingDataLength -= MSC_Machine.MSC_BulkInEpSize; + datapointer = datapointer + MSC_Machine.MSC_BulkInEpSize; + } else if (remainingDataLength == 0UL) { + /* If value was 0, and successful transfer, then change the state */ + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_RECEIVE_CSW_STATE; + } else { + usb_host_recvbulkdata(pdev, + datapointer, + (uint16_t)remainingDataLength, + MSC_Machine.hc_num_in); + remainingDataLength = 0UL; + } + } else if (URB_Status == HOST_CH_XFER_STALL) { + error_direction = HOST_MSC_DIR_IN; + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_BOT_ERROR_IN; + USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_RECEIVE_CSW_STATE; + } else { + ; + } + break; + case HOST_MSC_BOT_DATAOUT_STATE: + URB_Status = host_driver_getxferstate(pdev, MSC_Machine.hc_num_out); + if (URB_Status == HOST_CH_XFER_DONE) { + BOTStallErrorCount = 0UL; + USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_BOT_DATAOUT_STATE; + if (remainingDataLength > MSC_Machine.MSC_BulkOutEpSize) { + usb_host_sendbulkdata(pdev, + datapointer, + MSC_Machine.MSC_BulkOutEpSize, + MSC_Machine.hc_num_out); + datapointer_prev = datapointer; + datapointer = datapointer + MSC_Machine.MSC_BulkOutEpSize; + + remainingDataLength = remainingDataLength - MSC_Machine.MSC_BulkOutEpSize; + } else if (remainingDataLength == 0UL) { + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_RECEIVE_CSW_STATE; + } else { + usb_host_sendbulkdata(pdev, + datapointer, + (uint16_t)remainingDataLength, + MSC_Machine.hc_num_out); + remainingDataLength = 0UL; + } + } else if (URB_Status == HOST_CH_XFER_UNREADY) { + if (datapointer != datapointer_prev) { + usb_host_sendbulkdata(pdev, + (datapointer - MSC_Machine.MSC_BulkOutEpSize), + MSC_Machine.MSC_BulkOutEpSize, + MSC_Machine.hc_num_out); + } else { + usb_host_sendbulkdata(pdev, + datapointer, + MSC_Machine.MSC_BulkOutEpSize, + MSC_Machine.hc_num_out); + } + } else if (URB_Status == HOST_CH_XFER_STALL) { + error_direction = HOST_MSC_DIR_OUT; + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_BOT_ERROR_OUT; + USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_RECEIVE_CSW_STATE; + } else { + ; + } + break; + + case HOST_MSC_RECEIVE_CSW_STATE: + USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_RECEIVE_CSW_STATE; + USBH_MSC_BOTXferParam.pRxTxBuff = USBH_MSC_CSWData.CSWArray; + USBH_MSC_BOTXferParam.DataLength = HOST_MSC_CSW_MAX_LENGTH; + for (index = 0U; index < HOST_MSC_CSW_LENGTH; index++) { + USBH_MSC_CSWData.CSWArray[index] = 0U; + } + + USBH_MSC_CSWData.CSWArray[0] = 0U; + usb_host_recvbulkdata(pdev, + USBH_MSC_BOTXferParam.pRxTxBuff, + HOST_MSC_CSW_MAX_LENGTH, + MSC_Machine.hc_num_in); + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_DECODE_CSW; + + break; + + case HOST_MSC_DECODE_CSW: + URB_Status = host_driver_getxferstate(pdev, MSC_Machine.hc_num_in); + if (URB_Status == HOST_CH_XFER_DONE) { + BOTStallErrorCount = 0UL; + USBH_MSC_BOTXferParam.BOTStateBkp = HOST_MSC_RECEIVE_CSW_STATE; + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateCurrent ; + USBH_MSC_BOTXferParam.BOTXferStatus = usb_host_msc_cswdecode(pdev, phost); + } else if (URB_Status == HOST_CH_XFER_STALL) { + error_direction = HOST_MSC_DIR_IN; + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_BOT_ERROR_IN; + } else { + ; + } + break; + + case HOST_MSC_BOT_ERROR_IN: + status = usb_host_msc_botabort(pdev, phost, HOST_MSC_DIR_IN); + if (status == HSTATUS_OK) { + if (error_direction == HOST_MSC_BOTH_DIR) { + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_BOT_ERROR_OUT; + } else { + /* switch back to the original state */ + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp; + } + } else if (status == HSTATUS_UNRECOVERED_ERROR) { + /* This means that there is a STALL Error limit, Do Reset Recovery */ + USBH_MSC_BOTXferParam.BOTXferStatus = (uint8_t)USB_HOST_MSC_PHASE_ERROR; + } else { + ; + } + break; + case HOST_MSC_BOT_ERROR_OUT: + status = usb_host_msc_botabort(pdev, phost, HOST_MSC_DIR_OUT); + if (status == HSTATUS_OK) { + /* switch back to the original state */ + USBH_MSC_BOTXferParam.BOTState = USBH_MSC_BOTXferParam.BOTStateBkp; + } else if (status == HSTATUS_UNRECOVERED_ERROR) { + /* This means that there is a STALL Error limit, Do Reset Recovery */ + USBH_MSC_BOTXferParam.BOTXferStatus = (uint8_t)USB_HOST_MSC_PHASE_ERROR; + } else { + ; + } + break; + + default: + break; + } + } +} + +/** + * @brief manages the different Error handling for STALL + * @param [in] pdev device instance + * @param [in] phost host state set + * @param [in] direction IN / OUT + * @retval None + */ +HOST_STATUS usb_host_msc_botabort(usb_core_instance *pdev, USBH_HOST *phost, uint8_t direction) +{ + HOST_STATUS status; + + status = HSTATUS_BUSY; + + switch (direction) { + case HOST_MSC_DIR_IN: + /* send ClrFeture on Bulk IN endpoint */ + status = usb_host_clrfeature(pdev, + phost, + MSC_Machine.MSC_BulkInEp, + MSC_Machine.hc_num_in); + break; + case HOST_MSC_DIR_OUT: + /* send ClrFeature on Bulk OUT endpoint */ + status = usb_host_clrfeature(pdev, + phost, + MSC_Machine.MSC_BulkOutEp, + MSC_Machine.hc_num_out); + break; + default: + break; + } + BOTStallErrorCount++; + if (BOTStallErrorCount > 4UL) { + status = HSTATUS_UNRECOVERED_ERROR; + } + return status; +} + +/** + * @brief Decodes the CSW received by the device and updates the same to upper layer + * @param [in] pdev device instance + * @param [in] phost host state set + * @retval On success USB_HOST_MSC_OK, on failure USB_HOST_MSC_FAIL + */ +uint8_t usb_host_msc_cswdecode(usb_core_instance *pdev, USBH_HOST *phost) +{ + USB_HOST_MSC_STATUS status; + uint32_t dataXferCount; + status = USB_HOST_MSC_FAIL; + + if (host_driver_ifdevconnected(pdev) != 0UL) { + dataXferCount = host_driver_getxfercnt(pdev, MSC_Machine.hc_num_in); + if (dataXferCount != HOST_MSC_CSW_LENGTH) { + /*(4) Hi > Dn (Host expects to receive data from the device, + Device intends to transfer no data) + (5) Hi > Di (Host expects to receive data from the device, + Device intends to send data to the host) + (9) Ho > Dn (Host expects to send data to the device, + Device intends to transfer no data) + (11) Ho > Do (Host expects to send data to the device, + Device intends to receive data from the host)*/ + status = USB_HOST_MSC_PHASE_ERROR; + } else { + /* CSW length is Correct */ + + /* Check validity of the CSW Signature and CSWStatus */ + if (USBH_MSC_CSWData.field.dCSWSignature == HOST_MSC_BOT_CSW_SIGNATURE) { + /* Check Condition 1. dCSWSignature is equal to 53425355h */ + if (USBH_MSC_CSWData.field.dCSWTag == USBH_MSC_CBWData.field.CBWTag) { + /* Check Condition 3. dCSWTag matches the dCBWTag from the + corresponding CBW */ + if (USBH_MSC_CSWData.field.dCSWStatus == (uint8_t)USB_HOST_MSC_OK) { + /* Refer to USB Mass-Storage Class : BOT (www.usb.org) + + Hn Host expects no data transfers + Hi Host expects to receive data from the device + Ho Host expects to send data to the device + + Dn Device intends to transfer no data + Di Device intends to send data to the host + Do Device intends to receive data from the host + + Section 6.7 + (1) Hn = Dn (Host expects no data transfers, + Device intends to transfer no data) + (6) Hi = Di (Host expects to receive data from the device, + Device intends to send data to the host) + (12) Ho = Do (Host expects to send data to the device, + Device intends to receive data from the host) + */ + status = USB_HOST_MSC_OK; + } else if (USBH_MSC_CSWData.field.dCSWStatus == (uint8_t)USB_HOST_MSC_FAIL) { + status = USB_HOST_MSC_FAIL; + } else if (USBH_MSC_CSWData.field.dCSWStatus == (uint8_t)USB_HOST_MSC_PHASE_ERROR) { + /* Refer to USB Mass-Storage Class : BOT (www.usb.org) + Section 6.7 + (2) Hn < Di ( Host expects no data transfers, + Device intends to send data to the host) + (3) Hn < Do ( Host expects no data transfers, + Device intends to receive data from the host) + (7) Hi < Di ( Host expects to receive data from the device, + Device intends to send data to the host) + (8) Hi <> Do ( Host expects to receive data from the device, + Device intends to receive data from the host) + (10) Ho <> Di (Host expects to send data to the device, + Di Device intends to send data to the host) + (13) Ho < Do (Host expects to send data to the device, + Device intends to receive data from the host) + */ + status = USB_HOST_MSC_PHASE_ERROR; + } else { + ; + } + } + } else { + status = USB_HOST_MSC_PHASE_ERROR; + } + } + } + + USBH_MSC_BOTXferParam.BOTXferStatus = (uint8_t)status; + return (uint8_t)status; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_bot.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_bot.h new file mode 100644 index 000000000..7950e7b6b --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_bot.h @@ -0,0 +1,162 @@ +/** + ******************************************************************************* + * @file usb_host_msc_bot.h + * @brief Head file for usb_host_msc_bot.c + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ +#ifndef __USB_HOST_MSC_BOT_H__ +#define __USB_HOST_MSC_BOT_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_stdreq.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CLASS + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_MSC + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ +typedef union _USBH_CBW_Block { + struct __CBW { + uint32_t CBWSignature; + uint32_t CBWTag; + uint32_t CBWTransferLength; + uint8_t CBWFlags; + uint8_t CBWLUN; + uint8_t CBWLength; + uint8_t CBWCB[16]; + } field; + uint8_t CBWArray[31]; +} HostCBWPkt_TypeDef; + +typedef struct { + uint8_t MSCState; + uint8_t MSCStateBkp; + uint8_t MSCStateCurrent; + uint8_t CmdStateMachine; + uint8_t BOTState; + uint8_t BOTStateBkp; + uint8_t *pRxTxBuff; + uint16_t DataLength; + uint8_t BOTXferStatus; +} USB_HOST_BOTXFER_TypeDef; + +typedef union { + struct { + uint32_t dCSWSignature; + uint32_t dCSWTag; + uint32_t dCSWDataResidue; + uint8_t dCSWStatus; + } field; + uint8_t CSWArray[13]; +} HOST_CSW_PACKET_TypeDef; + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ +#define HOST_MSC_BOT_INIT_STATE (0U) +#define HOST_MSC_BOT_RESET (1U) +#define HOST_MSC_GET_MAX_LUN (2U) +#define HOST_MSC_TEST_UNIT_READY (3U) +#define HOST_MSC_READ_CAPACITY10 (4U) +#define HOST_MSC_MODE_SENSE6 (5U) +#define HOST_MSC_REQUEST_SENSE (6U) +#define HOST_MSC_BOT_USB_TRANSFERS (7U) +#define HOST_MSC_DEFAULT_APPLI_STATE (8U) +#define HOST_MSC_CTRL_ERROR_STATE (9U) +#define HOST_MSC_UNRECOVERED_STATE (10U) + +#define HOST_MSC_SEND_CBW (1U) +#define HOST_MSC_SENT_CBW (2U) +#define HOST_MSC_BOT_DATAIN_STATE (3U) +#define HOST_MSC_BOT_DATAOUT_STATE (4U) +#define HOST_MSC_RECEIVE_CSW_STATE (5U) +#define HOST_MSC_DECODE_CSW (6U) +#define HOST_MSC_BOT_ERROR_IN (7U) +#define HOST_MSC_BOT_ERROR_OUT (8U) + +#define HOST_MSC_BOT_CBW_SIGNATURE (0x43425355UL) +#define HOST_MSC_BOT_CBW_TAG (0x20304050UL) +#define HOST_MSC_BOT_CSW_SIGNATURE (0x53425355UL) +#define HOST_MSC_CSW_DATA_LENGTH (13U) +#define HOST_MSC_BOT_CBW_PACKET_LENGTH (31U) +#define HOST_MSC_CSW_LENGTH (13U) +#define HOST_MSC_CSW_MAX_LENGTH (63U) +#define HOST_MSC_DIR_IN (0U) +#define HOST_MSC_DIR_OUT (1U) +#define HOST_MSC_BOTH_DIR (2U) +#define HOST_MSC_PAGE_LENGTH (512UL) + +#define CBW_CB_LENGTH (16U) +#define CBW_LENGTH (10U) +#define CBW_LENGTH_TEST_UNIT_READY (6U) + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ +extern USB_HOST_BOTXFER_TypeDef USBH_MSC_BOTXferParam; +extern HostCBWPkt_TypeDef USBH_MSC_CBWData; +extern HOST_CSW_PACKET_TypeDef USBH_MSC_CSWData; + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +extern void usb_host_msc_init(usb_core_instance *pdev); +extern void usb_host_msc_botxferprocess(usb_core_instance *pdev, USBH_HOST *phost); +extern uint8_t usb_host_msc_cswdecode(usb_core_instance *pdev, USBH_HOST *phost); +extern HOST_STATUS usb_host_msc_botabort(usb_core_instance *pdev, USBH_HOST *phost, uint8_t direction); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_HOST_MSC_BOT_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_class.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_class.c new file mode 100644 index 000000000..601b5834e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_class.c @@ -0,0 +1,395 @@ +/** + ******************************************************************************* + * @file usb_host_msc_class.c + * @brief The MSC class driver functions + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_msc_class.h" +#include "usb_host_msc_scsi.h" +#include "usb_host_msc_bot.h" +#include "usb_host_core.h" +#include "usb_host_driver.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CLASS + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_MSC + * @{ + */ + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ +#define USBH_MSC_ERROR_RETRY_LIMIT (10U) + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ +HOST_STATUS usb_host_msc_itfinit(usb_core_instance *pdev, void *phost); +void usb_host_msc_itfdeinit(usb_core_instance *pdev); +HOST_STATUS usb_host_msc_process(usb_core_instance *pdev, void *phost); +HOST_STATUS usb_host_msc_classreq(usb_core_instance *pdev, void *phost); + +HOST_STATUS usb_host_msc_bot_reset(usb_core_instance *pdev, USBH_HOST *phost); +HOST_STATUS usb_host_msc_maxlun_get(usb_core_instance *pdev, USBH_HOST *phost); +void usb_host_msc_error_process(USB_HOST_MSC_STATUS status); + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ +#ifdef USB_INTERNAL_DMA_ENABLED +#if defined ( __ICCARM__ ) /*!< IAR Compiler */ +#pragma data_alignment=4 +#endif +#endif /* USB_INTERNAL_DMA_ENABLED */ +__USB_ALIGN_BEGIN MSC_Machine_TypeDef MSC_Machine; + +#ifdef USB_INTERNAL_DMA_ENABLED +#if defined ( __ICCARM__ ) /*!< IAR Compiler */ +#pragma data_alignment=4 +#endif +#endif /* USB_INTERNAL_DMA_ENABLED */ +uint8_t MSCErrorCount = 0U; + +usb_host_class_callback_func USBH_MSC_cb = { + &usb_host_msc_itfinit, + &usb_host_msc_itfdeinit, + &usb_host_msc_classreq, + &usb_host_msc_process, +}; + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ +/** + * @brief This request is used to issue a request to reset the msc device and + * its related interface. This class-specific request shall prepare the + * device for the next CBW from the host. + * @param [in] pdev device instance + * @param [in] phost host state set + * @retval status define by HOST_STATUS + */ +HOST_STATUS usb_host_msc_bot_reset(usb_core_instance *pdev, USBH_HOST *phost) +{ + phost->ctrlparam.setup.b.bmRequestType = USB_H2D | USB_REQ_TYPE_CLASS | \ + USB_REQ_RECIPIENT_INTERFACE; + phost->ctrlparam.setup.b.bRequest = USB_REQ_BOT_RESET; + phost->ctrlparam.setup.b.wValue.w = 0U; + phost->ctrlparam.setup.b.wIndex.w = 0U; + phost->ctrlparam.setup.b.wLength.w = 0U; + return usb_host_ctrlreq(pdev, phost, NULL, 0U); +} + +/** + * @brief this request is used to issue a request to get the max logic unit of + * the msc device. + * @param [in] pdev device instance + * @param [in] phost host state set + * @retval status defined by HOST_STATUS + */ +HOST_STATUS usb_host_msc_maxlun_get(usb_core_instance *pdev, USBH_HOST *phost) +{ + phost->ctrlparam.setup.b.bmRequestType = USB_D2H | USB_REQ_TYPE_CLASS | \ + USB_REQ_RECIPIENT_INTERFACE; + + phost->ctrlparam.setup.b.bRequest = USB_REQ_GET_MAX_LUN; + phost->ctrlparam.setup.b.wValue.w = 0U; + phost->ctrlparam.setup.b.wIndex.w = 0U; + phost->ctrlparam.setup.b.wLength.w = 1U; + return usb_host_ctrlreq(pdev, phost, MSC_Machine.buff, 1U); +} + +/** + * @brief The function is used for handling errors during processing the MSC + * state machine + * @param [in] status + * @retval None + */ +void usb_host_msc_error_process(USB_HOST_MSC_STATUS status) +{ + switch (status) { + case USB_HOST_MSC_FAIL: + MSCErrorCount++; + if (MSCErrorCount < USBH_MSC_ERROR_RETRY_LIMIT) { + /* Try MSC level error recovery, Issue the request Sense to get + driver error reason */ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_REQUEST_SENSE; + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + } else { + /* Error trials exceeded the limit, go to unrecovered state */ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_UNRECOVERED_STATE; + } + break; + case USB_HOST_MSC_PHASE_ERROR: + /* Phase error, Go to Unrecoovered state */ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_UNRECOVERED_STATE; + break; + default: + break; + } +} + +/** + * @brief Interface initialization for msc class application, the channels for + * the IN and OUT EP will be distributed. + * @param [in] pdev device instance + * @param [in] phost host state set + * @retval status defined by HOST_STATUS + */ +HOST_STATUS usb_host_msc_itfinit(usb_core_instance *pdev, void *phost) +{ + USBH_HOST *pphost = phost; + + if ((pphost->device_prop.devitfdesc[0].bInterfaceClass == MSC_CLASS) && \ + (pphost->device_prop.devitfdesc[0].bInterfaceProtocol == MSC_PROTOCOL)) { + if ((pphost->device_prop.devepdesc[0][0].bEndpointAddress & 0x80U) == 0x80U) { + MSC_Machine.MSC_BulkInEp = (pphost->device_prop.devepdesc[0][0].bEndpointAddress); + MSC_Machine.MSC_BulkInEpSize = pphost->device_prop.devepdesc[0][0].wMaxPacketSize; + } else { + MSC_Machine.MSC_BulkOutEp = (pphost->device_prop.devepdesc[0][0].bEndpointAddress); + MSC_Machine.MSC_BulkOutEpSize = pphost->device_prop.devepdesc[0] [0].wMaxPacketSize; + } + if ((pphost->device_prop.devepdesc[0][1].bEndpointAddress & 0x80U) == 0x80U) { + MSC_Machine.MSC_BulkInEp = (pphost->device_prop.devepdesc[0][1].bEndpointAddress); + MSC_Machine.MSC_BulkInEpSize = pphost->device_prop.devepdesc[0][1].wMaxPacketSize; + } else { + MSC_Machine.MSC_BulkOutEp = (pphost->device_prop.devepdesc[0][1].bEndpointAddress); + MSC_Machine.MSC_BulkOutEpSize = pphost->device_prop.devepdesc[0][1].wMaxPacketSize; + } + /* distribute the channels for the EPs */ + MSC_Machine.hc_num_out = usb_host_distrch(pdev, MSC_Machine.MSC_BulkOutEp); + MSC_Machine.hc_num_in = usb_host_distrch(pdev, MSC_Machine.MSC_BulkInEp); + /* open the channels that have distributed */ + usb_host_chopen(pdev, + MSC_Machine.hc_num_out, + pphost->device_prop.devaddr, + pphost->device_prop.devspeed, + EP_TYPE_BULK, + MSC_Machine.MSC_BulkOutEpSize); + usb_host_chopen(pdev, + MSC_Machine.hc_num_in, + pphost->device_prop.devaddr, + pphost->device_prop.devspeed, + EP_TYPE_BULK, + MSC_Machine.MSC_BulkInEpSize); + } else { + pphost->user_callbk->huser_devunsupported(); + } + return HSTATUS_OK ; +} + +/** + * @brief deinitialize interface of msc class by freeing host channels + * @param [in] pdev device instance + * @retval None + */ +void usb_host_msc_itfdeinit(usb_core_instance *pdev) +{ + if (MSC_Machine.hc_num_out != 0U) { + usb_hchstop(&pdev->regs, MSC_Machine.hc_num_out); + (void)usb_host_freech(pdev, MSC_Machine.hc_num_out); + MSC_Machine.hc_num_out = 0U; + } + if (MSC_Machine.hc_num_in != 0U) { + usb_hchstop(&pdev->regs, MSC_Machine.hc_num_in); + (void)usb_host_freech(pdev, MSC_Machine.hc_num_in); + MSC_Machine.hc_num_in = 0U; + } +} + +/** + * @brief initialize the msc state machine + * @param [in] pdev device instance + * @param [in] phost host state set + * @retval status defined by HOST_STATUS + */ +HOST_STATUS usb_host_msc_classreq(usb_core_instance *pdev, void *phost) +{ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_INIT_STATE; + return HSTATUS_OK; +} + +/** + * @brief process the msc state machine + * @param [in] pdev device instance + * @param [in] phost host state set + * @retval status defined by HOST_STATUS + */ +HOST_STATUS usb_host_msc_process(usb_core_instance *pdev, void *phost) +{ + USBH_HOST *pphost = phost; + HOST_STATUS status = HSTATUS_BUSY; + USB_HOST_MSC_STATUS mscStatus; + uint8_t appliStatus; + static uint8_t maxLunExceed = FALSE; + + if (host_driver_ifdevconnected(pdev) != 0UL) { + switch (USBH_MSC_BOTXferParam.MSCState) { + case HOST_MSC_BOT_INIT_STATE: + usb_host_msc_init(pdev); + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_RESET; + break; + case HOST_MSC_BOT_RESET: + /* issue a request to reset the bot. */ + status = usb_host_msc_bot_reset(pdev, phost); + if (status == HSTATUS_OK) { + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_GET_MAX_LUN; + } + if (status == HSTATUS_UNSUPPORTED) { + /* if the request fails, it needs to move to next state and should save the next state as backup */ + USBH_MSC_BOTXferParam.MSCStateBkp = HOST_MSC_GET_MAX_LUN; + /* a clear feature should be issued if the request fails. */ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_CTRL_ERROR_STATE; + } + break; + case HOST_MSC_GET_MAX_LUN: + /* issue a request to get the max logical unit(MAXLUN). */ + status = usb_host_msc_maxlun_get(pdev, phost); + if (status == HSTATUS_OK) { + MSC_Machine.maxLun = *(MSC_Machine.buff) ; + if ((MSC_Machine.maxLun > 0U) && (maxLunExceed == FALSE)) { + maxLunExceed = TRUE; + pphost->user_callbk->huser_devunsupported(); + break; + } + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_TEST_UNIT_READY; + } + + if (status == HSTATUS_UNSUPPORTED) { + /* if the request fails, it needs to move to next state and should save the next state as backup */ + USBH_MSC_BOTXferParam.MSCStateBkp = HOST_MSC_TEST_UNIT_READY; + /* a clear feature should be issued if the request fails. */ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_CTRL_ERROR_STATE; + } + break; + case HOST_MSC_CTRL_ERROR_STATE: + /* issue a request to clear feature */ + status = usb_host_clrfeature(pdev, + phost, + 0x00U, + pphost->ctrlparam.hc_num_out); + if (status == HSTATUS_OK) { + /* If GetMaxLun Request not support, assume Single LUN configuration */ + MSC_Machine.maxLun = 0U; + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateBkp; + } + break; + case HOST_MSC_TEST_UNIT_READY: + /* issue the request Test Unit Ready[0] of SCSI command */ + mscStatus = usb_host_msc_TestUnitReady(pdev); + + if (mscStatus == USB_HOST_MSC_OK) { + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_READ_CAPACITY10; + MSCErrorCount = 0U; + status = HSTATUS_OK; + } else { + usb_host_msc_error_process(mscStatus); + } + break; + + case HOST_MSC_READ_CAPACITY10: + /* issue the request Read Capacity[0] of SCSI command. */ + mscStatus = usb_host_msc_ReadCapacity10(pdev); + if (mscStatus == USB_HOST_MSC_OK) { + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_MODE_SENSE6; + MSCErrorCount = 0U; + status = HSTATUS_OK; + } else { + usb_host_msc_error_process(mscStatus); + } + break; + case HOST_MSC_MODE_SENSE6: + /* issue the request ModeSense6 of SCSI command for detecting whelth the deviec is write-protected. */ + mscStatus = usb_host_msc_ModeSense6(pdev); + if (mscStatus == USB_HOST_MSC_OK) { + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_DEFAULT_APPLI_STATE; + MSCErrorCount = 0U; + status = HSTATUS_OK; + } else { + usb_host_msc_error_process(mscStatus); + } + break; + case HOST_MSC_REQUEST_SENSE: + /* issue the request RequestSense of SCSI command for retreiving error code. */ + mscStatus = usb_host_msc_RequestSense(pdev); + if (mscStatus == USB_HOST_MSC_OK) { + USBH_MSC_BOTXferParam.MSCState = USBH_MSC_BOTXferParam.MSCStateBkp; + status = HSTATUS_OK; + } else { + usb_host_msc_error_process(mscStatus); + } + break; + case HOST_MSC_BOT_USB_TRANSFERS: + /* handle the BOT state machine. */ + usb_host_msc_botxferprocess(pdev, phost); + break; + case HOST_MSC_DEFAULT_APPLI_STATE: + /* handle the user callback for the msc application. */ + appliStatus = pphost->user_callbk->huser_application(); + if (appliStatus == 0U) { + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_DEFAULT_APPLI_STATE; + } else if (appliStatus == 1U) { + /* deinit requested from the application layer. */ + status = HSTATUS_APP_DEINIT; + } else { + ; + } + break; + case HOST_MSC_UNRECOVERED_STATE: + status = HSTATUS_UNRECOVERED_ERROR; + break; + default: + break; + } + } + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_class.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_class.h new file mode 100644 index 000000000..fc3b7cfff --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_class.h @@ -0,0 +1,113 @@ +/** + ******************************************************************************* + * @file usb_host_msc_class.h + * @brief Head file for usb_host_msc_class.c + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ +#ifndef __USB_HOST_MSC_CLASS_H__ +#define __USB_HOST_MSC_CLASS_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_core.h" +#include "usb_host_stdreq.h" +#include "usb_bsp.h" +#include "usb_host_ctrltrans.h" +#include "usb_host_cfgch.h" +#include "usb_host_msc_class.h" +#include "usb_host_msc_scsi.h" +#include "usb_host_msc_bot.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CLASS + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_MSC + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ + +/* Structure for MSC process */ +typedef struct { + uint8_t hc_num_in; + uint8_t hc_num_out; + uint8_t MSC_BulkOutEp; + uint8_t MSC_BulkInEp; + uint16_t MSC_BulkInEpSize; + uint16_t MSC_BulkOutEpSize; + uint8_t buff[USBH_MSC_MPS_SIZE]; + uint8_t maxLun; +} MSC_Machine_TypeDef; + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ +#define USB_REQ_BOT_RESET (0xFFU) +#define USB_REQ_GET_MAX_LUN (0xFEU) + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ +extern usb_host_class_callback_func USBH_MSC_cb; +extern MSC_Machine_TypeDef MSC_Machine; +extern uint8_t MSCErrorCount; + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_HOST_MSC_CLASS_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ + + + + diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_fatfs.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_fatfs.c new file mode 100644 index 000000000..0a7e302f3 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_fatfs.c @@ -0,0 +1,241 @@ +/** + ******************************************************************************* + * @file usb_host_msc_fatfs.c + * @brief The fatfs functions. + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_app_conf.h" +#include "usb_host_driver.h" +#ifdef USB_MSC_FAT_VALID +#include "ff.h" +#include "diskio.h" +#include "usb_host_msc_class.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CLASS + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_MSC + * @{ + */ + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ +static volatile DSTATUS Stat = STA_NOINIT; /* Disk status */ + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ + +extern usb_core_instance usb_app_instance; +extern USBH_HOST usb_app_host; + +/** + * @brief Initialize Disk Drive + * @param [in] drv Physical drive number (0) + * @retval DSTATUS + */ +DSTATUS disk_initialize(BYTE drv) +{ + if (host_driver_ifdevconnected(&usb_app_instance) != 0UL) { + Stat &= (DSTATUS)~STA_NOINIT; + } + return Stat; +} + +/** + * @brief Get Disk Status + * @param [in] drv Physical drive number (0) + * @retval DSTATUS + */ +DSTATUS disk_status(BYTE drv) +{ + DSTATUS status = Stat; + if (drv != 0U) { + status = STA_NOINIT; /* Supports only single drive */ + } + return status; +} + +/** + * @brief Read Sector(s) + * @param [in] drv Physical drive number (0) + * @param [in] buff Pointer to the data buffer to store read data + * @param [in] sector Start sector number (LBA) + * @param [in] count Sector count (1..255) + * @retval DSTATUS + */ +DRESULT disk_read(BYTE pdrv, BYTE *buff, LBA_t sector, UINT count) +{ + USB_HOST_MSC_STATUS status = USB_HOST_MSC_OK; + + if ((pdrv != 0U) || (count == 0UL)) { + return RES_PARERR; + } + if ((Stat & STA_NOINIT) == STA_NOINIT) { + return RES_NOTRDY; + } + + if (host_driver_ifdevconnected(&usb_app_instance) != 0UL) { + + do { + status = usb_host_msc_Read10(&usb_app_instance, buff, sector, 512UL * (uint32_t)count); + usb_host_msc_botxferprocess(&usb_app_instance, &usb_app_host); + + if (host_driver_ifdevconnected(&usb_app_instance) == 0UL) { + return RES_ERROR; + } + } while (status == USB_HOST_MSC_BUSY); + } + + if (status == USB_HOST_MSC_OK) { + return RES_OK; + } + return RES_ERROR; + +} + + +#if _READONLY == 0 +/** + * @brief Write Sector(s) + * @param [in] drv Physical drive number (0) + * @param [in] buff Pointer to the data to be written + * @param [in] sector Start sector number (LBA) + * @param [in] count Sector count (1..255) + * @retval DSTATUS + */ +DRESULT disk_write(BYTE pdrv, const BYTE *buff, LBA_t sector, UINT count) +{ + USB_HOST_MSC_STATUS status = USB_HOST_MSC_OK; + + if ((pdrv != 0U) || (count == 0UL)) { + return RES_PARERR; + } + if ((Stat & STA_NOINIT) == STA_NOINIT) { + return RES_NOTRDY; + } + if ((Stat & STA_PROTECT) == STA_PROTECT) { + return RES_WRPRT; + } + if (host_driver_ifdevconnected(&usb_app_instance) != 0UL) { + do { + status = usb_host_msc_Write10(&usb_app_instance, (BYTE *)buff, sector, 512UL * (uint32_t)count); + usb_host_msc_botxferprocess(&usb_app_instance, &usb_app_host); + + if (host_driver_ifdevconnected(&usb_app_instance) == 0UL) { + return RES_ERROR; + } + } while (status == USB_HOST_MSC_BUSY); + } + + if (status == USB_HOST_MSC_OK) { + return RES_OK; + } + return RES_ERROR; +} +#endif /* _READONLY == 0 */ + +//#if _USE_IOCTL != 0 +/** + * @brief Miscellaneous Functions + * @param [in] drv Physical drive number (0) + * @param [in] ctrl Control code + * @param [in] buff Buffer to send/receive control data + ** + * @retval DSTATUS + */ +DRESULT disk_ioctl(BYTE pdrv, BYTE cmd, void *buff) +{ + DRESULT res; + + if (pdrv != 0U) { + return RES_PARERR; + } + + res = RES_ERROR; + + if ((Stat & STA_NOINIT) == STA_NOINIT) { + return RES_NOTRDY; + } + + switch (cmd) { + case CTRL_SYNC : /* Make sure that no pending write process */ + res = RES_OK; + break; + case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */ + *(DWORD *)buff = (DWORD) USB_HOST_MSC_Param.MSC_Capacity; + res = RES_OK; + break; + case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */ + *(WORD *)buff = 512U; + res = RES_OK; + break; + case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */ + *(DWORD *)buff = 512UL; + break; + default: + res = RES_PARERR; + break; + } + return res; +} +//#endif +#endif /* _USE_IOCTL != 0 */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_scsi.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_scsi.c new file mode 100644 index 000000000..f5964cc9c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_scsi.c @@ -0,0 +1,528 @@ +/** + ******************************************************************************* + * @file usb_host_msc_scsi.c + * @brief The SCSI commands。 + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_msc_class.h" +#include "usb_host_msc_scsi.h" +#include "usb_host_msc_bot.h" +#include "usb_host_ctrltrans.h" +#include "usb_host_def.h" +#include "usb_host_driver.h" +#include + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CLASS + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_MSC + * @{ + */ + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ +MSC_PARAMETER USB_HOST_MSC_Param; + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ +#ifdef USB_INTERNAL_DMA_ENABLED +#if defined ( __ICCARM__ ) +#pragma data_alignment=4 +#endif +#endif +__USB_ALIGN_BEGIN static uint8_t USB_HOST_DataInBuf[512]; + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ + +/** + * @brief Issues 'Test Unit Ready' command to the device. Once the response + * received, it updates the status to upper layer, the length of the + * command are 31bytes. + * @param [in] pdev device instance + * @retval status define by USB_HOST_MSC_STATUS + */ +USB_HOST_MSC_STATUS usb_host_msc_TestUnitReady(usb_core_instance *pdev) +{ + uint8_t index; + USB_HOST_MSC_STATUS status = USB_HOST_MSC_BUSY; + + if (host_driver_ifdevconnected(pdev) != 0UL) { + switch (USBH_MSC_BOTXferParam.CmdStateMachine) { + case USB_HOST_MSC_CMD_SEND: + USBH_MSC_CBWData.field.CBWTransferLength = 0UL; + USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_OUT; + USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH_TEST_UNIT_READY; + USBH_MSC_BOTXferParam.pRxTxBuff = USBH_MSC_CSWData.CSWArray; + USBH_MSC_BOTXferParam.DataLength = HOST_MSC_CSW_MAX_LENGTH; + USBH_MSC_BOTXferParam.MSCStateCurrent = HOST_MSC_TEST_UNIT_READY; + for (index = 0U; index < CBW_CB_LENGTH; index++) { + USBH_MSC_CBWData.field.CBWCB[index] = 0x00U; + } + USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_TEST_UNIT_READY; + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_SEND_CBW; + /* Start the transfer, then let the state machine magage the other transactions */ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_USB_TRANSFERS; + USBH_MSC_BOTXferParam.BOTXferStatus = (uint8_t)USB_HOST_MSC_BUSY; + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_WAIT; + + status = USB_HOST_MSC_BUSY; + break; + + case USB_HOST_MSC_CMD_WAIT: + switch (USBH_MSC_BOTXferParam.BOTXferStatus) { + case USB_HOST_MSC_OK: + /* Commands successfully sent and Response Received */ + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_OK; + break; + case USB_HOST_MSC_FAIL: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_FAIL; + break; + case USB_HOST_MSC_PHASE_ERROR: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_PHASE_ERROR; + break; + default: + break; + } + break; + default: + break; + } + } + return status; +} + +/** + * @brief Issue the 'Read capacity10' command to the device. Once the response + * received, it updates the status to upper layer + * @param [in] pdev device instance + * @retval status define by USB_HOST_MSC_STATUS + */ +USB_HOST_MSC_STATUS usb_host_msc_ReadCapacity10(usb_core_instance *pdev) +{ + uint8_t index; + USB_HOST_MSC_STATUS status = USB_HOST_MSC_BUSY; + + if (host_driver_ifdevconnected(pdev) != 0UL) { + switch (USBH_MSC_BOTXferParam.CmdStateMachine) { + case USB_HOST_MSC_CMD_SEND: + /*Prepare the CBW and relevent field*/ + USBH_MSC_CBWData.field.CBWTransferLength = XFER_LEN_READ_CAPACITY10; + USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN; + USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH; + USBH_MSC_BOTXferParam.pRxTxBuff = USB_HOST_DataInBuf; + USBH_MSC_BOTXferParam.MSCStateCurrent = HOST_MSC_READ_CAPACITY10; + for (index = 0U; index < CBW_CB_LENGTH; index++) { + USBH_MSC_CBWData.field.CBWCB[index] = 0x00U; + } + USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_READ_CAPACITY10; + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_SEND_CBW; + /* Start the transfer, then let the state machine manage the other + transactions */ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_USB_TRANSFERS; + USBH_MSC_BOTXferParam.BOTXferStatus = (uint8_t)USB_HOST_MSC_BUSY; + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_WAIT; + status = USB_HOST_MSC_BUSY; + break; + + case USB_HOST_MSC_CMD_WAIT: + switch (USBH_MSC_BOTXferParam.BOTXferStatus) { + case USB_HOST_MSC_OK: + /*assign the capacity*/ + (((uint8_t *)&USB_HOST_MSC_Param.MSC_Capacity)[3]) = USB_HOST_DataInBuf[0]; + (((uint8_t *)&USB_HOST_MSC_Param.MSC_Capacity)[2]) = USB_HOST_DataInBuf[1]; + (((uint8_t *)&USB_HOST_MSC_Param.MSC_Capacity)[1]) = USB_HOST_DataInBuf[2]; + (((uint8_t *)&USB_HOST_MSC_Param.MSC_Capacity)[0]) = USB_HOST_DataInBuf[3]; + /*assign the page length*/ + (((uint8_t *)&USB_HOST_MSC_Param.MSC_PageLength)[1]) = USB_HOST_DataInBuf[6]; + (((uint8_t *)&USB_HOST_MSC_Param.MSC_PageLength)[0]) = USB_HOST_DataInBuf[7]; + /* Commands successfully sent and Response Received */ + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_OK; + break; + case USB_HOST_MSC_FAIL: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_FAIL; + break; + case USB_HOST_MSC_PHASE_ERROR: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_PHASE_ERROR; + break; + default: + break; + } + break; + + default: + break; + } + } + return status; +} + +/** + * @brief Issue the 'Mode Sense6' Command to the device. This function is used + * for reading the WriteProtect Status of the MSC device. + * @param [in] pdev device instance + * @retval status by USB_HOST_MSC_STATUS + */ +USB_HOST_MSC_STATUS usb_host_msc_ModeSense6(usb_core_instance *pdev) +{ + uint8_t index; + USB_HOST_MSC_STATUS status = USB_HOST_MSC_BUSY; + + if (host_driver_ifdevconnected(pdev) != 0UL) { + switch (USBH_MSC_BOTXferParam.CmdStateMachine) { + case USB_HOST_MSC_CMD_SEND: + /*Prepare the CBW and relevent field*/ + USBH_MSC_CBWData.field.CBWTransferLength = XFER_LEN_MODE_SENSE6; + USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN; + USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH; + + USBH_MSC_BOTXferParam.pRxTxBuff = USB_HOST_DataInBuf; + USBH_MSC_BOTXferParam.MSCStateCurrent = HOST_MSC_MODE_SENSE6; + + for (index = 0U; index < CBW_CB_LENGTH; index++) { + USBH_MSC_CBWData.field.CBWCB[index] = 0x00U; + } + + USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_MODE_SENSE6; + USBH_MSC_CBWData.field.CBWCB[2] = MODE_SENSE_PAGE_CONTROL_FIELD | \ + MODE_SENSE_PAGE_CODE; + + USBH_MSC_CBWData.field.CBWCB[4] = XFER_LEN_MODE_SENSE6; + + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_SEND_CBW; + + /* Start the transfer, then let the state machine manage the other + transactions */ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_USB_TRANSFERS; + USBH_MSC_BOTXferParam.BOTXferStatus = (uint8_t)USB_HOST_MSC_BUSY; + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_WAIT; + + status = USB_HOST_MSC_BUSY; + break; + + case USB_HOST_MSC_CMD_WAIT: + switch (USBH_MSC_BOTXferParam.BOTXferStatus) { + case USB_HOST_MSC_OK: + /* Assign the Write Protect status */ + /* If WriteProtect = 0, Writing is allowed + If WriteProtect != 0, Disk is Write Protected */ + if (0U != (USB_HOST_DataInBuf[2] & MASK_MODE_SENSE_WRITE_PROTECT)) { + USB_HOST_MSC_Param.MSC_WriteProtect = DISK_WRITE_PROTECTED; + } else { + USB_HOST_MSC_Param.MSC_WriteProtect = 0U; + } + + /* Commands successfully sent and Response Received */ + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_OK; + break; + case USB_HOST_MSC_FAIL: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_FAIL; + break; + case USB_HOST_MSC_PHASE_ERROR: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_PHASE_ERROR; + break; + default: + break; + } + break; + + default: + break; + } + } + return status; +} + +/** + * @brief usb_host_msc_RequestSense + * Issues the Request Sense command to the device. Once the response + * received, it updates the status to upper layer + * @param [in] pdev device instance + * @retval status defined by USB_HOST_MSC_STATUS + */ +USB_HOST_MSC_STATUS usb_host_msc_RequestSense(usb_core_instance *pdev) +{ + USB_HOST_MSC_STATUS status = USB_HOST_MSC_BUSY; + uint8_t index; + + if (host_driver_ifdevconnected(pdev) != 0UL) { + switch (USBH_MSC_BOTXferParam.CmdStateMachine) { + case USB_HOST_MSC_CMD_SEND: + /*Prepare the CBW and relevent field*/ + USBH_MSC_CBWData.field.CBWTransferLength = \ + ALLOCATION_LENGTH_REQUEST_SENSE; + USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN; + USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH; + + USBH_MSC_BOTXferParam.pRxTxBuff = USB_HOST_DataInBuf; + USBH_MSC_BOTXferParam.MSCStateBkp = USBH_MSC_BOTXferParam.MSCStateCurrent; + USBH_MSC_BOTXferParam.MSCStateCurrent = HOST_MSC_REQUEST_SENSE; + + for (index = 0U; index < CBW_CB_LENGTH; index++) { + USBH_MSC_CBWData.field.CBWCB[index] = 0x00U; + } + + USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_REQUEST_SENSE; + USBH_MSC_CBWData.field.CBWCB[1] = DESC_REQUEST_SENSE; + USBH_MSC_CBWData.field.CBWCB[4] = ALLOCATION_LENGTH_REQUEST_SENSE; + + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_SEND_CBW; + /* Start the transfer, then let the state machine magage + the other transactions */ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_USB_TRANSFERS; + USBH_MSC_BOTXferParam.BOTXferStatus = (uint8_t)USB_HOST_MSC_BUSY; + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_WAIT; + status = USB_HOST_MSC_BUSY; + break; + + case USB_HOST_MSC_CMD_WAIT: + switch (USBH_MSC_BOTXferParam.BOTXferStatus) { + case USB_HOST_MSC_OK: + /* Get Sense data*/ + (((uint8_t *)&USB_HOST_MSC_Param.MSC_Sense)[3]) = USB_HOST_DataInBuf[0]; + (((uint8_t *)&USB_HOST_MSC_Param.MSC_Sense)[2]) = USB_HOST_DataInBuf[1]; + (((uint8_t *)&USB_HOST_MSC_Param.MSC_Sense)[1]) = USB_HOST_DataInBuf[2]; + (((uint8_t *)&USB_HOST_MSC_Param.MSC_Sense)[0]) = USB_HOST_DataInBuf[3]; + + /* Commands successfully sent and Response Received */ + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_OK; + break; + case USB_HOST_MSC_FAIL: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_FAIL; + break; + case USB_HOST_MSC_PHASE_ERROR: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_PHASE_ERROR; + break; + default: + break; + } + break; + + default: + break; + } + } + return status; +} + +/** + * @brief issue the 'Write10 ' command to the device. Once the response received, + * it updates the status to upper layer + * @param [in] pdev device instance + * @param [in] dataBuffer data buffer contains the data to write + * @param [in] address address to which the data will be written + * @param [in] nbOfbytes NbOfbytes to be written + * @retval status define by USB_HOST_MSC_STATUS + */ +USB_HOST_MSC_STATUS usb_host_msc_Write10(usb_core_instance *pdev, + uint8_t *dataBuffer, + uint32_t address, + uint32_t nbOfbytes) +{ + uint8_t index; + USB_HOST_MSC_STATUS status = USB_HOST_MSC_BUSY; + uint16_t nbOfPages; + + if (host_driver_ifdevconnected(pdev) != 0UL) { + switch (USBH_MSC_BOTXferParam.CmdStateMachine) { + case USB_HOST_MSC_CMD_SEND: + USBH_MSC_CBWData.field.CBWTransferLength = nbOfbytes; + USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_OUT; + USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH; + USBH_MSC_BOTXferParam.pRxTxBuff = dataBuffer; + + for (index = 0U; index < CBW_CB_LENGTH; index++) { + USBH_MSC_CBWData.field.CBWCB[index] = 0x00U; + } + + USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_WRITE10; + /*logical block address*/ + USBH_MSC_CBWData.field.CBWCB[2] = (((uint8_t *)&address)[3]) ; + USBH_MSC_CBWData.field.CBWCB[3] = (((uint8_t *)&address)[2]); + USBH_MSC_CBWData.field.CBWCB[4] = (((uint8_t *)&address)[1]); + USBH_MSC_CBWData.field.CBWCB[5] = (((uint8_t *)&address)[0]); + + /*HOST_MSC_PAGE_LENGTH = 512*/ + nbOfPages = (uint16_t)(nbOfbytes / HOST_MSC_PAGE_LENGTH); + + /*Tranfer length */ + USBH_MSC_CBWData.field.CBWCB[7] = (((uint8_t *)&nbOfPages)[1]) ; + USBH_MSC_CBWData.field.CBWCB[8] = (((uint8_t *)&nbOfPages)[0]) ; + + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_SEND_CBW; + /* Start the transfer, then let the state machine + magage the other transactions */ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_USB_TRANSFERS; + USBH_MSC_BOTXferParam.BOTXferStatus = (uint8_t)USB_HOST_MSC_BUSY; + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_WAIT; + + status = USB_HOST_MSC_BUSY; + break; + + case USB_HOST_MSC_CMD_WAIT: + switch (USBH_MSC_BOTXferParam.BOTXferStatus) { + case USB_HOST_MSC_OK: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_OK; + break; + case USB_HOST_MSC_FAIL: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + break; + case USB_HOST_MSC_PHASE_ERROR: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_PHASE_ERROR; + break; + default: + break; + } + break; + + default: + break; + } + } + return status; +} + +/** + * @brief issue the read command to the device. Once the response received, + * it updates the status to upper layer + * @param [in] pdev device instance + * @param [in] dataBuffer data buffer will contain the data to be read + * @param [in] address Address from which the data will be read + * @param [in] nbOfbytes number of bytes to be read + * @retval status defined by USB_HOST_MSC_STATUS + */ +USB_HOST_MSC_STATUS usb_host_msc_Read10(usb_core_instance *pdev, + uint8_t *dataBuffer, + uint32_t address, + uint32_t nbOfbytes) +{ + uint8_t index; + static USB_HOST_MSC_STATUS status = USB_HOST_MSC_BUSY; + uint16_t nbOfPages; + status = USB_HOST_MSC_BUSY; + + if (host_driver_ifdevconnected(pdev) != 0UL) { + switch (USBH_MSC_BOTXferParam.CmdStateMachine) { + case USB_HOST_MSC_CMD_SEND: + /*Prepare the CBW and relevent field*/ + USBH_MSC_CBWData.field.CBWTransferLength = nbOfbytes; + USBH_MSC_CBWData.field.CBWFlags = USB_EP_DIR_IN; + USBH_MSC_CBWData.field.CBWLength = CBW_LENGTH; + + USBH_MSC_BOTXferParam.pRxTxBuff = dataBuffer; + + for (index = 0U; index < CBW_CB_LENGTH; index++) { + USBH_MSC_CBWData.field.CBWCB[index] = 0x00U; + } + + USBH_MSC_CBWData.field.CBWCB[0] = OPCODE_READ10; + + /*logical block address*/ + USBH_MSC_CBWData.field.CBWCB[2] = (((uint8_t *)&address)[3]); + USBH_MSC_CBWData.field.CBWCB[3] = (((uint8_t *)&address)[2]); + USBH_MSC_CBWData.field.CBWCB[4] = (((uint8_t *)&address)[1]); + USBH_MSC_CBWData.field.CBWCB[5] = (((uint8_t *)&address)[0]); + /*HOST_MSC_PAGE_LENGTH = 512*/ + nbOfPages = (uint16_t)(nbOfbytes / HOST_MSC_PAGE_LENGTH); + /*Tranfer length */ + USBH_MSC_CBWData.field.CBWCB[7] = (((uint8_t *)&nbOfPages)[1]) ; + USBH_MSC_CBWData.field.CBWCB[8] = (((uint8_t *)&nbOfPages)[0]) ; + USBH_MSC_BOTXferParam.BOTState = HOST_MSC_SEND_CBW; + /* Start the transfer, then let the state machine + magage the other transactions */ + USBH_MSC_BOTXferParam.MSCState = HOST_MSC_BOT_USB_TRANSFERS; + USBH_MSC_BOTXferParam.BOTXferStatus = (uint8_t)USB_HOST_MSC_BUSY; + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_WAIT; + status = USB_HOST_MSC_BUSY; + break; + + case USB_HOST_MSC_CMD_WAIT: + switch (USBH_MSC_BOTXferParam.BOTXferStatus) { + case USB_HOST_MSC_OK: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_OK; + break; + case USB_HOST_MSC_FAIL: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + break; + case USB_HOST_MSC_PHASE_ERROR: + USBH_MSC_BOTXferParam.CmdStateMachine = USB_HOST_MSC_CMD_SEND; + status = USB_HOST_MSC_PHASE_ERROR; + break; + default: + break; + } + break; + + default: + break; + } + } + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/****************************************************************************** + * EOF (not truncated) + *****************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_scsi.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_scsi.h new file mode 100644 index 000000000..e3336a8aa --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc/usb_host_msc_scsi.h @@ -0,0 +1,136 @@ +/** + ******************************************************************************* + * @file usb_host_msc_scsi.h + * @brief Head file for usb_host_msc_scsi.c + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ +#ifndef __USB_HOST_MSC_SCSI_H__ +#define __USB_HOST_MSC_SCSI_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_stdreq.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CLASS + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_MSC + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ + +/* USBH_MSC_SCSI_Exported_Types */ +typedef enum { + USB_HOST_MSC_OK = 0U, + USB_HOST_MSC_FAIL, + USB_HOST_MSC_PHASE_ERROR, + USB_HOST_MSC_BUSY +} USB_HOST_MSC_STATUS; + +typedef struct { + uint32_t MSC_Capacity; + uint32_t MSC_Sense; + uint16_t MSC_PageLength; + uint8_t MSC_BulkOutEP; + uint8_t MSC_BulkInEP; + uint8_t MSC_WriteProtect; +} MSC_PARAMETER; + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ +#define USB_HOST_MSC_CMD_SEND (1) +#define USB_HOST_MSC_CMD_WAIT (2) + +#define OPCODE_TEST_UNIT_READY (0x00U) +#define OPCODE_READ_CAPACITY10 (0x25U) +#define OPCODE_MODE_SENSE6 (0x1AU) +#define OPCODE_READ10 (0x28U) +#define OPCODE_WRITE10 (0x2AU) +#define OPCODE_REQUEST_SENSE (0x03U) + +#define DESC_REQUEST_SENSE (0x00U) +#define ALLOCATION_LENGTH_REQUEST_SENSE (63U) +#define XFER_LEN_READ_CAPACITY10 (8U) +#define XFER_LEN_MODE_SENSE6 (63U) + +#define MASK_MODE_SENSE_WRITE_PROTECT (0x80U) +#define MODE_SENSE_PAGE_CONTROL_FIELD (0x00U) +#define MODE_SENSE_PAGE_CODE (0x3FU) +#define DISK_WRITE_PROTECTED (0x01U) + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ +extern MSC_PARAMETER USB_HOST_MSC_Param; + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +extern USB_HOST_MSC_STATUS usb_host_msc_TestUnitReady(usb_core_instance *pdev); +extern USB_HOST_MSC_STATUS usb_host_msc_ReadCapacity10(usb_core_instance *pdev); +extern USB_HOST_MSC_STATUS usb_host_msc_ModeSense6(usb_core_instance *pdev); +extern USB_HOST_MSC_STATUS usb_host_msc_RequestSense(usb_core_instance *pdev); +extern USB_HOST_MSC_STATUS usb_host_msc_Write10(usb_core_instance *pdev, + uint8_t *dataBuffer, + uint32_t address, + uint32_t nbOfbytes); +extern USB_HOST_MSC_STATUS usb_host_msc_Read10(usb_core_instance *pdev, + uint8_t *dataBuffer, + uint32_t address, + uint32_t nbOfbytes); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_HOST_MSC_SCSI_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ + + diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/Makefile new file mode 100644 index 000000000..f7cdc020a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := usb_host_cfgch.c usb_host_core.c usb_host_ctrltrans.c usb_host_driver.c usb_host_int.c usb_host_stdreq.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_cfgch.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_cfgch.c new file mode 100644 index 000000000..90a3884fb --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_cfgch.c @@ -0,0 +1,202 @@ +/** + ******************************************************************************* + * @file usb_host_cfgch.c + * @brief Functions for opening and closing host channels + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_cfgch.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE LL USB Host Core + * @{ + */ + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ +uint16_t usb_host_getfreech(usb_core_instance *pdev); + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ + +/** + * @brief configure and open a pipe + * @param [in] pdev device instance + * @param [in] hc_num host channel index + * @param [in] dev_address USB Device address allocated to attached device + * @param [in] speed core speed + * @param [in] ep_type communication type of the EP + * @param [in] mps max size of the packet + * @retval None + */ +void usb_host_chopen(usb_core_instance *pdev, + uint8_t hc_num, + uint8_t dev_address, + uint8_t speed, + uint8_t ep_type, + uint16_t mps) +{ + pdev->host.hc[hc_num].ep_idx = (uint8_t) pdev->host.channel[hc_num] & 0x7Fu; + pdev->host.hc[hc_num].is_epin = (uint8_t)((pdev->host.channel[hc_num] & 0x80U) == 0x80U); + pdev->host.hc[hc_num].dev_addr = dev_address; + pdev->host.hc[hc_num].ep_type = ep_type; + pdev->host.hc[hc_num].max_packet = mps; + pdev->host.hc[hc_num].ch_speed = speed; + pdev->host.hc[hc_num].in_toggle = 0U; + pdev->host.hc[hc_num].out_toggle = 0U; + + (void)usb_inithch(&pdev->regs, hc_num, &pdev->host.hc[hc_num], pdev->basic_cfgs.dmaen); +} + +/** + * @brief change a pipe on host + * @param [in] pdev device instance + * @param [in] hc_num host channel index + * @param [in] dev_address USB Device address allocated to attached device + * @param [in] speed core speed + * @param [in] ep_type communication type of EP + * @param [in] mps max size of packet + * @retval None + */ +void usb_host_mdfch(usb_core_instance *pdev, + uint8_t hc_num, + uint8_t dev_address, + uint8_t speed, + uint8_t ep_type, + uint16_t mps) +{ + (void)(ep_type); + if (dev_address != 0U) { + pdev->host.hc[hc_num].dev_addr = dev_address; + } + if ((pdev->host.hc[hc_num].max_packet != mps) && (mps != 0U)) { + pdev->host.hc[hc_num].max_packet = mps; + } + if ((pdev->host.hc[hc_num].ch_speed != speed) && (speed != 0U)) { + pdev->host.hc[hc_num].ch_speed = speed; + } + + (void)usb_inithch(&pdev->regs, hc_num, &pdev->host.hc[hc_num], pdev->basic_cfgs.dmaen); +} + +/** + * @brief distribute a new channel for the pipe + * @param [in] pdev device instance + * @param [in] ep_addr EP index the channel distributed for + * @retval hc_num host channel index + */ +uint8_t usb_host_distrch(usb_core_instance *pdev, uint8_t ep_addr) +{ + __IO uint16_t hc_num; + + hc_num = usb_host_getfreech(pdev); + if (hc_num != HC_ERROR) { + pdev->host.channel[hc_num & (USB_MAX_TX_FIFOS - 1U)] = HC_USED | ep_addr; + } + return (uint8_t)hc_num; +} + +/** + * @brief free the USB host channel assigned by idx + * @param [in] pdev device instance + * @param [in] idx Channel number to be freed + * @retval Status + */ +uint8_t usb_host_freech(usb_core_instance *pdev, uint8_t idx) +{ + if (idx < MAX_CHNUM) { + pdev->host.channel[idx & (USB_MAX_TX_FIFOS - 1U)] &= HC_USED_MASK; + } + return (uint8_t)HSTATUS_OK; +} + +/** + * @brief free all the USB host channels + * @param [in] pdev device instance + * @retval None + */ +void usb_host_dedistrallch(usb_core_instance *pdev) +{ + uint8_t idx; + + for (idx = 2U; idx < MAX_CHNUM ; idx ++) { + pdev->host.channel[idx & (USB_MAX_TX_FIFOS - 1U)] = 0U; + } +} + +/** + * @brief Get a free channel number so that can be distributed to a device endpoint + * @param [in] pdev device instance + * @retval idx the free channel index + */ +uint16_t usb_host_getfreech(usb_core_instance *pdev) +{ + uint8_t tmp_idx; + uint16_t u16Ret = HC_ERROR; + + for (tmp_idx = 0U ; tmp_idx < MAX_CHNUM ; tmp_idx++) { + if ((pdev->host.channel[tmp_idx & (USB_MAX_TX_FIFOS - 1U)] & HC_USED) == 0U) { + u16Ret = HC_OK; + break; + } + } + + if (u16Ret == HC_OK) { + u16Ret = tmp_idx; + } else { + u16Ret = HC_ERROR; + } + + return u16Ret; +} + +/** + * @} + */ + +/** + * @} + */ + +/****************************************************************************** + * EOF (not truncated) + *****************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_cfgch.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_cfgch.h new file mode 100644 index 000000000..bea377cde --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_cfgch.h @@ -0,0 +1,103 @@ +/** + ******************************************************************************* + * @file usb_host_cfgch.h + * @brief header file for the usb_host_cfgch.c + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ +#ifndef __USB_HOST_CFGCH_H__ +#define __USB_HOST_CFGCH_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_def.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/* USBH_HCS_Exported_Defines */ +#define MAX_CHNUM (12U) + +#define HC_OK (0x0000U) +#define HC_USED (0x8000U) +#define HC_ERROR (0xFFFFU) +#define HC_USED_MASK (0x7FFFU) + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +extern uint8_t usb_host_distrch(usb_core_instance *pdev, uint8_t ep_addr); + +extern uint8_t usb_host_freech(usb_core_instance *pdev, uint8_t idx); + +extern void usb_host_dedistrallch(usb_core_instance *pdev); + +extern void usb_host_chopen(usb_core_instance *pdev, + uint8_t hc_num, + uint8_t dev_address, + uint8_t speed, + uint8_t ep_type, + uint16_t mps); + +extern void usb_host_mdfch(usb_core_instance *pdev, + uint8_t hc_num, + uint8_t dev_address, + uint8_t speed, + uint8_t ep_type, + uint16_t mps); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_HOST_CFGCH_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_core.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_core.c new file mode 100644 index 000000000..97ffb8d8b --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_core.c @@ -0,0 +1,539 @@ +/** + ******************************************************************************* + * @file usb_host_core.c + * @brief The core state machine process the enumeration and the control transfer process + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include +#include "usb_host_core.h" +#include "usb_host_cfgch.h" +#include "usb_host_ctrltrans.h" +#include "usb_host_driver.h" +#include "usb_host_stdreq.h" +#include "usb_host_int.h" +#include "usb_bsp.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ +HOST_STATUS usb_host_ctrlprocess(usb_core_instance *pdev, USBH_HOST *phost); +HOST_STATUS usb_host_enumprocess(usb_core_instance *pdev, USBH_HOST *phost); + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ +static uint8_t Local_Buffer[ENUM_LOCAL_BUF]; + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ + +/** + * @brief initialization for the host application + * @param [in] pdev device instance + * @param [in] phost host state set + * @param [in] class_cbk the call back function for the class application + * @param [in] user_cbk the call back function for user + * @retval None + */ +void usb_host_init(usb_core_instance *pdev, + USBH_HOST *phost, + usb_host_class_callback_func *class_cbk, + usb_host_user_callback_func *user_cbk) +{ + usb_bsp_init(pdev); + usb_host_deinit(pdev, phost); + phost->class_callbk = class_cbk; + phost->user_callbk = user_cbk; + host_driver_init(pdev); + phost->user_callbk->huser_init(); + usb_bsp_nvicconfig(); +} + +/** + * @brief deinitialize the host application + * @param [in] pdev device instance + * @param [in] phost host state set + * @retval None + */ +void usb_host_deinit(usb_core_instance *pdev, USBH_HOST *phost) +{ + phost->host_state = HOST_IDLE; + phost->host_state_backup = HOST_IDLE; + phost->enum_state = ENUM_IDLE; + phost->req_state = REQ_CMD_TX; + + phost->ctrlparam.ctrl_state = CTRL_SETUP; + phost->ctrlparam.ctrlmaxsize = USB_MAX_EP0_SIZE; + + phost->device_prop.devaddr = DEV_DEFAULT_ADDRESS; + phost->device_prop.devspeed = PRTSPD_FULL_SPEED; + + (void)usb_host_freech(pdev, phost->ctrlparam.hc_num_in); + (void)usb_host_freech(pdev, phost->ctrlparam.hc_num_out); +} + +/** + * @brief This is the main process function for the host core, it will process + * the main machine, such as connect,disconnect, emunation etc. + * @param [in] pdev device instance + * @param [in] phost host state set + * @retval None + */ +int usb_host_mainprocess(usb_core_instance *pdev, USBH_HOST *phost) +{ + __IO HOST_STATUS tmp_status; + tmp_status = HSTATUS_FAIL; + HOST_HANDLE_STATE tmp_host_state; + + if ((host_driver_ifdevconnected(pdev) == 0UL) && (phost->host_state != HOST_IDLE)) { + if (phost->host_state != HOST_DEV_DISCONNECTED) { + phost->host_state = HOST_DEV_DISCONNECTED; + } + } + + if ((host_driver_ifdevconnected(pdev) == 0UL) && (phost->host_state == HOST_IDLE) + && (host_driver_getvbusdrivestate(pdev) == 0UL)) { + phost->host_state = HOST_DEV_DISCONNECTED; + } + + tmp_host_state = phost->host_state; + if (tmp_host_state == HOST_IDLE) { + if (0U != host_driver_ifdevconnected(pdev)) { + phost->host_state = HOST_DEV_CONNECTED; + usb_mdelay(50UL); + } + } else if (tmp_host_state == HOST_DEV_CONNECTED) { +#ifdef MSC_HID_COMPOSITE + if (host_driver_getcurrentspd(pdev) == 2) { + host_driver_init(pdev); + } +#endif /* MSC_HID_COMPOSITE */ + phost->user_callbk->huser_devattached(); + phost->ctrlparam.hc_num_out = usb_host_distrch(pdev, 0x00U); + phost->ctrlparam.hc_num_in = usb_host_distrch(pdev, 0x80U); + host_driver_portrst(pdev); + phost->user_callbk->huser_devreset(); + phost->device_prop.devspeed = (uint8_t)host_driver_getcurrentspd(pdev); + phost->host_state = HOST_ENUM; + phost->user_callbk->huser_devspddetected(phost->device_prop.devspeed); + usb_host_chopen(pdev, + phost->ctrlparam.hc_num_in, + phost->device_prop.devaddr, + phost->device_prop.devspeed, + EP_TYPE_CTRL, + (uint16_t)phost->ctrlparam.ctrlmaxsize); + usb_host_chopen(pdev, + phost->ctrlparam.hc_num_out, + phost->device_prop.devaddr, + phost->device_prop.devspeed, + EP_TYPE_CTRL, + (uint16_t)phost->ctrlparam.ctrlmaxsize); + } else if (tmp_host_state == HOST_ENUM) { + if (usb_host_enumprocess(pdev, phost) == HSTATUS_OK) { + phost->user_callbk->huser_enumcompl(); + phost->host_state = HOST_USER_INPUT; + } + } else if (tmp_host_state == HOST_USER_INPUT) { + if ((phost->class_callbk->host_class_init(pdev, phost)) == HSTATUS_OK) { + phost->host_state = HOST_CLASS_REQ; + } + } else if (tmp_host_state == HOST_CLASS_REQ) { + tmp_status = phost->class_callbk->host_class_request(pdev, phost); + if (tmp_status == HSTATUS_OK) { + phost->host_state = HOST_CLASS_PROCESS; + } else { + usb_host_errorprocess(phost, tmp_status); + } + } else if (tmp_host_state == HOST_CLASS_PROCESS) { + tmp_status = phost->class_callbk->host_class_process(pdev, phost); + usb_host_errorprocess(phost, tmp_status); + } else if (tmp_host_state == HOST_CTRL_TRANSMIT) { + (void)usb_host_ctrlprocess(pdev, phost); + } else if (tmp_host_state == HOST_ERROR_STATE) { + usb_host_deinit(pdev, phost); + phost->user_callbk->huser_deinit(); + phost->class_callbk->host_class_deinit(pdev); + } else if (tmp_host_state == HOST_DEV_DISCONNECTED) { + phost->user_callbk->huser_devdisconn(); + usb_host_deinit(pdev, phost); + phost->user_callbk->huser_deinit(); + phost->class_callbk->host_class_deinit(pdev); + usb_host_dedistrallch(pdev); + phost->host_state = HOST_IDLE; + + host_driver_init(pdev); + } else { + ; + } + + return 0; +} + +/** + * @brief process the status when related error status happens. + * @param [in] phost host state set + * @param [in] errType host status + * @retval None + */ +void usb_host_errorprocess(USBH_HOST *phost, HOST_STATUS errType) +{ + switch (errType) { + case HSTATUS_APP_DEINIT: + phost->host_state = HOST_ERROR_STATE; + phost->user_callbk->huser_init(); + break; + case HSTATUS_SPEED_UNKNOWN: + case HSTATUS_UNRECOVERED_ERROR: + phost->user_callbk->huser_unrecoverederror(); + phost->host_state = HOST_ERROR_STATE; + break; + default: + break; + } +} + +/** + * @brief this function process all the emunation steps. + * @param [in] pdev device instance + * @param [in] phost host state set + * @retval status + */ +HOST_STATUS usb_host_enumprocess(usb_core_instance *pdev, USBH_HOST *phost) +{ + HOST_STATUS tmp_status; + + ENUM_HANDLE_STATE tmp_enum_state; + tmp_status = HSTATUS_BUSY; + tmp_enum_state = phost->enum_state; + if (tmp_enum_state == ENUM_IDLE) { + if (usb_host_getdevdesc(pdev, phost, 8U) == HSTATUS_OK) { + phost->ctrlparam.ctrlmaxsize = phost->device_prop.devdesc.bMaxPacketSize0; + host_driver_portrst(pdev); + phost->enum_state = ENUM_GET_FULL_DEVDESC; + usb_host_mdfch(pdev, + phost->ctrlparam.hc_num_out, + 0U, + 0U, + 0U, + (uint16_t)phost->ctrlparam.ctrlmaxsize); + usb_host_mdfch(pdev, + phost->ctrlparam.hc_num_in, + 0U, + 0U, + 0U, + (uint16_t)phost->ctrlparam.ctrlmaxsize); + } + } + if (tmp_enum_state == ENUM_GET_FULL_DEVDESC) { + if (usb_host_getdevdesc(pdev, phost, USB_DEVICE_DESC_SIZE) == HSTATUS_OK) { + phost->user_callbk->huser_devdescavailable(&phost->device_prop.devdesc); + phost->enum_state = ENUM_SET_DEVADDR; + } + } + if (tmp_enum_state == ENUM_SET_DEVADDR) { + if (usb_host_setdevaddr(pdev, phost, DEV_ASSIGNED_ADDRESS) == HSTATUS_OK) { + usb_mdelay(2UL); + phost->device_prop.devaddr = DEV_ASSIGNED_ADDRESS; + phost->user_callbk->huser_devaddrdistributed(); + phost->enum_state = ENUM_GET_CFGDESC; + usb_host_mdfch(pdev, + phost->ctrlparam.hc_num_in, + phost->device_prop.devaddr, + 0U, + 0U, + 0U); + + usb_host_mdfch(pdev, + phost->ctrlparam.hc_num_out, + phost->device_prop.devaddr, + 0U, + 0U, + 0U); + } + } + if (tmp_enum_state == ENUM_GET_CFGDESC) { + if (usb_host_getcfgdesc(pdev, phost, USB_CONFIGURATION_DESC_SIZE) == HSTATUS_OK) { + phost->enum_state = ENUM_GET_FULL_CFGDESC; + } + } + if (tmp_enum_state == ENUM_GET_FULL_CFGDESC) { + if (usb_host_getcfgdesc(pdev, phost, phost->device_prop.devcfgdesc.wTotalLength) == HSTATUS_OK) { + phost->user_callbk->huser_cfgdescavailable(&phost->device_prop.devcfgdesc, + phost->device_prop.devitfdesc, + phost->device_prop.devepdesc[0]); + phost->enum_state = ENUM_GET_MFCSTRINGDESC; + } + } + if (tmp_enum_state == ENUM_GET_MFCSTRINGDESC) { + if (phost->device_prop.devdesc.iManufacturer != (uint8_t)0) { + if (usb_host_getstringdesc(pdev, + phost, + phost->device_prop.devdesc.iManufacturer, + Local_Buffer, + 0xffu) == HSTATUS_OK) { + phost->user_callbk->huser_mfcstring(Local_Buffer); + phost->enum_state = ENUM_GET_PRODUCT_STRINGDESC; + } + } else { + phost->user_callbk->huser_mfcstring("N/A"); + phost->enum_state = ENUM_GET_PRODUCT_STRINGDESC; + } + } + if (tmp_enum_state == ENUM_GET_PRODUCT_STRINGDESC) { + if (phost->device_prop.devdesc.iProduct != (uint8_t)0) { + if (usb_host_getstringdesc(pdev, + phost, + phost->device_prop.devdesc.iProduct, + Local_Buffer, + 0xffu) == HSTATUS_OK) { + phost->user_callbk->huser_productstring(Local_Buffer); + phost->enum_state = ENUM_GET_SERIALNUM_STRINGDESC; + } + } else { + phost->user_callbk->huser_productstring("N/A"); + phost->enum_state = ENUM_GET_SERIALNUM_STRINGDESC; + } + } + if (tmp_enum_state == ENUM_GET_SERIALNUM_STRINGDESC) { + if (phost->device_prop.devdesc.iSerialNumber != (uint8_t)0) { + if (usb_host_getstringdesc(pdev, + phost, + phost->device_prop.devdesc.iSerialNumber, + Local_Buffer, + 0xffu) == HSTATUS_OK) { + phost->user_callbk->huser_serialnum(Local_Buffer); + phost->enum_state = ENUM_SET_CFG; + } + } else { + phost->user_callbk->huser_serialnum("N/A"); + phost->enum_state = ENUM_SET_CFG; + } + } + if (tmp_enum_state == ENUM_SET_CFG) { + if (usb_host_setconfig(pdev, phost, + (uint16_t)phost->device_prop.devcfgdesc.bConfigurationValue) == HSTATUS_OK) { + phost->enum_state = ENUM_DEV_CFG_OVER; + } + } + if (tmp_enum_state == ENUM_DEV_CFG_OVER) { + tmp_status = HSTATUS_OK; + } else { + ; + } + return tmp_status; +} + + +/** + * @brief process the state machine of control transfer + * @param [in] pdev device instance + * @param [in] phost host state set + * @retval status + */ +HOST_STATUS usb_host_ctrlprocess(usb_core_instance *pdev, USBH_HOST *phost) +{ + uint8_t direction; + CTRL_HANDLE_STATE tmp_ctrl_state; + static uint16_t timeout = 0; + HOST_STATUS status = HSTATUS_OK; + HOST_CH_XFER_STATE URB_Status; + + phost->ctrlparam.ctrl_status = CTRL_START; + tmp_ctrl_state = phost->ctrlparam.ctrl_state; + + if (tmp_ctrl_state == CTRL_SETUP) { + /* transmit a setup packet to the device */ + usb_host_sendctrlsetup(pdev, phost->ctrlparam.setup.d8, phost->ctrlparam.hc_num_out); + phost->ctrlparam.ctrl_state = CTRL_SETUP_WAIT; + timeout = DATA_STAGE_TIMEOUT * 6U; + phost->ctrlparam.sof_num = (uint16_t)host_driver_getcurrentfrm(pdev); + } else if (tmp_ctrl_state == CTRL_SETUP_WAIT) { + URB_Status = host_driver_getxferstate(pdev, phost->ctrlparam.hc_num_out); + /* case SETUP packet sent successfully */ + if (URB_Status == HOST_CH_XFER_DONE) { + /* parse the direction of the request from the setup just sent */ + direction = (phost->ctrlparam.setup.b.bmRequestType & USB_REQ_DIR_MASK); + /* judge if there is a data stage, if wLength is not zero, there may be a in or out + data stage */ + if (phost->ctrlparam.setup.b.wLength.w != 0U) { + timeout = DATA_STAGE_TIMEOUT; + if (direction == USB_D2H) { + /* Data Direction is IN, device should send data in */ + phost->ctrlparam.ctrl_state = CTRL_DATA_IN; + } else { + /* Data Direction is OUT, host will send data out for device */ + phost->ctrlparam.ctrl_state = CTRL_DATA_OUT; + } + } + /* No DATA stage */ + else { + timeout = NODATA_STAGE_TIMEOUT; + /* If there is No Data Transfer Stage */ + if (direction == USB_D2H) { + /* Data Direction is IN */ + phost->ctrlparam.ctrl_state = CTRL_STATUS_OUT; + } else { + /* Data Direction is OUT */ + phost->ctrlparam.ctrl_state = CTRL_STATUS_IN; + } + } + /* Set the delay timer to enable timeout for data stage completion */ + phost->ctrlparam.sof_num = (uint16_t)host_driver_getcurrentfrm(pdev); + } else if (URB_Status == HOST_CH_XFER_ERROR) { + phost->ctrlparam.ctrl_state = CTRL_ERROR; + phost->ctrlparam.ctrl_status = CTRL_XACTERR; + } else if ((host_driver_getcurrentfrm(pdev) - phost->ctrlparam.sof_num) > timeout) { +#if (LL_PRINT_ENABLE == DDL_ON) + DDL_Printf("Device not responding\r\n"); +#endif + } else { + ; + } + } else if (tmp_ctrl_state == CTRL_DATA_IN) { + /* Issue an IN token */ + usb_host_recvctrldata(pdev, phost->ctrlparam.buff, phost->ctrlparam.length, phost->ctrlparam.hc_num_in); + phost->ctrlparam.ctrl_state = CTRL_DATA_IN_WAIT; + } else if (tmp_ctrl_state == CTRL_DATA_IN_WAIT) { + URB_Status = host_driver_getxferstate(pdev, phost->ctrlparam.hc_num_in); + /* check is DATA packet transfered successfully */ + if (URB_Status == HOST_CH_XFER_DONE) { + phost->ctrlparam.ctrl_state = CTRL_STATUS_OUT; + } + /* manage error cases*/ + if (URB_Status == HOST_CH_XFER_STALL) { + /* In stall case, return to previous machine state*/ + phost->host_state = phost->host_state_backup; + } else if (URB_Status == HOST_CH_XFER_ERROR) { + /* Device error */ + phost->ctrlparam.ctrl_state = CTRL_ERROR; + } else if ((host_driver_getcurrentfrm(pdev) - phost->ctrlparam.sof_num) > timeout) { + /* timeout for IN transfer */ + phost->ctrlparam.ctrl_state = CTRL_ERROR; + } else { + ; + } + } else if (tmp_ctrl_state == CTRL_DATA_OUT) { + /* Start DATA out transfer (only one DATA packet)*/ + pdev->host.hc[phost->ctrlparam.hc_num_out].out_toggle = 1; + + usb_host_sendctrldata(pdev, + phost->ctrlparam.buff, + phost->ctrlparam.length, + phost->ctrlparam.hc_num_out); + phost->ctrlparam.ctrl_state = CTRL_DATA_OUT_WAIT; + } else if (tmp_ctrl_state == CTRL_DATA_OUT_WAIT) { + URB_Status = host_driver_getxferstate(pdev, phost->ctrlparam.hc_num_out); + switch (URB_Status) { + case HOST_CH_XFER_DONE: + phost->ctrlparam.ctrl_state = CTRL_STATUS_IN; + break; + case HOST_CH_XFER_STALL: + phost->host_state = phost->host_state_backup; + phost->ctrlparam.ctrl_state = CTRL_STALLED; + break; + case HOST_CH_XFER_UNREADY: + phost->ctrlparam.ctrl_state = CTRL_DATA_OUT; + break; + case HOST_CH_XFER_ERROR: + phost->ctrlparam.ctrl_state = CTRL_ERROR; + break; + default: + break; + } + } else if (tmp_ctrl_state == CTRL_STATUS_IN) { + /* receive a packet with 0 byte */ + usb_host_recvctrldata(pdev, NULL, 0U, phost->ctrlparam.hc_num_in); + phost->ctrlparam.ctrl_state = CTRL_STATUS_IN_WAIT; + } else if (tmp_ctrl_state == CTRL_STATUS_IN_WAIT) { + URB_Status = host_driver_getxferstate(pdev, phost->ctrlparam.hc_num_in); + if (URB_Status == HOST_CH_XFER_DONE) { + /* Control transfers completed, Exit the State Machine */ + phost->host_state = phost->host_state_backup; + phost->ctrlparam.ctrl_state = CTRL_COMPLETE; + } else if (URB_Status == HOST_CH_XFER_ERROR) { + phost->ctrlparam.ctrl_state = CTRL_ERROR; + } else if ((host_driver_getcurrentfrm(pdev) - phost->ctrlparam.sof_num) > timeout) { + phost->ctrlparam.ctrl_state = CTRL_ERROR; + } else if (URB_Status == HOST_CH_XFER_STALL) { + /* Control transfers completed, Exit the State Machine */ + phost->host_state = phost->host_state_backup; + phost->ctrlparam.ctrl_status = CTRL_STALL; + status = HSTATUS_UNSUPPORTED; + } else { + ; + } + } else if (tmp_ctrl_state == CTRL_STATUS_OUT) { + pdev->host.hc[phost->ctrlparam.hc_num_out].out_toggle ^= 1U; + usb_host_sendctrldata(pdev, NULL, 0U, phost->ctrlparam.hc_num_out); + phost->ctrlparam.ctrl_state = CTRL_STATUS_OUT_WAIT; + } else if (tmp_ctrl_state == CTRL_STATUS_OUT_WAIT) { + URB_Status = host_driver_getxferstate(pdev, phost->ctrlparam.hc_num_out); + switch (URB_Status) { + case HOST_CH_XFER_DONE: + phost->host_state = phost->host_state_backup; + phost->ctrlparam.ctrl_state = CTRL_COMPLETE; + break; + case HOST_CH_XFER_UNREADY: + phost->ctrlparam.ctrl_state = CTRL_STATUS_OUT; + break; + case HOST_CH_XFER_ERROR: + phost->ctrlparam.ctrl_state = CTRL_ERROR; + break; + default: + break; + } + } else if (tmp_ctrl_state == CTRL_ERROR) { + if (++ phost->ctrlparam.err_cnt <= HOST_MAX_ERROR_CNT) { + /* re-start the transmission, starting from SETUP packet */ + phost->ctrlparam.ctrl_state = CTRL_SETUP; + } else { + phost->ctrlparam.ctrl_status = CTRL_FAIL; + phost->host_state = phost->host_state_backup; + + status = HSTATUS_FAIL; + } + } else { + ; + } + return status; +} + +/** + * @} + */ + +/** + * @} + */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_core.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_core.h new file mode 100644 index 000000000..788f7090d --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_core.h @@ -0,0 +1,95 @@ +/** + ******************************************************************************* + * @file usb_host_core.h + * @brief header file for the usb_host_core.c + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ +#ifndef __USB_HOST_CORE_H__ +#define __USB_HOST_CORE_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_def.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ +/* USBH_CORE_Exported_Defines */ +#define MSC_CLASS (0x08U) +#define HID_CLASS (0x03U) +#define MSC_PROTOCOL (0x50U) +#define CBI_PROTOCOL (0x01U) + +#define DEV_DEFAULT_ADDRESS (0U) +#define DEV_ASSIGNED_ADDRESS (1U) + +#define HOST_MAX_ERROR_CNT (2U) + +#define ENUM_LOCAL_BUF (256U) + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +extern void usb_host_init(usb_core_instance *pdev, + USBH_HOST *phost, + usb_host_class_callback_func *class_cbk, + usb_host_user_callback_func *user_cbk); +extern void usb_host_deinit(usb_core_instance *pdev, USBH_HOST *phost); +extern int usb_host_mainprocess(usb_core_instance *pdev, USBH_HOST *phost); +extern void usb_host_errorprocess(USBH_HOST *phost, HOST_STATUS errType); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_HOST_CORE_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_ctrltrans.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_ctrltrans.c new file mode 100644 index 000000000..db3379775 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_ctrltrans.c @@ -0,0 +1,320 @@ +/** + ******************************************************************************* + * @file usb_host_ctrltrans.c + * @brief This file handles the issuing of the USB transactions + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_ctrltrans.h" +#include "usb_host_driver.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ +void usb_host_submitsetupreq(USBH_HOST *phost, uint8_t *buff, uint16_t length); + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ +/** + * @brief Start a setup transfer by changing the state-machine and + * initializing the required variables needed for the Control Transfer + * @param [in] phost host state set + * @param [in] buff data buffer used for setup request + * @param [in] length data length in byte + * @retval status + */ +void usb_host_submitsetupreq(USBH_HOST *phost, uint8_t *buff, uint16_t length) +{ + /* Save Global State */ + phost->host_state_backup = phost->host_state; + /* Prepare the Transactions */ + phost->host_state = HOST_CTRL_TRANSMIT; + phost->ctrlparam.buff = buff; + phost->ctrlparam.length = length; + phost->ctrlparam.ctrl_state = CTRL_SETUP; +} + +/** + * @brief send a control request and update the status after the request sent. + * @param [in] pdev device instance + * @param [in] phost host state set + * @param [in] buff data buffer whose data will be sent in the control pipe. + * @param [in] length length of the data sent. + * @retval status + */ +HOST_STATUS usb_host_ctrlreq(usb_core_instance *pdev, + USBH_HOST *phost, + uint8_t *buff, + uint16_t length) +{ + HOST_STATUS status; + REQ_HANDLE_STATE tmp_req_state; + (void)(pdev); + status = HSTATUS_BUSY; + tmp_req_state = phost->req_state; + if (tmp_req_state == REQ_CMD_TX) { + /* prepare a setup packet for transferring */ + usb_host_submitsetupreq(phost, buff, length); + /* update the request state */ + phost->req_state = REQ_CMD_WAIT; + /* The status would be returned in this function */ + status = HSTATUS_BUSY; + } else if (tmp_req_state == REQ_CMD_WAIT) { + switch (phost->ctrlparam.ctrl_state) { + case CTRL_COMPLETE: + /* Commands have been successfully sent and Responses have been Received */ + phost->req_state = REQ_CMD_TX; + /* update the control state */ + phost->ctrlparam.ctrl_state = CTRL_IDLE; + status = HSTATUS_OK; + break; + case CTRL_ERROR: + /* fail transfer */ + phost->req_state = REQ_CMD_TX; + status = HSTATUS_FAIL; + break; + case CTRL_STALLED: + /* Commands have been successfully sent and Responses have been Received */ + phost->req_state = REQ_CMD_TX; + status = HSTATUS_UNSUPPORTED; + break; + default: + break; + } + } else { + ; + } + return status; +} + +/** + * @brief sends a setup packet to the control EP of the USB device + * @param [in] pdev device instance + * @param [in] buff data buffer whose data will be sent in the control pipe to the control EP of the device. + * @param [in] hc_num host channel index + * @retval None + */ +void usb_host_sendctrlsetup(usb_core_instance *pdev, uint8_t *buff, uint8_t hc_num) +{ + pdev->host.hc[hc_num].is_epin = 0U; + pdev->host.hc[hc_num].pid_type = PID_SETUP; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = 8; + (void)host_driver_submitrequest(pdev, hc_num); +} + +/** + * @brief sends a data packet to the USB device + * @param [in] pdev device instance + * @param [in] buff data buffer whose data will be sent to the USB device + * @param [in] length the data length in byte that would be sent + * @param [in] hc_num host channel index + * @retval None + */ +void usb_host_sendctrldata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num) +{ + pdev->host.hc[hc_num].is_epin = 0; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = length; + if (length == 0U) { + /* For Status OUT stage, Length==0, Status Out PID = 1 always */ + pdev->host.hc[hc_num].out_toggle = 1; + } + /* Set the Data Toggle bit */ + if (pdev->host.hc[hc_num].out_toggle == 0U) { + pdev->host.hc[hc_num].pid_type = PID_DATA0; + } else { + pdev->host.hc[hc_num].pid_type = PID_DATA1 ; + } + (void)host_driver_submitrequest(pdev, hc_num); +} + +/** + * @brief Receives the response data to the setup packet + * @param [in] pdev device instance + * @param [in] buff data buffer when received data. + * @param [in] length the length data in byte have received. + * @param [in] hc_num host channel index + * @retval None + */ +void usb_host_recvctrldata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num) +{ + pdev->host.hc[hc_num].is_epin = (uint8_t)1; + pdev->host.hc[hc_num].pid_type = PID_DATA1; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = length; + + (void)host_driver_submitrequest(pdev, hc_num); +} + +/** + * @brief sent the bulk packet to the device + * @param [in] pdev device instance + * @param [in] buff data buffer whose data will be sent + * @param [in] length data length in byte + * @param [in] hc_num host channel index + * @retval None + */ +void usb_host_sendbulkdata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num) +{ + pdev->host.hc[hc_num].is_epin = 0; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = length; + /* Set the Data Toggle bit */ + if (pdev->host.hc[hc_num].out_toggle == 0U) { + pdev->host.hc[hc_num].pid_type = PID_DATA0; + } else { + pdev->host.hc[hc_num].pid_type = PID_DATA1 ; + } + + (void)host_driver_submitrequest(pdev, hc_num); +} + +/** + * @brief receives bulk packet from device + * @param [in] pdev device instance + * @param [in] buff buffer to save the data received from the device + * @param [in] length data length in byte + * @param [in] hc_num host channel index + * @retval status + */ +void usb_host_recvbulkdata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num) +{ + pdev->host.hc[hc_num].is_epin = (uint8_t)1; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = length; + + + if (pdev->host.hc[hc_num].in_toggle == (uint8_t)0) { + pdev->host.hc[hc_num].pid_type = PID_DATA0; + } else { + pdev->host.hc[hc_num].pid_type = PID_DATA1; + } + + (void)host_driver_submitrequest(pdev, hc_num); +} + +/** + * @brief receives the device response to the Interrupt IN token + * @param [in] pdev device instance + * @param [in] buff buffer to save the data received from the device + * @param [in] length data length in byte + * @param [in] hc_num host channel index + * @retval None + */ +void usb_host_recvintdata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num) +{ + pdev->host.hc[hc_num].is_epin = (uint8_t)1; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = length; + if (pdev->host.hc[hc_num].in_toggle == (uint8_t)0) { + pdev->host.hc[hc_num].pid_type = PID_DATA0; + } else { + pdev->host.hc[hc_num].pid_type = PID_DATA1; + } + /* toggle the DATA PID */ + pdev->host.hc[hc_num].in_toggle ^= (uint8_t)1; + (void)host_driver_submitrequest(pdev, hc_num); +} + +/** + * @brief send the data on Interrupt OUT Endpoint + * @param [in] pdev device instance + * @param [in] buff data buffer whose data will be sent + * @param [in] length data length in byte + * @param [in] hc_num host channel index + * @retval None + */ +void usb_host_sentintdata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num) +{ + pdev->host.hc[hc_num].is_epin = (uint8_t)0; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = length; + + if (pdev->host.hc[hc_num].in_toggle == (uint8_t)0) { + pdev->host.hc[hc_num].pid_type = PID_DATA0; + } else { + pdev->host.hc[hc_num].pid_type = PID_DATA1; + } + + pdev->host.hc[hc_num].in_toggle ^= (uint8_t)1; + (void)host_driver_submitrequest(pdev, hc_num); +} + +/** + * @brief receives the Device Response to the Isochronous IN token + * @param [in] pdev device instance + * @param [in] buff buffer to save the data received from the device + * @param [in] length data length in byte + * @param [in] hc_num host channel index + * @retval None + */ +void usb_host_recvisocdata(usb_core_instance *pdev, uint8_t *buff, uint32_t length, uint8_t hc_num) +{ + pdev->host.hc[hc_num].is_epin = (uint8_t)1; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = length; + pdev->host.hc[hc_num].pid_type = PID_DATA0; + + (void)host_driver_submitrequest(pdev, hc_num); +} + +/** + * @brief Sends the data through Isochronous OUT Endpoint + * @param [in] pdev device instance + * @param [in] buff data buffer whose data will be sent + * @param [in] length data length in byte + * @param [in] hc_num host channel index + * @retval None + */ +void usb_host_sendisocdata(usb_core_instance *pdev, uint8_t *buff, uint32_t length, uint8_t hc_num) +{ + pdev->host.hc[hc_num].is_epin = (uint8_t)0; + pdev->host.hc[hc_num].xfer_buff = buff; + pdev->host.hc[hc_num].xfer_len = length; + pdev->host.hc[hc_num].pid_type = PID_DATA0; + (void)host_driver_submitrequest(pdev, hc_num); +} + +/** + * @} + */ + +/** + * @} + */ + +/****************************************************************************** + * EOF (not truncated) + *****************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_ctrltrans.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_ctrltrans.h new file mode 100644 index 000000000..98e461caf --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_ctrltrans.h @@ -0,0 +1,86 @@ +/** + ******************************************************************************* + * @file usb_host_ctrltrans.h + * @brief header file for the usb_host_ctrltrans.c + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ +#ifndef __USB_HOST_CTRLTRANS_H__ +#define __USB_HOST_CTRLTRANS_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_def.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +extern void usb_host_sendctrlsetup(usb_core_instance *pdev, uint8_t *buff, uint8_t hc_num); +extern void usb_host_sendctrldata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num); +extern void usb_host_recvctrldata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num); +extern void usb_host_recvbulkdata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num); +extern void usb_host_sendbulkdata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num); +extern void usb_host_recvintdata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num); +extern void usb_host_sentintdata(usb_core_instance *pdev, uint8_t *buff, uint16_t length, uint8_t hc_num); +extern HOST_STATUS usb_host_ctrlreq(usb_core_instance *pdev, USBH_HOST *phost, uint8_t *buff, uint16_t length); +extern void usb_host_recvisocdata(usb_core_instance *pdev, uint8_t *buff, uint32_t length, uint8_t hc_num); +extern void usb_host_sendisocdata(usb_core_instance *pdev, uint8_t *buff, uint32_t length, uint8_t hc_num); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_HOST_CTRLTRANS_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_def.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_def.h new file mode 100644 index 000000000..df7549071 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_def.h @@ -0,0 +1,430 @@ +/** + ******************************************************************************* + * @file usb_host_def.h + * @brief Definitions used in the USB host library + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ +#ifndef __USB_HOST_DEF_H__ +#define __USB_HOST_DEF_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include +#include "usb_app_conf.h" +#include "usb_lib.h" +#include "hc32_ll.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ +/* This Union is copied from usb_core.h */ +typedef union { + uint16_t w; + struct BW { + uint8_t msb; + uint8_t lsb; + } + bw; +} uint16_t_uint8_t; +/* standard setup packet defination */ +typedef union { + uint8_t d8[8]; + struct _SetupPkt_Struc { + uint8_t bmRequestType; + uint8_t bRequest; + uint16_t_uint8_t wValue; + uint16_t_uint8_t wIndex; + uint16_t_uint8_t wLength; + } b; +} usb_setup_typedef; + +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; +} USB_HOST_DescHeader_TypeDef; + +/* Standard Device Descriptor */ +typedef struct { + uint8_t bLength; /* Size of this descriptor in bytes */ + uint8_t bDescriptorType; /* Device descriptor type */ + uint16_t bcdUSB; /* USB Specification Release Numbrer in Binary-Coded Decimal(i.e.,2.10 is 210H) */ + uint8_t bDeviceClass; /* Class code(assigned by the USB-IF) */ + uint8_t bDeviceSubClass; /* Subclass code(assigned by the USB-IF) this code is qualified by the value of the \ + bDeviceClass field. */ + uint8_t bDeviceProtocol; /* Protocol code(assigned by the USB-IF), this code is qualified by the value of the \ + bDeviceClass and the bDeviceSubClass fields. */ + uint8_t bMaxPacketSize0; /* Maximum packet size for EP0 */ + uint16_t idVendor; /* Vendor ID (assigned by the USB-IF) */ + uint16_t idProduct; /* Product ID (assigned by manufacturer) */ + uint16_t bcdDevice; /* Device Release Number in binary-coded decimal */ + uint8_t iManufacturer; /* Index of string descriptor describing manufacturer */ + uint8_t iProduct; /* Index of string descriptor describing product */ + uint8_t iSerialNumber; /* Index of string descriptor describing the device's serial number */ + uint8_t bNumConfigurations; /* Number of possible configurations */ +} usb_host_devdesc_typedef; + +/* Standard Configuration Descriptor */ +typedef struct { + uint8_t bLength; /* Size of this descriptor in bytes */ + uint8_t bDescriptorType; /* CONFIGURATION descriptor type */ + uint16_t wTotalLength; /* Total length of data returned for this configuration */ + uint8_t bNumInterfaces; /* Number of interfaces supported by this configuration */ + uint8_t bConfigurationValue; /* Value to use as an argument to the SetConfiguration() request to select this configuration */ + uint8_t iConfiguration; /* Index of string descriptor describing this configuration */ + uint8_t bmAttributes; /* Configuration characteristics: D7:Reserved(set to one) D6:Self-powered D5:Remote Wakeup D4..0 Reserved(set to zero) */ + uint8_t bMaxPower; /* Maximum power consumption of the device from the bus in this specific configuration when the device is fully operational */ +} usb_host_cfgdesc_typedef; + +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdHID; /* indicates what endpoint this descriptor is describing */ + uint8_t bCountryCode; /* specifies the transfer type. */ + uint8_t bNumDescriptors; /* specifies the transfer type. */ + uint8_t bReportDescriptorType; /* Maximum Packet Size this endpoint is capable of sending or receiving */ + uint16_t wItemLength; /* is used to specify the polling interval of certain transfers. */ +} USB_HOST_HIDDesc_TypeDef; + +/* Standard Interface Descriptor */ +typedef struct { + uint8_t bLength; /* Size of this descriptor in bytes */ + uint8_t bDescriptorType; /* INTERFACE Descriptor Type */ + uint8_t bInterfaceNumber; /* Number of this interface */ + uint8_t bAlternateSetting; /* Value used to select this alternate setting for the interface identifiled in the \ + prior field */ + uint8_t bNumEndpoints; /* Number of Endpoints used by this interface */ + uint8_t bInterfaceClass; /* Class code (assigned by the USB-IF) */ + uint8_t bInterfaceSubClass; /* Subclass code (assigned by the USB-IF) */ + uint8_t bInterfaceProtocol; /* Protocol code (assigned by the USB) */ + uint8_t iInterface; /* Index of string descriptor describing this interface */ +} usb_host_itfdesc_typedef; + +/* Standard Endpoint Descriptor */ +typedef struct { + uint8_t bLength; /* Size of this descriptor in bytes */ + uint8_t bDescriptorType; /* ENDPOINT descriptor type */ + uint8_t bEndpointAddress; /* The address of the endpoint on the device described by this descriptor */ + uint8_t bmAttributes; /* refer to the related standard of USB 2.0 */ + uint16_t wMaxPacketSize; /* Maximum Packet Size this endpoint is capable of sending or receiving when this \ + configuration is selected */ + uint8_t bInterval; /* Interval for servicing the endpoint for data transfers */ +} USB_HOST_EPDesc_TypeDef; + +/* USBH_CORE_Exported_Types */ +/* Host status */ +typedef enum { + HSTATUS_OK = 0, + HSTATUS_BUSY, + HSTATUS_FAIL, + HSTATUS_UNSUPPORTED, + HSTATUS_UNRECOVERED_ERROR, + HSTATUS_SPEED_UNKNOWN, + HSTATUS_APP_DEINIT +} HOST_STATUS; + +/* states about the handle stages on the host side */ +typedef enum { + HOST_IDLE = 0, + HOST_DEV_CONNECTED, + HOST_DEV_DISCONNECTED, + HOST_GET_DEVSPEED, + HOST_ENUM, + HOST_CLASS_REQ, + HOST_CLASS_PROCESS, + HOST_CTRL_TRANSMIT, + HOST_USER_INPUT, + HOST_SUSPENDED, + HOST_ERROR_STATE +} HOST_HANDLE_STATE; + + +/* states of the enumeration stage on the host side */ +typedef enum { + ENUM_IDLE = 0, + ENUM_GET_FULL_DEVDESC, + ENUM_SET_DEVADDR, + ENUM_GET_CFGDESC, + ENUM_GET_FULL_CFGDESC, + ENUM_GET_MFCSTRINGDESC, + ENUM_GET_PRODUCT_STRINGDESC, + ENUM_GET_SERIALNUM_STRINGDESC, + ENUM_SET_CFG, + ENUM_DEV_CFG_OVER +} ENUM_HANDLE_STATE; + +/* states of the control stages on the host side */ +typedef enum { + CTRL_IDLE = 0, + CTRL_SETUP, + CTRL_SETUP_WAIT, + CTRL_DATA_IN, + CTRL_DATA_IN_WAIT, + CTRL_DATA_OUT, + CTRL_DATA_OUT_WAIT, + CTRL_STATUS_IN, + CTRL_STATUS_IN_WAIT, + CTRL_STATUS_OUT, + CTRL_STATUS_OUT_WAIT, + CTRL_ERROR, + CTRL_STALLED, + CTRL_COMPLETE +} CTRL_HANDLE_STATE; + +/* Following states are state machine for the request transferring */ +typedef enum { + REQ_CMD_IDLE = 0, + REQ_CMD_TX, + REQ_CMD_WAIT +} REQ_HANDLE_STATE; + +typedef enum { + USER_HAVE_RESP = 0, + USER_NONE_RESP +} HOST_USER_STATUS; + +typedef struct { + uint8_t hc_num_in; /* channel number for the IN EP */ + uint8_t hc_num_out; /* channel number for the OUT EP */ + uint8_t ctrlmaxsize; /* the max size of EP0 parsed from the device descriptor */ + uint8_t err_cnt; /* the error counter */ + uint16_t sof_num; /* the frame number for sof packet */ + uint16_t length; /* length of data in byte */ + uint8_t *buff; /* data buffer */ + CTRL_HANDLE_STATUS ctrl_status; /* status of control pipe */ + CTRL_HANDLE_STATE ctrl_state; /* running state of the control transfer */ + usb_setup_typedef setup; /* setup packet */ +} usb_host_ctrl_param; + +/* Device information parsed from the related descriptors requested from the connected device + the following data are all parsed from the data sent by the connnected device */ +typedef struct { + uint8_t devaddr; /* the address of the connected device */ + uint8_t devspeed; /* the core speed of the connected device */ + usb_host_devdesc_typedef devdesc; /* the device descriptor parsed from the data sent by device */ + usb_host_cfgdesc_typedef devcfgdesc; /* the device configuration descriptor parsed from the data sent by device */ + usb_host_itfdesc_typedef devitfdesc[USBH_MAX_NUM_INTERFACES]; /* the interface descritpor */ + USB_HOST_EPDesc_TypeDef devepdesc[USBH_MAX_NUM_INTERFACES][USBH_MAX_NUM_ENDPOINTS]; /* the endpoint descriptor */ + USB_HOST_HIDDesc_TypeDef hiddesc; /* the hid descriptor */ +} usb_host_devinformation; + +typedef struct { + HOST_STATUS(*host_class_init)(usb_core_instance *pdev, void *phost); + void (*host_class_deinit)(usb_core_instance *pdev); + HOST_STATUS(*host_class_request)(usb_core_instance *pdev, void *phost); + HOST_STATUS(*host_class_process)(usb_core_instance *pdev, void *phost); +} usb_host_class_callback_func; + +typedef struct { + void (*huser_init)(void); + void (*huser_deinit)(void); + void (*huser_devattached)(void); + void (*huser_devreset)(void); + void (*huser_devdisconn)(void); + void (*huser_overcurrent)(void); + void (*huser_devspddetected)(uint8_t DeviceSpeed); + void (*huser_devdescavailable)(void *); + void (*huser_devaddrdistributed)(void); + void (*huser_cfgdescavailable)(usb_host_cfgdesc_typedef *, + usb_host_itfdesc_typedef *, + USB_HOST_EPDesc_TypeDef *); + /* Configuration Descriptor available */ + void (*huser_mfcstring)(void *); + void (*huser_productstring)(void *); + void (*huser_serialnum)(void *); + void (*huser_enumcompl)(void); + HOST_USER_STATUS(*huser_userinput)(void); + int (*huser_application)(void); + void (*huser_devunsupported)(void); + void (*huser_unrecoverederror)(void); +} usb_host_user_callback_func; + +typedef struct { + /* states for the host, enumeration, request */ + REQ_HANDLE_STATE req_state; /* value of state machine about the request */ + ENUM_HANDLE_STATE enum_state; /* state machine while enumerating */ + HOST_HANDLE_STATE host_state_backup; /* backup value of state machine about the host */ + HOST_HANDLE_STATE host_state; /* value of state machine about the host */ + /* control informations */ + usb_host_ctrl_param ctrlparam; /* values about the control parameters */ + /* device information parsed from the descriptors from the device */ + usb_host_devinformation device_prop; + /* functions: call back functions for the class and user */ + usb_host_class_callback_func *class_callbk; + usb_host_user_callback_func *user_callbk; +} USBH_HOST; + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ + +#ifndef FALSE +#define FALSE 0U +#endif + +#ifndef TRUE +#define TRUE 1U +#endif + +/* Get a 16bits data from buffer in little end mode. */ +#define SMALL_END(addr) (((uint16_t)(*((uint8_t *)(addr)))) + (((uint16_t)(*(((uint8_t *)(addr)) + 1U))) << 8U)) + +#define USB_LEN_CFG_DESC (0x09U) + +/* bmRequestType +D7: Data transfer direction + 0 = Host-to-device + 1 = Device-to-host +*/ +#define USB_REQ_DIR_MASK (0x80U) +#define USB_H2D (0x00U) +#define USB_D2H (0x80U) + +/* bmRequestType +D6...5: Type + 0 = Standard + 1 = Class + 2 = Vendor + 3 = Reserved +*/ +#define USB_REQ_TYPE_STANDARD (0x00U) +#define USB_REQ_TYPE_CLASS (0x20U) +#define USB_REQ_TYPE_VENDOR (0x40U) +#define USB_REQ_TYPE_RESERVED (0x60U) + +/* bmRequestType +D4...0: Recipient + 0 = Device + 1 = Interface + 2 = Endpoint + 3 = Other + 4...31 = Reserved +*/ +#define USB_REQ_RECIPIENT_DEVICE (0x00U) +#define USB_REQ_RECIPIENT_INTERFACE (0x01U) +#define USB_REQ_RECIPIENT_ENDPOINT (0x02U) +#define USB_REQ_RECIPIENT_OTHER (0x03U) + +/* Table 9-4. Standard Request Codes [USB Specification] */ +/* bRequest Value */ +#define USB_REQ_GET_STATUS (0x00U) +#define USB_REQ_CLEAR_FEATURE (0x01U) +#define USB_REQ_SET_FEATURE (0x03U) +#define USB_REQ_SET_ADDRESS (0x05U) +#define USB_REQ_GET_DESCRIPTOR (0x06U) +#define USB_REQ_SET_DESCRIPTOR (0x07U) +#define USB_REQ_GET_CONFIGURATION (0x08U) +#define USB_REQ_SET_CONFIGURATION (0x09U) +#define USB_REQ_GET_INTERFACE (0x0AU) +#define USB_REQ_SET_INTERFACE (0x0BU) +#define USB_REQ_SYNCH_FRAME (0x0Cu) + +/* Table 9-5. Descriptor Types [USB Specification] */ +/* Descriptor Types Value */ +#define USB_DESC_TYPE_DEVICE (1U) +#define USB_DESC_TYPE_CONFIGURATION (2U) +#define USB_DESC_TYPE_STRING (3U) +#define USB_DESC_TYPE_INTERFACE (4U) +#define USB_DESC_TYPE_ENDPOINT (5U) +#define USB_DESC_TYPE_DEVICE_QUALIFIER (6U) +#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION (7U) +#define USB_DESC_TYPE_INTERFACE_POWER (8U) +#define USB_DESC_TYPE_HID (0x21U) +#define USB_DESC_TYPE_HID_REPORT (0x22U) + +#define USB_DEVICE_DESC_SIZE (18U) +#define USB_CONFIGURATION_DESC_SIZE (9U) +#define USB_HID_DESC_SIZE (9U) +#define USB_INTERFACE_DESC_SIZE (9U) +#define USB_ENDPOINT_DESC_SIZE (7U) + +/* Descriptor Type and Descriptor Index */ +/* Use the following values when calling the function usb_host_getdesc */ +#define USB_DESC_DEVICE (((uint16_t)USB_DESC_TYPE_DEVICE << 8U) & 0xFF00U) +#define USB_DESC_CONFIGURATION (((uint16_t)USB_DESC_TYPE_CONFIGURATION << 8U) & 0xFF00U) +#define USB_DESC_STRING (((uint16_t)USB_DESC_TYPE_STRING << 8U) & 0xFF00U) +#define USB_DESC_INTERFACE (((uint16_t)USB_DESC_TYPE_INTERFACE << 8U) & 0xFF00U) +#define USB_DESC_ENDPOINT (((uint16_t)USB_DESC_TYPE_INTERFACE << 8U) & 0xFF00U) +#define USB_DESC_DEVICE_QUALIFIER (((uint16_t)USB_DESC_TYPE_DEVICE_QUALIFIER << 8U) & 0xFF00U) +#define USB_DESC_OTHER_SPEED_CONFIGURATION (((uint16_t)USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION << 8U) & 0xFF00U) +#define USB_DESC_INTERFACE_POWER (((uint16_t)USB_DESC_TYPE_INTERFACE_POWER << 8U) & 0xFF00U) +#define USB_DESC_HID_REPORT (((uint16_t)USB_DESC_TYPE_HID_REPORT << 8U) & 0xFF00U) +#define USB_DESC_HID (((uint16_t)USB_DESC_TYPE_HID << 8U) & 0xFF00U) + +#define USB_EP_DIR_OUT (0x00U) +#define USB_EP_DIR_IN (0x80U) +#define USB_EP_DIR_MSK (0x80U) + +/* supported classes */ +#define USB_MSC_CLASS (0x08U) +#define USB_HID_CLASS (0x03U) + +/* Interface Descriptor field values for HID Boot Protocol */ +#define HID_BOOT_CODE (0x01U) +#define HID_KEYBRD_BOOT_CODE (0x01U) +#define HID_MOUSE_BOOT_CODE (0x02U) + +/* As per USB specs 9.2.6.4 :Standard request with data request timeout: 5sec + Standard request with no data stage timeout : 50ms */ +#define DATA_STAGE_TIMEOUT (5000U) +#define NODATA_STAGE_TIMEOUT (50U) + +/* Macro definations for host mode */ +#define PID_DATA0 (0U) +#define PID_DATA2 (1U) +#define PID_DATA1 (2U) +#define PID_SETUP (3U) +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_HOST_DEF_H__ */ + +/****************************************************************************** + * EOF (not truncated) + *****************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_driver.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_driver.c new file mode 100644 index 000000000..606709899 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_driver.c @@ -0,0 +1,231 @@ +/** + ******************************************************************************* + * @file usb_host_driver.c + * @brief Host Interface Layer. + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_driver.h" +#include "usb_bsp.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ +/** + * @brief Initialize the driver for the host mode + * @param [in] pdev device instance + * @retval None + */ +void host_driver_init(usb_core_instance *pdev) +{ + uint8_t i; + + pdev->host.is_dev_connect = 0U; + for (i = 0U; i < USB_MAX_TX_FIFOS; i++) { + pdev->host.ErrCnt[i] = 0U; + pdev->host.XferCnt[i] = 0U; + pdev->host.HC_Status[i] = HOST_CH_IDLE; + } + pdev->host.hc[0].max_packet = 8U; + + usb_setregaddr(&pdev->regs, &pdev->basic_cfgs);; + + usb_gintdis(&pdev->regs); + usb_initusbcore(&pdev->regs, &pdev->basic_cfgs); + /* force to work in host mode*/ + usb_modeset(&pdev->regs, HOST_MODE); + /* configure charge pump IO */ + usb_bsp_cfgvbus(&pdev->regs); + usb_vbusctrl(&pdev->regs, 1U); + usb_mdelay(50UL); + + usb_hostmodeinit(&pdev->regs, &pdev->basic_cfgs); + usb_ginten(&pdev->regs); +} + +/** + * @brief get current speed when in host mode + * @param [in] pdev device instance + * @retval current speed + */ +uint32_t host_driver_getcurrentspd(usb_core_instance *pdev) +{ + uint32_t u32hppt; + u32hppt = READ_REG32(*pdev->regs.HPRT); + return ((u32hppt & USBFS_HPRT_PSPD) >> USBFS_HPRT_PSPD_POS); +} + +/** + * @brief get current DM DP state + * @param [in] pdev device instance + * @retval DM DP state + * 0x00 DM L, DP L + * 0x01 DM L, DP H + * 0x02 DM H, DP L + * 0x03 DM H, DP H + */ +uint32_t host_driver_getdmdpstate(usb_core_instance *pdev) +{ + uint32_t u32hppt; + u32hppt = READ_REG32(*pdev->regs.HPRT); + return ((u32hppt & USBFS_HPRT_PLSTS) >> USBFS_HPRT_PLSTS_POS); +} + +/** + * @brief get vbus drive state + * @param [in] pdev device instance + * @retval vbus driver state + * 0x00 vbus driver disable + * 0x01 vbus driver enable + */ +uint32_t host_driver_getvbusdrivestate(usb_core_instance *pdev) +{ + uint32_t u32hppt; + u32hppt = READ_REG32(*pdev->regs.HPRT); + return ((u32hppt & USBFS_HPRT_PWPR) >> USBFS_HPRT_PWPR_POS); +} + +/** + * @brief reset the port + * @param [in] pdev device instance + * @retval None + */ +void host_driver_portrst(usb_core_instance *pdev) +{ + usb_hprtrst(&pdev->regs); +} + +/** + * @brief get the connected status of the device + * @param [in] pdev device instance + * @retval 1 connected or 0 disconnected + */ +uint32_t host_driver_ifdevconnected(usb_core_instance *pdev) +{ + return (pdev->host.is_dev_connect); +} + +/** + * @brief gets the frame number for of sof packet + * @param [in] pdev device instance + * @retval number of frame + */ +uint32_t host_driver_getcurrentfrm(usb_core_instance *pdev) +{ + return (READ_REG32(pdev->regs.HREGS->HFNUM) & 0xFFFFUL) ; +} + +/** + * @brief gets the last xfer state + * @param [in] pdev device instance + * @param [in] ch_num channel number + * @retval HOST_CH_XFER_STATE + */ +HOST_CH_XFER_STATE host_driver_getxferstate(usb_core_instance *pdev, uint8_t ch_num) +{ + return pdev->host.URB_State[ch_num] ; +} + +/** + * @brief gets the xfer count + * @param [in] pdev device instance + * @param [in] ch_num channel number + * @retval number of data trandmitted in bytes + */ +uint32_t host_driver_getxfercnt(usb_core_instance *pdev, uint8_t ch_num) +{ + return pdev->host.XferCnt[ch_num] ; +} + +/** + * @brief gets the host channel status + * @param [in] pdev device instance + * @param [in] ch_num channel number + * @retval HOST_CH_STATUS + */ +HOST_CH_STATUS host_driver_gethostchstate(usb_core_instance *pdev, uint8_t ch_num) +{ + return pdev->host.HC_Status[ch_num] ; +} + +/** + * @brief prepare a host channel and start a transfer + * @param [in] pdev device instance + * @param [in] hc_num channel number + * @retval status + */ +uint32_t host_driver_hostch_init(usb_core_instance *pdev, uint8_t hc_num) +{ + return usb_inithch(&pdev->regs, hc_num, &pdev->host.hc[hc_num], pdev->basic_cfgs.dmaen); +} + +/** + * @brief prepare a host channel and start a transfer + * @param [in] pdev device instance + * @param [in] hc_num channel number + * @retval status + */ +uint32_t host_driver_submitrequest(usb_core_instance *pdev, uint8_t hc_num) +{ + pdev->host.URB_State[hc_num] = HOST_CH_XFER_IDLE; + pdev->host.hc[hc_num].xfer_count = 0U ; + return usb_hchtransbegin(&pdev->regs, hc_num, &pdev->host.hc[hc_num], pdev->basic_cfgs.dmaen); +} + +/** + * @} + */ + +/** + * @} + */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_driver.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_driver.h new file mode 100644 index 000000000..b7a902d21 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_driver.h @@ -0,0 +1,90 @@ +/** + ******************************************************************************* + * @file usb_host_driver.h + * @brief Head file for usb_host_driver.c + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ +#ifndef __USB_HOST_DRIVER_H__ +#define __USB_HOST_DRIVER_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_def.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +extern void host_driver_init(usb_core_instance *pdev); +extern uint32_t host_driver_hostch_init(usb_core_instance *pdev, uint8_t hc_num); +extern uint32_t host_driver_submitrequest(usb_core_instance *pdev, uint8_t hc_num); +extern uint32_t host_driver_getcurrentspd(usb_core_instance *pdev); +extern uint32_t host_driver_getdmdpstate(usb_core_instance *pdev); +extern uint32_t host_driver_getvbusdrivestate(usb_core_instance *pdev); +extern void host_driver_portrst(usb_core_instance *pdev); +extern uint32_t host_driver_ifdevconnected(usb_core_instance *pdev); +extern uint32_t host_driver_getcurrentfrm(usb_core_instance *pdev); +extern HOST_CH_XFER_STATE host_driver_getxferstate(usb_core_instance *pdev, uint8_t ch_num); +extern uint32_t host_driver_getxfercnt(usb_core_instance *pdev, uint8_t ch_num); +extern HOST_CH_STATUS host_driver_gethostchstate(usb_core_instance *pdev, uint8_t ch_num); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_HOST_DRIVER_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ + + diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_int.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_int.c new file mode 100644 index 000000000..cb8fe2899 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_int.c @@ -0,0 +1,575 @@ +/** + ******************************************************************************* + * @file usb_host_int.c + * @brief Host driver interrupt subroutines. + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_int.h" +#include "usb_host_driver.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ +void usb_host_hc_isr(usb_core_instance *pdev); + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ + +/** + * @brief processes interrupt for a specific host channel which is used for OUT EP + * @param [in] pdev device instance + * @param [in] chnum channel index + * @retval None + */ +static void usb_host_chx_out_isr(usb_core_instance *pdev, uint8_t chnum) +{ + uint32_t u32hcchar; + uint32_t u32hcint; + uint32_t u32hcintmsk; + + u32hcchar = READ_REG32(pdev->regs.HC_REGS[chnum]->HCCHAR); + u32hcint = READ_REG32(pdev->regs.HC_REGS[chnum]->HCINT); + u32hcintmsk = READ_REG32(pdev->regs.HC_REGS[chnum]->HCINTMSK); + u32hcint = u32hcint & u32hcintmsk; + + if (0UL != (u32hcint & USBFS_HCINT_ACK)) { + usb_host_clrint(pdev, chnum, USBFS_HCINT_ACK); + } +#if defined (HC32F4A0) + else if (0UL != (u32hcint & USBFS_HCINT_AHBERR)) { + usb_host_clrint(pdev, chnum, USBFS_HCINT_AHBERR); + usb_host_int_unmskchhltd(pdev, chnum); + } +#endif + else if (0UL != (u32hcint & USBFS_HCINT_FRMOR)) { + usb_host_int_unmskchhltd(pdev, chnum); + usb_hchstop(&pdev->regs, chnum); + usb_host_clrint(pdev, chnum, USBFS_HCINT_FRMOR); + } else if (0UL != (u32hcint & USBFS_HCINT_XFRC)) { + pdev->host.ErrCnt[chnum] = 0U; + usb_host_int_unmskchhltd(pdev, chnum); + usb_hchstop(&pdev->regs, chnum); + usb_host_clrint(pdev, chnum, USBFS_HCINT_XFRC); + pdev->host.HC_Status[chnum] = HOST_CH_XFERCOMPL; + } else if (0UL != (u32hcint & USBFS_HCINT_STALL)) { + usb_host_clrint(pdev, chnum, USBFS_HCINT_STALL); + usb_host_int_unmskchhltd(pdev, chnum); + usb_hchstop(&pdev->regs, chnum); + pdev->host.HC_Status[chnum] = HOST_CH_STALL; + } else if (0UL != (u32hcint & USBFS_HCINT_NAK)) { + pdev->host.ErrCnt[chnum] = 0U; + usb_host_int_unmskchhltd(pdev, chnum); + usb_hchstop(&pdev->regs, chnum); + usb_host_clrint(pdev, chnum, USBFS_HCINT_NAK); + pdev->host.HC_Status[chnum] = HOST_CH_NAK; + } else if (0UL != (u32hcint & USBFS_HCINT_TXERR)) { + usb_host_int_unmskchhltd(pdev, chnum); + usb_hchstop(&pdev->regs, chnum); + pdev->host.ErrCnt[chnum] ++; + pdev->host.HC_Status[chnum] = HOST_CH_XACTERR; + usb_host_clrint(pdev, chnum, USBFS_HCINT_TXERR); + } else if (0UL != (u32hcint & HCINT_NYET)) { + pdev->host.ErrCnt[chnum] = 0U; + usb_host_int_unmskchhltd(pdev, chnum); + usb_hchstop(&pdev->regs, chnum); + usb_host_clrint(pdev, chnum, HCINT_NYET); + pdev->host.HC_Status[chnum] = HOST_CH_NYET; + } else if (0UL != (u32hcint & USBFS_HCINT_DTERR)) { + usb_host_int_unmskchhltd(pdev, chnum); + usb_hchstop(&pdev->regs, chnum); + usb_host_clrint(pdev, chnum, USBFS_HCINT_NAK); + pdev->host.HC_Status[chnum] = HOST_CH_DATATGLERR; + usb_host_clrint(pdev, chnum, USBFS_HCINT_DTERR); + } else if (0UL != (u32hcint & USBFS_HCINT_CHH)) { + usb_host_int_mskchhltd(pdev, chnum); + if (pdev->host.HC_Status[chnum] == HOST_CH_XFERCOMPL) { + pdev->host.URB_State[chnum] = HOST_CH_XFER_DONE; + + if (((u32hcchar & USBFS_HCCHAR_EPTYP) >> USBFS_HCCHAR_EPTYP_POS) == EP_TYPE_BULK) { + pdev->host.hc[chnum].out_toggle ^= 1U; + } + } else if (pdev->host.HC_Status[chnum] == HOST_CH_NAK) { + pdev->host.URB_State[chnum] = HOST_CH_XFER_UNREADY; + } else if (pdev->host.HC_Status[chnum] == HOST_CH_NYET) { + if (pdev->host.hc[chnum].do_ping == 1U) { + usb_pingtokenissue(&pdev->regs, chnum); + } + pdev->host.URB_State[chnum] = HOST_CH_XFER_UNREADY; + } else if (pdev->host.HC_Status[chnum] == HOST_CH_STALL) { + pdev->host.URB_State[chnum] = HOST_CH_XFER_STALL; + } else if (pdev->host.HC_Status[chnum] == HOST_CH_XACTERR) { + if (pdev->host.ErrCnt[chnum] == 3UL) { + pdev->host.URB_State[chnum] = HOST_CH_XFER_ERROR; + pdev->host.ErrCnt[chnum] = 0UL; + } + } else { + ; + } + usb_host_clrint(pdev, chnum, USBFS_HCINT_CHH); + } else { + ; + } +} + +/** + * @brief processes interrupt for a specific host Channel which is used for IN EP + * @param [in] pdev device instance + * @param [in] chnum channel index + * @retval None + */ +static void usb_host_chx_in_isr(usb_core_instance *pdev, uint8_t chnum) +{ + uint32_t u32hcchar; + uint32_t u32hctsiz; + uint32_t u32eptypetmp; + uint32_t u32hcint; + uint32_t u32hcintmsk; + + u32hcchar = READ_REG32(pdev->regs.HC_REGS[chnum]->HCCHAR); + u32hcint = READ_REG32(pdev->regs.HC_REGS[chnum]->HCINT); + u32hcintmsk = READ_REG32(pdev->regs.HC_REGS[chnum]->HCINTMSK); + u32hcint = u32hcint & u32hcintmsk; + + u32eptypetmp = (u32hcchar & USBFS_HCCHAR_EPTYP) >> USBFS_HCCHAR_EPTYP_POS; + if (0UL != (u32hcint & USBFS_HCINT_ACK)) { + usb_host_clrint(pdev, chnum, USBFS_HCINT_ACK); + } +#if defined (HC32F4A0) + else if (0UL != (u32hcint & USBFS_HCINT_AHBERR)) { + usb_host_clrint(pdev, chnum, USBFS_HCINT_AHBERR); + usb_host_int_unmskchhltd(pdev, chnum); + } +#endif + else if (0UL != (u32hcint & USBFS_HCINT_STALL)) { + usb_host_int_unmskchhltd(pdev, chnum); + pdev->host.HC_Status[chnum] = HOST_CH_STALL; + usb_host_clrint(pdev, chnum, USBFS_HCINT_NAK); + usb_host_clrint(pdev, chnum, USBFS_HCINT_STALL); + usb_hchstop(&pdev->regs, chnum); + } else if (0UL != (u32hcint & USBFS_HCINT_DTERR)) { + usb_host_int_unmskchhltd(pdev, chnum); + usb_hchstop(&pdev->regs, chnum); + usb_host_clrint(pdev, chnum, USBFS_HCINT_NAK); + pdev->host.HC_Status[chnum] = HOST_CH_DATATGLERR; + usb_host_clrint(pdev, chnum, USBFS_HCINT_DTERR); + } else if (0UL != (u32hcint & USBFS_HCINT_FRMOR)) { + usb_host_int_unmskchhltd(pdev, chnum); + usb_hchstop(&pdev->regs, chnum); + usb_host_clrint(pdev, chnum, USBFS_HCINT_FRMOR); + } else if (0UL != (u32hcint & USBFS_HCINT_XFRC)) { + if (pdev->basic_cfgs.dmaen == 1U) { + u32hctsiz = READ_REG32(pdev->regs.HC_REGS[chnum]->HCTSIZ); + pdev->host.XferCnt[chnum] = pdev->host.hc[chnum].xfer_len - (u32hctsiz & USBFS_HCTSIZ_XFRSIZ); + } + pdev->host.HC_Status[chnum] = HOST_CH_XFERCOMPL; + pdev->host.ErrCnt [chnum] = 0U; + usb_host_clrint(pdev, chnum, USBFS_HCINT_XFRC); + switch (u32eptypetmp) { + case EP_TYPE_CTRL: + case EP_TYPE_BULK: + usb_host_int_unmskchhltd(pdev, chnum); + usb_hchstop(&pdev->regs, chnum); + usb_host_clrint(pdev, chnum, USBFS_HCINT_NAK); + pdev->host.hc[chnum].in_toggle ^= (uint8_t)1; + break; + case EP_TYPE_INTR: + u32hcchar |= USBFS_HCCHAR_ODDFRM; + WRITE_REG32(pdev->regs.HC_REGS[chnum]->HCCHAR, u32hcchar); + pdev->host.URB_State[chnum] = HOST_CH_XFER_DONE; + break; + case EP_TYPE_ISOC: + if (pdev->host.HC_Status[chnum] == HOST_CH_XFERCOMPL) { + pdev->host.URB_State[chnum] = HOST_CH_XFER_DONE; + } + break; + default: + break; + } + } else if (0UL != (u32hcint & USBFS_HCINT_CHH)) { + usb_host_int_mskchhltd(pdev, chnum); + if (pdev->host.HC_Status[chnum] == HOST_CH_XFERCOMPL) { + pdev->host.URB_State[chnum] = HOST_CH_XFER_DONE; + } else if (pdev->host.HC_Status[chnum] == HOST_CH_STALL) { + pdev->host.URB_State[chnum] = HOST_CH_XFER_STALL; + } else if (pdev->host.HC_Status[chnum] == HOST_CH_XACTERR) { + pdev->host.ErrCnt[chnum] = 0U; + pdev->host.URB_State[chnum] = HOST_CH_XFER_ERROR; + } else if (pdev->host.HC_Status[chnum] == HOST_CH_DATATGLERR) { + pdev->host.ErrCnt[chnum] = 0U; + pdev->host.URB_State[chnum] = HOST_CH_XFER_ERROR; + } else if (u32eptypetmp == EP_TYPE_INTR) { + pdev->host.hc[chnum].in_toggle ^= (uint8_t)1; + } else { + ; + } + usb_host_clrint(pdev, chnum, USBFS_HCINT_CHH); + } else if (0UL != (u32hcint & USBFS_HCINT_TXERR)) { + usb_host_int_unmskchhltd(pdev, chnum); + pdev->host.ErrCnt[chnum] ++; + pdev->host.HC_Status[chnum] = HOST_CH_XACTERR; + usb_hchstop(&pdev->regs, chnum); + usb_host_clrint(pdev, chnum, USBFS_HCINT_TXERR); + } else if (0UL != (u32hcint & USBFS_HCINT_NAK)) { + if (u32eptypetmp == EP_TYPE_INTR) { + usb_host_int_unmskchhltd(pdev, chnum); + usb_hchstop(&pdev->regs, chnum); + } else if ((u32eptypetmp == EP_TYPE_CTRL) || (u32eptypetmp == EP_TYPE_BULK)) { + u32hcchar |= USBFS_HCCHAR_CHENA; + u32hcchar &= ~USBFS_HCCHAR_CHDIS; + WRITE_REG32(pdev->regs.HC_REGS[chnum]->HCCHAR, u32hcchar); + } else { + ; + } + pdev->host.HC_Status[chnum] = HOST_CH_NAK; + usb_host_clrint(pdev, chnum, USBFS_HCINT_NAK); + } else { + ; + } +} + +/** + * @brief this function processes the channel interrupt + * @param [in] pdev device instance + * @retval None + */ +void usb_host_hc_isr(usb_core_instance *pdev) +{ + uint32_t u32hcchar; + uint8_t u8Cnt; + uint32_t u32haint; + + u32haint = READ_REG32(pdev->regs.HREGS->HAINT); + for (u8Cnt = 0U; u8Cnt < pdev->basic_cfgs.host_chnum; u8Cnt++) { + if (0UL != (u32haint & (1UL << u8Cnt))) { + u32hcchar = READ_REG32(pdev->regs.HC_REGS[u8Cnt]->HCCHAR); + if (0UL != ((u32hcchar & USBFS_HCCHAR_EPDIR) >> USBFS_HCCHAR_EPDIR_POS)) { + usb_host_chx_in_isr(pdev, u8Cnt); + } else { + usb_host_chx_out_isr(pdev, u8Cnt); + } + } + } +} + +/** + * @brief process the start-of-frame interrupt in host mode. + * @param [in] pdev device instance + * @retval None + */ +static void usb_host_sof_isr(usb_core_instance *pdev) +{ + WRITE_REG32(pdev->regs.GREGS->GINTSTS, USBFS_GINTSTS_SOF); +} + +/** + * @brief processes disconnect interrupt + * @param [in] pdev device instance + * @retval None + */ +static void usb_host_disconn_isr(usb_core_instance *pdev) +{ + usb_gintdis(&pdev->regs); + usb_vbusctrl(&pdev->regs, 0U); + WRITE_REG32(pdev->regs.GREGS->GINTSTS, USBFS_GINTSTS_DISCINT); + + pdev->host.is_dev_connect = 0U; +} + +#define USBFS_HNPTXSTS_NPTXQTOP_CHEPNUM_POS (27U) +#define USBFS_HNPTXSTS_NPTXQTOP_CHEPNUM (0x78000000UL) +/** + * @brief processes non-periodic txFIFO empty interrupt. + * @param [in] pdev device instance + * @retval None + */ +static void usb_host_nptxfifoempty_isr(usb_core_instance *pdev) +{ + uint32_t u32hnptxsts; + uint16_t u16LenWord; + uint16_t u16Len; + uint8_t u8ChNum; + + u32hnptxsts = READ_REG32(pdev->regs.GREGS->HNPTXSTS); + u8ChNum = (uint8_t)((u32hnptxsts & USBFS_HNPTXSTS_NPTXQTOP_CHEPNUM) >> USBFS_HNPTXSTS_NPTXQTOP_CHEPNUM_POS); + + u16LenWord = (uint16_t)((pdev->host.hc[u8ChNum].xfer_len + 3UL) / 4UL); + while (((u32hnptxsts & USBFS_HNPTXSTS_NPTXFSAV) > u16LenWord) && (pdev->host.hc[u8ChNum].xfer_len != 0U)) { + u16Len = (uint16_t)((u32hnptxsts & USBFS_HNPTXSTS_NPTXFSAV) * 4UL); + if (u16Len > pdev->host.hc[u8ChNum].xfer_len) { + u16Len = (uint16_t)pdev->host.hc[u8ChNum].xfer_len; + CLR_REG32_BIT(pdev->regs.GREGS->GINTMSK, USBFS_GINTSTS_NPTXFE); + } + u16LenWord = (uint16_t)((pdev->host.hc[u8ChNum].xfer_len + 3UL) / 4UL); + usb_wrpkt(&pdev->regs, pdev->host.hc[u8ChNum].xfer_buff, u8ChNum, u16Len, pdev->basic_cfgs.dmaen); + pdev->host.hc[u8ChNum].xfer_buff += u16Len; + pdev->host.hc[u8ChNum].xfer_len -= u16Len; + pdev->host.hc[u8ChNum].xfer_count += u16Len; + u32hnptxsts = READ_REG32(pdev->regs.GREGS->HNPTXSTS); + } +} +#define USBFS_HPTXSTS_PTXQTOP_CHNUM_POS (27U) +#define USBFS_HPTXSTS_PTXQTOP_CHNUM (0x78000000UL) +/** + * @brief processes periodic txFIFO empty interrupt + * @param [in] pdev device instance + * @retval None + */ +static void usb_host_ptxfifoempty_isr(usb_core_instance *pdev) +{ + uint32_t u32hptxsts; + uint16_t u16LenWord; + uint16_t u16Len; + uint8_t u8ChNum; + + u32hptxsts = READ_REG32(pdev->regs.HREGS->HPTXSTS); + u8ChNum = (uint8_t)((u32hptxsts & USBFS_HPTXSTS_PTXQTOP_CHNUM) >> USBFS_HPTXSTS_PTXQTOP_CHNUM_POS); + u16LenWord = (uint16_t)((pdev->host.hc[u8ChNum].xfer_len + 3UL) / 4UL); + while ((((u32hptxsts & USBFS_HPTXSTS_PTXFSAVL)) > u16LenWord) && (pdev->host.hc[u8ChNum].xfer_len != 0U)) { + u16Len = (uint16_t)((u32hptxsts & USBFS_HPTXSTS_PTXFSAVL) * 4UL); + if (u16Len > pdev->host.hc[u8ChNum].xfer_len) { + u16Len = (uint16_t)pdev->host.hc[u8ChNum].xfer_len; + CLR_REG32_BIT(pdev->regs.GREGS->GINTMSK, USBFS_GINTMSK_PTXFEM); + } + u16LenWord = (uint16_t)((pdev->host.hc[u8ChNum].xfer_len + 3UL) / 4UL); + usb_wrpkt(&pdev->regs, pdev->host.hc[u8ChNum].xfer_buff, u8ChNum, u16Len, pdev->basic_cfgs.dmaen); + pdev->host.hc[u8ChNum].xfer_buff += u16Len; + pdev->host.hc[u8ChNum].xfer_len -= u16Len; + pdev->host.hc[u8ChNum].xfer_count += u16Len; + u32hptxsts = READ_REG32(pdev->regs.HREGS->HPTXSTS); + } +} + +/** + * @brief This function determines which interrupt conditions have occurred + * @param [in] pdev device instance + * @retval None + */ +static void usb_host_port_isr(usb_core_instance *pdev) +{ + uint32_t u32hprt; + uint32_t u32hprt_bk; + uint8_t u8fslspclksel; + uint32_t do_reset = 0UL; + uint8_t u8PortSpeed; + + u32hprt = READ_REG32(*pdev->regs.HPRT); + u32hprt_bk = u32hprt; + /* Clear the interrupt bits in GINTSTS */ + //tmp_hprt_bk.b.prtovrcurrchng = 0U; //todo don't have this bit + u32hprt_bk &= ~(USBFS_HPRT_PENA | USBFS_HPRT_PCDET | USBFS_HPRT_PENCHNG); + + /* check if a port connect have been detected */ + if ((u32hprt & USBFS_HPRT_PCDET) != 0UL) { + u32hprt_bk |= USBFS_HPRT_PCDET; + if (host_driver_getvbusdrivestate(pdev) != 0UL) { + pdev->host.is_dev_connect = 1U; + } + } + /* check if port enable or disable change */ + if ((u32hprt & USBFS_HPRT_PENCHNG) != 0UL) { + u32hprt_bk |= USBFS_HPRT_PENCHNG; + + if ((u32hprt & USBFS_HPRT_PENA) != 0UL) { + u8PortSpeed = (uint8_t)((u32hprt & USBFS_HPRT_PSPD) >> USBFS_HPRT_PSPD_POS); + if ((u8PortSpeed == PRTSPD_LOW_SPEED) || (u8PortSpeed == PRTSPD_FULL_SPEED)) { + u8fslspclksel = (uint8_t)(READ_REG32(pdev->regs.HREGS->HCFG) & USBFS_HCFG_FSLSPCS); + if (u8PortSpeed == PRTSPD_LOW_SPEED) { + if (u8fslspclksel != HCFG_6_MHZ) { + do_reset = 1U; + } + } else { + /* 1ms*(PHY clock frequency for FS/LS)-1 */ + WRITE_REG32(pdev->regs.HREGS->HFIR, 48000UL); + if (u8fslspclksel != HCFG_48_MHZ) { + usb_fslspclkselset(&pdev->regs, HCFG_48_MHZ); + do_reset = 1U; + } + } + } else { + do_reset = 1U; + } + } + } + + //todo don't have this bit + //if ((u32hprt & USBFS_HPRT_PRTOVRCURRCHNG) != 0UL) { + // u32hprt_bk |= USBFS_HPRT_PRTOVRCURRCHNG; + //} + + if (0UL != do_reset) { + usb_hprtrst(&pdev->regs); + } + WRITE_REG32(*pdev->regs.HPRT, u32hprt_bk); +} + +/** + * @brief processes the rxFIFO non-empty interrupt + * @param [in] pdev device instance + * @retval None + */ +static void usb_host_rxflvl_isr(usb_core_instance *pdev) +{ + uint32_t u32grxsts; + uint32_t u32hctsiz; + uint32_t u32hcchar; + uint8_t u8chnum; + uint8_t *pu8Tmp; + uint16_t u16bcnt; + + CLR_REG32_BIT(pdev->regs.GREGS->GINTMSK, USBFS_GINTSTS_RXFNE); + + u32grxsts = READ_REG32(pdev->regs.GREGS->GRXSTSP); + u8chnum = (uint8_t)(u32grxsts & USBFS_GRXSTSP_CHNUM_EPNUM); + u16bcnt = (uint16_t)((u32grxsts & USBFS_GRXSTSP_BCNT) >> USBFS_GRXSTSP_BCNT_POS); + u32hcchar = READ_REG32(pdev->regs.HC_REGS[u8chnum]->HCCHAR); + + switch ((u32grxsts & USBFS_GRXSTSP_PKTSTS) >> USBFS_GRXSTSP_PKTSTS_POS) { + case 2: /* IN dat packet received */ + pu8Tmp = pdev->host.hc[u8chnum].xfer_buff; + if ((u16bcnt > 0U) && (pu8Tmp != (void *)0U)) { + usb_rdpkt(&pdev->regs, pdev->host.hc[u8chnum].xfer_buff, u16bcnt); + pdev->host.hc[u8chnum].xfer_buff += u16bcnt; + pdev->host.hc[u8chnum].xfer_count += u16bcnt; + pdev->host.XferCnt[u8chnum] = pdev->host.hc[u8chnum].xfer_count; + + u32hctsiz = READ_REG32(pdev->regs.HC_REGS[u8chnum]->HCTSIZ); + if (((u32hctsiz & USBFS_HCTSIZ_PKTCNT) >> USBFS_HCTSIZ_PKTCNT_POS) > 0U) { + u32hcchar |= USBFS_HCCHAR_CHENA; + u32hcchar &= ~USBFS_HCCHAR_CHDIS; + WRITE_REG32(pdev->regs.HC_REGS[u8chnum]->HCCHAR, u32hcchar); + } + } + break; + + case 3: /* IN transfer completed(trigger an interrupt) */ + break; + case 5: /* Daat toggle error(trigger an interrupt) */ + break; + case 7: /* Channel halted(trigger an interrupt) */ + break; + default: + break; + } + + SET_REG32_BIT(pdev->regs.GREGS->GINTMSK, USBFS_GINTSTS_RXFNE); +} + +/** + * @brief process the incomplete periodic transfer interrupt(incompIP) + * @param [in] pdev device instance + * @retval None + */ +static void usb_host_incomplisoout_isr(usb_core_instance *pdev) +{ + SET_REG32_BIT(pdev->regs.HC_REGS[0]->HCCHAR, USBFS_HCCHAR_CHENA | USBFS_HCCHAR_CHDIS); + WRITE_REG32(pdev->regs.GREGS->GINTSTS, USBFS_GINTSTS_IPXFR_INCOMPISOOUT); +} + +/** + * @brief process the resume/remote wakeup detected interrupt(WkUpInt) + * @param [in] pdev device instance + * @retval None + */ +static void usb_host_wkupint_isr(usb_core_instance *pdev) +{ + uint32_t u32hprt; + u32hprt = usb_rdhprt(&pdev->regs); + u32hprt &= ~USBFS_HPRT_PRES; + WRITE_REG32(*pdev->regs.HPRT, u32hprt); +} + +/** + * @brief This function process all interrupt of USB in host mode + * @param [in] pdev device instance + * @retval None + */ +void usb_host_isr(usb_core_instance *pdev) +{ + uint32_t gintstsval; + if (0U != usb_getcurmod(&pdev->regs)) { + gintstsval = usb_getcoreintr(&pdev->regs); + if (0UL != (gintstsval & USBFS_GINTSTS_SOF)) { + usb_host_sof_isr(pdev); + } + if (0UL != (gintstsval & USBFS_GINTSTS_RXFNE)) { + usb_host_rxflvl_isr(pdev); + } + if (0UL != (gintstsval & USBFS_GINTSTS_NPTXFE)) { + usb_host_nptxfifoempty_isr(pdev); + } + if (0UL != (gintstsval & USBFS_GINTSTS_PTXFE)) { + usb_host_ptxfifoempty_isr(pdev); + } + if (0UL != (gintstsval & USBFS_GINTSTS_HCINT)) { + usb_host_hc_isr(pdev); + } + if (0UL != (gintstsval & USBFS_GINTSTS_HPRTINT)) { + usb_host_port_isr(pdev); + } + if (0UL != (gintstsval & USBFS_GINTSTS_DISCINT)) { + usb_host_disconn_isr(pdev); + } + if (0UL != (gintstsval & USBFS_GINTSTS_IPXFR_INCOMPISOOUT)) { + usb_host_incomplisoout_isr(pdev); + } + if (0UL != (gintstsval & USBFS_GINTSTS_WKUINT)) { + usb_host_wkupint_isr(pdev); + } + } +} + +/** + * @} + */ + +/** + * @} + */ + +/****************************************************************************** + * EOF (not truncated) + *****************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_int.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_int.h new file mode 100644 index 000000000..6942068b9 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_int.h @@ -0,0 +1,128 @@ +/** + ******************************************************************************* + * @file usb_host_int.h + * @brief Head file for usb_host_int.c + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ +#ifndef __USB_HOST_INT_H__ +#define __USB_HOST_INT_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_def.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ +#define HCINT_NYET (1UL << 6) + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +/** + * @brief clear the interrupt flag bit + * @param [in] pdev device instance + * @param [in] ch_num the channel index + * @param [in] intbit the interrupt bit of the register HCINTn + * @retval None + */ +__STATIC_INLINE void usb_host_clrint(usb_core_instance *pdev, uint32_t ch_num, uint32_t intbit) +{ + WRITE_REG32(pdev->regs.HC_REGS[ch_num]->HCINT, intbit); +} + +/** + * @brief mask the interrupt of ChHltd + * @param [in] pdev device instance + * @param [in] ch_num channel index of the host application + * @retval None + */ +__STATIC_INLINE void usb_host_int_mskchhltd(usb_core_instance *pdev, uint32_t ch_num) +{ + CLR_REG32_BIT(pdev->regs.HC_REGS[ch_num]->HCINTMSK, USBFS_HCINTMSK_CHHM); +} + +/** + * @brief unmask the interrupt of ChHltd + * @param [in] pdev device instance + * @param [in] ch_num channel index of the host application + * @retval None + */ +__STATIC_INLINE void usb_host_int_unmskchhltd(usb_core_instance *pdev, uint32_t ch_num) +{ + SET_REG32_BIT(pdev->regs.HC_REGS[ch_num]->HCINTMSK, USBFS_HCINTMSK_CHHM); +} + +/** + * @brief mask the interrupt of ACK + * @param [in] pdev device instance + * @param [in] ch_num channel index of the host application + * @retval None + */ +__STATIC_INLINE void usb_host_int_mskack(usb_core_instance *pdev, uint32_t ch_num) +{ + CLR_REG32_BIT(pdev->regs.HC_REGS[ch_num]->HCINTMSK, USBFS_HCINTMSK_ACKM); +} + +/** + * @brief unmask the interrupt of ACK + * @param [in] pdev device instance + * @param [in] ch_num channel index of the host application + * @retval None + */ +__STATIC_INLINE void usb_host_int_unmskack(usb_core_instance *pdev, uint32_t ch_num) +{ + SET_REG32_BIT(pdev->regs.HC_REGS[ch_num]->HCINTMSK, USBFS_HCINTMSK_ACKM); +} + +void usb_host_isr(usb_core_instance *pdev); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_HOST_INT_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ + + diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_stdreq.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_stdreq.c new file mode 100644 index 000000000..02f316bca --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_stdreq.c @@ -0,0 +1,482 @@ +/** + ******************************************************************************* + * @file usb_host_stdreq.c + * @brief Standard requests for device enumeration + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_stdreq.h" +#include "usb_host_ctrltrans.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ + +/******************************************************************************* + * Local function prototypes declared in the last part. + ******************************************************************************/ +void usb_host_parsedevdesc(usb_host_devdesc_typedef *, uint8_t *buf, uint16_t length); + +void usb_host_parsecfgdesc(usb_host_cfgdesc_typedef *cfg_desc, + usb_host_itfdesc_typedef *itf_desc, + USB_HOST_EPDesc_TypeDef ep_desc[][USBH_MAX_NUM_ENDPOINTS], + uint8_t *buf, + uint16_t length); +void usb_host_parseitfdesc(usb_host_itfdesc_typedef *if_descriptor, uint8_t *buf); +void usb_host_parseepdesc(USB_HOST_EPDesc_TypeDef *ep_descriptor, uint8_t *buf); +void usb_host_parsestringdesc(uint8_t *psrc, uint8_t *pdest, uint16_t length); + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ +/** + * @brief issue a command descriptor from the connected device. parses the + * descriptor and updates the status once the response has been received. + * @param [in] pdev device instance + * @param [in] phost host state set + * @param [in] req_type type of the descriptor + * @param [in] value_idx wValue of setup for the request to get Descriptr + * @param [in] buff: buffer to save the the descriptor + * @param [in] length the length of the description. + * @retval status + */ +HOST_STATUS usb_host_getdesc(usb_core_instance *pdev, + USBH_HOST *phost, + uint8_t req_type, + uint16_t value_idx, + uint8_t *buff, + uint16_t length) +{ + phost->ctrlparam.setup.b.bmRequestType = USB_D2H | req_type; + phost->ctrlparam.setup.b.bRequest = USB_REQ_GET_DESCRIPTOR; + phost->ctrlparam.setup.b.wValue.w = value_idx; + + if ((value_idx & 0xff00U) == USB_DESC_STRING) { + phost->ctrlparam.setup.b.wIndex.w = 0x0409U; + } else { + phost->ctrlparam.setup.b.wIndex.w = 0U; + } + phost->ctrlparam.setup.b.wLength.w = length; + return usb_host_ctrlreq(pdev, phost, buff, length); +} + +/** + * @brief Issue command to the device to get the device discription. it parses + * the device descriptor and updates the status once getting the device + * description. + * @param [in] pdev device instance + * @param [in] phost host state set. + * @param [in] length the length of the description. + * @retval status + */ +HOST_STATUS usb_host_getdevdesc(usb_core_instance *pdev, + USBH_HOST *phost, + uint8_t length) +{ + HOST_STATUS status; + status = usb_host_getdesc(pdev, + phost, + (uint8_t)(USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD), + USB_DESC_DEVICE, + pdev->host.Rx_Buffer, + (uint16_t)length); + if (status == HSTATUS_OK) { + /* Commands successfully sent and Response Received */ + usb_host_parsedevdesc(&phost->device_prop.devdesc, pdev->host.Rx_Buffer, (uint16_t)length); + } + return status; +} + +/** + * @brief Issue a command to get the configuration description from the device + * connected, parse the configuration descriptor and update the + * status once the response has been received. + * @param [in] pdev device instance + * @param [in] phost host state set. + * @param [in] length the length of the description. + * @retval status + */ +HOST_STATUS usb_host_getcfgdesc(usb_core_instance *pdev, + USBH_HOST *phost, + uint16_t length) +{ + HOST_STATUS status; + + status = usb_host_getdesc(pdev, + phost, + USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD, + USB_DESC_CONFIGURATION, + pdev->host.Rx_Buffer, + length); + if (status == HSTATUS_OK) { + usb_host_parsecfgdesc(&phost->device_prop.devcfgdesc, + phost->device_prop.devitfdesc, + phost->device_prop.devepdesc, + pdev->host.Rx_Buffer, + length); + } + return status; +} + +/** + * @brief Issues string Descriptor command to the device. Once the response + * received, it parses the string descriptor and updates the status. + * @param [in] pdev device instance + * @param [in] phost host state set + * @param [in] string_index the index for the string + * @param [in] buff buffer to save the the string descriptor + * @param [in] length the length of the description. + * @retval status + */ +HOST_STATUS usb_host_getstringdesc(usb_core_instance *pdev, + USBH_HOST *phost, + uint8_t string_index, + uint8_t *buff, + uint16_t length) +{ + HOST_STATUS status; + status = usb_host_getdesc(pdev, + phost, + USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD, + USB_DESC_STRING | string_index, + pdev->host.Rx_Buffer, + length); + if (status == HSTATUS_OK) { + usb_host_parsestringdesc(pdev->host.Rx_Buffer, buff, length); + } + return status; +} + +/** + * @brief issue a command to set the address for the device that have connected. + * @param [in] pdev device instance + * @param [in] phost host state set + * @param [in] DeviceAddress Device address which would be set to the conected device + * @retval status + */ +HOST_STATUS usb_host_setdevaddr(usb_core_instance *pdev, + USBH_HOST *phost, + uint8_t DeviceAddress) +{ + /* + Refer to table9-3 of 9.4 + */ + phost->ctrlparam.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD; + phost->ctrlparam.setup.b.bRequest = USB_REQ_SET_ADDRESS; + phost->ctrlparam.setup.b.wValue.w = (uint16_t)DeviceAddress; + phost->ctrlparam.setup.b.wIndex.w = 0U; + phost->ctrlparam.setup.b.wLength.w = 0U; + + return usb_host_ctrlreq(pdev, phost, NULL, 0U); +} + +/** + * @brief issue a command to set the configuration to the connected device. + * @param [in] pdev device instance + * @param [in] phost host state set + * @param [in] cfg_idx value for the configuration setup + * @retval status + */ +HOST_STATUS usb_host_setconfig(usb_core_instance *pdev, + USBH_HOST *phost, + uint16_t cfg_idx) +{ + phost->ctrlparam.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_DEVICE | USB_REQ_TYPE_STANDARD; + phost->ctrlparam.setup.b.bRequest = USB_REQ_SET_CONFIGURATION; + phost->ctrlparam.setup.b.wValue.w = cfg_idx; + phost->ctrlparam.setup.b.wIndex.w = 0U; + phost->ctrlparam.setup.b.wLength.w = 0U; + + return usb_host_ctrlreq(pdev, phost, NULL, 0U); +} + +/** + * @brief issue a command to set the Interface value to the connected device + * @param [in] pdev device instance + * @param [in] phost host state set + * @param [in] ep_num the index of the endpoint + * @param [in] altSetting the value for the setup of set interface + * @retval status + */ +HOST_STATUS usb_host_setintf(usb_core_instance *pdev, + USBH_HOST *phost, + uint8_t ep_num, + uint8_t altSetting) +{ + phost->ctrlparam.setup.b.bmRequestType = USB_H2D | USB_REQ_RECIPIENT_INTERFACE | USB_REQ_TYPE_STANDARD; + + phost->ctrlparam.setup.b.bRequest = USB_REQ_SET_INTERFACE; + phost->ctrlparam.setup.b.wValue.w = altSetting; + phost->ctrlparam.setup.b.wIndex.w = ep_num; + phost->ctrlparam.setup.b.wLength.w = 0U; + + return usb_host_ctrlreq(pdev, phost, NULL, 0U); +} + +/** + * @brief issue a comman to clear or disable a specific feature in the device. + * @param [in] pdev device instance + * @param [in] phost host state set + * @param [in] ep_num index of the endpoint + * @param [in] hc_num host channel index + * @retval status + */ +HOST_STATUS usb_host_clrfeature(usb_core_instance *pdev, + USBH_HOST *phost, + uint8_t ep_num, + uint8_t hc_num) +{ + phost->ctrlparam.setup.b.bmRequestType = USB_H2D | + USB_REQ_RECIPIENT_ENDPOINT | + USB_REQ_TYPE_STANDARD; + + phost->ctrlparam.setup.b.bRequest = USB_REQ_CLEAR_FEATURE; + phost->ctrlparam.setup.b.wValue.w = FEATURE_SELECTOR_ENDPOINT; + phost->ctrlparam.setup.b.wIndex.w = ep_num; + phost->ctrlparam.setup.b.wLength.w = 0U; + + if ((ep_num & USB_REQ_DIR_MASK) == USB_D2H) { + pdev->host.hc[hc_num].in_toggle = 0U; + } else { + pdev->host.hc[hc_num].out_toggle = 0U; + } + + return usb_host_ctrlreq(pdev, phost, NULL, 0U); +} + +/** + * @brief parse the data frame of device descriptor + * @param [in] dev_desc the structure of the device descriptor + * @param [in] buf buffer where the source descriptor is save + * @param [in] length Length of the descriptor in byte + * @retval None + */ +void usb_host_parsedevdesc(usb_host_devdesc_typedef *dev_desc, + uint8_t *buf, + uint16_t length) +{ + dev_desc->bLength = *(uint8_t *)(buf + 0U); + dev_desc->bDescriptorType = *(uint8_t *)(buf + 1U); + dev_desc->bcdUSB = SMALL_END(buf + 2U); + dev_desc->bDeviceClass = *(uint8_t *)(buf + 4U); + dev_desc->bDeviceSubClass = *(uint8_t *)(buf + 5U); + dev_desc->bDeviceProtocol = *(uint8_t *)(buf + 6U); + dev_desc->bMaxPacketSize0 = *(uint8_t *)(buf + 7U); + + if (length > (uint16_t)8) { + dev_desc->idVendor = SMALL_END(buf + 8U); + dev_desc->idProduct = SMALL_END(buf + 10U); + dev_desc->bcdDevice = SMALL_END(buf + 12U); + dev_desc->iManufacturer = *(uint8_t *)(buf + 14U); + dev_desc->iProduct = *(uint8_t *)(buf + 15U); + dev_desc->iSerialNumber = *(uint8_t *)(buf + 16U); + dev_desc->bNumConfigurations = *(uint8_t *)(buf + 17U); + } +} + +/** + * @brief This function Parses the configuration descriptor from the received buffer + * @param [in] cfg_desc the structure of configuration descriptor + * @param [in] itf_desc the structure of interface descriptor + * @param [in] ep_desc the structure of endpoint descriptor + * @param [in] buf buffer where the source descriptor is save + * @param [in] length Length of the descriptor in byte + * @retval None + */ +void usb_host_parsecfgdesc(usb_host_cfgdesc_typedef *cfg_desc, + usb_host_itfdesc_typedef *itf_desc, + USB_HOST_EPDesc_TypeDef ep_desc[][USBH_MAX_NUM_ENDPOINTS], + uint8_t *buf, + uint16_t length) +{ + usb_host_itfdesc_typedef *pif ; + usb_host_itfdesc_typedef temp_pif ; + USB_HOST_EPDesc_TypeDef *pep; + USB_HOST_DescHeader_TypeDef *pdesc = (USB_HOST_DescHeader_TypeDef *)buf; + uint16_t ptr; + int8_t if_ix; + int8_t ep_ix; + static uint16_t prev_ep_size = 0U; + static uint8_t prev_itf = 0U; + + /* Parse the configuration descriptor */ + cfg_desc->bLength = *(uint8_t *)(buf + 0U); + cfg_desc->bDescriptorType = *(uint8_t *)(buf + 1U); + cfg_desc->wTotalLength = SMALL_END(buf + 2U); + cfg_desc->bNumInterfaces = *(uint8_t *)(buf + 4U); + cfg_desc->bConfigurationValue = *(uint8_t *)(buf + 5U); + cfg_desc->iConfiguration = *(uint8_t *)(buf + 6U); + cfg_desc->bmAttributes = *(uint8_t *)(buf + 7U); + cfg_desc->bMaxPower = *(uint8_t *)(buf + 8U); + + if (length > USB_CONFIGURATION_DESC_SIZE) { + ptr = USB_LEN_CFG_DESC; + + if (cfg_desc->bNumInterfaces <= USBH_MAX_NUM_INTERFACES) { + + while (ptr < cfg_desc->wTotalLength) { + pdesc = usb_host_getnextdesc((uint8_t *)pdesc, &ptr); + if (pdesc->bDescriptorType == USB_DESC_TYPE_INTERFACE) { + if_ix = (int8_t) * (((uint8_t *)pdesc) + 2U); + pif = &itf_desc[if_ix]; + + if ((*((uint8_t *)pdesc + 3U)) < 3U) { + usb_host_parseitfdesc(&temp_pif, (uint8_t *)pdesc); + ep_ix = (int8_t)0; + + /* Parse Ep descriptors relative to the current interface */ + if (temp_pif.bNumEndpoints <= USBH_MAX_NUM_ENDPOINTS) { + while (ep_ix < (int8_t)temp_pif.bNumEndpoints) { + pdesc = usb_host_getnextdesc((void *)pdesc, &ptr); + if (pdesc->bDescriptorType == USB_DESC_TYPE_ENDPOINT) { + pep = &ep_desc[if_ix][ep_ix]; + + if (prev_itf != (uint8_t)if_ix) { + prev_itf = (uint8_t)if_ix; + usb_host_parseitfdesc(pif, (uint8_t *)&temp_pif); + } else { + if (prev_ep_size > SMALL_END((uint8_t *)pdesc + 4U)) { + break; + } else { + usb_host_parseitfdesc(pif, (uint8_t *)&temp_pif); + } + } + usb_host_parseepdesc(pep, (uint8_t *)pdesc); + prev_ep_size = SMALL_END((uint8_t *)pdesc + 4U); + ep_ix++; + } + } + } + } + } + } + } + prev_ep_size = 0U; + prev_itf = 0U; + } +} + +/** + * @brief This function parses the interface descriptor from the received buffer. + * @param [in] if_descriptor structure of interface descriptor + * @param [in] buf buffer where the source descriptor is save + * @retval None + */ +void usb_host_parseitfdesc(usb_host_itfdesc_typedef *if_descriptor, uint8_t *buf) +{ + if_descriptor->bLength = *(uint8_t *)(buf + 0U); + if_descriptor->bDescriptorType = *(uint8_t *)(buf + 1U); + if_descriptor->bInterfaceNumber = *(uint8_t *)(buf + 2U); + if_descriptor->bAlternateSetting = *(uint8_t *)(buf + 3U); + if_descriptor->bNumEndpoints = *(uint8_t *)(buf + 4U); + if_descriptor->bInterfaceClass = *(uint8_t *)(buf + 5U); + if_descriptor->bInterfaceSubClass = *(uint8_t *)(buf + 6U); + if_descriptor->bInterfaceProtocol = *(uint8_t *)(buf + 7U); + if_descriptor->iInterface = *(uint8_t *)(buf + 8U); +} + +/** + * @brief This function parses the endpoint descriptor from the received buffer. + * @param [in] ep_descriptor the structure of endpoint descriptor. + * @param [in] buf buffer where the source descriptor is save + * @retval None + */ +void usb_host_parseepdesc(USB_HOST_EPDesc_TypeDef *ep_descriptor, uint8_t *buf) +{ + ep_descriptor->bLength = *(uint8_t *)(buf + 0U); + ep_descriptor->bDescriptorType = *(uint8_t *)(buf + 1U); + ep_descriptor->bEndpointAddress = *(uint8_t *)(buf + 2U); + ep_descriptor->bmAttributes = *(uint8_t *)(buf + 3U); + ep_descriptor->wMaxPacketSize = SMALL_END(buf + 4U); + ep_descriptor->bInterval = *(uint8_t *)(buf + 6U); +} + +/** + * @brief This function parses the string descriptor from the received buffer. + * @param [in] psrc source data + * @param [in] pdest destination data + * @param [in] length Length of the descriptor in byte + * @retval None + */ +void usb_host_parsestringdesc(uint8_t *psrc, uint8_t *pdest, uint16_t length) +{ + uint16_t strlength; + uint16_t tmp_idx; + /* + The describ of String Desctipor refers to 9.6.8 + psrc[0] = bLength bLength = N+2 + psrc[1] = bDescriptorType STRING Descriptor Type + ... + */ + if (psrc[1] == USB_DESC_TYPE_STRING) { + strlength = ((((uint16_t)psrc[0]) - 2U) <= length) ? (((uint16_t)psrc[0]) - 2U) : length; + psrc += 2U; + for (tmp_idx = 0U; tmp_idx < strlength; tmp_idx += 2U) { + *pdest = psrc[tmp_idx]; + pdest++; + } + *pdest = 0U; + } +} + +/** + * @brief This function gets the header of next descriptor. + * @param [in] pbuf buffer where the configuration descriptor is contained. + * @param [in] ptr data popinter inside the cfg descriptor + * @retval header of next descriptor + */ +USB_HOST_DescHeader_TypeDef *usb_host_getnextdesc(uint8_t *pbuf, uint16_t *ptr) +{ + USB_HOST_DescHeader_TypeDef *pnext; + + *ptr += ((USB_HOST_DescHeader_TypeDef *)pbuf)->bLength; + pnext = (USB_HOST_DescHeader_TypeDef *)((uint8_t *)pbuf + ((USB_HOST_DescHeader_TypeDef *)pbuf)->bLength); + + return (pnext); +} + +/** + * @} + */ + +/** + * @} + */ + +/****************************************************************************** + * EOF (not truncated) + *****************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_stdreq.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_stdreq.h new file mode 100644 index 000000000..762a89597 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core/usb_host_stdreq.h @@ -0,0 +1,107 @@ +/** + ******************************************************************************* + * @file usb_host_stdreq.h + * @brief Header file for usb_host_stdreq.c + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ +#ifndef __USB_HOST_STDREQ_H__ +#define __USB_HOST_STDREQ_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "usb_host_def.h" + +/** + * @addtogroup LL_USB_LIB + * @{ + */ + +/** + * @addtogroup LL_USB_HOST_CORE + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/* USBH_STDREQ_Exported_Defines */ +/* Standard Feature Selector for clear feature command */ +#define FEATURE_SELECTOR_ENDPOINT (0x00U) +#define FEATURE_SELECTOR_DEVICE (0x01U) + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +extern HOST_STATUS usb_host_getdesc(usb_core_instance *pdev, + USBH_HOST *phost, + uint8_t req_type, + uint16_t value_idx, + uint8_t *buff, + uint16_t length); + +extern HOST_STATUS usb_host_getdevdesc(usb_core_instance *pdev, USBH_HOST *phost, uint8_t length); + +HOST_STATUS usb_host_getstringdesc(usb_core_instance *pdev, + USBH_HOST *phost, + uint8_t string_index, + uint8_t *buff, + uint16_t length); + +extern HOST_STATUS usb_host_setconfig(usb_core_instance *pdev, USBH_HOST *phost, uint16_t cfg_idx); + +extern HOST_STATUS usb_host_getcfgdesc(usb_core_instance *pdev, USBH_HOST *phost, uint16_t length); + +extern HOST_STATUS usb_host_setdevaddr(usb_core_instance *pdev, USBH_HOST *phost, uint8_t DeviceAddress); + +extern HOST_STATUS usb_host_clrfeature(usb_core_instance *pdev, USBH_HOST *phost, uint8_t ep_num, uint8_t hc_num); + +extern HOST_STATUS usb_host_setintf(usb_core_instance *pdev, USBH_HOST *phost, uint8_t ep_num, uint8_t altSetting); + +extern USB_HOST_DescHeader_TypeDef *usb_host_getnextdesc(uint8_t *pbuf, uint16_t *ptr); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_HOST_STDREQ_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/usb_lib.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/usb_lib.h new file mode 100644 index 000000000..9b1132c27 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_lib/usb_lib.h @@ -0,0 +1,199 @@ +/** + ******************************************************************************* + * @file usb_lib.h + * @brief Header of the Core Layer Driver + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ +#ifndef __USB_LIB_H__ +#define __USB_LIB_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include +#include + +/** + * @addtogroup LL_USB_LIB LL USB Lib + * @{ + */ + +/** + * @addtogroup LL_USB_LIB_DEF LL USB Lib Define + * @{ + */ + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ +#define MAX_DATA_LENGTH (0x200U) + + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ + +/* status of the host channel */ +typedef enum { + HOST_CH_IDLE = 0U, + HOST_CH_XFERCOMPL, + HOST_CH_CHHLTD, + HOST_CH_NAK, + HOST_CH_NYET, + HOST_CH_STALL, + HOST_CH_XACTERR, + HOST_CH_BBLERR, + HOST_CH_DATATGLERR, + HOST_CH_AHBERR, + HOST_CH_FRMOVRUN, + HOST_CH_BNAINTR, + HOST_CH_XCS_XACT_ERR, + HOST_CH_DESC_LST_ROLLINTR +} HOST_CH_STATUS; + +typedef enum { + HOST_CH_XFER_IDLE = 0U, + HOST_CH_XFER_DONE, + HOST_CH_XFER_UNREADY, + HOST_CH_XFER_ERROR, + HOST_CH_XFER_STALL +} HOST_CH_XFER_STATE; + +typedef enum { + CTRL_START = 0U, + CTRL_XFRC, + CTRL_HALTED, + CTRL_NAK, + CTRL_STALL, + CTRL_XACTERR, + CTRL_BBLERR, + CTRL_DATATGLERR, + CTRL_FAIL +} CTRL_HANDLE_STATUS; + +typedef struct { + uint8_t bmRequest; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +} USB_SETUP_REQ; + +typedef struct { + uint8_t *(*get_dev_desc)(uint16_t *length); + uint8_t *(*get_dev_langiddesc)(uint16_t *length); + uint8_t *(*get_dev_manufacturerstr)(uint16_t *length); + uint8_t *(*get_dev_productstr)(uint16_t *length); + uint8_t *(*get_dev_serialstr)(uint16_t *length); + uint8_t *(*get_dev_configstr)(uint16_t *length); + uint8_t *(*get_dev_interfacestr)(uint16_t *length); +} usb_dev_desc_func; + +typedef struct { + void (*class_init)(void *pdev); + void (*class_deinit)(void *pdev); + uint8_t (*ep0_setup)(void *pdev, USB_SETUP_REQ *req); + void (*ep0_datain)(void *pdev); + void (*ep0_dataout)(void *pdev); + uint8_t *(*class_getconfigdesc)(uint16_t *length); + uint8_t (*class_sof)(void *pdev); + void (*class_datain)(void *pdev, uint8_t epnum); + void (*class_dataout)(void *pdev, uint8_t epnum); + void (*class_syn_in_incomplt)(void *pdev); + void (*class_syn_out_incomplt)(void *pdev); +} usb_dev_class_func; + +typedef struct { + void (*user_init)(void); + void (*user_devrst)(void); + void (*user_devconfig)(void); + void (*user_devsusp)(void); + void (*user_devresume)(void); + void (*user_devconn)(void); + void (*user_devdisconn)(void); +} usb_dev_user_func; + +typedef struct { + __IO uint8_t device_config; + __IO uint8_t device_address; + __IO uint8_t device_state; + __IO uint8_t device_old_status; + __IO uint8_t device_cur_status; + __IO uint8_t connection_status; + __IO uint8_t device_remote_wakeup; + __IO uint8_t test_mode; + USB_DEV_EP in_ep[USB_MAX_TX_FIFOS]; + USB_DEV_EP out_ep[USB_MAX_TX_FIFOS]; + uint8_t setup_pkt_buf[24]; + usb_dev_class_func *class_callback; + usb_dev_user_func *user_callback; + usb_dev_desc_func *desc_callback; +} USB_DEV_PARAM; + +typedef struct { + uint16_t channel[USB_MAX_TX_FIFOS]; + USB_HOST_CH hc[USB_MAX_TX_FIFOS]; + __IO uint32_t is_dev_connect; + uint8_t Rx_Buffer[MAX_DATA_LENGTH]; + __IO uint32_t ErrCnt[USB_MAX_TX_FIFOS]; + __IO uint32_t XferCnt[USB_MAX_TX_FIFOS]; + __IO HOST_CH_STATUS HC_Status[USB_MAX_TX_FIFOS]; + __IO HOST_CH_XFER_STATE URB_State[USB_MAX_TX_FIFOS]; +} USB_HOST_PARAM; + +typedef struct { + USB_CORE_BASIC_CFGS basic_cfgs; + LL_USB_TypeDef regs; +#ifdef USE_DEVICE_MODE + USB_DEV_PARAM dev; +#endif +#ifdef USE_HOST_MODE + USB_HOST_PARAM host; +#endif +} usb_core_instance; + + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_LIB_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_user.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_user.c new file mode 100644 index 000000000..5cb3ad369 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_user.c @@ -0,0 +1,333 @@ +/** + ******************************************************************************* + * @file usb/usb_host_msc/source/usb_host_user.c + * @brief user application layer. + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +/** +* @file usb_host_user.c +* @brief support hc32f4a0-board usb function +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-11-07 +*/ + +/************************************************* +File name: usb_host_user.c +Description: support hc32f4a0-board usb function +Others: +History: +1. Date: 2022-11-07 +Author: AIIT XUOS Lab +Modification: +1. delete useless usb host configure and define +2. add KPrintf function +3. add UsbMountFileSystem() and UsbUnmountFileSystem() +*************************************************/ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include +#include +#include +#include "usb_host_user.h" +#include "usb_host_msc_class.h" +#include "usb_host_msc_scsi.h" +#include "usb_host_msc_bot.h" +#include "usb_host_driver.h" + +/** + * @addtogroup HC32F4A0_DDL_Applications + * @{ + */ + +/** + * @addtogroup USB_Host_Msc + * @{ + */ + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ +extern void UsbMountFileSystem(); +extern void UsbUnmountFileSystem(); + +/* USBH_USR_Private_Macros */ +extern usb_core_instance usb_app_instance; + +/* Points to the DEVICE_PROP structure of current device */ +/* The purpose of this register is to speed up the execution */ +usb_host_user_callback_func USR_cb = { + &host_user_init, + &host_user_denint, + &host_user_devattached, + &host_user_devreset, + &host_user_devdisconn, + &host_user_overcurrent, + &host_user_devspddetected, + &host_user_devdescavailable, + &host_user_devaddrdistributed, + &host_user_cfgdescavailable, + &host_user_mfcstring, + &host_user_productstring, + &host_user_serialnum, + &host_user_enumcompl, + &host_user_userinput, + &host_user_msc_app, + &host_user_devunsupported, + &host_user_unrecoverederror + +}; + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ +uint8_t USB_HOST_USER_AppState = USH_USR_FS_INIT; + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ +/** + * @brief Displays the message on terminal for host lib initialization + * @param None + * @retval None + */ +void host_user_init(void) +{ + static uint8_t startup = 0U; + + if (startup == 0U) { + startup = 1U; + KPrintf("USB Host library v2.1.0 started\r\n"); + } +} + +/** + * @brief Displays the message on terminal via DDL_Printf + * @param None + * @retval None + */ +void host_user_devattached(void) +{ + KPrintf("USB device attached\r\n"); + UsbMountFileSystem(); +} + +/** + * @brief host_user_unrecoverederror + * @param None + * @retval None + */ +void host_user_unrecoverederror(void) +{ + KPrintf("USB device unrecovered error\r\n"); +} + +/** + * @brief Device disconnect event + * @param None + * @retval None + */ +void host_user_devdisconn(void) +{ + KPrintf("USB device disconnect\r\n"); + UsbUnmountFileSystem(); +} + +/** + * @brief USBH_USR_ResetUSBDevice + * @param None + * @retval None + */ +void host_user_devreset(void) +{ + /* callback for USB-Reset */ + KPrintf("USB device reset\r\n"); +} + +/** + * @brief host_user_devspddetected + * @param [in] DeviceSpeed USB speed + * @retval None + */ +void host_user_devspddetected(uint8_t DeviceSpeed) +{ + if (DeviceSpeed == PRTSPD_FULL_SPEED) { + KPrintf("USB device speed PRTSPD_FULL_SPEED\r\n"); + } else if (DeviceSpeed == PRTSPD_LOW_SPEED) { + KPrintf("USB device speed PRTSPD_LOW_SPEED\r\n"); + } else { + KPrintf("USB device speed error\r\n"); + } +} + +/** + * @brief host_user_devdescavailable + * @param [in] DeviceDesc device descriptor + * @retval None + */ +void host_user_devdescavailable(void *DeviceDesc) +{ + usb_host_devdesc_typedef *hs; + hs = DeviceDesc; + KPrintf("USB device VID : %04lXh PID : %04lXh\r\n", (uint32_t)(*hs).idVendor, (uint32_t)(*hs).idProduct); +} + +/** + * @brief host_user_devaddrdistributed + * @param None + * @retval None + */ +void host_user_devaddrdistributed(void) +{ +} + +/** + * @brief host_user_cfgdescavailable + * @param [in] cfgDesc Configuration desctriptor + * @param [in] itfDesc Interface desctriptor + * @param [in] epDesc Endpoint desctriptor + * @retval None + */ +void host_user_cfgdescavailable(usb_host_cfgdesc_typedef *cfgDesc, + usb_host_itfdesc_typedef *itfDesc, + USB_HOST_EPDesc_TypeDef *epDesc) +{ + usb_host_itfdesc_typedef *id; + + id = itfDesc; + if ((*id).bInterfaceClass == 0x08U) { + KPrintf("USB Mass storage device connected\r\n"); + } else if ((*id).bInterfaceClass == 0x03U) { + KPrintf("USB HID device connected\r\n"); + } else { + ; + } +} + +/** + * @brief Displays the message on terminal for Manufacturer String + * @param [in] ManufacturerString + * @retval None + */ +void host_user_mfcstring(void *ManufacturerString) +{ + KPrintf("Manufacturer : %s\r\n", (char *)ManufacturerString); +} + +/** + * @brief Displays the message on terminal for product String + * @param [in] ProductString + * @retval None + */ +void host_user_productstring(void *ProductString) +{ + KPrintf("Product : %s\r\n", (char *)ProductString); +} + +/** + * @brief Displays the message on terminal for SerialNum_String + * @param [in] SerialNumString + * @retval None + */ +void host_user_serialnum(void *SerialNumString) +{ + KPrintf("Serial Number : %s\r\n", (char *)SerialNumString); +} + +/** + * @brief User response request is displayed to ask application jump to class + * @param None + * @retval None + */ +void host_user_enumcompl(void) +{ +} + +/** + * @brief Device is not supported + * @param None + * @retval None + */ +void host_user_devunsupported(void) +{ + KPrintf("USB Device not supported.\r\n"); +} + +/** + * @brief User Action for application state entry + * @param None + * @retval HOST_USER_STATUS User response for key button + */ +HOST_USER_STATUS host_user_userinput(void) +{ +} + +/** + * @brief Over Current Detected on VBUS + * @param None + * @retval None + */ +void host_user_overcurrent(void) +{ + KPrintf("USB HOST Overcurrent detected.\r\n"); +} + +/** + * @brief Demo application for mass storage + * @param None + * @retval None + */ +int host_user_msc_app(void) +{ + return ((int)0); +} + +/** + * @brief Deint User state and associated variables + * @param None + * @retval None + */ +void host_user_denint(void) +{ + USB_HOST_USER_AppState = USH_USR_FS_INIT; +} + +/** + * @} + */ + +/** + * @} + */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_user.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_user.h new file mode 100644 index 000000000..b12cb152a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/usb/hc32_usb_driver/usb_host_user.h @@ -0,0 +1,109 @@ +/** + ******************************************************************************* + * @file usb/usb_host_msc/source/usb_host_user.h + * @brief Header file for usb_host_user.c + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ +#ifndef __USB_HOST_USER_H__ +#define __USB_HOST_USER_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +//#include "ff.h" +#include "usb_host_core.h" +#include "usb_app_conf.h" +#include +#include "usb_host_msc_class.h" + +/** + * @addtogroup HC32F4A0_DDL_Applications + * @{ + */ + +/** + * @addtogroup USB_Host_Msc + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ +/* State Machine for the USBH_USR_ApplicationState */ +#define USH_USR_FS_INIT (0U) +#define USH_USR_FS_READLIST (1U) +#define USH_USR_FS_WRITEFILE (2U) +#define USH_USR_FS_IDLE (3U) + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ +extern usb_host_user_callback_func USR_cb; +extern uint8_t USB_HOST_USER_AppState; + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +extern void host_user_init(void); +extern void host_user_denint(void); +extern void host_user_devattached(void); +extern void host_user_devreset(void); +extern void host_user_devdisconn(void); +extern void host_user_overcurrent(void); +extern void host_user_devspddetected(uint8_t DeviceSpeed); +extern void host_user_devdescavailable(void *DeviceDesc); +extern void host_user_devaddrdistributed(void); +extern void host_user_cfgdescavailable(usb_host_cfgdesc_typedef *cfgDesc, + usb_host_itfdesc_typedef *itfDesc, + USB_HOST_EPDesc_TypeDef *epDesc); +extern void host_user_mfcstring(void *ManufacturerString); +extern void host_user_productstring(void *ProductString); +extern void host_user_serialnum(void *SerialNumString); +extern void host_user_enumcompl(void); +extern HOST_USER_STATUS host_user_userinput(void); +extern void host_user_devunsupported(void); +extern void host_user_unrecoverederror(void); +extern int host_user_msc_app(void); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /*__USB_HOST_USER_H__*/ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ + + diff --git a/Ubiquitous/XiZi_IIoT/path_kernel.mk b/Ubiquitous/XiZi_IIoT/path_kernel.mk index 745c1f064..3731ae559 100755 --- a/Ubiquitous/XiZi_IIoT/path_kernel.mk +++ b/Ubiquitous/XiZi_IIoT/path_kernel.mk @@ -402,6 +402,10 @@ KERNELPATHS += \ -I$(BSP_ROOT)/third_party_driver/CMSIS/include \ -I$(BSP_ROOT)/third_party_driver/spi/third_party_spi_lora/sx12xx/inc \ -I$(BSP_ROOT)/third_party_driver/spi/third_party_spi_lora/sx12xx/src/radio \ + -I$(BSP_ROOT)/third_party_driver/usb/hc32_usb_driver \ + -I$(BSP_ROOT)/third_party_driver/usb/hc32_usb_driver/usb_host_lib \ + -I$(BSP_ROOT)/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc \ + -I$(BSP_ROOT)/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core \ -I$(KERNEL_ROOT)/include # endif diff --git a/Ubiquitous/XiZi_IIoT/resources/include/device.h b/Ubiquitous/XiZi_IIoT/resources/include/device.h index 5c2d49a30..cf0e0a2ed 100644 --- a/Ubiquitous/XiZi_IIoT/resources/include/device.h +++ b/Ubiquitous/XiZi_IIoT/resources/include/device.h @@ -53,9 +53,11 @@ #include #include #ifdef RESOURCES_USB_HOST +#ifdef BSP_USING_STM32_USBH #include #endif #endif +#endif #ifdef RESOURCES_SERIAL #include