[ch569w]ch569w support for uart spi serdes usb and watchdog from Song_yanguang
it is OK
|
@ -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
|
|
@ -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 芯片。最后点击“下载”,即可使程序下载到评估版上的主芯片。
|
||||
|
||||
<img src="imgs/image_shaolukaifabanpaizhao.jpg" alt="image_shaolukaifabanpaizhao" style="zoom:30%;" />
|
||||
|
||||
<img src="imgs/image_shaoluruanjianjietu.png" alt="image_shaoluruanjianjietu" style="zoom:50%;" />
|
||||
|
||||
|
||||
|
||||
# 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 芯片。最后点击“下载”,即可使程序下载到评估版上的主芯片。
|
||||
|
||||
<img src="imgs/image_shaolukaifabanpaizhao.jpg" alt="image_shaolukaifabanpaizhao" style="zoom:30%;" />
|
||||
|
||||
<img src="imgs/image_shaoluruanjianjietu.png" alt="image_shaoluruanjianjietu" style="zoom:50%;" />
|
||||
|
||||
|
||||
|
||||
# 6. 启动
|
||||
|
||||
烧录完成后,并且将串口连接至电脑。
|
||||
|
||||
将评估板上电重新,即可看到操作系统启动的信息,如下:
|
||||
|
||||

|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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`的默认配置。
|
||||
|
||||

|
||||
|
||||
# 2. 模块测试用例
|
||||
|
||||
下面介绍各模块的测试方法。
|
||||
|
||||
## 2.1 UART
|
||||
|
||||
UART用于串口打印,和shell命令输入。
|
||||
|
||||
测试方法,查看设备启动日志,以及输入命令。
|
||||
|
||||
## 2.2 SPI FLASH
|
||||
|
||||
开发板的spi没有外部接口,是连接的flash芯片。测试通过spi对flash的读写。
|
||||
|
||||
串口执行:`SpiFlashTest`
|
||||
|
||||

|
||||
|
||||
## 2.3 SerDes
|
||||
|
||||
串并互转控制器及收发器(SerDes)。系统内置了支持信号隔离和远距离传输的 SerDes 模块,支持 1.2Gbps 高速差分信号(GXM/GXP
|
||||
引脚),可以通过光纤模块或网线中的一个差分对等传输媒体,进行远距离数据传输。
|
||||
|
||||
开发板上SERDES为半双工接口,仅单向传输使用。需要两个CH569设备通过SerDes进行通信。
|
||||
|
||||
SerDes测试需要先执行`SerdesRxTest`,等到SerdesRx打印初始化成功后,在另有一个设备上执行`SerdesTxTest`。
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## 2.4 USBD CDC
|
||||
|
||||
USBD CDC(USB Device Communication Device Class)是一种将 USB 设备模拟为串口(虚拟串口)的功能实现,允许设备通过 USB 与主机进行串行数据通信。
|
||||
|
||||
串口输入命令:`UsbdCdcTest`,在电脑的设备管理器查看,出现新增COM口。
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## 2.5 Watchdog
|
||||
|
||||
看门狗测试,需要编译时选择打开watchdog功能。
|
||||
|
||||
系统在后台运行wdt,通过命令`WdtTest`,停止喂狗,触发系统重启。
|
||||
|
||||

|
||||
|
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 5.8 KiB |
After Width: | Height: | Size: 8.2 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 18 KiB |
|
@ -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
|
||||
|
|
@ -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_ */
|
||||
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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_ */
|
|
@ -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
|
|
@ -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 <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
|
||||
#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
|
|
@ -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
|
|
@ -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
|
|
@ -0,0 +1,7 @@
|
|||
config SERDES_TRANS
|
||||
bool "Config serdes transmit mode."
|
||||
default y
|
||||
|
||||
config SERIAL_RECEI
|
||||
bool "Config serdes receive mode."
|
||||
default y
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := connect_serdes.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -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);
|
|
@ -0,0 +1,3 @@
|
|||
menuconfig BSP_USING_SPI0_FLASH
|
||||
bool "Enable SPI0 FLASH"
|
||||
default y
|
|
@ -0,0 +1,5 @@
|
|||
ifeq ($(CONFIG_BSP_USING_SPI0_FLASH),y)
|
||||
SRC_FILES += connect_spi_flash.c
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -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 <xizi.h>
|
||||
#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);
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := connect_sys.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -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 <xizi.h>
|
||||
#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;
|
||||
}
|
|
@ -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
|
|
@ -0,0 +1,5 @@
|
|||
ifeq ($(CONFIG_BSP_USING_USBD),y)
|
||||
SRC_DIR += usbd
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,3 @@
|
|||
menuconfig BSP_USING_USBD_CDC
|
||||
bool "Using usbd cdc device"
|
||||
default y
|
|
@ -0,0 +1,5 @@
|
|||
ifeq ($(CONFIG_BSP_USING_USBD_CDC),y)
|
||||
SRC_DIR += simulate_cdc
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
||||
}
|
|
@ -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);
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := connect_wdt.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -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);
|
|
@ -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
|
||||
|
|