diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/.defconfig b/Ubiquitous/XiZi_IIoT/board/ch569w/.defconfig new file mode 100644 index 000000000..2c4f13ba0 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/.defconfig @@ -0,0 +1,293 @@ +# +# Automatically generated file; DO NOT EDIT. +# XiZi_IIoT Project Configuration +# +CONFIG_BOARD_CH569W=y +CONFIG_ARCH_RISCV=y + +# +# ch569w feature +# +CONFIG_BSP_USING_UART=y +CONFIG_BSP_USING_UART1=y +CONFIG_SERIAL_BUS_NAME_1="uart1" +CONFIG_SERIAL_DRV_NAME_1="uart1_drv" +CONFIG_SERIAL_1_DEVICE_NAME_0="uart1_dev1" + +# +# Hardware feature +# +CONFIG_RESOURCES_SERIAL=y +CONFIG_SERIAL_USING_DMA=y +CONFIG_SERIAL_RB_BUFSZ=128 + +# +# Kernel feature +# + +# +# separate compile(choose none for compile once) +# +# CONFIG_SEPARATE_COMPILE is not set +# CONFIG_COMPILER_APP is not set +# CONFIG_APP_STARTUP_FROM_SDCARD is not set +CONFIG_APP_STARTUP_FROM_FLASH=y +# CONFIG_COMPILER_KERNEL is not set + +# +# Memory Management +# +# CONFIG_KERNEL_MEMBLOCK is not set +CONFIG_MEM_ALIGN_SIZE=8 +# CONFIG_MEM_EXTERN_SRAM is not set +CONFIG_MM_PAGE_SIZE=4096 + +# +# Using small memory allocator +# +CONFIG_KERNEL_SMALL_MEM_ALLOC=y +CONFIG_SMALL_NUMBER_32B=64 +CONFIG_SMALL_NUMBER_64B=32 + +# +# Task feature +# +CONFIG_USER_APPLICATION=y +# CONFIG_TASK_ISOLATION is not set +# CONFIG_KERNEL_CAPABILITY is not set + +# +# Inter-Task communication +# +CONFIG_KERNEL_SEMAPHORE=y +CONFIG_KERNEL_MUTEX=y +CONFIG_KERNEL_EVENT=y +CONFIG_KERNEL_MESSAGEQUEUE=y +CONFIG_KERNEL_SOFTTIMER=y +CONFIG_SCHED_POLICY_RR_REMAINSLICE=y +# CONFIG_SCHED_POLICY_RR is not set +# CONFIG_SCHED_POLICY_FIFO is not set +# CONFIG_KTASK_PRIORITY_8 is not set +CONFIG_KTASK_PRIORITY_32=y +# CONFIG_KTASK_PRIORITY_256 is not set +CONFIG_KTASK_PRIORITY_MAX=32 +CONFIG_TICK_PER_SECOND=1000 +CONFIG_KERNEL_STACK_OVERFLOW_CHECK=y +CONFIG_IDLE_KTASK_STACKSIZE=1024 +CONFIG_ZOMBIE_KTASK_STACKSIZE=2048 + +# +# Kernel Console +# +CONFIG_KERNEL_CONSOLE=y +CONFIG_KERNEL_BANNER=y +CONFIG_KERNEL_CONSOLEBUF_SIZE=128 + +# +# Kernel Hook +# +# CONFIG_KERNEL_HOOK is not set + +# +# Command shell +# +CONFIG_TOOL_SHELL=y +CONFIG_SHELL_ENTER_CR=y +CONFIG_SHELL_ENTER_LF=y +CONFIG_SHELL_ENTER_CR_AND_LF=y +# CONFIG_SHELL_ENTER_CRLF is not set + +# +# Set shell user control +# +CONFIG_SHELL_DEFAULT_USER="letter" +CONFIG_SHELL_DEFAULT_USER_PASSWORD="" +CONFIG_SHELL_LOCK_TIMEOUT=10000 + +# +# Set shell config param +# +CONFIG_SHELL_TASK_STACK_SIZE=4096 +CONFIG_SHELL_TASK_PRIORITY=20 +CONFIG_SHELL_MAX_NUMBER=5 +CONFIG_SHELL_PARAMETER_MAX_NUMBER=8 +CONFIG_SHELL_HISTORY_MAX_NUMBER=5 +CONFIG_SHELL_PRINT_BUFFER=128 +CONFIG_SHELL_HELP_SHOW_PERMISSION=y +# CONFIG_SHELL_HELP_LIST_USER is not set +CONFIG_SHELL_HELP_LIST_VAR=y +# CONFIG_SHELL_HELP_LIST_KEY is not set + +# +# Kernel data structure Manage +# +CONFIG_KERNEL_QUEUEMANAGE=y +CONFIG_KERNEL_WORKQUEUE=y +CONFIG_WORKQUEUE_KTASK_STACKSIZE=2048 +CONFIG_WORKQUEUE_KTASK_PRIORITY=23 +CONFIG_QUEUE_MAX=16 +CONFIG_KERNEL_WAITQUEUE=y +CONFIG_KERNEL_DATAQUEUE=y +# CONFIG_KERNEL_CIRCULAR_AREA is not set +# CONFIG_KERNEL_AVL_TREE is not set + +# +# Kernel components init +# +CONFIG_KERNEL_COMPONENTS_INIT=y +CONFIG_ENV_INIT_KTASK_STACK_SIZE=8192 +CONFIG_KERNEL_USER_MAIN=y +CONFIG_NAME_NUM_MAX=32 +# CONFIG_KERNEL_DEBUG is not set +# CONFIG_ARCH_SMP is not set + +# +# hash table config +# +CONFIG_ID_HTABLE_SIZE=16 +CONFIG_ID_NUM_MAX=128 +# CONFIG_KERNEL_TEST is not set + +# +# Kernel Lib +# +CONFIG_LIB=y +CONFIG_LIB_POSIX=y +CONFIG_LIB_NEWLIB=y +# CONFIG_LIB_MUSLLIB is not set +# CONFIG_LIB_OTHER is not set + +# +# C++ features +# +# CONFIG_LIB_CPLUSPLUS is not set + +# +# File system +# +CONFIG_FS_VFS=y +CONFIG_VFS_USING_WORKDIR=y +CONFIG_FS_VFS_DEVFS=y +CONFIG_FS_VFS_FATFS=y +# CONFIG_FS_CH376 is not set +# CONFIG_FS_LWEXT4 is not set + +# +# Tool feature +# + +# +# OTA function +# +# CONFIG_TOOL_USING_OTA is not set + +# +# APP_Framework +# + +# +# Framework +# +CONFIG_TRANSFORM_LAYER_ATTRIUBUTE=y +CONFIG_ADD_XIZI_FEATURES=y +# CONFIG_ADD_NUTTX_FEATURES is not set +# CONFIG_ADD_RTTHREAD_FEATURES is not set +# CONFIG_SUPPORT_SENSOR_FRAMEWORK is not set +# CONFIG_SUPPORT_CONNECTION_FRAMEWORK is not set +# CONFIG_SUPPORT_KNOWING_FRAMEWORK is not set +# CONFIG_SUPPORT_CONTROL_FRAMEWORK is not set + +# +# Security +# +# CONFIG_CRYPTO is not set +# CONFIG_MBEDTLS is not set + +# +# Applications +# + +# +# config stack size and priority of main task +# +CONFIG_MAIN_KTASK_STACK_SIZE=1024 +CONFIG_MAIN_KTASK_PRIORITY=16 + +# +# test app +# +# CONFIG_USER_TEST is not set + +# +# connection app +# +# CONFIG_APPLICATION_CONNECTION is not set + +# +# control app +# + +# +# knowing app +# +# CONFIG_APPLICATION_KNOWING is not set + +# +# sensor app +# +# CONFIG_APPLICATION_SENSOR is not set +# CONFIG_USING_EMBEDDED_DATABASE_APP is not set +# CONFIG_APP_USING_WEBNET is not set +# CONFIG_APPLICATION_WEBSERVER is not set + +# +# app lib +# +CONFIG_APP_SELECT_NEWLIB=y +# CONFIG_APP_SELECT_OTHER_LIB is not set + +# +# lib using cJSON +# +# CONFIG_LIB_USING_CJSON is not set + +# +# lib using queue +# +# CONFIG_LIB_USING_QUEUE is not set + +# +# lib using LVGL +# +# CONFIG_LIB_LV is not set + +# +# lvgl image display parameter settings +# +CONFIG_LVGL_WIDTH=320 +CONFIG_LVGL_HEIGHT=320 + +# +# lib using embedded_database +# +# CONFIG_USING_EMBEDDED_DATABASE is not set + +# +# lib using LoRaWan +# +# CONFIG_LIB_USING_LORAWAN is not set + +# +# lib using MQTT +# +# CONFIG_LIB_USING_MQTT is not set + +# +# lib using JerryScript +# +# CONFIG_LIB_USING_JERRYSCRIPT is not set + +# +# lib using SQLite +# +# CONFIG_LIB_USING_SQLITE is not set diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/README.md b/Ubiquitous/XiZi_IIoT/board/ch569w/README.md index 89e770521..1ab572cf3 100644 --- a/Ubiquitous/XiZi_IIoT/board/ch569w/README.md +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/README.md @@ -1,78 +1,75 @@ -# 1. 简介 - -| 硬件 | 描述 | -| --------- | ----------------------------------------- | -| 芯片型号 | CH569W | -| CPU | 单核RISC-V3A | -| 主频 | 120MHz | -| 片内SRAM | 32/64/96KB 可配置的 128 位宽 SRAM(RAMX) | -| 片内FLASH | 448KB 用户应用程序存储区 CodeFlash | -| 外设 | UART等 | - -# 2. 克隆代码 - -将XiUOS的源代码克隆下来: - -```bash -git clone https://gitlink.org.cn/xuos/xiuos.git -``` - -# 3. 下载编译工具链 - -编译环境:Ubuntu 20.04.6 LTS - -编译工具链:riscv-none-embed-gcc(xpack-riscv-none-embed-gcc-8.2.0-3.1) - -编译工具链可到Github进行下载:https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack/releases/download/v8.2.0-3.1/xpack-riscv-none-embed-gcc-8.2.0-3.1-linux-x64.tgz - -下载完成后将其移动到`/opt`目录下,并进行解压: - -```bash -sudo tar -xvzf xpack-riscv-none-embed-gcc-8.2.0-3.1-linux-x64.tgz -``` - -# 4. 编译 - -## 方式1(推荐) - -可以在`Ubiquitous/XiZi_IIoT`目录下创建文件`script.sh`,内容如下: - -```sh -#! /bin/env sh -export CROSS_COMPILE=/opt/xPacks/riscv-none-embed-gcc/8.2.0-3.1/bin/riscv-none-embed- -make BOARD=ch569w distclean # 将之前的编译生成文件清空 -make BOARD=ch569w menuconfig -make BOARD=ch569w -``` - -创建之后,在命令行移动到`XiZi-IIOT`目录下,键入`./script`运行该脚本。 - -经过Kconfig配置、编译后,即可在`Ubiquitous/XiZi_IIoT/build`目录中生成`XiZi-ch569w.bin`文件,将该文件拷贝至Windows侧待下一步进行烧录。 - -> [!CAUTION] -> -> 如果`make BOARD=ch569w menuconfig`显示【无法找到`kconfig-mconf`】,需要先安装`ncurses-devel`和`kconfig-mconf`,如下: -> -> ```bash -> sudo apt install libncurses5-dev kconfig-frontends - - - -# 5. 烧录 - -1. 沁恒微电子官网下载 WCHISPTool.exe 工具进行 bin 文件下载到芯片 flash 的操作。CH569W 芯片需要进入下载模式才能使用 ISP 工具下载代码,一般使用 USB 方式下载代码最为方便。 -2. 将 CH569W 评估板使用 USB 插头对插头线和计算机连接起来。如图,打开 ISP 下载工具,芯片信号选择 CH569,下载方式选择 USB,将 CH569W 评估板断电,然后将下载配置脚(出厂默认为 PA5,原理图上的HD0)接地后对评估板上电,此时 ISP 工具的 USB 设备列表中将显示新连上来的 CH569W 芯片。最后点击“下载”,即可使程序下载到评估版上的主芯片。 - -image_shaolukaifabanpaizhao - -image_shaoluruanjianjietu - - - -# 6. 启动 - -烧录完成后,并且将串口连接至电脑。 - -将评估板上电重新,即可看到操作系统启动的信息,如下: - +# 1. 简介 + +| 硬件 | 描述 | +| --------- | ------------------------------------------------- | +| 芯片型号 | CH569W | +| CPU | 单核RISC-V3A | +| 主频 | 120MHz | +| 片内SRAM | 32/64/96KB 可配置的 128 位宽 SRAM(RAMX) | +| 片内FLASH | 448KB 用户应用程序存储区 CodeFlash | +| 外设 | 串口、SPI FLASH、SerDes网络、USBD CDC、Watchdog等 | + +# 2. 克隆代码 + +将XiUOS的源代码克隆下来: + +```bash +git clone https://gitlink.org.cn/xuos/xiuos.git +``` + +# 3. 下载编译工具链 + +编译环境:Ubuntu 20.04.6 LTS + +编译工具链:riscv-none-embed-gcc(xpack-riscv-none-embed-gcc-8.2.0-3.1) + +编译工具链可到Github进行下载:https://github.com/xpack-dev-tools/riscv-none-embed-gcc-xpack/releases/download/v8.2.0-3.1/xpack-riscv-none-embed-gcc-8.2.0-3.1-linux-x64.tgz + +下载完成后将其移动到`/opt`目录下,并进行解压: + +```bash +sudo tar -xvzf xpack-riscv-none-embed-gcc-8.2.0-3.1-linux-x64.tgz +``` + +# 4. 编译 + +## 方式1(推荐) + +可以在`Ubiquitous/XiZi_IIoT`目录下创建文件`script.sh`,内容如下: + +```sh +#! /bin/env sh +export CROSS_COMPILE=/opt/xPacks/riscv-none-embed-gcc/8.2.0-3.1/bin/riscv-none-embed- +make BOARD=ch569w distclean # 将之前的编译生成文件清空 +make BOARD=ch569w menuconfig +make BOARD=ch569w +``` + +创建之后,在命令行移动到`XiZi-IIOT`目录下,键入`./script.sh`运行该脚本。 + +经过Kconfig配置、编译后,即可在`Ubiquitous/XiZi_IIoT/build`目录中生成`XiZi-ch569w.bin`文件,将该文件拷贝至Windows本地电脑,用于下一步烧录。 + +如果`make BOARD=ch569w menuconfig`显示【无法找到`kconfig-mconf`】,需要先安装`ncurses-devel`和`kconfig-mconf`,如下: + +```bash +sudo apt install libncurses5-dev kconfig-frontends +``` + +# 5. 烧录 + +1. 沁恒微电子官网下载 WCHISPTool.exe 工具进行 bin 文件下载到芯片 flash 的操作。CH569W 芯片需要进入下载模式才能使用 ISP 工具下载代码,一般使用 USB 方式下载代码最为方便。 +2. 将 CH569W 评估板使用 USB 插头对插头线和计算机连接起来。如图,打开 ISP 下载工具,芯片信号选择 CH569,下载方式选择 USB,将 CH569W 评估板断电,然后将下载配置脚(出厂默认为 PA5,原理图上的HD0)接地后对评估板上电,此时 ISP 工具的 USB 设备列表中将显示新连上来的 CH569W 芯片。最后点击“下载”,即可使程序下载到评估版上的主芯片。 + +image_shaolukaifabanpaizhao + +image_shaoluruanjianjietu + + + +# 6. 启动 + +烧录完成后,并且将串口连接至电脑。 + +将评估板上电重新,即可看到操作系统启动的信息,如下: + ![image_xitongqidongrizhi](imgs/image_xitongqidongrizhi.png) \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/board.c b/Ubiquitous/XiZi_IIoT/board/ch569w/board.c index 03c951fa6..293141fa1 100644 --- a/Ubiquitous/XiZi_IIoT/board/ch569w/board.c +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/board.c @@ -29,11 +29,10 @@ void InitBoardHardware() { - SystemInit(FREQ_SYS); Delay_Init(FREQ_SYS); - SysTick_Config(FREQ_SYS / TICK_PER_SECOND); + SysTick_Config(FREQ_SYS / 8 / TICK_PER_SECOND); PFIC_EnableIRQ(SWI_IRQn); /* initialize memory system */ @@ -45,6 +44,11 @@ void InitBoardHardware() KPrintf("\nconsole init completed.\n"); #endif +#ifdef BSP_USING_SPI + int InitHwSpi(void); + InitHwSpi(); +#endif + KPrintf("memory address range: [0x%08x - 0x%08x] ssize: %x\n", (x_ubase)MEMORY_START_ADDRESS, (x_ubase)MEMORY_END_ADDRESS, MEMORY_STACK_SIZE); diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/config.mk b/Ubiquitous/XiZi_IIoT/board/ch569w/config.mk index 6db9c93c7..6a4afcfce 100644 --- a/Ubiquitous/XiZi_IIoT/board/ch569w/config.mk +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/config.mk @@ -14,5 +14,10 @@ export DEFINES := -DDEBUG=1 export ARCH = risc-v export MCU = CH569W +ifeq ($(CONFIG_BSP_USING_SERDES), y) +export LINK_BOARD += $(KERNEL_ROOT)/board/ch569w/third_party_driver/serdes/libSERDES.a +endif - +ifeq ($(CONFIG_BSP_USING_USBD), y) +export LINK_BOARD += $(KERNEL_ROOT)/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB30/libCH56x_USB30_device_lib.a +endif diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/imgs/image_xitongqidongrizhi.png b/Ubiquitous/XiZi_IIoT/board/ch569w/imgs/image_xitongqidongrizhi.png index 2813913a8..9b0265fd3 100644 Binary files a/Ubiquitous/XiZi_IIoT/board/ch569w/imgs/image_xitongqidongrizhi.png and b/Ubiquitous/XiZi_IIoT/board/ch569w/imgs/image_xitongqidongrizhi.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/Kconfig b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/Kconfig index 6fdbc2813..1177c855b 100644 --- a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/Kconfig @@ -5,3 +5,28 @@ menuconfig BSP_USING_UART if BSP_USING_UART source "$BSP_DIR/third_party_driver/uart/Kconfig" endif + +menuconfig BSP_USING_SPI + bool "Using SPI device" + default y + if BSP_USING_SPI + source "$BSP_DIR/third_party_driver/spi/Kconfig" + endif + +menuconfig BSP_USING_SERDES + bool "Using serdes device" + default y + if BSP_USING_SERDES + source "$BSP_DIR/third_party_driver/serdes/Kconfig" + endif + +menuconfig BSP_USING_USB + bool "Using usb device" + default y + if BSP_USING_USB + source "$BSP_DIR/third_party_driver/usb/Kconfig" + endif + +menuconfig BSP_USING_WDT + bool "Using watchdog timer device" + default n diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/Makefile b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/Makefile index 7b5f34c94..0d445e3a7 100644 --- a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/Makefile @@ -1,7 +1,25 @@ SRC_DIR := Peripheral +SRC_DIR += sys + ifeq ($(CONFIG_BSP_USING_UART),y) SRC_DIR += uart endif +ifeq ($(CONFIG_BSP_USING_SPI),y) + SRC_DIR += spi +endif + +ifeq ($(CONFIG_BSP_USING_SERDES),y) + SRC_DIR += serdes +endif + +ifeq ($(CONFIG_BSP_USING_USB),y) + SRC_DIR += usb +endif + +ifeq ($(CONFIG_BSP_USING_WDT),y) + SRC_DIR += wdt +endif + include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/Peripheral/inc/CH56xSFR.h b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/Peripheral/inc/CH56xSFR.h index 8555a966d..6bbaf7021 100644 --- a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/Peripheral/inc/CH56xSFR.h +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/Peripheral/inc/CH56xSFR.h @@ -1341,6 +1341,7 @@ extern "C" { #ifndef TABLE_IRQN typedef enum IRQn { + PWMX_OFFn = 0, Reset_IRQn = 1, NMI_IRQn = 2, /*!< Non Maskable Interrupt */ EXC_IRQn = 3, /*!< Exceptions Interrupt */ @@ -1367,6 +1368,7 @@ typedef enum IRQn ETH_IRQn = 34, PMT_IRQn = 35, ECDC_IRQn = 36, + END_OF_IRQn } IRQn_Type; #endif diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/README.md b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/README.md new file mode 100644 index 000000000..09e8feab0 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/README.md @@ -0,0 +1,61 @@ +# 1. 模块编译配置 + +开发板支持外设驱动:UART、SPI FLASH、SerDes网络、USBD CDC、Watchdog。 + +默认配置文件路径:`xiuos/Ubiquitous/XiZi_IIoT$ ll board/ch569w/.defconfig` + +可以通过命令`make BOARD=ch569w menuconfig` ,查看`ch569w feature`的默认配置。 + +![make-menuconfig.png](imgs/make-menuconfig.png) + +# 2. 模块测试用例 + +下面介绍各模块的测试方法。 + +## 2.1 UART + +UART用于串口打印,和shell命令输入。 + +测试方法,查看设备启动日志,以及输入命令。 + +## 2.2 SPI FLASH + +开发板的spi没有外部接口,是连接的flash芯片。测试通过spi对flash的读写。 + +串口执行:`SpiFlashTest` + +![SpiFlashTest.png](imgs/SpiFlashTest.png) + +## 2.3 SerDes + +串并互转控制器及收发器(SerDes)。系统内置了支持信号隔离和远距离传输的 SerDes 模块,支持 1.2Gbps 高速差分信号(GXM/GXP +引脚),可以通过光纤模块或网线中的一个差分对等传输媒体,进行远距离数据传输。 + +开发板上SERDES为半双工接口,仅单向传输使用。需要两个CH569设备通过SerDes进行通信。 + +SerDes测试需要先执行`SerdesRxTest`,等到SerdesRx打印初始化成功后,在另有一个设备上执行`SerdesTxTest`。 + +![SerdesTestRx.png](imgs/SerdesTestRx.png) + +![SerdesTxTest.png](imgs/SerdesTxTest.png) + +## 2.4 USBD CDC + +USBD CDC(USB Device Communication Device Class)是一种将 USB 设备模拟为串口(虚拟串口)的功能实现,允许设备通过 USB 与主机进行串行数据通信。 + +串口输入命令:`UsbdCdcTest`,在电脑的设备管理器查看,出现新增COM口。 + +![UsbdCdcTestCmd.png](imgs/UsbdCdcTestCmd.png) + +![UsbdCdcTestUSB20.png](imgs/UsbdCdcTestUSB20.png) + + + +## 2.5 Watchdog + +看门狗测试,需要编译时选择打开watchdog功能。 + +系统在后台运行wdt,通过命令`WdtTest`,停止喂狗,触发系统重启。 + +![WdtTest.png](imgs/WdtTest.png) + diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/imgs/SerdesTestRx.png b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/imgs/SerdesTestRx.png new file mode 100644 index 000000000..f93f60366 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/imgs/SerdesTestRx.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/imgs/SerdesTxTest.png b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/imgs/SerdesTxTest.png new file mode 100644 index 000000000..704915edc Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/imgs/SerdesTxTest.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/imgs/SpiFlashTest.png b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/imgs/SpiFlashTest.png new file mode 100644 index 000000000..48787feda Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/imgs/SpiFlashTest.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/imgs/UsbdCdcTestCmd.png b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/imgs/UsbdCdcTestCmd.png new file mode 100644 index 000000000..d5c62e3a0 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/imgs/UsbdCdcTestCmd.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/imgs/UsbdCdcTestUSB20.png b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/imgs/UsbdCdcTestUSB20.png new file mode 100644 index 000000000..48ab50459 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/imgs/UsbdCdcTestUSB20.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/imgs/WdtTest.png b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/imgs/WdtTest.png new file mode 100644 index 000000000..fbae2c308 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/imgs/WdtTest.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/imgs/make-menuconfig.png b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/imgs/make-menuconfig.png new file mode 100644 index 000000000..cdf478cb6 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/imgs/make-menuconfig.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/CH56x_usb20.h b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/CH56x_usb20.h new file mode 100644 index 000000000..c9eebe5f7 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/CH56x_usb20.h @@ -0,0 +1,56 @@ +/********************************** (C) COPYRIGHT ******************************* +* File Name : CH56x_usb20.h +* Author : WCH +* Version : V1.2 +* Date : 2024/07/10 +* Description : +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef USB20_CH56X_USB20_H_ +#define USB20_CH56X_USB20_H_ +#include "CH56x_common.h" +#ifdef __cplusplus +extern "C" { +#endif + +/* Global define */ +#define U20_MAXPACKET_LEN 512 +#define U20_UEP0_MAXSIZE 64 +#define PID_OUT 0 +#define PID_SOF 1 +#define PID_IN 2 + +/* Global Variable */ +typedef struct __attribute__((packed)) +{ + UINT8 dev_speed; + UINT8 dev_addr; + UINT8 dev_config_value; + UINT8 dev_sleep_status; + UINT8 dev_enum_status; +}DevInfo_Typedef; + + +extern const UINT8 hs_device_descriptor[]; +extern const UINT8 hs_config_descriptor[]; +extern const UINT8 hs_string_descriptor0[]; +extern const UINT8 hs_string_descriptor1[]; +extern const UINT8 hs_string_descriptor2[]; +extern const UINT8 hs_bos_descriptor[]; + +/* Function declaration */ +void USB20_Device_Init ( FunctionalState sta ); +UINT16 U20_NonStandard_Request_Deal(); +UINT16 U20_Standard_Request_Deal(); +UINT16 U20_Endp0_IN_Callback(void); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/CH56x_usb30.h b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/CH56x_usb30.h new file mode 100644 index 000000000..8ef6d0217 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/CH56x_usb30.h @@ -0,0 +1,61 @@ +/********************************** (C) COPYRIGHT ******************************* +* File Name : CH56x_usb30.h +* Author : WCH +* Version : V1.2 +* Date : 2024/07/10 +* Description : +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef USB30_CH56X_USB30_H_ +#define USB30_CH56X_USB30_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "CH56x_common.h" + + +/* Global define */ +#define endpoint_1_OUT_burst_level 1 +#define endpoint_1_IN_burst_level 1 +#define endpoint_2_OUT_burst_level 1 +#define endpoint_2_IN_burst_level 1 + + +#define SIZE_DEVICE_DESC 18 +#define SIZE_CONFIG_DESC 85 +#define SIZE_STRING_LANGID 4 +#define SIZE_STRING_VENDOR 8 +#define SIZE_STRING_PRODUCT 38 +#define SIZE_STRING_SERIAL 22 +#define SIZE_BOS_DESC 22 +#define SIZE_STRING_OS 18 + +#define LINK_STA_1 (1<<0) +#define LINK_STA_3 (1<<2) +/* Global Variable */ +extern __attribute__ ((aligned(16))) UINT8 endp0RTbuff[512] __attribute__((section(".DMADATA"))); +extern __attribute__ ((aligned(16))) UINT8 endp1RTbuff[4096] __attribute__((section(".DMADATA"))); +extern __attribute__ ((aligned(16))) UINT8 endp2Rxbuff[4096] __attribute__((section(".DMADATA"))); +extern __attribute__ ((aligned(16))) UINT8 endp2Txbuff[4096] __attribute__((section(".DMADATA"))); + + +extern UINT8V Link_Sta; + +/* Function declaration */ +void USB30D_init(FunctionalState sta); +void TMR0_IRQHandler() __attribute__((interrupt())); +void LINK_IRQHandler() __attribute__((interrupt())); +void USBSS_IRQHandler(void) __attribute__((interrupt())); //USB3.0 interrupt service + +#ifdef __cplusplus +} +#endif + +#endif /* USER_USB30_DESC_H_ */ + + diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/CH56x_usb30_LIB.h b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/CH56x_usb30_LIB.h new file mode 100644 index 000000000..95c04564b --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/CH56x_usb30_LIB.h @@ -0,0 +1,482 @@ +/********************************** (C) COPYRIGHT ******************************* +* File Name : CH56x_usb30_lib.h +* Author : WCH +* Version : V1.2 +* Date : 2024/07/10 +* Description : +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef USB30_CH56X_USB30_LIB_H_ +#define USB30_CH56X_USB30_LIB_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "CH56x_common.h" + +// link CFG +#define TERM_EN (1<<1) +#define PIPE_RESET (1<<3) +#define LFPS_RX_PD (1<<5) +#define CFG_EQ_EN (1<<6) +#define TX_SWING (1<<7) +#define DEEMPH_CFG (1<<8) + +#define POWER_MODE_0 ((UINT32)0x00000000) +#define POWER_MODE_1 ((UINT32)0x00000001) +#define POWER_MODE_2 ((UINT32)0x00000002) +#define POWER_MODE_3 ((UINT32)0x00000003) + +#define LINK_PRESENT (1<<0) +#define RX_WARM_RESET ((UINT32)1<<1) + +#define LINK_TXEQ (1<<6) +#define GO_DISABLED (1<<4) +#define POLLING_EN (1<<12) + +#define TX_HOT_RESET ((UINT32)1<<16) +#define RX_HOT_RESET ((UINT32)1<<24) + +#define TX_WARM_RESET ((UINT32)1<<8) +#define TX_Ux_EXIT ((UINT32)1<<9) +// link int flag +#define LINK_RDY_FLAG (1<<0) +#define LINK_RECOV_FLAG (1<<1) +#define LINK_INACT_FLAG (1<<2) +#define LINK_DISABLE_FLAG (1<<3) +#define LINK_GO_U3_FLAG (1<<4) +#define LINK_GO_U2_FLAG (1<<5) +#define LINK_GO_U1_FLAG (1<<6) +#define LINK_GO_U0_FLAG (1<<7) +#define LINK_U3_WAKE_FLAG (1<<8) +#define LINK_Ux_REJECT_FLAG (1<<9) +#define TERM_PRESENT_FLAG (1<<10) +#define LINK_TXEQ_FLAG (1<<11) +#define LINK_Ux_EXIT_FLAG (1<<12) +#define WARM_RESET_FLAG (1<<13) +#define U3_WAKEUP_FLAG (1<<14) +#define HOT_RESET_FLAG (1<<15) +#define LINK_RX_DET_FLAG (1<<20) + +#define EP0_R_EN (1<<0) +#define EP1_R_EN (1<<1) +#define EP2_R_EN (1<<2) +#define EP3_R_EN (1<<3) +#define EP4_R_EN (1<<4) +#define EP5_R_EN (1<<5) +#define EP6_R_EN (1<<6) +#define EP7_R_EN (1<<7) + +#define EP0_T_EN (1<<8) +#define EP1_T_EN (1<<9) +#define EP2_T_EN (1<<10) +#define EP3_T_EN (1<<11) +#define EP4_T_EN (1<<12) +#define EP5_T_EN (1<<13) +#define EP6_T_EN (1<<14) +#define EP7_T_EN (1<<15) + +#define USB_FORCE_RST (1<<2) +#define USB_ALL_CLR (1<<1) +// LMP +#define LMP_HP (0) +#define LMP_SUBTYPE_MASK (0xf<<5) +#define SET_LINK_FUNC (0x1<<5) +#define U2_INACT_TOUT (0x2<<5) +#define VENDOR_TEST (0x3<<5) +#define PORT_CAP (0x4<<5) +#define PORT_CFG (0x5<<5) +#define PORT_CFG_RES (0x6<<5) + +#define LINK_SPEED (1<<9) + +#define NUM_HP_BUF (4<<0) +#define DOWN_STREAM (1<<16) +#define UP_STREAM (2<<16) +#define TIE_BRK (1<<20) + +/**********device status***********/ +typedef enum _DEVICE_STATE +{ + UNCONNECTED, + ATTACHED, + POWERED, + SUSPENDED, + ADDRESSED, + CONFIGURED +} DEVICE_STATE; + +/**********standard request command***********/ +typedef struct __PACKED +{ + UINT8 bRequestType; + UINT8 bRequest; + UINT8 wValueL; + UINT8 wValueH; + UINT8 wIndexL; + UINT8 wIndexH; + UINT16 wLength; +} *PUSB_SETUP; + +#define UsbSetupBuf ((PUSB_SETUP)endp0RTbuff)//endpoint 0 + + +#define ENDP0_MAXPACK 512 + +// status response +#define NRDY 0 +#define ACK 0x01 +#define STALL 0x02 +#define INVALID 0x03 +// number of NUMP +#define NUMP_0 0x00 +#define NUMP_1 0x01 +#define NUMP_2 0x02 +#define NUMP_3 0x03 +#define NUMP_4 0x04 +#define NUMP_5 0x05 +#define NUMP_6 0x06 +/* USB endpoint direction */ +#define OUT 0x00 +#define IN 0x80 +/* USB endpoint serial number */ +#define ENDP_0 0x00 +#define ENDP_1 0x01 +#define ENDP_2 0x02 +#define ENDP_3 0x03 +#define ENDP_4 0x04 +#define ENDP_5 0x05 +#define ENDP_6 0x06 +#define ENDP_7 0x07 + +#define USB_DESCR_TYP_BOS 0x0f +#define USB_DESCR_UNSUPPORTED 0xffff +#define INVALID_REQ_CODE 0xFF + +/* string descriptor type */ +#ifndef USB_DESCR_STRING + #define USB_DESCR_LANGID_STRING 0x00 + #define USB_DESCR_VENDOR_STRING 0x01 + #define USB_DESCR_PRODUCT_STRING 0x02 + #define USB_DESCR_SERIAL_STRING 0x03 + #define USB_DESCR_OS_STRING 0xee +#endif + + +extern void USB30_Device_forceclr(); +/******************************************************************************* + * @fn USB30_Device_Init + * + * @brief USB3.0 Device initialization + * + * @return None + */ +extern UINT8 USB30_Device_Init(void); + +/******************************************************************************* + * @fn USB30_Lib_Getversion + * + * @brief USB3.0 Device Lib initialization + * + * @return None + */ +extern UINT8 USB30_Lib_Getversion(void); + +/******************************************************************************* + * @fn USB30_ISO_Setendp + * + * @brief Configure synchronization endpoint + * + * @return None + */ +extern void USB30_ISO_Setendp(UINT8 num,FunctionalState Status ); + +/******************************************************************************* + * @fn USB30_ISO_Setdelay( UINT32 dly ) + * + * @brief Set synchronization delay time + * + * @param dly - delay time + * + * @return None + */ +extern void USB30_ISO_Setdelay( UINT32 dly ); + +/******************************************************************************* + * @fn USB30_ITP_Enable + * + * @brief USB ITP enable + * + * @param Status - enable/disable + * + * @return None + */ +extern void USB30_ITP_Enable(FunctionalState Status); + +/******************************************************************************* + * @fn USB30_OUT_Status + * + * @brief Get the length of endpoint received data + * + * @param endp - Endpoint number + * nump - The remaining number of packets that can be received by the endpoint + * len - The length of data received by the endpoint. For burst transmission, + * it indicates the length of the last packet received by the endpoint. + * status - Indicates whether the host still has data packets to be distributed, + * 1 - the end of the burst received non-full packets, + * 0 - the host still has data packets to be distributed. + * + * @return None + */ +extern void USB30_OUT_Status(UINT8 endp,UINT8 *nump,UINT16 *len,UINT8 *status); + +/******************************************************************************* + * @fn USB30_OUT_Set + * + * @brief Endpoint receive settings + * + * @param endp - Set endpoint number + * nump - The remaining number of packets that can be received by the endpoint + * status - Endpoint Status :0-NRDY,1-ACK,2-STALL + * + * @return None + */ +extern void USB30_OUT_Set(UINT8 endp,UINT8 status,UINT8 nump); + +/******************************************************************************* + * @fn USB30_OUT_ClearIT + * + * @brief Clear the OUT transaction completion interrupt, and only keep the package serial number + * + * @param endp - Set endpoint number + * + * @return None + */ +extern void USB30_OUT_ClearIT(UINT8 endp); + +/******************************************************************************* + * @fn USB30_OUT_ClearPendingIT + * + * @brief Clear the OUT transaction completion interrupt, and keep other endpoint configurations + * + * @param endp - Set endpoint number + * + * @return None + */ +extern void USB30_OUT_ClearPendingIT(UINT8 endp); + +/******************************************************************************* + * @fn USB30_OUT_ITflag + * + * @brief Get the OUT transaction completion interrupt flag + * + * @param endp - Set endpoint number + * + * @return 1 - interrupt 0 - non-interrupt + */ +extern UINT8 USB30_OUT_ITflag(UINT8 endp); + +/******************************************************************************* + * @fn USB30_IN_Set + * + * @brief Endpoint sending settings + * + * @param endp - endpoint number + * lpf - end of burst: 1-enable 0-disable + * nump - The number of packets that the endpoint can send + * status - endpoint status: 0-NRDY,1-ACK,2-STALL + * TxLen - The data length of the last packet sent by the endpoint + * + * @return None + */ +extern void USB30_IN_Set(UINT8 endp,FunctionalState lpf,UINT8 status,UINT8 nump,UINT16 TxLen); + +/******************************************************************************* + * @fn USB30_IN_ClearPendingIT + * + * @brief Clear the IN transaction completion interrupt and keep the other configurations of the endpoint + * + * @param endp - endpoint number + * + * @return None + */ +extern void USB30_IN_ClearPendingIT(UINT8 endp); + +/******************************************************************************* + * @fn USB30_IN_ClearIT + * + * @brief Clear the IN transaction interrupt and the remaining status of the endpoint, + * and only retain the packet serial number. + * + * @param endp - endpoint number + * + * @return None + */ +extern void USB30_IN_ClearIT(UINT8 endp); + +/******************************************************************************* + * @fn USB30_IN_ITflagT + * + * @brief Get IN transaction completion interrupt flag + * + * @param endp - Set endpoint number + * + * @return None + */ +extern UINT8 USB30_IN_ITflag(UINT8 endp); + +/******************************************************************************* + * @fn USB30_IN_Nump + * + * @brief Get the remaining number of packets to be sent by the endpoint + * + * @param endp - endpoint number + * + * @return Remaining number of packets to be sent + */ +extern UINT8 USB30_IN_Nump(UINT8 endp); + +/******************************************************************************* + * @fn USB30_Send_ERDY + * + * @brief send ERDY packet + * + * @param endp - endpoint number + * nump - Number of packets received or sent by the endpoint + * + * @return None + */ +extern void USB30_Send_ERDY(UINT8 endp,UINT8 nump); + +/******************************************************************************* + * @fn USB30_Device_Setaddress + * + * @brief Set device address + * + * @param address - device address + * + * @return None + */ +extern void USB30_Device_Setaddress( UINT32 address ); + +/******************************************************************************* + * @fn USB30_IN_Nump + * + * @brief Get the remaining number of packets to be sent by the endpoint + * + * @return Control the length of data sent by the host when the transmission data stage is OUT + */ +extern UINT16 USB30_Setup_OutData(void); + +/******************************************************************************* + * @fn USB30_IRQHandler + * + * @brief USB30_IRQHandler + * + * @return None + */ +extern void USB30_IRQHandler(); + +/******************************************************************************* + * @fn USB30_StandardReq + * + * @brief USB device mode standard request command processing + * + * @return The length of data sent by the host request device + */ +extern UINT16 USB30_StandardReq(); + +/******************************************************************************* + * @fn USB30_NonStandardReq + * + * @brief USB device mode non-standard request command processing + * + * @return The length of data sent by the host request device + */ +extern UINT16 USB30_NonStandardReq(); + +/******************************************************************************* + * @fn EP0_IN_Callback + * + * @brief endpoint 0 IN Transfer completion callback function + * + * @return Data length + */ +extern UINT16 EP0_IN_Callback(); + +/******************************************************************************* + * @fn EP0_OUT_Callback + * + * @brief endpoint 0 OUT Transfer completion callback function + * + * @return None + */ +extern UINT16 EP0_OUT_Callback(); + +/******************************************************************************* + * @fn USB30_Setup_Status + * + * @brief Control transmission status stage + * + * @return None + */ +extern void USB30_Setup_Status(); + +/******************************************************************************* + * @fn USB30_ITP_Callback + * + * @brief ITP Callback function + * + * @return None + */ +extern void USB30_ITP_Callback(UINT32 ITPCounter); + +/******************************************************************************* + * @fn USB30_switch_pwr_mode + * + * @brief switch USB3.0 Power mode + * + * @return None + */ +extern void USB30_Switch_Powermode( UINT8 pwr_mode ); + +/******************************************************************************* + * @fn EPn_IN_Callback() + * + * @brief endpointN IN transaction callback function + * + * @return None + */ +extern void EP1_IN_Callback(void); +extern void EP2_IN_Callback(void); +extern void EP3_IN_Callback(void); +extern void EP4_IN_Callback(void); +extern void EP5_IN_Callback(void); +extern void EP6_IN_Callback(void); +extern void EP7_IN_Callback(void); + +/******************************************************************************* + * @fn EPn_IN_Callback() + * + * @brief endpointN OUT transaction callback function + * + * @return None + */ +extern void EP1_OUT_Callback(void); +extern void EP2_OUT_Callback(void); +extern void EP3_OUT_Callback(void); +extern void EP4_OUT_Callback(void); +extern void EP5_OUT_Callback(void); +extern void EP6_OUT_Callback(void); +extern void EP7_OUT_Callback(void); + +#ifdef __cplusplus +} +#endif + +#endif /* USB30_CH56X_USB30_LIB_H_ */ + diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/cdc.h b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/cdc.h new file mode 100644 index 000000000..107d17f02 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/cdc.h @@ -0,0 +1,27 @@ +/********************************** (C) COPYRIGHT ******************************* +* File Name : cdc.h +* Author : WCH +* Version : V1.2 +* Date : 2024/07/10 +* Description : +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#ifndef CDC_CDC_H_ +#define CDC_CDC_H_ + + +extern volatile UINT16 USBByteCount; +extern volatile UINT16 USBBufOutPoint; +extern volatile UINT8 UploadPoint2_Busy; +extern volatile UINT8 DownloadPoint2_Busy; +extern volatile UINT16 Uart_Sendlenth; + +void CDC_Uart_Init( UINT32 baudrate ); +void TMR2_TimerInit1( void ); +void CDC_Uart_Deal( void ); +void CDC_Variable_Clear(void); + +#endif /* CDC_CDC_H_ */ diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/connect_serdes.h b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/connect_serdes.h new file mode 100644 index 000000000..4d125cc3b --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/connect_serdes.h @@ -0,0 +1,196 @@ + +#ifndef __CONNECT_SERDES_H__ +#define __CONNECT_SERDES_H__ + + + +#ifdef __cplusplus +extern "C" { +#endif + +#include "CH56xSFR.h" +#include "core_riscv.h" + +# + +#define SDS_ALIGN_EN (1<<18) +#define SDS_CONT_EN (1<<17) +#define SDS_POWR_UP (1<<16) +#define SDS_TX_PU (1<<15) +#define SDS_RX_PU (1<<14) +#define SDS_PLL_PU (1<<13) +#define SDS_PLL_DIV (18<<8) // 60*(DIV+2)MHz +#define SDS_PLL_1_2G (18<<8) // 60*(18+2)MHz +#define SDS_PLL_900M (13<<8) // 60*(13+2)MHz +#define SDS_PLL_600M ( 8<<8) // 60*(8+2)MHz + +#define SDS_DMA_EN 1<<7 +#define SDS_TX_EN 1<<6 +#define SDS_RX_EN 1<<5 +#define SDS_RX_POLAR 1<<4 +#define SDS_INT_BUSY_EN 1<<3 +#define PHY_RESET 1<<2 +#define LINK_RESET 1<<1 +#define SDS_ALL_CLR 1<<0 + +#define SDS_LINK_INIT 1<<16 +#define SDS_TX_START ((uint32_t)1<<17) +#define SDS_BUF_MODE 1<<18 + +#define SDS_PHY_RDY_EN 1<<0 +#define SDS_TX_INT_EN 1<<1 +#define SDS_RX_ERR_EN 1<<1 +#define SDS_RX_INT_EN 1<<2 +#define SDS_FIFO_OV_EN 1<<3 +#define SDS_COMMA_INT_EN 1<<5 +#define ALL_INT_TYPE 47 + +#define SDS_PHY_RDY_FLG 1<<0 +#define SDS_TX_INT_FLG 1<<1 +#define SDS_RX_INT_FLG 1<<2 +#define SDS_FIFO_OV_FLG 1<<3 +#define SDS_COMMA_INT_FLG 1<<5 +#define ALL_INT_FLG 47 + +#define SDS_SEQ_MATCH 1<<17 +#define SDS_RX_CRC_OK 1<<18 +#define SDS_PLL_READY 1<<19 +#define SDS_TX_READY 1<<20 + +#define SDS_RX_BUF 1<<24 +#define SDS_TX_BUF 1<<28 + +#define SDS_TX_NUMP_1 1<<20 +#define SDS_TX_NUMP_2 2<<20 +#define SDS_TX_NUMP_3 3<<20 +#define SDS_TX_NUMP_4 4<<20 + +/******************************************************************************* +* Function Name : Serdes_Tx_Init +* Description : Serdes configuration of hardware in Tx mode +* Input : None +* Return : None +*******************************************************************************/ +extern void Serdes_Tx_Init(void); + +/******************************************************************************* +* Function Name : Serdes_Rx_init +* Description : Serdes configuration of hardware in Rx mode +* Input : None +* Return : None +*******************************************************************************/ +extern UINT8 Serdes_Rx_Init(UINT32 cnt); + +/******************************************************************************* +* Function Name : DMA_Tx_CFG +* Description : Configure DMA transmitting mode +* Input : DMAaddr: DMA starting address +* Tx_len : length of transmitting data once +* custom_number: customized data using for data checking +* Return : None +*******************************************************************************/ +extern void DMA_Tx_CFG( UINT32 DMAaddr, UINT32 Tx_len, UINT32 custom_number); + +/******************************************************************************* +* Function Name : DoubleDMA_Rx_CFG +* Description : Configure double DMA receiving mode +* Input : DMA0_addr: DMA0 starting address + DMA1_addr: DMA1 starting address +* Return : None +*******************************************************************************/ +extern void DoubleDMA_Rx_CFG( UINT32 DMA0_addr , UINT32 DMA1_addr ); + +/******************************************************************************* +* Function Name : DMA_Tx +* Description : DMA start sending data +* Input : None +* Return : None +*******************************************************************************/ +extern void DMA_Tx(void); + +/******************************************************************************* +* Function Name : DMA_Rx_check +* Description : double DMA receiving data +* Input : DMA0_addr--DMA0 address + DMA1_addr--DMA1 address + custom_number: customized data using for data checking, + consistent with the transmitting one +* Return : None +*******************************************************************************/ +extern void DMA_Rx_check( UINT32 DMA0_addr, UINT32 DMA1_addr, UINT32 custom_number); + +/******************************************************************************* +* Function Name : ClearITFlag +* Description : Clear interruption flag +* Input : ITFlag: + 1.SDS_PHY_RDY_FLG + 2.SDS_TX_INT_FLG + 3.SDS_RX_INT_FLG + 4.SDS_FIFO_OV_FLG + 5.SDS_COMMA_INT_FLG + 6.ALL_INT_FLG +* Return : None +*******************************************************************************/ +extern void ClearITFlag( UINT16 ITFlag); + +/******************************************************************************* +* Function Name : EnableIT +* Description : Enable Interrupt +* Input : ITType: + 1.SDS_PHY_RDY_EN + 2(1).SDS_TX_INT_EN (Tx mode) + 2(2).SDS_RX_ERR_EN (Rx mode) + 3.SDS_RX_INT_EN + 4.SDS_FIFO_OV_EN + 5.SDS_COMMA_INT_EN + 6.ALL_INT_TYPE +* Return : None +*******************************************************************************/ +extern void EnableIT( UINT16 ITType); + +/******************************************************************************* +* Function Name : Wait_Txdone +* Description : waiting for Tx done +* Input : None +* Return : None +*******************************************************************************/ +extern void Wait_Txdone(void); + +/******************************************************************************* +* Function Name : Wait_commadone +* Description : waiting for Rx COMMA done +* Input : None +* Return : None +*******************************************************************************/ +extern UINT8 Wait_commadone(UINT32 cnt); + +/******************************************************************************* +* Function Name : ReadRxFlagBit +* Description : read Rx IT status +* Input : None +* Return : None +*******************************************************************************/ +extern UINT32 ReadITFlagBit(UINT16 ITFlag); + +/******************************************************************************* +* Function Name : ReadCOMMAFlagBit +* Description : read COMMA IT status +* Input : None +* Return : None +*******************************************************************************/ +extern UINT32 ReadCOMMAFlagBit(void); + +/******************************************************************************* +* Function Name : serdes_Rx_init +* Description : receiver module initialization +* Input : None +* Return : None +*******************************************************************************/ +extern void serdes_Rx_init(void); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/connect_soc.h b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/connect_soc.h new file mode 100644 index 000000000..fde7751fb --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/connect_soc.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-07-15 Emuzit first version + */ +#ifndef __CONNECT_SOC_H__ +#define __CONNECT_SOC_H__ + +#include +#include +#include + +#if !defined(SOC_CH567) && \ + !defined(SOC_CH568) && \ + !defined(SOC_SERIES_CH569) +#define SOC_SERIES_CH569 +#endif + +#ifndef __packed +#define __packed __attribute__((packed)) +#endif + +//#define CHECK_STRUCT_SIZE(s, size) \ +// static_assert(sizeof(s) == size, #s " has wrong size") + +#define BITS_SET(x, bits) do x |= bits; while(0) +#define BITS_CLR(x, bits) do x &= ~bits; while(0) + +#define FLASH_BASE_ADDRESS 0x00000000 +#define RAMS_BASE_ADDRESS 0x20000000 +#define BUS8_BASE_ADDRESS 0x80000000 + +#ifdef SOC_SERIES_CH569 +#define RAMX_BASE_ADDRESS 0x20020000 +#define RAMS_SIZE 16 +#else +#define RAMS_SIZE 32 +#endif +#define RAMS_END (RAMS_BASE_ADDRESS + RAMS_SIZE * 1024) + +#define SYS_REG_BASE 0x40001000 +#define GPIO_REG_BASE 0x40001000 +#define GPIO_REG_BASE_PA 0x40001040 +#define GPIO_REG_BASE_PB 0x40001060 + +#define GPIO_PORTS 2 // 2 ports : PA & PB +#define GPIO_PA_PIN_START 0 // PA : pin number 0~31 +#define GPIO_PB_PIN_START 32 // PB : pin number 32~63 + +#ifdef SOC_SERIES_CH569 +#define GPIO_PA_PIN_MARK 0x00ffffff // PA : bits 0~23 +#define GPIO_PB_PIN_MARK 0x01ffffff // PB : bits 0~24 +#else +#define GPIO_PA_PIN_MARK 0x0000ffff // PA : bits 0~15 +#define GPIO_PB_PIN_MARK 0x00003fff // PB : bits 0~13 +#endif + +#define TMR0_REG_BASE 0x40002000 +#define TMR1_REG_BASE 0x40002400 +#define TMR2_REG_BASE 0x40002800 + +#define UART0_REG_BASE 0x40003000 +#define UART1_REG_BASE 0x40003400 +#define UART2_REG_BASE 0x40003800 +#define UART3_REG_BASE 0x40003c00 + +#define SPI0_REG_BASE 0x40004000 +#define SPI1_REG_BASE 0x40004400 + +#define PWMX_REG_BASE 0x40005000 + +#define PFIC_REG_BASE 0xe000e000 +#define SysTick_REG_BASE 0xe000f000 + +#ifdef SOC_SERIES_CH569 +#define HSPI_REG_BASE 0x40006000 // CH569W +#define ECDC_REG_BASE 0x40007000 +#define USBSS_REG_BASE 0x40008000 +#define USBHS_REG_BASE 0x40009000 +#define EMMC_REG_BASE 0x4000a000 +#define SERDES_REG_BASE 0x4000b000 +#define ETH_REG_BASE 0x4000c000 // CH565W/CH569W +#define DVP_REG_BASE 0x4000e000 // CH565W/CH565M +#else +#define LED_REG_BASE 0x40006000 +#define USB0_REG_BASE 0x40008000 // CH567 +#define USB1_REG_BASE 0x40009000 // CH567 +#define USB_REG_BASE 0x40009000 // CH568 +#define SDC_REG_BASE 0x4000a000 +#define SATA_REG_BASE 0x4000b000 // CH568 +#define ECDC_REG_BASE 0x4000c400 +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/connect_sys.h b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/connect_sys.h new file mode 100644 index 000000000..450e162f8 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/connect_sys.h @@ -0,0 +1,396 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-07-15 Emuzit first version + */ +#ifndef __CONNECT_SYS_H__ +#define __CONNECT_SYS_H__ + +#include "connect_soc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define sys_safe_access_enter(sys) \ + do { \ + sys->SAFE_ACCESS_SIG.reg = SAFE_ACCESS_SIG_1; \ + sys->SAFE_ACCESS_SIG.reg = SAFE_ACCESS_SIG_2; \ + } while(0) + +#define sys_safe_access_leave(sys) \ + do sys->SAFE_ACCESS_SIG.reg = 0; while(0) + +union _sys_safe_access_sig +{ + uint8_t reg; + struct + { + uint8_t safe_acc_mode : 2; // RO, current safe access, 11b => RWA ok + uint8_t resv_2 : 2; + uint8_t safe_acc_timer : 3; // RO, current safe access time count + uint8_t resv_7 : 1; + }; +}; +#define RB_SAFE_ACC_MODE 0x03 +#define RB_SAFE_ACC_TIMER 0x70 + +#define SAFE_ACCESS_SIG_1 0x57 +#define SAFE_ACCESS_SIG_2 0xa8 + +union _sys_glob_rom_cfg +{ + uint8_t reg; + struct + { + uint8_t rom_ext_re : 1; // RO, allow programmer to read FlashROM + uint8_t code_ram_we : 1; // RWA, code SRAM writaboe + uint8_t rom_data_we : 1; // RWA, FlashROM data erasable/writable + uint8_t rom_code_we : 1; // RWA, FlashROM code erasable/writable + uint8_t rom_code_ofs : 1; // RWA, FlashROM offset for user code + uint8_t resv_5 : 3; + }; +}; +#define RB_ROM_EXT_RE 0x01 +#define RB_CODE_RAM_WE 0x02 +#define RB_ROM_DATA_WE 0x04 +#define RB_ROM_CODE_WE 0x08 +#define RB_ROM_CODE_OFS 0x10 + +#define ROM_CODE_OFS_0x00000 0 +#define ROM_CODE_OFS_0x04000 1 + +union _sys_rst_boot_stat +{ + uint8_t reg; + struct + { + uint8_t reset_flag : 2; // RO, last reset cause + uint8_t cfg_reset_en : 1; // RO, external reset pin (#RST) status + uint8_t cfg_boot_en : 1; // RO, reset as 1 + uint8_t cfg_debug_en : 1; // RO + uint8_t boot_loader : 1; // RO + uint8_t resv_6 : 2; + }; +}; +#define RB_RESET_FLAG 0x03 +#define RB_CFG_RESET_EN 0x04 +#define RB_CFG_BOOT_EN 0x08 +#define RB_CFG_DEBUG_EN 0x10 +#define RB_BOOT_LOADER 0x20 + +#define RESET_FLAG_IS_SOFT 0 +#define RESET_FLAG_IS_POR 1 +#define RESET_FLAG_IS_WDOG 2 +#define RESET_FLAG_IS_RSTPIN 3 + +union _sys_rst_wdog_ctrl +{ + uint8_t reg; + struct + { + uint8_t software_reset : 1; // WA/WZ, system software reset, auto clear +#if defined(SOC_SERIES_CH569) + uint8_t wdog_rst_en : 1; // RWA, enable watchdog overflow to reset + uint8_t wdog_int_en : 1; // RWA, enable watchdog overflow interrupt + uint8_t wdog_int_flag : 1; // RW1, watchdog counter overflow +#else + uint8_t resv_2 : 3; +#endif + uint8_t resv_4 : 4; // RO, B.7-6 must write 01b + }; +}; +#define RB_SOFTWARE_RESET 0x01 +#ifdef SOC_SERIES_CH569 +#define RB_WDOG_RST_EN 0x02 +#define RB_WDOG_INT_EN 0x04 +#define RB_WDOG_INT_FLAG 0x08 +#endif +#define wdog_ctrl_wdat(v) (0x40 | (v)) + +union _sys_clk_pll_div +{ + uint8_t reg; + struct + { + uint8_t pll_div : 4; // RWA, min 2 + uint8_t resv_4 : 4; // RWA, B.7-6 must write 01b + }; +}; +#define clk_pll_div_wdat(div) (0x40 | (div)) + +union _sys_clk_cfg_ctrl +{ + uint8_t reg; + struct + { + uint8_t pll_sleep : 1; // RWA, PLL sleep control + uint8_t sel_pll : 1; // RWA, clock source select + uint8_t resv_6 : 6; // RWA, must write 10b + }; +}; +#define RB_CLK_PLL_SLEEP 0x01 +#define RB_CLK_SEL_PLL 0x02 + +#define CLK_PLL_SLEEP_DISABLE 0 +#define CLK_PLL_SLEEP_ENABLE 1 +#define CLK_SEL_PLL_HSE_30M 0 +#define CLK_SEL_PLL_USB_480M 1 +#define clk_cfg_ctrl_wdat(v) (0x80 | (v)) + +union _sys_clk_mod_aux +{ + uint8_t reg; + struct + { + uint8_t int_125m_en : 1; // RWA, USB PHY 125MHz to ETH + uint8_t ext_125m_en : 1; // RWA, external 125MHz to ETH + uint8_t mco_sel_msk : 2; // RWA, MCO output select + uint8_t mco_en : 1; // RWA, MCO output enable + uint8_t resv_5 : 3; + }; +}; +#define RB_INT_125M_EN 0x01 +#define RB_EXT_125M_EN 0x02 +#define RB_MCO_SEL_MSK 0x0C +#define RB_MCO_EN 0x10 + +#define MCO_SEL_MSK_125M 0 +#define MCO_SEL_MSK_25M 1 +#define MCO_SEL_MSK_2_5M 2 + +/* All bits are RWA (need safe_access_sig), 0/1 : clock on/off +*/ +union _sys_slp_clk_off0 +{ + uint8_t reg; + struct + { + uint8_t tmr0 : 1; + uint8_t tmr1 : 1; + uint8_t tmr2 : 1; + uint8_t pwmx : 1; + uint8_t uart0 : 1; + uint8_t uart1 : 1; + uint8_t uart2 : 1; + uint8_t uart3 : 1; + }; +}; +#define RB_SLP_CLK_TMR0 0x01 +#define RB_SLP_CLK_TMR1 0x02 +#define RB_SLP_CLK_TMR2 0x04 +#define RB_SLP_CLK_PWMX 0x08 +#define RB_SLP_CLK_UART0 0x10 +#define RB_SLP_CLK_UART1 0x20 +#define RB_SLP_CLK_UART2 0x40 +#define RB_SLP_CLK_UART3 0x80 + +#define SYS_SLP_CLK_ON 0 +#define SYS_SLP_CLK_OFF 1 + +/* All writable bits are RWA (need safe_access_sig), 0/1 : clock on/off +*/ +union _sys_slp_clk_off1 +{ + uint8_t reg; + struct + { + uint8_t spi0 : 1; + uint8_t spi1 : 1; +#if defined(SOC_CH567) + uint8_t sdc : 1; + uint8_t led : 1; + uint8_t usb0 : 1; + uint8_t usb1 : 1; + uint8_t resv_6 : 1; +#elif defined(SOC_CH568) + uint8_t sdc : 1; + uint8_t led : 1; + uint8_t resv_4 : 1; + uint8_t usb1 : 1; + uint8_t sata : 1; + uint8_t ecdc : 1; +#else + uint8_t emmc : 1; + uint8_t hspi : 1; + uint8_t usbhs : 1; + uint8_t usbss : 1; + uint8_t serd : 1; + uint8_t dvp : 1; +#endif + }; +}; +#define RB_SLP_CLK_SPI0 0x01 +#define RB_SLP_CLK_SPI1 0x02 +#if defined(SOC_WCH_CH567) +#define RB_SLP_CLK_SDC 0x04 +#define RB_SLP_CLK_LED 0x08 +#define RB_SLP_CLK_USB0 0x10 +#define RB_SLP_CLK_USB1 0x20 +#define RB_SLP_CLK_ECDC 0x80 +#elif defined(SOC_WCH_CH568) +#define RB_SLP_CLK_SDC 0x04 +#define RB_SLP_CLK_LED 0x08 +#define RB_SLP_CLK_USB1 0x20 +#define RB_SLP_CLK_SATA 0x40 +#define RB_SLP_CLK_ECDC 0x80 +#else +#define RB_SLP_CLK_EMMC 0x04 +#define RB_SLP_CLK_HSPI 0x08 +#define RB_SLP_CLK_USBHS 0x10 +#define RB_SLP_CLK_USBSS 0x20 +#define RB_SLP_CLK_SERD 0x40 +#define RB_SLP_CLK_DVP 0x80 +#endif + +/* All writable bits are RWA (need safe_access_sig) +*/ +union _sys_slp_wake_ctrl +{ + uint8_t reg; + struct + { +#if defined(SOC_WCH_CH567) + uint8_t usb0_wake : 1; + uint8_t usb1_wake : 1; + uint8_t resv_2 : 2; + uint8_t gpio_wake : 1; + uint8_t resv_5 : 3; +#elif defined(SOC_WCH_CH568) + uint8_t resv_0 : 1; + uint8_t usb1_wake : 1; + uint8_t sata_wake : 1; + uint8_t resv_3 : 1; + uint8_t gpio_wake : 1; + uint8_t resv_5 : 3; +#else + uint8_t usbhs_wake : 1; + uint8_t usbss_wake : 1; + uint8_t clk_eth : 1; + uint8_t clk_ecdc : 1; + uint8_t gpio_wake : 1; + uint8_t eth_wake : 1; + uint8_t resv_6 : 2; +#endif + }; +}; +#if defined(SOC_WCH_CH567) +#define RB_SLP_USB0_WAKE 0x01 +#define RB_SLP_USB1_WAKE 0x02 +#define RB_SLP_GPIO_WAKE 0x10 +#elif defined(SOC_WCH_CH568) +#define RB_SLP_USB1_WAKE 0x02 +#define RB_SLP_SATA_WAKE 0x04 +#define RB_SLP_GPIO_WAKE 0x10 +#else +#define RB_SLP_USBHS_WAKE 0x01 +#define RB_SLP_USBSS_WAKE 0x02 +#define RB_SLP_CLK_ETH 0x04 +#define RB_SLP_CLK_ECDC 0x08 +#define RB_SLP_GPIO_WAKE 0x10 +#define RB_SLP_ETH_WAKE 0x20 +#endif + +union _sys_slp_power_ctrl +{ + uint8_t reg; + struct + { + uint8_t usbhs_pwrdn : 1; // RWA, USBHS power down (0:PWRUP) + uint8_t resv_2 : 7; + }; +}; +#define RB_SLP_USBHS_PWRDN 0x01 + +union _sys_serd_ana_cfg1 +{ + uint16_t reg; + struct + { + uint8_t serd_pll_cfg; // RWA, reset as 0x5a + uint8_t serd_30m_sel : 1; // RWA + uint8_t serd_dn_tst : 1; // RWA + uint8_t resv_10 : 6; + }; +}; +#define RB_SERD_PLL_CFG 0x0ff +#define RB_SERD_30M_SEL 0x100 +#define RB_SERD_DN_TST 0x200 + +union _sys_serd_ana_cfg2 +{ + uint32_t reg; + struct + { + uint32_t serd_trx_cfg : 25; // RWA, reset as 423015h + uint32_t resv_25 : 7; + }; +}; +#define RB_SERD_TRX_CFG 0x1000000 + +/* + * 0x00 R8_SAFE_ACCESS_SIG: safe access signature register + * 0x01 R8_CHIP_ID: RF, chip ID register + * 0x02 R8_SAFE_ACCESS_ID: RF, read as 02h + * 0x03 R8_WDOG_COUNT RW, watchdog counter + * 0x04 R8_GLOB_ROM_CFG: ROM config register + * 0x05 R8_RST_BOOT_STAT: RO, boot state register + * 0x06 R8_RST_WDOG_CTRL: software reset & watchdog control register + * 0x07 R8_GLOB_RESET_KEEP: RW, only power-on-reset can clear this register + * 0x08 R8_CLK_PLL_DIV: RWA, PLL output divisor register + * 0x0a R8_CLK_CFG_CTRL: RWA, clock config register + * 0x0b R8_CLK_MOD_AUX: RWA, clock auxiliary register + * 0x0c R8_SLP_CLK_OFF0: RWA, sleep control register 0 + * 0x0d R8_SLP_CLK_OFF1: RWA, sleep control register 1 + * 0x0e R8_SLP_WAKE_CTRL: RWA, wakeup control register + * 0x0f R8_SLP_POWER_CTRL: RWA, low power management register + * 0x20 R16_SERD_ANA_CFG1: RWA, SerDes PHY analog param config register 1 + * 0x24 R32_SERD_ANA_CFG2: RWA, SerDes PHY analog param config register 2 + * + * CAVEAT: gcc (as of 8.2.0) tends to read 32-bit word for bit field test. + * Be careful for those with side effect for read. + */ +struct sys_registers +{ + union _sys_safe_access_sig SAFE_ACCESS_SIG; + uint8_t CHIP_ID; + uint8_t SAFE_ACCESS_ID; + uint8_t WDOG_COUNT; + union _sys_glob_rom_cfg GLOB_ROM_CFG; + union _sys_rst_boot_stat RST_BOOT_STAT; + union _sys_rst_wdog_ctrl RST_WDOG_CTRL; + uint8_t GLOB_RESET_KEEP; + union _sys_clk_pll_div CLK_PLL_DIV; + uint8_t resv_9; + union _sys_clk_cfg_ctrl CLK_CFG_CTRL; + union _sys_clk_mod_aux CLK_MOD_AUX; + union _sys_slp_clk_off0 SLP_CLK_OFF0; + union _sys_slp_clk_off1 SLP_CLK_OFF1; + union _sys_slp_wake_ctrl SLP_WAKE_CTRL; + union _sys_slp_power_ctrl SLP_POWER_CTRL; +#if defined(SOC_SERIES_CH569) + uint32_t resv_10[4]; + union _sys_serd_ana_cfg1 SERD_ANA_CFG1; + uint16_t resv_22; + union _sys_serd_ana_cfg2 SERD_ANA_CFG2; +#endif +} __packed; + +//CHECK_STRUCT_SIZE(struct sys_registers, 0x28); + +uint32_t sys_hclk_calc(void); +uint32_t sys_hclk_get(void); +int sys_hclk_set(uint32_t freq); +int sys_clk_off_by_irqn(uint8_t irqn, int off); +void sys_slp_clk_off0(uint8_t bits, int off); +void sys_slp_clk_off1(uint8_t bits, int off); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/connect_usb.h b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/connect_usb.h new file mode 100644 index 000000000..66e5c5f19 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/include/connect_usb.h @@ -0,0 +1,37 @@ +/* +* 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 aiit-arm32-board usb function and struct +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef CONNECT_USB_H +#define CONNECT_USB_H + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef BSP_USING_USBD_CDC +// TODO +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/serdes/Kconfig b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/serdes/Kconfig new file mode 100644 index 000000000..47ea6f04b --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/serdes/Kconfig @@ -0,0 +1,7 @@ +config SERDES_TRANS + bool "Config serdes transmit mode." + default y + +config SERIAL_RECEI + bool "Config serdes receive mode." + default y \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/serdes/Makefile b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/serdes/Makefile new file mode 100644 index 000000000..2b985267c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/serdes/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_serdes.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/serdes/connect_serdes.c b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/serdes/connect_serdes.c new file mode 100644 index 000000000..06d6b68e1 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/serdes/connect_serdes.c @@ -0,0 +1,154 @@ +/* + * 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_usart.c + * @brief support ch569 uart function and register to bus framework + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2025-04-07 + */ + +#include "CH56x_common.h" +#include "xizi.h" +#include "board.h" +#include "shell.h" +#include "connect_serdes.h" + + +//#define Trans 1 +//#define Recei 1 + +//UINT32 Tx_DMAaddr = 0x20020000; +//UINT32 RX_DMA0_addr = 0x20033330; +//UINT32 RX_DMA1_addr = 0x20034330; +UINT32 Tx_DMAaddr[512] __attribute__((aligned(16))) = {0}; +UINT32 RX_DMA0_addr[512] __attribute__((aligned(16))) = {0}; +UINT32 RX_DMA1_addr[512] __attribute__((aligned(16))) = {0}; + +volatile UINT32 i=0; +volatile UINT32 k=0; +/******************************************************************************* +* Function Name : __attribute__((interrupt())) +* Description : SERDES_IRQHandler hard push +* Input : baudrate: UART1 communication baud rate. +* Return : None +*******************************************************************************/ +void SERDES_IRQHandler (void) __attribute__((interrupt())); + +/******************************************************************************* +* Function Name : SerdesTxTest +* Description : SerdesTxTest program. +* Input : None +* Return : None +*******************************************************************************/ +int SerdesTxTest(void) +{ + UINT32 *p32_txdma = (UINT32 *)Tx_DMAaddr; + UINT32 n=0; + UINT32 data=0; + + KPrintf("SerdesTxTest start\r\n"); + KPrintf("SerdesTxTest Tx_DMAaddr=0x%08x\r\n", (UINT32)Tx_DMAaddr); + +#ifdef SERDES_TRANS //Serdes query sent. + Serdes_Tx_Init(); + + do + { + *p32_txdma++ = data; + data += 0x01010101; + n++; + }while(n!=512); + mDelaymS(500); + + DMA_Tx_CFG( (UINT32)Tx_DMAaddr,2048,0x555555); //512 address spaces 2048 bytes + + while(1) + { + KPrintf("SerdesTxTest DMA_Tx\r\n"); + DMA_Tx(); + Wait_Txdone(); + ClearITFlag(SDS_TX_INT_FLG); + mDelaymS(5000); + } +#endif + +} + +/******************************************************************************* +* Function Name : SerdesRxTest +* Description : SerdesRxTest program. +* Input : None +* Return : None +*******************************************************************************/ +int SerdesRxTest(void) +{ + KPrintf("SerdesRxTest start\r\n"); + KPrintf("SerdesRxTest RX_DMA0_addr=0x%08x RX_DMA1_addr=0x%08x\r\n", (UINT32)RX_DMA0_addr, (UINT32)RX_DMA1_addr); + +#ifdef SERIAL_RECEI // Serdes interrupt reception. + PFIC_EnableIRQ(INT_ID_SERDES); + + DoubleDMA_Rx_CFG((UINT32)RX_DMA0_addr , (UINT32)RX_DMA1_addr ); + Serdes_Rx_Init(10*1000*1000); + Wait_commadone(10*1000*1000); + Serdes_Rx_Init(10*1000*1000); + EnableIT(SDS_RX_INT_EN|SDS_COMMA_INT_EN); + + KPrintf("SerdesRxTest init OK\r\n"); + while(1) + { + if(k==2) // After each completion of the double-buffered reception, print the received data. + { + for(i=0;i<512;i++) + { + KPrintf("%x\r\n",*(UINT32 *)(0x20033330+4*i)); + KPrintf("%x\r\n",*(UINT32 *)(0x20034330+4*i)); + } + k=0; + } + } +#endif +} + +/******************************************************************************* +* Function Name : SERDES_IRQHandler +* Description : Interruption function +* Input : None +* Return : None +*******************************************************************************/ +void SERDES_IRQHandler (void) +{ + if(ReadITFlagBit(SDS_RX_INT_FLG)) + { + ClearITFlag(SDS_RX_INT_FLG); + k++; + DMA_Rx_check((UINT32)RX_DMA0_addr, (UINT32)RX_DMA1_addr, 0x555555); + KPrintf("\nbuffer received ....... !\n"); + } + if(ReadITFlagBit(SDS_COMMA_INT_FLG)) + { + KPrintf("\nreceive COMMA, init....... !\n"); + Serdes_Rx_Init( 1000*30 ); + i = 0; + mDelaymS(50); + ClearITFlag(SDS_COMMA_INT_FLG); + } +} + + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + SerdesTxTest, SerdesTxTest, test serdes tx); + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + SerdesRxTest, SerdesRxTest, test serdes rx); diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/serdes/libSERDES.a b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/serdes/libSERDES.a new file mode 100644 index 000000000..1d9b91a31 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/serdes/libSERDES.a differ diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/spi/Kconfig b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/spi/Kconfig new file mode 100644 index 000000000..701b1335d --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/spi/Kconfig @@ -0,0 +1,3 @@ +menuconfig BSP_USING_SPI0_FLASH + bool "Enable SPI0 FLASH" + default y diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/spi/Makefile b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/spi/Makefile new file mode 100644 index 000000000..73c862fab --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/spi/Makefile @@ -0,0 +1,5 @@ +ifeq ($(CONFIG_BSP_USING_SPI0_FLASH),y) + SRC_FILES += connect_spi_flash.c +endif + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/spi/connect_spi_flash.c b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/spi/connect_spi_flash.c new file mode 100644 index 000000000..193dc112a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/spi/connect_spi_flash.c @@ -0,0 +1,463 @@ +/* + * 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_spi.c + * @brief support ch569 spi function and register to bus framework + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2025-04-07 + */ +/* + *@Note + *SPI0_FLASH routine + * SPI0 operation external FLASH + */ + +#include +#include "xsconfig.h" +#include "CH56x_common.h" +#include "board.h" +#include "shell.h" + + +#define CMD_STATUS1 0x05 +#define CMD_WR_ENABLE 0x06 +#define CMD_ERASE_4KBYTE 0x20 +#define CMD_ERASE_32KBYTE 0x52 +#define CMD_READ_DATA 0x03 +#define CMD_PAGE_PROG 0x02 +#define CMD_FAST_READ 0x0B +#define CMD_DEVICE_ID 0x90 + +/********************************* Pin Definitions ************************************ +* PA12 <===========> SCS0 +* PA13 <===========> SCK0 +* PA14 <===========> MOSI0 +* PA15 <===========> MISO0 +*******************************************************************************/ +#define SPI0_CS_LOW() R32_PA_CLR |= 1<<12 +#define SPI0_CS_HIGH() R32_PA_OUT |= 1<<12 + +/******************************************************************************* + * @fn DebugInit + * + * @brief Initializes the UART1 peripheral. + * + * @param baudrate - UART1 communication baud rate. + * + * @return None + */ +void DebugInit(UINT32 baudrate) +{ + UINT32 x; + UINT32 t = FREQ_SYS; + + x = 10 * t * 2 / 16 / baudrate; + x = ( x + 5 ) / 10; + R8_UART1_DIV = 1; + R16_UART1_DL = x; + R8_UART1_FCR = RB_FCR_FIFO_TRIG | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN; + R8_UART1_LCR = RB_LCR_WORD_SZ; + R8_UART1_IER = RB_IER_TXD_EN; + R32_PA_SMT |= (1<<8) |(1<<7); + R32_PA_DIR |= (1<<8); +} + +/******************************************************************************* + * @fn SPI_MASTER_INIT + * + * @brief SPI0 master mode initialization + * + * @return None + */ +void SPI_MASTER_INIT(void) +{ + R8_SPI0_CTRL_MOD = RB_SPI_MOSI_OE|RB_SPI_SCK_OE; /* MOSI, SCK output enable, host mode, mode 0 */ + R8_SPI0_CLOCK_DIV = 0x0a; /* 10 frequency division, 100/10=10M */ + R32_PA_DIR |= (1<<14 | 1<<13 | 1<<12); /* MOSI(PA14), SCK0(PA13), SCS(PA12) are the output*/ + R32_PA_PU |= 1<<12 ; + R8_SPI0_CTRL_CFG &= ~RB_SPI_DMA_ENABLE; +} + +/******************************************************************************* + * @fn SPI0_Trans + * + * @brief send a byte of data + * + * @param data - data to send + * + * @return None + */ +void SPI0_Trans(UINT8 data) +{ + +// R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR; +// R8_SPI0_BUFFER = data; +// while( !(R8_SPI0_INT_FLAG & RB_SPI_FREE) ); + + R32_SPI0_FIFO = data; + R16_SPI0_TOTAL_CNT = 0x01; + while( R8_SPI0_FIFO_COUNT != 0 ); /* Wait for the data to be sent */ +} + +/******************************************************************************* + * @fn SPI0_Recv + * + * @brief Receive a byte of data + * + * @return None + */ +UINT8 SPI0_Recv(void) +{ +// R8_SPI0_CTRL_MOD &= ~RB_SPI_FIFO_DIR; +// R8_SPI0_BUFFER = 0xFF; //start transfer +// while( !(R8_SPI0_INT_FLAG & RB_SPI_FREE) ); +// return ( R8_SPI0_BUFFER ); + + UINT8 data; + R32_SPI0_FIFO = 0xff; + R16_SPI0_TOTAL_CNT = 0x01; + while( R8_SPI0_FIFO_COUNT != 0 ); /* wait for data to come back */ + data = R8_SPI0_BUFFER; + return data; +} + +/******************************************************************************* + * @fn SPI0_RecvS + * + * @brief Receive multiple bytes continuously using FIFO + * + * @param pbuf - The first address of the data content to be sent + len - The length of the data sent by the request, the maximum is 4095 + + * @return None + */ +void SPI0_RecvS(UINT8 *pbuf, UINT16 len) +{ + UINT16 readlen; + + readlen = len; + R8_SPI0_CTRL_MOD |= RB_SPI_FIFO_DIR; //Set data direction to input + R16_SPI0_TOTAL_CNT = len; //Set the length of the data to be received, the FIFO direction will start the transmission if the input length is not 0 + R8_SPI0_INT_FLAG = RB_SPI_IF_CNT_END; + while( readlen ) + { + if( R8_SPI0_FIFO_COUNT ) + { + *pbuf = R8_SPI0_FIFO; + pbuf++; + readlen--; + } + } +} + +/******************************************************************************* + * @fn ReadExternalFlashStatusReg_SPI + * + * @brief Used to read the status register and return the value of the status register + * + * @return ExFlashRegStatus + */ +UINT8 ReadExternalFlashStatusReg_SPI(void) +{ + UINT8 ExFlashRegStatus; + + + SPI0_CS_LOW(); + SPI0_Trans( CMD_STATUS1 ); //Send a command to read the status register + ExFlashRegStatus = SPI0_Recv(); //read status register + SPI0_CS_HIGH(); + + return ExFlashRegStatus; +} + +/******************************************************************************* + * @fn WaitExternalFlashIfBusy + * + * @brief Wait for the chip to be free (after performing Byte-Program, Sector-Erase, Block-Erase, Chip-Erase operations) + * + * @return None + */ +void WaitExternalFlashIfBusy(void) +{ + while ((ReadExternalFlashStatusReg_SPI())&0x01 == 0x01 ) + { + ; //Waiting for Flash to be idle + } +} + +/******************************************************************************* + * @fn WriteExternalFlashEnable_SPI + * + * @brief Write enable, also can be used to enable write status register + * + * @return None + */ +void WriteExternalFlashEnable_SPI(void) +{ + SPI0_CS_LOW(); + SPI0_Trans( CMD_WR_ENABLE ); //Send write enable command + SPI0_CS_HIGH(); +} + +/******************************************************************************* + * @fn EraseExternal4KFlash_SPI + * + * @brief Erase 4K Flash Erase a sector + * + * @param Dst_Addr 0-1 ffff ffff, Clear the sector where any address is located + * + * @return None + */ +void EraseExternal4KFlash_SPI(UINT32 Dst_Addr) +{ + WriteExternalFlashEnable_SPI(); + WaitExternalFlashIfBusy(); + + SPI0_CS_LOW(); + SPI0_Trans(CMD_ERASE_4KBYTE); //sector erase command + SPI0_Trans(((Dst_Addr & 0xFFFFFF) >> 16)); //Send 3 byte address + SPI0_Trans(((Dst_Addr & 0xFFFF) >> 8)); + SPI0_Trans(Dst_Addr & 0xFF); + SPI0_CS_HIGH(); + + WaitExternalFlashIfBusy(); +} + +/******************************************************************************* + * @fn EraseExternalFlash_SPI + * + * @brief Erase 32K Flash Erase a sector + * + * @param Dst_Addr 0-1 ffff ffff, Clear the sector where any address is located + * + * @return None + */ +void EraseExternal32KFlash_SPI(UINT32 Dst_Addr) +{ + WriteExternalFlashEnable_SPI(); + WaitExternalFlashIfBusy(); + + SPI0_CS_LOW(); + SPI0_Trans(CMD_ERASE_32KBYTE); //32K erase command + SPI0_Trans(((Dst_Addr & 0xFFFFFF) >> 16)); //Send 3 byte address + SPI0_Trans(((Dst_Addr & 0xFFFF) >> 8)); + SPI0_Trans(Dst_Addr & 0xFF); + SPI0_CS_HIGH(); + + WaitExternalFlashIfBusy(); +} + +/******************************************************************************* + * @fn PageWriteExternalFlash_SPI + * + * @brief Page write, SPI writes less than 256 bytes of data in one page + * + * @param RcvBuffer - data storage area + * StarAddr - address to start writing + * Len - The number of bytes to write (up to 256), which should not exceed the number of bytes remaining on the page + * + * @returnNone + */ +void PageWriteExternalFlash_SPI(UINT32 StarAddr, UINT16 Len, PUINT8 RcvBuffer) +{ + UINT16 i; + + WriteExternalFlashEnable_SPI(); //SET WEL + + SPI0_CS_LOW(); + SPI0_Trans(CMD_PAGE_PROG); //send write page command + SPI0_Trans(((StarAddr & 0xFFFFFF) >> 16)); //Send 24bit address + SPI0_Trans(((StarAddr & 0xFFFF) >> 8)); + SPI0_Trans(StarAddr & 0xFF); + for(i=0; i!=Len; i++){ + SPI0_Trans(RcvBuffer[i]); //cycle write + } + SPI0_CS_HIGH(); + + WaitExternalFlashIfBusy(); //Wait for write to end +} + +/******************************************************************************* + * @fn BlukWriteExternalFlash_SPI + * + * @brief Write SPI FLASH without verification + * It must be ensured that the data in the address range to be written is all 0XFF, otherwise the data written at non-0XFF will fail + * + * @param SendBuffer - data storage area + * StarAddr - address to start writing + * Len - The number of bytes to write (max 65535) + * + * @return None + */ +void BlukWriteExternalFlash_SPI(UINT32 StarAddr, UINT16 Len, PUINT8 SendBuffer) +{ + UINT16 pageremain; + + pageremain = 256-StarAddr%256; //The remaining bytes of a single page + if(Len<=pageremain) + { + pageremain=Len; //No more than 256 bytes + } + while(1) + { + PageWriteExternalFlash_SPI(StarAddr,pageremain,SendBuffer); + if(Len==pageremain) + { + break; //end of writing + } + else + { + SendBuffer+=pageremain; + StarAddr+=pageremain; + Len-=pageremain; //Subtract the number of bytes already written + if(Len>256) + { + pageremain=256; //256 bytes can be written at a time + } + else + { + pageremain=Len; //Not enough 256 bytes + } + } + } +} + +/******************************************************************************* + * @fn ReadExternalFlash_SPI + * + * @brief read data from address + * + * @param StarAddr + * Len read data length + * RcvBuffer Receive buffer start address + * + * @return None + */ +void ReadExternalFlash_SPI(UINT32 StarAddr, UINT16 Len, PUINT8 RcvBuffer) +{ + SPI0_CS_LOW(); + SPI0_Trans(CMD_READ_DATA); //read command + SPI0_Trans(((StarAddr & 0xFFFFFF) >> 16)); //Send 3 byte address + SPI0_Trans(((StarAddr & 0xFFFF) >> 8)); + SPI0_Trans(StarAddr & 0xFF); + SPI0_RecvS( RcvBuffer, Len ); + SPI0_CS_HIGH(); +} + +/******************************************************************************* + * @fn BlukReadExternalFlash_SPI + * + * @brief Read the data of multiple bytes in the starting address and store it in the buffer + * + * @param StarAddr -Destination Address 000000H - 1FFFFFH + Len - read data length + RcvBuffer - Receive buffer start address + + * @return None + */ +void BlukReadExternalFlash_SPI(UINT32 StarAddr, UINT16 Len, PUINT8 RcvBuffer) +{ + SPI0_CS_LOW(); + SPI0_Trans(CMD_FAST_READ); //high speed + SPI0_Trans(((StarAddr & 0xFFFFFF) >> 16)); //Send 3 byte address + SPI0_Trans(((StarAddr & 0xFFFF) >> 8)); + SPI0_Trans(StarAddr & 0xFF); + SPI0_Trans(0x00); + SPI0_RecvS( RcvBuffer, Len ); + SPI0_CS_HIGH(); +} + +/******************************************************************************* + * @fn SPIFlash_ReadID + * + * @brief SPI Flash read chip ID + * + * @return 0XEF13 - Indicates that the chip model is W25Q80 + * 0XEF14 - Indicates that the chip model is W25Q16 + * 0XEF15 - Indicates that the chip model is W25Q32 + * 0XEF16 - Indicates that the chip model is W25Q64 + * 0XEF17 - Indicates that the chip model is W25Q128 + */ +UINT16 SPIFlash_ReadID(void) +{ + UINT16 temp = 0; + + R32_PA_CLR |= 1<<12 ; + + SPI0_Trans(0x90); //read ID command + SPI0_Trans(0x00); + SPI0_Trans(0x00); + SPI0_Trans(0x00); + temp = SPI0_Recv(); + temp = temp<<8; + temp |= SPI0_Recv(); + + R32_PA_OUT |= 1<<12 ; + + return temp; +} + +/********************************************************************* + * @fn InitHwSpi + * + * @brief InitHwSpi program. + * + * @return none + */ +int InitHwSpi(void) { + SPI_MASTER_INIT ( ); /* SPI0 master mode initialization */ + return 0; +} + +int SpiFlashTest(int argc, char *argv[]) +{ + UINT8 buf[1024]; + UINT8 i; + int read_only = 0; + + KPrintf("SpiFlashTest Start\n"); + + KPrintf("spi flash id:0x%04x\n", SPIFlash_ReadID() ); /*Read chip ID */ + + for(i=0; i!=255; i++){ + buf[i] = i; + } + + if (argc == 3) { + KPrintf("SpiFlashTest argv[2]=%s\n", argv[2]); + if (argv[2][0] == 'r') { + read_only = 1; + } + else { + buf[0] = argv[2][0] - '0'; + } + } + + if (read_only == 0) { + EraseExternal4KFlash_SPI(0); + BlukWriteExternalFlash_SPI(0,255,buf); + } + + BlukReadExternalFlash_SPI( 0,255,buf ); + + for(i=0; i!=255; i++){ + KPrintf("%d ",(UINT16)buf[i]); + } + KPrintf("done\n"); + + return 0; +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + SpiFlashTest, SpiFlashTest, test spi); diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/sys/Makefile b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/sys/Makefile new file mode 100644 index 000000000..c56958110 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/sys/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_sys.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/sys/connect_sys.c b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/sys/connect_sys.c new file mode 100644 index 000000000..c5d43e6db --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/sys/connect_sys.c @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-07-15 Emuzit first version + */ +#include +#include "xsconfig.h" +#include "board.h" +#include "xs_isr.h" +#include "CH56xSFR.h" +#include "connect_sys.h" + +static uint32_t hclk_freq; + +uint8_t _slp_clk_off0_irqn_bit(uint8_t irqn) +{ + uint8_t bitpos; + + switch (irqn) + { + case TMR0_IRQn: bitpos = RB_SLP_CLK_TMR0; break; + case TMR1_IRQn: bitpos = RB_SLP_CLK_TMR1; break; + case TMR2_IRQn: bitpos = RB_SLP_CLK_TMR2; break; + /* special case to control PWMX clock in irqn way */ + case PWMX_OFFn: bitpos = RB_SLP_CLK_PWMX; break; + case UART0_IRQn: bitpos = RB_SLP_CLK_UART0; break; + case UART1_IRQn: bitpos = RB_SLP_CLK_UART1; break; + case UART2_IRQn: bitpos = RB_SLP_CLK_UART2; break; + case UART3_IRQn: bitpos = RB_SLP_CLK_UART3; break; + default: + bitpos = 0; + } + + return bitpos; +} + +uint8_t _slp_clk_off1_irqn_bit(uint8_t irqn) +{ + uint8_t bitpos; + + switch (irqn) + { + case SPI0_IRQn: bitpos = RB_SLP_CLK_SPI0; break; + case SPI1_IRQn: bitpos = RB_SLP_CLK_SPI1; break; +#if defined(SOC_CH567) + case SDC_IRQn: bitpos = RB_SLP_CLK_SDC; break; + case LED_IRQn: bitpos = RB_SLP_CLK_LED; break; + case USB0_IRQn: bitpos = RB_SLP_CLK_USB0; break; + case USB1_IRQn: bitpos = RB_SLP_CLK_USB1; break; + case ECDC_IRQn: bitpos = RB_SLP_CLK_ECDC; break; +#elif defined(SOC_CH568) + case SDC_IRQn: bitpos = RB_SLP_CLK_SDC; break; + case LED_IRQn: bitpos = RB_SLP_CLK_LED; break; + case USB1_IRQn: bitpos = RB_SLP_CLK_USB1; break; + case USB0_IRQn: bitpos = RB_SLP_CLK_SATA; break; + case ECDC_IRQn: bitpos = RB_SLP_CLK_ECDC; break; +#else + case EMMC_IRQn: bitpos = RB_SLP_CLK_EMMC; break; + case HSPI_IRQn: bitpos = RB_SLP_CLK_HSPI; break; + case USBHS_IRQn: bitpos = RB_SLP_CLK_USBHS; break; + case USBSS_IRQn: bitpos = RB_SLP_CLK_USBSS; break; + case SERDES_IRQn: bitpos = RB_SLP_CLK_SERD; break; + case DVP_IRQn: bitpos = RB_SLP_CLK_DVP; break; +#endif + default: + bitpos = 0; + } + + return bitpos; +} + +#if defined(SOC_SERIES_CH569) +uint8_t _wake_clk_off_irqn_bit(uint8_t irqn) +{ + uint8_t bitpos; + + switch (irqn) + { + case ETH_IRQn: bitpos = RB_SLP_CLK_ETH; break; + case ECDC_IRQn: bitpos = RB_SLP_CLK_ECDC; break; + default: + bitpos = 0; + } + + return bitpos; +} +#endif + +/** + * @brief Turn on/off device clock for group clk_off0. + * + * @param bits is a bit mask to select corresponding devices. + * + * @param off is to turn off the clock (1) or trun on (0). + */ +void sys_slp_clk_off0(uint8_t bits, int off) +{ + volatile struct sys_registers *sys = (void *)SYS_REG_BASE; + x_base level; + uint8_t u8v; + + u8v = sys->SLP_CLK_OFF0.reg; + if ((u8v & bits) != (off ? bits : 0)) + { + u8v = off ? (u8v | bits) : (u8v & ~bits); + level = DisableLocalInterrupt(); + sys_safe_access_enter(sys); + sys->SLP_CLK_OFF0.reg = u8v; + sys_safe_access_leave(sys); + EnableLocalInterrupt(level); + } +} + +/** + * @brief Turn on/off device clock for group clk_off1. + * + * @param bits is a bit mask to select corresponding devices. + * + * @param off is to turn off the clock (1) or trun on (0). + */ +void sys_slp_clk_off1(uint8_t bits, int off) +{ + volatile struct sys_registers *sys = (void *)SYS_REG_BASE; + x_base level; + uint8_t u8v; + + u8v = sys->SLP_CLK_OFF1.reg; + if ((u8v & bits) != (off ? bits : 0)) + { + u8v = off ? (u8v | bits) : (u8v & ~bits); + level = DisableLocalInterrupt(); + sys_safe_access_enter(sys); + sys->SLP_CLK_OFF1.reg = u8v; + sys_safe_access_leave(sys); + EnableLocalInterrupt(level); + } +} + +/** + * @brief Turn on/off device clock, specified by its irq number. + * + * @param irqn is the irq number of the target device. + * PWMX does not have irqn, use special PWMX_OFFn number. + * + * @param off is to turn off the clock (1) or trun on (0). + * + * @return Returns if irqn-device has corresponding clk off bit : + * 0 if device not found; otherwise bit position of off0/off1. + */ +int sys_clk_off_by_irqn(uint8_t irqn, int off) +{ + volatile struct sys_registers *sys = (void *)SYS_REG_BASE; + uint8_t u8v; + size_t offset; + + uint8_t bitpos = 0; + + if (irqn < END_OF_IRQn) + { + if ((bitpos = _slp_clk_off0_irqn_bit(irqn)) != 0) + { + offset = offsetof(struct sys_registers, SLP_CLK_OFF0); + } + else if ((bitpos = _slp_clk_off1_irqn_bit(irqn)) != 0) + { + offset = offsetof(struct sys_registers, SLP_CLK_OFF1); + } +#if defined(SOC_SERIES_CH569) + else if ((bitpos = _wake_clk_off_irqn_bit(irqn)) != 0) + { + offset = offsetof(struct sys_registers, SLP_WAKE_CTRL); + } +#endif + if (bitpos) + { + volatile uint8_t *cxreg = (void *)sys; + x_base level; + u8v = cxreg[offset]; + if ((u8v & bitpos) != (off ? bitpos : 0)) + { + u8v = off ? (u8v | bitpos) : (u8v & ~bitpos); + level = DisableLocalInterrupt(); + sys_safe_access_enter(sys); + cxreg[offset] = u8v; + sys_safe_access_leave(sys); + EnableLocalInterrupt(level); + } + } + } + + return bitpos; +} + +/** + * @brief Setup HCLK frequency. + * + * @param freq is the desired hclk frequency. + * supported : 120/96/80/60/48/40/32/30/15/10/6/3/2 MHz + * + * @return Returns 0 if hclk is successfully set. + */ +int sys_hclk_set(uint32_t freq) +{ + volatile struct sys_registers *sys = (void *)SYS_REG_BASE; + + uint8_t plldiv; + + int clksel = -1; + + if (freq >= 30000000) + { + if (freq <= 120000000) + { + /* supported : 120/96/80/60/48/40/32/30 MHz */ + plldiv = 480000000 / freq; // 30M => 16 & 0xf => 0 + clksel = RB_CLK_SEL_PLL; + } + } + else if (freq >= 2000000) + { + /* supported : 15/10/6/3/2 MHz */ + plldiv = 30000000 / freq; + clksel = 0; + } + + if (clksel >= 0) + { + x_base level = DisableLocalInterrupt(); + sys_safe_access_enter(sys); + sys->CLK_PLL_DIV.reg = clk_pll_div_wdat(plldiv); + sys->CLK_CFG_CTRL.reg = clk_cfg_ctrl_wdat(clksel); + sys_safe_access_leave(sys); + EnableLocalInterrupt(level); + /* save to hclk_freq for quick report */ + sys_hclk_calc(); + clksel = 0; + } + + return clksel; +} + +/** + * @brief Get saved HCLK frequency. + * + * Valid only if HCLK is set strickly with sys_hclk_set(). + * Use sys_hclk_calc() otherwise. + * + * @return Returns saved HCLK frequency (Hz, 0 if not set yet). + */ +uint32_t sys_hclk_get(void) +{ + return hclk_freq; +} + +/** + * @brief Get current HCLK frequency, calculated from hw setting. + * + * @return Returns current HCLK frequency (Hz). + */ +uint32_t sys_hclk_calc(void) +{ + volatile struct sys_registers *sys = (void *)SYS_REG_BASE; + + uint8_t plldiv = sys->CLK_PLL_DIV.pll_div; + + if (sys->CLK_CFG_CTRL.sel_pll == CLK_SEL_PLL_USB_480M) + { + hclk_freq = plldiv ? 480000000 / plldiv : 30000000; + } + else + { + hclk_freq = plldiv ? 30000000 / plldiv : 2000000; + } + + return hclk_freq; +} diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/Kconfig b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/Kconfig new file mode 100644 index 000000000..5f473df64 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/Kconfig @@ -0,0 +1,6 @@ +menuconfig BSP_USING_USBD + bool "Using usbd device" + default y + if BSP_USING_USBD + source "$BSP_DIR/third_party_driver/usb/usbd/Kconfig" + endif diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/Makefile b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/Makefile new file mode 100644 index 000000000..3358dc1a0 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/Makefile @@ -0,0 +1,5 @@ +ifeq ($(CONFIG_BSP_USING_USBD),y) + SRC_DIR += usbd +endif + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/Kconfig b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/Kconfig new file mode 100644 index 000000000..31c0c6fd6 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/Kconfig @@ -0,0 +1,3 @@ +menuconfig BSP_USING_USBD_CDC + bool "Using usbd cdc device" + default y diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/Makefile b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/Makefile new file mode 100644 index 000000000..3ca5a9b37 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/Makefile @@ -0,0 +1,5 @@ +ifeq ($(CONFIG_BSP_USING_USBD_CDC),y) + SRC_DIR += simulate_cdc +endif + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/CDC/cdc.c b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/CDC/cdc.c new file mode 100644 index 000000000..5b0ce329c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/CDC/cdc.c @@ -0,0 +1,337 @@ +/********************************** (C) COPYRIGHT ******************************* +* File Name : cdc.c +* Author : WCH +* Version : V1.2 +* Date : 2024/07/10 +* Description : +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#include "CH56x_common.h" +#include "CH56x_usb30_LIB.h" +#include "CH56x_usb30.h" +#include "CH56x_usb20.h" +#include "cdc.h" + +/* Global define */ +#define UART_REV_LEN 1024 //uart receive buffer size +#define UART_TIMEOUT 1000 + +/* Global Variable */ +__attribute__ ((aligned(16))) UINT8 Receive_Uart_Buf[UART_REV_LEN] __attribute__((section(".DMADATA")));//uart receive buffer + +volatile UINT16 Uart_Input_Point = 0; //Circular buffer write pointer +volatile UINT16 Uart_Output_Point = 0; //Loop buffer fetch pointer +volatile UINT16 UartByteCount = 0; //The number of bytes remaining to be fetched in the current buffer +volatile UINT16 USBByteCount = 0; //Data received by USB endpoint +volatile UINT16 USBBufOutPoint = 0; //Get data pointer +volatile UINT8 UploadPoint2_Busy = 0; //Upload whether the endpoint is busy +volatile UINT8 DownloadPoint2_Busy = 0; //Download whether the endpoint is busy +volatile UINT16 Uart_Timecount = 0; //Timeout processing calculation time +volatile UINT16 Uart_Sendlenth = 0; //USB upload data length +/* Function declaration */ +void TMR2_IRQHandler (void) __attribute__((interrupt())); +void UART2_IRQHandler (void) __attribute__((interrupt())); + +/******************************************************************************* + * @fn CDC_Uart_Init + * + * @brief CDC UART initialization + * + * @param baudrate: UART2 communication baud rate. + * + * @return None + */ +void CDC_Uart_Init( UINT32 baudrate ) +{ + UINT32 x; + UINT32 t = FREQ_SYS; + x = 10 * t * 2 / 16 / baudrate; + x = ( x + 5 ) / 10; + R8_UART2_DIV = 1; + R16_UART2_DL = x; + R8_UART2_FCR = RB_FCR_FIFO_TRIG | RB_FCR_TX_FIFO_CLR | RB_FCR_RX_FIFO_CLR | RB_FCR_FIFO_EN; + R8_UART2_LCR = RB_LCR_WORD_SZ; + R8_UART2_IER = RB_IER_TXD_EN; + + GPIOA_SetBits(GPIO_Pin_3); + GPIOA_ModeCfg(GPIO_Pin_2, GPIO_ModeIN_PU_NSMT); + GPIOA_ModeCfg(GPIO_Pin_3, GPIO_Slowascent_PP_8mA); + UART2_ByteTrigCfg( UART_7BYTE_TRIG ); + UART2_INTCfg( ENABLE, RB_IER_RECV_RDY|RB_IER_LINE_STAT ); + PFIC_EnableIRQ( UART2_IRQn ); +} + + +/******************************************************************************* + * @fn TMR2_TimerInit1 + * + * @brief CDC timeout timer initialization + * + * @return None + */ +void TMR2_TimerInit1( void ) +{ + R32_TMR2_CNT_END = FREQ_SYS/100000; //10us + R8_TMR2_CTRL_MOD = RB_TMR_ALL_CLEAR; + R8_TMR2_CTRL_MOD = RB_TMR_COUNT_EN; + R8_TMR2_INTER_EN |= 0x01; + PFIC_EnableIRQ( TMR2_IRQn ); +} + +/******************************************************************************* + * @fn TMR2_IRQHandler + * + * @brief CDC timer interrupt function + * + * @return None + */ +void TMR2_IRQHandler( void ) +{ + if( R8_TMR2_INT_FLAG &0x01 ) + { + R8_TMR2_INT_FLAG = 0x01; + Uart_Timecount++; + } +} + +/******************************************************************************* + * @fn U30_CDC_UartRx_Deal + * + * @brief usb3.0 CDC serial port receiving data processing + * + * @return None + */ +void U30_CDC_UartRx_Deal( void ) +{ + if(!UploadPoint2_Busy) + { + Uart_Sendlenth = UartByteCount; + if(Uart_Sendlenth > 0) + { + if( (Uart_Sendlenth >= (UART_REV_LEN/2) && DownloadPoint2_Busy == 0 ) || Uart_Timecount > UART_TIMEOUT )//If the sent data overflows or times out, upload the data + { + if(Uart_Output_Point+Uart_Sendlenth>UART_REV_LEN)//Determine if the pointer to the stored data array is out of bounds + { + Uart_Sendlenth = UART_REV_LEN-Uart_Output_Point; + } + + if(Uart_Sendlenth > (UART_REV_LEN/2))//Limit sending length + { + Uart_Sendlenth = (UART_REV_LEN/2); + } + + UartByteCount -= Uart_Sendlenth;//Reduce the length of data to be sent + memcpy(endp2Txbuff,&Receive_Uart_Buf[Uart_Output_Point],Uart_Sendlenth);//Copy the data to be sent to the USB buffer + Uart_Output_Point+=Uart_Sendlenth;//Move buffer pointer + + if(Uart_Output_Point>=UART_REV_LEN) + { + Uart_Output_Point = 0; + } + + UploadPoint2_Busy = 1; + /* Start USB sending */ + USB30_IN_ClearIT( ENDP_2 ); + USB30_IN_Set( ENDP_2 , ENABLE , ACK , 1, Uart_Sendlenth); + USB30_Send_ERDY( ENDP_2 | IN , 1 ); + + Uart_Timecount = 0; + } + } + } +} + +/******************************************************************************* + * @fn U20_CDC_UartRx_Deal + * + * @brief usb2.0 CDC serial port receiving data processing + * + * @return None + */ +void U20_CDC_UartRx_Deal( void ) +{ + UINT16 i= 0; + if(!UploadPoint2_Busy) + { + Uart_Sendlenth = UartByteCount; + if(Uart_Sendlenth>0) + { + + if( (Uart_Sendlenth >= (UART_REV_LEN/4)) || Uart_Timecount > UART_TIMEOUT ) + { + if(Uart_Output_Point+Uart_Sendlenth>UART_REV_LEN) + { + Uart_Sendlenth = UART_REV_LEN - Uart_Output_Point; + } + if(Uart_Sendlenth > (UART_REV_LEN/4)) + { + Uart_Sendlenth = (UART_REV_LEN/4); + } + + UartByteCount -= Uart_Sendlenth; + memcpy(endp2Txbuff,&Receive_Uart_Buf[Uart_Output_Point],Uart_Sendlenth); + Uart_Output_Point+=Uart_Sendlenth; + if(Uart_Output_Point>=UART_REV_LEN) + { + Uart_Output_Point = 0; + } + + UploadPoint2_Busy = 1; + + R16_UEP2_T_LEN = Uart_Sendlenth; + R8_UEP2_TX_CTRL = (R8_UEP2_TX_CTRL & ~RB_UEP_TRES_MASK) | UEP_T_RES_ACK; + + Uart_Timecount = 0; + } + } + } +} + +/******************************************************************************* + * @fn U30_CDC_UartTx_Deal + * + * @brief usb3.0 CDC serial port sending data processing + * + * @return None + */ +void U30_CDC_UartTx_Deal( void ) +{ + static UINT16 i = 0; + + if(USBByteCount)//If there is any remaining data to be downloaded, it will be sent through the uart + { + UART2_SendString(&endp2Rxbuff[USBBufOutPoint++],1); + USBByteCount --; + } + + if( DownloadPoint2_Busy == 0 ) + { + if(USBByteCount == 0 && UploadPoint2_Busy == 0)//Allow Next Send + { + USBBufOutPoint = 0; + DownloadPoint2_Busy = 1; + USBSS->UEP2_RX_DMA = (UINT32)(UINT8 *)endp2Rxbuff; + USB30_OUT_ClearIT(ENDP_2); + USB30_OUT_Set( ENDP_2 , ACK , 1 ); + USB30_Send_ERDY( ENDP_2 | OUT , 1 ); + } + } +} + +/******************************************************************************* + * @fn U20_CDC_UartTx_Deal + * + * @brief usb2.0 CDC serial port sending data processing + * + * @return None + */ +void U20_CDC_UartTx_Deal( void ) +{ + static UINT16 i = 0; + if(USBByteCount) + { + UART2_SendString(&endp2Rxbuff[USBBufOutPoint++],1); + + USBByteCount--; + if(USBByteCount==0){ + USBBufOutPoint = 0; + R32_UEP2_RX_DMA = (UINT32)(UINT8 *)endp2Rxbuff; + R8_UEP2_RX_CTRL = (R8_UEP2_RX_CTRL &~RB_UEP_RRES_MASK)|UEP_R_RES_ACK; + } + } +} + +/******************************************************************************* + * @fn CDC_Uart_Deal + * + * @brief CDC processing function + * + * @return None + */ +void CDC_Uart_Deal( void ) +{ + if( Link_Sta == LINK_STA_1)//2.0 + { + U20_CDC_UartTx_Deal(); + U20_CDC_UartRx_Deal(); + } + else + { + U30_CDC_UartTx_Deal(); + U30_CDC_UartRx_Deal(); + } +} + +/******************************************************************************* + * @fn CDC_Variable_Clear + * + * @brief CDC variable initialization + * + * @return None + */ +void CDC_Variable_Clear(void){ + Uart_Input_Point = 0; + Uart_Output_Point = 0; + UartByteCount = 0; + USBByteCount = 0; + USBBufOutPoint = 0; + UploadPoint2_Busy = 0; + Uart_Timecount = 0; + Uart_Sendlenth = 0; +} + +/******************************************************************************* + * @fn UART2_IRQHandler + * + * @brief CDC serial port interrupt function + * + * @return None + */ +void UART2_IRQHandler(void) +{ + UINT8 i,rec_length; + UINT8 rec[7] = {0}; + + switch( UART2_GetITFlag() ) + { + case UART_II_LINE_STAT: //Line status error + printf("error:%x\n",R8_UART2_LSR); + break; + + case UART_II_RECV_RDY: //Data reaches the trigger point + for(rec_length = 0; rec_length < 7; rec_length++) + { + Receive_Uart_Buf[Uart_Input_Point++] = UART2_RecvByte(); + if(Uart_Input_Point>=UART_REV_LEN ) + { + Uart_Input_Point = 0; + } + } + UartByteCount += rec_length; + Uart_Timecount = 0; + + break; + case UART_II_RECV_TOUT: //Receive timeout + rec_length = UART2_RecvString(rec); + for(i = 0; i < rec_length ; i++) + { + Receive_Uart_Buf[Uart_Input_Point++] = rec[i]; + if(Uart_Input_Point>=UART_REV_LEN ) + { + Uart_Input_Point = 0; + } + } + UartByteCount += i; + Uart_Timecount = 0; + break; + + case UART_II_THR_EMPTY: //Send buffer empty + break; + + default: + break; + } +} diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/Makefile b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/Makefile new file mode 100644 index 000000000..aba78b0ef --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_cdc.c USB20/CH56x_usb20.c USB30/CH56x_usb30.c CDC/cdc.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB20/CH56x_usb20.c b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB20/CH56x_usb20.c new file mode 100644 index 000000000..5d8204ec4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB20/CH56x_usb20.c @@ -0,0 +1,756 @@ +/********************************** (C) COPYRIGHT ******************************* +* File Name : CH56x_usb20.c +* Author : WCH +* Version : V1.2 +* Date : 2024/07/10 +* Description : +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#include "CH56x_common.h" +#include "CH56x_usb20.h" +#include "CH56x_usb30.h" +#include "CH56x_usb30_LIB.h" +#include "cdc.h" + +/* Global Variable */ +UINT32V U20_vitrul_buad = 115200; +UINT16V U20_EndpnMaxSize = 512; +UINT16V SetupReqLen=0; //Host request data length +UINT16V SetupLen = 0; //Data length actually sent or received in data phase +UINT32V seq_num = 0; +DevInfo_Typedef g_devInfo; +static UINT8V SetupReqType = 0; //Host request descriptor type +static UINT8V SetupReq = 0; //Host request descriptor type +static PUINT8 pDescr; +extern UINT8V Link_Sta; + +__attribute__ ((aligned(16))) UINT8 vendor_buff[16] __attribute__((section(".DMADATA"))); +/* Function declaration */ +void USBHS_IRQHandler(void) __attribute__((interrupt())); + +const UINT8 hs_device_descriptor[] = +{ + 0x12, // bLength + 0x01, // DEVICE descriptor type + 0x00, // 2.00 + 0x02, + 0x02, // device class + 0x00, // device sub-class + 0x00, // vendor specific protocol + 0x40, // max packet size 64B + 0x86, // vendor id-0x1A86(qinheng) + 0x1A, + 0x0c, // product id 0xfe0c + 0xfe, + 0x01, //bcdDevice 0x01 + 0x00, + 0x01, // manufacturer index string + 0x02, // product index string + 0x03, // serial number index string + 0x01 // number of configurations +}; + +const UINT8 hs_config_descriptor[] = +{ + 0x09, // length of this descriptor + 0x02, // CONFIGURATION (2) + 0x43, // total length includes endpoint descriptors (should be 1 more than last address) + 0x00, // total length high byte + 0x02, // number of interfaces + 0x01, // configuration value for this one + 0x00, // configuration - string is here, 0 means no string + 0x80, // attributes - bus powered, no wakeup + 0x32, // max power - 800 ma is 100 (64 hex) + + /*control interface*/ + 0x09, // length of the interface descriptor + 0x04, // INTERFACE (4) + 0x00, // Zero based index 0f this interface + 0x00, // Alternate setting value (?) + 0x01, // Number of endpoints (not counting 0) + 0x02, // Interface class, ff is vendor specific + 0x02, // Interface sub-class + 0x01, // Interface protocol + 0x00, // Index to string descriptor for this interface + + /*Header Functional Descriptor*/ + 0x05, /* bLength: Endpoint Descriptor size */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x00, /* bDescriptorSubtype: Header Func Desc */ + 0x10, /* bcdCDC: spec release number */ + 0x01, + /*Call Management Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x01, /* bDescriptorSubtype: Call Management Func Desc */ + 0x00, + 0x01, + + 0x04, + 0x24, + 0x02, + 0x02, + + 0x05, + 0x24, + 0x06, + 0x00, + 0x01, + + + 0x07, // length of this endpoint descriptor + 0x05, // ENDPOINT (5) + 0x81, // endpoint direction (80 is in) and address + 0x03, // transfer type - 00 = control, 01 = iso, 10 = bulk, 11 = int + 0x40, // max packet size - 1024 bytes + 0x00, // max packet size - high + 0x01, // polling interval in milliseconds (1 for iso) + + + /*data interface*/ + 0x09, // length of the interface descriptor + 0x04, // INTERFACE (4) + 0x01, // Zero based index 0f this interface + 0x00, // Alternate setting value (?) + 0x02, // Number of endpoints (not counting 0) + 0x0a, // Interface class, ff is vendor specific + 0x00, // Interface sub-class + 0x00, // Interface protocol + 0x00, // Index to string descriptor for this interface + + //Endpoint 2 Descriptor + 0x07, // length of this endpoint descriptor + 0x05, // ENDPOINT (5) + 0x82, // endpoint direction (80 is in) and address + 0x02, // transfer type - 00 = control, 01 = iso, 10 = bulk, 11 = int + 0x00, // max packet size - 1024 bytes + 0x02, // max packet size - high + 0x00, // polling interval in milliseconds (1 for iso) + + + //endp2_descriptor + 0x07, // length of this endpoint descriptor + 0x05, // ENDPOINT (5) + 0x02, // endpoint direction (00 is out) and address + 0x02, // transfer type - 00 = control, 01 = iso, 10 = bulk, 11 = int + 0x00, // max packet size - 1024 bytes + 0x02, // max packet size - high + 0x00, // polling interval in milliseconds (1 for iso) + +}; + +/* Language Descriptor */ +const UINT8 hs_string_descriptor0[] = +{ + 0x04, // this descriptor length + 0x03, // descriptor type + 0x09, // Language ID 0 low byte + 0x04 // Language ID 0 high byte +}; + +/* Manufacturer Descriptor */ +const UINT8 hs_string_descriptor1[] = +{ + 0x08, // length of this descriptor + 0x03, + 'W', + 0x00, + 'C', + 0x00, + 'H', + 0x00 +}; + +/* Product Descriptor */ +const UINT8 hs_string_descriptor2[]= +{ + 38, //38 bytes + 0x03, //0x03 + 0x57, 0x00, //W + 0x43, 0x00, //C + 0x48, 0x00, //H + 0x20, 0x00, // + 0x55, 0x00, //U + 0x53, 0x00, //S + 0x42, 0x00, //B + 0x32, 0x00, //2 + 0x2e, 0x00, //. + 0x30, 0x00, //0 + 0x20, 0x00, // + 0x44, 0x00, //D + 0x45, 0x00, //E + 0x56, 0x00, //V + 0x49, 0x00, //I + 0x43, 0x00, //C + 0x45, 0x00, //E + 0x20, 0x00 // +}; + + +const UINT8 hs_bos_descriptor[] = +{ + 0x05, // length of this descriptor + 0x0f, // CONFIGURATION (2) + 0x16, // total length includes endpoint descriptors (should be 1 more than last address) + 0x00, // total length high byte + 0x02, // number of device cap + + 0x07, + 0x10, // DEVICE CAPABILITY type + 0x02, // USB2.0 EXTENSION + 0x02, + 0x00, + 0x00, + 0x00, + + 0x0a, // length of this descriptor + 0x10, // DEVICE CAPABILITY type + 0x03, // superspeed usb device capability + 0x00, // + 0x0e, // ss/hs/fs + 0x00, + 0x01, // the lowest speed is full speed + 0x0a, // u1 exit latency is 10us + 0xff, // u1 exit latency is 8us + 0x07 +}; + + + +/******************************************************************************* + * @fn USB20_Endp_Init + * + * @brief USB2.0 Endpoint initialization + * + * @return None + */ +void USB20_Endp_Init () // USBHS device endpoint initial +{ + R8_UEP4_1_MOD = RB_UEP1_TX_EN; + R8_UEP2_3_MOD = RB_UEP2_RX_EN | RB_UEP2_TX_EN ; + + R16_UEP0_MAX_LEN = 64; + R16_UEP1_MAX_LEN = 512; + R16_UEP2_MAX_LEN = 512; + + R32_UEP0_RT_DMA = (UINT32)(UINT8 *)endp0RTbuff; + R32_UEP1_TX_DMA = (UINT32)(UINT8 *)endp1RTbuff; + R32_UEP2_TX_DMA = (UINT32)(UINT8 *)endp2Txbuff; + R32_UEP2_RX_DMA = (UINT32)(UINT8 *)endp2Rxbuff; + + R16_UEP0_T_LEN = 0; + R8_UEP0_TX_CTRL = UEP_T_RES_NAK; + R8_UEP0_RX_CTRL = 0; + + R16_UEP1_T_LEN = 0; + R8_UEP1_TX_CTRL = UEP_T_RES_NAK ; + + R16_UEP2_T_LEN = U20_MAXPACKET_LEN; + R8_UEP2_TX_CTRL = UEP_T_RES_NAK | RB_UEP_T_TOG_0; + R8_UEP2_RX_CTRL = UEP_R_RES_ACK | RB_UEP_R_TOG_0; + +} + +/******************************************************************************* + * @fn USB20_Device_Init + * + * @brief USB2.0 Device initialization + * + * @param sta - ENABLE / DISABLE + * + * @return None + */ +void USB20_Device_Init ( FunctionalState sta ) // USBHS device initial +{ + UINT16 i; + UINT32 *p; + if(sta) + { + R8_USB_CTRL = 0; + R8_USB_CTRL = UCST_HS | RB_DEV_PU_EN | RB_USB_INT_BUSY |RB_USB_DMA_EN; + R8_USB_INT_EN = RB_USB_IE_SETUPACT | RB_USB_IE_TRANS | RB_USB_IE_SUSPEND |RB_USB_IE_BUSRST ; + USB20_Endp_Init(); + } + else + { + R8_USB_CTRL = RB_USB_CLR_ALL | RB_USB_RESET_SIE; + } +} + +/******************************************************************************* + * @fn USB20_Device_setaddress + * + * @brief USB2.0 Set device address + * + * @param address + * + * @return None + **/ +void USB20_Device_Setaddress( UINT32 address ) +{ + R8_USB_DEV_AD = address; // SET ADDRESS +} + +/******************************************************************************* + * @fn U20_NonStandard_Request_Deal + * + * @brief Non-standard request processing + * + * @return None + */ +UINT16 U20_NonStandard_Request_Deal() +{ + UINT16 len = 0; + switch( UsbSetupBuf->bRequest ) + { + /* Open the serial port and send the baud rate */ + case 0x20: + R8_UEP0_RX_CTRL = UEP_R_RES_ACK | RB_UEP_R_TOG_1; + break; + /* Read the current serial port configuration */ + case 0x21: + *(UINT32 *)&endp0RTbuff[0] = U20_vitrul_buad; + endp0RTbuff[4]=0x00;endp0RTbuff[5]=0x00;endp0RTbuff[6]=0x08; + len = 7; + break; + /* Close uart */ + case 0x22: + CDC_Variable_Clear(); + break; + case 0x02: + break; + default: + return USB_DESCR_UNSUPPORTED; + break; + } + return len; +} + +/******************************************************************************* + * @fn U20_Standard_Request_Deal + * + * @brief USB2.0 standard request deal + * + * @return None + */ +UINT16 U20_Standard_Request_Deal() +{ + UINT16 len = 0; + UINT8 endp_dir; + SetupLen = 0; + endp_dir = UsbSetupBuf->bRequestType & 0x80; + switch( SetupReq ) + { + case USB_GET_DESCRIPTOR: + { + switch( UsbSetupBuf->wValueH ) + { + case USB_DESCR_TYP_DEVICE: + pDescr = (UINT8 *)hs_device_descriptor; + SetupLen = ( SetupReqLen > sizeof(hs_device_descriptor) )? sizeof(hs_device_descriptor):SetupReqLen; + break; + case USB_DESCR_TYP_CONFIG: + pDescr = (UINT8 *)hs_config_descriptor; + SetupLen = ( SetupReqLen > sizeof(hs_config_descriptor) )? sizeof(hs_config_descriptor):SetupReqLen; + break; + case USB_DESCR_TYP_STRING: + switch( UsbSetupBuf->wValueL ) + { + case USB_DESCR_LANGID_STRING: + + pDescr = (UINT8 *)hs_string_descriptor0; + SetupLen = ( SetupReqLen > sizeof(hs_string_descriptor0) )? sizeof(hs_string_descriptor0):SetupReqLen; + break; + case USB_DESCR_VENDOR_STRING: + pDescr = (UINT8 *)hs_string_descriptor1; + SetupLen = ( SetupReqLen > sizeof(hs_string_descriptor1) )? sizeof(hs_string_descriptor1):SetupReqLen; + break; + case USB_DESCR_PRODUCT_STRING: + pDescr =(UINT8 *) hs_string_descriptor2; + SetupLen = ( SetupReqLen > sizeof(hs_string_descriptor2) )? sizeof(hs_string_descriptor2):SetupReqLen; + break; + case USB_DESCR_SERIAL_STRING: + break; + default: + SetupLen = USB_DESCR_UNSUPPORTED; + break; + } + break; + case USB_DESCR_TYP_BOS: + pDescr =(UINT8 *) hs_bos_descriptor; + SetupLen = ( SetupReqLen > sizeof(hs_bos_descriptor) )? sizeof(hs_bos_descriptor):SetupReqLen; + break; + + default : + SetupLen = USB_DESCR_UNSUPPORTED; + break; + } + } + break; + case USB_SET_ADDRESS: + g_devInfo.dev_addr = UsbSetupBuf->wValueL; + break; + case USB_GET_CONFIGURATION: + endp0RTbuff[ 0 ] = g_devInfo.dev_config_value; + SetupLen = 1; + break; + + case USB_SET_CONFIGURATION: + if( (R8_USB_SPD_TYPE & RB_USBSPEED_MASK) == UST_FS ) + { + U20_EndpnMaxSize = 64; + } + else if( (R8_USB_SPD_TYPE & RB_USBSPEED_MASK) == UST_LS ) + { + U20_EndpnMaxSize = 8; + } + g_devInfo.dev_config_value = UsbSetupBuf->wValueL; + g_devInfo.dev_enum_status = 0x01; + break; + case USB_CLEAR_FEATURE: + if( ( UsbSetupBuf->bRequestType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_ENDP ) + { + switch( UsbSetupBuf->wIndexL ) + { + case 0x82: + R16_UEP2_T_LEN= 0; + R8_UEP2_TX_CTRL = UEP_T_RES_NAK | RB_UEP_T_TOG_0; + break; + case 0x02: + R8_UEP2_TX_CTRL = UEP_R_RES_ACK | RB_UEP_R_TOG_0; + break; + case 0x81: + R16_UEP1_T_LEN = 0; + R8_UEP1_TX_CTRL = UEP_T_RES_NAK | RB_UEP_T_TOG_0; + break; + case 0x01: + R8_UEP1_RX_CTRL = UEP_T_RES_ACK | RB_UEP_R_TOG_0; + break; + default: + SetupLen = USB_DESCR_UNSUPPORTED; + break; + } + } + else if( ( UsbSetupBuf->bRequestType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_DEVICE ) + { + if( ( UsbSetupBuf->wValueL ) == 1 ) + { + g_devInfo.dev_sleep_status &= ~0x01; + } + } + else + { + SetupLen = USB_DESCR_UNSUPPORTED; + } + break; + case USB_SET_FEATURE: + if( ( UsbSetupBuf->bRequestType & 0x1F ) == 0x00 ) + { + if( UsbSetupBuf->wValueL == 0x01 ) + { + if( hs_config_descriptor[ 7 ] & 0x20 ) + { + g_devInfo.dev_sleep_status = 0x01; + } + else + { + SetupLen = USB_DESCR_UNSUPPORTED; + } + } + else + { + SetupLen = USB_DESCR_UNSUPPORTED; + } + } + else if( ( UsbSetupBuf->bRequestType & 0x1F ) == 0x02 ) + { + if( UsbSetupBuf->wValueL == 0x00 ) + { + switch( UsbSetupBuf->wIndexL ) + { + case 0x82: + R8_UEP2_TX_CTRL = ( R8_UEP2_TX_CTRL & ~RB_UEP_TRES_MASK ) | UEP_T_RES_STALL; + break; + + case 0x02: + R8_UEP2_RX_CTRL = ( R8_UEP2_RX_CTRL & ~RB_UEP_RRES_MASK ) | UEP_R_RES_STALL; + break; + + case 0x81: + R8_UEP1_TX_CTRL = ( R8_UEP1_TX_CTRL & ~RB_UEP_TRES_MASK ) | UEP_T_RES_STALL; + break; + + case 0x01: + R8_UEP1_RX_CTRL = ( R8_UEP1_RX_CTRL & ~RB_UEP_RRES_MASK ) | UEP_R_RES_STALL; + break; + + default: + SetupLen = USB_DESCR_UNSUPPORTED; + break; + } + } + else + { + SetupLen = USB_DESCR_UNSUPPORTED; + } + } + else + { + SetupLen = USB_DESCR_UNSUPPORTED; + } + break; + case USB_GET_INTERFACE: + break; + case USB_SET_INTERFACE: + break; + case USB_GET_STATUS: + endp0RTbuff[ 0 ] = 0x00; + endp0RTbuff[ 1 ] = 0x00; + SetupLen = 2; + if( UsbSetupBuf->wIndexL == 0x81 ) + { + if( ( R8_UEP1_TX_CTRL & RB_UEP_TRES_MASK ) == UEP_T_RES_STALL ) + { + endp0RTbuff[ 0 ] = 0x01; + SetupLen = 1; + } + } + else if( UsbSetupBuf->wIndexL == 0x01 ) + { + if( ( R8_UEP1_RX_CTRL & RB_UEP_RRES_MASK ) == UEP_R_RES_STALL ) + { + endp0RTbuff[ 0 ] = 0x01; + SetupLen = 1; + } + } + else if( UsbSetupBuf->wIndexL == 0x82 ) + { + if( ( R8_UEP2_TX_CTRL & RB_UEP_TRES_MASK ) == UEP_T_RES_STALL ) + { + endp0RTbuff[ 0 ] = 0x01; + SetupLen = 1; + } + } + else if( UsbSetupBuf->wIndexL == 0x02 ) + { + if( ( R8_UEP2_RX_CTRL & RB_UEP_RRES_MASK ) == UEP_R_RES_STALL ) + { + endp0RTbuff[ 0 ] = 0x01; + SetupLen = 1; + } + } + break; + default: + SetupLen = USB_DESCR_UNSUPPORTED; + break; + } + + if( (SetupLen != USB_DESCR_UNSUPPORTED) && (SetupLen != 0)) + { + len = ( SetupLen >= U20_UEP0_MAXSIZE ) ? U20_UEP0_MAXSIZE : SetupLen; + if(endp_dir) + { + memcpy( endp0RTbuff, pDescr, len ); + pDescr += len; + } + SetupLen -= len; + } + return len; +} + +/******************************************************************************* + * @fn USBHSD_IRQHandler + * + * @brief USB2.0 Interrupt Handler. + * + * @return None + */ +void USBHS_IRQHandler(void) //USBHS interrupt service +{ + UINT32 end_num; + UINT32 rx_token; + UINT16 ret_len,i; + UINT16 rxlen; + UINT8 *p8; + UINT8 int_flg; + UINT32 baudrate; + + int_flg = R8_USB_INT_FG; + if( int_flg & RB_USB_IF_SETUOACT ) //SETUP interrupt + { +#if 0 + printf("SETUP :"); + p8 = (UINT8 *)endp0RTbuff; + for(i=0; i<8; i++) { printf("%02x ", *p8++); } + printf("\n"); +#endif + SetupReqType = UsbSetupBuf->bRequestType; + SetupReq = UsbSetupBuf->bRequest; + SetupReqLen = UsbSetupBuf->wLength; //Data length + + /*Analyze host requests*/ + if((UsbSetupBuf->bRequestType & USB_REQ_TYP_MASK) != USB_REQ_TYP_STANDARD) + { + ret_len = U20_NonStandard_Request_Deal(); + } + else + { + ret_len = U20_Standard_Request_Deal(); + } + if(ret_len == 0xFFFF) + { + R16_UEP0_T_LEN = 0; + R8_UEP0_TX_CTRL = UEP_T_RES_STALL ; + R8_UEP0_RX_CTRL = UEP_R_RES_STALL ; + } + else + { + R16_UEP0_T_LEN = ret_len; + R8_UEP0_TX_CTRL = UEP_T_RES_ACK | RB_UEP_T_TOG_1; + R8_UEP0_RX_CTRL = UEP_R_RES_ACK | RB_UEP_R_TOG_1; + } + R8_USB_INT_FG = RB_USB_IF_SETUOACT; // clear int flag + } + /*Transaction transfer complete interrupt*/ + else if( int_flg & RB_USB_IF_TRANSFER ) + { + end_num = R8_USB_INT_ST & 0xf; + rx_token = ( (R8_USB_INT_ST )>>4) & 0x3; +#if 0 + if( !(R8_USB_INT_ST & RB_USB_ST_TOGOK) ) + { + printf(" TOG MATCH FAIL : ENDP %x token %x \n", end_num, rx_token); + } +#endif + switch( end_num ) + { + case 0: + if( rx_token == PID_IN ) + { + ret_len = U20_Endp0_IN_Callback(); + if(ret_len == 0) + { + R8_UEP0_RX_CTRL = UEP_R_RES_ACK | RB_UEP_R_TOG_1; + R16_UEP0_T_LEN = 0; + R8_UEP0_TX_CTRL = 0; + } + else + { + R16_UEP0_T_LEN = ret_len; + R8_UEP0_TX_CTRL ^= RB_UEP_T_TOG_1; + R8_UEP0_TX_CTRL = ( R8_UEP0_TX_CTRL &~RB_UEP_TRES_MASK )| UEP_T_RES_ACK ; + } + } + else if( rx_token == PID_OUT ) + { + SetupLen -= SetupLen > R16_USB_RX_LEN ? R16_USB_RX_LEN :SetupLen; + if( SetupLen > 0 ) + { + R8_UEP0_RX_CTRL ^=RB_UEP_R_TOG_1; + R8_UEP0_RX_CTRL = ( R8_UEP0_RX_CTRL &~RB_UEP_RRES_MASK) | UEP_R_RES_ACK; + + } + else + { + R16_UEP0_T_LEN = 0; + R8_UEP0_TX_CTRL = UEP_T_RES_ACK | RB_UEP_T_TOG_1; + R8_UEP0_RX_CTRL = 0 ; + } + + /* save bauds */ + baudrate = endp0RTbuff[ 0 ]; + baudrate += ((UINT32)endp0RTbuff[ 1 ] << 8 ); + baudrate += ((UINT32)endp0RTbuff[ 2 ] << 16 ); + baudrate += ((UINT32)endp0RTbuff[ 3 ] << 24 ); + + U20_vitrul_buad = baudrate; + + CDC_Uart_Init(baudrate); + + } + break; + case 1: + break; + case 2: + if(rx_token == PID_IN) + { + R16_UEP2_T_LEN = 0; + R8_UEP2_TX_CTRL ^= RB_UEP_T_TOG_1; + R8_UEP2_TX_CTRL = (R8_UEP2_TX_CTRL & ~RB_UEP_TRES_MASK) | UEP_T_RES_NAK; + UploadPoint2_Busy = 0; + } + else if(rx_token == PID_OUT) + { + USBByteCount = R16_USB_RX_LEN; + R8_UEP2_RX_CTRL ^= RB_UEP_R_TOG_1; + R8_UEP2_RX_CTRL = (R8_UEP2_RX_CTRL &~RB_UEP_RRES_MASK) | UEP_R_RES_NAK; + } + break; + case 3: + break; + case 4: + break; + case 5: + break; + case 6: + break; + case 7: + break; + default: + break; + + } + R8_USB_INT_FG = RB_USB_IF_TRANSFER; + } + else if( int_flg & RB_USB_IF_BUSRST ) + { + USB20_Endp_Init(); + USB20_Device_Setaddress( 0 ); + R8_USB_INT_FG = RB_USB_IF_BUSRST; + if( Link_Sta == LINK_STA_1 ) + { + PFIC_EnableIRQ(USBSS_IRQn); + PFIC_EnableIRQ(LINK_IRQn); + PFIC_EnableIRQ(TMR0_IRQn); + R8_TMR0_INTER_EN = 1; + TMR0_TimerInit( 67000000 ); + USB30D_init(ENABLE); + } + } + else if( int_flg & RB_USB_IF_SUSPEND ) + { + R8_USB_INT_FG = RB_USB_IF_SUSPEND; + } +} + +/******************************************************************************* + * @fn U20_Endp0_IN_Callback + * + * @brief U20_Endp0_IN_Callback Handler. + * + * @return None + */ +UINT16 U20_Endp0_IN_Callback(void) +{ + UINT16 len = 0; + switch(SetupReq) + { + case USB_GET_DESCRIPTOR: + len = SetupLen >= U20_UEP0_MAXSIZE ? U20_UEP0_MAXSIZE : SetupLen; + memcpy(endp0RTbuff, pDescr, len); + SetupLen -= len; + pDescr += len; + break; + case USB_SET_ADDRESS: + USB20_Device_Setaddress(g_devInfo.dev_addr); + break; + default: + break; + } + return len; +} + + diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB30/CH56x_usb30.c b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB30/CH56x_usb30.c new file mode 100644 index 000000000..0fc14fb61 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB30/CH56x_usb30.c @@ -0,0 +1,832 @@ +/********************************** (C) COPYRIGHT ******************************* +* File Name : CH56x_usb30.c +* Author : WCH +* Version : V1.2 +* Date : 2024/07/10 +* Description : +********************************************************************************* +* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd. +* Attention: This software (modified or not) and binary are used for +* microcontroller manufactured by Nanjing Qinheng Microelectronics. +*******************************************************************************/ +#include "CH56x_common.h" +#include "CH56x_usb30_LIB.h" +#include "CH56x_usb20.h" +#include "CH56x_usb30.h" +#include "cdc.h" + +/* Global Variable */ +UINT8V Tx_Lmp_Port = 0; +UINT8V Link_Sta = 0; +UINT32V vitrul_buad = 115200; +static UINT32 SetupLen = 0; +static UINT8 SetupReqCode = 0; +static PUINT8 pDescr; +__attribute__ ((aligned(16))) UINT8 endp0RTbuff[512] __attribute__((section(".DMADATA"))); //Endpoint 0 data receiving and sending buffer +__attribute__ ((aligned(16))) UINT8 endp1RTbuff[4096] __attribute__((section(".DMADATA"))); //Endpoint 1 data receiving and sending buffer +__attribute__ ((aligned(16))) UINT8 endp2Rxbuff[4096] __attribute__((section(".DMADATA"))); //Endpoint 2 data receiving and sending buffer +__attribute__ ((aligned(16))) UINT8 endp2Txbuff[4096] __attribute__((section(".DMADATA"))); //Endpoint 2 data receiving and sending buffer + + +/*Superspeed device descriptor*/ +const UINT8 SS_DeviceDescriptor[] = +{ + 0x12, // bLength + 0x01, // DEVICE descriptor type + 0x00, // 3.00 + 0x03, + 0x02, // device class + 0x00, // device sub-class + 0x00, // vendor specific protocol + 0x09, // max packet size 512B + 0x86, // vendor id 0x1a86 + 0x1a, + 0x0c, // product id 0xfe0c + 0xfe, + 0x01, // bcdDevice + 0x00, + 0x01, // manufacturer index string + 0x02, // product index string + 0x03, // serial number index string + 0x01 // number of configurations +}; + +/*Superspeed Configuration Descriptor*/ +const UINT8 SS_ConfigDescriptor[] = +{ + 0x09, // length of this descriptor + 0x02, // CONFIGURATION (2) + 85, // total length includes endpoint descriptors (should be 1 more than last address) + 0x00, // total length high byte + 0x02, // number of interfaces + 0x01, // configuration value for this one + 0x00, // configuration - string is here, 0 means no string + 0x80, // attributes - bus powered, no wakeup + 0x64, // max power - 800 ma is 100 (64 hex) + + + 0x09, // length of the interface descriptor + 0x04, // INTERFACE (4) + 0x00, // Zero based index 0f this interface + 0x00, // Alternate setting value (?) + 0x01, // Number of endpoints (not counting 0) + 0x02, // Interface class, ff is vendor specific + 0x02, // Interface sub-class + 0x01, // Interface protocol + 0x00, // Index to string descriptor for this interface + + 0x05, /* bLength: Endpoint Descriptor size */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x00, /* bDescriptorSubtype: Header Func Desc */ + 0x10, /* bcdCDC: spec release number */ + 0x01, + + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x01, /* bDescriptorSubtype: Call Management Func Desc */ + 0x00, + 0x01, + + 0x04, + 0x24, + 0x02, + 0x02, + + 0x05, + 0x24, + 0x06, + 0x00, + 0x01, + + 0x07, // length of this endpoint descriptor + 0x05, // ENDPOINT (5) + 0x81, // endpoint direction (80 is in) and address + 0x03, // transfer type - 00 = control, 01 = iso, 10 = bulk, 11 = int + 0x00, // max packet size - 1024 bytes + 0x04, // max packet size - high + 0x08, // polling interval in milliseconds (1 for iso) + + 0x06, // length of this endpoint compansion descriptor + 0x30, + 0x00, // max burst size + 0x00, // no stream + 0x00, + 0x00, + + 0x09, // length of the interface descriptor + 0x04, // INTERFACE (4) + 0x01, // Zero based index 0f this interface + 0x00, // Alternate setting value (?) + 0x02, // Number of endpoints (not counting 0) + 0x0a, // Interface class, ff is vendor specific + 0x00, // Interface sub-class + 0x00, // Interface protocol + 0x00, // Index to string descriptor for this interface + + //Endpoint 2 Descriptor + 0x07, // length of this endpoint descriptor + 0x05, // ENDPOINT (5) + 0x82, // endpoint direction (80 is in) and address + 0x02, // transfer type - 00 = control, 01 = iso, 10 = bulk, 11 = int + 0x00, // max packet size - 1024 bytes + 0x04, // max packet size - high + 0x00, // polling interval in milliseconds (1 for iso) + + 0x06, // length of this endpoint compansion descriptor + 0x30, + 0x00, // max burst size + 0x00, // no stream + 0x00, + 0x00, + + //endp2_descriptor + 0x07, // length of this endpoint descriptor + 0x05, // ENDPOINT (5) + 0x02, // endpoint direction (00 is out) and address + 0x02, // transfer type - 00 = control, 01 = iso, 10 = bulk, 11 = int + 0x00, // max packet size - 1024 bytes + 0x04, // max packet size - high + 0x00, // polling interval in milliseconds (1 for iso) + + 0x06, // length of this endpoint compansion descriptor + 0x30, + 0x00, // max burst size + 0x00, // no stream + 0x00, + 0x00 +}; + +/*String Descriptor Lang ID*/ +const UINT8 StringLangID[] = +{ + 0x04, // this descriptor length + 0x03, // descriptor type + 0x09, // Language ID 0 low byte + 0x04 // Language ID 0 high byte +}; + +/*String Descriptor Vendor*/ +const UINT8 StringVendor[] = +{ + 0x08, // length of this descriptor + 0x03, + 'W', + 0x00, + 'C', + 0x00, + 'H', + 0x00 +}; + + +/*String Descriptor Product*/ +const UINT8 StringProduct[]= +{ + 38, //38 bytes in length + 0x03, //Type code + 0x57, 0x00, //W + 0x43, 0x00, //C + 0x48, 0x00, //H + 0x20, 0x00, // + 0x55, 0x00, //U + 0x53, 0x00, //S + 0x42, 0x00, //B + 0x33, 0x00, //3 + 0x2e, 0x00, //. + 0x30, 0x00, //0 + 0x20, 0x00, // + 0x44, 0x00, //D + 0x45, 0x00, //E + 0x56, 0x00, //V + 0x49, 0x00, //I + 0x43, 0x00, //C + 0x45, 0x00, //E + 0x20, 0x00 +}; + +/*String Descriptor Serial*/ +UINT8 StringSerial[] = +{ + 0x16, // length of this descriptor + 0x03, + '0', + 0x00, + '1', + 0x00, + '2', + 0x00, + '3', + 0x00, + '4', + 0x00, + '5', + 0x00, + '6', + 0x00, + '7', + 0x00, + '8', + 0x00, + '9', + 0x00, +}; + +const UINT8 OSStringDescriptor[] = +{ + 0x12, // length of this descriptor + 0x03, + 'M', + 0x00, + 'S', + 0x00, + 'F', + 0x00, + 'T', + 0x00, + '1', + 0x00, + '0', + 0x00, + '0', + 0x00, + 0x01, + 0x00 +}; + +const UINT8 BOSDescriptor[] = +{ + 0x05, // length of this descriptor + 0x0f, // CONFIGURATION (2) + 0x16, // total length includes endpoint descriptors (should be 1 more than last address) + 0x00, // total length high byte + 0x02, // number of device cap + + //dev_cap_descriptor1 + 0x07, + 0x10, // DEVICE CAPABILITY type + 0x02, // USB2.0 EXTENSION + 0x06, + 0x00, + 0x00, + 0x00, + + //dev_cap_descriptor2 + 0x0a, // length of this descriptor + 0x10, // DEVICE CAPABILITY type + 0x03, // superspeed usb device capability + 0x00, // + 0x0e, // ss/hs/fs + 0x00, + 0x01, // the lowest speed is full speed + 0x0a, // u1 exit latency is 10us + 0xff, // u1 exit latency is 8us + 0x07 +}; + +/******************************************************************************* + * @fn USB30D_init + * + * @brief USB3.0 initialization + * + * @return None + */ +void USB30D_init(FunctionalState sta) { + UINT16 i,s; + if (sta) { + USB30_Device_Init(); + + USBSS->UEP0_DMA = (UINT32)(UINT8 *)endp0RTbuff; + USBSS->UEP1_TX_DMA = (UINT32)(UINT8 *)endp1RTbuff; + USBSS->UEP2_TX_DMA = (UINT32)(UINT8 *)endp2Txbuff; + USBSS->UEP2_RX_DMA = (UINT32)(UINT8 *)endp2Rxbuff; + + USBSS->UEP_CFG = EP0_R_EN | EP0_T_EN | EP1_T_EN | EP2_R_EN | EP2_T_EN;// set end point rx/tx enable + + USB30_OUT_Set(ENDP_2, ACK, 1); + + } + else { + USB30_Switch_Powermode(POWER_MODE_2); + USBSS->LINK_CFG = PIPE_RESET | LFPS_RX_PD; + USBSS->LINK_CTRL = GO_DISABLED | POWER_MODE_3; + USBSS->LINK_INT_CTRL = 0; + USB30_Device_forceclr(); + } +} + +/******************************************************************************* + * @fn USB30_NonStandardReq + * + * @brief USB3.0 Nonstandard request processing function + * + * @return Length + */ +UINT16 USB30_NonStandardReq() { + UINT16 len = 0; + + SetupReqCode = UsbSetupBuf->bRequest; + SetupLen = UsbSetupBuf->wLength; + switch (SetupReqCode) { + + /* Open the serial port and send the baud rate */ + case 0x20: + USB30_OUT_Set(ENDP_0, ACK, 1 ); + break; + /* Read the current serial port configuration */ + case 0x21: + *(UINT32 *)&endp0RTbuff[50] = vitrul_buad; + endp0RTbuff[54]=0x00;endp0RTbuff[55]=0x00;endp0RTbuff[56]=0x08; + SetupLen = 7; + break; + /* Close uart */ + case 0x22: + CDC_Variable_Clear(); + break; + default: + printf("stall\n"); + SetupReqCode = INVALID_REQ_CODE; + return USB_DESCR_UNSUPPORTED; + break; + } + len = SetupLen >= ENDP0_MAXPACK ? ENDP0_MAXPACK : SetupLen; + memcpy(endp0RTbuff, &endp0RTbuff[50], len); + SetupLen -= len; + pDescr += len; + return len; +} + +/******************************************************************************* + * @fn USB30_StandardReq + * + * @brief USB3.0 Standard request + * + * @return Length + */ +UINT16 USB30_StandardReq() { + UINT16 len = 0; + + SetupReqCode = UsbSetupBuf->bRequest; + SetupLen = UsbSetupBuf->wLength; + + if (( UsbSetupBuf->bRequestType & USB_REQ_TYP_MASK) != USB_REQ_TYP_STANDARD) + { + len= USB30_NonStandardReq(); + } + else + { + switch (SetupReqCode) { + case USB_GET_DESCRIPTOR: + switch (UsbSetupBuf->wValueH) { + case USB_DESCR_TYP_DEVICE: + if (SetupLen > SIZE_DEVICE_DESC) + SetupLen = SIZE_DEVICE_DESC; + pDescr = (PUINT8) SS_DeviceDescriptor; + break; + case USB_DESCR_TYP_CONFIG: + if (SetupLen > SIZE_CONFIG_DESC) + SetupLen = SIZE_CONFIG_DESC; + pDescr = (PUINT8) SS_ConfigDescriptor; + break; + case USB_DESCR_TYP_BOS: + if (SetupLen > SIZE_BOS_DESC) + SetupLen = SIZE_BOS_DESC; + pDescr = (PUINT8) BOSDescriptor; + break; + case USB_DESCR_TYP_STRING: + switch (UsbSetupBuf->wValueL) { + case USB_DESCR_LANGID_STRING: + if (SetupLen > SIZE_STRING_LANGID) + SetupLen = SIZE_STRING_LANGID; + pDescr = (PUINT8) StringLangID; + break; + case USB_DESCR_VENDOR_STRING: + if (SetupLen > SIZE_STRING_VENDOR) + SetupLen = SIZE_STRING_VENDOR; + pDescr = (PUINT8) StringVendor; + break; + case USB_DESCR_PRODUCT_STRING: + if (SetupLen > SIZE_STRING_PRODUCT) + SetupLen = SIZE_STRING_PRODUCT; + pDescr = (PUINT8) StringProduct; + break; + case USB_DESCR_SERIAL_STRING: + if (SetupLen > SIZE_STRING_SERIAL) + SetupLen = SIZE_STRING_SERIAL; + pDescr = (PUINT8) StringSerial; + break; + case USB_DESCR_OS_STRING: + if (SetupLen > SIZE_STRING_OS) + SetupLen = SIZE_STRING_OS; + pDescr = (PUINT8) OSStringDescriptor; + break; + default: + len = USB_DESCR_UNSUPPORTED; + SetupReqCode = INVALID_REQ_CODE; + break; + } + break; + default: + len = USB_DESCR_UNSUPPORTED; + SetupReqCode = INVALID_REQ_CODE; + break; + } + len = SetupLen >= ENDP0_MAXPACK ? ENDP0_MAXPACK : SetupLen; + memcpy(endp0RTbuff, pDescr, len); + SetupLen -= len; + pDescr += len; + break; + case USB_SET_ADDRESS: + SetupLen = UsbSetupBuf->wValueL; + break; + case 0x31: + SetupLen = UsbSetupBuf->wValueL; + break; + case 0x30: + break; + case USB_SET_CONFIGURATION: + break; + case USB_GET_STATUS: + len = 2; + endp0RTbuff[0] = 0x01; + endp0RTbuff[1] = 0x00; + SetupLen = 0; + break; + case USB_CLEAR_FEATURE: + switch(UsbSetupBuf->wIndexL){ + case 0x82: + USB30_IN_ClearIT( ENDP_2 ); + USB30_IN_Set( ENDP_2 , ENABLE , ACK , 1 , 0); + USB30_Send_ERDY( ENDP_2 | IN , 1 ); + break; + } + break; + case USB_SET_FEATURE: + break; + case USB_SET_INTERFACE: + break; + default: + len = USB_DESCR_UNSUPPORTED; + SetupReqCode = INVALID_REQ_CODE; + printf(" stall \n"); + break; + } + } + return len; +} + +/******************************************************************************* + * @fn EP0_IN_Callback + * + * @brief USB3.0 Endpoint 0 IN transaction callback + * + * @return Send length + */ +UINT16 EP0_IN_Callback(void) { + UINT16 len = 0; + switch (SetupReqCode) { + case USB_GET_DESCRIPTOR: + len = SetupLen >= ENDP0_MAXPACK ? ENDP0_MAXPACK : SetupLen; + memcpy(endp0RTbuff, pDescr, len); + SetupLen -= len; + pDescr += len; + break; + } + return len; +} + +/******************************************************************************* + * @fn EP0_OUT_Callback + * + * @brief USB3.0 Endpoint 0 OUT transaction callback + * + * @return Length + */ +UINT16 EP0_OUT_Callback() { + UINT32 baudrate; + + /* save bauds */ + baudrate = endp0RTbuff[ 0 ]; + baudrate += ((UINT32)endp0RTbuff[ 1 ] << 8 ); + baudrate += ((UINT32)endp0RTbuff[ 2 ] << 16 ); + baudrate += ((UINT32)endp0RTbuff[ 3 ] << 24 ); + + vitrul_buad = baudrate; + + CDC_Uart_Init(baudrate); + + return 0; +} + +/******************************************************************************* + * @fn USB30_Setup_Status + * + * @brief USB3.0 Control transfer status stage callback + * + * @return None + */ +void USB30_Setup_Status(void) { + switch (SetupReqCode) { + case USB_SET_ADDRESS: + USB30_Device_Setaddress(SetupLen); // SET ADDRESS + break; + case 0x31: + break; + } +} + +/******************************************************************************* + * @fn USBSS_IRQHandler + * + * @brief USB3.0 Interrupt Handler. + * + * @return None + */ +void USBSS_IRQHandler (void) //USBSS interrupt service +{ + USB30_IRQHandler(); +} + +/******************************************************************************* + * @fn TMR0_IRQHandler + * + * @brief USB3.0 Connection failure timeout processing + * + * @return None + */ +void TMR0_IRQHandler( ) +{ + R8_TMR0_INTER_EN |= 1; + PFIC_DisableIRQ(TMR0_IRQn); + R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR; + if(Link_Sta == LINK_STA_1 ) + { + Link_Sta =0; + PFIC_DisableIRQ(USBSS_IRQn); + PFIC_DisableIRQ(LINK_IRQn); + USB30D_init(DISABLE); + return; + } + if( Link_Sta != LINK_STA_3 ) + { + PFIC_DisableIRQ(USBSS_IRQn); + PFIC_DisableIRQ(LINK_IRQn); + USB30D_init(DISABLE); + R32_USB_CONTROL = 0; + PFIC_EnableIRQ(USBHS_IRQn); + USB20_Device_Init(ENABLE); + } + Link_Sta = LINK_STA_1; + return; +} + + +/******************************************************************************* + * @fn LINK_IRQHandler + * + * @brief USB3.0 Link Interrupt Handler. + * + * @return None + */ +void LINK_IRQHandler() //USBSS link interrupt service +{ + if(USBSS->LINK_INT_FLAG & LINK_Ux_EXIT_FLAG) // device enter U2 + { + USBSS->LINK_CFG = CFG_EQ_EN | TX_SWING | DEEMPH_CFG | TERM_EN; + USB30_Switch_Powermode(POWER_MODE_0); + USBSS->LINK_INT_FLAG = LINK_Ux_EXIT_FLAG; + } + if(USBSS->LINK_INT_FLAG & LINK_RDY_FLAG) // POLLING SHAKE DONE + { + USBSS->LINK_INT_FLAG = LINK_RDY_FLAG; + if(Tx_Lmp_Port) // LMP, TX PORT_CAP & RX PORT_CAP + { + USBSS->LMP_TX_DATA0 = LINK_SPEED | PORT_CAP | LMP_HP; + USBSS->LMP_TX_DATA1 = UP_STREAM | NUM_HP_BUF; + USBSS->LMP_TX_DATA2 = 0x0; + Tx_Lmp_Port = 0; + } + /*Successful USB3.0 communication*/ + Link_Sta = LINK_STA_3; + PFIC_DisableIRQ(TMR0_IRQn); + R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR; + R8_TMR0_INTER_EN = 0; + PFIC_DisableIRQ(USBHS_IRQn); + USB20_Device_Init(DISABLE); + } + + if(USBSS->LINK_INT_FLAG & LINK_INACT_FLAG) + { + Link_Sta = 0; + PFIC_EnableIRQ(USBSS_IRQn); + PFIC_EnableIRQ(LINK_IRQn); + PFIC_EnableIRQ(TMR0_IRQn); + R8_TMR0_INTER_EN = RB_TMR_IE_CYC_END; + TMR0_TimerInit( 67000000 ); + USB30D_init(ENABLE); + USBSS->LINK_INT_FLAG = LINK_INACT_FLAG; + USB30_Switch_Powermode(POWER_MODE_2); + } + if(USBSS->LINK_INT_FLAG & LINK_DISABLE_FLAG) // GO DISABLED + { + USBSS->LINK_INT_FLAG = LINK_DISABLE_FLAG; + Link_Sta = LINK_STA_1; + USB30D_init(DISABLE); + PFIC_DisableIRQ(USBSS_IRQn); + R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR; + R8_TMR0_INTER_EN = 0; + PFIC_DisableIRQ(TMR0_IRQn); + PFIC_EnableIRQ(USBHS_IRQn); + USB20_Device_Init(ENABLE); + } + if(USBSS->LINK_INT_FLAG & LINK_RX_DET_FLAG) + { + USBSS->LINK_INT_FLAG = LINK_RX_DET_FLAG; + USB30_Switch_Powermode(POWER_MODE_2); + } + if(USBSS->LINK_INT_FLAG & TERM_PRESENT_FLAG) // term present , begin POLLING + { + USBSS->LINK_INT_FLAG = TERM_PRESENT_FLAG; + if(USBSS->LINK_STATUS & LINK_PRESENT) + { + USB30_Switch_Powermode(POWER_MODE_2); + USBSS->LINK_CTRL |= POLLING_EN; + } + else + { + USBSS->LINK_INT_CTRL = 0; + } + } + if(USBSS->LINK_INT_FLAG & LINK_TXEQ_FLAG) // POLLING SHAKE DONE + { + Tx_Lmp_Port = 1; + USBSS->LINK_INT_FLAG = LINK_TXEQ_FLAG; + USB30_Switch_Powermode(POWER_MODE_0); + } + if(USBSS->LINK_INT_FLAG & WARM_RESET_FLAG) + { + USBSS->LINK_INT_FLAG = WARM_RESET_FLAG; + USB30_Switch_Powermode(POWER_MODE_2); + USBSS->LINK_CTRL |= TX_WARM_RESET; + while(USBSS->LINK_STATUS & RX_WARM_RESET); + USBSS->LINK_CTRL &= ~TX_WARM_RESET; + USB30_Device_Setaddress(0); + + } + if(USBSS->LINK_INT_FLAG & HOT_RESET_FLAG) //The host may send hot reset,Note the configuration of the endpoint + { + USBSS->USB_CONTROL |= 1 << 31; + USBSS->LINK_INT_FLAG = HOT_RESET_FLAG; // HOT RESET begin + USBSS->UEP0_TX_CTRL = 0; + USB30_IN_Set(ENDP_1, DISABLE, NRDY, 0, 0); + USB30_IN_Set(ENDP_2, DISABLE, NRDY, 0, 0); + USB30_IN_Set(ENDP_3, DISABLE, NRDY, 0, 0); + USB30_IN_Set(ENDP_4, DISABLE, NRDY, 0, 0); + USB30_IN_Set(ENDP_5, DISABLE, NRDY, 0, 0); + USB30_IN_Set(ENDP_6, DISABLE, NRDY, 0, 0); + USB30_IN_Set(ENDP_7, DISABLE, NRDY, 0, 0); + USB30_OUT_Set(ENDP_1, NRDY, 0); + USB30_OUT_Set(ENDP_2, NRDY, 0); + USB30_OUT_Set(ENDP_3, NRDY, 0); + USB30_OUT_Set(ENDP_4, NRDY, 0); + USB30_OUT_Set(ENDP_5, NRDY, 0); + USB30_OUT_Set(ENDP_6, NRDY, 0); + USB30_OUT_Set(ENDP_7, NRDY, 0); + + USB30_Device_Setaddress(0); + USBSS->LINK_CTRL &= ~TX_HOT_RESET; // HOT RESET end + } + if(USBSS->LINK_INT_FLAG & LINK_GO_U1_FLAG) // device enter U1 + { + USB30_Switch_Powermode(POWER_MODE_1); + USBSS->LINK_INT_FLAG = LINK_GO_U1_FLAG; + } + if(USBSS->LINK_INT_FLAG & LINK_GO_U2_FLAG) // device enter U2 + { + USB30_Switch_Powermode(POWER_MODE_2); + USBSS->LINK_INT_FLAG = LINK_GO_U2_FLAG; + } + if(USBSS->LINK_INT_FLAG & LINK_GO_U3_FLAG) // device enter U2 + { + USB30_Switch_Powermode(POWER_MODE_2); + USBSS->LINK_INT_FLAG = LINK_GO_U3_FLAG; + } +} + +/******************************************************************************* + * @fn EP2_OUT_Callback + * + * @brief USB3.0 endpoint2 out callback. + * + * @return None + */ +void EP2_OUT_Callback() +{ + UINT16 rx_len; + UINT8 nump; + UINT8 status; + USB30_OUT_Status(ENDP_2,&nump,&rx_len,&status); + + USBByteCount = rx_len; + USB30_OUT_ClearIT(ENDP_2); + USB30_OUT_Set( ENDP_2 , NRDY , 0 ); + + DownloadPoint2_Busy = 0; +} + +/******************************************************************************* + * @fn EP2_IN_Callback + * + * @brief USB3.0 endpoint2 in callback. + * + * @return None + */ +void EP2_IN_Callback() +{ + UINT8 nump; + USB30_IN_ClearIT( ENDP_2 ); + USB30_IN_Set( ENDP_2 , ENABLE , NRDY , 0 , 0); + UploadPoint2_Busy = 0; +} + + +/***************Endpointn IN Transaction Processing*******************/ +void EP1_IN_Callback() +{ + +} + +void EP3_IN_Callback() +{ + +} + + +void EP4_IN_Callback() +{ + +} + + +void EP5_IN_Callback() +{ + +} + + +void EP6_IN_Callback() +{ + +} + + +void EP7_IN_Callback() +{ + +} + + +/***************Endpointn OUT Transaction Processing*******************/ +void EP1_OUT_Callback() +{ + +} + +void EP3_OUT_Callback() +{ + +} + +void EP4_OUT_Callback() +{ + +} + + +void EP5_OUT_Callback() +{ + +} + + +void EP6_OUT_Callback() +{ + +} + + +void EP7_OUT_Callback() +{ + +} + +/******************************************************************************* + * @fn USB30_ITP_Callback + * + * @brief USB3.0 ITP callback function + * + * @return None + */ +void USB30_ITP_Callback(UINT32 ITPCounter) +{ + +} diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB30/libCH56x_USB30_device_lib.a b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB30/libCH56x_USB30_device_lib.a new file mode 100644 index 000000000..eaf065736 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/USB30/libCH56x_USB30_device_lib.a differ diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/connect_cdc.c b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/connect_cdc.c new file mode 100644 index 000000000..c624dd333 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/usb/usbd/simulate_cdc/connect_cdc.c @@ -0,0 +1,58 @@ +/* + * 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. + */ + +/* + * @Note + * Example routine to emulate a simulate USB-CDC Device,Use UART2(PA2/PA3). +*/ + +#include "xizi.h" +#include "board.h" +#include "shell.h" + +#include "CH56x_common.h" +#include "CH56x_usb30.h" +#include "cdc.h" + + +/******************************************************************************* + * @fn main + * + * @brief main program + * + * @return None + */ +int UsbdCdcTest() +{ + KPrintf("UsbdCdcTest start\n"); + KPrintf("CH56x USB3.0 & USB2.0 device test(80MHz) !\n"); + + /* USB initialization */ + TMR2_TimerInit1(); + R32_USB_CONTROL = 0; + PFIC_EnableIRQ(USBSS_IRQn); + PFIC_EnableIRQ(LINK_IRQn); + PFIC_EnableIRQ(TMR0_IRQn); + R8_TMR0_INTER_EN = 1; + TMR0_TimerInit( 67000000 ); + USB30D_init(ENABLE); + KPrintf("UsbdCdcTest USB30D_init OK\n"); + + while(1) + { + CDC_Uart_Deal(); + } +} + + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + UsbdCdcTest, UsbdCdcTest, test usbd cdc); diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/wdt/Makefile b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/wdt/Makefile new file mode 100644 index 000000000..9be59f003 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/wdt/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_wdt.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/wdt/connect_wdt.c b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/wdt/connect_wdt.c new file mode 100644 index 000000000..29d1056c5 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ch569w/third_party_driver/wdt/connect_wdt.c @@ -0,0 +1,71 @@ +/* + * 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_usart.c + * @brief support ch569 uart function and register to bus framework + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2025-04-07 + */ + +#include "CH56x_common.h" +#include "xizi.h" +#include "board.h" +#include "shell.h" + +#define WDOG_MSECOND_MAX ( (0xff << 19) / (FREQ_SYS / 1000) ) // watchdog timer is clocked at Fsys/524288, arround 3~228Hz +int g_feed_wdt_stop = 0; + +int InitHwWdt(void) +{ + KPrintf("InitHwWdt WDOG_MSECOND_MAX is %d ms\n", WDOG_MSECOND_MAX); + + WWDG_SetCounter(0); + WWDG_ClearFlag(); + WWDG_ResetCfg(ENABLE); + while(1) { + WWDG_SetCounter(0); + //mDelaymS(100); + if (g_feed_wdt_stop == 1) { + KPrintf("%s watchdog feed stop!\n", __func__); + break; + } + } + + return 0; +} + +/** + * @description: Watchdog function + * @return success: EOK, failure: other + */ +int StartWatchdog(void) +{ + int ret = EOK; + + int32 WdtTask = KTaskCreate("WdtTask", (void *)InitHwWdt, NONE, 1024, 19); + StartupKTask(WdtTask); + + return EOK; +} + +int WdtTest(int argc, char *argv[]) +{ + KPrintf("WdtTest Start\n"); + g_feed_wdt_stop = 1; + + return 0; +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + WdtTest, WdtTest, test wdt); diff --git a/Ubiquitous/XiZi_IIoT/link.mk b/Ubiquitous/XiZi_IIoT/link.mk index fa76da46c..00e8eb95b 100644 --- a/Ubiquitous/XiZi_IIoT/link.mk +++ b/Ubiquitous/XiZi_IIoT/link.mk @@ -3,7 +3,7 @@ OBJS := $(shell cat make.obj) $(TARGET): $(OBJS) @echo ------------------------------------------------ @echo link $(TARGET) - @$(CROSS_COMPILE)g++ -o $@ $($(LINK_FLAGS)) $(OBJS) $(LINK_LWIP) $(LINK_MUSLLIB) $(LINK_MONGOOSE) $(LINK_WCH_NET) $(LIBCC) $(LINK_WCH_BLE) + @$(CROSS_COMPILE)g++ -o $@ $($(LINK_FLAGS)) $(OBJS) $(LINK_LWIP) $(LINK_MUSLLIB) $(LINK_MONGOOSE) $(LINK_WCH_NET) $(LIBCC) $(LINK_WCH_BLE) $(LINK_BOARD) @echo ------------------------------------------------ @$(CROSS_COMPILE)objcopy -O binary $@ XiZi-$(BOARD)$(COMPILE_TYPE).bin @$(CROSS_COMPILE)objdump -S $@ > XiZi-$(BOARD)$(COMPILE_TYPE).asm