diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/.defconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/.defconfig new file mode 100644 index 000000000..2fa96ea66 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/.defconfig @@ -0,0 +1,233 @@ +# +# Automatically generated file; DO NOT EDIT. +# XiZi_IIoT Project Configuration +# +CONFIG_BOARD_K210_EVB=y +CONFIG_KERNEL_CONSOLE_DEVICE_NAME="uarths" +CONFIG_LED0=24 +CONFIG_LED1=25 +CONFIG_ARCH_CPU_64BIT=y +CONFIG_ARCH_RISCV=y +CONFIG_ARCH_RISCV64=y + +# +# kd233 feature +# +# CONFIG_BSP_USING_AUDIO is not set +# CONFIG_BSP_USING_CAMERA is not set +# CONFIG_BSP_USING_SDIO is not set +CONFIG_BSP_USING_DMA=y +CONFIG_BSP_USING_GPIO=y +# CONFIG_BSP_USING_I2C is not set +# CONFIG_BSP_USING_I2S is not set +# CONFIG_BSP_USING_LCD is not set +# CONFIG_BSP_USING_RTC is not set +# CONFIG_BSP_USING_SECURITY is not set +# CONFIG_BSP_USING_SPI is not set +CONFIG_BSP_USING_UART=y +CONFIG_BSP_USING_UART_HS=y +# CONFIG_BSP_USING_VIDEO is not set +# CONFIG_BSP_USING_WDT is not set + +# +# General Purpose UARTs +# +# CONFIG_BSP_USING_UART1=y +# CONFIG_BSP_UART1_TXD_PIN=20 +# CONFIG_BSP_UART1_RXD_PIN=21 +# CONFIG_BSP_USING_UART2=y +# CONFIG_BSP_UART2_TXD_PIN=28 +# CONFIG_BSP_UART2_RXD_PIN=27 +# CONFIG_BSP_USING_UART3=y +# CONFIG_BSP_UART3_TXD_PIN=22 +# CONFIG_BSP_UART3_RXD_PIN=23 +# CONFIG___STACKSIZE__=4096 + +# +# Hardware feature +# +CONFIG_RESOURCES_SERIAL=y +# CONFIG_SERIAL_USING_DMA is not set +# CONFIG_SERIAL_RB_BUFSZ is not set +# CONFIG_RESOURCES_HWTIMER is not set +# CONFIG_RESOURCES_I2C is not set +# CONFIG_RESOURCES_LCD is not set +# CONFIG_RESOURCES_SDIO is not set +# CONFIG_RESOURCES_TOUCH is not set +CONFIG_RESOURCES_PIN=y +# CONFIG_RESOURCES_RTC is not set +# CONFIG_RESOURCES_SPI is not set +#CONFIG_RESOURCES_SPI_SD is not set +#CONFIG_RESOURCES_SPI_SFUD is not set +# SFUD_USING_SFDP is not set +# SFUD_USING_FLASH_INFO_TABLE is not set +# SFUD_DEBUG_LOG is not set +# CONFIG_RESOURCES_WDT is not set +# CONFIG_RESOURCES_USB is not set +# CONFIG_RESOURCES_USB_HOST is not set +# CONFIG_UDISK_MOUNTPOINT is not set +# CONFIG_USBH_MSTORAGE is not set +# CONFIG_RESOURCES_USB_DEVICE is not set +# CONFIG_USBD_THREAD_STACK_SZ is not set + +# +# Kernel feature +# +# CONFIG_SEPARATE_COMPILE is not set +# CONFIG_COMPILER_APP is not set +# CONFIG_COMPILER_KERNEL is not set +# +# Kernel Device Object +# +CONFIG_KERNEL_DEVICE=y +CONFIG_KERNEL_CONSOLE=y +CONFIG_KERNEL_CONSOLEBUF_SIZE=128 + +# +# Task feature +# +CONFIG_SCHED_POLICY_RR_REMAINSLICE=y +# CONFIG_SCHED_POLICY_RR is not set +# CONFIG_SCHED_POLICY_FIFO is not set + +# +# Inter-Task communication +# +CONFIG_KERNEL_SEMAPHORE=y +CONFIG_KERNEL_MUTEX=y +CONFIG_KERNEL_EVENT=y +CONFIG_KERNEL_MESSAGEQUEUE=y +# 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=100 +CONFIG_KERNEL_STACK_OVERFLOW_CHECK=y +CONFIG_KERNEL_BANNER=y +# CONFIG_KERNEL_HOOK is not set +CONFIG_KERNEL_SOFTTIMER=y +CONFIG_KERNEL_IDLE_HOOK=y +CONFIG_IDEL_HOOK_LIST_SIZE=4 +CONFIG_IDLE_KTASK_STACKSIZE=1024 +CONFIG_USER_APPLICATION=y +# CONFIG_TASK_ISOLATION is not set + +# +# Memory Management +# +# CONFIG_KERNEL_MEMBLOCK is not set + +# +# Command shell +# +CONFIG_TOOL_SHELL=y +CONFIG_SHELL_TASK_PRIORITY=20 +CONFIG_SHELL_TASK_STACK_SIZE=4096 + +# +# User Control +# +CONFIG_SHELL_DEFAULT_USER="letter" +CONFIG_SHELL_DEFAULT_USER_PASSWORD="" +CONFIG_SHELL_LOCK_TIMEOUT=10000 +CONFIG_SHELL_ENTER_CR_AND_LF=y +# CONFIG_SHELL_ENTER_CRLF is not set +CONFIG_SHELL_ENTER_CR=y +CONFIG_SHELL_ENTER_LF=y +CONFIG_SHELL_MAX_NUMBER=5 +CONFIG_SHELL_PARAMETER_MAX_NUMBER=8 +CONFIG_SHELL_HISTORY_MAX_NUMBER=5 +CONFIG_SHELL_PRINT_BUFFER=128 +CONFIG_SHELL_USING_CMD_EXPORT=y +# CONFIG_SHELL_HELP_LIST_USER is not set +CONFIG_SHELL_HELP_SHOW_PERMISSION=y +# CONFIG_SHELL_HELP_LIST_VAR is not set +# CONFIG_SHELL_HELP_LIST_KEY is not set +CONFIG_KERNEL_QUEUEMANAGE=y +CONFIG_KERNEL_WORKQUEUE=y +CONFIG_WORKQUEUE_KTASK_STACKSIZE=512 +CONFIG_WORKQUEUE_KTASK_PRIORITY=23 +CONFIG_KERNEL_WAITQUEUE=y +CONFIG_KERNEL_DATAQUEUE=y +# CONFIG_KERNEL_CIRCULAR_AREA is not set +# CONFIG_KERNEL_AVL_TREE is not set +CONFIG_NAME_MAX=32 +CONFIG_ALIGN_SIZE=8 +CONFIG_KERNEL_COMPONENTS_INIT=y +CONFIG_KERNEL_USER_MAIN=y +CONFIG_MAIN_KTASK_STACK_SIZE=2048 +CONFIG_ENV_INIT_KTASK_STACK_SIZE=8192 +CONFIG_MAIN_KTASK_PRIORITY=10 +# CONFIG_USER_TEST is not set +# CONFIG_TOOL_TEST_SEM is not set +# CONFIG_TOOL_TEST_MUTEX is not set +# CONFIG_TOOL_TEST_EVENT is not set +# CONFIG_TOOL_TEST_MSG is not set +# CONFIG_TOOL_TEST_AVLTREE is not set +# CONFIG_TEST_CRICULAR_AREA is not set +# CONFIG_TOOL_TEST_MEM is not set +# CONFIG_TOOL_TEST_TIMER is not set +# CONFIG_TOOL_TEST_IWG is not set +# CONFIG_TOOL_TEST_REALTIME is not set +# CONFIG_TOOL_TEST_DBG is not set +# CONFIG_TOOL_TEST_SCHED is not set +# CONFIG_KERNEL_DEBUG is not set +CONFIG_DEBUG_INIT_CONFIG=y +CONFIG_DBG_INIT=1 +CONFIG_ARCH_SMP=y +CONFIG_CPUS_NR=2 + +# +# File system +# +CONFIG_FS_VFS=y +CONFIG_VFS_USING_WORKDIR=y +CONFIG_FS_VFS_DEVFS=y + +# +# Fat filesystem +# + +# +# IOT-Device File system +# + +# +# Lwext4 filesystem +# + +# +# APP Framework +# + +# +# connection +# +# CONFIG_CONNECTION_AT is not set +# CONFIG_CONNECTION_MQTT is not set + +# +# medium communication +# + + +# +# Intelligence +# + +# +# Control +# + +# +# Lib +# +CONFIG_LIB=y +CONFIG_LIB_POSIX=y +CONFIG_LIB_NEWLIB=y + +CONFIG_LITTLEVGL2RTT_USING_DEMO=y + +# +# Security +# diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/Kconfig new file mode 100644 index 000000000..4b08e250a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/Kconfig @@ -0,0 +1,65 @@ +mainmenu "XiZi_IIoT Project Configuration" + +config BSP_DIR + string + option env="BSP_ROOT" + default "." + +config KERNEL_DIR + string + option env="KERNEL_ROOT" + default "../.." + +config BOARD_EDU_RISCV64_EVB + bool + select ARCH_RISCV + select ARCH_RISCV64 + select ARCH_CPU_64BIT + default y + +source "$KERNEL_DIR/arch/Kconfig" + +menu "edu-riscv64 feature" + source "$BSP_DIR/third_party_driver/Kconfig" + + menu "config default board resources" + menu "config board app name" + config BOARD_APP_NAME + string "config board app name" + default "/XiUOS_edu_riscv64_app.bin" + endmenu + + menu "config board service table" + config SERVICE_TABLE_ADDRESS + hex "board service table address" + default 0x80100000 + endmenu + + menu "config board peripheral" + config MOUNT_SDCARD + bool "mount cd card" + default n + config MOUNT_USB + bool "mount usb" + default n + endmenu + + endmenu + + config __STACKSIZE__ + int "stack size for interrupt" + default 4096 + +endmenu + + + + + +menu "Hardware feature" +source "$KERNEL_DIR/resources/Kconfig" +endmenu + +source "$KERNEL_DIR/Kconfig" + + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/Makefile new file mode 100644 index 000000000..12f414817 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/Makefile @@ -0,0 +1,6 @@ +SRC_FILES := board.c + +SRC_DIR := third_party_driver + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/README.md b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/README.md new file mode 100644 index 000000000..c65511c16 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/README.md @@ -0,0 +1,187 @@ +# 从零开始构建矽璓工业物联操作系统:使用risc-v架构的edu-riscv64开发板 + +[XiUOS](http://xuos.io/) (X Industrial Ubiquitous Operating System) 矽璓XiUOS是一款面向智慧车间的工业物联网操作系统,主要由一个极简的微型实时操作系统内核和其上的工业物联框架构成,通过高效管理工业物联网设备、支撑工业物联应用,在生产车间内实现智能化的“感知环境、联网传输、知悉识别、控制调整”,促进以工业设备和工业控制系统为核心的人、机、物深度互联,帮助提升生产线的数字化和智能化水平。 + +## 开发环境搭建 + +### 推荐使用: + +**操作系统:** ubuntu18.04 [https://ubuntu.com/download/desktop](https://ubuntu.com/download/desktop) +**开发工具推荐使用 VSCode ,VScode下载地址为:** VSCode [https://code.visualstudio.com/](https://code.visualstudio.com/),推荐下载地址为 [http://vscode.cdn.azure.cn/stable/3c4e3df9e89829dce27b7b5c24508306b151f30d/code_1.55.2-1618307277_amd64.deb](http://vscode.cdn.azure.cn/stable/3c4e3df9e89829dce27b7b5c24508306b151f30d/code_1.55.2-1618307277_amd64.deb) + +### 依赖包安装: + +``` +$ sudo apt install build-essential pkg-config +$ sudo apt install gcc make libncurses5-dev openssl libssl-dev bison flex libelf-dev autoconf libtool gperf libc6-dev git +``` + +**源码下载:** XiUOS [https://www.gitlink.org.cn/xuos/xiuos](https://www.gitlink.org.cn/xuos/xiuos) +新建一个空文件夹并进入文件夹中,并下载源码,具体命令如下: + +```c +mkdir test && cd test +git clone https://gitlink.org.cn/xuos/xiuos.git +``` + +1、打开XiUOS源码文件包可以看到以下目录: +| 名称 | 说明 | +| -- | -- | +| APP_Framework | 应用代码 | +| Ubiquitous | 板级支持包,支持NuttX、RT-Thread和XiZi内核 | + +2、打开XiZi内核源码文件包可以看到以下目录: +| 名称 | 说明 | +| -- | -- | +| arch | 架构代码 | +| board | 板级支持包 | +| fs | 文件系统 | +| kernel | 内核源码 | +| lib | 第三方库源码 | +| resources | 驱动文件 | +| tool | 系统工具 | + +使用VScode打开代码,具体操作步骤为:在源码文件夹下打开系统终端,输入`code .`即可打开VScode开发环境,如下图所示: + +
+ +
+ +### 裁减配置工具的下载 +**裁减配置工具:** kconfig-frontends [https://www.gitlink.org.cn/xuos/kconfig-frontends](https://www.gitlink.org.cn/xuos/kconfig-frontends) +执行以下命令下载配置工具: + +```c +mkdir kfrontends && cd kfrontends +git clone https://gitlink.org.cn/xuos/kconfig-frontends.git +``` + +下载源码后按以下步骤执行软件安装: + +```c +cd kconfig-frontends +./xs_build.sh +``` + +### 编译工具链: + +RISC-V: riscv-none-embed-,默认安装到Ubuntu的/opt/,下载源码并解压。[下载网址 http://101.36.126.201:8011/gnu-mcu-eclipse.tar.bz2](http://101.36.126.201:8011/gnu-mcu-eclipse.tar.bz2) + +```shell +$ tar -xjf gnu-mcu-eclipse.tar.bz2 -C /opt/ +``` + +将上述解压的编译工具链的路径添加到board/edu-riscv64/config.mk文件当中,例如: + +``` +export CROSS_COMPILE ?=/opt/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.1-20190425-1021/bin/riscv-none-embed- +``` + +若`CROSS_COMPILE ` 变量定义语句已经存在,将它替换成上面的语句 + +# 在edu-riscv64上创建第一个应用 --helloworld + +# edu-riscv64开发板简介 + +## 1. 微处理器简介 + +| 硬件 | 描述 | +| -- | -- | +|芯片型号| K210 | +|CPU| 双核RV64GC | +|主频| 400MHz | +|片内SRAM| 8MB | +| 外设 | DVP、JTAG、OTP、FPIOA、GPIO、UART、SPI、RTC、I²S、I²C、WDT、Timer与PWM | + +XiUOS板级当前支持使用GPIO、I2C、LCD、RTC、SPI、Timer、UART、watchdog。 + +## 2. 代码编写与编译说明 + +编辑环境:`VScode` + +编译工具链:`riscv-none-embed-gcc` +使用`VScode`打开工程的方法有多种,本文介绍一种快捷键,在项目目录下将`code .`输入终端即可打开目标项目 + +修改`APP_Framework/Applications`文件夹下`main.c` +在输出函数中写入 Hello, world!!! \n完成代码编辑。 + +![main](img/main.png) + +编译步骤: + +1.在`VScode`的“命令终端”下执行以下命令,生成配置文件 + +```c +cd ./Ubiquitous/XiZi +make BOARD=edu-riscv64 distclean +make BOARD=edu-riscv64 menuconfig +``` + +2.在`menuconfig`界面配置需要关闭和开启的功能,按回车键进入下级菜单,按Y键选中需要开启的功能,按N键选中需要关闭的功能,配置结束后选择Exit保存并退出(本实验无需选择任何选项,所以双击ESC结束选择,继续操作即可)。 + +![menuconfig1](img/menuconfig1.png) + +双击`ESC`键会出现如下图所示结果: + +![menuconfig2](img/menuconfig2.png) + +选择`yes`键退出。 + +若执行 `make BOARD=edu-riscv64 menuconfig`后出现以下界面: + +![menuconfig3](img/menuconfig3.png) + +解决的方法是将终端向上拉伸超过当前界面的三分之二以上,效果如下: + +![menuconfig4](img/menuconfig4.png) + +3.继续在`VScode`的“命令终端”中执行以下命令,进行编译 + +```c +make BOARD=edu-riscv64 +``` + +4.如果编译正确无误,会在build文件夹下生成XiZi-edu-riscv64.elf、XiZi-edu-riscv64.bin文件。其中XiZi-edu-riscv64.bin需要烧写到设备中进行运行。 + +>注:最后可以执行以下命令,清除配置文件和编译生成的文件 + +```c +make BOARD=edu-riscv64 distclean +``` + +## 3. 烧写及执行 + +连接开发板串口(即Type-C口)到USB接口,按住“boot”按键并按下“电源按钮”上电,观察电源指示灯点亮,此时表示已进入ISP模式,松开“boot”按键即可;然后使用K-Flash工具进行烧写bin文件。 + +![edu-riscv64](img/edu-riscv64.png) + +执行以下命令安装K-Flash工具 + +``` +sudo apt install python3 python3-pip +sudo pip3 install pyserial +sudo pip3 install pyelftools +sudo pip3 install kflash +``` + +如果最后一步安装kflash出现错误,可以尝试以下命令 + +``` +sudo python -m pip install kflash +sudo python3 -m pip install kflash +sudo pip install kflash +sudo pip2 install kflash +``` + +代码根目录下执行K-Flash工具烧录,-p为USB端口号,视实际情况而定 + +``` +sudo kflash -t build/XiZi-edu-riscv64.bin -p /dev/ttyUSB0 +``` +烧写完毕可以按下“reset”按键,系统即可启动。 + +### 3.1 运行结果 + +如果编译 & 烧写无误,将会在串口终端上看到信息打印输出。 + +![terminal](img/terminal.png) diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c new file mode 100644 index 000000000..69ec0d706 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.c @@ -0,0 +1,278 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file board.c + * @brief support kd233-board init configure and start-up + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022-07-25 + */ + +/************************************************* +File name: board.c +Description: support edu-riscv64-board init configure and driver/task/... init +Others: https://canaan-creative.com/developer +History: +1. Date: 2022-07-25 +Author: AIIT XUOS Lab +Modification: +1. support edu-riscv64-board InitBoardHardware +2. support edu-riscv64-board Kd233Start +3. support edu-riscv64-board shell cmd, include reboot, shutdown +*************************************************/ + +#include "board.h" + +#include +#include +#include + +#include "connect_gpio.h" +#include "connect_hwtimer.h" +#include "connect_rtc.h" +#include "connect_soft_spi.h" +#include "connect_uart.h" +#include "connect_w5500.h" +#include "connect_wdt.h" +#include "dmac.h" +#include "encoding.h" +#include "fpioa.h" +#include "tick.h" + +// #if defined(FS_VFS) +// #include +// #endif + +#define CPU0 (0) +#define CPU1 (1) +extern x_base cpu2_boot_flag; +extern void entry(void); +extern void SecondaryCpuCStart(void); +extern int IoConfigInit(void); +extern int HwI2cInit(void); +extern int HwTouchInit(void); +extern int HwCh376Init(void); +extern int HwLcdInit(void); +extern int HwSpiInit(void); +extern int HwSoftSPIInit(void); +extern int HwWiznetInit(void); + +#include +#ifdef MOUNT_USB +/** + * @description: Mount USB + * @return 0 + */ +int MountUsb(void) { + if (MountFilesystem(USB_BUS_NAME, USB_DEVICE_NAME, USB_DRIVER_NAME, + FSTYPE_CH376, "/") == 0) + KPrintf("usb mount to '/'\n"); + else + KPrintf("usb mount to '/' failed!\n"); + + return 0; +} +#endif + +#if defined(FS_VFS) && defined(MOUNT_SDCARD) +#include +#include +extern SpiSdDeviceType SpiSdInit(struct Bus *bus, const char *dev_name, + const char *drv_name, const char *sd_name); + +/** + * @description: Mount SD card + * @return 0 + */ +int MountSDCard(void) { + struct Bus *spi_bus; + spi_bus = BusFind(SOFT_SPI_BUS_NAME); + if (NONE == SpiSdInit(spi_bus, SOFT_SPI_DEVICE_NAME, SOFT_SPI_DRV_NAME, + SPI_SD_NAME)) { + KPrintf("MountSDCard SpiSdInit error!\n"); + return -1; + } + if (EOK != MountFilesystem(SOFT_SPI_BUS_NAME, SPI_SD_NAME, SOFT_SPI_DRV_NAME, + FSTYPE_FATFS, "/")) { + return -1; + } + + KPrintf("SPI SD card fatfs mounted\n"); + return 0; +} +#endif + +void InitBss(void) { + unsigned int *dst; + + dst = &__bss_start; + while (dst < &__bss_end) { + *dst++ = 0; + } +} + +void Kd233Start(uint32_t mhartid) { + switch (mhartid) { + case CPU0: + InitBss(); + + /*kernel start entry*/ + entry(); + break; + case CPU1: + while (0x2018050420191010 != + cpu2_boot_flag) { ///< waiting for boot flag ,then start cpu1 core +#ifndef ARCH_SMP + asm volatile("wfi"); +#endif + } +#ifdef ARCH_SMP + SecondaryCpuCStart(); +#endif + break; + + default: + break; + } +} + +int Freq(void) { + uint64 value = 0; + + value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL0); + KPrintf("PLL0: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL1); + KPrintf("PLL1: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_PLL2); + KPrintf("PLL2: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_CPU); + KPrintf("CPU : %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_APB0); + KPrintf("APB0: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_APB1); + KPrintf("APB1: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_APB2); + KPrintf("APB2: %d\n", value); + value = SysctlClockGetFreq(SYSCTL_CLOCK_HCLK); + KPrintf("HCLK: %d\n", value); + + value = clint_get_time(); + KPrintf("mtime: %d\n", value); + + return 0; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(0), + Freq, Freq, show frequency information); + +#ifdef ARCH_SMP +extern int EnableHwclintIpi(void); +#endif + +struct InitSequenceDesc _board_init[] = { +#ifdef BSP_USING_GPIO + {"hw_pin", HwGpioInit}, + {"io_config", IoConfigInit}, +#endif +#ifdef BSP_USING_I2C + {"hw_i2c", HwI2cInit}, +#endif +#ifdef BSP_USING_RTC + {"hw_rtc", HwRtcInit}, +#endif +#ifdef BSP_USING_SPI + {"hw_spi", HwSpiInit}, +#endif +#ifdef BSP_USING_LCD + {"hw_lcd", HwLcdInit}, +#endif +#ifdef BSP_USING_USB + {"hw_usb", HwCh376Init}, +#endif +#ifdef BSP_USING_TOUCH + {"touch", HwTouchInit}, +#endif +#ifdef BSP_USING_SOFT_SPI + {"soft_spi", HwSoftSPIInit}, +#endif +#ifdef BSP_USING_HWTIMER + {"hw_timer", HwTimerInit}, +#endif +#ifdef BSP_USING_WDT + {"hw_wdt", HwWdtInit}, +#endif +#ifdef BSP_USING_W5500 + {"w5500", HwWiznetInit}, +#endif + {" NONE ", NONE}, +}; + +void InitBoardHardware(void) { + int i = 0; + int ret = 0; + + SysctlPllSetFreq(SYSCTL_PLL0, 800000000UL); + SysctlPllSetFreq(SYSCTL_PLL1, 400000000UL); +#ifdef BSP_USING_GPIO + /* Init FPIOA */ + FpioaInit(); +#endif +#ifdef BSP_USING_DMA + /* Dmac init */ + DmacInit(); +#endif + /* initalize interrupt */ + InitHwinterrupt(); +#ifdef BSP_USING_UART + HwUartInit(); +#endif + + /* initialize memory system */ + InitBoardMemory(MEMORY_START_ADDRESS, MEMORY_END_ADDRESS); + +#ifdef KERNEL_CONSOLE + /* set console device */ + InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, + KERNEL_CONSOLE_DEVICE_NAME); + KPrintf("\nconsole init completed.\n"); + KPrintf("board initialization......\n"); +#endif /* KERNEL_CONSOLE */ + + InitHwTick(); + +#ifdef ARCH_SMP + EnableHwclintIpi(); +#endif + +#ifdef KERNEL_COMPONENTS_INIT + for (i = 0; _board_init[i].fn != NONE; i++) { + ret = _board_init[i].fn(); + KPrintf("initialize %s %s\n", _board_init[i].fn_name, + ret == 0 ? "success" : "failed"); + } +#endif + KPrintf("board init done.\n"); + KPrintf("start kernel...\n"); +} + +void HwCpuReset(void) { + sysctl->soft_reset.soft_reset = 1; + while (RET_TRUE) + ; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(0), + Reboot, HwCpuReset, reset machine); diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.h new file mode 100644 index 000000000..949e968c4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/board.h @@ -0,0 +1,91 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file board.h +* @brief define edu-riscv64-board init configure and start-up function +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-07-25 +*/ + +/************************************************* +File name: board.h +Description: define edu-riscv64-board board init function and struct +Others: https://canaan-creative.com/developer +History: +1. Date: 2022-07-25 +Author: AIIT XUOS Lab +Modification: +1. define edu-riscv64-board InitBoardHardware +2. define edu-riscv64-board data and bss struct +*************************************************/ + +#ifndef BOARD_H__ +#define BOARD_H__ + +#include +#include +// #include "../../kernel/include/xs_service.h" + +extern unsigned int __bss_start; +extern unsigned int __bss_end; +extern unsigned int __stack_end__; +extern unsigned int g_service_table_start; +extern unsigned int g_service_table_end; + + +#ifdef SEPARATE_COMPILE +#define G_SERVICE_TABLE_LENGTH (0x1000) + +#define MEMORY_START_ADDRESS (void*)&__stack_end__ +#define MEMORY_END_ADDRESS (void*)((0x80000000 + 1 * 1024 * 1024)) /* 1M SRAM */ + +typedef int (*main_t)(int argc, char *argv[]); +typedef void (*exit_t)(void); +struct UserSpaceS +{ + main_t us_entrypoint; + exit_t us_taskquit; + uintptr_t us_textstart; + uintptr_t us_textend; + uintptr_t us_datasource; + uintptr_t us_datastart; + uintptr_t us_dataend; + uintptr_t us_bssstart; + uintptr_t us_bssend; + uintptr_t us_heapend; +}; +#define USERSPACE (( struct UserSpaceS *)(MEMORY_END_ADDRESS + G_SERVICE_TABLE_LENGTH)) + +#ifndef SERVICE_TABLE_ADDRESS +#define SERVICE_TABLE_ADDRESS (0x80100000) +#endif + +#define USER_MEMORY_START_ADDRESS (USERSPACE->us_bssend) + +#define USER_MEMORY_END_ADDRESS (void*)((0x80000000 + 6 * 1024 * 1024) ) + +#else + +#define MEMORY_START_ADDRESS (void*)&__stack_end__ +#define MEMORY_END_ADDRESS (void*)(0x80000000 + 6 * 1024 * 1024) +#endif + + + +void InitBoardHardware(void); + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/config.mk b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/config.mk new file mode 100644 index 000000000..409cda39c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/config.mk @@ -0,0 +1,27 @@ +export CFLAGS := -mcmodel=medany -march=rv64imafdc -mabi=lp64d -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -O0 -ggdb -fgnu89-inline -Werror +export AFLAGS := -c -mcmodel=medany -march=rv64imafdc -mabi=lp64d -x assembler-with-cpp -ggdb +export LFLAGS := -mcmodel=medany -march=rv64imafdc -mabi=lp64d -nostartfiles -Wl,--gc-sections,-Map=XiZi-edu-riscv64.map,-cref,-u,_start -T $(BSP_ROOT)/link.lds + +ifeq ($(CONFIG_LIB_MUSLLIB), y) +export LFLAGS += -nostdlib -nostdinc # -fno-builtin -nodefaultlibs +export LIBCC := -lgcc +export LINK_MUSLLIB := $(KERNEL_ROOT)/lib/musllib/libmusl.a +endif + +ifeq ($(CONFIG_RESOURCES_LWIP), y) +export LINK_LWIP := $(KERNEL_ROOT)/resources/ethernet/LwIP/liblwip.a +endif + +export APPLFLAGS := -mcmodel=medany -march=rv64imafdc -mabi=lp64d -nostartfiles -Wl,--gc-sections,-Map=XiZi-edu-riscv64.map,-cref,-u, -T $(BSP_ROOT)/link_userspace.lds + +export CXXFLAGS := -mcmodel=medany -march=rv64imafdc -mabi=lp64d -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -O0 -ggdb -Werror + +export CROSS_COMPILE ?=/opt/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.1-20190425-1021/bin/riscv-none-embed- + + +export DEFINES := -DHAVE_CCONFIG_H -DHAVE_SIGINFO + +export ARCH = risc-v +export MCU = k210 + + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/edu-riscv64.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/edu-riscv64.png new file mode 100644 index 000000000..1d4d096ff Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/edu-riscv64.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/main.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/main.png new file mode 100644 index 000000000..26e304c78 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/main.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/menuconfig1.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/menuconfig1.png new file mode 100644 index 000000000..4dac11b78 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/menuconfig1.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/menuconfig2.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/menuconfig2.png new file mode 100644 index 000000000..090885a10 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/menuconfig2.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/menuconfig3.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/menuconfig3.png new file mode 100644 index 000000000..b5d7f7bb7 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/menuconfig3.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/menuconfig4.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/menuconfig4.png new file mode 100644 index 000000000..22b40707a Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/menuconfig4.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/terminal.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/terminal.png new file mode 100644 index 000000000..f2cd49ad7 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/terminal.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/vscode.jpg b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/vscode.jpg new file mode 100644 index 000000000..b9bacff78 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/img/vscode.jpg differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/bsp.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/bsp.h new file mode 100644 index 000000000..269429b88 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/bsp.h @@ -0,0 +1,31 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file bsp.h +* @brief add from Canaan K210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef _KENDRYTE_BSP_H +#define _KENDRYTE_BSP_H +#include "bsp_atomic.h" +#include "entry.h" +#include "sleep.h" +#include "encoding.h" +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/bsp_atomic.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/bsp_atomic.h new file mode 100644 index 000000000..d43ebc7aa --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/bsp_atomic.h @@ -0,0 +1,253 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file atomic.h +* @brief add from Canaan K210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef _BSP_ATOMIC_H +#define _BSP_ATOMIC_H + +#ifdef __cplusplus +extern "C" { +#endif + + +#define SPINLOCK_INIT \ + { \ + 0 \ + } + +#define CORELOCK_INIT \ + { \ + .lock = SPINLOCK_INIT, \ + .count = 0, \ + .core = -1 \ + } + + +/* Defination of memory barrier macro */ +#define mb() \ + { \ + asm volatile("fence" :: \ + : "memory"); \ + } + +#define atomic_set(ptr, val) (*(volatile typeof(*(ptr))*)(ptr) = val) +#define atomic_read(ptr) (*(volatile typeof(*(ptr))*)(ptr)) + +#ifndef __riscv_atomic +#error "atomic extension is required." +#endif +#define atomic_add(ptr, inc) __sync_fetch_and_add(ptr, inc) +#define atomic_or(ptr, inc) __sync_fetch_and_or(ptr, inc) +#define atomic_swap(ptr, swp) __sync_lock_test_and_set(ptr, swp) +#define atomic_cas(ptr, cmp, swp) __sync_val_compare_and_swap(ptr, cmp, swp) + +typedef struct _spinlock +{ + int lock; +} spinlock_t; + +typedef struct _semaphore +{ + spinlock_t lock; + int count; + int waiting; +} semaphore_t; + + +typedef struct _corelock +{ + spinlock_t lock; + int count; + int core; +} corelock_t; + +static inline int spinlock_trylock(spinlock_t *lock) +{ + int res = atomic_swap(&lock->lock, -1); + /* Use memory barrier to keep coherency */ + mb(); + return res; +} + +static inline void spinlock_lock(spinlock_t *lock) +{ + while (spinlock_trylock(lock)); +} + +static inline void spinlock_unlock(spinlock_t *lock) +{ + /* Use memory barrier to keep coherency */ + mb(); + atomic_set(&lock->lock, 0); + asm volatile ("nop"); +} + +static inline void semaphore_signal(semaphore_t *semaphore, int i) +{ + spinlock_lock(&(semaphore->lock)); + semaphore->count += i; + spinlock_unlock(&(semaphore->lock)); +} + +static inline void semaphore_wait(semaphore_t *semaphore, int i) +{ + atomic_add(&(semaphore->waiting), 1); + while (1) + { + spinlock_lock(&(semaphore->lock)); + if (semaphore->count >= i) + { + semaphore->count -= i; + atomic_add(&(semaphore->waiting), -1); + spinlock_unlock(&(semaphore->lock)); + break; + } + spinlock_unlock(&(semaphore->lock)); + } +} + +static inline int semaphore_count(semaphore_t *semaphore) +{ + int res = 0; + + spinlock_lock(&(semaphore->lock)); + res = semaphore->count; + spinlock_unlock(&(semaphore->lock)); + return res; +} + +static inline int semaphore_waiting(semaphore_t *semaphore) +{ + return atomic_read(&(semaphore->waiting)); +} + +static inline int corelock_trylock(corelock_t *lock) +{ + int res = 0; + unsigned long core; + + asm volatile("csrr %0, mhartid;" + : "=r"(core)); + if(spinlock_trylock(&lock->lock)) + { + return -1; + } + + if (lock->count == 0) + { + /* First time get lock */ + lock->count++; + lock->core = core; + res = 0; + } + else if (lock->core == core) + { + /* Same core get lock */ + lock->count++; + res = 0; + } + else + { + /* Different core get lock */ + res = -1; + } + spinlock_unlock(&lock->lock); + + return res; +} + +static inline void corelock_lock(corelock_t *lock) +{ + unsigned long core; + + asm volatile("csrr %0, mhartid;" + : "=r"(core)); + spinlock_lock(&lock->lock); + + if (lock->count == 0) + { + /* First time get lock */ + lock->count++; + lock->core = core; + } + else if (lock->core == core) + { + /* Same core get lock */ + lock->count++; + } + else + { + /* Different core get lock */ + spinlock_unlock(&lock->lock); + + do + { + while (atomic_read(&lock->count)) + ; + } while (corelock_trylock(lock)); + return; + } + spinlock_unlock(&lock->lock); +} + +static inline void corelock_unlock(corelock_t *lock) +{ + unsigned long core; + + asm volatile("csrr %0, mhartid;" + : "=r"(core)); + spinlock_lock(&lock->lock); + + if (lock->core == core) + { + /* Same core release lock */ + lock->count--; + if (lock->count <= 0) + { + lock->core = -1; + lock->count = 0; + } + } + else + { + /* Different core release lock */ + spinlock_unlock(&lock->lock); + + register unsigned long a7 asm("a7") = 93; + register unsigned long a0 asm("a0") = 0; + register unsigned long a1 asm("a1") = 0; + register unsigned long a2 asm("a2") = 0; + + asm volatile("scall" + : "+r"(a0) + : "r"(a1), "r"(a2), "r"(a7)); + } + spinlock_unlock(&lock->lock); +} + +#ifdef __cplusplus +} +#endif + +#endif /* _BSP_ATOMIC_H */ + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/dump.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/dump.h new file mode 100644 index 000000000..8da4c2230 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/dump.h @@ -0,0 +1,150 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file dump.h +* @brief add from Canaan K210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef _BSP_DUMP_H +#define _BSP_DUMP_H + +#include +#include +#include "syslog.h" +#include "hardware_uarths.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DUMP_PRINTF printk + +static inline void +dump_core(const char *reason, uintptr_t cause, uintptr_t epc, uintptr_t regs[32], uintptr_t fregs[32]) +{ + static const char *const reg_usage[][2] = + { + {"zero ", "Hard-wired zero"}, + {"ra ", "Return address"}, + {"sp ", "Stack pointer"}, + {"gp ", "Global pointer"}, + {"tp ", "Task pointer"}, + {"t0 ", "Temporaries Caller"}, + {"t1 ", "Temporaries Caller"}, + {"t2 ", "Temporaries Caller"}, + {"s0/fp", "Saved register/frame pointer"}, + {"s1 ", "Saved register"}, + {"a0 ", "Function arguments/return values"}, + {"a1 ", "Function arguments/return values"}, + {"a2 ", "Function arguments values"}, + {"a3 ", "Function arguments values"}, + {"a4 ", "Function arguments values"}, + {"a5 ", "Function arguments values"}, + {"a6 ", "Function arguments values"}, + {"a7 ", "Function arguments values"}, + {"s2 ", "Saved registers"}, + {"s3 ", "Saved registers"}, + {"s4 ", "Saved registers"}, + {"s5 ", "Saved registers"}, + {"s6 ", "Saved registers"}, + {"s7 ", "Saved registers"}, + {"s8 ", "Saved registers"}, + {"s9 ", "Saved registers"}, + {"s10 ", "Saved registers"}, + {"s11 ", "Saved registers"}, + {"t3 ", "Temporaries Caller"}, + {"t4 ", "Temporaries Caller"}, + {"t5 ", "Temporaries Caller"}, + {"t6 ", "Temporaries Caller"}, + }; + + static const char *const regf_usage[][2] = + { + {"ft0 ", "FP temporaries"}, + {"ft1 ", "FP temporaries"}, + {"ft2 ", "FP temporaries"}, + {"ft3 ", "FP temporaries"}, + {"ft4 ", "FP temporaries"}, + {"ft5 ", "FP temporaries"}, + {"ft6 ", "FP temporaries"}, + {"ft7 ", "FP temporaries"}, + {"fs0 ", "FP saved registers"}, + {"fs1 ", "FP saved registers"}, + {"fa0 ", "FP arguments/return values"}, + {"fa1 ", "FP arguments/return values"}, + {"fa2 ", "FP arguments values"}, + {"fa3 ", "FP arguments values"}, + {"fa4 ", "FP arguments values"}, + {"fa5 ", "FP arguments values"}, + {"fa6 ", "FP arguments values"}, + {"fa7 ", "FP arguments values"}, + {"fs2 ", "FP Saved registers"}, + {"fs3 ", "FP Saved registers"}, + {"fs4 ", "FP Saved registers"}, + {"fs5 ", "FP Saved registers"}, + {"fs6 ", "FP Saved registers"}, + {"fs7 ", "FP Saved registers"}, + {"fs8 ", "FP Saved registers"}, + {"fs9 ", "FP Saved registers"}, + {"fs10", "FP Saved registers"}, + {"fs11", "FP Saved registers"}, + {"ft8 ", "FP Temporaries Caller"}, + {"ft9 ", "FP Temporaries Caller"}, + {"ft10", "FP Temporaries Caller"}, + {"ft11", "FP Temporaries Caller"}, + }; + + if (CONFIG_LOG_LEVEL >= LOG_ERROR) + { + const char unknown_reason[] = "unknown"; + + if (!reason) + reason = unknown_reason; + + DUMP_PRINTF("core dump: %s\r\n", reason); + DUMP_PRINTF("Cause 0x%016lx, EPC 0x%016lx\r\n", cause, epc); + + int i = 0; + for (i = 0; i < 32 / 2; i++) + { + DUMP_PRINTF( + "reg[%02d](%s) = 0x%016lx, reg[%02d](%s) = 0x%016lx\r\n", + i * 2, reg_usage[i * 2][0], regs[i * 2], + i * 2 + 1, reg_usage[i * 2 + 1][0], regs[i * 2 + 1]); + } + + for (i = 0; i < 32 / 2; i++) + { + DUMP_PRINTF( + "freg[%02d](%s) = 0x%016lx(%f), freg[%02d](%s) = 0x%016lx(%f)\r\n", + i * 2, regf_usage[i * 2][0], fregs[i * 2], (float)fregs[i * 2], + i * 2 + 1, regf_usage[i * 2 + 1][0], fregs[i * 2 + 1], (float)fregs[i * 2 + 1]); + } + } +} + +#undef DUMP_PRINTF + +#ifdef __cplusplus +} +#endif + +#endif /* _BSP_DUMP_H */ + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/encoding.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/encoding.h new file mode 100644 index 000000000..6a5f1a62d --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/encoding.h @@ -0,0 +1,1336 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file encoding.h +* @brief add from Canaan K210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef RISCV_CSR_ENCODING_H +#define RISCV_CSR_ENCODING_H + +#define MSTATUS_UIE 0x00000001U +#define MSTATUS_SIE 0x00000002U +#define MSTATUS_HIE 0x00000004U +#define MSTATUS_MIE 0x00000008U +#define MSTATUS_UPIE 0x00000010U +#define MSTATUS_SPIE 0x00000020U +#define MSTATUS_HPIE 0x00000040U +#define MSTATUS_MPIE 0x00000080U +#define MSTATUS_SPP 0x00000100U +#define MSTATUS_HPP 0x00000600U +#define MSTATUS_MPP 0x00001800U +#define MSTATUS_FS 0x00006000U +#define MSTATUS_XS 0x00018000U +#define MSTATUS_MPRV 0x00020000U +#define MSTATUS_PUM 0x00040000U +#define MSTATUS_MXR 0x00080000U +#define MSTATUS_VM 0x1F000000U +#define MSTATUS32_SD 0x80000000U +#define MSTATUS64_SD 0x8000000000000000U + +#define SSTATUS_UIE 0x00000001U +#define SSTATUS_SIE 0x00000002U +#define SSTATUS_UPIE 0x00000010U +#define SSTATUS_SPIE 0x00000020U +#define SSTATUS_SPP 0x00000100U +#define SSTATUS_FS 0x00006000U +#define SSTATUS_XS 0x00018000U +#define SSTATUS_PUM 0x00040000U +#define SSTATUS32_SD 0x80000000U +#define SSTATUS64_SD 0x8000000000000000U + +#define DCSR_XDEBUGVER (3U<<30) +#define DCSR_NDRESET (1U<<29) +#define DCSR_FULLRESET (1U<<28) +#define DCSR_EBREAKM (1U<<15) +#define DCSR_EBREAKH (1U<<14) +#define DCSR_EBREAKS (1U<<13) +#define DCSR_EBREAKU (1U<<12) +#define DCSR_STOPCYCLE (1U<<10) +#define DCSR_STOPTIME (1U<<9) +#define DCSR_CAUSE (7U<<6) +#define DCSR_DEBUGINT (1U<<5) +#define DCSR_HALT (1U<<3) +#define DCSR_STEP (1U<<2) +#define DCSR_PRV (3U<<0) + +#define DCSR_CAUSE_NONE 0 +#define DCSR_CAUSE_SWBP 1 +#define DCSR_CAUSE_HWBP 2 +#define DCSR_CAUSE_DEBUGINT 3 +#define DCSR_CAUSE_STEP 4 +#define DCSR_CAUSE_HALT 5 + +#define MCONTROL_SELECT (1U<<19) +#define MCONTROL_TIMING (1U<<18) +#define MCONTROL_ACTION (0x3fU<<12) +#define MCONTROL_CHAIN (1U<<11) +#define MCONTROL_MATCH (0xfU<<7) +#define MCONTROL_M (1U<<6) +#define MCONTROL_H (1U<<5) +#define MCONTROL_S (1U<<4) +#define MCONTROL_U (1U<<3) +#define MCONTROL_EXECUTE (1U<<2) +#define MCONTROL_STORE (1U<<1) +#define MCONTROL_LOAD (1U<<0) + +#define MCONTROL_TYPE_NONE 0 +#define MCONTROL_TYPE_MATCH 2 + +#define MCONTROL_ACTION_DEBUG_EXCEPTION 0 +#define MCONTROL_ACTION_DEBUG_MODE 1 +#define MCONTROL_ACTION_TRACE_START 2 +#define MCONTROL_ACTION_TRACE_STOP 3 +#define MCONTROL_ACTION_TRACE_EMIT 4 + +#define MCONTROL_MATCH_EQUAL 0 +#define MCONTROL_MATCH_NAPOT 1 +#define MCONTROL_MATCH_GE 2 +#define MCONTROL_MATCH_LT 3 +#define MCONTROL_MATCH_MASK_LOW 4 +#define MCONTROL_MATCH_MASK_HIGH 5 + +#define MIP_SSIP (1U << IRQ_S_SOFT) +#define MIP_HSIP (1U << IRQ_H_SOFT) +#define MIP_MSIP (1U << IRQ_M_SOFT) +#define MIP_STIP (1U << IRQ_S_TIMER) +#define MIP_HTIP (1U << IRQ_H_TIMER) +#define MIP_MTIP (1U << IRQ_M_TIMER) +#define MIP_SEIP (1U << IRQ_S_EXT) +#define MIP_HEIP (1U << IRQ_H_EXT) +#define MIP_MEIP (1U << IRQ_M_EXT) + +#define SIP_SSIP MIP_SSIP +#define SIP_STIP MIP_STIP + +#define PRV_U 0 +#define PRV_S 1 +#define PRV_H 2 +#define PRV_M 3 + +#define VM_MBARE 0 +#define VM_MBB 1 +#define VM_MBBID 2 +#define VM_SV32 8 +#define VM_SV39 9 +#define VM_SV48 10 + +#define IRQ_S_SOFT 1 +#define IRQ_H_SOFT 2 +#define IRQ_M_SOFT 3 +#define IRQ_S_TIMER 5 +#define IRQ_H_TIMER 6 +#define IRQ_M_TIMER 7 +#define IRQ_S_EXT 9 +#define IRQ_H_EXT 10 +#define IRQ_M_EXT 11 +#define IRQ_COP 12 +#define IRQ_HOST 13 + +#define DEFAULT_RSTVEC 0x00001000U +#define DEFAULT_NMIVEC 0x00001004U +#define DEFAULT_MTVEC 0x00001010U +#define CONFIG_STRING_ADDR 0x0000100CU +#define EXT_IO_BASE 0x40000000U +#define DRAM_BASE 0x80000000U + +/* page table entry (PTE) fields */ +#define PTE_V 0x001U /* Valid */ +#define PTE_R 0x002U /* Read */ +#define PTE_W 0x004U /* Write */ +#define PTE_X 0x008U /* Execute */ +#define PTE_U 0x010U /* User */ +#define PTE_G 0x020U /* Global */ +#define PTE_A 0x040U /* Accessed */ +#define PTE_D 0x080U /* Dirty */ +#define PTE_SOFT 0x300U /* Reserved for Software */ + +#define PTE_PPN_SHIFT 10 + +#define MCONTROL_TYPE(xlen) (0xfULL<<((xlen)-4)) +#define MCONTROL_DMODE(xlen) (1ULL<<((xlen)-5)) +#define MCONTROL_MASKMAX(xlen) (0x3fULL<<((xlen)-11)) + +#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V) + +#if defined(__riscv) + +#if defined(__riscv64) +# define MSTATUS_SD MSTATUS64_SD +# define SSTATUS_SD SSTATUS64_SD +# define RISCV_PGLEVEL_BITS 9 +#else +# define MSTATUS_SD MSTATUS32_SD +# define SSTATUS_SD SSTATUS32_SD +# define RISCV_PGLEVEL_BITS 10 +#endif +#define RISCV_PGSHIFT 12 +#define RISCV_PGSIZE (1 << RISCV_PGSHIFT) + +#ifndef __ASSEMBLER__ + +#if defined(__GNUC__) + +#define READ_CSR(reg) ({ unsigned long __tmp; \ + asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \ + __tmp; }) + +#define WRITE_CSR(reg, val) ({ \ + if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ + asm volatile ("csrw " #reg ", %0" :: "i"(val)); \ + else \ + asm volatile ("csrw " #reg ", %0" :: "r"(val)); }) + +#define swap_csr(reg, val) ({ unsigned long __tmp; \ + if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ + asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "i"(val)); \ + else \ + asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \ + __tmp; }) + +#define SET_CSR(reg, bit) ({ unsigned long __tmp; \ + if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ + asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \ + else \ + asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \ + __tmp; }) + +#define CLEAR_CSR(reg, bit) ({ unsigned long __tmp; \ + if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ + asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \ + else \ + asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \ + __tmp; }) + +#define read_time() READ_CSR(mtime) +#define read_cycle() READ_CSR(mcycle) +#define current_coreid() READ_CSR(mhartid) + +#endif + +#endif + +#endif + +#endif + +#ifndef RISCV_ENCODING_H +#define RISCV_ENCODING_H +#define MATCH_BEQ 0x63U +#define MASK_BEQ 0x707fU +#define MATCH_BNE 0x1063U +#define MASK_BNE 0x707fU +#define MATCH_BLT 0x4063U +#define MASK_BLT 0x707fU +#define MATCH_BGE 0x5063U +#define MASK_BGE 0x707fU +#define MATCH_BLTU 0x6063U +#define MASK_BLTU 0x707fU +#define MATCH_BGEU 0x7063U +#define MASK_BGEU 0x707fU +#define MATCH_JALR 0x67U +#define MASK_JALR 0x707fU +#define MATCH_JAL 0x6fU +#define MASK_JAL 0x7fU +#define MATCH_LUI 0x37U +#define MASK_LUI 0x7fU +#define MATCH_AUIPC 0x17U +#define MASK_AUIPC 0x7fU +#define MATCH_ADDI 0x13U +#define MASK_ADDI 0x707fU +#define MATCH_SLLI 0x1013U +#define MASK_SLLI 0xfc00707fU +#define MATCH_SLTI 0x2013U +#define MASK_SLTI 0x707fU +#define MATCH_SLTIU 0x3013U +#define MASK_SLTIU 0x707fU +#define MATCH_XORI 0x4013U +#define MASK_XORI 0x707fU +#define MATCH_SRLI 0x5013U +#define MASK_SRLI 0xfc00707fU +#define MATCH_SRAI 0x40005013U +#define MASK_SRAI 0xfc00707fU +#define MATCH_ORI 0x6013U +#define MASK_ORI 0x707fU +#define MATCH_ANDI 0x7013U +#define MASK_ANDI 0x707fU +#define MATCH_ADD 0x33U +#define MASK_ADD 0xfe00707fU +#define MATCH_SUB 0x40000033U +#define MASK_SUB 0xfe00707fU +#define MATCH_SLL 0x1033U +#define MASK_SLL 0xfe00707fU +#define MATCH_SLT 0x2033U +#define MASK_SLT 0xfe00707fU +#define MATCH_SLTU 0x3033U +#define MASK_SLTU 0xfe00707fU +#define MATCH_XOR 0x4033U +#define MASK_XOR 0xfe00707fU +#define MATCH_SRL 0x5033U +#define MASK_SRL 0xfe00707fU +#define MATCH_SRA 0x40005033U +#define MASK_SRA 0xfe00707fU +#define MATCH_OR 0x6033U +#define MASK_OR 0xfe00707fU +#define MATCH_AND 0x7033U +#define MASK_AND 0xfe00707fU +#define MATCH_ADDIW 0x1bU +#define MASK_ADDIW 0x707fU +#define MATCH_SLLIW 0x101bU +#define MASK_SLLIW 0xfe00707fU +#define MATCH_SRLIW 0x501bU +#define MASK_SRLIW 0xfe00707fU +#define MATCH_SRAIW 0x4000501bU +#define MASK_SRAIW 0xfe00707fU +#define MATCH_ADDW 0x3bU +#define MASK_ADDW 0xfe00707fU +#define MATCH_SUBW 0x4000003bU +#define MASK_SUBW 0xfe00707fU +#define MATCH_SLLW 0x103bU +#define MASK_SLLW 0xfe00707fU +#define MATCH_SRLW 0x503bU +#define MASK_SRLW 0xfe00707fU +#define MATCH_SRAW 0x4000503bU +#define MASK_SRAW 0xfe00707fU +#define MATCH_LB 0x3U +#define MASK_LB 0x707fU +#define MATCH_LH 0x1003U +#define MASK_LH 0x707fU +#define MATCH_LW 0x2003U +#define MASK_LW 0x707fU +#define MATCH_LD 0x3003U +#define MASK_LD 0x707fU +#define MATCH_LBU 0x4003U +#define MASK_LBU 0x707fU +#define MATCH_LHU 0x5003U +#define MASK_LHU 0x707fU +#define MATCH_LWU 0x6003U +#define MASK_LWU 0x707fU +#define MATCH_SB 0x23U +#define MASK_SB 0x707fU +#define MATCH_SH 0x1023U +#define MASK_SH 0x707fU +#define MATCH_SW 0x2023U +#define MASK_SW 0x707fU +#define MATCH_SD 0x3023U +#define MASK_SD 0x707fU +#define MATCH_FENCE 0xfU +#define MASK_FENCE 0x707fU +#define MATCH_FENCE_I 0x100fU +#define MASK_FENCE_I 0x707fU +#define MATCH_MUL 0x2000033U +#define MASK_MUL 0xfe00707fU +#define MATCH_MULH 0x2001033U +#define MASK_MULH 0xfe00707fU +#define MATCH_MULHSU 0x2002033U +#define MASK_MULHSU 0xfe00707fU +#define MATCH_MULHU 0x2003033U +#define MASK_MULHU 0xfe00707fU +#define MATCH_DIV 0x2004033U +#define MASK_DIV 0xfe00707fU +#define MATCH_DIVU 0x2005033U +#define MASK_DIVU 0xfe00707fU +#define MATCH_REM 0x2006033U +#define MASK_REM 0xfe00707fU +#define MATCH_REMU 0x2007033U +#define MASK_REMU 0xfe00707fU +#define MATCH_MULW 0x200003bU +#define MASK_MULW 0xfe00707fU +#define MATCH_DIVW 0x200403bU +#define MASK_DIVW 0xfe00707fU +#define MATCH_DIVUW 0x200503bU +#define MASK_DIVUW 0xfe00707fU +#define MATCH_REMW 0x200603bU +#define MASK_REMW 0xfe00707fU +#define MATCH_REMUW 0x200703bU +#define MASK_REMUW 0xfe00707fU +#define MATCH_AMOADD_W 0x202fU +#define MASK_AMOADD_W 0xf800707fU +#define MATCH_AMOXOR_W 0x2000202fU +#define MASK_AMOXOR_W 0xf800707fU +#define MATCH_AMOOR_W 0x4000202fU +#define MASK_AMOOR_W 0xf800707fU +#define MATCH_AMOAND_W 0x6000202fU +#define MASK_AMOAND_W 0xf800707fU +#define MATCH_AMOMIN_W 0x8000202fU +#define MASK_AMOMIN_W 0xf800707fU +#define MATCH_AMOMAX_W 0xa000202fU +#define MASK_AMOMAX_W 0xf800707fU +#define MATCH_AMOMINU_W 0xc000202fU +#define MASK_AMOMINU_W 0xf800707fU +#define MATCH_AMOMAXU_W 0xe000202fU +#define MASK_AMOMAXU_W 0xf800707fU +#define MATCH_AMOSWAP_W 0x800202fU +#define MASK_AMOSWAP_W 0xf800707fU +#define MATCH_LR_W 0x1000202fU +#define MASK_LR_W 0xf9f0707fU +#define MATCH_SC_W 0x1800202fU +#define MASK_SC_W 0xf800707fU +#define MATCH_AMOADD_D 0x302fU +#define MASK_AMOADD_D 0xf800707fU +#define MATCH_AMOXOR_D 0x2000302fU +#define MASK_AMOXOR_D 0xf800707fU +#define MATCH_AMOOR_D 0x4000302fU +#define MASK_AMOOR_D 0xf800707fU +#define MATCH_AMOAND_D 0x6000302fU +#define MASK_AMOAND_D 0xf800707fU +#define MATCH_AMOMIN_D 0x8000302fU +#define MASK_AMOMIN_D 0xf800707fU +#define MATCH_AMOMAX_D 0xa000302fU +#define MASK_AMOMAX_D 0xf800707fU +#define MATCH_AMOMINU_D 0xc000302fU +#define MASK_AMOMINU_D 0xf800707fU +#define MATCH_AMOMAXU_D 0xe000302fU +#define MASK_AMOMAXU_D 0xf800707fU +#define MATCH_AMOSWAP_D 0x800302fU +#define MASK_AMOSWAP_D 0xf800707fU +#define MATCH_LR_D 0x1000302fU +#define MASK_LR_D 0xf9f0707fU +#define MATCH_SC_D 0x1800302fU +#define MASK_SC_D 0xf800707fU +#define MATCH_ECALL 0x73U +#define MASK_ECALL 0xffffffffU +#define MATCH_EBREAK 0x100073U +#define MASK_EBREAK 0xffffffffU +#define MATCH_URET 0x200073U +#define MASK_URET 0xffffffffU +#define MATCH_SRET 0x10200073U +#define MASK_SRET 0xffffffffU +#define MATCH_HRET 0x20200073U +#define MASK_HRET 0xffffffffU +#define MATCH_MRET 0x30200073U +#define MASK_MRET 0xffffffffU +#define MATCH_DRET 0x7b200073U +#define MASK_DRET 0xffffffffU +#define MATCH_SFENCE_VM 0x10400073U +#define MASK_SFENCE_VM 0xfff07fffU +#define MATCH_WFI 0x10500073U +#define MASK_WFI 0xffffffffU +#define MATCH_CSRRW 0x1073U +#define MASK_CSRRW 0x707fU +#define MATCH_CSRRS 0x2073U +#define MASK_CSRRS 0x707fU +#define MATCH_CSRRC 0x3073U +#define MASK_CSRRC 0x707fU +#define MATCH_CSRRWI 0x5073U +#define MASK_CSRRWI 0x707fU +#define MATCH_CSRRSI 0x6073U +#define MASK_CSRRSI 0x707fU +#define MATCH_CSRRCI 0x7073U +#define MASK_CSRRCI 0x707fU +#define MATCH_FADD_S 0x53U +#define MASK_FADD_S 0xfe00007fU +#define MATCH_FSUB_S 0x8000053U +#define MASK_FSUB_S 0xfe00007fU +#define MATCH_FMUL_S 0x10000053U +#define MASK_FMUL_S 0xfe00007fU +#define MATCH_FDIV_S 0x18000053U +#define MASK_FDIV_S 0xfe00007fU +#define MATCH_FSGNJ_S 0x20000053U +#define MASK_FSGNJ_S 0xfe00707fU +#define MATCH_FSGNJN_S 0x20001053U +#define MASK_FSGNJN_S 0xfe00707fU +#define MATCH_FSGNJX_S 0x20002053U +#define MASK_FSGNJX_S 0xfe00707fU +#define MATCH_FMIN_S 0x28000053U +#define MASK_FMIN_S 0xfe00707fU +#define MATCH_FMAX_S 0x28001053U +#define MASK_FMAX_S 0xfe00707fU +#define MATCH_FSQRT_S 0x58000053U +#define MASK_FSQRT_S 0xfff0007fU +#define MATCH_FADD_D 0x2000053U +#define MASK_FADD_D 0xfe00007fU +#define MATCH_FSUB_D 0xa000053U +#define MASK_FSUB_D 0xfe00007fU +#define MATCH_FMUL_D 0x12000053U +#define MASK_FMUL_D 0xfe00007fU +#define MATCH_FDIV_D 0x1a000053U +#define MASK_FDIV_D 0xfe00007fU +#define MATCH_FSGNJ_D 0x22000053U +#define MASK_FSGNJ_D 0xfe00707fU +#define MATCH_FSGNJN_D 0x22001053U +#define MASK_FSGNJN_D 0xfe00707fU +#define MATCH_FSGNJX_D 0x22002053U +#define MASK_FSGNJX_D 0xfe00707fU +#define MATCH_FMIN_D 0x2a000053U +#define MASK_FMIN_D 0xfe00707fU +#define MATCH_FMAX_D 0x2a001053U +#define MASK_FMAX_D 0xfe00707fU +#define MATCH_FCVT_S_D 0x40100053U +#define MASK_FCVT_S_D 0xfff0007fU +#define MATCH_FCVT_D_S 0x42000053U +#define MASK_FCVT_D_S 0xfff0007fU +#define MATCH_FSQRT_D 0x5a000053U +#define MASK_FSQRT_D 0xfff0007fU +#define MATCH_FLE_S 0xa0000053U +#define MASK_FLE_S 0xfe00707fU +#define MATCH_FLT_S 0xa0001053U +#define MASK_FLT_S 0xfe00707fU +#define MATCH_FEQ_S 0xa0002053U +#define MASK_FEQ_S 0xfe00707fU +#define MATCH_FLE_D 0xa2000053U +#define MASK_FLE_D 0xfe00707fU +#define MATCH_FLT_D 0xa2001053U +#define MASK_FLT_D 0xfe00707fU +#define MATCH_FEQ_D 0xa2002053U +#define MASK_FEQ_D 0xfe00707fU +#define MATCH_FCVT_W_S 0xc0000053U +#define MASK_FCVT_W_S 0xfff0007fU +#define MATCH_FCVT_WU_S 0xc0100053U +#define MASK_FCVT_WU_S 0xfff0007fU +#define MATCH_FCVT_L_S 0xc0200053U +#define MASK_FCVT_L_S 0xfff0007fU +#define MATCH_FCVT_LU_S 0xc0300053U +#define MASK_FCVT_LU_S 0xfff0007fU +#define MATCH_FMV_X_S 0xe0000053U +#define MASK_FMV_X_S 0xfff0707fU +#define MATCH_FCLASS_S 0xe0001053U +#define MASK_FCLASS_S 0xfff0707fU +#define MATCH_FCVT_W_D 0xc2000053U +#define MASK_FCVT_W_D 0xfff0007fU +#define MATCH_FCVT_WU_D 0xc2100053U +#define MASK_FCVT_WU_D 0xfff0007fU +#define MATCH_FCVT_L_D 0xc2200053U +#define MASK_FCVT_L_D 0xfff0007fU +#define MATCH_FCVT_LU_D 0xc2300053U +#define MASK_FCVT_LU_D 0xfff0007fU +#define MATCH_FMV_X_D 0xe2000053U +#define MASK_FMV_X_D 0xfff0707fU +#define MATCH_FCLASS_D 0xe2001053U +#define MASK_FCLASS_D 0xfff0707fU +#define MATCH_FCVT_S_W 0xd0000053U +#define MASK_FCVT_S_W 0xfff0007fU +#define MATCH_FCVT_S_WU 0xd0100053U +#define MASK_FCVT_S_WU 0xfff0007fU +#define MATCH_FCVT_S_L 0xd0200053U +#define MASK_FCVT_S_L 0xfff0007fU +#define MATCH_FCVT_S_LU 0xd0300053U +#define MASK_FCVT_S_LU 0xfff0007fU +#define MATCH_FMV_S_X 0xf0000053U +#define MASK_FMV_S_X 0xfff0707fU +#define MATCH_FCVT_D_W 0xd2000053U +#define MASK_FCVT_D_W 0xfff0007fU +#define MATCH_FCVT_D_WU 0xd2100053U +#define MASK_FCVT_D_WU 0xfff0007fU +#define MATCH_FCVT_D_L 0xd2200053U +#define MASK_FCVT_D_L 0xfff0007fU +#define MATCH_FCVT_D_LU 0xd2300053U +#define MASK_FCVT_D_LU 0xfff0007fU +#define MATCH_FMV_D_X 0xf2000053U +#define MASK_FMV_D_X 0xfff0707fU +#define MATCH_FLW 0x2007U +#define MASK_FLW 0x707fU +#define MATCH_FLD 0x3007U +#define MASK_FLD 0x707fU +#define MATCH_FSW 0x2027U +#define MASK_FSW 0x707fU +#define MATCH_FSD 0x3027U +#define MASK_FSD 0x707fU +#define MATCH_FMADD_S 0x43U +#define MASK_FMADD_S 0x600007fU +#define MATCH_FMSUB_S 0x47U +#define MASK_FMSUB_S 0x600007fU +#define MATCH_FNMSUB_S 0x4bU +#define MASK_FNMSUB_S 0x600007fU +#define MATCH_FNMADD_S 0x4fU +#define MASK_FNMADD_S 0x600007fU +#define MATCH_FMADD_D 0x2000043U +#define MASK_FMADD_D 0x600007fU +#define MATCH_FMSUB_D 0x2000047U +#define MASK_FMSUB_D 0x600007fU +#define MATCH_FNMSUB_D 0x200004bU +#define MASK_FNMSUB_D 0x600007fU +#define MATCH_FNMADD_D 0x200004fU +#define MASK_FNMADD_D 0x600007fU +#define MATCH_C_NOP 0x1U +#define MASK_C_NOP 0xffffU +#define MATCH_C_ADDI16SP 0x6101U +#define MASK_C_ADDI16SP 0xef83U +#define MATCH_C_JR 0x8002U +#define MASK_C_JR 0xf07fU +#define MATCH_C_JALR 0x9002U +#define MASK_C_JALR 0xf07fU +#define MATCH_C_EBREAK 0x9002U +#define MASK_C_EBREAK 0xffffU +#define MATCH_C_LD 0x6000U +#define MASK_C_LD 0xe003U +#define MATCH_C_SD 0xe000U +#define MASK_C_SD 0xe003U +#define MATCH_C_ADDIW 0x2001U +#define MASK_C_ADDIW 0xe003U +#define MATCH_C_LDSP 0x6002U +#define MASK_C_LDSP 0xe003U +#define MATCH_C_SDSP 0xe002U +#define MASK_C_SDSP 0xe003U +#define MATCH_C_ADDI4SPN 0x0U +#define MASK_C_ADDI4SPN 0xe003U +#define MATCH_C_FLD 0x2000U +#define MASK_C_FLD 0xe003U +#define MATCH_C_LW 0x4000U +#define MASK_C_LW 0xe003U +#define MATCH_C_FLW 0x6000U +#define MASK_C_FLW 0xe003U +#define MATCH_C_FSD 0xa000U +#define MASK_C_FSD 0xe003U +#define MATCH_C_SW 0xc000U +#define MASK_C_SW 0xe003U +#define MATCH_C_FSW 0xe000U +#define MASK_C_FSW 0xe003U +#define MATCH_C_ADDI 0x1U +#define MASK_C_ADDI 0xe003U +#define MATCH_C_JAL 0x2001U +#define MASK_C_JAL 0xe003U +#define MATCH_C_LI 0x4001U +#define MASK_C_LI 0xe003U +#define MATCH_C_LUI 0x6001U +#define MASK_C_LUI 0xe003U +#define MATCH_C_SRLI 0x8001U +#define MASK_C_SRLI 0xec03U +#define MATCH_C_SRAI 0x8401U +#define MASK_C_SRAI 0xec03U +#define MATCH_C_ANDI 0x8801U +#define MASK_C_ANDI 0xec03U +#define MATCH_C_SUB 0x8c01U +#define MASK_C_SUB 0xfc63U +#define MATCH_C_XOR 0x8c21U +#define MASK_C_XOR 0xfc63U +#define MATCH_C_OR 0x8c41U +#define MASK_C_OR 0xfc63U +#define MATCH_C_AND 0x8c61U +#define MASK_C_AND 0xfc63U +#define MATCH_C_SUBW 0x9c01U +#define MASK_C_SUBW 0xfc63U +#define MATCH_C_ADDW 0x9c21U +#define MASK_C_ADDW 0xfc63U +#define MATCH_C_J 0xa001U +#define MASK_C_J 0xe003U +#define MATCH_C_BEQZ 0xc001U +#define MASK_C_BEQZ 0xe003U +#define MATCH_C_BNEZ 0xe001U +#define MASK_C_BNEZ 0xe003U +#define MATCH_C_SLLI 0x2U +#define MASK_C_SLLI 0xe003U +#define MATCH_C_FLDSP 0x2002U +#define MASK_C_FLDSP 0xe003U +#define MATCH_C_LWSP 0x4002U +#define MASK_C_LWSP 0xe003U +#define MATCH_C_FLWSP 0x6002U +#define MASK_C_FLWSP 0xe003U +#define MATCH_C_MV 0x8002U +#define MASK_C_MV 0xf003U +#define MATCH_C_ADD 0x9002U +#define MASK_C_ADD 0xf003U +#define MATCH_C_FSDSP 0xa002U +#define MASK_C_FSDSP 0xe003U +#define MATCH_C_SWSP 0xc002U +#define MASK_C_SWSP 0xe003U +#define MATCH_C_FSWSP 0xe002U +#define MASK_C_FSWSP 0xe003U +#define MATCH_CUSTOM0 0xbU +#define MASK_CUSTOM0 0x707fU +#define MATCH_CUSTOM0_RS1 0x200bU +#define MASK_CUSTOM0_RS1 0x707fU +#define MATCH_CUSTOM0_RS1_RS2 0x300bU +#define MASK_CUSTOM0_RS1_RS2 0x707fU +#define MATCH_CUSTOM0_RD 0x400bU +#define MASK_CUSTOM0_RD 0x707fU +#define MATCH_CUSTOM0_RD_RS1 0x600bU +#define MASK_CUSTOM0_RD_RS1 0x707fU +#define MATCH_CUSTOM0_RD_RS1_RS2 0x700bU +#define MASK_CUSTOM0_RD_RS1_RS2 0x707fU +#define MATCH_CUSTOM1 0x2bU +#define MASK_CUSTOM1 0x707fU +#define MATCH_CUSTOM1_RS1 0x202bU +#define MASK_CUSTOM1_RS1 0x707fU +#define MATCH_CUSTOM1_RS1_RS2 0x302bU +#define MASK_CUSTOM1_RS1_RS2 0x707fU +#define MATCH_CUSTOM1_RD 0x402bU +#define MASK_CUSTOM1_RD 0x707fU +#define MATCH_CUSTOM1_RD_RS1 0x602bU +#define MASK_CUSTOM1_RD_RS1 0x707fU +#define MATCH_CUSTOM1_RD_RS1_RS2 0x702bU +#define MASK_CUSTOM1_RD_RS1_RS2 0x707fU +#define MATCH_CUSTOM2 0x5bU +#define MASK_CUSTOM2 0x707fU +#define MATCH_CUSTOM2_RS1 0x205bU +#define MASK_CUSTOM2_RS1 0x707fU +#define MATCH_CUSTOM2_RS1_RS2 0x305bU +#define MASK_CUSTOM2_RS1_RS2 0x707fU +#define MATCH_CUSTOM2_RD 0x405bU +#define MASK_CUSTOM2_RD 0x707fU +#define MATCH_CUSTOM2_RD_RS1 0x605bU +#define MASK_CUSTOM2_RD_RS1 0x707fU +#define MATCH_CUSTOM2_RD_RS1_RS2 0x705bU +#define MASK_CUSTOM2_RD_RS1_RS2 0x707fU +#define MATCH_CUSTOM3 0x7bU +#define MASK_CUSTOM3 0x707fU +#define MATCH_CUSTOM3_RS1 0x207bU +#define MASK_CUSTOM3_RS1 0x707fU +#define MATCH_CUSTOM3_RS1_RS2 0x307bU +#define MASK_CUSTOM3_RS1_RS2 0x707fU +#define MATCH_CUSTOM3_RD 0x407bU +#define MASK_CUSTOM3_RD 0x707fU +#define MATCH_CUSTOM3_RD_RS1 0x607bU +#define MASK_CUSTOM3_RD_RS1 0x707fU +#define MATCH_CUSTOM3_RD_RS1_RS2 0x707bU +#define MASK_CUSTOM3_RD_RS1_RS2 0x707fU +#define CSR_FFLAGS 0x1U +#define CSR_FRM 0x2U +#define CSR_FCSR 0x3U +#define CSR_CYCLE 0xc00U +#define CSR_TIME 0xc01U +#define CSR_INSTRET 0xc02U +#define CSR_HPMCOUNTER3 0xc03U +#define CSR_HPMCOUNTER4 0xc04U +#define CSR_HPMCOUNTER5 0xc05U +#define CSR_HPMCOUNTER6 0xc06U +#define CSR_HPMCOUNTER7 0xc07U +#define CSR_HPMCOUNTER8 0xc08U +#define CSR_HPMCOUNTER9 0xc09U +#define CSR_HPMCOUNTER10 0xc0aU +#define CSR_HPMCOUNTER11 0xc0bU +#define CSR_HPMCOUNTER12 0xc0cU +#define CSR_HPMCOUNTER13 0xc0dU +#define CSR_HPMCOUNTER14 0xc0eU +#define CSR_HPMCOUNTER15 0xc0fU +#define CSR_HPMCOUNTER16 0xc10U +#define CSR_HPMCOUNTER17 0xc11U +#define CSR_HPMCOUNTER18 0xc12U +#define CSR_HPMCOUNTER19 0xc13U +#define CSR_HPMCOUNTER20 0xc14U +#define CSR_HPMCOUNTER21 0xc15U +#define CSR_HPMCOUNTER22 0xc16U +#define CSR_HPMCOUNTER23 0xc17U +#define CSR_HPMCOUNTER24 0xc18U +#define CSR_HPMCOUNTER25 0xc19U +#define CSR_HPMCOUNTER26 0xc1aU +#define CSR_HPMCOUNTER27 0xc1bU +#define CSR_HPMCOUNTER28 0xc1cU +#define CSR_HPMCOUNTER29 0xc1dU +#define CSR_HPMCOUNTER30 0xc1eU +#define CSR_HPMCOUNTER31 0xc1fU +#define CSR_SSTATUS 0x100U +#define CSR_SIE 0x104U +#define CSR_STVEC 0x105U +#define CSR_SSCRATCH 0x140U +#define CSR_SEPC 0x141U +#define CSR_SCAUSE 0x142U +#define CSR_SBADADDR 0x143U +#define CSR_SIP 0x144U +#define CSR_SPTBR 0x180U +#define CSR_MSTATUS 0x300U +#define CSR_MISA 0x301U +#define CSR_MEDELEG 0x302U +#define CSR_MIDELEG 0x303U +#define CSR_MIE 0x304U +#define CSR_MTVEC 0x305U +#define CSR_MSCRATCH 0x340U +#define CSR_MEPC 0x341U +#define CSR_MCAUSE 0x342U +#define CSR_MBADADDR 0x343U +#define CSR_MIP 0x344U +#define CSR_TSELECT 0x7a0U +#define CSR_TDATA1 0x7a1U +#define CSR_TDATA2 0x7a2U +#define CSR_TDATA3 0x7a3U +#define CSR_DCSR 0x7b0U +#define CSR_DPC 0x7b1U +#define CSR_DSCRATCH 0x7b2U +#define CSR_MCYCLE 0xb00U +#define CSR_MINSTRET 0xb02U +#define CSR_MHPMCOUNTER3 0xb03U +#define CSR_MHPMCOUNTER4 0xb04U +#define CSR_MHPMCOUNTER5 0xb05U +#define CSR_MHPMCOUNTER6 0xb06U +#define CSR_MHPMCOUNTER7 0xb07U +#define CSR_MHPMCOUNTER8 0xb08U +#define CSR_MHPMCOUNTER9 0xb09U +#define CSR_MHPMCOUNTER10 0xb0aU +#define CSR_MHPMCOUNTER11 0xb0bU +#define CSR_MHPMCOUNTER12 0xb0cU +#define CSR_MHPMCOUNTER13 0xb0dU +#define CSR_MHPMCOUNTER14 0xb0eU +#define CSR_MHPMCOUNTER15 0xb0fU +#define CSR_MHPMCOUNTER16 0xb10U +#define CSR_MHPMCOUNTER17 0xb11U +#define CSR_MHPMCOUNTER18 0xb12U +#define CSR_MHPMCOUNTER19 0xb13U +#define CSR_MHPMCOUNTER20 0xb14U +#define CSR_MHPMCOUNTER21 0xb15U +#define CSR_MHPMCOUNTER22 0xb16U +#define CSR_MHPMCOUNTER23 0xb17U +#define CSR_MHPMCOUNTER24 0xb18U +#define CSR_MHPMCOUNTER25 0xb19U +#define CSR_MHPMCOUNTER26 0xb1aU +#define CSR_MHPMCOUNTER27 0xb1bU +#define CSR_MHPMCOUNTER28 0xb1cU +#define CSR_MHPMCOUNTER29 0xb1dU +#define CSR_MHPMCOUNTER30 0xb1eU +#define CSR_MHPMCOUNTER31 0xb1fU +#define CSR_MUCOUNTEREN 0x320U +#define CSR_MSCOUNTEREN 0x321U +#define CSR_MHPMEVENT3 0x323U +#define CSR_MHPMEVENT4 0x324U +#define CSR_MHPMEVENT5 0x325U +#define CSR_MHPMEVENT6 0x326U +#define CSR_MHPMEVENT7 0x327U +#define CSR_MHPMEVENT8 0x328U +#define CSR_MHPMEVENT9 0x329U +#define CSR_MHPMEVENT10 0x32aU +#define CSR_MHPMEVENT11 0x32bU +#define CSR_MHPMEVENT12 0x32cU +#define CSR_MHPMEVENT13 0x32dU +#define CSR_MHPMEVENT14 0x32eU +#define CSR_MHPMEVENT15 0x32fU +#define CSR_MHPMEVENT16 0x330U +#define CSR_MHPMEVENT17 0x331U +#define CSR_MHPMEVENT18 0x332U +#define CSR_MHPMEVENT19 0x333U +#define CSR_MHPMEVENT20 0x334U +#define CSR_MHPMEVENT21 0x335U +#define CSR_MHPMEVENT22 0x336U +#define CSR_MHPMEVENT23 0x337U +#define CSR_MHPMEVENT24 0x338U +#define CSR_MHPMEVENT25 0x339U +#define CSR_MHPMEVENT26 0x33aU +#define CSR_MHPMEVENT27 0x33bU +#define CSR_MHPMEVENT28 0x33cU +#define CSR_MHPMEVENT29 0x33dU +#define CSR_MHPMEVENT30 0x33eU +#define CSR_MHPMEVENT31 0x33fU +#define CSR_MVENDORID 0xf11U +#define CSR_MARCHID 0xf12U +#define CSR_MIMPID 0xf13U +#define CSR_MHARTID 0xf14U +#define CSR_CYCLEH 0xc80U +#define CSR_TIMEH 0xc81U +#define CSR_INSTRETH 0xc82U +#define CSR_HPMCOUNTER3H 0xc83U +#define CSR_HPMCOUNTER4H 0xc84U +#define CSR_HPMCOUNTER5H 0xc85U +#define CSR_HPMCOUNTER6H 0xc86U +#define CSR_HPMCOUNTER7H 0xc87U +#define CSR_HPMCOUNTER8H 0xc88U +#define CSR_HPMCOUNTER9H 0xc89U +#define CSR_HPMCOUNTER10H 0xc8aU +#define CSR_HPMCOUNTER11H 0xc8bU +#define CSR_HPMCOUNTER12H 0xc8cU +#define CSR_HPMCOUNTER13H 0xc8dU +#define CSR_HPMCOUNTER14H 0xc8eU +#define CSR_HPMCOUNTER15H 0xc8fU +#define CSR_HPMCOUNTER16H 0xc90U +#define CSR_HPMCOUNTER17H 0xc91U +#define CSR_HPMCOUNTER18H 0xc92U +#define CSR_HPMCOUNTER19H 0xc93U +#define CSR_HPMCOUNTER20H 0xc94U +#define CSR_HPMCOUNTER21H 0xc95U +#define CSR_HPMCOUNTER22H 0xc96U +#define CSR_HPMCOUNTER23H 0xc97U +#define CSR_HPMCOUNTER24H 0xc98U +#define CSR_HPMCOUNTER25H 0xc99U +#define CSR_HPMCOUNTER26H 0xc9aU +#define CSR_HPMCOUNTER27H 0xc9bU +#define CSR_HPMCOUNTER28H 0xc9cU +#define CSR_HPMCOUNTER29H 0xc9dU +#define CSR_HPMCOUNTER30H 0xc9eU +#define CSR_HPMCOUNTER31H 0xc9fU +#define CSR_MCYCLEH 0xb80U +#define CSR_MINSTRETH 0xb82U +#define CSR_MHPMCOUNTER3H 0xb83U +#define CSR_MHPMCOUNTER4H 0xb84U +#define CSR_MHPMCOUNTER5H 0xb85U +#define CSR_MHPMCOUNTER6H 0xb86U +#define CSR_MHPMCOUNTER7H 0xb87U +#define CSR_MHPMCOUNTER8H 0xb88U +#define CSR_MHPMCOUNTER9H 0xb89U +#define CSR_MHPMCOUNTER10H 0xb8aU +#define CSR_MHPMCOUNTER11H 0xb8bU +#define CSR_MHPMCOUNTER12H 0xb8cU +#define CSR_MHPMCOUNTER13H 0xb8dU +#define CSR_MHPMCOUNTER14H 0xb8eU +#define CSR_MHPMCOUNTER15H 0xb8fU +#define CSR_MHPMCOUNTER16H 0xb90U +#define CSR_MHPMCOUNTER17H 0xb91U +#define CSR_MHPMCOUNTER18H 0xb92U +#define CSR_MHPMCOUNTER19H 0xb93U +#define CSR_MHPMCOUNTER20H 0xb94U +#define CSR_MHPMCOUNTER21H 0xb95U +#define CSR_MHPMCOUNTER22H 0xb96U +#define CSR_MHPMCOUNTER23H 0xb97U +#define CSR_MHPMCOUNTER24H 0xb98U +#define CSR_MHPMCOUNTER25H 0xb99U +#define CSR_MHPMCOUNTER26H 0xb9aU +#define CSR_MHPMCOUNTER27H 0xb9bU +#define CSR_MHPMCOUNTER28H 0xb9cU +#define CSR_MHPMCOUNTER29H 0xb9dU +#define CSR_MHPMCOUNTER30H 0xb9eU +#define CSR_MHPMCOUNTER31H 0xb9fU +#define CAUSE_MISALIGNED_FETCH 0x0 +#define CAUSE_FAULT_FETCH 0x1 +#define CAUSE_ILLEGAL_INSTRUCTION 0x2 +#define CAUSE_BREAKPOINT 0x3 +#define CAUSE_MISALIGNED_LOAD 0x4 +#define CAUSE_FAULT_LOAD 0x5 +#define CAUSE_MISALIGNED_STORE 0x6 +#define CAUSE_FAULT_STORE 0x7 +#define CAUSE_USER_ECALL 0x8 +#define CAUSE_SUPERVISOR_ECALL 0x9 +#define CAUSE_HYPERVISOR_ECALL 0xa +#define CAUSE_MACHINE_ECALL 0xb +#endif +#if defined(DECLARE_INSN) +DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ) +DECLARE_INSN(bne, MATCH_BNE, MASK_BNE) +DECLARE_INSN(blt, MATCH_BLT, MASK_BLT) +DECLARE_INSN(bge, MATCH_BGE, MASK_BGE) +DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU) +DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU) +DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR) +DECLARE_INSN(jal, MATCH_JAL, MASK_JAL) +DECLARE_INSN(lui, MATCH_LUI, MASK_LUI) +DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC) +DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI) +DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI) +DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI) +DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU) +DECLARE_INSN(xori, MATCH_XORI, MASK_XORI) +DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI) +DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI) +DECLARE_INSN(ori, MATCH_ORI, MASK_ORI) +DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI) +DECLARE_INSN(add, MATCH_ADD, MASK_ADD) +DECLARE_INSN(sub, MATCH_SUB, MASK_SUB) +DECLARE_INSN(sll, MATCH_SLL, MASK_SLL) +DECLARE_INSN(slt, MATCH_SLT, MASK_SLT) +DECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU) +DECLARE_INSN(xor, MATCH_XOR, MASK_XOR) +DECLARE_INSN(srl, MATCH_SRL, MASK_SRL) +DECLARE_INSN(sra, MATCH_SRA, MASK_SRA) +DECLARE_INSN(or, MATCH_OR, MASK_OR) +DECLARE_INSN(and, MATCH_AND, MASK_AND) +DECLARE_INSN(addiw, MATCH_ADDIW, MASK_ADDIW) +DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW) +DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW) +DECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW) +DECLARE_INSN(addw, MATCH_ADDW, MASK_ADDW) +DECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW) +DECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW) +DECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW) +DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW) +DECLARE_INSN(lb, MATCH_LB, MASK_LB) +DECLARE_INSN(lh, MATCH_LH, MASK_LH) +DECLARE_INSN(lw, MATCH_LW, MASK_LW) +DECLARE_INSN(ld, MATCH_LD, MASK_LD) +DECLARE_INSN(lbu, MATCH_LBU, MASK_LBU) +DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU) +DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU) +DECLARE_INSN(sb, MATCH_SB, MASK_SB) +DECLARE_INSN(sh, MATCH_SH, MASK_SH) +DECLARE_INSN(sw, MATCH_SW, MASK_SW) +DECLARE_INSN(sd, MATCH_SD, MASK_SD) +DECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE) +DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I) +DECLARE_INSN(mul, MATCH_MUL, MASK_MUL) +DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH) +DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU) +DECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU) +DECLARE_INSN(div, MATCH_DIV, MASK_DIV) +DECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU) +DECLARE_INSN(rem, MATCH_REM, MASK_REM) +DECLARE_INSN(remu, MATCH_REMU, MASK_REMU) +DECLARE_INSN(mulw, MATCH_MULW, MASK_MULW) +DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW) +DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW) +DECLARE_INSN(remw, MATCH_REMW, MASK_REMW) +DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW) +DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W) +DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W) +DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W) +DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W) +DECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W) +DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W) +DECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W) +DECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W) +DECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W) +DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W) +DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W) +DECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D) +DECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D) +DECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D) +DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D) +DECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D) +DECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D) +DECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D) +DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D) +DECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D) +DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D) +DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D) +DECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL) +DECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK) +DECLARE_INSN(uret, MATCH_URET, MASK_URET) +DECLARE_INSN(sret, MATCH_SRET, MASK_SRET) +DECLARE_INSN(hret, MATCH_HRET, MASK_HRET) +DECLARE_INSN(mret, MATCH_MRET, MASK_MRET) +DECLARE_INSN(dret, MATCH_DRET, MASK_DRET) +DECLARE_INSN(sfence_vm, MATCH_SFENCE_VM, MASK_SFENCE_VM) +DECLARE_INSN(wfi, MATCH_WFI, MASK_WFI) +DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW) +DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS) +DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC) +DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI) +DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI) +DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI) +DECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S) +DECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S) +DECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S) +DECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S) +DECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S) +DECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S) +DECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S) +DECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S) +DECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S) +DECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S) +DECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D) +DECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D) +DECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D) +DECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D) +DECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D) +DECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D) +DECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D) +DECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D) +DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D) +DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D) +DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S) +DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D) +DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S) +DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S) +DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S) +DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D) +DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D) +DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D) +DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S) +DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S) +DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S) +DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S) +DECLARE_INSN(fmv_x_s, MATCH_FMV_X_S, MASK_FMV_X_S) +DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S) +DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D) +DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D) +DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D) +DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D) +DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D) +DECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D) +DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W) +DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU) +DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L) +DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU) +DECLARE_INSN(fmv_s_x, MATCH_FMV_S_X, MASK_FMV_S_X) +DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W) +DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU) +DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L) +DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU) +DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X) +DECLARE_INSN(flw, MATCH_FLW, MASK_FLW) +DECLARE_INSN(fld, MATCH_FLD, MASK_FLD) +DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW) +DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD) +DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S) +DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S) +DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S) +DECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S) +DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D) +DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D) +DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D) +DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D) +DECLARE_INSN(c_nop, MATCH_C_NOP, MASK_C_NOP) +DECLARE_INSN(c_addi16sp, MATCH_C_ADDI16SP, MASK_C_ADDI16SP) +DECLARE_INSN(c_jr, MATCH_C_JR, MASK_C_JR) +DECLARE_INSN(c_jalr, MATCH_C_JALR, MASK_C_JALR) +DECLARE_INSN(c_ebreak, MATCH_C_EBREAK, MASK_C_EBREAK) +DECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD) +DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD) +DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW) +DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP) +DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP) +DECLARE_INSN(c_addi4spn, MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN) +DECLARE_INSN(c_fld, MATCH_C_FLD, MASK_C_FLD) +DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW) +DECLARE_INSN(c_flw, MATCH_C_FLW, MASK_C_FLW) +DECLARE_INSN(c_fsd, MATCH_C_FSD, MASK_C_FSD) +DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW) +DECLARE_INSN(c_fsw, MATCH_C_FSW, MASK_C_FSW) +DECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI) +DECLARE_INSN(c_jal, MATCH_C_JAL, MASK_C_JAL) +DECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI) +DECLARE_INSN(c_lui, MATCH_C_LUI, MASK_C_LUI) +DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI) +DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI) +DECLARE_INSN(c_andi, MATCH_C_ANDI, MASK_C_ANDI) +DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB) +DECLARE_INSN(c_xor, MATCH_C_XOR, MASK_C_XOR) +DECLARE_INSN(c_or, MATCH_C_OR, MASK_C_OR) +DECLARE_INSN(c_and, MATCH_C_AND, MASK_C_AND) +DECLARE_INSN(c_subw, MATCH_C_SUBW, MASK_C_SUBW) +DECLARE_INSN(c_addw, MATCH_C_ADDW, MASK_C_ADDW) +DECLARE_INSN(c_j, MATCH_C_J, MASK_C_J) +DECLARE_INSN(c_beqz, MATCH_C_BEQZ, MASK_C_BEQZ) +DECLARE_INSN(c_bnez, MATCH_C_BNEZ, MASK_C_BNEZ) +DECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI) +DECLARE_INSN(c_fldsp, MATCH_C_FLDSP, MASK_C_FLDSP) +DECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP) +DECLARE_INSN(c_flwsp, MATCH_C_FLWSP, MASK_C_FLWSP) +DECLARE_INSN(c_mv, MATCH_C_MV, MASK_C_MV) +DECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD) +DECLARE_INSN(c_fsdsp, MATCH_C_FSDSP, MASK_C_FSDSP) +DECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP) +DECLARE_INSN(c_fswsp, MATCH_C_FSWSP, MASK_C_FSWSP) +DECLARE_INSN(custom0, MATCH_CUSTOM0, MASK_CUSTOM0) +DECLARE_INSN(custom0_rs1, MATCH_CUSTOM0_RS1, MASK_CUSTOM0_RS1) +DECLARE_INSN(custom0_rs1_rs2, MATCH_CUSTOM0_RS1_RS2, MASK_CUSTOM0_RS1_RS2) +DECLARE_INSN(custom0_rd, MATCH_CUSTOM0_RD, MASK_CUSTOM0_RD) +DECLARE_INSN(custom0_rd_rs1, MATCH_CUSTOM0_RD_RS1, MASK_CUSTOM0_RD_RS1) +DECLARE_INSN(custom0_rd_rs1_rs2, MATCH_CUSTOM0_RD_RS1_RS2, MASK_CUSTOM0_RD_RS1_RS2) +DECLARE_INSN(custom1, MATCH_CUSTOM1, MASK_CUSTOM1) +DECLARE_INSN(custom1_rs1, MATCH_CUSTOM1_RS1, MASK_CUSTOM1_RS1) +DECLARE_INSN(custom1_rs1_rs2, MATCH_CUSTOM1_RS1_RS2, MASK_CUSTOM1_RS1_RS2) +DECLARE_INSN(custom1_rd, MATCH_CUSTOM1_RD, MASK_CUSTOM1_RD) +DECLARE_INSN(custom1_rd_rs1, MATCH_CUSTOM1_RD_RS1, MASK_CUSTOM1_RD_RS1) +DECLARE_INSN(custom1_rd_rs1_rs2, MATCH_CUSTOM1_RD_RS1_RS2, MASK_CUSTOM1_RD_RS1_RS2) +DECLARE_INSN(custom2, MATCH_CUSTOM2, MASK_CUSTOM2) +DECLARE_INSN(custom2_rs1, MATCH_CUSTOM2_RS1, MASK_CUSTOM2_RS1) +DECLARE_INSN(custom2_rs1_rs2, MATCH_CUSTOM2_RS1_RS2, MASK_CUSTOM2_RS1_RS2) +DECLARE_INSN(custom2_rd, MATCH_CUSTOM2_RD, MASK_CUSTOM2_RD) +DECLARE_INSN(custom2_rd_rs1, MATCH_CUSTOM2_RD_RS1, MASK_CUSTOM2_RD_RS1) +DECLARE_INSN(custom2_rd_rs1_rs2, MATCH_CUSTOM2_RD_RS1_RS2, MASK_CUSTOM2_RD_RS1_RS2) +DECLARE_INSN(custom3, MATCH_CUSTOM3, MASK_CUSTOM3) +DECLARE_INSN(custom3_rs1, MATCH_CUSTOM3_RS1, MASK_CUSTOM3_RS1) +DECLARE_INSN(custom3_rs1_rs2, MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2) +DECLARE_INSN(custom3_rd, MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD) +DECLARE_INSN(custom3_rd_rs1, MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1) +DECLARE_INSN(custom3_rd_rs1_rs2, MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2) +#endif +#if defined(DECLARE_CSR) +DECLARE_CSR(fflags, CSR_FFLAGS) +DECLARE_CSR(frm, CSR_FRM) +DECLARE_CSR(fcsr, CSR_FCSR) +DECLARE_CSR(cycle, CSR_CYCLE) +DECLARE_CSR(time, CSR_TIME) +DECLARE_CSR(instret, CSR_INSTRET) +DECLARE_CSR(hpmcounter3, CSR_HPMCOUNTER3) +DECLARE_CSR(hpmcounter4, CSR_HPMCOUNTER4) +DECLARE_CSR(hpmcounter5, CSR_HPMCOUNTER5) +DECLARE_CSR(hpmcounter6, CSR_HPMCOUNTER6) +DECLARE_CSR(hpmcounter7, CSR_HPMCOUNTER7) +DECLARE_CSR(hpmcounter8, CSR_HPMCOUNTER8) +DECLARE_CSR(hpmcounter9, CSR_HPMCOUNTER9) +DECLARE_CSR(hpmcounter10, CSR_HPMCOUNTER10) +DECLARE_CSR(hpmcounter11, CSR_HPMCOUNTER11) +DECLARE_CSR(hpmcounter12, CSR_HPMCOUNTER12) +DECLARE_CSR(hpmcounter13, CSR_HPMCOUNTER13) +DECLARE_CSR(hpmcounter14, CSR_HPMCOUNTER14) +DECLARE_CSR(hpmcounter15, CSR_HPMCOUNTER15) +DECLARE_CSR(hpmcounter16, CSR_HPMCOUNTER16) +DECLARE_CSR(hpmcounter17, CSR_HPMCOUNTER17) +DECLARE_CSR(hpmcounter18, CSR_HPMCOUNTER18) +DECLARE_CSR(hpmcounter19, CSR_HPMCOUNTER19) +DECLARE_CSR(hpmcounter20, CSR_HPMCOUNTER20) +DECLARE_CSR(hpmcounter21, CSR_HPMCOUNTER21) +DECLARE_CSR(hpmcounter22, CSR_HPMCOUNTER22) +DECLARE_CSR(hpmcounter23, CSR_HPMCOUNTER23) +DECLARE_CSR(hpmcounter24, CSR_HPMCOUNTER24) +DECLARE_CSR(hpmcounter25, CSR_HPMCOUNTER25) +DECLARE_CSR(hpmcounter26, CSR_HPMCOUNTER26) +DECLARE_CSR(hpmcounter27, CSR_HPMCOUNTER27) +DECLARE_CSR(hpmcounter28, CSR_HPMCOUNTER28) +DECLARE_CSR(hpmcounter29, CSR_HPMCOUNTER29) +DECLARE_CSR(hpmcounter30, CSR_HPMCOUNTER30) +DECLARE_CSR(hpmcounter31, CSR_HPMCOUNTER31) +DECLARE_CSR(sstatus, CSR_SSTATUS) +DECLARE_CSR(sie, CSR_SIE) +DECLARE_CSR(stvec, CSR_STVEC) +DECLARE_CSR(sscratch, CSR_SSCRATCH) +DECLARE_CSR(sepc, CSR_SEPC) +DECLARE_CSR(scause, CSR_SCAUSE) +DECLARE_CSR(sbadaddr, CSR_SBADADDR) +DECLARE_CSR(sip, CSR_SIP) +DECLARE_CSR(sptbr, CSR_SPTBR) +DECLARE_CSR(mstatus, CSR_MSTATUS) +DECLARE_CSR(misa, CSR_MISA) +DECLARE_CSR(medeleg, CSR_MEDELEG) +DECLARE_CSR(mideleg, CSR_MIDELEG) +DECLARE_CSR(mie, CSR_MIE) +DECLARE_CSR(mtvec, CSR_MTVEC) +DECLARE_CSR(mscratch, CSR_MSCRATCH) +DECLARE_CSR(mepc, CSR_MEPC) +DECLARE_CSR(mcause, CSR_MCAUSE) +DECLARE_CSR(mbadaddr, CSR_MBADADDR) +DECLARE_CSR(mip, CSR_MIP) +DECLARE_CSR(tselect, CSR_TSELECT) +DECLARE_CSR(tdata1, CSR_TDATA1) +DECLARE_CSR(tdata2, CSR_TDATA2) +DECLARE_CSR(tdata3, CSR_TDATA3) +DECLARE_CSR(dcsr, CSR_DCSR) +DECLARE_CSR(dpc, CSR_DPC) +DECLARE_CSR(dscratch, CSR_DSCRATCH) +DECLARE_CSR(mcycle, CSR_MCYCLE) +DECLARE_CSR(minstret, CSR_MINSTRET) +DECLARE_CSR(mhpmcounter3, CSR_MHPMCOUNTER3) +DECLARE_CSR(mhpmcounter4, CSR_MHPMCOUNTER4) +DECLARE_CSR(mhpmcounter5, CSR_MHPMCOUNTER5) +DECLARE_CSR(mhpmcounter6, CSR_MHPMCOUNTER6) +DECLARE_CSR(mhpmcounter7, CSR_MHPMCOUNTER7) +DECLARE_CSR(mhpmcounter8, CSR_MHPMCOUNTER8) +DECLARE_CSR(mhpmcounter9, CSR_MHPMCOUNTER9) +DECLARE_CSR(mhpmcounter10, CSR_MHPMCOUNTER10) +DECLARE_CSR(mhpmcounter11, CSR_MHPMCOUNTER11) +DECLARE_CSR(mhpmcounter12, CSR_MHPMCOUNTER12) +DECLARE_CSR(mhpmcounter13, CSR_MHPMCOUNTER13) +DECLARE_CSR(mhpmcounter14, CSR_MHPMCOUNTER14) +DECLARE_CSR(mhpmcounter15, CSR_MHPMCOUNTER15) +DECLARE_CSR(mhpmcounter16, CSR_MHPMCOUNTER16) +DECLARE_CSR(mhpmcounter17, CSR_MHPMCOUNTER17) +DECLARE_CSR(mhpmcounter18, CSR_MHPMCOUNTER18) +DECLARE_CSR(mhpmcounter19, CSR_MHPMCOUNTER19) +DECLARE_CSR(mhpmcounter20, CSR_MHPMCOUNTER20) +DECLARE_CSR(mhpmcounter21, CSR_MHPMCOUNTER21) +DECLARE_CSR(mhpmcounter22, CSR_MHPMCOUNTER22) +DECLARE_CSR(mhpmcounter23, CSR_MHPMCOUNTER23) +DECLARE_CSR(mhpmcounter24, CSR_MHPMCOUNTER24) +DECLARE_CSR(mhpmcounter25, CSR_MHPMCOUNTER25) +DECLARE_CSR(mhpmcounter26, CSR_MHPMCOUNTER26) +DECLARE_CSR(mhpmcounter27, CSR_MHPMCOUNTER27) +DECLARE_CSR(mhpmcounter28, CSR_MHPMCOUNTER28) +DECLARE_CSR(mhpmcounter29, CSR_MHPMCOUNTER29) +DECLARE_CSR(mhpmcounter30, CSR_MHPMCOUNTER30) +DECLARE_CSR(mhpmcounter31, CSR_MHPMCOUNTER31) +DECLARE_CSR(mucounteren, CSR_MUCOUNTEREN) +DECLARE_CSR(mscounteren, CSR_MSCOUNTEREN) +DECLARE_CSR(mhpmevent3, CSR_MHPMEVENT3) +DECLARE_CSR(mhpmevent4, CSR_MHPMEVENT4) +DECLARE_CSR(mhpmevent5, CSR_MHPMEVENT5) +DECLARE_CSR(mhpmevent6, CSR_MHPMEVENT6) +DECLARE_CSR(mhpmevent7, CSR_MHPMEVENT7) +DECLARE_CSR(mhpmevent8, CSR_MHPMEVENT8) +DECLARE_CSR(mhpmevent9, CSR_MHPMEVENT9) +DECLARE_CSR(mhpmevent10, CSR_MHPMEVENT10) +DECLARE_CSR(mhpmevent11, CSR_MHPMEVENT11) +DECLARE_CSR(mhpmevent12, CSR_MHPMEVENT12) +DECLARE_CSR(mhpmevent13, CSR_MHPMEVENT13) +DECLARE_CSR(mhpmevent14, CSR_MHPMEVENT14) +DECLARE_CSR(mhpmevent15, CSR_MHPMEVENT15) +DECLARE_CSR(mhpmevent16, CSR_MHPMEVENT16) +DECLARE_CSR(mhpmevent17, CSR_MHPMEVENT17) +DECLARE_CSR(mhpmevent18, CSR_MHPMEVENT18) +DECLARE_CSR(mhpmevent19, CSR_MHPMEVENT19) +DECLARE_CSR(mhpmevent20, CSR_MHPMEVENT20) +DECLARE_CSR(mhpmevent21, CSR_MHPMEVENT21) +DECLARE_CSR(mhpmevent22, CSR_MHPMEVENT22) +DECLARE_CSR(mhpmevent23, CSR_MHPMEVENT23) +DECLARE_CSR(mhpmevent24, CSR_MHPMEVENT24) +DECLARE_CSR(mhpmevent25, CSR_MHPMEVENT25) +DECLARE_CSR(mhpmevent26, CSR_MHPMEVENT26) +DECLARE_CSR(mhpmevent27, CSR_MHPMEVENT27) +DECLARE_CSR(mhpmevent28, CSR_MHPMEVENT28) +DECLARE_CSR(mhpmevent29, CSR_MHPMEVENT29) +DECLARE_CSR(mhpmevent30, CSR_MHPMEVENT30) +DECLARE_CSR(mhpmevent31, CSR_MHPMEVENT31) +DECLARE_CSR(mvendorid, CSR_MVENDORID) +DECLARE_CSR(marchid, CSR_MARCHID) +DECLARE_CSR(mimpid, CSR_MIMPID) +DECLARE_CSR(mhartid, CSR_MHARTID) +DECLARE_CSR(cycleh, CSR_CYCLEH) +DECLARE_CSR(timeh, CSR_TIMEH) +DECLARE_CSR(instreth, CSR_INSTRETH) +DECLARE_CSR(hpmcounter3h, CSR_HPMCOUNTER3H) +DECLARE_CSR(hpmcounter4h, CSR_HPMCOUNTER4H) +DECLARE_CSR(hpmcounter5h, CSR_HPMCOUNTER5H) +DECLARE_CSR(hpmcounter6h, CSR_HPMCOUNTER6H) +DECLARE_CSR(hpmcounter7h, CSR_HPMCOUNTER7H) +DECLARE_CSR(hpmcounter8h, CSR_HPMCOUNTER8H) +DECLARE_CSR(hpmcounter9h, CSR_HPMCOUNTER9H) +DECLARE_CSR(hpmcounter10h, CSR_HPMCOUNTER10H) +DECLARE_CSR(hpmcounter11h, CSR_HPMCOUNTER11H) +DECLARE_CSR(hpmcounter12h, CSR_HPMCOUNTER12H) +DECLARE_CSR(hpmcounter13h, CSR_HPMCOUNTER13H) +DECLARE_CSR(hpmcounter14h, CSR_HPMCOUNTER14H) +DECLARE_CSR(hpmcounter15h, CSR_HPMCOUNTER15H) +DECLARE_CSR(hpmcounter16h, CSR_HPMCOUNTER16H) +DECLARE_CSR(hpmcounter17h, CSR_HPMCOUNTER17H) +DECLARE_CSR(hpmcounter18h, CSR_HPMCOUNTER18H) +DECLARE_CSR(hpmcounter19h, CSR_HPMCOUNTER19H) +DECLARE_CSR(hpmcounter20h, CSR_HPMCOUNTER20H) +DECLARE_CSR(hpmcounter21h, CSR_HPMCOUNTER21H) +DECLARE_CSR(hpmcounter22h, CSR_HPMCOUNTER22H) +DECLARE_CSR(hpmcounter23h, CSR_HPMCOUNTER23H) +DECLARE_CSR(hpmcounter24h, CSR_HPMCOUNTER24H) +DECLARE_CSR(hpmcounter25h, CSR_HPMCOUNTER25H) +DECLARE_CSR(hpmcounter26h, CSR_HPMCOUNTER26H) +DECLARE_CSR(hpmcounter27h, CSR_HPMCOUNTER27H) +DECLARE_CSR(hpmcounter28h, CSR_HPMCOUNTER28H) +DECLARE_CSR(hpmcounter29h, CSR_HPMCOUNTER29H) +DECLARE_CSR(hpmcounter30h, CSR_HPMCOUNTER30H) +DECLARE_CSR(hpmcounter31h, CSR_HPMCOUNTER31H) +DECLARE_CSR(mcycleh, CSR_MCYCLEH) +DECLARE_CSR(minstreth, CSR_MINSTRETH) +DECLARE_CSR(mhpmcounter3h, CSR_MHPMCOUNTER3H) +DECLARE_CSR(mhpmcounter4h, CSR_MHPMCOUNTER4H) +DECLARE_CSR(mhpmcounter5h, CSR_MHPMCOUNTER5H) +DECLARE_CSR(mhpmcounter6h, CSR_MHPMCOUNTER6H) +DECLARE_CSR(mhpmcounter7h, CSR_MHPMCOUNTER7H) +DECLARE_CSR(mhpmcounter8h, CSR_MHPMCOUNTER8H) +DECLARE_CSR(mhpmcounter9h, CSR_MHPMCOUNTER9H) +DECLARE_CSR(mhpmcounter10h, CSR_MHPMCOUNTER10H) +DECLARE_CSR(mhpmcounter11h, CSR_MHPMCOUNTER11H) +DECLARE_CSR(mhpmcounter12h, CSR_MHPMCOUNTER12H) +DECLARE_CSR(mhpmcounter13h, CSR_MHPMCOUNTER13H) +DECLARE_CSR(mhpmcounter14h, CSR_MHPMCOUNTER14H) +DECLARE_CSR(mhpmcounter15h, CSR_MHPMCOUNTER15H) +DECLARE_CSR(mhpmcounter16h, CSR_MHPMCOUNTER16H) +DECLARE_CSR(mhpmcounter17h, CSR_MHPMCOUNTER17H) +DECLARE_CSR(mhpmcounter18h, CSR_MHPMCOUNTER18H) +DECLARE_CSR(mhpmcounter19h, CSR_MHPMCOUNTER19H) +DECLARE_CSR(mhpmcounter20h, CSR_MHPMCOUNTER20H) +DECLARE_CSR(mhpmcounter21h, CSR_MHPMCOUNTER21H) +DECLARE_CSR(mhpmcounter22h, CSR_MHPMCOUNTER22H) +DECLARE_CSR(mhpmcounter23h, CSR_MHPMCOUNTER23H) +DECLARE_CSR(mhpmcounter24h, CSR_MHPMCOUNTER24H) +DECLARE_CSR(mhpmcounter25h, CSR_MHPMCOUNTER25H) +DECLARE_CSR(mhpmcounter26h, CSR_MHPMCOUNTER26H) +DECLARE_CSR(mhpmcounter27h, CSR_MHPMCOUNTER27H) +DECLARE_CSR(mhpmcounter28h, CSR_MHPMCOUNTER28H) +DECLARE_CSR(mhpmcounter29h, CSR_MHPMCOUNTER29H) +DECLARE_CSR(mhpmcounter30h, CSR_MHPMCOUNTER30H) +DECLARE_CSR(mhpmcounter31h, CSR_MHPMCOUNTER31H) +#endif +#if defined(DECLARE_CAUSE) +DECLARE_CAUSE("misaligned fetch", CAUSE_MISALIGNED_FETCH) +DECLARE_CAUSE("fault fetch", CAUSE_FAULT_FETCH) +DECLARE_CAUSE("illegal instruction", CAUSE_ILLEGAL_INSTRUCTION) +DECLARE_CAUSE("breakpoint", CAUSE_BREAKPOINT) +DECLARE_CAUSE("misaligned load", CAUSE_MISALIGNED_LOAD) +DECLARE_CAUSE("fault load", CAUSE_FAULT_LOAD) +DECLARE_CAUSE("misaligned store", CAUSE_MISALIGNED_STORE) +DECLARE_CAUSE("fault store", CAUSE_FAULT_STORE) +DECLARE_CAUSE("user_ecall", CAUSE_USER_ECALL) +DECLARE_CAUSE("supervisor_ecall", CAUSE_SUPERVISOR_ECALL) +DECLARE_CAUSE("hypervisor_ecall", CAUSE_HYPERVISOR_ECALL) +DECLARE_CAUSE("machine_ecall", CAUSE_MACHINE_ECALL) +#endif + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/entry.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/entry.h new file mode 100644 index 000000000..58f48477c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/entry.h @@ -0,0 +1,90 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file entry.h +* @brief add from Canaan K210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef _BSP_ENTRY_H +#define _BSP_ENTRY_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int (*core_function)(void *ctx); + +typedef struct _core_instance_t +{ + core_function callback; + void *ctx; +} core_instance_t; + +int register_core1(core_function func, void *ctx); + +static inline void init_lma(void) +{ + extern unsigned int _data_lma; + extern unsigned int _data; + extern unsigned int _edata; + unsigned int *src, *dst; + + src = &_data_lma; + dst = &_data; + while (dst < &_edata) + *dst++ = *src++; +} + +static inline void InitBss(void) +{ + extern unsigned int _bss; + extern unsigned int _ebss; + unsigned int *dst; + + dst = &_bss; + while (dst < &_ebss) + *dst++ = 0; +} + +static inline void init_tls(void) +{ + register void *task_pointer asm("tp"); + extern char _tls_data; + + extern __thread char _tdata_begin, _tdata_end, _tbss_end; + + size_t tdata_size = &_tdata_end - &_tdata_begin; + + memcpy(task_pointer, &_tls_data, tdata_size); + + size_t tbss_size = &_tbss_end - &_tdata_end; + + memset(task_pointer + tdata_size, 0, tbss_size); +} + +#ifdef __cplusplus +} +#endif + +#endif /* _BSP_ENTRY_H */ + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/interrupt.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/interrupt.h new file mode 100644 index 000000000..847b5fde3 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/interrupt.h @@ -0,0 +1,56 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file interrupt.h +* @brief add from Canaan K210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef _BSP_INTERRUPT_H +#define _BSP_INTERRUPT_H + +#ifdef __cplusplus +extern "C" { +#endif +/* clang-format off */ +/* Machine interrupt mask for 64 bit system, 0x8000 0000 0000 0000 */ +#define CAUSE_MACHINE_IRQ_MASK (0x1ULL << 63) + +/* Machine interrupt reason mask for 64 bit system, 0x7FFF FFFF FFFF FFFF */ +#define CAUSE_MACHINE_IRQ_REASON_MASK (CAUSE_MACHINE_IRQ_MASK - 1) + +/* Hypervisor interrupt mask for 64 bit system, 0x8000 0000 0000 0000 */ +#define CAUSE_HYPERVISOR_IRQ_MASK (0x1ULL << 63) + +/* Hypervisor interrupt reason mask for 64 bit system, 0x7FFF FFFF FFFF FFFF */ +#define CAUSE_HYPERVISOR_IRQ_REASON_MASK (CAUSE_HYPERVISOR_IRQ_MASK - 1) + +/* Supervisor interrupt mask for 64 bit system, 0x8000 0000 0000 0000 */ +#define CAUSE_SUPERVISOR_IRQ_MASK (0x1ULL << 63) + +/* Supervisor interrupt reason mask for 64 bit system, 0x7FFF FFFF FFFF FFFF */ +#define CAUSE_SUPERVISOR_IRQ_REASON_MASK (CAUSE_SUPERVISOR_IRQ_MASK - 1) +/* clang-format on */ + +#ifdef __cplusplus +} +#endif + +#endif /* _BSP_INTERRUPT_H */ + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/platform.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/platform.h new file mode 100644 index 000000000..c30e41771 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/platform.h @@ -0,0 +1,108 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file platform.h +* @brief add from Canaan K210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef _BSP_PLATFORM_H +#define _BSP_PLATFORM_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* clang-format off */ +/* Register base address */ + +/* Under Coreplex */ +#define CLINT_BASE_ADDR (0x02000000U) +#define PLIC_BASE_ADDR (0x0C000000U) + +/* Under TileLink */ +#define UARTHS_BASE_ADDR (0x38000000U) +#define GPIOHS_BASE_ADDR (0x38001000U) + +/* Under AXI 64 bit */ +#define RAM_BASE_ADDR (0x80000000U) +#define RAM_SIZE (6 * 1024 * 1024U) + +#define IO_BASE_ADDR (0x40000000U) +#define IO_SIZE (6 * 1024 * 1024U) + +#define AI_RAM_BASE_ADDR (0x80600000U) +#define AI_RAM_SIZE (2 * 1024 * 1024U) + +#define AI_IO_BASE_ADDR (0x40600000U) +#define AI_IO_SIZE (2 * 1024 * 1024U) + +#define AI_BASE_ADDR (0x40800000U) +#define AI_SIZE (12 * 1024 * 1024U) + +#define FFT_BASE_ADDR (0x42000000U) +#define FFT_SIZE (4 * 1024 * 1024U) + +#define ROM_BASE_ADDR (0x88000000U) +#define ROM_SIZE (128 * 1024U) + +/* Under AHB 32 bit */ +#define DMAC_BASE_ADDR (0x50000000U) + +/* Under APB1 32 bit */ +#define GPIO_BASE_ADDR (0x50200000U) +#define UART1_BASE_ADDR (0x50210000U) +#define UART2_BASE_ADDR (0x50220000U) +#define UART3_BASE_ADDR (0x50230000U) +#define SPI_SLAVE_BASE_ADDR (0x50240000U) +#define I2S0_BASE_ADDR (0x50250000U) +#define I2S1_BASE_ADDR (0x50260000U) +#define I2S2_BASE_ADDR (0x50270000U) +#define I2C0_BASE_ADDR (0x50280000U) +#define I2C1_BASE_ADDR (0x50290000U) +#define I2C2_BASE_ADDR (0x502A0000U) +#define FPIOA_BASE_ADDR (0x502B0000U) +#define SHA256_BASE_ADDR (0x502C0000U) +#define TIMER0_BASE_ADDR (0x502D0000U) +#define TIMER1_BASE_ADDR (0x502E0000U) +#define TIMER2_BASE_ADDR (0x502F0000U) + +/* Under APB2 32 bit */ +#define WDT0_BASE_ADDR (0x50400000U) +#define WDT1_BASE_ADDR (0x50410000U) +#define OTP_BASE_ADDR (0x50420000U) +#define DVP_BASE_ADDR (0x50430000U) +#define SYSCTL_BASE_ADDR (0x50440000U) +#define AES_BASE_ADDR (0x50450000U) +#define RTC_BASE_ADDR (0x50460000U) + + +/* Under APB3 32 bit */ +#define SPI0_BASE_ADDR (0x52000000U) +#define SPI1_BASE_ADDR (0x53000000U) +#define SPI3_BASE_ADDR (0x54000000U) + +/* clang-format on */ + +#ifdef __cplusplus +} +#endif + +#endif /* _BSP_PLATFORM_H */ + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/printf.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/printf.h new file mode 100644 index 000000000..c41b3e4e7 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/printf.h @@ -0,0 +1,218 @@ +/** + * File: printf.h + * + * Copyright (c) 2004,2012 Kustaa Nyholm / SpareTimeLabs + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Kustaa Nyholm or SpareTimeLabs nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * This library is really just two files: 'tinyprintf.h' and 'tinyprintf.c'. + * + * They provide a simple and small (+400 loc) printf functionality to be used + * in embedded systems. + * + * I've found them so useful in debugging that I do not bother with a debugger + * at all. + * + * They are distributed in source form, so to use them, just compile them into + * your project. + * + * Two printf variants are provided: printf and the 'sprintf' family of + * functions ('snprintf', 'sprintf', 'vsnprintf', 'vsprintf'). + * + * The formats supported by this implementation are: 'c' 'd' 'i' 'o' 'p' 'u' + * 's' 'x' 'X'. + * + * Zero padding, field width, and precision are also supported. + * + * If the library is compiled with 'PRINTF_SUPPORT_LONG' defined, then the + * long specifier is also supported. Note that this will pull in some long + * math routines (pun intended!) and thus make your executable noticeably + * longer. Likewise with 'PRINTF_LONG_LONG_SUPPORT' for the long long + * specifier, and with 'PRINTF_SIZE_T_SUPPORT' for the size_t specifier. + * + * The memory footprint of course depends on the target CPU, compiler and + * compiler options, but a rough guesstimate (based on a H8S target) is about + * 1.4 kB for code and some twenty 'int's and 'char's, say 60 bytes of stack + * space. Not too bad. Your mileage may vary. By hacking the source code you + * can get rid of some hundred bytes, I'm sure, but personally I feel the + * balance of functionality and flexibility versus code size is close to + * optimal for many embedded systems. + * + * To use the printf, you need to supply your own character output function, + * something like : + * + * void putc ( void* p, char c) { while (!SERIAL_PORT_EMPTY) ; + * SERIAL_PORT_TX_REGISTER = c; } + * + * Before you can call printf, you need to initialize it to use your character + * output function with something like: + * + * init_printf(NULL,putc); + * + * Notice the 'NULL' in 'init_printf' and the parameter 'void* p' in 'putc', + * the NULL (or any pointer) you pass into the 'init_printf' will eventually + * be passed to your 'putc' routine. This allows you to pass some storage + * space (or anything really) to the character output function, if necessary. + * This is not often needed but it was implemented like that because it made + * implementing the sprintf function so neat (look at the source code). + * + * The code is re-entrant, except for the 'init_printf' function, so it is + * safe to call it from interrupts too, although this may result in mixed + * output. If you rely on re-entrancy, take care that your 'putc' function is + * re-entrant! + * + * The printf and sprintf functions are actually macros that translate to + * 'tfp_printf' and 'tfp_sprintf' when 'TINYPRINTF_OVERRIDE_LIBC' is set + * (default). Setting it to 0 makes it possible to use them along with + * 'stdio.h' printf's in a single source file. When 'TINYPRINTF_OVERRIDE_LIBC' + * is set, please note that printf/sprintf are not function-like macros, so if + * you have variables or struct members with these names, things will explode + * in your face. Without variadic macros this is the best we can do to wrap + * these function. If it is a problem, just give up the macros and use the + * functions directly, or rename them. + * + * It is also possible to avoid defining tfp_printf and/or tfp_sprintf by + * clearing 'TINYPRINTF_DEFINE_TFP_PRINTF' and/or + * 'TINYPRINTF_DEFINE_TFP_SPRINTF' to 0. This allows for example to export + * only tfp_format, which is at the core of all the other functions. + * + * For further details see source code. + * + * regs Kusti, 23.10.2004 + */ + +/** +* @file printf.h +* @brief add from Canaan K210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef _BSP_PRINTF_H +#define _BSP_PRINTF_H + +#include +#include + +/* Global configuration */ + +/* Set this to 0 if you do not want to provide tfp_printf */ +#ifndef TINYPRINTF_DEFINE_TFP_PRINTF +#define TINYPRINTF_DEFINE_TFP_PRINTF 1 +#endif + +/** + * Set this to 0 if you do not want to provide + * tfp_sprintf/snprintf/vsprintf/vsnprintf + */ +#ifndef TINYPRINTF_DEFINE_TFP_SPRINTF +#define TINYPRINTF_DEFINE_TFP_SPRINTF 1 +#endif + +/** + * Set this to 0 if you do not want tfp_printf and + * tfp_{vsn,sn,vs,s}printf to be also available as + * printf/{vsn,sn,vs,s}printf + */ +#ifndef TINYPRINTF_OVERRIDE_LIBC +#define TINYPRINTF_OVERRIDE_LIBC 0 +#endif + +/* Optional external types dependencies */ + +/* Declarations */ + +#if defined(__GNUC__) +#define _TFP_SPECIFY_PRINTF_FMT(fmt_idx, arg1_idx) \ + __attribute__((format(printf, fmt_idx, arg1_idx))) +#else +#define _TFP_SPECIFY_PRINTF_FMT(fmt_idx, arg1_idx) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*putcf)(void*, char); + +/** + * 'tfp_format' really is the central function for all tinyprintf. For + * each output character after formatting, the 'putf' callback is + * called with 2 args: + * - an arbitrary void* 'putp' param defined by the user and + * passed unmodified from 'tfp_format', + * - the character. + * The 'tfp_printf' and 'tfp_sprintf' functions simply define their own + * callback and pass to it the right 'putp' it is expecting. + */ +void tfp_format(void *putp, putcf putf, const char *fmt, va_list va); + +#if TINYPRINTF_DEFINE_TFP_SPRINTF +int tfp_vsnprintf(char *str, size_t size, const char *fmt, va_list ap); +int tfp_snprintf(char *str, size_t size, const char *fmt, ...) + _TFP_SPECIFY_PRINTF_FMT(3, 4); +int tfp_vsprintf(char *str, const char *fmt, va_list ap); +int tfp_sprintf(char *str, const char *fmt, ...) _TFP_SPECIFY_PRINTF_FMT(2, 3); +#if TINYPRINTF_OVERRIDE_LIBC +#define vsnprintf tfp_vsnprintf +#define snprintf tfp_snprintf +#define vsprintf tfp_vsprintf +#define sprintf tfp_sprintf +#endif +#endif + +#if TINYPRINTF_DEFINE_TFP_PRINTF +void init_printf(void *putp, putcf putf); +void tfp_printf(char *fmt, ...) _TFP_SPECIFY_PRINTF_FMT(1, 2); +#if TINYPRINTF_OVERRIDE_LIBC +#define printf tfp_printf + +#ifdef __cplusplus +#include +namespace std +{ + template + auto tfp_printf(Args&&... args) -> decltype(::tfp_printf(std::forward(args)...)) + { + return ::tfp_printf(std::forward(args)...); + } +} +#endif +#endif +#endif + +int printk(const char *format, ...) _TFP_SPECIFY_PRINTF_FMT(1, 2); + +#ifdef __cplusplus +} +#endif + +#endif /* _BSP_PRINTF_H */ + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/sleep.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/sleep.h new file mode 100644 index 000000000..a9da6630a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/sleep.h @@ -0,0 +1,45 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file sleep.h +* @brief add from Canaan K210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef _BSP_SLEEP_H +#define _BSP_SLEEP_H + +#include "encoding.h" +#include "clint.h" +#include "syscalls.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int usleep(uint64_t usec); +int msleep(uint64_t msec); +unsigned int sleep(unsigned int seconds); + +#ifdef __cplusplus +} +#endif + +#endif /* _BSP_SLEEP_H */ + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/syscalls.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/syscalls.h new file mode 100644 index 000000000..1134d5154 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/syscalls.h @@ -0,0 +1,54 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file syscalls.h +* @brief add from Canaan K210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef _BSP_SYSCALLS_H +#define _BSP_SYSCALLS_H + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void __attribute__((noreturn)) sys_exit(int code); + +void setStats(int enable); + +#undef putchar +int putchar(int ch); +void printstr(const char *s); + +void printhex(uint64_t x); + + +#ifdef __cplusplus +} +#endif + +#endif /* _BSP_SYSCALLS_H */ + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/syslog.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/syslog.h new file mode 100644 index 000000000..00d25ddf1 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/syslog.h @@ -0,0 +1,151 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file syslog.h +* @brief add from Canaan K210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef _SYSLOG_H +#define _SYSLOG_H + +#include +#include +#include "printf.h" +#include "encoding.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Logging library + * + * Log library has two ways of managing log verbosity: compile time, set via + * menuconfig + * + * At compile time, filtering is done using CONFIG_LOG_DEFAULT_LEVEL macro, set via + * menuconfig. All logging statments for levels higher than CONFIG_LOG_DEFAULT_LEVEL + * will be removed by the preprocessor. + * + * + * How to use this library: + * + * In each C file which uses logging functionality, define TAG variable like this: + * + * static const char *TAG = "MODULE_NAME"; + * + * then use one of logging macros to produce output, e.g: + * + * LOGW(TAG, "Interrupt error %d", error); + * + * Several macros are available for different verbosity levels: + * + * LOGE - error + * LOGW - warning + * LOGI - info + * LOGD - debug + * LOGV - verbose + * + * To override default verbosity level at file or component scope, define LOG_LEVEL macro. + * At file scope, define it before including esp_log.h, e.g.: + * + * #define LOG_LEVEL LOG_VERBOSE + * #include "dxx_log.h" + * + * At component scope, define it in component makefile: + * + * CFLAGS += -D LOG_LEVEL=LOG_DEBUG + * + * + */ + +/* clang-format off */ +typedef enum _kendryte_log_level +{ + LOG_NONE, /*!< No log output */ + LOG_ERROR, /*!< Critical errors, software module can not recover on its own */ + LOG_WARN, /*!< Error conditions from which recovery measures have been taken */ + LOG_INFO, /*!< Information messages which describe normal flow of events */ + LOG_DEBUG, /*!< Extra information which is not necessary for normal use (values, pointers, sizes, etc). */ + LOG_VERBOSE /*!< Bigger chunks of debugging information, or frequent messages which can potentially flood the output. */ +} kendryte_log_level_t ; +/* clang-format on */ + +/* clang-format off */ +#if CONFIG_LOG_COLORS +#define LOG_COLOR_BLACK "30" +#define LOG_COLOR_RED "31" +#define LOG_COLOR_GREEN "32" +#define LOG_COLOR_BROWN "33" +#define LOG_COLOR_BLUE "34" +#define LOG_COLOR_PURPLE "35" +#define LOG_COLOR_CYAN "36" +#define LOG_COLOR(COLOR) "\033[0;" COLOR "m" +#define LOG_BOLD(COLOR) "\033[1;" COLOR "m" +#define LOG_RESET_COLOR "\033[0m" +#define LOG_COLOR_E LOG_COLOR(LOG_COLOR_RED) +#define LOG_COLOR_W LOG_COLOR(LOG_COLOR_BROWN) +#define LOG_COLOR_I LOG_COLOR(LOG_COLOR_GREEN) +#define LOG_COLOR_D +#define LOG_COLOR_V +#else /* CONFIG_LOG_COLORS */ +#define LOG_COLOR_E +#define LOG_COLOR_W +#define LOG_COLOR_I +#define LOG_COLOR_D +#define LOG_COLOR_V +#define LOG_RESET_COLOR +#endif /* CONFIG_LOG_COLORS */ +/* clang-format on */ + +#define LOG_FORMAT(letter, format) LOG_COLOR_ ## letter #letter " (%lu) %s: " format LOG_RESET_COLOR "\n" + +#ifdef LOG_LEVEL +#undef CONFIG_LOG_LEVEL +#define CONFIG_LOG_LEVEL LOG_LEVEL +#endif + +#ifdef LOG_KERNEL +#define LOG_PRINTF printk +#else +#define LOG_PRINTF printf +#endif + +#ifdef CONFIG_LOG_ENABLE +#define LOGE(tag, format, ...) do {if (CONFIG_LOG_LEVEL >= LOG_ERROR) LOG_PRINTF(LOG_FORMAT(E, format), read_cycle(), tag, ##__VA_ARGS__); } while (0) +#define LOGW(tag, format, ...) do {if (CONFIG_LOG_LEVEL >= LOG_WARN) LOG_PRINTF(LOG_FORMAT(W, format), read_cycle(), tag, ##__VA_ARGS__); } while (0) +#define LOGI(tag, format, ...) do {if (CONFIG_LOG_LEVEL >= LOG_INFO) LOG_PRINTF(LOG_FORMAT(I, format), read_cycle(), tag, ##__VA_ARGS__); } while (0) +#define LOGD(tag, format, ...) do {if (CONFIG_LOG_LEVEL >= LOG_DEBUG) LOG_PRINTF(LOG_FORMAT(D, format), read_cycle(), tag, ##__VA_ARGS__); } while (0) +#define LOGV(tag, format, ...) do {if (CONFIG_LOG_LEVEL >= LOG_VERBOSE) LOG_PRINTF(LOG_FORMAT(V, format), read_cycle(), tag, ##__VA_ARGS__); } while (0) +#else +#define LOGE(tag, format, ...) +#define LOGW(tag, format, ...) +#define LOGI(tag, format, ...) +#define LOGD(tag, format, ...) +#define LOGV(tag, format, ...) +#endif /* LOG_ENABLE */ + +#ifdef __cplusplus +} +#endif + + +#endif /* _SYSLOG_H */ + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/util.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/util.h new file mode 100644 index 000000000..fb766b279 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/include/util.h @@ -0,0 +1,207 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file util.h +* @brief add from Canaan K210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef _BSP_UTIL_H +#define _BSP_UTIL_H + + +#include +#if defined(__riscv) +#include "encoding.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wunused-parameter" +#pragma GCC diagnostic ignored "-Wunused-function" +#endif + +/** + * -------------------------------------------------------------------------- + * Macros + + * Set HOST_DEBUG to 1 if you are going to compile this for a host + * machine (ie Athena/Linux) for debug purposes and set HOST_DEBUG + * to 0 if you are compiling with the smips-gcc toolchain. + */ + +#ifndef HOST_DEBUG +#define HOST_DEBUG 0 +#endif + +/** + * Set PREALLOCATE to 1 if you want to preallocate the benchmark + * function before starting stats. If you have instruction/data + * caches and you don't want to count the overhead of misses, then + * you will need to use preallocation. +*/ + +#ifndef PREALLOCATE +#define PREALLOCATE 0 +#endif + + +#define static_assert(cond) \ + { \ + switch (0) \ + { \ + case 0: \ + case !!(long)(cond):; \ + } \ + } + +#define stringify_1(s) #s +#define stringify(s) stringify_1(s) +#define stats(code, iter) \ + do \ + { \ + unsigned long _c = -read_cycle(), _i = -READ_CSR(minstret); \ + code; \ + _c += read_cycle(), _i += READ_CSR(minstret); \ + if (cid == 0) \ + printf("\r\n%s: %ld cycles, %ld.%ld cycles/iter, %ld.%ld CPI\r\n", \ + stringify(code), _c, _c / iter, 10 * _c / iter % 10, _c / _i, 10 * _c / _i % 10); \ + } while (0) + + +/** + * Set SET_STATS to 1 if you want to carve out the piece that actually + * does the computation. + */ + +#if HOST_DEBUG +#include +static void setStats(int enable) {} +#else +extern void setStats(int enable); +#endif + + +static void printArray(const char name[], int n, const int arr[]) +{ +#if HOST_DEBUG + int i; + + printf(" %10s :", name); + for (i = 0; i < n; i++) + printf(" %3d ", arr[i]); + printf("\r\n"); +#endif +} + +static void printDoubleArray(const char name[], int n, const double arr[]) +{ +#if HOST_DEBUG + int i; + + printf(" %10s :", name); + for (i = 0; i < n; i++) + printf(" %g ", arr[i]); + printf("\r\n"); +#endif +} + +static int verify(int n, const volatile int *test, const int *verify) +{ + int i; + /* Unrolled for faster verification */ + for (i = 0; i < n / 2 * 2; i += 2) + { + int t0 = test[i], t1 = test[i + 1]; + int v0 = verify[i], v1 = verify[i + 1]; + + if (t0 != v0) + return i + 1; + if (t1 != v1) + return i + 2; + } + if (n % 2 != 0 && test[n - 1] != verify[n - 1]) + return n; + return 0; +} + +static int verifyDouble(int n, const volatile double *test, const double *verify) +{ + int i; + /* Unrolled for faster verification */ + for (i = 0; i < n / 2 * 2; i += 2) + { + double t0 = test[i], t1 = test[i + 1]; + double v0 = verify[i], v1 = verify[i + 1]; + int eq1 = t0 == v0, eq2 = t1 == v1; + + if (!(eq1 & eq2)) + return i + 1 + eq1; + } + if (n % 2 != 0 && test[n - 1] != verify[n - 1]) + return n; + return 0; +} + +static void __attribute__((noinline)) barrier(int ncores) +{ + static volatile int sense = 0; + static volatile int count = 0; + + static __thread int threadsense; + + __sync_synchronize(); + + threadsense = !threadsense; + if (__sync_fetch_and_add(&count, 1) == ncores - 1) + { + count = 0; + sense = threadsense; + } + else + { + while (sense != threadsense) + ; + } + + __sync_synchronize(); +} + +static uint64_t lfsr(uint64_t x) +{ + uint64_t bit = (x ^ (x >> 1)) & 1; + + return (x >> 1) | (bit << 62); +} + + +#if defined(__GNUC__) +#pragma GCC diagnostic warning "-Wunused-parameter" +#pragma GCC diagnostic warning "-Wunused-function" +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _BSP_UTIL_H */ + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/link.lds b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/link.lds new file mode 100644 index 000000000..79bc98ce6 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/link.lds @@ -0,0 +1,115 @@ +/* +* 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. +*/ + +__STACKSIZE__ = 4096; +OUTPUT_ARCH( "riscv" ) +MEMORY +{ + sram (wxa!ri): ORIGIN = 0x80000000, LENGTH = ( 6 * 1024 * 1024 ) +} + +ENTRY(_begin) +SECTIONS +{ + .start : + { + *(.start); + } > sram + + . = ALIGN(8); + + .text : + { + PROVIDE( _text = ABSOLUTE(.) ); + + *(.text .text.*) /* Normal code */ + *(.rodata .rodata*) /* read-only data (constants) */ + + /* section information for shell */ + . = ALIGN(8); + _shell_command_start = .; + KEEP (*(shellCommand)) + _shell_command_end = .; + . = ALIGN(8); + + PROVIDE(__ctors_start__ = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE(__ctors_end__ = .); + + . = ALIGN(4); + + __isrtbl_idx_start = .; + KEEP(*(.isrtbl.idx)) + __isrtbl_start = .; + KEEP(*(.isrtbl)) + __isrtbl_end = .; + . = ALIGN(8); + + PROVIDE(g_service_table_start = ABSOLUTE(.)); + KEEP(*(.g_service_table)) + PROVIDE(g_service_table_end = ABSOLUTE(.)); + + PROVIDE( _etext = ABSOLUTE(.) ); + } > sram + + . = ALIGN(8); + + .data : + { + PROVIDE( _sdata = ABSOLUTE(.) ); + + /* Writable data segment */ + *(.data .data.*) + + . = ALIGN(8); + PROVIDE( __global_pointer$ = ABSOLUTE(.) + 0x800 ); + + /* Writable small data segment (.sdata segment) */ + *(.sdata .sdata.*) + + PROVIDE( _edata = ABSOLUTE(.) ); + } > sram + + .bss : + { + __bss_start = ABSOLUTE(.); + + /* Writable uninitialized small data segment (.sbss segment)*/ + *(.sbss .sbss.*) + *(.scommon) + + /* Uninitialized writeable data section (.bss segment)*/ + *(.bss .bss.*) + *(COMMON) + + . = ALIGN(8); + __bss_end = ABSOLUTE(.); + } > sram + + .stack : + { + . = ALIGN(64); + PROVIDE(__stack_start__ = ABSOLUTE(.)); + + /* cpu0 stack top site */ + . = . + __STACKSIZE__; + __stack_tp0 = . ; + + /* cpu1 stack top site */ + . = . + __STACKSIZE__; + __stack_tp1 = . ; + + PROVIDE( __stack_end__ = ABSOLUTE(.) ); + } > sram + _end = ABSOLUTE(.); +} diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/link_userspace.lds b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/link_userspace.lds new file mode 100644 index 000000000..2ff351308 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/link_userspace.lds @@ -0,0 +1,76 @@ +/* +* 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. +*/ + +OUTPUT_ARCH("riscv") +MEMORY +{ + usram (rw) : ORIGIN = 0x80101000, LENGTH = ( 5 * 1024 * 1024 - 4 * 1024 ) /* 5M -4k usram */ +} + +SECTIONS +{ + .userspace : + { + . = ALIGN(8); + KEEP(*(.userspace)) + } > usram + + .text : + { + _ustext = ABSOLUTE(.); + *(.text .text.*) + *(.rodata .rodata*) + *(.glue_7) + *(.glue_7t) + + PROVIDE(__ctors_start__ = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + PROVIDE(__ctors_end__ = .); + + PROVIDE(_uetext = ABSOLUTE(.)); + } > usram + + .init_section : { + _sinit = ABSOLUTE(.); + KEEP(*(.init_array .init_array.*)) + _einit = ABSOLUTE(.); + } > usram + + __uexidx_start = ABSOLUTE(.); + + .ARM.exidx : + { + PROVIDE(__uexidx_start = ABSOLUTE(.)); + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + PROVIDE(__uexidx_end = ABSOLUTE(.)); + } > usram + + _ueronly = ABSOLUTE(.); + + .data : AT(_ueronly) + { + _usdata = ABSOLUTE(.); + *(.data .data.*) + . = ALIGN(8); + _uedata = ABSOLUTE(.); + } > usram + + .bss : { + . = ALIGN(8); + _usbss = ABSOLUTE(.); + *(.bss .bss.*) + *(.sbss .sbss.*) + . = ALIGN(8); + _uebss = ABSOLUTE(.); + } > usram +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig new file mode 100755 index 000000000..46ac183a1 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig @@ -0,0 +1,122 @@ +menuconfig BSP_USING_CH376 + bool "Using CH376 device" + default n + select FS_VFS + select FS_CH376 + if BSP_USING_CH376 + source "$BSP_DIR/third_party_driver/ch376/Kconfig" + endif + +menuconfig BSP_USING_SPI + bool "Using SPI device" + default n + select RESOURCES_SPI + select BSP_USING_DMA + if BSP_USING_SPI + source "$BSP_DIR/third_party_driver/spi/Kconfig" + endif + +menuconfig BSP_USING_SOFT_SPI + bool "Using SOFT_SPI device" + default n + select BSP_USING_SPI + select MOUNT_SDCARD + select FS_VFS + if BSP_USING_SOFT_SPI + source "$BSP_DIR/third_party_driver/soft_spi/Kconfig" + endif + +menuconfig BSP_USING_LCD + bool "Using LCD device" + default n + select BSP_USING_SPI + select RESOURCES_LCD + if BSP_USING_LCD + source "$BSP_DIR/third_party_driver/lcd/Kconfig" + endif + +menuconfig BSP_USING_DMA + bool "Using DMA device" + default y + if BSP_USING_DMA + source "$BSP_DIR/third_party_driver/dma/Kconfig" + endif + +menuconfig BSP_USING_GPIO + bool "Using GPIO device" + default y + select RESOURCES_PIN + if BSP_USING_GPIO + source "$BSP_DIR/third_party_driver/gpio/Kconfig" + endif + +menuconfig BSP_USING_I2C + bool "Using I2C device" + default n + select RESOURCES_I2C + if BSP_USING_I2C + source "$BSP_DIR/third_party_driver/i2c/Kconfig" + endif + +menuconfig BSP_USING_TOUCH + bool "Using TOUCH device" + default n + select BSP_USING_I2C + select RESOURCES_TOUCH + if BSP_USING_TOUCH + source "$BSP_DIR/third_party_driver/touch/Kconfig" + endif + +menuconfig BSP_USING_PLIC + bool "Using PLIC device" + default y + if BSP_USING_PLIC + source "$BSP_DIR/third_party_driver/plic/Kconfig" + endif + +menuconfig BSP_USING_SYSCLOCK + bool "Using SYSCLOCK device" + default y + if BSP_USING_SYSCLOCK + source "$BSP_DIR/third_party_driver/sys_clock/Kconfig" + endif + +menuconfig BSP_USING_UART + bool "Using UART device" + default y + select RESOURCES_SERIAL + if BSP_USING_UART + source "$BSP_DIR/third_party_driver/uart/Kconfig" + endif + +menuconfig BSP_USING_RTC + bool "Using RTC device" + default y + select RESOURCES_RTC + if BSP_USING_RTC + source "$BSP_DIR/third_party_driver/rtc/Kconfig" + endif + +menuconfig BSP_USING_HWTIMER + bool "Using TIMER device" + default y + select RESOURCES_HWTIMER + if BSP_USING_HWTIMER + source "$BSP_DIR/third_party_driver/timer/Kconfig" + endif + +menuconfig BSP_USING_WDT + bool "Using WATCHDOG device" + default y + select RESOURCES_WDT + if BSP_USING_WDT + source "$BSP_DIR/third_party_driver/watchdog/Kconfig" + endif + +menuconfig BSP_USING_WIZCHIP + bool "Using w5500 as network device" + default n + select RESOURCES_WIZCHIP + if BSP_USING_WIZCHIP + source "$BSP_DIR/third_party_driver/ethernet/Kconfig" + endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Makefile new file mode 100644 index 000000000..6ad13cc12 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Makefile @@ -0,0 +1,63 @@ +SRC_FILES := sleep.c + +ifeq ($(CONFIG_BSP_USING_CH376),y) + SRC_DIR += ch376 +endif + +ifeq ($(CONFIG_BSP_USING_DMA),y) + SRC_DIR += dma +endif + +ifeq ($(CONFIG_BSP_USING_GPIO),y) + SRC_DIR += gpio +endif + +ifeq ($(CONFIG_BSP_USING_SPI),y) + SRC_DIR += spi +endif + +ifeq ($(CONFIG_BSP_USING_I2C),y) + SRC_DIR += i2c +endif + +ifeq ($(CONFIG_BSP_USING_TOUCH),y) + SRC_DIR += touch +endif + +ifeq ($(CONFIG_BSP_USING_PLIC),y) + SRC_DIR += plic +endif + +ifeq ($(CONFIG_BSP_USING_SYSCLOCK),y) + SRC_DIR += sys_clock +endif + +ifeq ($(CONFIG_BSP_USING_UART),y) + SRC_DIR += uart +endif + +ifeq ($(CONFIG_BSP_USING_LCD),y) + SRC_DIR += lcd +endif + +ifeq ($(CONFIG_BSP_USING_SOFT_SPI),y) + SRC_DIR += soft_spi +endif + +ifeq ($(CONFIG_BSP_USING_RTC),y) + SRC_DIR += rtc +endif + +ifeq ($(CONFIG_BSP_USING_HWTIMER),y) + SRC_DIR += timer +endif + +ifeq ($(CONFIG_BSP_USING_WDT),y) + SRC_DIR += watchdog +endif + +ifeq ($(CONFIG_BSP_USING_WIZCHIP),y) + SRC_DIR += ethernet +endif + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ch376/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ch376/Kconfig new file mode 100644 index 000000000..921b92fea --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ch376/Kconfig @@ -0,0 +1,37 @@ +menuconfig BSP_USING_SDIO +bool "Using CH376 SD card" +default n +select RESOURCES_SDIO +select MOUNT_SDCARD +if BSP_USING_SDIO +config SDIO_BUS_NAME + string "sdio bus name" + default "sdio" + +config SDIO_DRIVER_NAME + string "sdio driver name" + default "sdio_drv" + +config SDIO_DEVICE_NAME + string "sdio device name" + default "sdio_dev" +endif + +menuconfig BSP_USING_USB +bool "Using CH376 USB" +default n +select RESOURCES_USB +select MOUNT_USB +if BSP_USING_USB +config USB_BUS_NAME + string "USB bus name" + default "usb" + +config USB_DRIVER_NAME + string "USB driver name" + default "usb_drv" + +config USB_DEVICE_NAME + string "USB device name" + default "usb_dev" +endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ch376/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ch376/Makefile new file mode 100644 index 000000000..d5393d313 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ch376/Makefile @@ -0,0 +1,4 @@ +SRC_FILES := connect_ch376.c + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ch376/connect_ch376.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ch376/connect_ch376.c new file mode 100644 index 000000000..1830e116e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ch376/connect_ch376.c @@ -0,0 +1,224 @@ +/* +* 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_ch376.c +* @brief support to register ch376 pointer and function +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#include +#include + +static struct HwCh376 ch376; + +static uint32 Ch376Configure(void *drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + + uint8 temp[2]; + temp[0] = 0x57; + temp[1] = 0xab; + MdelayKTask(100); + + struct BusBlockWriteParam write_param; + write_param.pos = 0; + write_param.buffer = (void *)temp; + write_param.size = 2; + BusDevWriteData(ch376.dev, &write_param); + + write_param.pos = 0; + write_param.buffer = &configure_info->configure_cmd; + write_param.size = 1; + BusDevWriteData(ch376.dev, &write_param); + + return EOK; +} + +static int HwCh376RxInd(void *dev, x_size_t length) +{ + ch376.msg_len += length; + KSemaphoreAbandon(ch376.sem); + + return EOK; +} + +static uint32 Ch376Open(void *dev) +{ + NULL_PARAM_CHECK(dev); + + ch376.sem = KSemaphoreCreate(0); + if (ch376.sem < 0) { + KPrintf("CH376 open fail\n"); + return -ERROR; + } + + struct Bus *bus = BusFind(SERIAL_BUS_NAME_3); + struct Driver *bus_driver = BusFindDriver(bus, SERIAL_DRV_NAME_3); + ch376.dev = BusFindDevice(bus, SERIAL_3_DEVICE_NAME_0); + if (!ch376.dev) { + KPrintf("CH376 open fail\n"); + return -ERROR; + } + + struct SerialCfgParam serial_cfg; + memset(&serial_cfg, 0, sizeof(struct SerialCfgParam)); + serial_cfg.data_cfg.serial_buffer_size = 512; + struct BusConfigureInfo cfg; + cfg.configure_cmd = OPE_INT; + cfg.private_data = &serial_cfg; + + BusDrvConfigure(bus_driver, &cfg); + + bus->match(bus_driver, ch376.dev); + + struct SerialDevParam *serial_dev_param = (struct SerialDevParam *)ch376.dev->private_data; + serial_dev_param->serial_set_mode = SIGN_OPER_INT_RX; + BusDevOpen(ch376.dev); + + BusDevRecvCallback(ch376.dev, HwCh376RxInd); + + KPrintf("CH376 open done\n"); + + return EOK; +} + +static uint32 Ch376Close(void *dev) +{ + BusDevClose(ch376.dev); + KSemaphoreDelete(ch376.sem); + + return EOK; +} + +static uint32 Ch376Write(void *dev, struct BusBlockWriteParam *write_param) +{ + if (EOK == BusDevWriteData(ch376.dev, write_param)) + return EOK; + + return -ERROR; +} + +static uint32 Ch376Read(void *dev, struct BusBlockReadParam *read_param) +{ + if (KSemaphoreObtain(ch376.sem, WAITING_FOREVER) == EOK) { + while(KSemaphoreObtain(ch376.sem, TICK_PER_SECOND) != -ETIMEOUT); + read_param->size = ch376.msg_len; + BusDevReadData(ch376.dev, read_param); + ch376.msg_len = 0; + } + + return read_param->read_length; +} + +#ifdef BSP_USING_SDIO +static struct SdioDevDone sdio_done = +{ + Ch376Open, + Ch376Close, + Ch376Write, + Ch376Read, +}; +#endif + +#ifdef BSP_USING_USB +static struct UsbDevDone usb_done = +{ + Ch376Open, + Ch376Close, + Ch376Write, + Ch376Read, +}; +#endif + +int HwCh376Init(void) +{ + x_err_t ret = EOK; + +#ifdef BSP_USING_SDIO + static struct SdioBus sdio_bus; + static struct SdioDriver sdio_drv; + static struct SdioHardwareDevice sdio_dev; + + ret = SdioBusInit(&sdio_bus,SDIO_BUS_NAME ); + if (ret != EOK) { + KPrintf("Sdio bus init error %d\n", ret); + return -ERROR; + } + + sdio_drv.configure = &Ch376Configure; + ret = SdioDriverInit(&sdio_drv, SDIO_DRIVER_NAME); + if (ret != EOK) { + KPrintf("Sdio driver init error %d\n", ret); + return -ERROR; + } + + ret = SdioDriverAttachToBus( SDIO_DRIVER_NAME, SDIO_BUS_NAME); + if (ret != EOK) { + KPrintf("Sdio driver attach error %d\n", ret); + return -ERROR; + } + + sdio_dev.dev_done = &sdio_done; + ret = SdioDeviceRegister(&sdio_dev, SDIO_DEVICE_NAME); + if (ret != EOK) { + KPrintf("Sdio device register error %d\n", ret); + return -ERROR; + } + + ret = SdioDeviceAttachToBus(SDIO_DEVICE_NAME, SDIO_BUS_NAME); + if (ret != EOK) { + KPrintf("Sdio device register error %d\n", ret); + return -ERROR; + } +#endif + +#ifdef BSP_USING_USB + static struct UsbBus usb_bus; + static struct UsbDriver usb_drv; + static struct UsbHardwareDevice usb_dev; + + ret = UsbBusInit(&usb_bus, USB_BUS_NAME); + if (ret != EOK) { + KPrintf("USB bus init error %d\n", ret); + return -ERROR; + } + + usb_drv.configure = &Ch376Configure; + ret = UsbDriverInit(&usb_drv, USB_DRIVER_NAME); + if (ret != EOK) { + KPrintf("USB driver init error %d\n", ret); + return -ERROR; + } + ret = UsbDriverAttachToBus(USB_DRIVER_NAME, USB_BUS_NAME); + if (ret != EOK) { + KPrintf("USB driver attach error %d\n", ret); + return -ERROR; + } + + usb_dev.dev_done = &usb_done; + ret = USBDeviceRegister(&usb_dev, NONE, USB_DEVICE_NAME); + if (ret != EOK) { + KPrintf("USB device register error %d\n", ret); + return -ERROR; + } + ret = USBDeviceAttachToBus(USB_DEVICE_NAME, USB_BUS_NAME); + if (ret != EOK) { + KPrintf("USB device register error %d\n", ret); + return -ERROR; + } +#endif + return ret; +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dma/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dma/Kconfig new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dma/Kconfig @@ -0,0 +1 @@ + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dma/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dma/Makefile new file mode 100644 index 000000000..2929b9055 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dma/Makefile @@ -0,0 +1,6 @@ +SRC_FILES := dmac.c + + + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dma/dmac.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dma/dmac.c new file mode 100644 index 000000000..a899e44f2 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/dma/dmac.c @@ -0,0 +1,802 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"}, + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file dmac.c +* @brief add from Canaan K210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#include +#include +#include +#include "dmac.h" +#include "sysctl.h" +#include "fpioa.h" +#include "utils.h" +#include "plic.h" +#include "stdlib.h" + +volatile dmac_t *const dmac = (dmac_t *)DMAC_BASE_ADDR; + +typedef struct _dmac_context +{ + dmac_channel_number_t dmac_channel; + plic_irq_callback_t callback; + void *ctx; +} dmac_context_t; + +dmac_context_t dmac_context[6]; + +static int is_memory(uintptr_t address) +{ + enum { + mem_len = 6 * 1024 * 1024, + mem_no_cache_len = 8 * 1024 * 1024, + }; + return ((address >= 0x80000000) && (address < 0x80000000 + mem_len)) || ((address >= 0x40000000) && (address < 0x40000000 + mem_no_cache_len)) || (address == 0x50450040); +} + +uint64_t dmac_read_id(void) +{ + return dmac->id; +} + +uint64_t dmac_read_version(void) +{ + return dmac->compver; +} + +uint64_t dmac_read_channel_id(dmac_channel_number_t channel_num) +{ + return dmac->channel[channel_num].axi_id; +} + +static void dmac_enable(void) +{ + dmac_cfg_u_t dmac_cfg; + + dmac_cfg.data = readq(&dmac->cfg); + dmac_cfg.cfg.dmac_en = 1; + dmac_cfg.cfg.int_en = 1; + writeq(dmac_cfg.data, &dmac->cfg); +} + +void dmac_disable(void) +{ + dmac_cfg_u_t dmac_cfg; + + dmac_cfg.data = readq(&dmac->cfg); + dmac_cfg.cfg.dmac_en = 0; + dmac_cfg.cfg.int_en = 0; + writeq(dmac_cfg.data, &dmac->cfg); +} + +void src_transaction_complete_int_enable(dmac_channel_number_t channel_num) +{ + dmac_ch_intstatus_enable_u_t ch_intstat; + + ch_intstat.data = readq(&dmac->channel[channel_num].intstatus_en); + ch_intstat.ch_intstatus_enable.enable_src_transcomp_intstat = 1; + + writeq(ch_intstat.data, &dmac->channel[channel_num].intstatus_en); +} + +void dmac_channel_enable(dmac_channel_number_t channel_num) +{ + dmac_chen_u_t chen; + + chen.data = readq(&dmac->chen); + + switch (channel_num) { + case DMAC_CHANNEL0: + chen.dmac_chen.ch1_en = 1; + chen.dmac_chen.ch1_en_we = 1; + break; + case DMAC_CHANNEL1: + chen.dmac_chen.ch2_en = 1; + chen.dmac_chen.ch2_en_we = 1; + break; + case DMAC_CHANNEL2: + chen.dmac_chen.ch3_en = 1; + chen.dmac_chen.ch3_en_we = 1; + break; + case DMAC_CHANNEL3: + chen.dmac_chen.ch4_en = 1; + chen.dmac_chen.ch4_en_we = 1; + break; + case DMAC_CHANNEL4: + chen.dmac_chen.ch5_en = 1; + chen.dmac_chen.ch5_en_we = 1; + break; + case DMAC_CHANNEL5: + chen.dmac_chen.ch6_en = 1; + chen.dmac_chen.ch6_en_we = 1; + break; + default: + break; + } + + writeq(chen.data, &dmac->chen); +} + +void dmac_channel_disable(dmac_channel_number_t channel_num) +{ + dmac_chen_u_t chen; + + chen.data = readq(&dmac->chen); + + switch (channel_num) + { + case DMAC_CHANNEL0: + chen.dmac_chen.ch1_en = 0; + chen.dmac_chen.ch1_en_we = 1; + break; + case DMAC_CHANNEL1: + chen.dmac_chen.ch2_en = 0; + chen.dmac_chen.ch2_en_we = 1; + break; + case DMAC_CHANNEL2: + chen.dmac_chen.ch3_en = 0; + chen.dmac_chen.ch3_en_we = 1; + break; + case DMAC_CHANNEL3: + chen.dmac_chen.ch4_en = 0; + chen.dmac_chen.ch4_en_we = 1; + break; + case DMAC_CHANNEL4: + chen.dmac_chen.ch5_en = 0; + chen.dmac_chen.ch5_en_we = 1; + break; + case DMAC_CHANNEL5: + chen.dmac_chen.ch6_en = 0; + chen.dmac_chen.ch6_en_we = 1; + break; + default: + break; + } + + writeq(chen.data, &dmac->chen); +} + +int32_t dmac_check_channel_busy(dmac_channel_number_t channel_num) +{ + int32_t ret = 0; + dmac_chen_u_t chen_u; + + chen_u.data = readq(&dmac->chen); + switch (channel_num) { + case DMAC_CHANNEL0: + if (chen_u.dmac_chen.ch1_en == 1) + ret = 1; + break; + case DMAC_CHANNEL1: + if (chen_u.dmac_chen.ch2_en == 1) + ret = 1; + break; + case DMAC_CHANNEL2: + if (chen_u.dmac_chen.ch3_en == 1) + ret = 1; + break; + case DMAC_CHANNEL3: + if (chen_u.dmac_chen.ch4_en == 1) + ret = 1; + break; + case DMAC_CHANNEL4: + if (chen_u.dmac_chen.ch5_en == 1) + ret = 1; + break; + case DMAC_CHANNEL5: + if (chen_u.dmac_chen.ch6_en == 1) + ret = 1; + break; + default: + break; + } + + writeq(chen_u.data, &dmac->chen); + + return ret; +} + +int32_t dmac_set_list_master_select(dmac_channel_number_t channel_num, + dmac_src_dst_select_t sd_sel, dmac_master_number_t mst_num) +{ + int32_t ret = 0; + uint64_t tmp = 0; + dmac_ch_ctl_u_t ctl; + + ctl.data = readq(&dmac->channel[channel_num].ctl); + ret = dmac_check_channel_busy(channel_num); + if (ret == 0) { + if (sd_sel == DMAC_SRC || sd_sel == DMAC_SRC_DST) + ctl.ch_ctl.sms = mst_num; + + if (sd_sel == DMAC_DST || sd_sel == DMAC_SRC_DST) + ctl.ch_ctl.dms = mst_num; + tmp |= *(uint64_t *)&dmac->channel[channel_num].ctl; + writeq(ctl.data, &dmac->channel[channel_num].ctl); + } + + return ret; +} + +void dmac_enable_common_interrupt_status(void) +{ + dmac_commonreg_intstatus_enable_u_t intstatus; + + intstatus.data = readq(&dmac->com_intstatus_en); + intstatus.intstatus_enable.enable_slvif_dec_err_intstat = 1; + intstatus.intstatus_enable.enable_slvif_wr2ro_err_intstat = 1; + intstatus.intstatus_enable.enable_slvif_rd2wo_err_intstat = 1; + intstatus.intstatus_enable.enable_slvif_wronhold_err_intstat = 1; + intstatus.intstatus_enable.enable_slvif_undefinedreg_dec_err_intstat = 1; + + writeq(intstatus.data, &dmac->com_intstatus_en); +} + +void dmac_enable_common_interrupt_signal(void) +{ + dmac_commonreg_intsignal_enable_u_t intsignal; + + intsignal.data = readq(&dmac->com_intsignal_en); + intsignal.intsignal_enable.enable_slvif_dec_err_intsignal = 1; + intsignal.intsignal_enable.enable_slvif_wr2ro_err_intsignal = 1; + intsignal.intsignal_enable.enable_slvif_rd2wo_err_intsignal = 1; + intsignal.intsignal_enable.enable_slvif_wronhold_err_intsignal = 1; + intsignal.intsignal_enable.enable_slvif_undefinedreg_dec_err_intsignal = 1; + + writeq(intsignal.data, &dmac->com_intsignal_en); +} + +static void dmac_enable_channel_interrupt(dmac_channel_number_t channel_num) +{ + writeq(0xffffffff, &dmac->channel[channel_num].intclear); + writeq(0x2, &dmac->channel[channel_num].intstatus_en); +} + +void dmac_disable_channel_interrupt(dmac_channel_number_t channel_num) +{ + writeq(0, &dmac->channel[channel_num].intstatus_en); +} + +static void dmac_chanel_interrupt_clear(dmac_channel_number_t channel_num) +{ + writeq(0xffffffff, &dmac->channel[channel_num].intclear); +} + +int dmac_set_channel_config(dmac_channel_number_t channel_num, + dmac_channel_config_t *cfg_param) +{ + dmac_ch_ctl_u_t ctl; + dmac_ch_cfg_u_t cfg; + dmac_ch_llp_u_t ch_llp; + + if (cfg_param->ctl_sms > DMAC_MASTER2) + return -1; + if (cfg_param->ctl_dms > DMAC_MASTER2) + return -1; + if (cfg_param->ctl_src_msize > DMAC_MSIZE_256) + return -1; + if (cfg_param->ctl_drc_msize > DMAC_MSIZE_256) + return -1; + + /** + * cfg register must configure before ts_block and + * sar dar register + */ + cfg.data = readq(&dmac->channel[channel_num].cfg); + + cfg.ch_cfg.hs_sel_src = cfg_param->cfg_hs_sel_src; + cfg.ch_cfg.hs_sel_dst = cfg_param->cfg_hs_sel_dst; + cfg.ch_cfg.src_hwhs_pol = cfg_param->cfg_src_hs_pol; + cfg.ch_cfg.dst_hwhs_pol = cfg_param->cfg_dst_hs_pol; + cfg.ch_cfg.src_per = cfg_param->cfg_src_per; + cfg.ch_cfg.dst_per = cfg_param->cfg_dst_per; + cfg.ch_cfg.ch_prior = cfg_param->cfg_ch_prior; + cfg.ch_cfg.tt_fc = cfg_param->ctl_tt_fc; + + cfg.ch_cfg.src_multblk_type = cfg_param->cfg_src_multblk_type; + cfg.ch_cfg.dst_multblk_type = cfg_param->cfg_dst_multblk_type; + + writeq(cfg.data, &dmac->channel[channel_num].cfg); + + ctl.data = readq(&dmac->channel[channel_num].ctl); + ctl.ch_ctl.sms = cfg_param->ctl_sms; + ctl.ch_ctl.dms = cfg_param->ctl_dms; + /* master select */ + ctl.ch_ctl.sinc = cfg_param->ctl_sinc; + ctl.ch_ctl.dinc = cfg_param->ctl_dinc; + /* address incrememt */ + ctl.ch_ctl.src_tr_width = cfg_param->ctl_src_tr_width; + ctl.ch_ctl.dst_tr_width = cfg_param->ctl_dst_tr_width; + /* transfer width */ + ctl.ch_ctl.src_msize = cfg_param->ctl_src_msize; + ctl.ch_ctl.dst_msize = cfg_param->ctl_drc_msize; + /* Burst transaction length */ + ctl.ch_ctl.ioc_blktfr = cfg_param->ctl_ioc_blktfr; + /* interrupt on completion of block transfer */ + /* 0x1 enable BLOCK_TFR_DONE_IntStat field */ + + writeq(cfg_param->ctl_block_ts, &dmac->channel[channel_num].block_ts); + /* the number of (blcok_ts +1) data of width SRC_TR_WIDTF to be */ + /* transferred in a dma block transfer */ + + dmac->channel[channel_num].sar = cfg_param->sar; + dmac->channel[channel_num].dar = cfg_param->dar; + + ch_llp.data = readq(&dmac->channel[channel_num].llp); + ch_llp.llp.loc = cfg_param->llp_loc; + ch_llp.llp.lms = cfg_param->llp_lms; + writeq(ch_llp.data, &dmac->channel[channel_num].llp); + writeq(ctl.data, &dmac->channel[channel_num].ctl); + readq(&dmac->channel[channel_num].swhssrc); + + return 0; +} + +int dmac_set_channel_param(dmac_channel_number_t channel_num, + const void *src, void *dest, dmac_address_increment_t src_inc, dmac_address_increment_t dest_inc, + dmac_burst_trans_length_t dmac_burst_size, + dmac_transfer_width_t dmac_trans_width, + uint32_t blockSize) +{ + dmac_ch_ctl_u_t ctl; + dmac_ch_cfg_u_t cfg_u; + + int mem_type_src = is_memory((uintptr_t)src), mem_type_dest = is_memory((uintptr_t)dest); + dmac_transfer_flow_t flow_control; + if (mem_type_src == 0 && mem_type_dest == 0) + { + flow_control = DMAC_PRF2PRF_DMA; + }else if (mem_type_src == 1 && mem_type_dest == 0) + flow_control = DMAC_MEM2PRF_DMA; + else if (mem_type_src == 0 && mem_type_dest == 1) + flow_control = DMAC_PRF2MEM_DMA; + else + flow_control = DMAC_MEM2MEM_DMA; + + /** + * cfg register must configure before ts_block and + * sar dar register + */ + cfg_u.data = readq(&dmac->channel[channel_num].cfg); + + cfg_u.ch_cfg.tt_fc = flow_control; + cfg_u.ch_cfg.hs_sel_src = mem_type_src ? DMAC_HS_SOFTWARE : DMAC_HS_HARDWARE; + cfg_u.ch_cfg.hs_sel_dst = mem_type_dest ? DMAC_HS_SOFTWARE : DMAC_HS_HARDWARE; + cfg_u.ch_cfg.src_per = channel_num; + cfg_u.ch_cfg.dst_per = channel_num; + cfg_u.ch_cfg.src_multblk_type = 0; + cfg_u.ch_cfg.dst_multblk_type = 0; + + writeq(cfg_u.data, &dmac->channel[channel_num].cfg); + + dmac->channel[channel_num].sar = (uint64_t)src; + dmac->channel[channel_num].dar = (uint64_t)dest; + + ctl.data = readq(&dmac->channel[channel_num].ctl); + ctl.ch_ctl.sms = DMAC_MASTER1; + ctl.ch_ctl.dms = DMAC_MASTER2; + /* master select */ + ctl.ch_ctl.sinc = src_inc; + ctl.ch_ctl.dinc = dest_inc; + /* address incrememt */ + ctl.ch_ctl.src_tr_width = dmac_trans_width; + ctl.ch_ctl.dst_tr_width = dmac_trans_width; + /* transfer width */ + ctl.ch_ctl.src_msize = dmac_burst_size; + ctl.ch_ctl.dst_msize = dmac_burst_size; + + writeq(ctl.data, &dmac->channel[channel_num].ctl); + + writeq(blockSize - 1, &dmac->channel[channel_num].block_ts); + /*the number of (blcok_ts +1) data of width SRC_TR_WIDTF to be */ + /* transferred in a dma block transfer */ + return 0; +} + +int dmac_get_channel_config(dmac_channel_number_t channel_num, + dmac_channel_config_t *cfg_param) +{ + dmac_ch_ctl_u_t ctl; + dmac_ch_cfg_u_t cfg; + dmac_ch_llp_u_t ch_llp; + + if (cfg_param == 0) + return -1; + if (channel_num < DMAC_CHANNEL0 || + channel_num > DMAC_CHANNEL3) + return -1; + + ctl.data = readq(&dmac->channel[channel_num].ctl); + + cfg_param->ctl_sms = ctl.ch_ctl.sms; + cfg_param->ctl_dms = ctl.ch_ctl.dms; + cfg_param->ctl_sinc = ctl.ch_ctl.sinc; + cfg_param->ctl_dinc = ctl.ch_ctl.dinc; + cfg_param->ctl_src_tr_width = ctl.ch_ctl.src_tr_width; + cfg_param->ctl_dst_tr_width = ctl.ch_ctl.dst_tr_width; + cfg_param->ctl_src_msize = ctl.ch_ctl.src_msize; + cfg_param->ctl_drc_msize = ctl.ch_ctl.dst_msize; + cfg_param->ctl_ioc_blktfr = ctl.ch_ctl.ioc_blktfr; + + cfg.data = readq(&dmac->channel[channel_num].cfg); + cfg_param->cfg_hs_sel_src = cfg.ch_cfg.hs_sel_src; + cfg_param->cfg_hs_sel_dst = cfg.ch_cfg.hs_sel_dst; + cfg_param->cfg_src_hs_pol = cfg.ch_cfg.src_hwhs_pol; + cfg_param->cfg_dst_hs_pol = cfg.ch_cfg.dst_hwhs_pol; + cfg_param->cfg_src_per = cfg.ch_cfg.src_per; + cfg_param->cfg_dst_per = cfg.ch_cfg.dst_per; + cfg_param->cfg_ch_prior = cfg.ch_cfg.ch_prior; + cfg_param->cfg_src_multblk_type = cfg.ch_cfg.src_multblk_type; + cfg_param->cfg_dst_multblk_type = cfg.ch_cfg.dst_multblk_type; + + cfg_param->sar = dmac->channel[channel_num].sar; + cfg_param->dar = dmac->channel[channel_num].dar; + + ch_llp.data = readq(&dmac->channel[channel_num].llp); + cfg_param->llp_loc = ch_llp.llp.loc; + cfg_param->llp_lms = ch_llp.llp.lms; + + cfg_param->ctl_block_ts = readq(&dmac->channel[channel_num].block_ts); + + return 0; +} + +void dmac_set_address(dmac_channel_number_t channel_num, uint64_t src_addr, + uint64_t dst_addr) +{ + writeq(src_addr, &dmac->channel[channel_num].sar); + writeq(dst_addr, &dmac->channel[channel_num].dar); +} + +void dmac_set_block_ts(dmac_channel_number_t channel_num, + uint32_t BlockSize) +{ + uint32_t block_ts; + + block_ts = BlockSize & 0x3fffff; + writeq(block_ts, &dmac->channel[channel_num].block_ts); +} + +void dmac_source_control(dmac_channel_number_t channel_num, + dmac_master_number_t master_select, + dmac_address_increment_t address_mode, + dmac_transfer_width_t tr_width, + dmac_burst_trans_length_t burst_length) +{ + dmac_ch_ctl_u_t ctl_u; + + ctl_u.data = readq(&dmac->channel[channel_num].ctl); + ctl_u.ch_ctl.sms = master_select; + ctl_u.ch_ctl.sinc = address_mode; + ctl_u.ch_ctl.src_tr_width = tr_width; + ctl_u.ch_ctl.src_msize = burst_length; + + writeq(ctl_u.data, &dmac->channel[channel_num].ctl); +} + +void dmac_master_control(dmac_channel_number_t channel_num, + dmac_master_number_t master_select, + dmac_address_increment_t address_mode, + dmac_transfer_width_t tr_width, + dmac_burst_trans_length_t burst_length) +{ + dmac_ch_ctl_u_t ctl_u; + + ctl_u.data = readq(&dmac->channel[channel_num].ctl); + ctl_u.ch_ctl.dms = master_select; + ctl_u.ch_ctl.dinc = address_mode; + ctl_u.ch_ctl.dst_tr_width = tr_width; + ctl_u.ch_ctl.dst_msize = burst_length; + + writeq(ctl_u.data, &dmac->channel[channel_num].ctl); +} + +void dmac_set_source_transfer_control(dmac_channel_number_t channel_num, + dmac_multiblk_transfer_type_t transfer_type, + dmac_sw_hw_hs_select_t handshak_select) +{ + dmac_ch_cfg_u_t cfg_u; + + cfg_u.data = readq(&dmac->channel[channel_num].cfg); + cfg_u.ch_cfg.src_multblk_type = transfer_type; + cfg_u.ch_cfg.hs_sel_src = handshak_select; + + writeq(cfg_u.data, &dmac->channel[channel_num].cfg); +} + +void dmac_set_destination_transfer_control(dmac_channel_number_t channel_num, + dmac_multiblk_transfer_type_t transfer_type, + dmac_sw_hw_hs_select_t handshak_select) +{ + dmac_ch_cfg_u_t cfg_u; + + cfg_u.data = readq(&dmac->channel[channel_num].cfg); + cfg_u.ch_cfg.dst_multblk_type = transfer_type; + cfg_u.ch_cfg.hs_sel_dst = handshak_select; + + writeq(cfg_u.data, &dmac->channel[channel_num].cfg); +} + +void dmac_set_flow_control(dmac_channel_number_t channel_num, + dmac_transfer_flow_t flow_control) +{ + dmac_ch_cfg_u_t cfg_u; + + cfg_u.data = readq(&dmac->channel[channel_num].cfg); + cfg_u.ch_cfg.tt_fc = flow_control; + + writeq(cfg_u.data, &dmac->channel[channel_num].cfg); +} + +void dmac_set_linked_list_addr_point(dmac_channel_number_t channel_num, + uint64_t *addr) +{ + dmac_ch_llp_u_t llp_u; + + llp_u.data = readq(&dmac->channel[channel_num].llp); + /* Cast pointer to uint64_t */ + llp_u.llp.loc = (uint64_t)addr; + writeq(llp_u.data, &dmac->channel[channel_num].llp); +} + +void DmacInit(void) +{ + uint64_t tmp; + dmac_commonreg_intclear_u_t intclear; + dmac_cfg_u_t dmac_cfg; + dmac_reset_u_t dmac_reset; + + sysctl_clock_enable(SYSCTL_CLOCK_DMA); + + dmac_reset.data = readq(&dmac->reset); + dmac_reset.reset.rst = 1; + writeq(dmac_reset.data, &dmac->reset); + while (dmac_reset.reset.rst) + dmac_reset.data = readq(&dmac->reset); + + /*reset dmac */ + + intclear.data = readq(&dmac->com_intclear); + intclear.com_intclear.cear_slvif_dec_err_intstat = 1; + intclear.com_intclear.clear_slvif_wr2ro_err_intstat = 1; + intclear.com_intclear.clear_slvif_rd2wo_err_intstat = 1; + intclear.com_intclear.clear_slvif_wronhold_err_intstat = 1; + intclear.com_intclear.clear_slvif_undefinedreg_dec_err_intstat = 1; + writeq(intclear.data, &dmac->com_intclear); + /* clear common register interrupt */ + + dmac_cfg.data = readq(&dmac->cfg); + dmac_cfg.cfg.dmac_en = 0; + dmac_cfg.cfg.int_en = 0; + writeq(dmac_cfg.data, &dmac->cfg); + /* disable dmac and disable interrupt */ + + while (readq(&dmac->cfg)) + ; + tmp = readq(&dmac->chen); + tmp &= ~0xf; + writeq(tmp, &dmac->chen); + /* disable all channel before configure */ + dmac_enable(); +} + +static void list_add(struct list_head_t *new, struct list_head_t *prev, + struct list_head_t *next) +{ + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} + +void list_add_tail(struct list_head_t *new, struct list_head_t *head) +{ + list_add(new, head->prev, head); +} + +void INIT_LIST_HEAD(struct list_head_t *list) +{ + list->next = list; + list->prev = list; +} + +void dmac_link_list_item(dmac_channel_number_t channel_num, + uint8_t LLI_row_num, int8_t LLI_last_row, + dmac_lli_item_t *lli_item, + dmac_channel_config_t *cfg_param) +{ + dmac_ch_ctl_u_t ctl; + dmac_ch_llp_u_t llp_u; + + lli_item[LLI_row_num].sar = cfg_param->sar; + lli_item[LLI_row_num].dar = cfg_param->dar; + + ctl.data = readq(&dmac->channel[channel_num].ctl); + ctl.ch_ctl.sms = cfg_param->ctl_sms; + ctl.ch_ctl.dms = cfg_param->ctl_dms; + ctl.ch_ctl.sinc = cfg_param->ctl_sinc; + ctl.ch_ctl.dinc = cfg_param->ctl_dinc; + ctl.ch_ctl.src_tr_width = cfg_param->ctl_src_tr_width; + ctl.ch_ctl.dst_tr_width = cfg_param->ctl_dst_tr_width; + ctl.ch_ctl.src_msize = cfg_param->ctl_src_msize; + ctl.ch_ctl.dst_msize = cfg_param->ctl_drc_msize; + ctl.ch_ctl.src_stat_en = cfg_param->ctl_src_stat_en; + ctl.ch_ctl.dst_stat_en = cfg_param->ctl_dst_stat_en; + + if (LLI_last_row != LAST_ROW) { + ctl.ch_ctl.shadowreg_or_lli_valid = 1; + ctl.ch_ctl.shadowreg_or_lli_last = 0; + } else { + ctl.ch_ctl.shadowreg_or_lli_valid = 1; + ctl.ch_ctl.shadowreg_or_lli_last = 1; + } + + lli_item[LLI_row_num].ctl = ctl.data; + + lli_item[LLI_row_num].ch_block_ts = cfg_param->ctl_block_ts; + lli_item[LLI_row_num].sstat = 0; + lli_item[LLI_row_num].dstat = 0; + + llp_u.data = readq(&dmac->channel[channel_num].llp); + + if (LLI_last_row != LAST_ROW) + llp_u.llp.loc = ((uint64_t)&lli_item[LLI_row_num + 1]) >> 6; + else + llp_u.llp.loc = 0; + + lli_item[LLI_row_num].llp = llp_u.data; +} + +void dmac_update_shandow_register(dmac_channel_number_t channel_num, + int8_t last_block, dmac_channel_config_t *cfg_param) +{ + dmac_ch_ctl_u_t ctl_u; + + do { + ctl_u.data = readq(&dmac->channel[channel_num].ctl); + } while (ctl_u.ch_ctl.shadowreg_or_lli_valid); + + writeq(cfg_param->sar, &dmac->channel[channel_num].sar); + writeq(cfg_param->dar, &dmac->channel[channel_num].dar); + writeq(cfg_param->ctl_block_ts, &dmac->channel[channel_num].block_ts); + + ctl_u.ch_ctl.sms = cfg_param->ctl_sms; + ctl_u.ch_ctl.dms = cfg_param->ctl_dms; + ctl_u.ch_ctl.sinc = cfg_param->ctl_sinc; + ctl_u.ch_ctl.dinc = cfg_param->ctl_dinc; + ctl_u.ch_ctl.src_tr_width = cfg_param->ctl_src_tr_width; + ctl_u.ch_ctl.dst_tr_width = cfg_param->ctl_dst_tr_width; + ctl_u.ch_ctl.src_msize = cfg_param->ctl_src_msize; + ctl_u.ch_ctl.dst_msize = cfg_param->ctl_drc_msize; + ctl_u.ch_ctl.src_stat_en = cfg_param->ctl_src_stat_en; + ctl_u.ch_ctl.dst_stat_en = cfg_param->ctl_dst_stat_en; + if (last_block != LAST_ROW) + { + ctl_u.ch_ctl.shadowreg_or_lli_valid = 1; + ctl_u.ch_ctl.shadowreg_or_lli_last = 0; + } else { + ctl_u.ch_ctl.shadowreg_or_lli_valid = 1; + ctl_u.ch_ctl.shadowreg_or_lli_last = 1; + } + + writeq(ctl_u.data, &dmac->channel[channel_num].ctl); + writeq(0, &dmac->channel[channel_num].blk_tfr); +} + +void dmac_set_shadow_invalid_flag(dmac_channel_number_t channel_num) +{ + dmac_ch_ctl_u_t ctl_u; + + ctl_u.data = readq(&dmac->channel[channel_num].ctl); + ctl_u.ch_ctl.shadowreg_or_lli_valid = 1; + ctl_u.ch_ctl.shadowreg_or_lli_last = 0; + writeq(ctl_u.data, &dmac->channel[channel_num].ctl); +} + +void dmac_set_single_mode(dmac_channel_number_t channel_num, + const void *src, void *dest, dmac_address_increment_t src_inc, + dmac_address_increment_t dest_inc, + dmac_burst_trans_length_t dmac_burst_size, + dmac_transfer_width_t dmac_trans_width, + size_t BlockSize) { + dmac_chanel_interrupt_clear(channel_num); + dmac_channel_disable(channel_num); + dmac_wait_idle(channel_num); + dmac_set_channel_param(channel_num, src, dest, src_inc, dest_inc, + dmac_burst_size, dmac_trans_width, BlockSize); + dmac_enable(); + dmac_channel_enable(channel_num); +} + +int dmac_is_done(dmac_channel_number_t channel_num) +{ + if(readq(&dmac->channel[channel_num].intstatus) & 0x2) + return 1; + else + return 0; +} + +void dmac_wait_done(dmac_channel_number_t channel_num) +{ + dmac_wait_idle(channel_num); +} + +int dmac_is_idle(dmac_channel_number_t channel_num) +{ + dmac_chen_u_t chen; + chen.data = readq(&dmac->chen); + if((chen.data >> channel_num) & 0x1UL) + return 0; + else + return 1; +} + +void dmac_wait_idle(dmac_channel_number_t channel_num) +{ + while(!dmac_is_idle(channel_num)); + dmac_chanel_interrupt_clear(channel_num); /* clear interrupt */ +} + +void dmac_set_src_dest_length(dmac_channel_number_t channel_num, const void *src, void *dest, size_t len) +{ + if(src != NULL) + dmac->channel[channel_num].sar = (uint64_t)src; + if(dest != NULL) + dmac->channel[channel_num].dar = (uint64_t)dest; + if(len > 0) + dmac_set_block_ts(channel_num, len - 1); + dmac_channel_enable(channel_num); +} + +static int dmac_irq_callback(void *ctx) +{ + dmac_context_t *v_dmac_context = (dmac_context_t *)(ctx); + dmac_channel_number_t v_dmac_channel = v_dmac_context->dmac_channel; + dmac_chanel_interrupt_clear(v_dmac_channel); + if(v_dmac_context->callback != NULL) + v_dmac_context->callback(v_dmac_context->ctx); + + return 0; +} + +void dmac_irq_register(dmac_channel_number_t channel_num , plic_irq_callback_t dmac_callback, void *ctx, uint32_t priority) +{ + dmac_context[channel_num].dmac_channel = channel_num; + dmac_context[channel_num].callback = dmac_callback; + dmac_context[channel_num].ctx = ctx; + dmac_enable_channel_interrupt(channel_num); + plic_set_priority(IRQN_DMA0_INTERRUPT + channel_num, priority); + plic_irq_enable(IRQN_DMA0_INTERRUPT + channel_num); + plic_irq_register(IRQN_DMA0_INTERRUPT + channel_num, dmac_irq_callback, &dmac_context[channel_num]); +} + +void __attribute__((weak, alias("dmac_irq_register"))) dmac_set_irq(dmac_channel_number_t channel_num , plic_irq_callback_t dmac_callback, void *ctx, uint32_t priority); + +void dmac_irq_unregister(dmac_channel_number_t channel_num) +{ + dmac_context[channel_num].callback = NULL; + dmac_context[channel_num].ctx = NULL; + dmac_disable_channel_interrupt(channel_num); + plic_irq_unregister(IRQN_DMA0_INTERRUPT + channel_num); +} + +void __attribute__((weak, alias("dmac_irq_unregister"))) dmac_free_irq(dmac_channel_number_t channel_num); + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Kconfig new file mode 100644 index 000000000..baf59367c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Kconfig @@ -0,0 +1,15 @@ +# Kconfig file + +config BSP_USING_W5500 +bool "Using w5500 " +default y + +# if BSP_USING_W5500 + config BSP_WIZ_RST_PIN + int + default 13 + + config BSP_WIZ_INT_PIN + int + default 14 +# endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile new file mode 100644 index 000000000..1ea20caac --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := socket.c connect_w5500.c w5500.c wizchip_conf.c spi_interface.c wiz_ping.c + +include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/ReadMe.md b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/ReadMe.md new file mode 100644 index 000000000..947404f4a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/ReadMe.md @@ -0,0 +1,25 @@ +## w5500 测试文档 + +通过board/xidatong-riscv64/third_party_driver/ethernet/connect_w5500.c 可以找到内写的3个,包含ping, tcp server test, tcp client test; + + - ping 测试,测试结果包括: + - pc ping w5500 + - w5500 ping baidu.com (DNS实现暂未实现,因此使用baidu.com的ip地址进行寻址) + + + + + +- tcp server 测试:在xizi中调用wiz_server_op,指定port,之后可以在pc中向该端口发送数据 + - wiz_server 将额外启动一个线程执行server工作,server将向client返回client发来的消息 + + + + + +- client 测试:通过wiz_client_op可以向pc中打开的tcp server发送消息 + - 由于wiz_client_test函数参数接收问题,测试使用的ip地址暂时使用硬编码实现 + + + + \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c new file mode 100644 index 000000000..22803ee9e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c @@ -0,0 +1,505 @@ + +#include "connect_w5500.h" + +#include +#include +#include +#include +#include +#include + +#include "gpio_common.h" +#include "gpiohs.h" +#include "socket.h" +#include "w5500.h" + +#define SPI_LORA_FREQUENCY 10000000 + +// spi operations +extern void spi_enter_cris(void); +extern void spi_exit_cris(void); +extern void spi_select_cs(void); +extern void spi_deselete_cs(void); + +// global configurations for w5500 tcp connection +const uint32_t socket_tcp = 0; +const uint32_t g_wiznet_buf_size = 2048; + +static wiz_NetInfo g_wiz_netinfo = {.mac = {0x00, 0x08, 0xdc, 0x11, 0x11, 0x11}, + .ip = {192, 168, 31, 13}, + .sn = {255, 255, 255, 0}, + .gw = {192, 168, 31, 1}, + .dns = {0, 0, 0, 0}, + .dhcp = NETINFO_STATIC}; + +int network_init() { + wiz_NetInfo check_wiz_netinfo; + check_wiz_netinfo.dhcp = NETINFO_STATIC; + ctlnetwork(CN_SET_NETINFO, (void *)&g_wiz_netinfo); + ctlnetwork(CN_GET_NETINFO, (void *)&check_wiz_netinfo); + + if (memcmp(&g_wiz_netinfo, &check_wiz_netinfo, sizeof(wiz_NetInfo)) != 0) { + KPrintf( + "mac: %d; ip: %d; gw: %d; sn: %d; dns: %d; dhcp: %d;\n", + memcmp(&g_wiz_netinfo.mac, &check_wiz_netinfo.mac, sizeof(uint8_t) * 6), + memcmp(&g_wiz_netinfo.ip, &check_wiz_netinfo.ip, sizeof(uint8_t) * 4), + memcmp(&g_wiz_netinfo.sn, &check_wiz_netinfo.sn, sizeof(uint8_t) * 4), + memcmp(&g_wiz_netinfo.gw, &check_wiz_netinfo.gw, sizeof(uint8_t) * 4), + memcmp(&g_wiz_netinfo.dns, &check_wiz_netinfo.dns, sizeof(uint8_t) * 4), + memcmp(&g_wiz_netinfo.dhcp, &check_wiz_netinfo.dhcp, sizeof(uint8_t))); + KPrintf("WIZCHIP set network information fail.\n"); + return ERROR; + } + uint8_t tmpstr[6]; + ctlwizchip(CW_GET_ID, (void *)tmpstr); + KPrintf("=== %s NET CONF ===\r\n", (char *)tmpstr); + KPrintf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", g_wiz_netinfo.mac[0], + g_wiz_netinfo.mac[1], g_wiz_netinfo.mac[2], g_wiz_netinfo.mac[3], + g_wiz_netinfo.mac[4], g_wiz_netinfo.mac[5]); + KPrintf("SIP: %d.%d.%d.%d\r\n", g_wiz_netinfo.ip[0], g_wiz_netinfo.ip[1], + g_wiz_netinfo.ip[2], g_wiz_netinfo.ip[3]); + KPrintf("GAR: %d.%d.%d.%d\r\n", g_wiz_netinfo.gw[0], g_wiz_netinfo.gw[1], + g_wiz_netinfo.gw[2], g_wiz_netinfo.gw[3]); + KPrintf("SUB: %d.%d.%d.%d\r\n", g_wiz_netinfo.sn[0], g_wiz_netinfo.sn[1], + g_wiz_netinfo.sn[2], g_wiz_netinfo.sn[3]); + KPrintf("DNS: %d.%d.%d.%d\r\n", g_wiz_netinfo.dns[0], g_wiz_netinfo.dns[1], + g_wiz_netinfo.dns[2], g_wiz_netinfo.dns[3]); + KPrintf("======================\r\n"); + + return EOK; +} + +/****************** spi init ******************/ +static struct Bus *w5500_spi_bus; +int w5500_spi_init() { + x_err_t ret = EOK; + + w5500_spi_bus = BusFind(SPI_BUS_NAME_1); + w5500_spi_bus->owner_haldev = + BusFindDevice(w5500_spi_bus, SPI_1_DEVICE_NAME_0); + w5500_spi_bus->owner_driver = BusFindDriver(w5500_spi_bus, SPI_1_DRV_NAME); + + w5500_spi_bus->match(w5500_spi_bus->owner_driver, + w5500_spi_bus->owner_haldev); + + struct BusConfigureInfo configure_info; + struct SpiMasterParam spi_master_param; + spi_master_param.spi_data_bit_width = 8; + spi_master_param.spi_work_mode = SPI_MODE_0 | SPI_MSB; + spi_master_param.spi_maxfrequency = SPI_LORA_FREQUENCY; + spi_master_param.spi_data_endian = 0; + + configure_info.configure_cmd = OPE_CFG; + configure_info.private_data = (void *)&spi_master_param; + ret = BusDrvConfigure(w5500_spi_bus->owner_driver, &configure_info); + if (ret) { + KPrintf("spi drv OPE_CFG error drv %8p cfg %8p\n", + w5500_spi_bus->owner_driver, &spi_master_param); + return ERROR; + } + + configure_info.configure_cmd = OPE_INT; + ret = BusDrvConfigure(w5500_spi_bus->owner_driver, &configure_info); + if (ret) { + KPrintf("spi drv OPE_INT error drv %8p\n", w5500_spi_bus->owner_driver); + return ERROR; + } + + return EOK; +} + +void spi_write_byte(uint8_t tx_data) { + struct BusBlockWriteParam write_param; + write_param.buffer = &tx_data; + write_param.size = 1; + BusDevWriteData(w5500_spi_bus->owner_haldev, &write_param); +} +uint8_t spi_read_byte(void) { + uint8_t result = 0; + struct BusBlockReadParam read_param; + read_param.buffer = &result; + read_param.size = 1; + BusDevReadData(w5500_spi_bus->owner_haldev, &read_param); + return result; +} +void spi_write_burst(uint8_t *tx_buf, uint16_t len) { + struct BusBlockWriteParam write_param; + write_param.buffer = tx_buf; + write_param.size = len; + BusDevWriteData(w5500_spi_bus->owner_haldev, &write_param); +} +void spi_read_burst(uint8_t *rx_buf, uint16_t len) { + struct BusBlockReadParam read_param; + read_param.buffer = rx_buf; + read_param.size = len; + BusDevReadData(w5500_spi_bus->owner_haldev, &read_param); +} + +/****************** chip init ******************/ + +void wiz_reset() { + gpiohs_set_drive_mode(WIZ_RST_PIN, GPIO_DM_OUTPUT); + gpiohs_set_pin(WIZ_RST_PIN, GPIO_PV_LOW); + MdelayKTask(20); + + gpiohs_set_pin(WIZ_RST_PIN, GPIO_PV_HIGH); + MdelayKTask(20); +} + +void wiz_spi_handler_reg() { + // spi ops registration +#if (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_VDM_) || \ + (_WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_SPI_FDM_) + /* register SPI device CS select callback function */ + gpiohs_set_drive_mode(SPI1_CS0_PIN, GPIO_DM_OUTPUT); + reg_wizchip_cs_cbfunc(spi_select_cs, spi_deselete_cs); +#else +#if (_WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SIP_) != _WIZCHIP_IO_MODE_SIP_ +#error "Unknown _WIZCHIP_IO_MODE_" +#else + reg_wizchip_cs_cbfunc(wizchip_select, wizchip_deselect); +#endif +#endif + + reg_wizchip_spi_cbfunc(spi_read_byte, spi_write_byte); + reg_wizchip_cris_cbfunc(spi_enter_cris, spi_exit_cris); + reg_wizchip_spiburst_cbfunc(spi_read_burst, spi_write_burst); +} + +int wiz_chip_cfg_init() { + uint8_t mem_size[2][8] = {{2, 2, 2, 2, 2, 2, 2, 2}, {2, 2, 2, 2, 2, 2, 2, 2}}; + + /* reset WIZnet chip internal PHY, configures PHY mode. */ + if (ctlwizchip(CW_INIT_WIZCHIP, (void *)mem_size) == -1) { + KPrintf("WIZCHIP initialize failed."); + return ERROR; + } + + struct wiz_NetTimeout_t net_timeout; + net_timeout.retry_cnt = 5; + net_timeout.time_100us = 20000; + ctlnetwork(CN_SET_TIMEOUT, (void *)&net_timeout); + + return EOK; +} + +/****************** interrupt handle ******************/ +void wiz_irq_handler() {} + +int wiz_interrupt_init() { + int32_t ret = -ERROR; + + struct Bus *pin_bus = PinBusInitGet(); + + struct PinParam pin_param; + struct BusConfigureInfo pin_configure_info; + + pin_configure_info.configure_cmd = OPE_CFG; + pin_configure_info.private_data = (void *)&pin_param; + + pin_param.cmd = GPIO_CONFIG_MODE; + pin_param.pin = BSP_WIZ_INT_PIN; + pin_param.mode = GPIO_CFG_INPUT_PULLUP; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("config pin_param %d input failed!\n", pin_param.pin); + return -ERROR; + } + + pin_param.cmd = GPIO_IRQ_REGISTER; + pin_param.pin = BSP_WIZ_INT_PIN; + pin_param.irq_set.irq_mode = GPIO_IRQ_EDGE_FALLING; + pin_param.irq_set.hdr = wiz_irq_handler; + pin_param.irq_set.args = NONE; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("register pin_param %d irq failed!\n", pin_param.pin); + return -ERROR; + } + + pin_param.cmd = GPIO_IRQ_DISABLE; + pin_param.pin = BSP_WIZ_INT_PIN; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("disable pin_param %d irq failed!\n", pin_param.pin); + return -ERROR; + } + + // 4. enable interuption + pin_param.cmd = GPIO_IRQ_ENABLE; + pin_param.pin = BSP_WIZ_INT_PIN; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("enable pin_param %d irq failed!\n", pin_param.pin); + return -ERROR; + } + + return EOK; + + return EOK; +} + +int HwWiznetInit(void) { + wiz_reset(); + + if (EOK != w5500_spi_init()) { + return ERROR; + } + + wiz_spi_handler_reg(); + + if (EOK != wiz_chip_cfg_init()) { + return ERROR; + } + + network_init(); + + return EOK; +} + +/****************** basic functions ********************/ + +enum TCP_OPTION { + SEND_DATA = 0, + RECV_DATA, +}; + +uint32_t wiz_client_op(uint8_t sn, uint8_t *buf, uint32_t buf_size, + uint8_t dst_ip[4], uint16_t dst_port, + enum TCP_OPTION opt) { + // assert(buf_size <= g_wiznet_buf_size); + int32_t ret; + switch (getSn_SR(socket_tcp)) { + case SOCK_CLOSE_WAIT: + wiz_sock_disconnect(socket_tcp); + break; + case SOCK_CLOSED: + wiz_socket(socket_tcp, Sn_MR_TCP, 5000, 0x00); + break; + case SOCK_INIT: + KPrintf("[SOCKET CLIENT] sock init.\n"); + wiz_sock_connect(socket_tcp, dst_ip, dst_port); + break; + case SOCK_ESTABLISHED: + if (getSn_IR(socket_tcp) & Sn_IR_CON) { + printf("[SOCKET CLIENT] %d:Connected\r\n", socket_tcp); + setSn_IR(socket_tcp, Sn_IR_CON); + } + if (opt == SEND_DATA) { + uint32_t sent_size = 0; + ret = wiz_sock_send(socket_tcp, buf, buf_size); + if (ret < 0) { + wiz_sock_close(socket_tcp); + return ret; + } + } else if (opt == RECV_DATA) { + uint32_t size = 0; + if ((size = getSn_RX_RSR(sn)) > 0) { + if (size > buf_size) size = buf_size; + ret = wiz_sock_recv(sn, buf, size); + if (ret <= 0) return ret; + } + } + break; + default: + break; + } +} + +void wiz_client_op_test(char *addr, uint16_t port, char *msg) { + /* argv[1]: ip + * argv[2]: port + * argv[3]: msg + */ + uint8_t client_sock = 2; + uint8_t ip[4] = {192, 168, 31, 127}; + uint32_t tmp_ip[4]; + KPrintf("wiz client to %s", addr); + sscanf(addr, "%d.%d.%d.%d", &tmp_ip[0], &tmp_ip[1], &tmp_ip[2], &tmp_ip[3]); + for (int i = 0; i < 4; ++i) { + ip[i] = (uint8_t)tmp_ip[i]; + } + uint8_t buf[g_wiznet_buf_size]; + KPrintf("wiz_server, send to %d.%d.%d.%d %d\n", // tip info + ip[0], ip[1], ip[2], ip[3], port); + sscanf(msg, "%s", buf); + wiz_client_op(client_sock, buf, g_wiznet_buf_size, ip, port, SEND_DATA); + MdelayKTask(10); + memset(buf, 0, g_wiznet_buf_size); + // waiting for a responding. + wiz_client_op(client_sock, buf, g_wiznet_buf_size, ip, port, RECV_DATA); + KPrintf("received msg: %s\n", buf); +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(3), + wiz_client_op, wiz_client_op_test, + wiz_sock_recv or wiz_sock_send data as tcp client); + +int32_t wiz_server_op(uint8_t sn, uint8_t *buf, uint32_t buf_size, + uint16_t port, enum TCP_OPTION opt) { + int32_t ret = 0; + uint16_t size = 0, sentsize = 0; + switch (getSn_SR(sn)) { + case SOCK_ESTABLISHED: + if (getSn_IR(sn) & Sn_IR_CON) { + printf("%d:Connected\r\n", sn); + setSn_IR(sn, Sn_IR_CON); + } + if (opt == SEND_DATA) { + uint32_t sent_size = 0; + ret = wiz_sock_send(socket_tcp, buf, buf_size); + if (ret < 0) { + wiz_sock_close(socket_tcp); + return ret; + } + } else if (opt == RECV_DATA) { + uint32_t size = 0; + if ((size = getSn_RX_RSR(sn)) > 0) { + if (size > buf_size) size = buf_size; + ret = wiz_sock_recv(sn, buf, size); + return ret; + } + } + break; + case SOCK_CLOSE_WAIT: + printf("%d:CloseWait\r\n", sn); + if ((ret = wiz_sock_disconnect(sn)) != SOCK_OK) return ret; + printf("%d:Closed\r\n", sn); + break; + case SOCK_INIT: + printf("%d:Listen, port [%d]\r\n", sn, port); + if ((ret = wiz_sock_listen(sn)) != SOCK_OK) return ret; + break; + case SOCK_CLOSED: + printf("%d:LBTStart\r\n", sn); + if ((ret = wiz_socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret; + printf("%d:Opened\r\n", sn); + break; + default: + break; + } + return 0; +} + +void wiz_server(void *param) { + uint16_t port = *(uint16_t *)param; + KPrintf("wiz server, listen port: %d\n", port); + uint8_t buf[g_wiznet_buf_size]; + memset(buf, 0, g_wiznet_buf_size); + int ret = 0; + while (1) { + ret = wiz_server_op(0, buf, g_wiznet_buf_size, port, RECV_DATA); + if (ret > 0) { + wiz_server_op(0, buf, g_wiznet_buf_size, port, SEND_DATA); + }; + } +} + +void wiz_server_test(uint16_t port) { + /* argv[1]: port + */ + int32 wiz_server_id = + KTaskCreate("wiz_server", wiz_server, (void *)&port, 4096, 25); + x_err_t flag = StartupKTask(wiz_server_id); + if (flag != EOK) { + KPrintf("StartupKTask wiz_server_id failed .\n"); + } +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(1), + wiz_server_op, wiz_server_test, + wiz_sock_recv or wiz_sock_send data as tcp server); + +int32_t loopback_udps(uint8_t sn, uint8_t *buf, uint16_t port) { + int32_t ret; + uint16_t size, sentsize; + uint8_t destip[4]; + uint16_t destport; + // uint8_t packinfo = 0; + switch (getSn_SR(sn)) { + case SOCK_UDP: + if ((size = getSn_RX_RSR(sn)) > 0) { + if (size > g_wiznet_buf_size) size = g_wiznet_buf_size; + ret = wiz_sock_recvfrom(sn, buf, size, destip, (uint16_t *)&destport); + if (ret <= 0) { + printf("%d: wiz_sock_recvfrom error. %ld\r\n", sn, ret); + return ret; + } + size = (uint16_t)ret; + sentsize = 0; + while (sentsize != size) { + ret = wiz_sock_sendto(sn, buf + sentsize, size - sentsize, destip, + destport); + if (ret < 0) { + printf("%d: wiz_sock_sendto error. %ld\r\n", sn, ret); + return ret; + } + sentsize += ret; // Don't care SOCKERR_BUSY, because it is zero. + } + } + break; + case SOCK_CLOSED: + printf("%d:LBUStart\r\n", sn); + if ((ret = wiz_socket(sn, Sn_MR_UDP, port, 0x00)) != sn) return ret; + printf("%d:Opened, port [%d]\r\n", sn, port); + break; + default: + break; + } + return 1; +} + +void ifconfig() { + wiz_NetInfo wiz_netinfo; + ctlnetwork(CN_GET_NETINFO, (void *)&wiz_netinfo); + uint8_t tmpstr[6]; + ctlwizchip(CW_GET_ID, (void *)tmpstr); + KPrintf("=== %s NET CONF ===\r\n", (char *)tmpstr); + KPrintf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", wiz_netinfo.mac[0], + wiz_netinfo.mac[1], wiz_netinfo.mac[2], wiz_netinfo.mac[3], + wiz_netinfo.mac[4], wiz_netinfo.mac[5]); + KPrintf("SIP: %d.%d.%d.%d\r\n", wiz_netinfo.ip[0], wiz_netinfo.ip[1], + wiz_netinfo.ip[2], wiz_netinfo.ip[3]); + KPrintf("GAR: %d.%d.%d.%d\r\n", wiz_netinfo.gw[0], wiz_netinfo.gw[1], + wiz_netinfo.gw[2], wiz_netinfo.gw[3]); + KPrintf("SUB: %d.%d.%d.%d\r\n", wiz_netinfo.sn[0], wiz_netinfo.sn[1], + wiz_netinfo.sn[2], wiz_netinfo.sn[3]); + KPrintf("DNS: %d.%d.%d.%d\r\n", wiz_netinfo.dns[0], wiz_netinfo.dns[1], + wiz_netinfo.dns[2], wiz_netinfo.dns[3]); + KPrintf("======================\r\n"); +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), + ifconfig, ifconfig, printf w5500 configurations); + +void char_arr_assign(uint8_t **dst, uint32_t *src, uint32_t len) { + for (int i = 0; i < len; ++i) { + (*dst)[i] = (uint8_t)(src[i]); + } +} + +void config_w5500_network(char *mac, char *ip, char *sn, char *gw, char *dns) { + wiz_NetInfo wiz_netinfo; + uint32_t tmp_arr[4]; + // config netinfo + sscanf(mac, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], + &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.mac, tmp_arr, 4); + sscanf(ip, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.ip, tmp_arr, 4); + sscanf(sn, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.sn, tmp_arr, 4); + sscanf(gw, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.gw, tmp_arr, 4); + sscanf(dns, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], + &tmp_arr[3]); + char_arr_assign((uint8_t **)&wiz_netinfo.dns, tmp_arr, 4); + // set new netinfo + ctlnetwork(CN_SET_NETINFO, (void *)&wiz_netinfo); + ifconfig(); +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(5), + config_w5500_network, config_w5500_network, + set w5500 configurations); \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/client0.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/client0.png new file mode 100644 index 000000000..7df09b0d9 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/client0.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/client1.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/client1.png new file mode 100644 index 000000000..167d455b8 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/client1.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/ping baidu.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/ping baidu.png new file mode 100644 index 000000000..c79f4bb85 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/ping baidu.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/ping w5500.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/ping w5500.png new file mode 100644 index 000000000..e453995a6 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/ping w5500.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/server0.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/server0.png new file mode 100644 index 000000000..63f2d5f57 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/server0.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/server1.png b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/server1.png new file mode 100644 index 000000000..7643c9bf3 Binary files /dev/null and b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/imgs/server1.png differ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/socket.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/socket.c new file mode 100755 index 000000000..820e0631c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/socket.c @@ -0,0 +1,912 @@ + +//***************************************************************************** +// +//! \file socket.c +//! \brief SOCKET APIs Implements file. +//! \details SOCKET APIs like as Berkeley Socket APIs. +//! \version 1.0.3 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.3. Refer to M20140501 +//! 1. Implicit type casting -> Explicit type casting. +//! 2. replace 0x01 with PACK_REMAINED in recvfrom() +//! 3. Validation a destination ip in connect() & sendto(): +//! It occurs a fatal error on converting unint32 address if uint8* +//! addr parameter is not aligned by 4byte address. Copy 4 byte addr +//! value into temporary uint32 variable and then compares it. +//! <2013/12/20> V1.0.2 Refer to M20131220 +//! Remove Warning. +//! <2013/11/04> V1.0.1 2nd Release. Refer to "20131104". +//! In sendto(), Add to clear timeout interrupt status +//! (Sn_IR_TIMEOUT) +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +#include "socket.h" + +#include "wizchip_conf.h" + +// M20150401 : Typing Error +//#define SOCK_ANY_PORT_NUM 0xC000; +#define SOCK_ANY_PORT_NUM 0xC000 + +static uint16_t sock_any_port = SOCK_ANY_PORT_NUM; +static uint16_t sock_io_mode = 0; +static uint16_t sock_is_sending = 0; + +static uint16_t sock_remained_size[_WIZCHIP_SOCK_NUM_] = { + 0, + 0, +}; + +// M20150601 : For extern decleation +// static uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = {0,}; +uint8_t sock_pack_info[_WIZCHIP_SOCK_NUM_] = { + 0, +}; +// + +#if _WIZCHIP_ == 5200 +static uint16_t sock_next_rd[_WIZCHIP_SOCK_NUM_] = { + 0, +}; +#endif + +// A20150601 : For integrating with W5300 +#if _WIZCHIP_ == 5300 +uint8_t sock_remained_byte[_WIZCHIP_SOCK_NUM_] = { + 0, +}; // set by wiz_recv_data() +#endif + +#define CHECK_SOCKNUM() \ + do { \ + if (sn > _WIZCHIP_SOCK_NUM_) return SOCKERR_SOCKNUM; \ + } while (0); + +#define CHECK_SOCKMODE(mode) \ + do { \ + if ((getSn_MR(sn) & 0x0F) != mode) return SOCKERR_SOCKMODE; \ + } while (0); + +#define CHECK_SOCKINIT() \ + do { \ + if ((getSn_SR(sn) != SOCK_INIT)) return SOCKERR_SOCKINIT; \ + } while (0); + +#define CHECK_SOCKDATA() \ + do { \ + if (len == 0) return SOCKERR_DATALEN; \ + } while (0); + +int8_t wiz_socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag) { + CHECK_SOCKNUM(); + switch (protocol) { + case Sn_MR_TCP: { + // M20150601 : Fixed the warning - taddr will never be NULL + /* + uint8_t taddr[4]; + getSIPR(taddr); + */ + uint32_t taddr; + getSIPR((uint8_t *)&taddr); + if (taddr == 0) return SOCKERR_SOCKINIT; + break; + } + case Sn_MR_UDP: + case Sn_MR_MACRAW: + case Sn_MR_IPRAW: + break; +#if (_WIZCHIP_ < 5200) + case Sn_MR_PPPoE: + break; +#endif + default: + return SOCKERR_SOCKMODE; + } + // M20150601 : For SF_TCP_ALIGN & W5300 + // if((flag & 0x06) != 0) return SOCKERR_SOCKFLAG; + if ((flag & 0x04) != 0) return SOCKERR_SOCKFLAG; +#if _WIZCHIP_ == 5200 + if (flag & 0x10) return SOCKERR_SOCKFLAG; +#endif + + if (flag != 0) { + switch (protocol) { + case Sn_MR_TCP: + // M20150601 : For SF_TCP_ALIGN & W5300 +#if _WIZCHIP_ == 5300 + if ((flag & (SF_TCP_NODELAY | SF_IO_NONBLOCK | SF_TCP_ALIGN)) == 0) + return SOCKERR_SOCKFLAG; +#else + if ((flag & (SF_TCP_NODELAY | SF_IO_NONBLOCK)) == 0) + return SOCKERR_SOCKFLAG; +#endif + + break; + case Sn_MR_UDP: + if (flag & SF_IGMP_VER2) { + if ((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG; + } +#if _WIZCHIP_ == 5500 + if (flag & SF_UNI_BLOCK) { + if ((flag & SF_MULTI_ENABLE) == 0) return SOCKERR_SOCKFLAG; + } +#endif + break; + default: + break; + } + } + wiz_sock_close(sn); +// M20150601 +#if _WIZCHIP_ == 5300 + setSn_MR(sn, ((uint16_t)(protocol | (flag & 0xF0))) | + (((uint16_t)(flag & 0x02)) << 7)); +#else + setSn_MR(sn, (protocol | (flag & 0xF0))); +#endif + if (!port) { + port = sock_any_port++; + if (sock_any_port == 0xFFF0) sock_any_port = SOCK_ANY_PORT_NUM; + } + setSn_PORT(sn, port); + setSn_CR(sn, Sn_CR_OPEN); + while (getSn_CR(sn)) + ; + // A20150401 : For release the previous sock_io_mode + sock_io_mode &= ~(1 << sn); + // + sock_io_mode |= ((flag & SF_IO_NONBLOCK) << sn); + sock_is_sending &= ~(1 << sn); + sock_remained_size[sn] = 0; + // M20150601 : repalce 0 with PACK_COMPLETED + // sock_pack_info[sn] = 0; + sock_pack_info[sn] = PACK_COMPLETED; + // + while (getSn_SR(sn) == SOCK_CLOSED) + ; + return (int8_t)sn; +} + +int8_t wiz_sock_close(uint8_t sn) { + CHECK_SOCKNUM(); +// A20160426 : Applied the erratum 1 of W5300 +#if (_WIZCHIP_ == 5300) + // M20160503 : Wrong socket parameter. s -> sn + // if( ((getSn_MR(s)& 0x0F) == Sn_MR_TCP) && (getSn_TX_FSR(s) != + // getSn_TxMAX(s)) ) + if (((getSn_MR(sn) & 0x0F) == Sn_MR_TCP) && + (getSn_TX_FSR(sn) != getSn_TxMAX(sn))) { + uint8_t destip[4] = {0, 0, 0, 1}; + // TODO + // You can wait for completing to sending data; + // wait about 1 second; + // if you have completed to send data, skip the code of erratum 1 + // ex> wait_1s(); + // if (getSn_TX_FSR(s) == getSn_TxMAX(s)) continue; + // + // M20160503 : The socket() of close() calls close() itself again. It + // occures a infinite loop - close()->socket()->close()->socket()-> ~ + // socket(s,Sn_MR_UDP,0x3000,0); + // sendto(s,destip,1,destip,0x3000); // send the dummy data to an unknown + // destination(0.0.0.1). + setSn_MR(sn, Sn_MR_UDP); + setSn_PORTR(sn, 0x3000); + setSn_CR(sn, Sn_CR_OPEN); + while (getSn_CR(sn) != 0) + ; + while (getSn_SR(sn) != SOCK_UDP) + ; + wiz_sock_sendto( + sn, destip, 1, destip, + 0x3000); // send the dummy data to an unknown destination(0.0.0.1). + }; +#endif + setSn_CR(sn, Sn_CR_CLOSE); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + /* clear all interrupt of the socket. */ + setSn_IR(sn, 0xFF); + // A20150401 : Release the sock_io_mode of socket n. + sock_io_mode &= ~(1 << sn); + // + sock_is_sending &= ~(1 << sn); + sock_remained_size[sn] = 0; + sock_pack_info[sn] = 0; + while (getSn_SR(sn) != SOCK_CLOSED) + ; + return SOCK_OK; +} + +int8_t wiz_sock_listen(uint8_t sn) { + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKINIT(); + setSn_CR(sn, Sn_CR_LISTEN); + while (getSn_CR(sn)) + ; + while (getSn_SR(sn) != SOCK_LISTEN) { + wiz_sock_close(sn); + return SOCKERR_SOCKCLOSED; + } + return SOCK_OK; +} + +int8_t wiz_sock_connect(uint8_t sn, uint8_t *addr, uint16_t port) { + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKINIT(); + // M20140501 : For avoiding fatal error on memory align mismatched + // if( *((uint32_t*)addr) == 0xFFFFFFFF || *((uint32_t*)addr) == 0) return + // SOCKERR_IPINVALID; + { + uint32_t taddr; + taddr = ((uint32_t)addr[0] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF); + if (taddr == 0xFFFFFFFF || taddr == 0) return SOCKERR_IPINVALID; + } + // + + if (port == 0) return SOCKERR_PORTZERO; + setSn_DIPR(sn, addr); + setSn_DPORT(sn, port); + setSn_CR(sn, Sn_CR_CONNECT); + while (getSn_CR(sn)) + ; + if (sock_io_mode & (1 << sn)) return SOCK_BUSY; + while (getSn_SR(sn) != SOCK_ESTABLISHED) { + if (getSn_IR(sn) & Sn_IR_TIMEOUT) { + setSn_IR(sn, Sn_IR_TIMEOUT); + return SOCKERR_TIMEOUT; + } + + if (getSn_SR(sn) == SOCK_CLOSED) { + return SOCKERR_SOCKCLOSED; + } + } + + return SOCK_OK; +} + +int8_t wiz_sock_disconnect(uint8_t sn) { + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + setSn_CR(sn, Sn_CR_DISCON); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + sock_is_sending &= ~(1 << sn); + if (sock_io_mode & (1 << sn)) return SOCK_BUSY; + while (getSn_SR(sn) != SOCK_CLOSED) { + if (getSn_IR(sn) & Sn_IR_TIMEOUT) { + wiz_sock_close(sn); + return SOCKERR_TIMEOUT; + } + } + return SOCK_OK; +} + +int32_t wiz_sock_send(uint8_t sn, uint8_t *buf, uint16_t len) { + uint8_t tmp = 0; + uint16_t freesize = 0; + + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKDATA(); + tmp = getSn_SR(sn); + if (tmp != SOCK_ESTABLISHED && tmp != SOCK_CLOSE_WAIT) + return SOCKERR_SOCKSTATUS; + if (sock_is_sending & (1 << sn)) { + tmp = getSn_IR(sn); + if (tmp & Sn_IR_SENDOK) { + setSn_IR(sn, Sn_IR_SENDOK); +// M20150401 : Typing Error +//#if _WZICHIP_ == 5200 +#if _WIZCHIP_ == 5200 + if (getSn_TX_RD(sn) != sock_next_rd[sn]) { + setSn_CR(sn, Sn_CR_SEND); + while (getSn_CR(sn)) + ; + return SOCK_BUSY; + } +#endif + sock_is_sending &= ~(1 << sn); + } else if (tmp & Sn_IR_TIMEOUT) { + wiz_sock_close(sn); + return SOCKERR_TIMEOUT; + } else + return SOCK_BUSY; + } + freesize = getSn_TxMAX(sn); + if (len > freesize) len = freesize; // check size not to exceed MAX size. + while (1) { + freesize = getSn_TX_FSR(sn); + tmp = getSn_SR(sn); + if ((tmp != SOCK_ESTABLISHED) && (tmp != SOCK_CLOSE_WAIT)) { + wiz_sock_close(sn); + return SOCKERR_SOCKSTATUS; + } + if ((sock_io_mode & (1 << sn)) && (len > freesize)) return SOCK_BUSY; + if (len <= freesize) break; + } + wiz_send_data(sn, buf, len); +#if _WIZCHIP_ == 5200 + sock_next_rd[sn] = getSn_TX_RD(sn) + len; +#endif + +#if _WIZCHIP_ == 5300 + setSn_TX_WRSR(sn, len); +#endif + + setSn_CR(sn, Sn_CR_SEND); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + sock_is_sending |= (1 << sn); + // M20150409 : Explicit Type Casting + // return len; + return (int32_t)len; +} + +int32_t wiz_sock_recv(uint8_t sn, uint8_t *buf, uint16_t len) { + uint8_t tmp = 0; + uint16_t recvsize = 0; +// A20150601 : For integarating with W5300 +#if _WIZCHIP_ == 5300 + uint8_t head[2]; + uint16_t mr; +#endif + // + CHECK_SOCKNUM(); + CHECK_SOCKMODE(Sn_MR_TCP); + CHECK_SOCKDATA(); + + recvsize = getSn_RxMAX(sn); + if (recvsize < len) len = recvsize; + +// A20150601 : For Integrating with W5300 +#if _WIZCHIP_ == 5300 + // sock_pack_info[sn] = PACK_COMPLETED; // for clear + if (sock_remained_size[sn] == 0) { +#endif + // + while (1) { + recvsize = getSn_RX_RSR(sn); + tmp = getSn_SR(sn); + if (tmp != SOCK_ESTABLISHED) { + if (tmp == SOCK_CLOSE_WAIT) { + if (recvsize != 0) + break; + else if (getSn_TX_FSR(sn) == getSn_TxMAX(sn)) { + wiz_sock_close(sn); + return SOCKERR_SOCKSTATUS; + } + } else { + wiz_sock_close(sn); + return SOCKERR_SOCKSTATUS; + } + } + if ((sock_io_mode & (1 << sn)) && (recvsize == 0)) return SOCK_BUSY; + if (recvsize != 0) break; + }; +#if _WIZCHIP_ == 5300 + } +#endif + +// A20150601 : For integrating with W5300 +#if _WIZCHIP_ == 5300 + if ((sock_remained_size[sn] == 0) || (getSn_MR(sn) & Sn_MR_ALIGN)) { + mr = getMR(); + if ((getSn_MR(sn) & Sn_MR_ALIGN) == 0) { + wiz_recv_data(sn, head, 2); + if (mr & MR_FS) + recvsize = (((uint16_t)head[1]) << 8) | ((uint16_t)head[0]); + else + recvsize = (((uint16_t)head[0]) << 8) | ((uint16_t)head[1]); + sock_pack_info[sn] = PACK_FIRST; + } + sock_remained_size[sn] = recvsize; + } + if (len > sock_remained_size[sn]) len = sock_remained_size[sn]; + recvsize = len; + if (sock_pack_info[sn] & PACK_FIFOBYTE) { + *buf = sock_remained_byte[sn]; + buf++; + sock_pack_info[sn] &= ~(PACK_FIFOBYTE); + recvsize -= 1; + sock_remained_size[sn] -= 1; + } + if (recvsize != 0) { + wiz_recv_data(sn, buf, recvsize); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; + } + sock_remained_size[sn] -= recvsize; + if (sock_remained_size[sn] != 0) { + sock_pack_info[sn] |= PACK_REMAINED; + if (recvsize & 0x1) sock_pack_info[sn] |= PACK_FIFOBYTE; + } else + sock_pack_info[sn] = PACK_COMPLETED; + if (getSn_MR(sn) & Sn_MR_ALIGN) sock_remained_size[sn] = 0; + // len = recvsize; +#else + if (recvsize < len) len = recvsize; + wiz_recv_data(sn, buf, len); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; +#endif + + // M20150409 : Explicit Type Casting + // return len; + return (int32_t)len; +} + +int32_t wiz_sock_sendto(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *addr, + uint16_t port) { + uint8_t tmp = 0; + uint16_t freesize = 0; + uint32_t taddr; + + CHECK_SOCKNUM(); + switch (getSn_MR(sn) & 0x0F) { + case Sn_MR_UDP: + case Sn_MR_MACRAW: + // break; + // #if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW: + break; + // #endif + default: + return SOCKERR_SOCKMODE; + } + CHECK_SOCKDATA(); + // M20140501 : For avoiding fatal error on memory align mismatched + // if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; + //{ + // uint32_t taddr; + taddr = ((uint32_t)addr[0]) & 0x000000FF; + taddr = (taddr << 8) + ((uint32_t)addr[1] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[2] & 0x000000FF); + taddr = (taddr << 8) + ((uint32_t)addr[3] & 0x000000FF); + //} + // + // if(*((uint32_t*)addr) == 0) return SOCKERR_IPINVALID; + if ((taddr == 0) && ((getSn_MR(sn) & Sn_MR_MACRAW) != Sn_MR_MACRAW)) + return SOCKERR_IPINVALID; + if ((port == 0) && ((getSn_MR(sn) & Sn_MR_MACRAW) != Sn_MR_MACRAW)) + return SOCKERR_PORTZERO; + tmp = getSn_SR(sn); + //#if ( _WIZCHIP_ < 5200 ) + if ((tmp != SOCK_MACRAW) && (tmp != SOCK_UDP) && (tmp != SOCK_IPRAW)) + return SOCKERR_SOCKSTATUS; + //#else + // if(tmp != SOCK_MACRAW && tmp != SOCK_UDP) return SOCKERR_SOCKSTATUS; + //#endif + + setSn_DIPR(sn, addr); + setSn_DPORT(sn, port); + freesize = getSn_TxMAX(sn); + if (len > freesize) len = freesize; // check size not to exceed MAX size. + while (1) { + freesize = getSn_TX_FSR(sn); + if (getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; + if ((sock_io_mode & (1 << sn)) && (len > freesize)) return SOCK_BUSY; + if (len <= freesize) break; + }; + wiz_send_data(sn, buf, len); + +#if _WIZCHIP_ < 5500 // M20150401 : for WIZCHIP Errata #4, #5 (ARP errata) + getSIPR((uint8_t *)&taddr); + if (taddr == 0) { + getSUBR((uint8_t *)&taddr); + setSUBR((uint8_t *)"\x00\x00\x00\x00"); + } else + taddr = 0; +#endif + +// A20150601 : For W5300 +#if _WIZCHIP_ == 5300 + setSn_TX_WRSR(sn, len); +#endif + // + setSn_CR(sn, Sn_CR_SEND); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + while (1) { + tmp = getSn_IR(sn); + if (tmp & Sn_IR_SENDOK) { + setSn_IR(sn, Sn_IR_SENDOK); + break; + } + // M:20131104 + // else if(tmp & Sn_IR_TIMEOUT) return SOCKERR_TIMEOUT; + else if (tmp & Sn_IR_TIMEOUT) { + setSn_IR(sn, Sn_IR_TIMEOUT); +// M20150409 : Fixed the lost of sign bits by type casting. +// len = (uint16_t)SOCKERR_TIMEOUT; +// break; +#if _WIZCHIP_ < 5500 // M20150401 : for WIZCHIP Errata #4, #5 (ARP errata) + if (taddr) setSUBR((uint8_t *)&taddr); +#endif + return SOCKERR_TIMEOUT; + } + //////////// + } +#if _WIZCHIP_ < 5500 // M20150401 : for WIZCHIP Errata #4, #5 (ARP errata) + if (taddr) setSUBR((uint8_t *)&taddr); +#endif + // M20150409 : Explicit Type Casting + // return len; + return (int32_t)len; +} + +int32_t wiz_sock_recvfrom(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *addr, + uint16_t *port) { +// M20150601 : For W5300 +#if _WIZCHIP_ == 5300 + uint16_t mr; + uint16_t mr1; +#else + uint8_t mr; +#endif + // + uint8_t head[8]; + uint16_t pack_len = 0; + + CHECK_SOCKNUM(); + // CHECK_SOCKMODE(Sn_MR_UDP); +// A20150601 +#if _WIZCHIP_ == 5300 + mr1 = getMR(); +#endif + + switch ((mr = getSn_MR(sn)) & 0x0F) { + case Sn_MR_UDP: + case Sn_MR_IPRAW: + case Sn_MR_MACRAW: + break; +#if (_WIZCHIP_ < 5200) + case Sn_MR_PPPoE: + break; +#endif + default: + return SOCKERR_SOCKMODE; + } + CHECK_SOCKDATA(); + if (sock_remained_size[sn] == 0) { + while (1) { + pack_len = getSn_RX_RSR(sn); + if (getSn_SR(sn) == SOCK_CLOSED) return SOCKERR_SOCKCLOSED; + if ((sock_io_mode & (1 << sn)) && (pack_len == 0)) return SOCK_BUSY; + if (pack_len != 0) break; + }; + } + // D20150601 : Move it to bottom + // sock_pack_info[sn] = PACK_COMPLETED; + switch (mr & 0x07) { + case Sn_MR_UDP: + if (sock_remained_size[sn] == 0) { + wiz_recv_data(sn, head, 8); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; + // read peer's IP address, port number & packet length + // A20150601 : For W5300 +#if _WIZCHIP_ == 5300 + if (mr1 & MR_FS) { + addr[0] = head[1]; + addr[1] = head[0]; + addr[2] = head[3]; + addr[3] = head[2]; + *port = head[5]; + *port = (*port << 8) + head[4]; + sock_remained_size[sn] = head[7]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[6]; + } else { +#endif + addr[0] = head[0]; + addr[1] = head[1]; + addr[2] = head[2]; + addr[3] = head[3]; + *port = head[4]; + *port = (*port << 8) + head[5]; + sock_remained_size[sn] = head[6]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[7]; +#if _WIZCHIP_ == 5300 + } +#endif + sock_pack_info[sn] = PACK_FIRST; + } + if (len < sock_remained_size[sn]) + pack_len = len; + else + pack_len = sock_remained_size[sn]; + // A20150601 : For W5300 + len = pack_len; +#if _WIZCHIP_ == 5300 + if (sock_pack_info[sn] & PACK_FIFOBYTE) { + *buf++ = sock_remained_byte[sn]; + pack_len -= 1; + sock_remained_size[sn] -= 1; + sock_pack_info[sn] &= ~PACK_FIFOBYTE; + } +#endif + // + // Need to packet length check (default 1472) + // + wiz_recv_data(sn, buf, pack_len); // data copy. + break; + case Sn_MR_MACRAW: + if (sock_remained_size[sn] == 0) { + wiz_recv_data(sn, head, 2); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; + // read peer's IP address, port number & packet length + sock_remained_size[sn] = head[0]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[1] - 2; +#if _WIZCHIP_ == W5300 + if (sock_remained_size[sn] & 0x01) + sock_remained_size[sn] = sock_remained_size[sn] + 1 - 4; + else + sock_remained_size[sn] -= 4; +#endif + if (sock_remained_size[sn] > 1514) { + wiz_sock_close(sn); + return SOCKFATAL_PACKLEN; + } + sock_pack_info[sn] = PACK_FIRST; + } + if (len < sock_remained_size[sn]) + pack_len = len; + else + pack_len = sock_remained_size[sn]; + wiz_recv_data(sn, buf, pack_len); + break; + //#if ( _WIZCHIP_ < 5200 ) + case Sn_MR_IPRAW: + if (sock_remained_size[sn] == 0) { + wiz_recv_data(sn, head, 6); + setSn_CR(sn, Sn_CR_RECV); + while (getSn_CR(sn)) + ; + addr[0] = head[0]; + addr[1] = head[1]; + addr[2] = head[2]; + addr[3] = head[3]; + sock_remained_size[sn] = head[4]; + // M20150401 : For Typing Error + // sock_remaiend_size[sn] = (sock_remained_size[sn] << 8) + head[5]; + sock_remained_size[sn] = (sock_remained_size[sn] << 8) + head[5]; + sock_pack_info[sn] = PACK_FIRST; + } + // + // Need to packet length check + // + if (len < sock_remained_size[sn]) + pack_len = len; + else + pack_len = sock_remained_size[sn]; + wiz_recv_data(sn, buf, pack_len); // data copy. + break; + //#endif + default: + wiz_recv_ignore(sn, pack_len); // data copy. + sock_remained_size[sn] = pack_len; + break; + } + setSn_CR(sn, Sn_CR_RECV); + /* wait to process the command... */ + while (getSn_CR(sn)) + ; + sock_remained_size[sn] -= pack_len; + // M20150601 : + // if(sock_remained_size[sn] != 0) sock_pack_info[sn] |= 0x01; + if (sock_remained_size[sn] != 0) { + sock_pack_info[sn] |= PACK_REMAINED; +#if _WIZCHIP_ == 5300 + if (pack_len & 0x01) sock_pack_info[sn] |= PACK_FIFOBYTE; +#endif + } else + sock_pack_info[sn] = PACK_COMPLETED; +#if _WIZCHIP_ == 5300 + pack_len = len; +#endif + // + // M20150409 : Explicit Type Casting + // return pack_len; + return (int32_t)pack_len; +} + +int8_t wiz_ctlsocket(uint8_t sn, ctlsock_type cstype, void *arg) { + uint8_t tmp = 0; + CHECK_SOCKNUM(); + switch (cstype) { + case CS_SET_IOMODE: + tmp = *((uint8_t *)arg); + if (tmp == SOCK_IO_NONBLOCK) + sock_io_mode |= (1 << sn); + else if (tmp == SOCK_IO_BLOCK) + sock_io_mode &= ~(1 << sn); + else + return SOCKERR_ARG; + break; + case CS_GET_IOMODE: + // M20140501 : implict type casting -> explict type casting + //*((uint8_t*)arg) = (sock_io_mode >> sn) & 0x0001; + *((uint8_t *)arg) = (uint8_t)((sock_io_mode >> sn) & 0x0001); + // + break; + case CS_GET_MAXTXBUF: + *((uint16_t *)arg) = getSn_TxMAX(sn); + break; + case CS_GET_MAXRXBUF: + *((uint16_t *)arg) = getSn_RxMAX(sn); + break; + case CS_CLR_INTERRUPT: + if ((*(uint8_t *)arg) > SIK_ALL) return SOCKERR_ARG; + setSn_IR(sn, *(uint8_t *)arg); + break; + case CS_GET_INTERRUPT: + *((uint8_t *)arg) = getSn_IR(sn); + break; +#if _WIZCHIP_ != 5100 + case CS_SET_INTMASK: + if ((*(uint8_t *)arg) > SIK_ALL) return SOCKERR_ARG; + setSn_IMR(sn, *(uint8_t *)arg); + break; + case CS_GET_INTMASK: + *((uint8_t *)arg) = getSn_IMR(sn); + break; +#endif + default: + return SOCKERR_ARG; + } + return SOCK_OK; +} + +int8_t wiz_setsockopt(uint8_t sn, sockopt_type sotype, void *arg) { + // M20131220 : Remove warning + // uint8_t tmp; + CHECK_SOCKNUM(); + switch (sotype) { + case SO_TTL: + setSn_TTL(sn, *(uint8_t *)arg); + break; + case SO_TOS: + setSn_TOS(sn, *(uint8_t *)arg); + break; + case SO_MSS: + setSn_MSSR(sn, *(uint16_t *)arg); + break; + case SO_DESTIP: + setSn_DIPR(sn, (uint8_t *)arg); + break; + case SO_DESTPORT: + setSn_DPORT(sn, *(uint16_t *)arg); + break; +#if _WIZCHIP_ != 5100 + case SO_KEEPALIVESEND: + CHECK_SOCKMODE(Sn_MR_TCP); +#if _WIZCHIP_ > 5200 + if (getSn_KPALVTR(sn) != 0) return SOCKERR_SOCKOPT; +#endif + setSn_CR(sn, Sn_CR_SEND_KEEP); + while (getSn_CR(sn) != 0) { + // M20131220 + // if ((tmp = getSn_IR(sn)) & Sn_IR_TIMEOUT) + if (getSn_IR(sn) & Sn_IR_TIMEOUT) { + setSn_IR(sn, Sn_IR_TIMEOUT); + return SOCKERR_TIMEOUT; + } + } + break; +#if !((_WIZCHIP_ == 5100) || (_WIZCHIP_ == 5200)) + case SO_KEEPALIVEAUTO: + CHECK_SOCKMODE(Sn_MR_TCP); + setSn_KPALVTR(sn, *(uint8_t *)arg); + break; +#endif +#endif + default: + return SOCKERR_ARG; + } + return SOCK_OK; +} + +int8_t wiz_getsockopt(uint8_t sn, sockopt_type sotype, void *arg) { + CHECK_SOCKNUM(); + switch (sotype) { + case SO_FLAG: + *(uint8_t *)arg = getSn_MR(sn) & 0xF0; + break; + case SO_TTL: + *(uint8_t *)arg = getSn_TTL(sn); + break; + case SO_TOS: + *(uint8_t *)arg = getSn_TOS(sn); + break; + case SO_MSS: + *(uint16_t *)arg = getSn_MSSR(sn); + break; + case SO_DESTIP: + getSn_DIPR(sn, (uint8_t *)arg); + break; + case SO_DESTPORT: + *(uint16_t *)arg = getSn_DPORT(sn); + break; +#if _WIZCHIP_ > 5200 + case SO_KEEPALIVEAUTO: + CHECK_SOCKMODE(Sn_MR_TCP); + *(uint16_t *)arg = getSn_KPALVTR(sn); + break; +#endif + case SO_SENDBUF: + *(uint16_t *)arg = getSn_TX_FSR(sn); + break; + case SO_RECVBUF: + *(uint16_t *)arg = getSn_RX_RSR(sn); + break; + case SO_STATUS: + *(uint8_t *)arg = getSn_SR(sn); + break; + case SO_REMAINSIZE: + if (getSn_MR(sn) & Sn_MR_TCP) + *(uint16_t *)arg = getSn_RX_RSR(sn); + else + *(uint16_t *)arg = sock_remained_size[sn]; + break; + case SO_PACKINFO: + // CHECK_SOCKMODE(Sn_MR_TCP); +#if _WIZCHIP_ != 5300 + if ((getSn_MR(sn) == Sn_MR_TCP)) return SOCKERR_SOCKMODE; +#endif + *(uint8_t *)arg = sock_pack_info[sn]; + break; + default: + return SOCKERR_SOCKOPT; + } + return SOCK_OK; +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/spi_interface.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/spi_interface.c new file mode 100644 index 000000000..7dbba1b46 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/spi_interface.c @@ -0,0 +1,35 @@ + +#include +#include +#include +#include +#include +#include + +#include "gpio_common.h" +#include "gpiohs.h" + +// #define SPI1_CS_GPIONUM 24 + +static x_base g_w5500_spi_lock; +/** + * @brief 进入临界区 + * @retval None + */ +void spi_enter_cris(void) { g_w5500_spi_lock = DisableLocalInterrupt(); } +/** + * @brief 退出临界区 + * @retval None + */ +void spi_exit_cris(void) { EnableLocalInterrupt(g_w5500_spi_lock); } + +/** + * @brief 片选信号输出低电平 + * @retval None + */ +void spi_select_cs(void) { gpiohs_set_pin(SPI1_CS0_PIN, GPIO_PV_LOW); } +/** + * @brief 片选信号输出高电平 + * @retval None + */ +void spi_deselete_cs(void) { gpiohs_set_pin(SPI1_CS0_PIN, GPIO_PV_HIGH); } \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/w5500.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/w5500.c new file mode 100755 index 000000000..e98739488 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/w5500.c @@ -0,0 +1,255 @@ +//***************************************************************************** +// +//! \file w5500.c +//! \brief W5500 HAL Interface. +//! \version 1.0.2 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.2 +//! 1. Implicit type casting -> Explicit type casting. Refer to +//! M20140501 +//! Fixed the problem on porting into under 32bit MCU +//! Issued by Mathias ClauBen, wizwiki forum ID Think01 and bobh +//! Thank for your interesting and serious advices. +//! <2013/12/20> V1.0.1 +//! 1. Remove warning +//! 2. WIZCHIP_READ_BUF WIZCHIP_WRITE_BUF in case +//! _WIZCHIP_IO_MODE_SPI_FDM_ +//! for loop optimized(removed). refer to M20131220 +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +//#include +#include "w5500.h" + +#define _W5500_SPI_VDM_OP_ 0x00 +#define _W5500_SPI_FDM_OP_LEN1_ 0x01 +#define _W5500_SPI_FDM_OP_LEN2_ 0x02 +#define _W5500_SPI_FDM_OP_LEN4_ 0x03 + +#if (_WIZCHIP_ == 5500) +//////////////////////////////////////////////////// + +uint8_t WIZCHIP_READ(uint32_t AddrSel) { + uint8_t ret; + uint8_t spi_data[3]; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_); + + if (!WIZCHIP.IF.SPI._read_burst || + !WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + } else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + } + ret = WIZCHIP.IF.SPI._read_byte(); + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); + return ret; +} + +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb) { + uint8_t spi_data[4]; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_); + + // if(!WIZCHIP.IF.SPI._read_burst || !WIZCHIP.IF.SPI._write_burst) // byte + // operation + if (!WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + WIZCHIP.IF.SPI._write_byte(wb); + } else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + spi_data[3] = wb; + WIZCHIP.IF.SPI._write_burst(spi_data, 4); + } + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +void WIZCHIP_READ_BUF(uint32_t AddrSel, uint8_t *pBuf, uint16_t len) { + uint8_t spi_data[3]; + uint16_t i; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_READ_ | _W5500_SPI_VDM_OP_); + + if (!WIZCHIP.IF.SPI._read_burst || + !WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + for (i = 0; i < len; i++) + pBuf[i] = WIZCHIP.IF.SPI._read_byte(); + } else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + WIZCHIP.IF.SPI._read_burst(pBuf, len); + } + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t *pBuf, uint16_t len) { + uint8_t spi_data[3]; + uint16_t i; + + WIZCHIP_CRITICAL_ENTER(); + WIZCHIP.CS._select(); + + AddrSel |= (_W5500_SPI_WRITE_ | _W5500_SPI_VDM_OP_); + + if (!WIZCHIP.IF.SPI._write_burst) // byte operation + { + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x00FF0000) >> 16); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x0000FF00) >> 8); + WIZCHIP.IF.SPI._write_byte((AddrSel & 0x000000FF) >> 0); + for (i = 0; i < len; i++) + WIZCHIP.IF.SPI._write_byte(pBuf[i]); + } else // burst operation + { + spi_data[0] = (AddrSel & 0x00FF0000) >> 16; + spi_data[1] = (AddrSel & 0x0000FF00) >> 8; + spi_data[2] = (AddrSel & 0x000000FF) >> 0; + WIZCHIP.IF.SPI._write_burst(spi_data, 3); + WIZCHIP.IF.SPI._write_burst(pBuf, len); + } + + WIZCHIP.CS._deselect(); + WIZCHIP_CRITICAL_EXIT(); +} + +uint16_t getSn_TX_FSR(uint8_t sn) { + uint16_t val = 0, val1 = 0; + + do { + val1 = WIZCHIP_READ(Sn_TX_FSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn), 1)); + if (val1 != 0) { + val = WIZCHIP_READ(Sn_TX_FSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_FSR(sn), 1)); + } + } while (val != val1); + return val; +} + +uint16_t getSn_RX_RSR(uint8_t sn) { + uint16_t val = 0, val1 = 0; + + do { + val1 = WIZCHIP_READ(Sn_RX_RSR(sn)); + val1 = (val1 << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn), 1)); + if (val1 != 0) { + val = WIZCHIP_READ(Sn_RX_RSR(sn)); + val = (val << 8) + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RSR(sn), 1)); + } + } while (val != val1); + return val; +} + +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len) { + uint16_t ptr = 0; + uint32_t addrsel = 0; + + if (len == 0) + return; + ptr = getSn_TX_WR(sn); + // M20140501 : implict type casting -> explict type casting + // addrsel = (ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3); + addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_TXBUF_BLOCK(sn) << 3); + // + WIZCHIP_WRITE_BUF(addrsel, wizdata, len); + + ptr += len; + setSn_TX_WR(sn, ptr); +} + +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len) { + uint16_t ptr = 0; + uint32_t addrsel = 0; + + if (len == 0) + return; + ptr = getSn_RX_RD(sn); + // M20140501 : implict type casting -> explict type casting + // addrsel = ((ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3); + addrsel = ((uint32_t)ptr << 8) + (WIZCHIP_RXBUF_BLOCK(sn) << 3); + // + WIZCHIP_READ_BUF(addrsel, wizdata, len); + ptr += len; + + setSn_RX_RD(sn, ptr); +} + +void wiz_recv_ignore(uint8_t sn, uint16_t len) { + uint16_t ptr = 0; + + ptr = getSn_RX_RD(sn); + ptr += len; + setSn_RX_RD(sn, ptr); +} + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.c new file mode 100644 index 000000000..c424ed177 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.c @@ -0,0 +1,250 @@ + +#include "wiz_ping.h" + +#include +#include +#include +#include +#include + +#define Sn_PROTO(ch) (0x001408 + (ch << 5)) + +#define PING_BIND_PORT 3000 + +PINGMSGR PingRequest = {0}; +PINGMSGR PingReply = {0}; + +static uint16_t ping_RandomID = 0x1234; +static uint16_t ping_RandomSeqNum = 0x4321; +uint8_t ping_reply_received = 0; +uint8_t ping_req = 0; +uint8_t ping_rep = 0; +uint8_t ping_cnt = 0; +uint8_t ping_rep_buf[150] = {0}; + +// ping状态机 +#define PING_STA_FREE 0 +#define PING_STA_OPEN 1 +#define PING_STA_SEND 2 +#define PING_STA_WAIT 3 +#define PING_STA_CLOSE 4 + +uint8_t ping_sta = PING_STA_FREE; + +//当前ping的设备的序号 +uint8_t ping_socket = 0; + +#define bswap_16(A) ((((uint16)(A)&0xff00) >> 8) | (((uint16)(A)&0x00ff) << 8)) + +uint16_t htons(uint16_t n) { + union { + int i; + char c; + } u = {1}; + return u.c ? bswap_16(n) : n; +} + +uint16_t checksum(uint8_t *src, uint32_t len) { + uint16_t sum, tsum, i, j; + uint32_t lsum; + + j = len >> 1; + lsum = 0; + + for (i = 0; i < j; i++) { + tsum = src[i * 2]; + tsum = tsum << 8; + tsum += src[i * 2 + 1]; + lsum += tsum; + } + + if (len % 2) { + tsum = src[i * 2]; + lsum += (tsum << 8); + } + + sum = lsum; + sum = ~(sum + (lsum >> 16)); + return (uint16_t)sum; +} + +/** + *@brief 设定次数ping外网IP函数 + *@param sn- socket number + *@param addr- 外网IP地址 + *@param pCount- ping的次数 + *@return ping成功次数 + */ +uint8_t ping_count(uint8_t sn, uint16_t pCount, uint8_t *addr) { + uint16_t rlen, cnt, i; + + ping_reply_received = 0; + ping_req = 0; + ping_rep = 0; + KPrintf("Ping:%d.%d.%d.%d\r\n", (addr[0]), (addr[1]), (addr[2]), (addr[3])); + + for (i = 0; i < pCount + 1; i++) /*循环ping pCount次*/ + { + switch (getSn_SR(sn)) /*获取socket状态*/ + { + case SOCK_CLOSED: /*socket关闭状态*/ + { + wiz_sock_close(sn); + /* Create Socket */ + IINCHIP_WRITE(Sn_PROTO(sn), IPPROTO_ICMP); /*设置ICMP 协议*/ + if (wiz_socket(sn, Sn_MR_IPRAW, PING_BIND_PORT, 0) != + 0) /*判断ip raw模式socket是否开启*/ + { + } + /* Check socket register */ + while (getSn_SR(sn) != SOCK_IPRAW) { + MdelayKTask(50); + }; + break; + } + case SOCK_IPRAW: /*ip raw模式*/ + { + cnt = 0; + ping_request(sn, addr); /*发送Ping请求*/ + ping_req++; + while (1) { + if ((rlen = getSn_RX_RSR(sn)) > 0) { + rlen = ping_reply(sn, addr, rlen); /*获取回复信息*/ + ping_rep++; + if (ping_reply_received) { + break; + } + } + if ((cnt > 300)) { + cnt = 0; + break; + } else { + cnt++; + MdelayKTask(10); + } + } + break; + } + default: + break; + } + if (ping_req >= pCount) { + wiz_sock_close(sn); + } + } + return ping_rep; +} + +/** + *@brief ping请求函数 + *@param sn- socket number + *@param addr- P地址 + *@return 无 + */ +uint8_t ping_request(uint8_t sn, uint8_t *addr) { + uint8_t *buffer; + uint16_t i, temp_len = 0; + ping_reply_received = 0; /*ping 回复初始化标志位*/ + PingRequest.Type = PING_REQUEST; /*Ping-Request*/ + PingRequest.Code = CODE_ZERO; /*总是 '0'*/ + PingRequest.ID = htons(ping_RandomID++); /*设置ping响应ID为随机的整型变量*/ + PingRequest.SeqNum = + htons(ping_RandomSeqNum++); /*设置ping响应的序列号为随机整形变量*/ + for (i = 0; i < PING_BUF_LEN; i++) { + PingRequest.Data[i] = (i) % 8; /*ping相应的数在'0'~'8‘*/ + } + PingRequest.CheckSum = 0; + /* 计算响应次数*/ + PingRequest.CheckSum = + htons(checksum((uint8_t *)&PingRequest, sizeof(PingRequest))); + + /*发送ping响应到目的方 */ + if (wiz_sock_sendto(sn, (uint8_t *)&PingRequest, sizeof(PingRequest), addr, + PING_BIND_PORT) == 0) { + KPrintf("Fail to send ping-reply packet\r\n"); + } else { + KPrintf("ping send\n"); + } + return 0; +} + +/** + *@brief 解析Ping回复 + *@param sn- socket number + *@param addr- Ping地址 + *@return 无 + */ +uint8_t ping_reply(uint8_t sn, uint8_t *addr, uint16_t rlen) { + uint16_t tmp_checksum; + uint16_t len; + uint16_t i; + + uint16_t port = PING_BIND_PORT; + PINGMSGR PingReply; + + memset(ping_rep_buf, 0, sizeof(ping_rep_buf)); + len = wiz_sock_recvfrom(sn, ping_rep_buf, rlen, addr, + &port); /*从目的端接收数据*/ + + if (ping_rep_buf[0] == PING_REPLY) { + PingReply.Type = ping_rep_buf[0]; + PingReply.Code = ping_rep_buf[1]; + PingReply.CheckSum = (ping_rep_buf[3] << 8) + ping_rep_buf[2]; + PingReply.ID = (ping_rep_buf[5] << 8) + ping_rep_buf[4]; + PingReply.SeqNum = (ping_rep_buf[7] << 8) + ping_rep_buf[6]; + + for (i = 0; i < len - 8; i++) { + PingReply.Data[i] = ping_rep_buf[8 + i]; + } + tmp_checksum = ~checksum(ping_rep_buf, len); /*检查ping回复的次数*/ + if (tmp_checksum != 0xffff) { + KPrintf("tmp_checksum = %x\r\n", tmp_checksum); + } else { + KPrintf("Reply from %3d.%3d.%3d.%3d ID=%x Byte=%d\r\n\r\n", (addr[0]), + (addr[1]), (addr[2]), (addr[3]), htons(PingReply.ID), (rlen + 6)); + ping_reply_received = 1; /*当退出ping回复循环时,设置ping回复标志为1*/ + } + } else if (ping_rep_buf[0] == PING_REQUEST) { + PingReply.Code = ping_rep_buf[1]; + PingReply.Type = ping_rep_buf[2]; + PingReply.CheckSum = (ping_rep_buf[3] << 8) + ping_rep_buf[2]; + PingReply.ID = (ping_rep_buf[5] << 8) + ping_rep_buf[4]; + PingReply.SeqNum = (ping_rep_buf[7] << 8) + ping_rep_buf[6]; + for (i = 0; i < len - 8; i++) { + PingReply.Data[i] = ping_rep_buf[8 + i]; + } + tmp_checksum = PingReply.CheckSum; /*检查ping回复次数*/ + PingReply.CheckSum = 0; + if (tmp_checksum != PingReply.CheckSum) { + KPrintf(" \n CheckSum is in correct %x shold be %x \n", (tmp_checksum), + htons(PingReply.CheckSum)); + } else { + } + KPrintf( + " Request from %d.%d.%d.%d ID:%x SeqNum:%x :data size %d bytes\r\n", + (addr[0]), (addr[1]), (addr[2]), (addr[3]), (PingReply.ID), + (PingReply.SeqNum), (rlen + 6)); + ping_reply_received = 1; /* 当退出ping回复循环时,设置ping回复标志为1 + */ + } else { + KPrintf(" Unkonwn msg. \n"); + } + return 0; +} + +void wiz_ping_test(int argc, char *argv[]) { + uint32_t tmp_ip[4]; + uint8_t target_ip[4]; + if (argc >= 2) { + KPrintf("This is a Ping test: %s\n", argv[1]); + sscanf(argv[1], "%d.%d.%d.%d", &tmp_ip[0], &tmp_ip[1], &tmp_ip[2], + &tmp_ip[3]); + target_ip[0] = (uint8_t)tmp_ip[0]; + target_ip[1] = (uint8_t)tmp_ip[1]; + target_ip[2] = (uint8_t)tmp_ip[2]; + target_ip[3] = (uint8_t)tmp_ip[3]; + ping_count(ping_socket, 5, target_ip); + } +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + ping, wiz_ping_test, ping to given addr); \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.h new file mode 100644 index 000000000..3ead801b8 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_ping.h @@ -0,0 +1,35 @@ +#ifndef _WIZ_PING_H_ +#define _WIZ_PING_H_ + +#include "socket.h" +#include "w5500.h" + +#define PING_BUF_LEN 32 +#define PING_REQUEST 8 +#define PING_REPLY 0 +#define CODE_ZERO 0 + +#define SOCKET_ERROR 1 +#define TIMEOUT_ERROR 2 +#define SUCCESS 3 +#define REPLY_ERROR 4 + +typedef struct pingmsg { + uint8_t Type; // 0 - Ping Reply, 8 - Ping Request + uint8_t Code; // Always 0 + uint16_t CheckSum; // Check sum + uint16_t ID; // Identification + uint16_t SeqNum; // Sequence Number + int8_t Data[PING_BUF_LEN]; // Ping Data : 1452 = IP RAW MTU - + // sizeof(Type+Code+CheckSum+ID+SeqNum) +} PINGMSGR; + +uint8_t ping_count(uint8_t sn, uint16_t pCount, uint8_t *addr); + +uint8_t ping_request(uint8_t s, uint8_t *addr); + +uint8_t ping_reply(uint8_t s, uint8_t *addr, uint16_t rlen); + +void Ethernet_ping_service_deal(uint8_t sn); + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wizchip_conf.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wizchip_conf.c new file mode 100755 index 000000000..1407c852f --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wizchip_conf.c @@ -0,0 +1,862 @@ +//****************************************************************************/ +//! +//! \file wizchip_conf.c +//! \brief WIZCHIP Config Header File. +//! \version 1.0.1 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.1 Refer to M20140501 +//! 1. Explicit type casting in wizchip_bus_readdata() & +//! wizchip_bus_writedata() +// Issued by Mathias ClauBen. +//! uint32_t type converts into ptrdiff_t first. And then recoverting +//! it into uint8_t* For remove the warning when pointer type size is +//! not 32bit. If ptrdiff_t doesn't support in your complier, You +//! should must replace ptrdiff_t into your suitable pointer type. +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//*****************************************************************************/ +// A20140501 : for use the type - ptrdiff_t +#include +// + +#include "wizchip_conf.h" + +///////////// +// M20150401 : Remove ; in the default callback function such as +// wizchip_cris_enter(), wizchip_cs_select() and etc. +///////////// + +/** + * @brief Default function to enable interrupt. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_cris_enter(void) {}; +void wizchip_cris_enter(void) {} + +/** + * @brief Default function to disable interrupt. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_cris_exit(void) {}; +void wizchip_cris_exit(void) {} + +/** + * @brief Default function to select chip. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_cs_select(void) {}; +void wizchip_cs_select(void) {} + +/** + * @brief Default function to deselect chip. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_cs_deselect(void) {}; +void wizchip_cs_deselect(void) {} + +/** + * @brief Default function to read in direct or indirect interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// M20150601 : Rename the function for integrating with W5300 +// uint8_t wizchip_bus_readbyte(uint32_t AddrSel) { return * ((volatile uint8_t +// *)((ptrdiff_t) AddrSel)); } +iodata_t wizchip_bus_readdata(uint32_t AddrSel) { + return *((volatile iodata_t *)((ptrdiff_t)AddrSel)); +} + +/** + * @brief Default function to write in direct or indirect interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// M20150601 : Rename the function for integrating with W5300 +// void wizchip_bus_writebyte(uint32_t AddrSel, uint8_t wb) { *((volatile +// uint8_t*)((ptrdiff_t)AddrSel)) = wb; } +void wizchip_bus_writedata(uint32_t AddrSel, iodata_t wb) { + *((volatile iodata_t *)((ptrdiff_t)AddrSel)) = wb; +} + +/** + * @brief Default function to read in SPI interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// uint8_t wizchip_spi_readbyte(void) {return 0;}; +uint8_t wizchip_spi_readbyte(void) { return 0; } + +/** + * @brief Default function to write in SPI interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_spi_writebyte(uint8_t wb) {}; +void wizchip_spi_writebyte(uint8_t wb) {} + +/** + * @brief Default function to burst read in SPI interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_spi_readburst(uint8_t* pBuf, uint16_t len) {}; +void wizchip_spi_readburst(uint8_t *pBuf, uint16_t len) {} + +/** + * @brief Default function to burst write in SPI interface. + * @note This function help not to access wrong address. If you do not describe + * this function or register any functions, null function is called. + */ +// void wizchip_spi_writeburst(uint8_t* pBuf, uint16_t len) {}; +void wizchip_spi_writeburst(uint8_t *pBuf, uint16_t len) {} + +/** + * @\ref _WIZCHIP instance + */ +// +// M20150401 : For a compiler didnot support a member of structure +// Replace the assignment of struct members with the assingment of +// array +// +/* +_WIZCHIP WIZCHIP = + { + .id = _WIZCHIP_ID_, + .if_mode = _WIZCHIP_IO_MODE_, + .CRIS._enter = wizchip_cris_enter, + .CRIS._exit = wizchip_cris_exit, + .CS._select = wizchip_cs_select, + .CS._deselect = wizchip_cs_deselect, + .IF.BUS._read_byte = wizchip_bus_readbyte, + .IF.BUS._write_byte = wizchip_bus_writebyte +// .IF.SPI._read_byte = wizchip_spi_readbyte, +// .IF.SPI._write_byte = wizchip_spi_writebyte + }; +*/ +_WIZCHIP WIZCHIP = {_WIZCHIP_IO_MODE_, + _WIZCHIP_ID_, + {wizchip_cris_enter, wizchip_cris_exit}, + {wizchip_cs_select, wizchip_cs_deselect}, + { + {// M20150601 : Rename the function + // wizchip_bus_readbyte, + // wizchip_bus_writebyte + wizchip_bus_readdata, wizchip_bus_writedata}, + + }}; + +static uint8_t _DNS_[4]; // DNS server ip address +static dhcp_mode _DHCP_; // DHCP mode + +void reg_wizchip_cris_cbfunc(void (*cris_en)(void), void (*cris_ex)(void)) { + if (!cris_en || !cris_ex) { + WIZCHIP.CRIS._enter = wizchip_cris_enter; + WIZCHIP.CRIS._exit = wizchip_cris_exit; + } else { + WIZCHIP.CRIS._enter = cris_en; + WIZCHIP.CRIS._exit = cris_ex; + } +} + +void reg_wizchip_cs_cbfunc(void (*cs_sel)(void), void (*cs_desel)(void)) { + if (!cs_sel || !cs_desel) { + WIZCHIP.CS._select = wizchip_cs_select; + WIZCHIP.CS._deselect = wizchip_cs_deselect; + } else { + WIZCHIP.CS._select = cs_sel; + WIZCHIP.CS._deselect = cs_desel; + } +} + +// M20150515 : For integrating with W5300 +// void reg_wizchip_bus_cbfunc(uint8_t(*bus_rb)(uint32_t addr), void +// (*bus_wb)(uint32_t addr, uint8_t wb)) +void reg_wizchip_bus_cbfunc(iodata_t (*bus_rb)(uint32_t addr), + void (*bus_wb)(uint32_t addr, iodata_t wb)) { + while (!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_BUS_)) + ; + // M20150601 : Rename call back function for integrating with W5300 + /* + if(!bus_rb || !bus_wb) + { + WIZCHIP.IF.BUS._read_byte = wizchip_bus_readbyte; + WIZCHIP.IF.BUS._write_byte = wizchip_bus_writebyte; + } + else + { + WIZCHIP.IF.BUS._read_byte = bus_rb; + WIZCHIP.IF.BUS._write_byte = bus_wb; + } + */ + if (!bus_rb || !bus_wb) { + WIZCHIP.IF.BUS._read_data = wizchip_bus_readdata; + WIZCHIP.IF.BUS._write_data = wizchip_bus_writedata; + } else { + WIZCHIP.IF.BUS._read_data = bus_rb; + WIZCHIP.IF.BUS._write_data = bus_wb; + } +} + +void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), + void (*spi_wb)(uint8_t wb)) { + while (!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_)) + ; + + if (!spi_rb || !spi_wb) { + WIZCHIP.IF.SPI._read_byte = wizchip_spi_readbyte; + WIZCHIP.IF.SPI._write_byte = wizchip_spi_writebyte; + } else { + WIZCHIP.IF.SPI._read_byte = spi_rb; + WIZCHIP.IF.SPI._write_byte = spi_wb; + } +} + +// 20140626 Eric Added for SPI burst operations +void reg_wizchip_spiburst_cbfunc(void (*spi_rb)(uint8_t *pBuf, uint16_t len), + void (*spi_wb)(uint8_t *pBuf, uint16_t len)) { + while (!(WIZCHIP.if_mode & _WIZCHIP_IO_MODE_SPI_)) + ; + + if (!spi_rb || !spi_wb) { + WIZCHIP.IF.SPI._read_burst = wizchip_spi_readburst; + WIZCHIP.IF.SPI._write_burst = wizchip_spi_writeburst; + } else { + WIZCHIP.IF.SPI._read_burst = spi_rb; + WIZCHIP.IF.SPI._write_burst = spi_wb; + } +} + +int8_t ctlwizchip(ctlwizchip_type cwtype, void *arg) { +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500 + uint8_t tmp = 0; +#endif + uint8_t *ptmp[2] = {0, 0}; + switch (cwtype) { + case CW_RESET_WIZCHIP: + wizchip_sw_reset(); + break; + case CW_INIT_WIZCHIP: + if (arg != 0) { + ptmp[0] = (uint8_t *)arg; + ptmp[1] = ptmp[0] + _WIZCHIP_SOCK_NUM_; + } + return wizchip_init(ptmp[0], ptmp[1]); + case CW_CLR_INTERRUPT: + wizchip_clrinterrupt(*((intr_kind *)arg)); + break; + case CW_GET_INTERRUPT: + *((intr_kind *)arg) = wizchip_getinterrupt(); + break; + case CW_SET_INTRMASK: + wizchip_setinterruptmask(*((intr_kind *)arg)); + break; + case CW_GET_INTRMASK: + *((intr_kind *)arg) = wizchip_getinterruptmask(); + break; +// M20150601 : This can be supported by W5200, W5500 +//#if _WIZCHIP_ > W5100 +#if (_WIZCHIP_ == W5200 || _WIZCHIP_ == W5500) + case CW_SET_INTRTIME: + setINTLEVEL(*(uint16_t *)arg); + break; + case CW_GET_INTRTIME: + *(uint16_t *)arg = getINTLEVEL(); + break; +#endif + case CW_GET_ID: + ((uint8_t *)arg)[0] = WIZCHIP.id[0]; + ((uint8_t *)arg)[1] = WIZCHIP.id[1]; + ((uint8_t *)arg)[2] = WIZCHIP.id[2]; + ((uint8_t *)arg)[3] = WIZCHIP.id[3]; + ((uint8_t *)arg)[4] = WIZCHIP.id[4]; + ((uint8_t *)arg)[5] = WIZCHIP.id[5]; + ((uint8_t *)arg)[6] = 0; + break; +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 + case CW_RESET_PHY: + wizphy_reset(); + break; + case CW_SET_PHYCONF: + wizphy_setphyconf((wiz_PhyConf *)arg); + break; + case CW_GET_PHYCONF: + wizphy_getphyconf((wiz_PhyConf *)arg); + break; + case CW_GET_PHYSTATUS: + break; + case CW_SET_PHYPOWMODE: + return wizphy_setphypmode(*(uint8_t *)arg); +#endif +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500 + case CW_GET_PHYPOWMODE: + tmp = wizphy_getphypmode(); + if ((int8_t)tmp == -1) + return -1; + *(uint8_t *)arg = tmp; + break; + case CW_GET_PHYLINK: + tmp = wizphy_getphylink(); + if ((int8_t)tmp == -1) + return -1; + *(uint8_t *)arg = tmp; + break; +#endif + default: + return -1; + } + return 0; +} + +int8_t ctlnetwork(ctlnetwork_type cntype, void *arg) { + + switch (cntype) { + case CN_SET_NETINFO: + wizchip_setnetinfo((wiz_NetInfo *)arg); + break; + case CN_GET_NETINFO: + wizchip_getnetinfo((wiz_NetInfo *)arg); + break; + case CN_SET_NETMODE: + return wizchip_setnetmode(*(netmode_type *)arg); + case CN_GET_NETMODE: + *(netmode_type *)arg = wizchip_getnetmode(); + break; + case CN_SET_TIMEOUT: + wizchip_settimeout((wiz_NetTimeout *)arg); + break; + case CN_GET_TIMEOUT: + wizchip_gettimeout((wiz_NetTimeout *)arg); + break; + default: + return -1; + } + return 0; +} + +void wizchip_sw_reset(void) { + uint8_t gw[4], sn[4], sip[4]; + uint8_t mac[6]; +// A20150601 +#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_ + uint16_t mr = (uint16_t)getMR(); + setMR(mr | MR_IND); +#endif + // + getSHAR(mac); + getGAR(gw); + getSUBR(sn); + getSIPR(sip); + setMR(MR_RST); + getMR(); // for delay +// A2015051 : For indirect bus mode +#if _WIZCHIP_IO_MODE_ == _WIZCHIP_IO_MODE_BUS_INDIR_ + setMR(mr | MR_IND); +#endif + // + setSHAR(mac); + setGAR(gw); + setSUBR(sn); + setSIPR(sip); +} + +int8_t wizchip_init(uint8_t *txsize, uint8_t *rxsize) { + int8_t i; +#if _WIZCHIP_ < W5200 + int8_t j; +#endif + int8_t tmp = 0; + wizchip_sw_reset(); + if (txsize) { + tmp = 0; +// M20150601 : For integrating with W5300 +#if _WIZCHIP_ == W5300 + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + if (txsize[i] >= 64) + return -1; // No use 64KB even if W5300 support max 64KB memory + // allocation + tmp += txsize[i]; + if (tmp > 128) + return -1; + } + if (tmp % 8) + return -1; +#else + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + tmp += txsize[i]; + +#if _WIZCHIP_ < W5200 // 2016.10.28 peter add condition for w5100 and w5100s + if (tmp > 8) + return -1; +#else + if (tmp > 16) + return -1; +#endif + } + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { +#if _WIZCHIP_ < W5200 // 2016.10.28 peter add condition for w5100 + j = 0; + while ((txsize[i] >> j != 1) && (txsize[i] != 0)) { + j++; + } + setSn_TXBUF_SIZE(i, j); +#else + setSn_TXBUF_SIZE(i, txsize[i]); +#endif + } + +#endif + } + + if (rxsize) { + tmp = 0; +#if _WIZCHIP_ == W5300 + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + if (rxsize[i] >= 64) + return -1; // No use 64KB even if W5300 support max 64KB memory + // allocation + tmp += rxsize[i]; + if (tmp > 128) + return -1; + } + if (tmp % 8) + return -1; +#else + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { + tmp += rxsize[i]; +#if _WIZCHIP_ < W5200 // 2016.10.28 peter add condition for w5100 and w5100s + if (tmp > 8) + return -1; +#else + if (tmp > 16) + return -1; +#endif + } + + for (i = 0; i < _WIZCHIP_SOCK_NUM_; i++) { +#if _WIZCHIP_ < W5200 // add condition for w5100 + j = 0; + while ((rxsize[i] >> j != 1) && (txsize[i] != 0)) { + j++; + } + setSn_RXBUF_SIZE(i, j); +#else + setSn_RXBUF_SIZE(i, rxsize[i]); +#endif + } +#endif + } + return 0; +} + +void wizchip_clrinterrupt(intr_kind intr) { + uint8_t ir = (uint8_t)intr; + uint8_t sir = (uint8_t)((uint16_t)intr >> 8); +#if _WIZCHIP_ < W5500 + ir |= (1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + ir |= (1 << 6); +#endif + +#if _WIZCHIP_ < W5200 + sir &= 0x0F; +#endif + +#if _WIZCHIP_ <= W5100S + ir |= sir; + setIR(ir); +// A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + setIR(((((uint16_t)ir) << 8) | (((uint16_t)sir) & 0x00FF))); +#else + setIR(ir); + // M20200227 : For clear + // setSIR(sir); + for (ir = 0; ir < 8; ir++) { + if (sir & (0x01 << ir)) + setSn_IR(ir, 0xff); + } + +#endif +} + +intr_kind wizchip_getinterrupt(void) { + uint8_t ir = 0; + uint8_t sir = 0; + uint16_t ret = 0; +#if _WIZCHIP_ <= W5100S + ir = getIR(); + sir = ir & 0x0F; +// A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + ret = getIR(); + ir = (uint8_t)(ret >> 8); + sir = (uint8_t)ret; +#else + ir = getIR(); + sir = getSIR(); +#endif + +// M20150601 : For Integrating with W5300 +//#if _WIZCHIP_ < W5500 +#if _WIZCHIP_ < W5200 + ir &= ~(1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + ir &= ~(1 << 6); +#endif + ret = sir; + ret = (ret << 8) + ir; + return (intr_kind)ret; +} + +void wizchip_setinterruptmask(intr_kind intr) { + uint8_t imr = (uint8_t)intr; + uint8_t simr = (uint8_t)((uint16_t)intr >> 8); +#if _WIZCHIP_ < W5500 + imr &= ~(1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + imr &= ~(1 << 6); +#endif + +#if _WIZCHIP_ < W5200 + simr &= 0x0F; + imr |= simr; + setIMR(imr); +// A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + setIMR(((((uint16_t)imr) << 8) | (((uint16_t)simr) & 0x00FF))); +#else + setIMR(imr); + setSIMR(simr); +#endif +} + +intr_kind wizchip_getinterruptmask(void) { + uint8_t imr = 0; + uint8_t simr = 0; + uint16_t ret = 0; +#if _WIZCHIP_ < W5200 + imr = getIMR(); + simr = imr & 0x0F; +// A20150601 : For integrating with W5300 +#elif _WIZCHIP_ == W5300 + ret = getIMR(); + imr = (uint8_t)(ret >> 8); + simr = (uint8_t)ret; +#else + imr = getIMR(); + simr = getSIMR(); +#endif + +#if _WIZCHIP_ < W5500 + imr &= ~(1 << 4); // IK_WOL +#endif +#if _WIZCHIP_ == W5200 + imr &= ~(1 << 6); // IK_DEST_UNREACH +#endif + ret = simr; + ret = (ret << 8) + imr; + return (intr_kind)ret; +} + +int8_t wizphy_getphylink(void) { + int8_t tmp = PHY_LINK_OFF; +#if _WIZCHIP_ == W5100S + if (getPHYSR() & PHYSR_LNK) + tmp = PHY_LINK_ON; +#elif _WIZCHIP_ == W5200 + if (getPHYSTATUS() & PHYSTATUS_LINK) + tmp = PHY_LINK_ON; +#elif _WIZCHIP_ == W5500 + if (getPHYCFGR() & PHYCFGR_LNK_ON) + tmp = PHY_LINK_ON; + +#else + tmp = -1; +#endif + return tmp; +} + +#if _WIZCHIP_ > W5100 + +int8_t wizphy_getphypmode(void) { + int8_t tmp = 0; +#if _WIZCHIP_ == W5200 + if (getPHYSTATUS() & PHYSTATUS_POWERDOWN) + tmp = PHY_POWER_DOWN; + else + tmp = PHY_POWER_NORM; +#elif _WIZCHIP_ == 5500 + if ((getPHYCFGR() & PHYCFGR_OPMDC_ALLA) == PHYCFGR_OPMDC_PDOWN) + tmp = PHY_POWER_DOWN; + else + tmp = PHY_POWER_NORM; +#else + tmp = -1; +#endif + return tmp; +} +#endif + +#if _WIZCHIP_ == W5100S +void wizphy_reset(void) { + uint16_t tmp = wiz_mdio_read(PHYMDIO_BMCR); + tmp |= BMCR_RESET; + wiz_mdio_write(PHYMDIO_BMCR, tmp); + while (wiz_mdio_read(PHYMDIO_BMCR) & BMCR_RESET) { + } +} + +void wizphy_setphyconf(wiz_PhyConf *phyconf) { + uint16_t tmp = wiz_mdio_read(PHYMDIO_BMCR); + if (phyconf->mode == PHY_MODE_AUTONEGO) + tmp |= BMCR_AUTONEGO; + else { + tmp &= ~BMCR_AUTONEGO; + if (phyconf->duplex == PHY_DUPLEX_FULL) { + tmp |= BMCR_DUP; + } else { + tmp &= ~BMCR_DUP; + } + if (phyconf->speed == PHY_SPEED_100) { + tmp |= BMCR_SPEED; + } else { + tmp &= ~BMCR_SPEED; + } + } + wiz_mdio_write(PHYMDIO_BMCR, tmp); +} + +void wizphy_getphyconf(wiz_PhyConf *phyconf) { + uint16_t tmp = 0; + tmp = wiz_mdio_read(PHYMDIO_BMCR); + phyconf->by = PHY_CONFBY_SW; + if (tmp & BMCR_AUTONEGO) { + phyconf->mode = PHY_MODE_AUTONEGO; + } else { + phyconf->mode = PHY_MODE_MANUAL; + if (tmp & BMCR_DUP) + phyconf->duplex = PHY_DUPLEX_FULL; + else + phyconf->duplex = PHY_DUPLEX_HALF; + if (tmp & BMCR_SPEED) + phyconf->speed = PHY_SPEED_100; + else + phyconf->speed = PHY_SPEED_10; + } +} + +int8_t wizphy_setphypmode(uint8_t pmode) { + uint16_t tmp = 0; + tmp = wiz_mdio_read(PHYMDIO_BMCR); + if (pmode == PHY_POWER_DOWN) { + tmp |= BMCR_PWDN; + } else { + tmp &= ~BMCR_PWDN; + } + wiz_mdio_write(PHYMDIO_BMCR, tmp); + tmp = wiz_mdio_read(PHYMDIO_BMCR); + if (pmode == PHY_POWER_DOWN) { + if (tmp & BMCR_PWDN) + return 0; + } else { + if ((tmp & BMCR_PWDN) != BMCR_PWDN) + return 0; + } + return -1; +} + +#endif +#if _WIZCHIP_ == W5500 +void wizphy_reset(void) { + uint8_t tmp = getPHYCFGR(); + tmp &= PHYCFGR_RST; + setPHYCFGR(tmp); + tmp = getPHYCFGR(); + tmp |= ~PHYCFGR_RST; + setPHYCFGR(tmp); +} + +void wizphy_setphyconf(wiz_PhyConf *phyconf) { + uint8_t tmp = 0; + if (phyconf->by == PHY_CONFBY_SW) + tmp |= PHYCFGR_OPMD; + else + tmp &= ~PHYCFGR_OPMD; + if (phyconf->mode == PHY_MODE_AUTONEGO) + tmp |= PHYCFGR_OPMDC_ALLA; + else { + if (phyconf->duplex == PHY_DUPLEX_FULL) { + if (phyconf->speed == PHY_SPEED_100) + tmp |= PHYCFGR_OPMDC_100F; + else + tmp |= PHYCFGR_OPMDC_10F; + } else { + if (phyconf->speed == PHY_SPEED_100) + tmp |= PHYCFGR_OPMDC_100H; + else + tmp |= PHYCFGR_OPMDC_10H; + } + } + setPHYCFGR(tmp); + wizphy_reset(); +} + +void wizphy_getphyconf(wiz_PhyConf *phyconf) { + uint8_t tmp = 0; + tmp = getPHYCFGR(); + phyconf->by = (tmp & PHYCFGR_OPMD) ? PHY_CONFBY_SW : PHY_CONFBY_HW; + switch (tmp & PHYCFGR_OPMDC_ALLA) { + case PHYCFGR_OPMDC_ALLA: + case PHYCFGR_OPMDC_100FA: + phyconf->mode = PHY_MODE_AUTONEGO; + break; + default: + phyconf->mode = PHY_MODE_MANUAL; + break; + } + switch (tmp & PHYCFGR_OPMDC_ALLA) { + case PHYCFGR_OPMDC_100FA: + case PHYCFGR_OPMDC_100F: + case PHYCFGR_OPMDC_100H: + phyconf->speed = PHY_SPEED_100; + break; + default: + phyconf->speed = PHY_SPEED_10; + break; + } + switch (tmp & PHYCFGR_OPMDC_ALLA) { + case PHYCFGR_OPMDC_100FA: + case PHYCFGR_OPMDC_100F: + case PHYCFGR_OPMDC_10F: + phyconf->duplex = PHY_DUPLEX_FULL; + break; + default: + phyconf->duplex = PHY_DUPLEX_HALF; + break; + } +} + +void wizphy_getphystat(wiz_PhyConf *phyconf) { + uint8_t tmp = getPHYCFGR(); + phyconf->duplex = + (tmp & PHYCFGR_DPX_FULL) ? PHY_DUPLEX_FULL : PHY_DUPLEX_HALF; + phyconf->speed = (tmp & PHYCFGR_SPD_100) ? PHY_SPEED_100 : PHY_SPEED_10; +} + +int8_t wizphy_setphypmode(uint8_t pmode) { + uint8_t tmp = 0; + tmp = getPHYCFGR(); + if ((tmp & PHYCFGR_OPMD) == 0) + return -1; + tmp &= ~PHYCFGR_OPMDC_ALLA; + if (pmode == PHY_POWER_DOWN) + tmp |= PHYCFGR_OPMDC_PDOWN; + else + tmp |= PHYCFGR_OPMDC_ALLA; + setPHYCFGR(tmp); + wizphy_reset(); + tmp = getPHYCFGR(); + if (pmode == PHY_POWER_DOWN) { + if (tmp & PHYCFGR_OPMDC_PDOWN) + return 0; + } else { + if (tmp & PHYCFGR_OPMDC_ALLA) + return 0; + } + return -1; +} +#endif + +void wizchip_setnetinfo(wiz_NetInfo *pnetinfo) { + setSHAR(pnetinfo->mac); + setGAR(pnetinfo->gw); + setSUBR(pnetinfo->sn); + setSIPR(pnetinfo->ip); + _DNS_[0] = pnetinfo->dns[0]; + _DNS_[1] = pnetinfo->dns[1]; + _DNS_[2] = pnetinfo->dns[2]; + _DNS_[3] = pnetinfo->dns[3]; + _DHCP_ = pnetinfo->dhcp; +} + +void wizchip_getnetinfo(wiz_NetInfo *pnetinfo) { + getSHAR(pnetinfo->mac); + getGAR(pnetinfo->gw); + getSUBR(pnetinfo->sn); + getSIPR(pnetinfo->ip); + pnetinfo->dns[0] = _DNS_[0]; + pnetinfo->dns[1] = _DNS_[1]; + pnetinfo->dns[2] = _DNS_[2]; + pnetinfo->dns[3] = _DNS_[3]; + pnetinfo->dhcp = _DHCP_; +} + +int8_t wizchip_setnetmode(netmode_type netmode) { + uint8_t tmp = 0; +#if _WIZCHIP_ != W5500 + if (netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK)) + return -1; +#else + if (netmode & ~(NM_WAKEONLAN | NM_PPPOE | NM_PINGBLOCK | NM_FORCEARP)) + return -1; +#endif + tmp = getMR(); + tmp |= (uint8_t)netmode; + setMR(tmp); + return 0; +} + +netmode_type wizchip_getnetmode(void) { return (netmode_type)getMR(); } + +void wizchip_settimeout(wiz_NetTimeout *nettime) { + setRCR(nettime->retry_cnt); + setRTR(nettime->time_100us); +} + +void wizchip_gettimeout(wiz_NetTimeout *nettime) { + nettime->retry_cnt = getRCR(); + nettime->time_100us = getRTR(); +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/Kconfig new file mode 100644 index 000000000..35dce7392 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/Kconfig @@ -0,0 +1,11 @@ +config PIN_BUS_NAME + string "pin bus name" + default "pin" + +config PIN_DRIVER_NAME + string "pin driver name" + default "pin_drv" + +config PIN_DEVICE_NAME + string "pin device name" + default "pin_dev" diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/Makefile new file mode 100644 index 000000000..e017f0794 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/Makefile @@ -0,0 +1,8 @@ +SRC_FILES := connect_gpio.c drv_io_config.c fpioa.c gpio.c gpiohs.c utils.c + + + + + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/connect_gpio.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/connect_gpio.c new file mode 100644 index 000000000..9543ef775 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/connect_gpio.c @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-19 ZYH first version + */ + +/** +* @file connect_gpio.c +* @brief support gpio function using bus driver framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +/************************************************* +File name: connect_gpio.c +Description: support gpio configure and register to bus framework +Others: take RT-Thread v4.0.2/bsp/k210/driver/drv_gpio.c for references + https://github.com/RT-Thread/rt-thread/tree/v4.0.2 +History: +1. Date: 2022-10-17 +Author: AIIT XUOS Lab +Modification: add bus driver framework support for gpio +*************************************************/ + +#include +#include +#include +#include +#include "drv_io_config.h" +#include +#include +#include "connect_gpio.h" + +#define FUNC_GPIOHS(n) (FUNC_GPIOHS0 + n) + +static int pin_alloc_table[FPIOA_NUM_IO]; +static uint32_t free_pin = 0; + +static int AllocPinChannel(x_base pin_index) +{ + if (free_pin == 31) { + SYS_ERR("no free gpiohs channel to alloc"); + return -1; + } + + if (pin_alloc_table[pin_index] != -1) { + SYS_WARN("already alloc gpiohs channel for pin %d", pin_index); + return pin_alloc_table[pin_index]; + } + + pin_alloc_table[pin_index] = free_pin; + free_pin++; + + FpioaSetFunction(pin_index, FUNC_GPIOHS(pin_alloc_table[pin_index])); + return pin_alloc_table[pin_index]; +} + +static int GetPinChannel(x_base pin_index) +{ + return pin_alloc_table[pin_index]; +} + +static uint32 GpioConfigMode(int mode, uint8_t pin_channel) +{ + switch (mode) + { + case GPIO_CFG_OUTPUT: + gpiohs_set_drive_mode(pin_channel, GPIO_DM_OUTPUT); + break; + case GPIO_CFG_INPUT: + gpiohs_set_drive_mode(pin_channel, GPIO_DM_INPUT); + break; + case GPIO_CFG_INPUT_PULLUP: + gpiohs_set_drive_mode(pin_channel, GPIO_DM_INPUT_PULL_UP); + break; + case GPIO_CFG_INPUT_PULLDOWN: + gpiohs_set_drive_mode(pin_channel, GPIO_DM_INPUT_PULL_DOWN); + break; + case GPIO_CFG_OUTPUT_OD: + break; + default: + break; + } + return EOK; + +} + +static struct +{ + void (*hdr)(void *args); + void *args; + GpioPinEdgeT edge; +} IrqTable[32]; + +static void pin_irq(int vector, void *param) +{ + int pin_channel = vector - IRQN_GPIOHS0_INTERRUPT; + if (IrqTable[pin_channel].edge & GPIO_PE_FALLING) { + set_gpio_bit(gpiohs->fall_ie.u32, pin_channel, 0); + set_gpio_bit(gpiohs->fall_ip.u32, pin_channel, 1); + set_gpio_bit(gpiohs->fall_ie.u32, pin_channel, 1); + } + + if (IrqTable[pin_channel].edge & GPIO_PE_RISING) { + set_gpio_bit(gpiohs->rise_ie.u32, pin_channel, 0); + set_gpio_bit(gpiohs->rise_ip.u32, pin_channel, 1); + set_gpio_bit(gpiohs->rise_ie.u32, pin_channel, 1); + } + + if (IrqTable[pin_channel].edge & GPIO_PE_LOW) { + set_gpio_bit(gpiohs->low_ie.u32, pin_channel, 0); + set_gpio_bit(gpiohs->low_ip.u32, pin_channel, 1); + set_gpio_bit(gpiohs->low_ie.u32, pin_channel, 1); + } + + if (IrqTable[pin_channel].edge & GPIO_PE_HIGH) { + set_gpio_bit(gpiohs->high_ie.u32, pin_channel, 0); + set_gpio_bit(gpiohs->high_ip.u32, pin_channel, 1); + set_gpio_bit(gpiohs->high_ie.u32, pin_channel, 1); + } + + if (IrqTable[pin_channel].hdr) { + IrqTable[pin_channel].hdr(IrqTable[pin_channel].args); + } +} + +static uint32 GpioIrqRegister(int32 pin_channel, int32 mode, void (*hdr)(void *args), void *args) +{ + IrqTable[pin_channel].hdr = hdr; + IrqTable[pin_channel].args = args; + switch (mode) + { + case GPIO_IRQ_EDGE_RISING: + IrqTable[pin_channel].edge = GPIO_PE_RISING; + break; + case GPIO_IRQ_EDGE_FALLING: + IrqTable[pin_channel].edge = GPIO_PE_FALLING; + break; + case GPIO_IRQ_EDGE_BOTH: + IrqTable[pin_channel].edge = GPIO_PE_BOTH; + break; + case GPIO_IRQ_LEVEL_HIGH: + IrqTable[pin_channel].edge = GPIO_PE_LOW; + break; + case GPIO_IRQ_LEVEL_LOW: + IrqTable[pin_channel].edge = GPIO_PE_HIGH; + break; + default: + break; + } + gpiohs_set_pin_edge(pin_channel, IrqTable[pin_channel].edge); + + isrManager.done->registerIrq(IRQN_GPIOHS0_INTERRUPT + pin_channel, pin_irq, NONE); + + return EOK; +} + +static uint32 GpioIrqFree(int32 pin_channel) +{ + IrqTable[pin_channel].hdr = NONE; + IrqTable[pin_channel].args = NONE; + return EOK; +} + +static uint32 GpioIrqEnable(int32 pin_channel) +{ + isrManager.done->enableIrq(IRQN_GPIOHS0_INTERRUPT + pin_channel); + + return EOK; +} + +static uint32 GpioIrqDisable(int32 pin_channel) +{ + isrManager.done->disableIrq(IRQN_GPIOHS0_INTERRUPT + pin_channel); + return EOK; +} + +static uint32 PinConfigure(struct PinParam *param) +{ + NULL_PARAM_CHECK(param); + int ret = EOK; + + int pin_channel = GetPinChannel(param->pin); + if (pin_channel == -1) { + pin_channel = AllocPinChannel(param->pin); + if (pin_channel == -1) { + return ERROR; + } + } + + switch (param->cmd) + { + case GPIO_CONFIG_MODE: + GpioConfigMode(param->mode, pin_channel); + break; + case GPIO_IRQ_REGISTER: + ret = GpioIrqRegister(pin_channel,param->irq_set.irq_mode,param->irq_set.hdr,param->irq_set.args); + break; + case GPIO_IRQ_FREE: + ret = GpioIrqFree(pin_channel); + break; + case GPIO_IRQ_ENABLE: + ret = GpioIrqEnable(pin_channel); + break; + case GPIO_IRQ_DISABLE: + ret = GpioIrqDisable(pin_channel); + break; + default: + ret = -EINVALED; + break; + } + + return ret; +} + +static uint32 GpioDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + + x_err_t ret = EOK; + struct PinParam *param; + + switch (configure_info->configure_cmd) + { + case OPE_CFG: + param = (struct PinParam *)configure_info->private_data; + ret = PinConfigure(param); + break; + default: + break; + } + + return ret; +} + +uint32 PinWrite(void *dev, struct BusBlockWriteParam *write_param) +{ + NULL_PARAM_CHECK(dev); + NULL_PARAM_CHECK(write_param); + struct PinStat *pinstat = (struct PinStat *)write_param->buffer; + + int pin_channel = GetPinChannel(pinstat->pin); + if (pin_channel == -1) { + SYS_ERR("pin %d not set mode", pinstat->pin); + return ERROR; + } + gpiohs_set_pin(pin_channel, pinstat->val == GPIO_HIGH ? GPIO_PV_HIGH : GPIO_PV_LOW); +} + +uint32 PinRead(void *dev, struct BusBlockReadParam *read_param) +{ + NULL_PARAM_CHECK(dev); + NULL_PARAM_CHECK(read_param); + struct PinStat *pinstat = (struct PinStat *)read_param->buffer; + + int pin_channel = GetPinChannel(pinstat->pin); + if (pin_channel == -1) { + SYS_ERR("pin %d not set mode", pinstat->pin); + return ERROR; + } + + if (gpiohs_get_pin(pin_channel) == GPIO_PV_HIGH){ + pinstat->val = GPIO_HIGH; + return GPIO_HIGH; + } else { + pinstat->val = GPIO_LOW; + return GPIO_LOW; + } +} + +static const struct PinDevDone dev_done = +{ + .open = NONE, + .close = NONE, + .write = PinWrite, + .read = PinRead, +}; + +int HwGpioInit(void) +{ + x_err_t ret = EOK; + + static struct PinBus pin; + + memset(pin_alloc_table, -1, sizeof pin_alloc_table); + free_pin = GPIO_ALLOC_START; + + ret = PinBusInit(&pin, PIN_BUS_NAME); + if (ret != EOK) { + KPrintf("gpio bus init error %d\n", ret); + return ERROR; + } + + static struct PinDriver drv; + drv.configure = &GpioDrvConfigure; + + ret = PinDriverInit(&drv, PIN_DRIVER_NAME, NONE); + if (ret != EOK) { + KPrintf("pin driver init error %d\n", ret); + return -ERROR; + } + + ret = PinDriverAttachToBus(PIN_DRIVER_NAME, PIN_BUS_NAME); + if (ret != EOK) { + KPrintf("pin driver attach error %d\n", ret); + return -ERROR; + } + + static struct PinHardwareDevice dev; + dev.dev_done = &dev_done; + + ret = PinDeviceRegister(&dev, NONE, PIN_DEVICE_NAME); + if (ret != EOK) { + KPrintf("pin device register error %d\n", ret); + return -ERROR; + } + + ret = PinDeviceAttachToBus(PIN_DEVICE_NAME, PIN_BUS_NAME); + if (ret != EOK) { + KPrintf("pin device register error %d\n", ret); + return -ERROR; + } + + return ret; +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/drv_io_config.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/drv_io_config.c new file mode 100644 index 000000000..defc6e6b6 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/drv_io_config.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-19 ZYH first version + */ + +/** +* @file drv_io_config.c +* @brief support edu-riscv64-board io configure +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +/************************************************* +File name: drv_io_config.c +Description: support kd233-board io configure +Others: take RT-Thread v4.0.2/bsp/k210/driver/drv_io_config.c for references + https://github.com/RT-Thread/rt-thread/tree/v4.0.2 +History: +1. Date: 2022-10-17 +Author: AIIT XUOS Lab +Modification: support kd233-board io configure +*************************************************/ + +#include +#include +#include "drv_io_config.h" +#include + +#define HS_GPIO(n) (FUNC_GPIOHS0 + n) + +#define IOCONFIG(pin,func) {pin, func, #func} + +static struct io_config +{ + int io_num; + fpioa_function_t func; + const char * FuncName; +} io_config[] = +{ +#ifdef BSP_USING_LCD + IOCONFIG(BSP_LCD_CS_PIN, FUNC_SPI0_SS0), + IOCONFIG(BSP_LCD_WR_PIN, FUNC_SPI0_SCLK), + IOCONFIG(BSP_LCD_DC_PIN, HS_GPIO(FPIOA_LCD_DC)), + IOCONFIG(BSP_LCD_RST_PIN, HS_GPIO(FPIOA_LCD_RST)), +#endif + +#ifdef BSP_USING_SPI1 + IOCONFIG(BSP_SPI1_CLK_PIN, FUNC_SPI1_SCLK), + IOCONFIG(BSP_SPI1_D0_PIN, FUNC_SPI1_D0), + IOCONFIG(BSP_SPI1_D1_PIN, FUNC_SPI1_D1), +#ifdef BSP_USING_SPI1_AS_QSPI + IOCONFIG(BSP_SPI1_D2_PIN, FUNC_SPI1_D2), + IOCONFIG(BSP_SPI1_D3_PIN, FUNC_SPI1_D3), +#endif +#ifdef BSP_SPI1_USING_SS0 + IOCONFIG(BSP_SPI1_SS0_PIN, HS_GPIO(SPI1_CS0_PIN)), +#endif +#endif + +#ifdef BSP_USING_UART1 + IOCONFIG(BSP_UART1_TXD_PIN, FUNC_UART1_TX), + IOCONFIG(BSP_UART1_RXD_PIN, FUNC_UART1_RX), +#endif +#ifdef BSP_USING_UART2 + IOCONFIG(BSP_UART2_TXD_PIN, FUNC_UART2_TX), + IOCONFIG(BSP_UART2_RXD_PIN, FUNC_UART2_RX), +#endif +#ifdef BSP_USING_UART3 + IOCONFIG(BSP_UART3_TXD_PIN, FUNC_UART3_RX), + IOCONFIG(BSP_UART3_RXD_PIN, FUNC_UART3_TX), +#endif +#ifdef BSP_USING_I2C + IOCONFIG(BSP_I2C_SDA, FUNC_GPIO3), + IOCONFIG(BSP_I2C_SCL, FUNC_GPIO4), +#endif +#ifdef BSP_USING_TOUCH + // IOCONFIG(BSP_TOUCH_TP_INT, HS_GPIO(FPIOA_TOUCH_TP_INT)), + IOCONFIG(BSP_TOUCH_TP_INT, HS_GPIO(FUNC_GPIOHS30)), +#endif + +#ifdef BSP_USING_CH438 + IOCONFIG(BSP_CH438_ALE_PIN, HS_GPIO(FPIOA_CH438_ALE)), + IOCONFIG(BSP_CH438_NWR_PIN, HS_GPIO(FPIOA_CH438_NWR)), + IOCONFIG(BSP_CH438_NRD_PIN, HS_GPIO(FPIOA_CH438_NRD)), + IOCONFIG(BSP_CH438_INT_PIN, HS_GPIO(FPIOA_CH438_INT)), + IOCONFIG(BSP_CH438_D0_PIN, HS_GPIO(FPIOA_CH438_D0)), + IOCONFIG(BSP_CH438_D1_PIN, HS_GPIO(FPIOA_CH438_D1)), + IOCONFIG(BSP_CH438_D2_PIN, HS_GPIO(FPIOA_CH438_D2)), + IOCONFIG(BSP_CH438_D3_PIN, HS_GPIO(FPIOA_CH438_D3)), + IOCONFIG(BSP_CH438_D4_PIN, HS_GPIO(FPIOA_CH438_D4)), + IOCONFIG(BSP_CH438_D5_PIN, HS_GPIO(FPIOA_CH438_D5)), + IOCONFIG(BSP_CH438_D6_PIN, HS_GPIO(FPIOA_CH438_D6)), + IOCONFIG(BSP_CH438_D7_PIN, HS_GPIO(FPIOA_CH438_D7)), +#endif + +#ifdef BSP_USING_SOFT_SPI + IOCONFIG(BSP_SOFT_SPI_SCK_PIN, HS_GPIO(FPIOA_SOFT_SPI_SCK)), + IOCONFIG(BSP_SOFT_SPI_MIOS_PIN, HS_GPIO(FPIOA_SOFT_SPI_MIOS)), + IOCONFIG(BSP_SOFT_SPI_MSOI_PIN, HS_GPIO(FPIOA_SOFT_SPI_MSOI)), + IOCONFIG(BSP_SOFT_SPI_NCS_PIN, HS_GPIO(FPIOA_SOFT_SPI_NCS)), +#endif + +#ifdef BSP_USING_LORA + IOCONFIG(BSP_E220_M0_PIN, HS_GPIO(FUNC_GPIOHS10)), + IOCONFIG(BSP_E220_M1_PIN, HS_GPIO(FUNC_GPIOHS11)), +#endif + +#ifdef BSP_USING_RS485 + IOCONFIG(BSP_485_DIR_PIN,HS_GPIO(FUNC_GPIOHS12)); +#endif + +#ifdef BSP_USING_LED + IOCONFIG(BSP_LED_PIN,FUNC_GPIO5); +#endif + +#ifdef BSP_USING_KEY + IOCONFIG(BSP_KEY_PIN,FUNC_GPIO6); +#endif +}; + +static int PrintIoConfig() +{ + int i; + KPrintf("IO Configuration Table\n"); + KPrintf("┌───────┬────────────────────────┐\n"); + KPrintf("│Pin │Function │\n"); + KPrintf("├───────┼────────────────────────┤\n"); + for(i = 0; i < sizeof io_config / sizeof io_config[0]; i++) + { + KPrintf("│%-2d │%-24.24s│\n", io_config[i].io_num, io_config[i].FuncName); + } + KPrintf("└───────┴────────────────────────┘\n"); + return 0; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0), + io,PrintIoConfig,print io config); + +int IoConfigInit(void) +{ + int count = sizeof(io_config) / sizeof(io_config[0]); + int i; + int ret = 0; + + sysctl_set_power_mode(SYSCTL_POWER_BANK0, SYSCTL_POWER_V18); + sysctl_set_power_mode(SYSCTL_POWER_BANK1, SYSCTL_POWER_V18); + sysctl_set_power_mode(SYSCTL_POWER_BANK2, SYSCTL_POWER_V18); +#ifdef BSP_USING_UART2 + // for IO-27/28 + sysctl_set_power_mode(SYSCTL_POWER_BANK4, SYSCTL_POWER_V33); +#endif +#if defined(BSP_USING_UART1) || defined(BSP_USING_UART3) + // for IO-20~23 + sysctl_set_power_mode(SYSCTL_POWER_BANK3, SYSCTL_POWER_V33); +#endif + + for(i = 0; i < count; i++) + { + ret = FpioaSetFunction(io_config[i].io_num, io_config[i].func); + if(ret != 0) + return ret; + } + + return ret; +} + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/fpioa.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/fpioa.c new file mode 100644 index 000000000..f4edeb31d --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/fpioa.c @@ -0,0 +1,5439 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"}, + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file fpioa.c +* @brief add from Canaan K210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#include +#include +#include "sysctl.h" +#include "fpioa.h" + +volatile fpioa_t *const fpioa = (volatile fpioa_t *)FPIOA_BASE_ADDR; + +/** + * @brief Internal used FPIOA function initialize cell + * + * This is NOT fpioa_io_config_t, can't assign directly + * + */ +typedef struct _fpioa_assign_t +{ + uint32_t ch_sel : 8; + /* Channel select from 256 input. */ + uint32_t ds : 4; + /* Driving selector. */ + uint32_t oe_en : 1; + /* Static output enable, will AND with OE_INV. */ + uint32_t oe_inv : 1; + /* Invert output enable. */ + uint32_t do_sel : 1; + /* Data output select: 0 for DO, 1 for OE. */ + uint32_t do_inv : 1; + /* Invert the result of data output select (DO_SEL). */ + uint32_t pu : 1; + /* Pull up enable. 0 for nothing, 1 for pull up. */ + uint32_t pd : 1; + /* Pull down enable. 0 for nothing, 1 for pull down. */ + uint32_t resv0 : 1; + /* Reserved bits. */ + uint32_t sl : 1; + /* Slew rate control enable. */ + uint32_t ie_en : 1; + /* Static input enable, will AND with IE_INV. */ + uint32_t ie_inv : 1; + /* Invert input enable. */ + uint32_t di_inv : 1; + /* Invert Data input. */ + uint32_t st : 1; + /* Schmitt trigger. */ + uint32_t tie_en : 1; + /* Input tie enable, 1 for enable, 0 for disable. */ + uint32_t tie_val : 1; + /* Input tie value, 1 for high, 0 for low. */ + uint32_t resv1 : 5; + /* Reserved bits. */ + uint32_t pad_di : 1; + /* Read current PAD's data input. */ +} __attribute__((packed, aligned(4))) fpioa_assign_t; + +/* Function list */ +static const fpioa_assign_t function_config[FUNC_MAX] = +{ + { + .ch_sel = FUNC_JTAG_TCLK, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_JTAG_TDI, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_JTAG_TMS, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_JTAG_TDO, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI0_D0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI0_D1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI0_D2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI0_D3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI0_D4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI0_D5, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI0_D6, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI0_D7, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI0_SS0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI0_SS1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI0_SS2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI0_SS3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI0_ARB, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 1, + .tie_val = 1, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI0_SCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UARTHS_RX, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UARTHS_TX, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_RESV6, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_RESV7, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_CLK_SPI1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_CLK_I2C1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS5, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS6, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS7, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS8, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS9, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS10, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS11, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS12, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS13, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS14, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS15, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS16, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS17, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS18, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS19, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS20, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS21, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS22, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS23, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS24, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS25, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS26, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS27, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS28, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS29, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS30, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIOHS31, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIO0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIO1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIO2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIO3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIO4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIO5, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIO6, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_GPIO7, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART1_RX, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART1_TX, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART2_RX, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART2_TX, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART3_RX, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART3_TX, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI1_D0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI1_D1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI1_D2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI1_D3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI1_D4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI1_D5, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI1_D6, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI1_D7, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI1_SS0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI1_SS1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI1_SS2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI1_SS3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI1_ARB, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 1, + .tie_val = 1, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI1_SCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI_SLAVE_D0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI_SLAVE_SS, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SPI_SLAVE_SCLK, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S0_MCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S0_SCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S0_WS, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S0_IN_D0, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S0_IN_D1, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S0_IN_D2, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S0_IN_D3, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S0_OUT_D0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S0_OUT_D1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S0_OUT_D2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S0_OUT_D3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S1_MCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S1_SCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S1_WS, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S1_IN_D0, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S1_IN_D1, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S1_IN_D2, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S1_IN_D3, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S1_OUT_D0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S1_OUT_D1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S1_OUT_D2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S1_OUT_D3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S2_MCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S2_SCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S2_WS, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S2_IN_D0, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S2_IN_D1, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S2_IN_D2, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S2_IN_D3, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S2_OUT_D0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S2_OUT_D1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S2_OUT_D2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2S2_OUT_D3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_RESV0, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_RESV1, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_RESV2, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_RESV3, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_RESV4, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_RESV5, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2C0_SCLK, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2C0_SDA, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2C1_SCLK, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2C1_SDA, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2C2_SCLK, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_I2C2_SDA, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_CMOS_XCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_CMOS_RST, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_CMOS_PWDN, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_CMOS_VSYNC, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_CMOS_HREF, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_CMOS_PCLK, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_CMOS_D0, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_CMOS_D1, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_CMOS_D2, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_CMOS_D3, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_CMOS_D4, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_CMOS_D5, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_CMOS_D6, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_CMOS_D7, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SCCB_SCLK, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_SCCB_SDA, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART1_CTS, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART1_DSR, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART1_DCD, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART1_RI, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART1_SIR_IN, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART1_DTR, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART1_RTS, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART1_OUT2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART1_OUT1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART1_SIR_OUT, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART1_BAUD, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART1_RE, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART1_DE, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART1_RS485_EN, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART2_CTS, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART2_DSR, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART2_DCD, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART2_RI, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART2_SIR_IN, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART2_DTR, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART2_RTS, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART2_OUT2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART2_OUT1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART2_SIR_OUT, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART2_BAUD, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART2_RE, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART2_DE, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART2_RS485_EN, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART3_CTS, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART3_DSR, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART3_DCD, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART3_RI, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART3_SIR_IN, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART3_DTR, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART3_RTS, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART3_OUT2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART3_OUT1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART3_SIR_OUT, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART3_BAUD, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART3_RE, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART3_DE, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_UART3_RS485_EN, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_TIMER0_TOGGLE1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_TIMER0_TOGGLE2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_TIMER0_TOGGLE3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_TIMER0_TOGGLE4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_TIMER1_TOGGLE1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_TIMER1_TOGGLE2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_TIMER1_TOGGLE3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_TIMER1_TOGGLE4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_TIMER2_TOGGLE1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_TIMER2_TOGGLE2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_TIMER2_TOGGLE3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_TIMER2_TOGGLE4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_CLK_SPI2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_CLK_I2C2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_INTERNAL0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_INTERNAL1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_INTERNAL2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_INTERNAL3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_INTERNAL4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_INTERNAL5, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_INTERNAL6, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_INTERNAL7, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_INTERNAL8, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_INTERNAL9, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_INTERNAL10, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_INTERNAL11, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_INTERNAL12, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_INTERNAL13, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_INTERNAL14, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_INTERNAL15, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_INTERNAL16, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_INTERNAL17, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_CONSTANT, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_INTERNAL18, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG5, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG6, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG7, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG8, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG9, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG10, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG11, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG12, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG13, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG14, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG15, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG16, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG17, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG18, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG19, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG20, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG21, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG22, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG23, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG24, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG25, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG26, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG27, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG28, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG29, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG30, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, + { + .ch_sel = FUNC_DEBUG31, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0 + }, +}; + +int FpioaInit(void) +{ + int i = 0; + + /* Enable fpioa clock in system controller */ + sysctl_clock_enable(SYSCTL_CLOCK_FPIOA); + + /* Initialize tie */ + fpioa_tie_t tie = { 0 }; + + /* Set tie enable and tie value */ + for (i = 0; i < FUNC_MAX; i++) + { + tie.en[i / 32] |= (function_config[i].tie_en << (i % 32)); + tie.val[i / 32] |= (function_config[i].tie_val << (i % 32)); + } + + /* Atomic write every 32bit register to fpioa function */ + for (i = 0; i < FUNC_MAX / 32; i++) + { + /* Set value before enable */ + fpioa->tie.val[i] = tie.val[i]; + fpioa->tie.en[i] = tie.en[i]; + } + + return 0; +} + +int fpioa_get_io(int number, fpioa_io_config_t *cfg) +{ + /* Check parameters */ + if (number < 0 || number >= FPIOA_NUM_IO || cfg == NULL) + return -1; + /* Atomic read register */ + *cfg = fpioa->io[number]; + return 0; +} + +int fpioa_set_io(int number, fpioa_io_config_t *cfg) +{ + /* Check parameters */ + if (number < 0 || number >= FPIOA_NUM_IO || cfg == NULL) + return -1; + /* Atomic write register */ + fpioa->io[number] = *cfg; + return 0; +} + +int fpioa_set_io_pull(int number, fpioa_pull_t pull) +{ + /* Check parameters */ + if (number < 0 || number >= FPIOA_NUM_IO || pull >= FPIOA_PULL_MAX) + return -1; + + /* Atomic read register */ + fpioa_io_config_t cfg = fpioa->io[number]; + + switch (pull) + { + case FPIOA_PULL_NONE: + cfg.pu = 0; + cfg.pd = 0; + break; + case FPIOA_PULL_DOWN: + cfg.pu = 0; + cfg.pd = 1; + break; + case FPIOA_PULL_UP: + cfg.pu = 1; + cfg.pd = 0; + break; + default: + break; + } + /* Atomic write register */ + fpioa->io[number] = cfg; + return 0; +} + +int fpioa_get_io_pull(int number) +{ + /* Check parameters */ + if (number < 0 || number >= FPIOA_NUM_IO) + return -1; + + fpioa_pull_t pull; + /* Atomic read register */ + fpioa_io_config_t cfg = fpioa->io[number]; + + if (cfg.pu == 0 && cfg.pd == 1) + pull = FPIOA_PULL_DOWN; + else if (cfg.pu == 1 && cfg.pd == 0) + pull = FPIOA_PULL_UP; + else + pull = FPIOA_PULL_NONE; + return pull; +} + +int fpioa_set_io_driving(int number, fpioa_driving_t driving) +{ + /* Check parameters */ + if (number < 0 || number >= FPIOA_NUM_IO || driving >= FPIOA_DRIVING_MAX) + return -1; + + /* Atomic read register */ + fpioa_io_config_t cfg = fpioa->io[number]; + /* Set IO driving */ + cfg.ds = driving; + /* Atomic write register */ + fpioa->io[number] = cfg; + return 0; +} + +int fpioa_set_sl(int number, uint8_t sl_enable) +{ + /* Check parameters */ + if (number < 0 || number >= FPIOA_NUM_IO) + return -1; + + /* Atomic read register */ + fpioa_io_config_t cfg = fpioa->io[number]; + /* Set IO slew rate */ + cfg.sl = sl_enable; + /* Atomic write register */ + fpioa->io[number] = cfg; + return 0; +} + +int fpioa_set_st(int number, uint8_t st_enable) +{ + /* Check parameters */ + if (number < 0 || number >= FPIOA_NUM_IO) + return -1; + + /* Atomic read register */ + fpioa_io_config_t cfg = fpioa->io[number]; + /* Set IO schmitt trigger */ + cfg.st = st_enable; + /* Atomic write register */ + fpioa->io[number] = cfg; + return 0; +} + + +int fpioa_get_io_driving(int number) +{ + /* Check parameters */ + if (number < 0 || number >= FPIOA_NUM_IO) + return -1; + + return fpioa->io[number].ds; +} + +int fpioa_set_function_raw(int number, fpioa_function_t function) +{ + /* Check parameters */ + if (number < 0 || number >= FPIOA_NUM_IO || function < 0 || function >= FUNC_MAX) + return -1; + /* Atomic write register */ + fpioa->io[number] =(const fpioa_io_config_t) + { + .ch_sel = function_config[function].ch_sel, + .ds = function_config[function].ds, + .oe_en = function_config[function].oe_en, + .oe_inv = function_config[function].oe_inv, + .do_sel = function_config[function].do_sel, + .do_inv = function_config[function].do_inv, + .pu = function_config[function].pu, + .pd = function_config[function].pd, + .sl = function_config[function].sl, + .ie_en = function_config[function].ie_en, + .ie_inv = function_config[function].ie_inv, + .di_inv = function_config[function].di_inv, + .st = function_config[function].st, + /* resv and pad_di do not need initialization */ + }; + return 0; +} + +int FpioaSetFunction(int number, fpioa_function_t function) +{ + uint8_t index = 0; + /* Check parameters */ + if (number < 0 || number >= FPIOA_NUM_IO || function < 0 || function >= FUNC_MAX) + return -1; + if (function == FUNC_RESV0) + { + fpioa_set_function_raw(number, FUNC_RESV0); + return 0; + } + /* Compare all IO */ + for (index = 0; index < FPIOA_NUM_IO; index++) + { + if ((fpioa->io[index].ch_sel == function) && (index != number)) + fpioa_set_function_raw(index, FUNC_RESV0); + } + fpioa_set_function_raw(number, function); + return 0; +} + +int fpioa_set_tie_enable(fpioa_function_t function, int enable) +{ + /* Check parameters */ + if (function < 0 || function >= FUNC_MAX) + return -1; + /* Set tie enable */ + if (enable) + fpioa->tie.en[function / 32] |= (1UL << (function % 32)); + else + fpioa->tie.en[function / 32] &= (~(1UL << (function % 32))); + return 0; +} + +int fpioa_set_tie_value(fpioa_function_t function, int value) +{ + /* Check parameters */ + if (function < 0 || function >= FUNC_MAX) + return -1; + /* Set tie value */ + if (value) + fpioa->tie.val[function / 32] |= (1UL << (function % 32)); + else + fpioa->tie.val[function / 32] &= (~(1UL << (function % 32))); + return 0; +} + +int fpioa_get_io_by_function(fpioa_function_t function) +{ + int index = 0; + for (index = 0; index < FPIOA_NUM_IO; index++) + { + if (fpioa->io[index].ch_sel == function) + return index; + } + + return -1; +} diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/gpio.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/gpio.c new file mode 100644 index 000000000..db0ccca45 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/gpio.c @@ -0,0 +1,89 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"}, + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file gpio.c +* @brief add from Canaan K210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#include "gpio.h" +#include "utils.h" +#include "fpioa.h" +#include "sysctl.h" +#define GPIO_MAX_PINNO 8 + +volatile gpio_t* const gpio = (volatile gpio_t*)GPIO_BASE_ADDR; + +int gpio_init(void) +{ + return sysctl_clock_enable(SYSCTL_CLOCK_GPIO); +} + +void gpio_set_drive_mode(uint8_t pin, gpio_drive_mode_t mode) +{ + configASSERT(pin < GPIO_MAX_PINNO); + int io_number = fpioa_get_io_by_function(FUNC_GPIO0 + pin); + configASSERT(io_number >= 0); + + fpioa_pull_t pull; + uint32_t dir; + + switch (mode) + { + case GPIO_DM_INPUT: + pull = FPIOA_PULL_NONE; + dir = 0; + break; + case GPIO_DM_INPUT_PULL_DOWN: + pull = FPIOA_PULL_DOWN; + dir = 0; + break; + case GPIO_DM_INPUT_PULL_UP: + pull = FPIOA_PULL_UP; + dir = 0; + break; + case GPIO_DM_OUTPUT: + pull = FPIOA_PULL_DOWN; + dir = 1; + break; + default: + configASSERT(!"GPIO drive mode is not supported.") break; + } + + fpioa_set_io_pull(io_number, pull); + set_gpio_bit(gpio->direction.u32, pin, dir); +} + +gpio_pin_value_t gpio_get_pin(uint8_t pin) +{ + configASSERT(pin < GPIO_MAX_PINNO); + uint32_t dir = get_gpio_bit(gpio->direction.u32, pin); + volatile uint32_t *reg = dir ? gpio->data_output.u32 : gpio->data_input.u32; + return get_gpio_bit(reg, pin); +} + +void gpio_set_pin(uint8_t pin, gpio_pin_value_t value) +{ + configASSERT(pin < GPIO_MAX_PINNO); + uint32_t dir = get_gpio_bit(gpio->direction.u32, pin); + volatile uint32_t *reg = dir ? gpio->data_output.u32 : gpio->data_input.u32; + configASSERT(dir == 1); + set_gpio_bit(reg, pin, value); +} + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/gpiohs.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/gpiohs.c new file mode 100644 index 000000000..4259ae156 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/gpiohs.c @@ -0,0 +1,228 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"}, + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file gpiohs.c +* @brief add from Canaan K210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#include "gpiohs.h" +#include "utils.h" +#include "fpioa.h" +#include "sysctl.h" +#define GPIOHS_MAX_PINNO 32 + +volatile gpiohs_t* const gpiohs = (volatile gpiohs_t*)GPIOHS_BASE_ADDR; + +typedef struct _gpiohs_pin_instance +{ + size_t pin; + GpioPinEdgeT edge; + void (*callback)(); + plic_irq_callback_t gpiohs_callback; + void *context; +} gpiohs_pin_instance_t; + +static gpiohs_pin_instance_t pin_instance[32]; + +void gpiohs_set_drive_mode(uint8_t pin, gpio_drive_mode_t mode) +{ + configASSERT(pin < GPIOHS_MAX_PINNO); + int io_number = fpioa_get_io_by_function(FUNC_GPIOHS0 + pin); + configASSERT(io_number >= 0); + + fpioa_pull_t pull; + uint32_t dir; + + switch (mode) + { + case GPIO_DM_INPUT: + pull = FPIOA_PULL_NONE; + dir = 0; + break; + case GPIO_DM_INPUT_PULL_DOWN: + pull = FPIOA_PULL_DOWN; + dir = 0; + break; + case GPIO_DM_INPUT_PULL_UP: + pull = FPIOA_PULL_UP; + dir = 0; + break; + case GPIO_DM_OUTPUT: + pull = FPIOA_PULL_DOWN; + dir = 1; + break; + default: + configASSERT(!"GPIO drive mode is not supported.") break; + } + + fpioa_set_io_pull(io_number, pull); + volatile uint32_t *reg = dir ? gpiohs->output_en.u32 : gpiohs->input_en.u32; + volatile uint32_t *reg_d = !dir ? gpiohs->output_en.u32 : gpiohs->input_en.u32; + set_gpio_bit(reg_d, pin, 0); + set_gpio_bit(reg, pin, 1); +} + +gpio_pin_value_t gpiohs_get_pin(uint8_t pin) +{ + configASSERT(pin < GPIOHS_MAX_PINNO); + return get_gpio_bit(gpiohs->input_val.u32, pin); +} + +void gpiohs_set_pin(uint8_t pin, gpio_pin_value_t value) +{ + configASSERT(pin < GPIOHS_MAX_PINNO); + set_gpio_bit(gpiohs->output_val.u32, pin, value); +} + +void gpiohs_set_pin_edge(uint8_t pin, GpioPinEdgeT edge) +{ + set_gpio_bit(gpiohs->rise_ie.u32, pin, 0); + set_gpio_bit(gpiohs->rise_ip.u32, pin, 1); + + set_gpio_bit(gpiohs->fall_ie.u32, pin, 0); + set_gpio_bit(gpiohs->fall_ip.u32, pin, 1); + + set_gpio_bit(gpiohs->low_ie.u32, pin, 0); + set_gpio_bit(gpiohs->low_ip.u32, pin, 1); + + set_gpio_bit(gpiohs->high_ie.u32, pin, 0); + set_gpio_bit(gpiohs->high_ip.u32, pin, 1); + + if(edge & GPIO_PE_FALLING) + { + set_gpio_bit(gpiohs->fall_ie.u32, pin, 1); + } + else + { + set_gpio_bit(gpiohs->fall_ie.u32, pin, 0); + } + + if(edge & GPIO_PE_RISING) + { + set_gpio_bit(gpiohs->rise_ie.u32, pin, 1); + } + else + { + set_gpio_bit(gpiohs->rise_ie.u32, pin, 0); + } + + if(edge & GPIO_PE_LOW) + { + set_gpio_bit(gpiohs->low_ie.u32, pin, 1); + } + else + { + set_gpio_bit(gpiohs->low_ie.u32, pin, 0); + } + + if(edge & GPIO_PE_HIGH) + { + set_gpio_bit(gpiohs->high_ie.u32, pin, 1); + } + else + { + set_gpio_bit(gpiohs->high_ie.u32, pin, 0); + } + + pin_instance[pin].edge = edge; +} + +int gpiohs_pin_onchange_isr(void *userdata) +{ + gpiohs_pin_instance_t *ctx = (gpiohs_pin_instance_t *)userdata; + size_t pin = ctx->pin; + + if(ctx->edge & GPIO_PE_FALLING) + { + set_gpio_bit(gpiohs->fall_ie.u32, pin, 0); + set_gpio_bit(gpiohs->fall_ip.u32, pin, 1); + set_gpio_bit(gpiohs->fall_ie.u32, pin, 1); + } + + if(ctx->edge & GPIO_PE_RISING) + { + set_gpio_bit(gpiohs->rise_ie.u32, pin, 0); + set_gpio_bit(gpiohs->rise_ip.u32, pin, 1); + set_gpio_bit(gpiohs->rise_ie.u32, pin, 1); + } + + if(ctx->edge & GPIO_PE_LOW) + { + set_gpio_bit(gpiohs->low_ie.u32, pin, 0); + set_gpio_bit(gpiohs->low_ip.u32, pin, 1); + set_gpio_bit(gpiohs->low_ie.u32, pin, 1); + } + + if(ctx->edge & GPIO_PE_HIGH) + { + set_gpio_bit(gpiohs->high_ie.u32, pin, 0); + set_gpio_bit(gpiohs->high_ip.u32, pin, 1); + set_gpio_bit(gpiohs->high_ie.u32, pin, 1); + } + + if (ctx->callback) + ctx->callback(); + if(ctx->gpiohs_callback) + ctx->gpiohs_callback(ctx->context); + + return 0; +} + +void gpiohs_set_irq(uint8_t pin, uint32_t priority, void (*func)()) +{ + + pin_instance[pin].pin = pin; + pin_instance[pin].callback = func; + + plic_set_priority(IRQN_GPIOHS0_INTERRUPT + pin, priority); + plic_irq_register(IRQN_GPIOHS0_INTERRUPT + pin, gpiohs_pin_onchange_isr, &(pin_instance[pin])); + plic_irq_enable(IRQN_GPIOHS0_INTERRUPT + pin); +} + +void gpiohs_irq_register(uint8_t pin, uint32_t priority, plic_irq_callback_t callback, void *ctx) +{ + pin_instance[pin].pin = pin; + pin_instance[pin].gpiohs_callback = callback; + pin_instance[pin].context = ctx; + + plic_set_priority(IRQN_GPIOHS0_INTERRUPT + pin, priority); + plic_irq_register(IRQN_GPIOHS0_INTERRUPT + pin, gpiohs_pin_onchange_isr, &(pin_instance[pin])); + plic_irq_enable(IRQN_GPIOHS0_INTERRUPT + pin); +} + +void gpiohs_irq_unregister(uint8_t pin) +{ + pin_instance[pin] = (gpiohs_pin_instance_t){ + .callback = NULL, + .gpiohs_callback = NULL, + .context = NULL, + }; + set_gpio_bit(gpiohs->rise_ie.u32, pin, 0); + set_gpio_bit(gpiohs->fall_ie.u32, pin, 0); + set_gpio_bit(gpiohs->low_ie.u32, pin, 0); + set_gpio_bit(gpiohs->high_ie.u32, pin, 0); + plic_irq_unregister(IRQN_GPIOHS0_INTERRUPT + pin); +} + +void gpiohs_irq_disable(size_t pin) +{ + plic_irq_disable(IRQN_GPIOHS0_INTERRUPT + pin); +} + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/utils.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/utils.c new file mode 100644 index 000000000..13de0f277 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/gpio/utils.c @@ -0,0 +1,54 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"}, + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file utils.c +* @brief add from Canaan K210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-07-25 +*/ + +#include +#include "encoding.h" +#include "utils.h" + +void set_bit(volatile uint32_t *bits, uint32_t mask, uint32_t value) +{ + uint32_t org = (*bits) & ~mask; + *bits = org | (value & mask); +} + +void set_bit_offset(volatile uint32_t *bits, uint32_t mask, size_t offset, uint32_t value) +{ + set_bit(bits, mask << offset, value << offset); +} + +void set_gpio_bit(volatile uint32_t *bits, size_t offset, uint32_t value) +{ + set_bit_offset(bits, 1, offset, value); +} + +uint32_t get_bit(volatile uint32_t *bits, uint32_t mask, size_t offset) +{ + return ((*bits) & (mask << offset)) >> offset; +} + +uint32_t get_gpio_bit(volatile uint32_t *bits, size_t offset) +{ + return get_bit(bits, 1, offset); +} + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/i2c/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/i2c/Kconfig new file mode 100644 index 000000000..da6562c44 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/i2c/Kconfig @@ -0,0 +1,17 @@ +if BSP_USING_I2C + config BSP_I2C_SDA + int "SDA pin number for I2C" + default 15 + config BSP_I2C_SCL + int "SCLK pin number for I2C" + default 17 + config I2C_BUS_NAME_1 + string "i2c bus 1 name" + default "i2c1" + config I2C_DRV_NAME_1 + string "i2c bus 1 driver name" + default "i2c1_drv" + config I2C_1_DEVICE_NAME_0 + string "i2c bus 1 device 0 name" + default "i2c1_dev0" +endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/i2c/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/i2c/Makefile new file mode 100644 index 000000000..b2bf43649 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/i2c/Makefile @@ -0,0 +1,6 @@ +SRC_FILES := connect_i2c.c hardware_i2c.c + + + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/i2c/connect_i2c.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/i2c/connect_i2c.c new file mode 100644 index 000000000..3a24585a4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/i2c/connect_i2c.c @@ -0,0 +1,633 @@ +/* + * Copyright (c) 2020 RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2012-04-25 weety first version + */ + +/** +* @file connect_i2c.c +* @brief support kd233-board i2c function and register to bus framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +/************************************************* +File name: connect_i2c.c +Description: support edu-riscv64-board i2c configure and i2c bus register function +Others: take RT-Thread v4.0.2/components/drivers/i2c/i2c-bit-ops.c for references + https://github.com/RT-Thread/rt-thread/tree/v4.0.2 +History: +1. Date: 2022-10-17 +Author: AIIT XUOS Lab +Modification: +1. support edu-riscv64-board i2c bit configure, write and read +2. support edu-riscv64-board i2c bus device and driver register +*************************************************/ + +#include + #include "gpio_common.h" + #include"fpioa.h" +#include "connect_i2c.h" +#include +#include "sysctl.h" +#include "gpio.h" + +#ifndef BSP_USING_I2C1 +#define BSP_USING_I2C1 +#endif + +#define I2C_SDA_FUNC_GPIO 3 +#define I2C_SCL_FUNC_GPIO 4 + +static I2cBusParam i2c_bus_param = +{ + I2C_SDA_FUNC_GPIO, + I2C_SCL_FUNC_GPIO, +}; + +#define SET_SDA(done, val) done->SetSdaState(done->data, val) +#define SET_SCL(done, val) done->SetSclState(done->data, val) +#define GET_SDA(done) done->GetSdaState(done->data) +#define GET_SCL(done) done->GetSclState(done->data) +#define SdaLow(done) SET_SDA(done, 0) +#define SdaHigh(done) SET_SDA(done, 1) +#define SclLow(done) SET_SCL(done, 0) + +void I2cGpioInit(const I2cBusParam *bus_param) +{ + gpio_init (); + FpioaSetFunction(BSP_I2C_SDA , FUNC_GPIO3 );//RISC-V FPIOA CFG + FpioaSetFunction(BSP_I2C_SCL , FUNC_GPIO4 );//RISC-V FPIOA CFG + gpio_set_drive_mode(bus_param->i2c_sda_pin , GPIO_DM_OUTPUT ); + gpio_set_drive_mode(bus_param->i2c_scl_pin, GPIO_DM_OUTPUT ); + gpio_set_pin(bus_param->i2c_sda_pin , GPIO_PV_HIGH ); + gpio_set_pin(bus_param->i2c_scl_pin , GPIO_PV_HIGH ); +} + +static void SetSdaState(void *data, uint8 sda_state) +{ + I2cBusParam *bus_param = (I2cBusParam *)data; + if (sda_state) { + gpio_set_drive_mode(bus_param->i2c_sda_pin, GPIO_DM_OUTPUT ); + gpio_set_pin(bus_param->i2c_sda_pin , GPIO_PV_HIGH ); + } else { + gpio_set_drive_mode(bus_param->i2c_sda_pin, GPIO_DM_OUTPUT ); + gpio_set_pin(bus_param->i2c_sda_pin , GPIO_PV_LOW ); + } +} + +static void SetSclState(void *data, uint8 scl_state) +{ + I2cBusParam *bus_param = (I2cBusParam *)data; + if (scl_state) { + gpio_set_drive_mode(bus_param->i2c_scl_pin, GPIO_DM_OUTPUT ); + gpio_set_pin(bus_param->i2c_scl_pin , GPIO_PV_HIGH ); + } else { + gpio_set_drive_mode(bus_param->i2c_scl_pin, GPIO_DM_OUTPUT ); + gpio_set_pin(bus_param->i2c_scl_pin , GPIO_PV_LOW ); + } +} + +static uint8 GetSdaState(void *data) +{ + I2cBusParam *bus_param = (I2cBusParam *)data; + gpio_set_drive_mode (bus_param->i2c_sda_pin, GPIO_DM_INPUT_PULL_UP ); + return gpio_get_pin(bus_param->i2c_sda_pin); +} + +static uint8 GetSclState(void *data) +{ + I2cBusParam *bus_param = (I2cBusParam *)data; + gpio_set_drive_mode (bus_param->i2c_scl_pin, GPIO_DM_INPUT_PULL_UP ); + return gpio_get_pin(bus_param->i2c_scl_pin); +} + +static const struct I2cHalDrvDone I2cDrvDone = +{ + .data = (&i2c_bus_param), + .SetSdaState = SetSdaState, + .SetSclState = SetSclState, + .GetSdaState = GetSdaState, + .GetSclState = GetSclState, + .udelay = usleep, + .delay_us = 1, + .timeout = 100 +}; + +static x_err_t I2cBusReset(const I2cBusParam *bus_param) +{ + int32 i = 0; + gpio_set_drive_mode(bus_param->i2c_sda_pin, GPIO_DM_INPUT_PULL_UP ); + if (GPIO_LOW == gpio_get_pin(bus_param->i2c_sda_pin)) { + while (i++ < 9) { + gpio_set_drive_mode(bus_param->i2c_scl_pin, GPIO_DM_OUTPUT ); + gpio_set_pin(bus_param->i2c_scl_pin , GPIO_PV_HIGH ); + usleep(100); + gpio_set_pin(bus_param->i2c_scl_pin , GPIO_PV_LOW ); + usleep(100); + } + } + gpio_set_drive_mode(bus_param->i2c_sda_pin, GPIO_DM_INPUT_PULL_UP ); + if (GPIO_LOW == gpio_get_pin(bus_param->i2c_sda_pin)) { + return -ERROR; + } + return EOK; +} + +static __inline void I2cDelay(struct I2cHalDrvDone *done) +{ + done->udelay((done->delay_us + 1) >> 1); +} + +static __inline void I2cDelay2(struct I2cHalDrvDone *done) +{ + done->udelay(done->delay_us); +} + +static x_err_t SclHigh(struct I2cHalDrvDone *done) +{ + x_ticks_t start; + + SET_SCL(done, 1); + + if (!done->GetSclState) + goto done; + + start = CurrentTicksGain(); + while (!GET_SCL(done)) { + if ((CurrentTicksGain() - start) > done->timeout) + return -ETIMEOUT; + DelayKTask((done->timeout + 1) >> 1); + } + +done: + I2cDelay(done); + + return EOK; +} + +static void I2cStart(struct I2cHalDrvDone *done) +{ + SdaLow(done); + I2cDelay(done); + SclLow(done); +} + +static void I2cRestart(struct I2cHalDrvDone *done) +{ + SdaHigh(done); + SclHigh(done); + I2cDelay(done); + SdaLow(done); + I2cDelay(done); + SclLow(done); +} + +static void I2cStop(struct I2cHalDrvDone *done) +{ + SdaLow(done); + I2cDelay(done); + SclHigh(done); + I2cDelay(done); + SdaHigh(done); + I2cDelay2(done); +} + +static __inline x_bool I2cWaitack(struct I2cHalDrvDone *done) +{ + x_bool ack; + + SdaHigh(done); + GET_SDA(done); + I2cDelay(done); + + if (SclHigh(done) < 0) { + KPrintf("wait ack timeout"); + return -ETIMEOUT; + } + + ack = !GET_SDA(done); + + SclLow(done); + + return ack; +} + +static int32 I2cWriteb(struct I2cBus *bus, uint8 data) +{ + int32 i; + uint8 bit; + + struct I2cHalDrvDone *done = (struct I2cHalDrvDone *)bus->private_data; + + for (i = 7; i >= 0; i--) { + SclLow(done); + bit = (data >> i) & 1; + SET_SDA(done, bit); + I2cDelay(done); + if (SclHigh(done) < 0) { + KPrintf("I2cWriteb: 0x%02x, " + "wait scl pin high timeout at bit %d", + data, i); + + return -ETIMEOUT; + } + } + SclLow(done); + I2cDelay(done); + + return I2cWaitack(done); +} + +static int32 I2cReadb(struct I2cBus *bus) +{ + uint8 i; + uint8 data = 0; + struct I2cHalDrvDone *done = (struct I2cHalDrvDone *)bus->private_data; + + SdaHigh(done); + GET_SDA(done); + I2cDelay(done); + for (i = 0; i < 8; i++) { + data <<= 1; + + if (SclHigh(done) < 0) { + KPrintf("I2cReadb: wait scl pin high " + "timeout at bit %d", 7 - i); + + return -ETIMEOUT; + } + + if (GET_SDA(done)) + data |= 1; + SclLow(done); + I2cDelay2(done); + } + + return data; +} + +static x_size_t I2cSendBytes(struct I2cBus *bus, struct I2cDataStandard *msg) +{ + int32 ret; + x_size_t bytes = 0; + const uint8 *ptr = msg->buf; + int32 count = msg->len; + uint16 ignore_nack = msg->flags & I2C_IGNORE_NACK; + + while (count > 0) { + ret = I2cWriteb(bus, *ptr); + + if ((ret > 0) || (ignore_nack && (ret == 0))) { + count --; + ptr ++; + bytes ++; + } else if (ret == 0) { + return 0; + } else { + KPrintf("send bytes: error %d", ret); + + return ret; + } + } + + return bytes; +} + +static x_err_t I2cSendAckOrNack(struct I2cBus *bus, int ack) +{ + struct I2cHalDrvDone *done = (struct I2cHalDrvDone *)bus->private_data; + + if (ack) + SET_SDA(done, 0); + I2cDelay(done); + if (SclHigh(done) < 0) { + KPrintf("ACK or NACK timeout."); + + return -ETIMEOUT; + } + SclLow(done); + + return EOK; +} + +static x_size_t I2cRecvBytes(struct I2cBus *bus, struct I2cDataStandard *msg) +{ + int32 val; + int32 bytes = 0; + uint8 *ptr = msg->buf; + int32 count = msg->len; + const uint32 flags = msg->flags; + + while (count > 0) { + val = I2cReadb(bus); + if (val >= 0) { + *ptr = val; + bytes ++; + } else { + break; + } + + ptr ++; + count --; + + if (!(flags & I2C_NO_READ_ACK)) { + val = I2cSendAckOrNack(bus, count); + if (val < 0) + return val; + } + } + + return bytes; +} + +static int32 I2cSendAddress(struct I2cBus *bus, uint8 addr, int32 retries) +{ + struct I2cHalDrvDone *done = (struct I2cHalDrvDone *)bus->private_data; + int32 i; + x_err_t ret = 0; + + for (i = 0; i <= retries; i++) { + ret = I2cWriteb(bus, addr); + if (ret == 1 || i == retries) + break; + I2cStop(done); + I2cDelay2(done); + I2cStart(done); + } + + return ret; +} + +static x_err_t I2cBitSendAddress(struct I2cBus *bus, struct I2cDataStandard *msg) +{ + uint16 flags = msg->flags; + uint16 ignore_nack = msg->flags & I2C_IGNORE_NACK; + struct I2cHalDrvDone *done = (struct I2cHalDrvDone *)bus->private_data; + + uint8 addr1, addr2; + int32 retries; + x_err_t ret; + + retries = ignore_nack ? 0 : msg->retries; + + if (flags & I2C_ADDR_10BIT) { + addr1 = 0xf0 | ((msg->addr >> 7) & 0x06); + addr2 = msg->addr & 0xff; + + ret = I2cSendAddress(bus, addr1, retries); + if ((ret != 1) && !ignore_nack) { + + return -EPIO; + } + + ret = I2cWriteb(bus, addr2); + if ((ret != 1) && !ignore_nack) { + + return -EPIO; + } + + if (flags & I2C_RD) { + I2cRestart(done); + addr1 |= 0x01; + ret = I2cSendAddress(bus, addr1, retries); + if ((ret != 1) && !ignore_nack) { + + return -EPIO; + } + } + } else { + addr1 = msg->addr << 1; + if (flags & I2C_RD) + addr1 |= 1; + ret = I2cSendAddress(bus, addr1, retries); + if ((ret != 1) && !ignore_nack) + return -EPIO; + } + + return EOK; +} + +static uint32 I2cWriteData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg) +{ + struct I2cBus *bus = (struct I2cBus *)i2c_dev->haldev.owner_bus; + bus->private_data = i2c_dev->haldev.owner_bus->private_data; + struct I2cHalDrvDone *done = (struct I2cHalDrvDone *)bus->private_data; + int32 ret; + int32 i = 0; + uint16 ignore_nack; + + I2cStart(done); + while (NONE != msg) { + ignore_nack = msg->flags & I2C_IGNORE_NACK; + if (!(msg->flags & I2C_NO_START)) { + if (i) { + I2cRestart(done); + } + ret = I2cBitSendAddress(bus, msg); + if ((ret != EOK) && !ignore_nack) { + goto out; + } + } + + if (msg->flags == I2C_WR) { + ret = I2cSendBytes(bus, msg); + if (ret >= 1) + //KPrintf("write %d byte%s", ret, ret == 1 ? "" : "s"); + if (ret < msg->len) { + if (ret >= 0) + ret = -ERROR; + goto out; + } + } + msg = msg->next; + i++; + } + ret = i; + +out: + I2cStop(done); + + return ret; +} + +static uint32 I2cReadData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg) +{ + struct I2cBus *bus = (struct I2cBus *)i2c_dev->haldev.owner_bus; + bus->private_data = i2c_dev->haldev.owner_bus->private_data; + struct I2cHalDrvDone *done = (struct I2cHalDrvDone *)bus->private_data; + int32 ret; + int32 i = 0; + uint16 ignore_nack; + + I2cStart(done); + while (NONE != msg) { + ignore_nack = msg->flags & I2C_IGNORE_NACK; + if (!(msg->flags & I2C_NO_START)) { + if (i) { + I2cRestart(done); + } + + ret = I2cBitSendAddress(bus, msg); + if ((ret != EOK) && !ignore_nack) { + goto out; + } + } + + if (msg->flags & I2C_RD) { + ret = I2cRecvBytes(bus, msg); + if (ret >= 1) + //KPrintf("read %d byte%s", ret, ret == 1 ? "" : "s"); + if (ret < msg->len) { + if (ret >= 0) + ret = -EPIO; + goto out; + } + } + msg = msg->next; + i++; + } + ret = i; + +out: + I2cStop(done); + + return ret; +} + +static uint32 I2cInit(struct I2cDriver *i2c_drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(i2c_drv); + + struct I2cHardwareDevice *i2c_dev = (struct I2cHardwareDevice *)i2c_drv->driver.owner_bus->owner_haldev; + + if (configure_info->private_data) { + i2c_dev->i2c_dev_addr = *((uint16 *)configure_info->private_data); + return EOK; + } + + KPrintf("I2cInit need set i2c dev addr\n"); + return ERROR; +} + +static uint32 I2cDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + + x_err_t ret = EOK; + struct I2cDriver *i2c_drv = (struct I2cDriver *)drv; + + switch (configure_info->configure_cmd) + { + case OPE_INT: + ret = I2cInit(i2c_drv, configure_info); + break; + default: + break; + } + + return ret; +} + +/*manage the i2c device operations*/ +static const struct I2cDevDone i2c_dev_done = +{ + .dev_open = NONE, + .dev_close = NONE, + .dev_write = I2cWriteData, + .dev_read = I2cReadData, +}; + +/*Init i2c bus*/ +static int BoardI2cBusInit(struct I2cBus *i2c_bus, struct I2cDriver *i2c_driver) +{ + x_err_t ret = EOK; + + /*Init the i2c bus */ + i2c_bus->private_data = (void *)&I2cDrvDone; + ret = I2cBusInit(i2c_bus, I2C_BUS_NAME_1); + if (EOK != ret) { + KPrintf("board_i2c_init I2cBusInit error %d\n", ret); + return ERROR; + } + + /*Init the i2c driver*/ + i2c_driver->private_data = (void *)&I2cDrvDone; + ret = I2cDriverInit(i2c_driver, I2C_DRV_NAME_1); + if (EOK != ret) { + KPrintf("board_i2c_init I2cDriverInit error %d\n", ret); + return ERROR; + } + + /*Attach the i2c driver to the i2c bus*/ + ret = I2cDriverAttachToBus(I2C_DRV_NAME_1, I2C_BUS_NAME_1); + if (EOK != ret) { + KPrintf("board_i2c_init I2cDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +/*Attach the i2c device to the i2c bus*/ +static int BoardI2cDevBend(void) +{ + x_err_t ret = EOK; + static struct I2cHardwareDevice i2c_device0; + memset(&i2c_device0, 0, sizeof(struct I2cHardwareDevice)); + + i2c_device0.i2c_dev_done = &i2c_dev_done; + + ret = I2cDeviceRegister(&i2c_device0, NONE, I2C_1_DEVICE_NAME_0); + if (EOK != ret) { + KPrintf("board_i2c_init I2cDeviceInit device %s error %d\n", I2C_1_DEVICE_NAME_0, ret); + return ERROR; + } + + ret = I2cDeviceAttachToBus(I2C_1_DEVICE_NAME_0, I2C_BUS_NAME_1); + if (EOK != ret) { + KPrintf("board_i2c_init I2cDeviceAttachToBus device %s error %d\n", I2C_1_DEVICE_NAME_0, ret); + return ERROR; + } + + return ret; +} + +/*KD233 BOARD I2C INIT*/ +int HwI2cInit(void) +{ + x_err_t ret = EOK; + static struct I2cBus i2c_bus; + memset(&i2c_bus, 0, sizeof(struct I2cBus)); + + static struct I2cDriver i2c_driver; + memset(&i2c_driver, 0, sizeof(struct I2cDriver)); + +#ifdef BSP_USING_I2C1 + I2cGpioInit(&i2c_bus_param); + + i2c_driver.configure = I2cDrvConfigure; + + ret = BoardI2cBusInit(&i2c_bus, &i2c_driver); + if (EOK != ret) { + KPrintf("board_i2c_Init error ret %u\n", ret); + return ERROR; + } + + ret = BoardI2cDevBend(); + if (EOK != ret) { + KPrintf("board_i2c_Init error ret %u\n", ret); + return ERROR; + } + + I2cBusReset(&i2c_bus_param); +#endif + + return ret; +} diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/i2c/hardware_i2c.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/i2c/hardware_i2c.c new file mode 100644 index 000000000..9814147f9 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/i2c/hardware_i2c.c @@ -0,0 +1,371 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file hardware_i2c.c +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#include +#include "hardware_i2c.h" +#include "utils.h" +#include "fpioa.h" +#include "platform.h" +#include "stdlib.h" +#include "string.h" +#include "sysctl.h" +#include "bsp.h" + +typedef struct _i2c_slave_instance +{ + uint32_t i2c_num; + const i2c_slave_handler_t *slave_handler; +} i2c_slave_instance_t; + +static i2c_slave_instance_t slave_instance[I2C_MAX_NUM]; + +typedef struct _i2c_instance +{ + i2c_device_number_t i2c_num; + i2c_transfer_mode_t TransferMode; + dmac_channel_number_t dmac_channel; + plic_instance_t i2c_int_instance; + spinlock_t lock; +} i2c_instance_t; + +static i2c_instance_t g_i2c_instance[3]; + +volatile i2c_t* const i2c[3] = +{ + (volatile i2c_t*)I2C0_BASE_ADDR, + (volatile i2c_t*)I2C1_BASE_ADDR, + (volatile i2c_t*)I2C2_BASE_ADDR +}; + +static void i2c_clk_init(i2c_device_number_t i2c_num) +{ + configASSERT(i2c_num < I2C_MAX_NUM); + sysctl_clock_enable(SYSCTL_CLOCK_I2C0 + i2c_num); + sysctl_clock_set_threshold(SYSCTL_THRESHOLD_I2C0 + i2c_num, 3); +} + +void i2c_init(i2c_device_number_t i2c_num, uint32_t slave_address, uint32_t address_width, + uint32_t i2c_clk) +{ + configASSERT(i2c_num < I2C_MAX_NUM); + configASSERT(address_width == 7 || address_width == 10); + + volatile i2c_t *i2c_adapter = i2c[i2c_num]; + + i2c_clk_init(i2c_num); + + uint32_t v_i2c_freq = SysctlClockGetFreq(SYSCTL_CLOCK_I2C0 + i2c_num); + uint16_t v_period_clk_cnt = v_i2c_freq / i2c_clk / 2; + + if(v_period_clk_cnt == 0) + v_period_clk_cnt = 1; + + i2c_adapter->enable = 0; + i2c_adapter->con = I2C_CON_MASTER_MODE | I2C_CON_SLAVE_DISABLE | I2C_CON_RESTART_EN | + (address_width == 10 ? I2C_CON_10BITADDR_SLAVE : 0) | I2C_CON_SPEED(1); + i2c_adapter->ss_scl_hcnt = I2C_SS_SCL_HCNT_COUNT(v_period_clk_cnt); + i2c_adapter->ss_scl_lcnt = I2C_SS_SCL_LCNT_COUNT(v_period_clk_cnt); + + i2c_adapter->tar = I2C_TAR_ADDRESS(slave_address); + i2c_adapter->intr_mask = 0; + i2c_adapter->dma_cr = 0x3; + i2c_adapter->dma_rdlr = 0; + i2c_adapter->dma_tdlr = 4; + i2c_adapter->enable = I2C_ENABLE_ENABLE; +} + +static int i2c_slave_irq(void *userdata) +{ + i2c_slave_instance_t *instance = (i2c_slave_instance_t *)userdata; + volatile i2c_t *i2c_adapter = i2c[instance->i2c_num]; + uint32_t status = i2c_adapter->intr_stat; + if (status & I2C_INTR_STAT_START_DET) + { + instance->slave_handler->on_event(I2C_EV_START); + readl(&i2c_adapter->clr_start_det); + } + if (status & I2C_INTR_STAT_STOP_DET) + { + instance->slave_handler->on_event(I2C_EV_STOP); + readl(&i2c_adapter->clr_stop_det); + } + if (status & I2C_INTR_STAT_RX_FULL) + { + instance->slave_handler->on_receive(i2c_adapter->data_cmd); + } + if (status & I2C_INTR_STAT_RD_REQ) + { + i2c_adapter->data_cmd = instance->slave_handler->on_transmit(); + readl(&i2c_adapter->clr_rd_req); + } + return 0; +} + +void i2c_init_as_slave(i2c_device_number_t i2c_num, uint32_t slave_address, uint32_t address_width, + const i2c_slave_handler_t *handler) +{ + configASSERT(address_width == 7 || address_width == 10); + volatile i2c_t *i2c_adapter = i2c[i2c_num]; + slave_instance[i2c_num].i2c_num = i2c_num; + slave_instance[i2c_num].slave_handler = handler; + + i2c_clk_init(i2c_num); + i2c_adapter->enable = 0; + i2c_adapter->con = (address_width == 10 ? I2C_CON_10BITADDR_SLAVE : 0) | I2C_CON_SPEED(1) | I2C_CON_STOP_DET_IFADDRESSED; + i2c_adapter->ss_scl_hcnt = I2C_SS_SCL_HCNT_COUNT(37); + i2c_adapter->ss_scl_lcnt = I2C_SS_SCL_LCNT_COUNT(40); + i2c_adapter->sar = I2C_SAR_ADDRESS(slave_address); + i2c_adapter->rx_tl = I2C_RX_TL_VALUE(0); + i2c_adapter->tx_tl = I2C_TX_TL_VALUE(0); + i2c_adapter->intr_mask = I2C_INTR_MASK_RX_FULL | I2C_INTR_MASK_START_DET | I2C_INTR_MASK_STOP_DET | I2C_INTR_MASK_RD_REQ; + + plic_set_priority(IRQN_I2C0_INTERRUPT + i2c_num, 1); + plic_irq_register(IRQN_I2C0_INTERRUPT + i2c_num, i2c_slave_irq, slave_instance + i2c_num); + plic_irq_enable(IRQN_I2C0_INTERRUPT + i2c_num); + + i2c_adapter->enable = I2C_ENABLE_ENABLE; +} + +int i2c_send_data(i2c_device_number_t i2c_num, const uint8_t *SendBuf, size_t send_buf_len) +{ + configASSERT(i2c_num < I2C_MAX_NUM); + volatile i2c_t* i2c_adapter = i2c[i2c_num]; + size_t fifo_len, index; + i2c_adapter->clr_tx_abrt = i2c_adapter->clr_tx_abrt; + while (send_buf_len) + { + fifo_len = 8 - i2c_adapter->txflr; + fifo_len = send_buf_len < fifo_len ? send_buf_len : fifo_len; + for (index = 0; index < fifo_len; index++) + i2c_adapter->data_cmd = I2C_DATA_CMD_DATA(*SendBuf++); + if (i2c_adapter->tx_abrt_source != 0) + return 1; + send_buf_len -= fifo_len; + } + while ((i2c_adapter->status & I2C_STATUS_ACTIVITY) || !(i2c_adapter->status & I2C_STATUS_TFE)) + ; + + if (i2c_adapter->tx_abrt_source != 0) + return 1; + + return 0; +} + +void i2c_send_data_dma(dmac_channel_number_t dma_channel_num, i2c_device_number_t i2c_num, const uint8_t *SendBuf, + size_t send_buf_len) +{ + configASSERT(i2c_num < I2C_MAX_NUM); + volatile i2c_t* i2c_adapter = i2c[i2c_num]; + i2c_adapter->clr_tx_abrt = i2c_adapter->clr_tx_abrt; + uint32_t *buf = malloc(send_buf_len * sizeof(uint32_t)); + int i; + for (i = 0; i < send_buf_len; i++) + { + buf[i] = SendBuf[i]; + } + + sysctl_dma_select((sysctl_dma_channel_t)dma_channel_num, SYSCTL_DMA_SELECT_I2C0_TX_REQ + i2c_num * 2); + dmac_set_single_mode(dma_channel_num, buf, (void *)(&i2c_adapter->data_cmd), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, send_buf_len); + + dmac_wait_done(dma_channel_num); + free((void *)buf); + + while ((i2c_adapter->status & I2C_STATUS_ACTIVITY) || !(i2c_adapter->status & I2C_STATUS_TFE)) + { + if (i2c_adapter->tx_abrt_source != 0) + return; + } +} + +int i2c_recv_data(i2c_device_number_t i2c_num, const uint8_t *SendBuf, size_t send_buf_len, uint8_t *receive_buf, + size_t receive_buf_len) +{ + configASSERT(i2c_num < I2C_MAX_NUM); + + size_t fifo_len, index; + size_t rx_len = receive_buf_len; + volatile i2c_t* i2c_adapter = i2c[i2c_num]; + + while (send_buf_len) + { + fifo_len = 8 - i2c_adapter->txflr; + fifo_len = send_buf_len < fifo_len ? send_buf_len : fifo_len; + for (index = 0; index < fifo_len; index++) + i2c_adapter->data_cmd = I2C_DATA_CMD_DATA(*SendBuf++); + if (i2c_adapter->tx_abrt_source != 0) + return 1; + send_buf_len -= fifo_len; + } + + while (receive_buf_len || rx_len) + { + fifo_len = i2c_adapter->rxflr; + fifo_len = rx_len < fifo_len ? rx_len : fifo_len; + for (index = 0; index < fifo_len; index++) + *receive_buf++ = (uint8_t)i2c_adapter->data_cmd; + rx_len -= fifo_len; + fifo_len = 8 - i2c_adapter->txflr; + fifo_len = receive_buf_len < fifo_len ? receive_buf_len : fifo_len; + for (index = 0; index < fifo_len; index++) + i2c_adapter->data_cmd = I2C_DATA_CMD_CMD; + if (i2c_adapter->tx_abrt_source != 0) + return 1; + receive_buf_len -= fifo_len; + } + return 0; +} + +void i2c_recv_data_dma(dmac_channel_number_t dma_send_channel_num, dmac_channel_number_t dma_receive_channel_num, + i2c_device_number_t i2c_num, const uint8_t *SendBuf, size_t send_buf_len, + uint8_t *receive_buf, size_t receive_buf_len) +{ + configASSERT(i2c_num < I2C_MAX_NUM); + + volatile i2c_t* i2c_adapter = i2c[i2c_num]; + + uint32_t *write_cmd = malloc(sizeof(uint32_t) * (send_buf_len + receive_buf_len)); + size_t i; + for(i = 0; i < send_buf_len; i++) + write_cmd[i] = *SendBuf++; + for (i = 0; i < receive_buf_len; i++) + write_cmd[i + send_buf_len] = I2C_DATA_CMD_CMD; + + sysctl_dma_select((sysctl_dma_channel_t)dma_send_channel_num, SYSCTL_DMA_SELECT_I2C0_TX_REQ + i2c_num * 2); + sysctl_dma_select((sysctl_dma_channel_t)dma_receive_channel_num, SYSCTL_DMA_SELECT_I2C0_RX_REQ + i2c_num * 2); + + dmac_set_single_mode(dma_receive_channel_num, (void *)(&i2c_adapter->data_cmd), write_cmd, DMAC_ADDR_NOCHANGE, + DMAC_ADDR_INCREMENT,DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, receive_buf_len); + + dmac_set_single_mode(dma_send_channel_num, write_cmd, (void *)(&i2c_adapter->data_cmd), DMAC_ADDR_INCREMENT, + DMAC_ADDR_NOCHANGE,DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, receive_buf_len + send_buf_len); + + dmac_wait_done(dma_send_channel_num); + dmac_wait_done(dma_receive_channel_num); + + for (i = 0; i < receive_buf_len; i++) + { + receive_buf[i] = (uint8_t)write_cmd[i]; + } + + free(write_cmd); +} + +static int i2c_dma_irq(void *ctx) +{ + i2c_instance_t *v_instance = (i2c_instance_t *)ctx; + volatile i2c_t* i2c_adapter = i2c[v_instance->i2c_num]; + dmac_irq_unregister(v_instance->dmac_channel); + if(v_instance->TransferMode == I2C_SEND) + { + while ((i2c_adapter->status & I2C_STATUS_ACTIVITY) || !(i2c_adapter->status & I2C_STATUS_TFE)) + { + if (i2c_adapter->tx_abrt_source != 0) + { + spinlock_unlock(&v_instance->lock); + return -1; + } + } + } + spinlock_unlock(&v_instance->lock); + if(v_instance->i2c_int_instance.callback) + { + v_instance->i2c_int_instance.callback(v_instance->i2c_int_instance.ctx); + } + return 0; +} + +void i2c_handle_data_dma(i2c_device_number_t i2c_num, i2c_data_t data, plic_interrupt_t *cb) +{ + configASSERT(i2c_num < I2C_MAX_NUM); + configASSERT(data.tx_channel < DMAC_CHANNEL_MAX && data.rx_channel < DMAC_CHANNEL_MAX); + + spinlock_lock(&g_i2c_instance[i2c_num].lock); + if(cb) + { + g_i2c_instance[i2c_num].i2c_int_instance.callback = cb->callback; + g_i2c_instance[i2c_num].i2c_int_instance.ctx = cb->ctx; + } + + volatile i2c_t* i2c_adapter = i2c[i2c_num]; + if(data.TransferMode == I2C_SEND) + { + configASSERT(data.tx_buf && data.tx_len); + + i2c_adapter->clr_tx_abrt = i2c_adapter->clr_tx_abrt; + if(cb) + { + g_i2c_instance[i2c_num].dmac_channel = data.tx_channel; + g_i2c_instance[i2c_num].TransferMode = I2C_SEND; + dmac_irq_register(data.tx_channel, i2c_dma_irq, &g_i2c_instance[i2c_num], cb->priority); + } + sysctl_dma_select((sysctl_dma_channel_t)data.tx_channel, SYSCTL_DMA_SELECT_I2C0_TX_REQ + i2c_num * 2); + dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&i2c_adapter->data_cmd), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, data.tx_len); + if(!cb) + { + dmac_wait_done(data.tx_channel); + while ((i2c_adapter->status & I2C_STATUS_ACTIVITY) || !(i2c_adapter->status & I2C_STATUS_TFE)) + { + if (i2c_adapter->tx_abrt_source != 0) + configASSERT(!"source abort"); + } + } + } + else + { + configASSERT(data.rx_buf && data.rx_len); + if(data.tx_len) + configASSERT(data.tx_buf); + if(cb) + { + g_i2c_instance[i2c_num].dmac_channel = data.rx_channel; + g_i2c_instance[i2c_num].TransferMode = I2C_RECEIVE; + dmac_irq_register(data.rx_channel, i2c_dma_irq, &g_i2c_instance[i2c_num], cb->priority); + } + sysctl_dma_select((sysctl_dma_channel_t)data.rx_channel, SYSCTL_DMA_SELECT_I2C0_RX_REQ + i2c_num * 2); + dmac_set_single_mode(data.rx_channel, (void *)(&i2c_adapter->data_cmd), data.rx_buf, DMAC_ADDR_NOCHANGE, + DMAC_ADDR_INCREMENT,DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, data.rx_len); + + sysctl_dma_select((sysctl_dma_channel_t)data.tx_channel, SYSCTL_DMA_SELECT_I2C0_TX_REQ + i2c_num * 2); + if(data.tx_len) + { + configASSERT(data.tx_buf); + dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&i2c_adapter->data_cmd), DMAC_ADDR_INCREMENT, + DMAC_ADDR_NOCHANGE,DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, data.tx_len); + dmac_wait_done(data.tx_channel); + } + static uint32_t s_read_cmd = I2C_DATA_CMD_CMD; + dmac_set_single_mode(data.tx_channel, &s_read_cmd, (void *)(&i2c_adapter->data_cmd), DMAC_ADDR_NOCHANGE, + DMAC_ADDR_NOCHANGE,DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, data.rx_len); + + if(!cb) + { + dmac_wait_done(data.tx_channel); + dmac_wait_done(data.rx_channel); + } + } + if(!cb) + spinlock_unlock(&g_i2c_instance[i2c_num].lock); +} diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/clint.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/clint.h new file mode 100644 index 000000000..31370e071 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/clint.h @@ -0,0 +1,323 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file clint.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#ifndef __CLINT_H__ +#define __CLINT_H__ + +#include +#include +#include "platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* clang-format off */ +/* Register address offsets */ +#define CLINT_MSIP (0x0000) +#define CLINT_MSIP_SIZE (0x4) +#define CLINT_MTIMECMP (0x4000) +#define CLINT_MTIMECMP_SIZE (0x8) +#define CLINT_MTIME (0xBFF8) +#define CLINT_MTIME_SIZE (0x8) +/* Max number of cores */ +#define CLINT_MAX_CORES (4095) +/* Real number of cores */ +#define CLINT_NUM_CORES (2) +/* Clock frequency division factor */ +#define CLINT_CLOCK_DIV (50) +/* clang-format on */ + +/** + * @brief MSIP Registers + * + * Machine-mode software interrupts are generated by writing to a + * per-core memory-mapped control register. The msip registers are + * 32-bit wide WARL registers, where the LSB is reflected in the + * msip bit of the associated core’s mip register. Other bits in + * the msip registers are hardwired to zero. The mapping supports + * up to 4095 machine-mode cores. + */ +typedef struct _clint_msip +{ + uint32_t msip : 1; /*!< Bit 0 is msip */ + uint32_t zero : 31; /*!< Bits [32:1] is 0 */ +} __attribute__((packed, aligned(4))) clint_msip_t; + +/** + * @brief Timer compare Registers Machine-mode timer interrupts are + * generated by a real-time counter and a per-core comparator. The + * mtime register is a 64-bit read-only register that contains the + * current value of the real-time counter. Each mtimecmp register + * holds its core’s time comparator. A timer interrupt is pending + * whenever mtime is greater than or equal to the value in a + * core’s mtimecmp register. The timer interrupt is reflected in + * the mtip bit of the associated core’s mip register. + */ +typedef uint64_t clint_mtimecmp_t; + +/** + * @brief Timer Registers + * + * The mtime register has a 64-bit precision on all RV32, RV64, + * and RV128 systems. Platforms provide a 64-bit memory-mapped + * machine-mode timer compare register (mtimecmp), which causes a + * timer interrupt to be posted when the mtime register contains a + * value greater than or equal to the value in the mtimecmp + * register. The interrupt remains posted until it is cleared by + * writing the mtimecmp register. The interrupt will only be taken + * if interrupts are enabled and the MTIE bit is set in the mie + * register. + */ +typedef uint64_t clint_mtime_t; + +/** + * @brief CLINT object + * + * Coreplex-Local INTerrupts, which includes software interrupts, + * local timer interrupts, and other interrupts routed directly to + * a core. + */ +typedef struct _clint +{ + /* 0x0000 to 0x3FF8, MSIP Registers */ + clint_msip_t msip[CLINT_MAX_CORES]; + /* Resverd space, do not use */ + uint32_t resv0; + /* 0x4000 to 0xBFF0, Timer Compare Registers */ + clint_mtimecmp_t mtimecmp[CLINT_MAX_CORES]; + /* 0xBFF8, Time Register */ + clint_mtime_t mtime; +} __attribute__((packed, aligned(4))) clint_t; + +/** + * @brief Clint object instanse + */ +extern volatile clint_t* const clint; + +/** + * @brief Definitions for the timer callbacks + */ +typedef int (*clint_timer_callback_t)(void *ctx); + +/** + * @brief Definitions for local interprocessor interrupt callbacks + */ +typedef int (*clint_ipi_callback_t)(void *ctx); + +typedef struct _clint_timer_instance +{ + uint64_t interval; + uint64_t cycles; + uint64_t single_shot; + clint_timer_callback_t callback; + void *ctx; +} clint_timer_instance_t; + +typedef struct _clint_ipi_instance +{ + clint_ipi_callback_t callback; + void *ctx; +} clint_ipi_instance_t; + +/** + * @brief Get the time form CLINT timer register + * + * @note The CLINT must init to get right time + * + * @return 64bit Time + */ +uint64_t clint_get_time(void); + +/** + * @brief Init the CLINT timer + * + * @note MIP_MTIP will be clear after init. The MSTATUS_MIE must set by + * user. + * + * @return result + * - 0 Success + * - Other Fail + */ +int clint_timer_init(void); + +/** + * @brief Stop the CLINT timer + * + * @note MIP_MTIP will be clear after stop + * + * @return result + * - 0 Success + * - Other Fail + */ +int clint_timer_stop(void); + +/** + * @brief Start the CLINT timer + * + * @param[in] interval The interval with Millisecond(ms) + * @param[in] single_shot Single shot or repeat + * + * @return result + * - 0 Success + * - Other Fail + */ +int clint_timer_start(uint64_t interval, int single_shot); + +/** + * @brief Get the interval of timer + * + * @return The interval with Millisecond(ms) + */ +uint64_t clint_timer_get_interval(void); + +/** + * @brief Set the interval with Millisecond(ms) + * + * @param[in] interval The interval with Millisecond(ms) + * + * @return result + * - 0 Success + * - Other Fail + */ +int clint_timer_set_interval(uint64_t interval); + +/** + * @brief Get whether the timer is a single shot timer + * + * @return result + * - 0 It is a repeat timer + * - 1 It is a single shot timer + */ +int clint_timer_get_single_shot(void); + +/** + * @brief Set the timer working as a single shot timer or repeat timer + * + * @param[in] single_shot Single shot or repeat + * + * @return result + * - 0 Success + * - Other Fail + */ +int clint_timer_set_single_shot(int single_shot); + +/** + * @brief Set user callback function when timer is timeout + * + * @param[in] callback The callback function + * @param[in] ctx The context + * + * @return result + * - 0 Success + * - Other Fail + */ +int clint_timer_register(clint_timer_callback_t callback, void *ctx); + +/** + * @brief Deregister user callback function + * + * @return result + * - 0 Success + * - Other Fail + */ +int clint_timer_unregister(void); + +/** + * @brief Initialize local interprocessor interrupt + * + * @return result + * - 0 Success + * - Other Fail + */ +int clint_ipi_init(void); + +/** + * @brief Enable local interprocessor interrupt + * + * @return result + * - 0 Success + * - Other Fail + */ +int clint_ipi_enable(void); + +/** + * @brief Disable local interprocessor interrupt + * + * @return result + * - 0 Success + * - Other Fail + */ +int clint_ipi_disable(void); + +/** + * @brief Send local interprocessor interrupt to core by core id + * + * @param[in] core_id The core identifier + * + * @return result + * - 0 Success + * - Other Fail + */ +int clint_ipi_send(size_t core_id); + +/** + * @brief Clear local interprocessor interrupt + * + * @param[in] core_id The core identifier + * + * @return result + * - 1 An IPI was pending + * - 0 Non IPI was pending + * - -1 Fail + */ +int clint_ipi_clear(size_t core_id); + +/** + * @brief Set user callback function when interprocessor interrupt + * + * @param[in] callback The callback function + * @param[in] ctx The context + * + * @return result + * - 0 Success + * - Other Fail + */ +int clint_ipi_register(clint_ipi_callback_t callback, void *ctx); + +/** + * @brief Deregister user callback function + * + * @return result + * - 0 Success + * - Other Fail + */ +int clint_ipi_unregister(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __CLINT_H__ */ + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_ch376.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_ch376.h new file mode 100644 index 000000000..9dc6c59de --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_ch376.h @@ -0,0 +1,36 @@ +/* +* 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_ch376.h +* @brief define edu-riscv64 ch376 function and struct +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#ifndef CONNECT_CH376_H +#define CONNECT_CH376_H + +#include + +struct HwCh376 +{ + HardwareDevType dev; + x_size_t msg_len; + int sem; + KTaskDescriptorType task; +}; + +int HwCh376Init(void); + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_gpio.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_gpio.h new file mode 100644 index 000000000..70975d3e0 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_gpio.h @@ -0,0 +1,36 @@ +/* +* 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_gpio.h +* @brief define edu-riscv64-board gpio function and struct +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#ifndef CONNECT_GPIO_H +#define CONNECT_GPIO_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int HwGpioInit(void); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_hwtimer.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_hwtimer.h new file mode 100644 index 000000000..cb0a99eda --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_hwtimer.h @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_hwtimer.h +* @brief define aiit-riscv64-board hwtimer function and struct +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef CONNECT_HWTIMER_H +#define CONNECT_HWTIMER_H + +#include +#include "hardware_hwtimer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int HwTimerInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_i2c.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_i2c.h new file mode 100644 index 000000000..b59b6aa5d --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_i2c.h @@ -0,0 +1,36 @@ +/* +* 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_i2c.h +* @brief define edu-riscv64-board i2c function and struct +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#ifndef CONNECT_I2C_H +#define CONNECT_I2C_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int HwI2cInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_lcd.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_lcd.h new file mode 100644 index 000000000..1fe935c07 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_lcd.h @@ -0,0 +1,52 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file connect_lcd.h +* @brief define aiit-riscv64-board lcd function +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +/************************************************* +File name: connect_lcd.h +Description: define aiit-riscv64-board lcd function +Others: https://canaan-creative.com/developer +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. add aiit-riscv64-board lcd function +*************************************************/ + +#ifndef CONNECT_LCD_H +#define CONNECT_LCD_H + +#include +#include "hardware_spi.h" +#include + +#ifdef BSP_USING_TOUCH +#include "connect_touch.h" +#endif + +void DrvLcdClear(uint16_t color); +void LcdDrawLine(uint16 x1, uint16 y1, uint16 x2, uint16 y2,uint16 color); +void LcdDrawRectangle(uint16 x1, uint16 y1, uint16 x2, uint16 y2,uint16 color); +void LcdDrawCircle(uint16 x0,uint16 y0,uint8 r,uint16 color); + +int HwLcdInit(void); +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_rtc.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_rtc.h new file mode 100644 index 000000000..8d02d6e6b --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_rtc.h @@ -0,0 +1,36 @@ +/* +* 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_rtc.h +* @brief define aiit-riscv64-board rtc function and struct +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef CONNECT_RTC_H +#define CONNECT_RTC_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int HwRtcInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_soft_spi.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_soft_spi.h new file mode 100644 index 000000000..687c1383d --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_soft_spi.h @@ -0,0 +1,14 @@ +#ifndef CONNECT_TF_H +#define CONNECT_TF_H + +#ifdef __cplusplus +extern "C" { +#endif + +int HwSoftSPIInit(void); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_spi.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_spi.h new file mode 100644 index 000000000..cd746d016 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_spi.h @@ -0,0 +1,36 @@ +/* +* 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.h +* @brief define aiit-riscv64-board spi function and struct +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef CONNECT_SPI_H +#define CONNECT_SPI_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int HwSpiInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_touch.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_touch.h new file mode 100644 index 000000000..30ed6008d --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_touch.h @@ -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_touch.h +* @brief support edu-riscv64 touch function and register to bus framework +* @version 2.0 +* @author AIIT XiUOS Lab +* @date 2022-10-17 +*/ + +#ifndef __CONNECT_TOUCH_H__ +#define __CONNECT_TOUCH_H__ + +#include + +/* 表示读数据 */ +#define I2C_M_RD 0x0001 + +struct i2c_msg { + uint16_t flags; /*控制标志 */ + uint16_t len; /*读写数据的长度 */ + uint8_t *buf; /*存储读写数据的指针 */ +}; + +typedef struct +{ + int X; + int Y; +} POINT; + +typedef enum _touch_event +{ + kTouch_Down = 0, /*!< The state changed to touched. */ + kTouch_Up = 1, /*!< The state changed to not touched. */ + kTouch_Contact = 2, /*!< There is a continuous touch being detected. */ + kTouch_Reserved = 3 /*!< No touch information available. */ +} touch_event_t; + +/*设定使用的电容屏IIC设备地址*/ +#define GTP_ADDRESS 0xBA + +#define GTP_MAX_HEIGHT 272 +#define GTP_MAX_WIDTH 480 +#define GTP_INT_TRIGGER 0 +#define GTP_MAX_TOUCH 5 + +#define GTP_CONFIG_MAX_LENGTH 240 +#define GTP_ADDR_LENGTH 2 + +// Registers define +#define GTP_READ_COOR_ADDR 0x814E +#define GTP_REG_SLEEP 0x8040 +#define GTP_REG_SENSOR_ID 0x814A +#define GTP_REG_CONFIG_DATA 0x8047 +#define GTP_REG_VERSION 0x8140 + +#define CFG_GROUP_LEN(p_cfg_grp) (sizeof(p_cfg_grp) / sizeof(p_cfg_grp[0])) + +int HwTouchInit(void); + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_uart.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_uart.h new file mode 100644 index 000000000..45d3fe3ae --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_uart.h @@ -0,0 +1,40 @@ +/* +* 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_uart.h +* @brief define edu-riscv64-board uart function and struct +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#ifndef CONNECT_UART_H +#define CONNECT_UART_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define KERNEL_CONSOLE_BUS_NAME SERIAL_BUS_NAME_0 +#define KERNEL_CONSOLE_DRV_NAME SERIAL_DRV_NAME_0 +#define KERNEL_CONSOLE_DEVICE_NAME SERIAL_0_DEVICE_NAME_0 + +int HwUartInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_w5500.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_w5500.h new file mode 100644 index 000000000..43359e8f4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_w5500.h @@ -0,0 +1,38 @@ +/* + * 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_w5500.h + * @brief define aiit-riscv64-board spi function and struct + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022-10-16 + */ + +#ifndef _CONNECT_W5500_H_ +#define _CONNECT_W5500_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static struct Bus *spi_bus; + +int HwWiznetInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_wdt.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_wdt.h new file mode 100644 index 000000000..96cdb3e0e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/connect_wdt.h @@ -0,0 +1,36 @@ +/* +* 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_wdt.h +* @brief define aiit-riscv64-board wdt function and struct +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef CONNECT_WDT_H +#define CONNECT_WDT_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int HwWdtInit(void); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/dmac.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/dmac.h new file mode 100644 index 000000000..9d6815fbc --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/dmac.h @@ -0,0 +1,1552 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file dmac.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#ifndef __DMAC_H__ +#define __DMAC_H__ + +#include +#include "io.h" +#include "platform.h" +#include "stdbool.h" +#include "plic.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* DMAC */ +#define DMAC_CHANNEL_COUNT (DMAC_CHANNEL_MAX) +#define LAST_ROW (-1) + +typedef enum _dmac_channel_number +{ + DMAC_CHANNEL0 = 0, + DMAC_CHANNEL1 = 1, + DMAC_CHANNEL2 = 2, + DMAC_CHANNEL3 = 3, + DMAC_CHANNEL4 = 4, + DMAC_CHANNEL5 = 5, + DMAC_CHANNEL_MAX +} dmac_channel_number_t; + +typedef enum _dmac_src_dst_select +{ + DMAC_SRC = 0x1, + DMAC_DST = 0x2, + DMAC_SRC_DST = 0x3 +} dmac_src_dst_select_t; + +typedef enum _state_value +{ + clear = 0, + set = 1 +} state_value_t; + +typedef enum _dmac_lock_bus_ch +{ + DMAC_LOCK_BUS = 0x1, + DMAC_LOCK_CHANNEL = 0x2, + DMAC_LOCK_BUS_CH = 0x3 +} dmac_lock_bus_ch_t; + +typedef enum _dmac_sw_hw_hs_select +{ + DMAC_HS_HARDWARE = 0x0, + DMAC_HS_SOFTWARE = 0x1 +} dmac_sw_hw_hs_select_t; + +typedef enum _dmac_scatter_gather_param +{ + DMAC_SG_COUNT = 0x0, + DMAC_SG_INTERVAL = 0x1 +} dmac_scatter_gather_param_t; + +typedef enum _dmac_irq +{ + /* no interrupts */ + DMAC_IRQ_NONE = 0x00, + /* transfer complete */ + DMAC_IRQ_TFR = 0x01, + /* block transfer complete */ + DMAC_IRQ_BLOCK = 0x02, + /* source transaction complete */ + DMAC_IRQ_SRCTRAN = 0x04, + /* destination transaction complete */ + DMAC_IRQ_DSTTRAN = 0x08, + /* error */ + DMAC_IRQ_ERR = 0x10, + /* all interrupts */ + DMAC_IRQ_ALL = 0x1f +} dmac_irq_t; + +typedef enum _dmac_software_req +{ + /* ReqSrcReq/ReqDstReq */ + DMAC_REQUEST = 0x1, + /* SglReqSrcReq/SglReqDstReq */ + DMAC_SINGLE_REQUEST = 0x2, + /* LstReqSrcReq/LstReqDstReq */ + DMAC_LAST_REQUEST = 0x4 +} dmac_software_req_t; + +typedef enum _dmac_master_number +{ + DMAC_MASTER1 = 0x0, + DMAC_MASTER2 = 0x1 +} dmac_master_number_t; + +typedef enum _dmac_transfer_flow +{ + /* mem to mem - DMAC flow ctlr */ + DMAC_MEM2MEM_DMA = 0x0, + /* mem to prf - DMAC flow ctlr */ + DMAC_MEM2PRF_DMA = 0x1, + /* prf to mem - DMAC flow ctlr */ + DMAC_PRF2MEM_DMA = 0x2, + /* prf to prf - DMAC flow ctlr */ + DMAC_PRF2PRF_DMA = 0x3, + /* prf to mem - periph flow ctlr */ + DMAC_PRF2MEM_PRF = 0x4, + /* prf to prf - source flow ctlr */ + DMAC_PRF2PRF_SRCPRF = 0x5, + /* mem to prf - periph flow ctlr */ + DMAC_MEM2PRF_PRF = 0x6, + /* prf to prf - dest flow ctlr */ + DMAC_PRF2PRF_DSTPRF = 0x7 +} dmac_transfer_flow_t; + +typedef enum _dmac_burst_trans_length +{ + DMAC_MSIZE_1 = 0x0, + DMAC_MSIZE_4 = 0x1, + DMAC_MSIZE_8 = 0x2, + DMAC_MSIZE_16 = 0x3, + DMAC_MSIZE_32 = 0x4, + DMAC_MSIZE_64 = 0x5, + DMAC_MSIZE_128 = 0x6, + DMAC_MSIZE_256 = 0x7 +} dmac_burst_trans_length_t; + +typedef enum _dmac_address_increment +{ + DMAC_ADDR_INCREMENT = 0x0, + DMAC_ADDR_NOCHANGE = 0x1 +} dmac_address_increment_t; + +typedef enum _dmac_transfer_width +{ + DMAC_TRANS_WIDTH_8 = 0x0, + DMAC_TRANS_WIDTH_16 = 0x1, + DMAC_TRANS_WIDTH_32 = 0x2, + DMAC_TRANS_WIDTH_64 = 0x3, + DMAC_TRANS_WIDTH_128 = 0x4, + DMAC_TRANS_WIDTH_256 = 0x5 +} dmac_transfer_width_t; + +typedef enum _dmac_hs_interface +{ + DMAC_HS_IF0 = 0x0, + DMAC_HS_IF1 = 0x1, + DMAC_HS_IF2 = 0x2, + DMAC_HS_IF3 = 0x3, + DMAC_HS_IF4 = 0x4, + DMAC_HS_IF5 = 0x5, + DMAC_HS_IF6 = 0x6, + DMAC_HS_IF7 = 0x7, + DMAC_HS_IF8 = 0x8, + DMAC_HS_IF9 = 0x9, + DMAC_HS_IF10 = 0xa, + DMAC_HS_IF11 = 0xb, + DMAC_HS_IF12 = 0xc, + DMAC_HS_IF13 = 0xd, + DMAC_HS_IF14 = 0xe, + DMAC_HS_IF15 = 0xf +} dmac_hs_interface_t; + +typedef enum _dmac_multiblk_transfer_type +{ + CONTIGUOUS = 0, + RELOAD = 1, + SHADOWREGISTER = 2, + LINKEDLIST = 3 +} dmac_multiblk_transfer_type_t; + +typedef enum _dmac_multiblk_type +{ + DMAC_SRC_DST_CONTINUE = 0, + DMAC_SRC_CONTINUE_DST_RELAOD = 2, + DMAC_SRC_CONTINUE_DST_LINKEDLIST = 3, + DMAC_SRC_RELOAD_DST_CONTINUE = 4, + DMAC_SRC_RELOAD_DST_RELOAD = 5, + DMAC_SRC_RELOAD_DST_LINKEDLIST = 6, + DMAC_SRC_LINKEDLIST_DST_CONTINUE = 7, + DMAC_SRC_LINKEDLIST_DST_RELOAD = 8, + DMAC_SRC_LINKEDLIST_DST_LINKEDLIST = 9, + DMAC_SRC_SHADOWREG_DST_CONTINUE = 10 +} dmac_multiblk_type_t; + +typedef enum _dmac_transfer_type +{ + DMAC_TRANSFER_ROW1 = 0x1, + DMAC_TRANSFER_ROW2 = 0x2, + DMAC_TRANSFER_ROW3 = 0x3, + DMAC_TRANSFER_ROW4 = 0x4, + DMAC_TRANSFER_ROW5 = 0x5, + DMAC_TRANSFER_ROW6 = 0x6, + DMAC_TRANSFER_ROW7 = 0x7, + DMAC_TRANSFER_ROW8 = 0x8, + DMAC_TRANSFER_ROW9 = 0x9, + DMAC_TRANSFER_ROW10 = 0xa +} dmac_transfer_type_t; + +typedef enum _dmac_prot_level +{ + /* default prot level */ + DMAC_NONCACHE_NONBUFF_NONPRIV_OPCODE = 0x0, + DMAC_NONCACHE_NONBUFF_NONPRIV_DATA = 0x1, + DMAC_NONCACHE_NONBUFF_PRIV_OPCODE = 0x2, + DMAC_NONCACHE_NONBUFF_PRIV_DATA = 0x3, + DMAC_NONCACHE_BUFF_NONPRIV_OPCODE = 0x4, + DMAC_NONCACHE_BUFF_NONPRIV_DATA = 0x5, + DMAC_NONCACHE_BUFF_PRIV_OPCODE = 0x6, + DMAC_NONCACHE_BUFF_PRIV_DATA = 0x7, + DMAC_CACHE_NONBUFF_NONPRIV_OPCODE = 0x8, + DMAC_CACHE_NONBUFF_NONPRIV_DATA = 0x9, + DMAC_CACHE_NONBUFF_PRIV_OPCODE = 0xa, + DMAC_CACHE_NONBUFF_PRIV_DATA = 0xb, + DMAC_CACHE_BUFF_NONPRIV_OPCODE = 0xc, + DMAC_CACHE_BUFF_NONPRIV_DATA = 0xd, + DMAC_CACHE_BUFF_PRIV_OPCODE = 0xe, + DMAC_CACHE_BUFF_PRIV_DATA = 0xf +} dmac_prot_level_t; + +typedef enum _dmac_fifo_mode +{ + DMAC_FIFO_MODE_SINGLE = 0x0, + DMAC_FIFO_MODE_HALF = 0x1 +} dmac_fifo_mode_t; + +typedef enum _dw_dmac_flow_ctl_mode +{ + DMAC_DATA_PREFETCH_ENABLED = 0x0, + DMAC_DATA_PREFETCH_DISABLED = 0x1 +} dw_dmac_flow_ctl_mode_t; + +typedef enum _dmac_polarity_level +{ + DMAC_ACTIVE_HIGH = 0x0, + DMAC_ACTIVE_LOW = 0x1 +} dmac_polarity_level_t; + +typedef enum _dmac_lock_level +{ + DMAC_LOCK_LEVEL_DMA_TRANSFER = 0x0, + DMAC_LOCK_LEVEL_BLOCK_TRANSFER = 0x1, + DMAC_LOCK_LEVEL_TRANSACTION = 0x2 +} dmac_lock_level_t; + +typedef enum _dmac_channel_priority +{ + DMAC_PRIORITY_0 = 0x0, + DMAC_PRIORITY_1 = 0x1, + DMAC_PRIORITY_2 = 0x2, + DMAC_PRIORITY_3 = 0x3, + DMAC_PRIORITY_4 = 0x4, + DMAC_PRIORITY_5 = 0x5, + DMAC_PRIORITY_6 = 0x6, + DMAC_PRIORITY_7 = 0x7 +} dmac_channel_priority_t; + +typedef enum _dmac_state +{ + ZERO, + ONE +} dmac_state_t; + +typedef enum _dmac_common_int +{ + SLVIF_COMMON_DEC_ERR = 0, + SLVIF_COMMON_WR2RO_ERR = 1, + SLVIF_COMMON_RD2WO_ERR = 2, + SLVIF_COMMON__WRONHOLD_ERR = 3, + SLVIF_UNDEFINED_DEC_ERR = 4, + SLVIF_ALL_INT = 5 +} dmac_common_int_t; + +typedef struct _dmac_cfg +{ + /** + * Bit 0 is used to enable dmac + * 0x1 for enable, 0x0 for disable + */ + uint64_t dmac_en : 1; + /** + * Bit 1 is used to glabally enable interrupt generation + * 0x1 for enable interrupt, 0x0 for disable interrupt + */ + uint64_t int_en : 1; + /* Bits [63:2] is reserved */ + uint64_t rsvd : 62; +} __attribute__((packed, aligned(8))) dmac_cfg_t; + +typedef union _dmac_cfg_u +{ + dmac_cfg_t cfg; + uint64_t data; +} dmac_cfg_u_t; + +typedef struct _damc_chen +{ + /** + * Bit 0 is used to enable channel 1 + * 0x1 for enable, 0x0 for disable + */ + uint64_t ch1_en : 1; + /** + * Bit 1 is used to enable channel 2 + * 0x1 for enable, 0x0 for disable + */ + uint64_t ch2_en : 1; + /** + * Bit 2 is used to enable channel 3 + * 0x1 for enable, 0x0 for disable + */ + uint64_t ch3_en : 1; + /** + * Bit 3 is used to enable channel 4 + * 0x1 for enable, 0x0 for disable + */ + uint64_t ch4_en : 1; + /** + * Bit 4 is used to enable channel 5 + * 0x1 for enable, 0x0 for disable + */ + uint64_t ch5_en : 1; + /** + * Bit 5 is used to enable channel 6 + * 0x1 for enable, 0x0 for disable + */ + uint64_t ch6_en : 1; + /* Bits [7:6] is reserved */ + uint64_t rsvd1 : 2; + /** + * Bit 8 is write enable bit + * 0x1 for enable, 0x0 for disable + */ + uint64_t ch1_en_we : 1; + /** + * Bit 9 is write enable bit + * 0x1 for enable, 0x0 for disable + */ + uint64_t ch2_en_we : 1; + /** + * Bit 10 is write enable bit + * 0x1 for enable, 0x0 for disable + */ + uint64_t ch3_en_we : 1; + /** + * Bit 11 is write enable bit + * 0x1 for enable, 0x0 for disable + */ + uint64_t ch4_en_we : 1; + /** + * Bit 12 is write enable bit + * 0x1 for enable, 0x0 for disable + */ + uint64_t ch5_en_we : 1; + /** + * Bit 13 is write enable bit + * 0x1 for enable, 0x0 for disable + */ + uint64_t ch6_en_we : 1; + /* Bits [15:14] is reserved */ + uint64_t rsvd2 : 2; + /** + * Bit 16 is susped reuest + * 0x1 for request channel suspend + * 0x0 for no channel suspend request + */ + uint64_t ch1_susp : 1; + /** + * Bit 17 is susped reuest + * 0x1 for request channel suspend + * 0x0 for no channel suspend request + */ + uint64_t ch2_susp : 1; + /* Bit 18 is susped reuest + * 0x1 for request channel suspend + * 0x0 for no channel suspend request + */ + uint64_t ch3_susp : 1; + /** + * Bit 19 is susped reuest + * 0x1 for request channel suspend + * 0x0 for no channel suspend request + */ + uint64_t ch4_susp : 1; + /** + * Bit 20 is susped reuest + * 0x1 for request channel suspend + * 0x0 for no channel suspend request + */ + uint64_t ch5_susp : 1; + /** + * Bit 21 is susped reuest + * 0x1 for request channel suspend + * 0x0 for no channel suspend request + */ + uint64_t ch6_susp : 1; + /* Bits [23:22] is reserved */ + uint64_t rsvd3 : 2; + /** + * Bit 24 is write enable to the channel suspend bit + * 0x1 for enable write to CH1_SUSP bit + * 0x0 for disable write to CH1_SUSP bit + */ + uint64_t ch1_susp_we : 1; + /** + * Bit 25 is write enable to the channel suspend bit + * 0x1 for enable write to CH2_SUSP bit + * 0x0 for disable write to CH2_SUSP bit + */ + uint64_t ch2_susp_we : 1; + /** + * Bit 26 is write enable to the channel suspend bit + * 0x1 for enable write to CH3_SUSP bit + * 0x0 for disable write to CH3_SUSP bit + */ + uint64_t ch3_susp_we : 1; + /** + * Bit 27 is write enable to the channel suspend bit + * 0x1 for enable write to CH4_SUSP bit + * 0x0 for disable write to CH4_SUSP bit + */ + uint64_t ch4_susp_we : 1; + /** + * Bit 28 is write enable to the channel suspend bit + * 0x1 for enable write to CH5_SUSP bit + * 0x0 for disable write to CH5_SUSP bit + */ + uint64_t ch5_susp_we : 1; + /** + * Bit 29 is write enable to the channel suspend bit + * 0x1 for enable write to CH6_SUSP bit + * 0x0 for disable write to CH6_SUSP bit + */ + uint64_t ch6_susp_we : 1; + /* Bits [31:30] is reserved */ + uint64_t rsvd4 : 2; + /** + * Bit 32 is channel-1 abort requst bit + * 0x1 for request for channnel abort + * 0x0 for no channel abort request + */ + uint64_t ch1_abort : 1; + /** + * Bit 33 is channel-2 abort requst bit + * 0x1 for request for channnel abort + * 0x0 for no channel abort request + */ + uint64_t ch2_abort : 1; + /** + * Bit 34 is channel-3 abort requst bit + * 0x1 for request for channnel abort + * 0x0 for no channel abort request + */ + uint64_t ch3_abort : 1; + /** + * Bit 35 is channel-4 abort requst bit + * 0x1 for request for channnel abort + * 0x0 for no channel abort request + */ + uint64_t ch4_abort : 1; + /** + * Bit 36 is channel-5 abort requst bit + * 0x1 for request for channnel abort + * 0x0 for no channel abort request + */ + uint64_t ch5_abort : 1; + /** + * Bit 37 is channel-6 abort requst bit + * 0x1 for request for channnel abort + * 0x0 for no channel abort request + */ + uint64_t ch6_abort : 1; + /* Bits [39:38] is reserved */ + uint64_t rsvd5 : 2; + /** + * Bit 40 is ued to write enable channel-1 abort bit + * 0x1 for enable write to CH1_ABORT bit + * 0x0 for disable write to CH1_ABORT bit + */ + uint64_t ch1_abort_we : 1; + /** + * Bit 41 is ued to write enable channel-2 abort bit + * 0x1 for enable write to CH2_ABORT bit + * 0x0 for disable write to CH2_ABORT bit + */ + uint64_t ch2_abort_we : 1; + /** + * Bit 42 is ued to write enable channel-3 abort bit + * 0x1 for enable write to CH3_ABORT bit + * 0x0 for disable write to CH3_ABORT bit + */ + uint64_t ch3_abort_we : 1; + /** + * Bit 43 is ued to write enable channel-4 abort bit + * 0x1 for enable write to CH4_ABORT bit + * 0x0 for disable write to CH4_ABORT bit + */ + uint64_t ch4_abort_we : 1; + /** + * Bit 44 is ued to write enable channel-5 abort bit + * 0x1 for enable write to CH5_ABORT bit + * 0x0 for disable write to CH5_ABORT bit + */ + uint64_t ch5_abort_we : 1; + /** + * Bit 45 is ued to write enable channel-6 abort bit + * 0x1 for enable write to CH6_ABORT bit + * 0x0 for disable write to CH6_ABORT bit + */ + uint64_t ch6_abort_we : 1; + /* Bits [47:46] is reserved */ + uint64_t rsvd6 : 2; + /* Bits [63:48] is reserved */ + uint64_t rsvd7 : 16; +} __attribute__((packed, aligned(8))) damc_chen_t; + +typedef union _dmac_chen_u +{ + damc_chen_t dmac_chen; + uint64_t data; +} dmac_chen_u_t; + +typedef struct _dmac_intstatus +{ + /** + * Bit 0 is channel 1 interrupt bit + * 0x1 for channel 1 interrupt active + * 0x0 for channel 1 interrupt inactive + */ + uint64_t ch1_intstat : 1; + /** + * Bit 1 is channel 1 interrupt bit + * 0x1 for channel 2 interrupt active + * 0x0 for channel 2 interrupt inactive + */ + uint64_t ch2_intstat : 1; + /** + * Bit 2 is channel 3 interrupt bit + * 0x1 for channel 3 interrupt active + * 0x0 for channel 3 interrupt inactive + */ + uint64_t ch3_intstat : 1; + /** + * Bit 3 is channel 4 interrupt bit + * 0x1 for channel 4 interrupt active + * 0x0 for channel 4 interrupt inactive + */ + uint64_t ch4_intstat : 1; + /** + * Bit 4 is channel 5 interrupt bit + * 0x1 for channel 5 interrupt active + * 0x0 for channel 5 interrupt inactive + */ + uint64_t ch5_intstat : 1; + /** + * Bit 5 is channel 6 interrupt bit + * 0x1 for channel 6 interrupt active + * 0x0 for channel 6 interrupt inactive + */ + uint64_t ch6_intstat : 1; + /* Bits [15:6] is reserved */ + uint64_t rsvd1 : 10; + /** + * Bit 16 is commom register status bit + * 0x1 for common register interrupt is active + * 0x0 for common register interrupt inactive + */ + uint64_t commonreg_intstat : 1; + /* Bits [63:17] is reserved */ + uint64_t rsvd2 : 47; +} __attribute__((packed, aligned(8))) dmac_intstatus_t; + +typedef union _dmac_intstatus_u +{ + dmac_intstatus_t intstatus; + uint64_t data; +} dmac_intstatus_u_t; + +typedef struct _dmac_commonreg_intclear +{ + /** + * Bit 0 is slave nterface Common Register + * Decode Error Interrupt clear Bit + * x01 for clear SLVIF_CommonReg_DEC_ERR interrupt + * in DMAC_COMMONREG_INTSTATUSREG + * 0x0 for inactive signal + */ + uint64_t cear_slvif_dec_err_intstat : 1; + /** + * Bit 1 is Slave Interface Common Register Write + * to Read only Error Interrupt clear Bit + * x01 for clear SLVIF_CommonReg_WR2RO_ERR interrupt + * in DMAC_COMMONREG_INTSTATUSREG + * 0x0 for inactive signal + */ + uint64_t clear_slvif_wr2ro_err_intstat : 1; + /** + * Bit 2 is Slave Interface Common Register Read to + * Write only Error Interrupt clear Bit + * x01 for clear SLVIF_CommonReg_RD2WO_ERR interrupt + * in DMAC_COMMONREG_INTSTATUSREG + * 0x0 for inactive signal + */ + uint64_t clear_slvif_rd2wo_err_intstat : 1; + /** + * Bit 3 is Slave Interface Common Register Write + * On Hold Error Interrupt clear Bit + * x01 for clear SSLVIF_CommonReg_WrOnHold_ERR interrupt + * in DMAC_COMMONREG_INTSTATUSREG + * 0x0 for inactive signal + */ + uint64_t clear_slvif_wronhold_err_intstat : 1; + /* Bits [7:4] is reserved */ + uint64_t rsvd1 : 4; + /** + * Bit 8 is Slave Interface Undefined register + * Decode Error Interrupt clear Bit + * x01 for clear SLVIF_UndefinedReg_DEC_ERRinterrupt + * in DMAC_COMMONREG_INTSTATUSREG + * 0x0 for inactive signal + */ + uint64_t clear_slvif_undefinedreg_dec_err_intstat : 1; + /* Bits [63:9] is reserved */ + uint64_t rsvd2 : 55; +} __attribute__((packed, aligned(8))) dmac_commonreg_intclear_t; + +typedef union _dmac_commonreg_intclear_u +{ + dmac_commonreg_intclear_t com_intclear; + uint64_t data; +} dmac_commonreg_intclear_u_t; + +typedef struct _dmac_commonreg_intstatus_enable +{ + /** + * Bit 0 is Slave Interface Common Register Decode Error + * Interrupt Status Enable Bit + * 0x1 for SLVIF_CommonReg_DEC_ERR_IntStat bit enable + * 0x0 for SLVIF_CommonReg_DEC_ERR_IntStat bit disable + */ + uint64_t enable_slvif_dec_err_intstat : 1; + /** + * Bit 1 is Slave Interface Common Register Write to Read + * only Error Interrupt Status Enable Bit + * 0x1 for SLVIF_CommonReg_WR2RO_ERR_IntStat bit enable + * 0x0 for SLVIF_CommonReg_WR2RO_ERR_IntStat bit disable + */ + uint64_t enable_slvif_wr2ro_err_intstat : 1; + /*!< + * Bit 2 is Slave Interface Common Register Read to Write + * only Error Interrupt Status Enable Bit + * 0x1 for SLVIF_CommonReg_RD2WO_ERR_IntStat bit enable + * 0x0 for SLVIF_CommonReg_RD2WO_ERR_IntStat bit disable + */ + uint64_t enable_slvif_rd2wo_err_intstat : 1; + /** + * Bit 3 is Slave Interface Common Register Write On Hold + * Error Interrupt Status Enable Bit + * 0x1 for SLVIF_CommonReg_WrOnHold_ERR_IntStat bit enable + * 0x0 for SLVIF_CommonReg_WrOnHold_ERR_IntStat bit disable + */ + uint64_t enable_slvif_wronhold_err_intstat : 1; + /* Bits [7:4] is reserved */ + uint64_t rsvd1 : 4; + /** + * Bit 8 is Slave Interface Undefined register Decode + * Error Interrupt Status enable Bit + * 0x1 for SLVIF_UndefinedReg_DEC_ERR_IntStat bit enable + * 0x0 for SLVIF_UndefinedReg_DEC_ERR_IntStat disable + */ + uint64_t enable_slvif_undefinedreg_dec_err_intstat : 1; + /* Bits [63:9] is reserved */ + uint64_t rsvd2 : 55; +} __attribute__((packed, aligned(8))) dmac_commonreg_intstatus_enable_t; + +typedef union _dmac_commonreg_intstatus_enable_u +{ + dmac_commonreg_intstatus_enable_t intstatus_enable; + uint64_t data; +} dmac_commonreg_intstatus_enable_u_t; + +typedef struct _dmac_commonreg_intsignal_enable +{ + /** + * Bit 0 is Slave Interface Common Register Decode Error + * Interrupt Signal Enable Bit + * 0x1 for SLVIF_CommonReg_DEC_ERR_IntStat signal enable + * 0x0 for SLVIF_CommonReg_DEC_ERR_IntStat signal disable + */ + uint64_t enable_slvif_dec_err_intsignal : 1; + /** + * Bit 1 is Slave Interface Common Register Write to Read only + * Error Interrupt Signal Enable Bit + * 0x1 for SLVIF_CommonReg_WR2RO_ERR_IntStat signal enable + * 0x0 for SLVIF_CommonReg_WR2RO_ERR_IntStat signal disable + */ + uint64_t enable_slvif_wr2ro_err_intsignal : 1; + /** + * Bit 2 is Slave Interface Common Register Read to + * Write only Error Interrupt Status Enable Bit + * 0x1 for SLVIF_CommonReg_RD2WO_ERR_IntStat bit enable + * 0x0 for SLVIF_CommonReg_RD2WO_ERR_IntStat bit disable + */ + uint64_t enable_slvif_rd2wo_err_intsignal : 1; + /** + * Bit 3 is Slave Interface Common Register Write On Hold Error + * Interrupt Signal Enable Bit + * 0x1 for SLVIF_CommonReg_WrOnHold_ERR_IntStat signal enable + * 0x0 for SLVIF_CommonReg_WrOnHold_ERR_IntStat signal disable + */ + uint64_t enable_slvif_wronhold_err_intsignal : 1; + /* Bits [7:4] is reserved */ + uint64_t rsvd1 : 4; + /** + * Bit 8 is Slave Interface Undefined register Decode Error + * Interrupt Signal Enable Bit + * 0x1 for SLVIF_UndefinedReg_DEC_ERR_IntStat signal enable + * 0x0 for SLVIF_UndefinedReg_DEC_ERR_IntStat signal disable + */ + uint64_t enable_slvif_undefinedreg_dec_err_intsignal : 1; + /* Bits [63:9] is reserved */ + uint64_t rsvd2 : 55; +} __attribute__((packed, aligned(8))) dmac_commonreg_intsignal_enable_t; + +typedef union _dmac_commonreg_intsignal_enable_u +{ + dmac_commonreg_intsignal_enable_t intsignal_enable; + uint64_t data; +} dmac_commonreg_intsignal_enable_u_t; + +typedef struct _dmac_commonreg_intstatus +{ + /** + * Bit 0 is Slave Interface Common Register Decode + * Error Interrupt Status Bit + * 0x1 for Slave Interface Decode Error detected + * 0x0 for No Slave Interface Decode Errors + */ + uint64_t slvif_dec_err_intstat : 1; + /** + * Bit 1 is Slave Interface Common Register Write to Read Only + * Error Interrupt Status bit + * 0x1 for Slave Interface Write to Read Only Error detected + * 0x0 No Slave Interface Write to Read Only Errors + */ + uint64_t slvif_wr2ro_err_intstat : 1; + /** + * Bit 2 is Slave Interface Common Register Read to Write + * only Error Interrupt Status bit + * 0x1 for Slave Interface Read to Write Only Error detected + * 0x0 for No Slave Interface Read to Write Only Errors + */ + uint64_t slvif_rd2wo_err_intstat : 1; + /** + * Bit 3 is Slave Interface Common Register Write On + * Hold Error Interrupt Status Bit + * 0x1 for Slave Interface Common Register Write On Hold Error detected + * 0x0 for No Slave Interface Common Register Write On Hold Errors + */ + uint64_t slvif_wronhold_err_intstat : 1; + /*!< Bits [7:4] is reserved */ + uint64_t rsvd1 : 4; + /** + * Bit 8 is Slave Interface Undefined register Decode + * Error Interrupt Signal Enable Bit + * 0x1 for Slave Interface Decode Error detected + * 0x0 for No Slave Interface Decode Errors + */ + uint64_t slvif_undefinedreg_dec_err_intstat : 1; + /* Bits [63:9] is reserved */ + uint64_t rsvd2 : 55; +} __attribute__((packed, aligned(8))) dmac_commonreg_intstatus_t; + +typedef union _dmac_commonreg_intstatus_u +{ + dmac_commonreg_intstatus_t commonreg_intstatus; + uint64_t data; +} dmac_commonreg_intstatus_u_t; + +typedef struct _dmac_reset +{ + /* Bit 0 is DMAC reset request bit */ + uint64_t rst : 1; + /* Bits [63:1] is reserved */ + uint64_t rsvd : 63; +} __attribute__((packed, aligned(8))) dmac_reset_t; + +typedef union _dmac_reset_u +{ + dmac_reset_t reset; + uint64_t data; +} dmac_reset_u_t; + +typedef struct _dmac_ch_block_ts +{ + uint64_t block_ts : 22; + /*!< Bit [21:0] is block transfer size*/ + uint64_t rsvd : 42; + /*!< Bits [63:22] is reserved */ +} __attribute__((packed, aligned(8))) dmac_ch_block_ts_t; + +typedef union _dmac_ch_block_ts_u +{ + dmac_ch_block_ts_t block_ts; + uint64_t data; +} dmac_ch_block_ts_u_t; + +typedef struct _dmac_ch_ctl +{ + /** + * Bit 0 is source master select + * 1 for AXI master 2, 0 for AXI master 1 + */ + uint64_t sms : 1; + /* Bit 1 is reserved */ + uint64_t rsvd1 : 1; + /** + * Bit 2 is destination master select + * 0x1 for AXI master 2,0x0 for AXI master 1 + */ + uint64_t dms : 1; + /* Bit 3 is reserved */ + uint64_t rsvd2 : 1; + /** + * Bit 4 is source address increment + * 0x1 for no change, 0x0 for incremnet + */ + uint64_t sinc : 1; + /** + * Bit 5 is reserved + */ + uint64_t rsvd3 : 1; + /** + * Bit 6 is destination address incremnet + * 0x1 for no change, 0x0 for increment + */ + uint64_t dinc : 1; + /* Bit 7 is reserved*/ + uint64_t rsvd4 : 1; + /** + * Bits [10:8] is source transfer width + * 0x0 for source transfer width is 8 bits + * 0x1 for source transfer width is 16 bits + * 0x2 for source transfer width is 32 bits + * 0x3 for source transfer width is 64 bits + * 0x4 for source transfer width is 128 bits + * 0x5 for source transfer width is 256 bits + * 0x6 for source transfer width is 512 bits + */ + uint64_t src_tr_width : 3; + /** + * Bits [13:11] is detination transfer width + * 0x0 for detination transfer width is 8 bits + * 0x1 for detination transfer width is 16 bits + * 0x2 for detination transfer width is 32 bits + * 0x3 for detination transfer width is 64 bits + * 0x4 for detination transfer width is 128 bits + * 0x5 for detination transfer width is 256 bits + * 0x6 for detination transfer width is 512 bits + */ + uint64_t dst_tr_width : 3; + /** + * Bits [17:14] is source burst transaction length + * 0x0 for 1 data item read from rource in the burst transaction + * 0x1 for 4 data item read from rource in the burst transaction + * 0x2 for 8 data item read from rource in the burst transaction + * 0x3 for 16 data item read from rource in the burst transaction + * 0x4 for 32 data item read from rource in the burst transaction + * 0x5 for 64 data item read from rource in the burst transaction + * 0x6 for 128 data item read from rource in the burst transaction + * 0x7 for 256 data item read from rource in the burst transaction + * 0x8 for 512 data item read from rource in the burst transaction + * 0x9 for 1024 data item read from rource in the burst transaction + */ + uint64_t src_msize : 4; + /** + * Bits [17:14] is sdestination burst transaction length + * 0x0 for 1 data item read from rource in the burst transaction + * 0x1 for 4 data item read from rource in the burst transaction + * 0x2 for 8 data item read from rource in the burst transaction + * 0x3 for 16 data item read from rource in the burst transaction + * 0x4 for 32 data item read from rource in the burst transaction + * 0x5 for 64 data item read from rource in the burst transaction + * 0x6 for 128 data item read from rource in the burst transaction + * 0x7 for 256 data item read from rource in the burst transaction + * 0x8 for 512 data item read from rource in the burst transaction + * 0x9 for 1024 data item read from rource in the burst transaction + */ + uint64_t dst_msize : 4; + /** + * Bits [25:22] is reserved + */ + uint64_t rsvd5 : 4; + /*!< Bits [29:26] is reserved */ + uint64_t rsvd6 : 4; + /** + * Bit 30 is Non Posted Last Write Enable + * 0x1 for posted writes may be used till the end of the block + * 0x 0 for posted writes may be used throughout the block transfer + */ + uint64_t nonposted_lastwrite_en : 1; + /* Bit 31 is resrved */ + uint64_t rsvd7 : 1; + /* Bits [34:32] is reserved*/ + uint64_t rsvd8 : 3; + /* Bits [37:35] is reserved*/ + uint64_t rsvd9 : 3; + /** + * Bit 38 is source burst length enable + * 1 for enable, 0 for disable + */ + uint64_t arlen_en : 1; + /* Bits [46:39] is source burst length*/ + uint64_t arlen : 8; + /** + * Bit 47 is destination burst length enable + * 1 for enable, 0 for disable + */ + uint64_t awlen_en : 1; + /* Bits [55:48] is destination burst length */ + uint64_t awlen : 8; + /** + * Bit 56 is source status enable + * 0x1 for enable, 0x0 for disable + */ + uint64_t src_stat_en : 1; + /** + * Bit 57 is destination status enable + * 0x1 for enable, 0x0 for disable + */ + uint64_t dst_stat_en : 1; + /** + * Bit 58 is interrupt completion of block transfer + * 0x1 for enable CHx_IntStatusReg.BLOCK_TFR_DONE_IntStat field + * 0x0 for dsiable CHx_IntStatusReg.BLOCK_TFR_DONE_IntStat field + */ + uint64_t ioc_blktfr : 1; + /** + * Bits [61:59] is reserved + */ + uint64_t rsvd10 : 3; + /** + * Bit 62 is last shadow linked list item + * 0x1 for indicate shadowreg/LLI content is the last one + * 0x0 for indicate shadowreg/LLI content not the last one + */ + uint64_t shadowreg_or_lli_last : 1; + /** + * Bit 63 is last shadow linked list item valid + * 0x1 for indicate shadowreg/LLI content is valid + * 0x0 for indicate shadowreg/LLI content is invalid + */ + uint64_t shadowreg_or_lli_valid : 1; +} __attribute__((packed, aligned(8))) dmac_ch_ctl_t; + +typedef union _dmac_ch_ctl_u +{ + dmac_ch_ctl_t ch_ctl; + uint64_t data; +} dmac_ch_ctl_u_t; + +typedef struct _dmac_ch_cfg +{ + /** + * Bit[1:0] is source multi block transfer type + * 0x0 for continuous multiblock type + * 0x1 for reload multiblock type + * 0x2 for shadow register based multiblock type + * 0x3 for linked lisr bases multiblock type + */ + uint64_t src_multblk_type : 2; + /** + * Bit[3:2] is source multi block transfer type + * 0x0 for continuous multiblock type + * 0x1 for reload multiblock type + * 0x2 for shadow register based multiblock type + * 0x3 for linked lisr bases multiblock type + */ + uint64_t dst_multblk_type : 2; + /* Bits [31:4] is reserved*/ + uint64_t rsvd1 : 28; + /** + * Bits [34:32] is transfer type and flow control + * 0x0 transfer memory to memory and flow controler is dmac + * 0x1 transfer memory to peripheral and flow controler is dmac + * 0x2 transfer peripheral to memory and flow controler is dmac + * 0x3 transfer peripheral to peripheral and flow controler is dmac + * 0x4 transfer peripheral to memory and flow controler is + * source peripheral + * 0x5 transfer peripheral to peripheral and flow controler + * is source peripheral + * 0x6 transfer memory to peripheral and flow controler is + * destination peripheral + * 0x7 transfer peripheral to peripheral and flow controler + * is destination peripheral + */ + uint64_t tt_fc : 3; + /** + * Bit 35 is source software or hardware handshaking select + * 0x1 for software handshaking is used + * 0x0 for hardware handshaking is used + */ + uint64_t hs_sel_src : 1; + /** + * Bit 36 is destination software or hardware handshaking select + *0x1 for software handshaking is used + *0x0 for hardware handshaking is used + */ + uint64_t hs_sel_dst : 1; + /** + * Bit 37 is sorce hardware handshaking interface polarity + * 0x1 active low, 0x0 active high + */ + uint64_t src_hwhs_pol : 1; + /** + * Bit 38 is destination hardware handshaking interface polarity + * 0x1 active low, 0x0 active high + */ + uint64_t dst_hwhs_pol : 1; + /** + * Bits [41:39] is assign a hardware handshaking interface + * to source of channel x + */ + uint64_t src_per : 4; + /* Bit 43 is reserved*/ + uint64_t rsvd3 : 1; + /** + * Bits [46:44] is assign a hardware handshaking interface + * to destination of channel x + */ + uint64_t dst_per : 4; + /* Bit 48 is reserved*/ + uint64_t rsvd5 : 1; + /* Bits [51:49] is channel priority,7 is highest, 0 is lowest*/ + uint64_t ch_prior : 3; + /** + * Bit 52 is channel lock bit + * 0x0 for channel is not locked, 0x1 for channel is locked + */ + uint64_t lock_ch : 1; + /** + * Bits [54:53] is chnannel lock level + * 0x0 for duration of channel is locked for entire DMA transfer + * 0x1 for duration of channel is locked for current block transfer + */ + uint64_t lock_ch_l : 2; + uint64_t src_osr_lmt : 4; + /* Bits [58:55] is source outstanding request limit */ + uint64_t dst_osr_lmt : 4; + /* Bits [62:59] is destination outstanding request limit */ +} __attribute__((packed, aligned(8))) dmac_ch_cfg_t; + +typedef union _dmac_ch_cfg_u +{ + dmac_ch_cfg_t ch_cfg; + uint64_t data; +} dmac_ch_cfg_u_t; + +typedef struct _dmac_ch_llp +{ + /** + * Bit 0 is LLI master select + * 0x0 for next linked list item resides on AXI madster1 interface + * 0x1 for next linked list item resides on AXI madster2 interface + */ + uint64_t lms : 1; + /* Bits [5:1] is reserved */ + uint64_t rsvd1 : 5; + /* Bits [63:6] is starting address memeory of LLI block */ + uint64_t loc : 58; +} __attribute__((packed, aligned(8))) dmac_ch_llp_t; + +typedef union _dmac_ch_llp_u +{ + dmac_ch_llp_t llp; + uint64_t data; +} dmac_ch_llp_u_t; + +typedef struct _dmac_ch_status +{ + /* Bits [21:0] is completed block transfer size */ + uint64_t cmpltd_blk_size : 22; + /* Bits [46:32] is reserved */ + uint64_t rsvd1 : 15; + /* Bits [63:47] is reserved */ + uint64_t rsvd2 : 17; +} __attribute__((packed, aligned(8))) dmac_ch_status_t; + +typedef union _dmac_ch_status_u +{ + dmac_ch_status_t status; + uint64_t data; +} dmac_ch_status_u_t; + +typedef struct _dmac_ch_swhssrc +{ + /** + * Bit 0 is software handshake request for channel source + * 0x1 source periphraral request for a dma transfer + * 0x0 source peripheral is not request for a burst transfer + */ + uint64_t swhs_req_src : 1; + /** + * Bit 1 is write enable bit for software handshake request + *0x1 for enable, 0x0 for disable + */ + uint64_t swhs_req_src_we : 1; + /** + * Bit 2 is software handshake single request for channel source + * 0x1 for source peripheral requesr for a single dma transfer + * 0x0 for source peripheral is not requesting for a single transfer + */ + uint64_t swhs_sglreq_src : 1; + /** + * Bit 3 is write enable bit for software handshake + * single request for channle source + * 0x1 for enable write, 0x0 for disable write + */ + uint64_t swhs_sglreq_src_we : 1; + /** + * Bit 4 software handshake last request for channel source + * 0x1 for current transfer is last transfer + * 0x0 for current transfer is not the last transfer + */ + uint64_t swhs_lst_src : 1; + /** + * Bit 5 is write enable bit for software + * handshake last request + * 0x1 for enable, 0x0 for disable + */ + uint64_t swhs_lst_src_we : 1; + /* Bits [63:6] is reserved */ + uint64_t rsvd : 58; +} __attribute__((packed, aligned(8))) dmac_ch_swhssrc_t; + +typedef union _dmac_ch_swhssrc_u +{ + dmac_ch_swhssrc_t swhssrc; + uint64_t data; +} dmac_ch_swhssrc_u_t; + +typedef struct _dmac_ch_swhsdst +{ + /** + * Bit 0 is software handshake request for channel destination + * 0x1 destination periphraral request for a dma transfer + * 0x0 destination peripheral is not request for a burst transfer + */ + uint64_t swhs_req_dst : 1; + /** + * Bit 1 is write enable bit for software handshake request + * 0x1 for enable, 0x0 for disable + */ + uint64_t swhs_req_dst_we : 1; + /** + * Bit 2 is software handshake single request for channel destination + * 0x1 for destination peripheral requesr for a single dma transfer + * 0x0 for destination peripheral is not requesting + * for a single transfer + */ + uint64_t swhs_sglreq_dst : 1; + /** + * Bit 3 is write enable bit for software handshake + * single request for channle destination + * 0x1 for enable write, 0x0 for disable write + */ + uint64_t swhs_sglreq_dst_we : 1; + /** + * Bit 4 software handshake last request for channel dstination + * 0x1 for current transfer is last transfer + * 0x0 for current transfer is not the last transfer + */ + uint64_t swhs_lst_dst : 1; + /** + * Bit 5 is write enable bit for software handshake last request + * 0x1 for enable, 0x0 for disable + */ + uint64_t swhs_lst_dst_we : 1; + /* Bits [63:6] is reserved */ + uint64_t rsvd : 58; +} __attribute__((packed, aligned(8))) dmac_ch_swhsdst_t; + +typedef union _dmac_ch_swhsdst_u +{ + dmac_ch_swhsdst_t swhsdst; + uint64_t data; +} dmac_ch_swhsdst_u_t; + +typedef struct _dmac_ch_blk_tfr_resumereq +{ + /** + * Bit 0 is block transfer resume request bit + * 0x1 for request for resuming + * 0x0 for no request to resume + */ + uint64_t blk_tfr_resumereq : 1; + /* Bits [63:1] is reserved */ + uint64_t rsvd : 63; +} __attribute__((packed, aligned(8))) dmac_ch_blk_tfr_resumereq_t; + +typedef union _dmac_ch_blk_tfr_resumereq_u +{ + dmac_ch_blk_tfr_resumereq_t blk_tfr_resumereq; + uint64_t data; +} dmac_ch_blk_tfr_resumereq_u_t; + +typedef struct _dmac_ch_intstatus_enable +{ + /* Bit 0 is block transfer done interrupt status enable */ + uint64_t enable_block_tfr_done_intstatus : 1; + /* DMA transfer done interrupt status enable */ + uint64_t enable_dma_tfr_done_intstat : 1; + /* Bit 2 reserved */ + uint64_t rsvd1 : 1; + /* Bit 3 source transaction complete status enable */ + uint64_t enable_src_transcomp_intstat : 1; + /* Bit 4 destination transaction complete */ + uint64_t enable_dst_transcomp_intstat : 1; + /* Bit 5 Source Decode Error Status Enable */ + uint64_t enable_src_dec_err_intstat : 1; + /* Bit 6 Destination Decode Error Status Enable */ + uint64_t enable_dst_dec_err_intstat : 1; + /* Bit 7 Source Slave Error Status Enable */ + uint64_t enable_src_slv_err_intstat : 1; + /* Bit 8 Destination Slave Error Status Enable */ + uint64_t enable_dst_slv_err_intstat : 1; + /* Bit 9 LLI Read Decode Error Status Enable */ + uint64_t enable_lli_rd_dec_err_intstat : 1; + /* Bit 10 LLI WRITE Decode Error Status Enable */ + uint64_t enable_lli_wr_dec_err_intstat : 1; + /* Bit 11 LLI Read Slave Error Status Enable */ + uint64_t enable_lli_rd_slv_err_intstat : 1; + /* Bit 12 LLI WRITE Slave Error Status Enable */ + uint64_t enable_lli_wr_slv_err_intstat : 1; + uint64_t rsvd2 : 51; +} dmac_ch_intstatus_enable_t; + +typedef union _dmac_ch_intstatus_enable_u +{ + dmac_ch_intstatus_enable_t ch_intstatus_enable; + uint64_t data; +} dmac_ch_intstatus_enable_u_t; + +typedef struct _dmac_ch_intclear +{ + /* Bit 0 block transfer done interrupt clear bit.*/ + uint64_t blk_tfr_done_intstat : 1; + /* Bit 1 DMA transfer done interrupt clear bit */ + uint64_t dma_tfr_done_intstat : 1; + /* Bit 2 is reserved */ + uint64_t resv1 : 1; + uint64_t resv2 : 61; +} __attribute__((packed, aligned(8))) dmac_ch_intclear_t; + +typedef union _dmac_ch_intclear_u +{ + uint64_t data; + dmac_ch_intclear_t intclear; +} dmac_ch_intclear_u_t; + +typedef struct _dmac_channel +{ + /* (0x100) SAR Address Register */ + uint64_t sar; + /* (0x108) DAR Address Register */ + uint64_t dar; + /* (0x110) Block Transfer Size Register */ + uint64_t block_ts; + /* (0x118) Control Register */ + uint64_t ctl; + /* (0x120) Configure Register */ + uint64_t cfg; + /* (0x128) Linked List Pointer register */ + uint64_t llp; + /* (0x130) Channelx Status Register */ + uint64_t status; + /* (0x138) Channelx Software handshake Source Register */ + uint64_t swhssrc; + /* (0x140) Channelx Software handshake Destination Register */ + uint64_t swhsdst; + /* (0x148) Channelx Block Transfer Resume Request Register */ + uint64_t blk_tfr; + /* (0x150) Channelx AXI ID Register */ + uint64_t axi_id; + /* (0x158) Channelx AXI QOS Register */ + uint64_t axi_qos; + /* Reserved address */ + uint64_t reserved1[4]; + /* (0x180) Interrupt Status Enable Register */ + uint64_t intstatus_en; + /* (0x188) Channelx Interrupt Status Register */ + uint64_t intstatus; + /* (0x190) Interrupt Siganl Enable Register */ + uint64_t intsignal_en; + /* (0x198) Interrupt Clear Register */ + uint64_t intclear; + uint64_t reserved2[12]; +} __attribute__((packed, aligned(8))) dmac_channel_t; + +typedef struct _dmac +{ + /* (0x00) DMAC ID Rgister */ + uint64_t id; + /* (0x08) DMAC COMPVER Register */ + uint64_t compver; + /* (0x10) DMAC Configure Register */ + uint64_t cfg; + /* (0x18) Channel Enable Register */ + uint64_t chen; + uint64_t reserved1[2]; + /* (0x30) DMAC Interrupt Status Register */ + uint64_t intstatus; + /* (0x38) DMAC Common register Interrupt Status Register */ + uint64_t com_intclear; + /* (0x40) DMAC Common Interrupt Enable Register */ + uint64_t com_intstatus_en; + /* (0x48) DMAC Common Interrupt Signal Enable Register */ + uint64_t com_intsignal_en; + /* (0x50) DMAC Common Interrupt Status */ + uint64_t com_intstatus; + /* (0x58) DMAC Reset register */ + uint64_t reset; + uint64_t reserved2[20]; + dmac_channel_t channel[DMAC_CHANNEL_COUNT]; +} __attribute__((packed, aligned(8))) dmac_t; + +typedef struct _dmac_channel_config +{ + uint64_t sar; + uint64_t dar; + uint8_t ctl_sms; + uint8_t ctl_dms; + uint8_t ctl_src_msize; + uint8_t ctl_drc_msize; + uint8_t ctl_sinc; + uint8_t ctl_dinc; + uint8_t ctl_src_tr_width; + uint8_t ctl_dst_tr_width; + uint8_t ctl_ioc_blktfr; + uint8_t ctl_src_stat_en; + uint8_t ctl_dst_stat_en; + uint8_t cfg_dst_per; + uint8_t cfg_src_per; + uint8_t cfg_src_hs_pol; + uint8_t cfg_dst_hs_pol; + uint8_t cfg_hs_sel_src; + uint8_t cfg_hs_sel_dst; + uint64_t cfg_src_multblk_type; + uint64_t cfg_dst_multblk_type; + uint64_t llp_loc; + uint8_t llp_lms; + uint64_t ctl_block_ts; + uint8_t ctl_tt_fc; + uint8_t cfg_protctl; + uint8_t cfg_fifo_mode; + uint8_t cfg_fcmode; + uint8_t cfg_lock_ch_l; + uint8_t cfg_ch_prior; +} dmac_channel_config_t; + +#define LIST_ENTRY(ptr, type, member) \ + ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member))) + +struct list_head_t +{ + struct list_head_t *next, *prev; +}; + +/** + * @brief Dmac.data/dw_dmac_lli_item + * + * @desc This structure is used when creating Linked List Items. + * + * @see dw_dmac_addLliItem() + */ +typedef struct _dmac_lli_item +{ + uint64_t sar; + uint64_t dar; + uint64_t ch_block_ts; + uint64_t llp; + uint64_t ctl; + uint64_t sstat; + uint64_t dstat; + uint64_t resv; +} __attribute__((packed, aligned(64))) dmac_lli_item_t; + +extern volatile dmac_t *const dmac; + +/** + * @brief Dmac initialize + */ +void DmacInit(void); + +/** + * @brief Set dmac param + * + * @param[in] channel_num Dmac channel + * @param[in] src Dmac source + * @param[in] dest Dmac dest + * @param[in] src_inc Source address increase or not + * @param[in] dest_inc Dest address increase or not + * @param[in] dmac_burst_size Dmac burst length + * @param[in] dmac_trans_width Dmac transfer data width + * @param[in] BlockSize Dmac transfer length + * + */ +void dmac_set_single_mode(dmac_channel_number_t channel_num, + const void *src, void *dest, dmac_address_increment_t src_inc, + dmac_address_increment_t dest_inc, + dmac_burst_trans_length_t dmac_burst_size, + dmac_transfer_width_t dmac_trans_width, + size_t BlockSize); + +/** + * @brief Determine the transfer is complete or not + * + * @param[in] channel_num Dmac channel + * + * @return result + * - 0 uncompleted + * - 1 completed +*/ +int dmac_is_done(dmac_channel_number_t channel_num); + +/** + * @brief Wait for dmac work done + * + * @param[in] channel_num Dmac channel + * + */ +void dmac_wait_done(dmac_channel_number_t channel_num); + +/** + * @brief Determine the dma is idle or not + * + * @param[in] channel_num Dmac channel + * + * @return result + * - 0 busy + * - 1 idel +*/ +int dmac_is_idle(dmac_channel_number_t channel_num); + +/** + * @brief Wait for dmac idle + * + * @param[in] channel_num Dmac channel + * + */ +void dmac_wait_idle(dmac_channel_number_t channel_num); + +/** + * @brief Set interrupt param + * + * @param[in] channel_num Dmac channel + * @param[in] dmac_callback Dmac interrupt callback + * @param[in] ctx The param of callback + * @param[in] priority Interrupt priority + */ +void dmac_set_irq(dmac_channel_number_t channel_num , plic_irq_callback_t dmac_callback, void *ctx, uint32_t priority); + +/** + * @brief Set interrupt param + * + * @param[in] channel_num Dmac channel + * @param[in] dmac_callback Dmac interrupt callback + * @param[in] ctx The param of callback + * @param[in] priority Interrupt priority + */ +void dmac_irq_register(dmac_channel_number_t channel_num , plic_irq_callback_t dmac_callback, void *ctx, uint32_t priority); + + +/** + * @brief Unregister dmac interrupt + * + * @param[in] channel_num Dmac channel + * + */ +void dmac_irq_unregister(dmac_channel_number_t channel_num); + +/** + * @brief Disable dmac interrupt + * + * @param[in] channel_num Dmac channel + * + */ +void dmac_free_irq(dmac_channel_number_t channel_num); + +/** + * @brief Set source dest and length + * + * @param[in] channel_num Dmac channel + * @param[in] src Source + * @param[in] dest Dest + * @param[in] len The length of dmac transfer + */ +void dmac_set_src_dest_length(dmac_channel_number_t channel_num, const void *src, void *dest, size_t len); + +/** + * @brief Disable dmac channel interrupt + * + * @param[in] channel_num Dmac channel + * +*/ +void dmac_disable_channel_interrupt(dmac_channel_number_t channel_num); + +/** + * @brief Disable dmac channel + * + * @param[in] channel_num Dmac channel + * +*/ +void dmac_channel_disable(dmac_channel_number_t channel_num); + +/** + * @brief Enable dmac channel + * + * @param[in] channel_num Dmac channel + * +*/ +void dmac_channel_enable(dmac_channel_number_t channel_num); + +#ifdef __cplusplus +} +#endif + +#endif /* __DMAC_H__ */ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/drv_io_config.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/drv_io_config.h new file mode 100644 index 000000000..9a9145910 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/drv_io_config.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-19 ZYH first version + */ + +/** + * @file drv_io_config.h + * @brief define edu-riscv64-board io configure + * @version 2.0 + * @author AIIT XUOS Lab + * @date 2022-10-17 + */ + +/************************************************* +File name: drv_io_config.h +Description: define edu-riscv64-board io configure +Others: take RT-Thread v4.0.2/bsp/k210/driver/drv_io_config.h for references + https://github.com/RT-Thread/rt-thread/tree/v4.0.2 +History: +1. Date: 2022-10-17 +Author: AIIT XUOS Lab +Modification: add edu-riscv64-board io configure define +*************************************************/ + +#ifndef __DRV_IO_CONFIG_H__ +#define __DRV_IO_CONFIG_H__ + +enum HS_GPIO_CONFIG { +#ifdef BSP_USING_LCD + LCD_DC_PIN = 0, /* LCD DC PIN */ +#endif +#ifdef BSP_SPI1_USING_SS0 + SPI1_CS0_PIN, +#endif +#ifdef BSP_SPI1_USING_SS1 + SPI1_CS1_PIN, +#endif +#ifdef BSP_SPI1_USING_SS2 + SPI1_CS2_PIN, +#endif +#ifdef BSP_SPI1_USING_SS3 + SPI1_CS3_PIN, +#endif +#ifdef BSP_USING_W5500 + WIZ_RST_PIN, + WIZ_INT_PIN, +#endif + GPIO_ALLOC_START /* index of gpio driver start */ +}; + +#ifdef BSP_USING_CH438 +#define FPIOA_CH438_ALE 12 +#define FPIOA_CH438_NWR 13 +#define FPIOA_CH438_NRD 14 +#define FPIOA_CH438_D0 15 +#define FPIOA_CH438_D1 16 +#define FPIOA_CH438_D2 17 +#define FPIOA_CH438_D3 18 +#define FPIOA_CH438_D4 19 +#define FPIOA_CH438_D5 20 +#define FPIOA_CH438_D6 21 +#define FPIOA_CH438_D7 22 +#define FPIOA_CH438_INT 23 + +#define BSP_CH438_ALE_PIN 24 +#define BSP_CH438_NWR_PIN 25 +#define BSP_CH438_NRD_PIN 26 +#define BSP_CH438_D0_PIN 27 +#define BSP_CH438_D1_PIN 28 +#define BSP_CH438_D2_PIN 29 +#define BSP_CH438_D3_PIN 30 +#define BSP_CH438_D4_PIN 31 +#define BSP_CH438_D5_PIN 32 +#define BSP_CH438_D6_PIN 33 +#define BSP_CH438_D7_PIN 34 +#define BSP_CH438_INT_PIN 35 +#endif + +#ifdef BSP_USING_SOFT_SPI +#define FPIOA_SOFT_SPI_SCK 26 +#define FPIOA_SOFT_SPI_MIOS 25 +#define FPIOA_SOFT_SPI_MSOI 27 +#define FPIOA_SOFT_SPI_NCS 28 + +#define BSP_SOFT_SPI_SCK_PIN 26 +#define BSP_SOFT_SPI_MIOS_PIN 25 +#define BSP_SOFT_SPI_MSOI_PIN 27 +#define BSP_SOFT_SPI_NCS_PIN 28 + +#endif + +#ifdef BSP_USING_LED +#define BSP_LED_PIN 29 +#endif + +#ifdef BSP_USING_KEY +#define BSP_KEY_PIN 31 +#endif + +#ifdef BSP_USING_LORA +#define BSP_E220_M0_PIN 32 +#define BSP_E220_M1_PIN 33 +#endif + +#ifdef BSP_USING_RS485 +#define BSP_485_DIR_PIN 24 +#endif + +extern int IoConfigInit(void); + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/dvp.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/dvp.h new file mode 100644 index 000000000..9cc6568f0 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/dvp.h @@ -0,0 +1,279 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file dvp.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#ifndef __DVP_H__ +#define __DVP_H__ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* clang-format off */ +/** + * @brief DVP object + */ +typedef struct _dvp +{ + uint32_t dvp_cfg; + uint32_t r_addr; + uint32_t g_addr; + uint32_t b_addr; + uint32_t cmos_cfg; + uint32_t sccb_cfg; + uint32_t sccb_ctl; + uint32_t axi; + uint32_t sts; + uint32_t reverse; + uint32_t rgb_addr; +} __attribute__((packed, aligned(4))) dvp_t; + +/* DVP Config Register */ +#define DVP_CFG_START_INT_ENABLE 0x00000001U +#define DVP_CFG_FINISH_INT_ENABLE 0x00000002U +#define DVP_CFG_AI_OUTPUT_ENABLE 0x00000004U +#define DVP_CFG_DISPLAY_OUTPUT_ENABLE 0x00000008U +#define DVP_CFG_AUTO_ENABLE 0x00000010U +#define DVP_CFG_BURST_SIZE_4BEATS 0x00000100U +#define DVP_CFG_FORMAT_MASK 0x00000600U +#define DVP_CFG_RGB_FORMAT 0x00000000U +#define DVP_CFG_YUV_FORMAT 0x00000200U +#define DVP_CFG_Y_FORMAT 0x00000600U +#define DVP_CFG_HREF_BURST_NUM_MASK 0x000FF000U +#define DVP_CFG_HREF_BURST_NUM(x) ((x) << 12) +#define DVP_CFG_LINE_NUM_MASK 0x3FF00000U +#define DVP_CFG_LINE_NUM(x) ((x) << 20) + +/* DVP CMOS Config Register */ +#define DVP_CMOS_CLK_DIV_MASK 0x000000FFU +#define DVP_CMOS_CLK_DIV(x) ((x) << 0) +#define DVP_CMOS_CLK_ENABLE 0x00000100U +#define DVP_CMOS_RESET 0x00010000U +#define DVP_CMOS_POWER_DOWN 0x01000000U + +/* DVP SCCB Config Register */ +#define DVP_SCCB_BYTE_NUM_MASK 0x00000003U +#define DVP_SCCB_BYTE_NUM_2 0x00000001U +#define DVP_SCCB_BYTE_NUM_3 0x00000002U +#define DVP_SCCB_BYTE_NUM_4 0x00000003U +#define DVP_SCCB_SCL_LCNT_MASK 0x0000FF00U +#define DVP_SCCB_SCL_LCNT(x) ((x) << 8) +#define DVP_SCCB_SCL_HCNT_MASK 0x00FF0000U +#define DVP_SCCB_SCL_HCNT(x) ((x) << 16) +#define DVP_SCCB_RDATA_BYTE(x) ((x) >> 24) + +/* DVP SCCB Control Register */ +#define DVP_SCCB_WRITE_DATA_ENABLE 0x00000001U +#define DVP_SCCB_DEVICE_ADDRESS(x) ((x) << 0) +#define DVP_SCCB_REG_ADDRESS(x) ((x) << 8) +#define DVP_SCCB_WDATA_BYTE0(x) ((x) << 16) +#define DVP_SCCB_WDATA_BYTE1(x) ((x) << 24) + +/* DVP AXI Register */ +#define DVP_AXI_GM_MLEN_MASK 0x000000FFU +#define DVP_AXI_GM_MLEN_1BYTE 0x00000000U +#define DVP_AXI_GM_MLEN_4BYTE 0x00000003U + +/* DVP STS Register */ +#define DVP_STS_FRAME_START 0x00000001U +#define DVP_STS_FRAME_START_WE 0x00000002U +#define DVP_STS_FRAME_FINISH 0x00000100U +#define DVP_STS_FRAME_FINISH_WE 0x00000200U +#define DVP_STS_DVP_EN 0x00010000U +#define DVP_STS_DVP_EN_WE 0x00020000U +#define DVP_STS_SCCB_EN 0x01000000U +#define DVP_STS_SCCB_EN_WE 0x02000000U +/* clang-format on */ + +typedef enum _dvp_output_mode +{ + DVP_OUTPUT_AI, + DVP_OUTPUT_DISPLAY, +} dvp_output_mode_t; + +/** + * @brief DVP object instance + */ +extern volatile dvp_t* const dvp; + +/** + * @brief Initialize DVP + */ +void dvp_init(uint8_t reg_len); + +/** + * @brief Set image format + * + * @param[in] format The image format + */ +void dvp_set_image_format(uint32_t format); + +/** + * @brief Set image size + * + * @param[in] width The width of image + * @param[in] height The height of image + */ +void dvp_set_image_size(uint32_t width, uint32_t height); + +/** + * @brief Set the address of RGB for AI + * + * @param[in] r_addr The R address of RGB + * @param[in] g_addr The G address of RGB + * @param[in] b_addr The B address of RGB + */ +void dvp_set_ai_addr(uint32_t r_addr, uint32_t g_addr, uint32_t b_addr); + +/** + * @brief Set the address of RGB for display + * + * @param[in] r_addr The R address of RGB + * @param[in] g_addr The G address of RGB + * @param[in] b_addr The B address of RGB + */ +void dvp_set_display_addr(uint32_t addr); + +/** + * @brief The frame start transfer + */ +void dvp_start_frame(void); + +/** + * @brief The DVP convert start + */ +void dvp_start_convert(void); + +/** + * @brief The DVP convert finish + */ +void dvp_finish_convert(void); + +/** + * @brief Get the image data + * + * @note The image data stored in the address of RGB + */ +void dvp_get_image(void); + +/** + * @brief Use SCCB write register + * + * @param[in] DevAddr The device address + * @param[in] reg_addr The register address + * @param[in] reg_data The register data + */ +void dvp_sccb_send_data(uint8_t DevAddr, uint16_t reg_addr, uint8_t reg_data); + +/** + * @brief Use SCCB read register + * + * @param[in] DevAddr The device address + * @param[in] reg_addr The register address + * + * @return The register value + */ +uint8_t dvp_sccb_receive_data(uint8_t DevAddr, uint16_t reg_addr); + +/** + * @brief Enable dvp burst + */ +void dvp_enable_burst(void); + +/** + * @brief Disable dvp burst + */ +void dvp_disable_burst(void); + +/** + * @brief Enable or disable dvp interrupt + * + * @param[in] interrupt Dvp interrupt + * @param[in] status 0:disable 1:enable + * + */ +void dvp_config_interrupt(uint32_t interrupt, uint8_t enable); + +/** + * @brief Get dvp interrupt status + * + * @param[in] interrupt Dvp interrupt + * + * + * @return Interrupt status + * - 0 false + * - 1 true + */ +int dvp_get_interrupt(uint32_t interrupt); + +/** + * @brief Clear dvp interrupt status + * + * @param[in] interrupt Dvp interrupt + * + */ +void dvp_clear_interrupt(uint32_t interrupt); + +/** + * @brief Enable dvp auto mode + */ +void dvp_enable_auto(void); + +/** + * @brief Disable dvp auto mode + */ +void dvp_disable_auto(void); + +/** + * @brief Dvp ouput data enable or not + * + * @param[in] index 0:AI, 1:display + * @param[in] enable 0:disable, 1:enable + * + */ +void dvp_set_output_enable(dvp_output_mode_t index, int enable); + +/** + * @brief Set sccb clock rate + * + * @param[in] clk_rate Sccb clock rate + * + * @return The real sccb clock rate + */ +uint32_t dvp_sccb_set_clk_rate(uint32_t clk_rate); + +/** + * @brief Set xclk rate + * + * @param[in] clk_rate xclk rate + * + * @return The real xclk rate + */ +uint32_t dvp_set_xclk_rate(uint32_t xclk_rate); + +#ifdef __cplusplus +} +#endif + +#endif /* __DVP_H__ */ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/font.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/font.h new file mode 100644 index 000000000..c975f2672 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/font.h @@ -0,0 +1,425 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file font.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#ifndef __FONT_H__ +#define __FONT_H__ +//ASCII char table +//offset 32 +//ASCII char : !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ +//bytes of a single char : (size/8+((size%8)?1:0))*(size/2), size : (12/16/24/32...) code table size + +//12*12 ASCII code +const unsigned char asc2_1206[95][12]={ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/ +{0x00,0x00,0x00,0x00,0x3F,0x40,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/ +{0x00,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x40,0x00,0x00,0x00},/*""",2*/ +{0x09,0x00,0x0B,0xC0,0x3D,0x00,0x0B,0xC0,0x3D,0x00,0x09,0x00},/*"#",3*/ +{0x18,0xC0,0x24,0x40,0x7F,0xE0,0x22,0x40,0x31,0x80,0x00,0x00},/*"$",4*/ +{0x18,0x00,0x24,0xC0,0x1B,0x00,0x0D,0x80,0x32,0x40,0x01,0x80},/*"%",5*/ +{0x03,0x80,0x1C,0x40,0x27,0x40,0x1C,0x80,0x07,0x40,0x00,0x40},/*"&",6*/ +{0x10,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x20,0x40,0x40,0x20},/*"(",8*/ +{0x00,0x00,0x40,0x20,0x20,0x40,0x1F,0x80,0x00,0x00,0x00,0x00},/*")",9*/ +{0x09,0x00,0x06,0x00,0x1F,0x80,0x06,0x00,0x09,0x00,0x00,0x00},/*"*",10*/ +{0x04,0x00,0x04,0x00,0x3F,0x80,0x04,0x00,0x04,0x00,0x00,0x00},/*"+",11*/ +{0x00,0x10,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/ +{0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00},/*"-",13*/ +{0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/ +{0x00,0x20,0x01,0xC0,0x06,0x00,0x38,0x00,0x40,0x00,0x00,0x00},/*"/",15*/ +{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"0",16*/ +{0x00,0x00,0x10,0x40,0x3F,0xC0,0x00,0x40,0x00,0x00,0x00,0x00},/*"1",17*/ +{0x18,0xC0,0x21,0x40,0x22,0x40,0x24,0x40,0x18,0x40,0x00,0x00},/*"2",18*/ +{0x10,0x80,0x20,0x40,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"3",19*/ +{0x02,0x00,0x0D,0x00,0x11,0x00,0x3F,0xC0,0x01,0x40,0x00,0x00},/*"4",20*/ +{0x3C,0x80,0x24,0x40,0x24,0x40,0x24,0x40,0x23,0x80,0x00,0x00},/*"5",21*/ +{0x1F,0x80,0x24,0x40,0x24,0x40,0x34,0x40,0x03,0x80,0x00,0x00},/*"6",22*/ +{0x30,0x00,0x20,0x00,0x27,0xC0,0x38,0x00,0x20,0x00,0x00,0x00},/*"7",23*/ +{0x1B,0x80,0x24,0x40,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"8",24*/ +{0x1C,0x00,0x22,0xC0,0x22,0x40,0x22,0x40,0x1F,0x80,0x00,0x00},/*"9",25*/ +{0x00,0x00,0x00,0x00,0x08,0x40,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/ +{0x00,0x00,0x00,0x00,0x04,0x60,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/ +{0x00,0x00,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0x40,0x40},/*"<",28*/ +{0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x09,0x00,0x00,0x00},/*"=",29*/ +{0x00,0x00,0x40,0x40,0x20,0x80,0x11,0x00,0x0A,0x00,0x04,0x00},/*">",30*/ +{0x18,0x00,0x20,0x00,0x23,0x40,0x24,0x00,0x18,0x00,0x00,0x00},/*"?",31*/ +{0x1F,0x80,0x20,0x40,0x27,0x40,0x29,0x40,0x1F,0x40,0x00,0x00},/*"@",32*/ +{0x00,0x40,0x07,0xC0,0x39,0x00,0x0F,0x00,0x01,0xC0,0x00,0x40},/*"A",33*/ +{0x20,0x40,0x3F,0xC0,0x24,0x40,0x24,0x40,0x1B,0x80,0x00,0x00},/*"B",34*/ +{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x30,0x80,0x00,0x00},/*"C",35*/ +{0x20,0x40,0x3F,0xC0,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"D",36*/ +{0x20,0x40,0x3F,0xC0,0x24,0x40,0x2E,0x40,0x30,0xC0,0x00,0x00},/*"E",37*/ +{0x20,0x40,0x3F,0xC0,0x24,0x40,0x2E,0x00,0x30,0x00,0x00,0x00},/*"F",38*/ +{0x0F,0x00,0x10,0x80,0x20,0x40,0x22,0x40,0x33,0x80,0x02,0x00},/*"G",39*/ +{0x20,0x40,0x3F,0xC0,0x04,0x00,0x04,0x00,0x3F,0xC0,0x20,0x40},/*"H",40*/ +{0x20,0x40,0x20,0x40,0x3F,0xC0,0x20,0x40,0x20,0x40,0x00,0x00},/*"I",41*/ +{0x00,0x60,0x20,0x20,0x20,0x20,0x3F,0xC0,0x20,0x00,0x20,0x00},/*"J",42*/ +{0x20,0x40,0x3F,0xC0,0x24,0x40,0x0B,0x00,0x30,0xC0,0x20,0x40},/*"K",43*/ +{0x20,0x40,0x3F,0xC0,0x20,0x40,0x00,0x40,0x00,0x40,0x00,0xC0},/*"L",44*/ +{0x3F,0xC0,0x3C,0x00,0x03,0xC0,0x3C,0x00,0x3F,0xC0,0x00,0x00},/*"M",45*/ +{0x20,0x40,0x3F,0xC0,0x0C,0x40,0x23,0x00,0x3F,0xC0,0x20,0x00},/*"N",46*/ +{0x1F,0x80,0x20,0x40,0x20,0x40,0x20,0x40,0x1F,0x80,0x00,0x00},/*"O",47*/ +{0x20,0x40,0x3F,0xC0,0x24,0x40,0x24,0x00,0x18,0x00,0x00,0x00},/*"P",48*/ +{0x1F,0x80,0x21,0x40,0x21,0x40,0x20,0xE0,0x1F,0xA0,0x00,0x00},/*"Q",49*/ +{0x20,0x40,0x3F,0xC0,0x24,0x40,0x26,0x00,0x19,0xC0,0x00,0x40},/*"R",50*/ +{0x18,0xC0,0x24,0x40,0x24,0x40,0x22,0x40,0x31,0x80,0x00,0x00},/*"S",51*/ +{0x30,0x00,0x20,0x40,0x3F,0xC0,0x20,0x40,0x30,0x00,0x00,0x00},/*"T",52*/ +{0x20,0x00,0x3F,0x80,0x00,0x40,0x00,0x40,0x3F,0x80,0x20,0x00},/*"U",53*/ +{0x20,0x00,0x3E,0x00,0x01,0xC0,0x07,0x00,0x38,0x00,0x20,0x00},/*"V",54*/ +{0x38,0x00,0x07,0xC0,0x3C,0x00,0x07,0xC0,0x38,0x00,0x00,0x00},/*"W",55*/ +{0x20,0x40,0x39,0xC0,0x06,0x00,0x39,0xC0,0x20,0x40,0x00,0x00},/*"X",56*/ +{0x20,0x00,0x38,0x40,0x07,0xC0,0x38,0x40,0x20,0x00,0x00,0x00},/*"Y",57*/ +{0x30,0x40,0x21,0xC0,0x26,0x40,0x38,0x40,0x20,0xC0,0x00,0x00},/*"Z",58*/ +{0x00,0x00,0x00,0x00,0x7F,0xE0,0x40,0x20,0x40,0x20,0x00,0x00},/*"[",59*/ +{0x00,0x00,0x70,0x00,0x0C,0x00,0x03,0x80,0x00,0x40,0x00,0x00},/*"\",60*/ +{0x00,0x00,0x40,0x20,0x40,0x20,0x7F,0xE0,0x00,0x00,0x00,0x00},/*"]",61*/ +{0x00,0x00,0x20,0x00,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x00},/*"^",62*/ +{0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10},/*"_",63*/ +{0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/ +{0x00,0x00,0x02,0x80,0x05,0x40,0x05,0x40,0x03,0xC0,0x00,0x40},/*"a",65*/ +{0x20,0x00,0x3F,0xC0,0x04,0x40,0x04,0x40,0x03,0x80,0x00,0x00},/*"b",66*/ +{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x40,0x06,0x40,0x00,0x00},/*"c",67*/ +{0x00,0x00,0x03,0x80,0x04,0x40,0x24,0x40,0x3F,0xC0,0x00,0x40},/*"d",68*/ +{0x00,0x00,0x03,0x80,0x05,0x40,0x05,0x40,0x03,0x40,0x00,0x00},/*"e",69*/ +{0x00,0x00,0x04,0x40,0x1F,0xC0,0x24,0x40,0x24,0x40,0x20,0x00},/*"f",70*/ +{0x00,0x00,0x02,0xE0,0x05,0x50,0x05,0x50,0x06,0x50,0x04,0x20},/*"g",71*/ +{0x20,0x40,0x3F,0xC0,0x04,0x40,0x04,0x00,0x03,0xC0,0x00,0x40},/*"h",72*/ +{0x00,0x00,0x04,0x40,0x27,0xC0,0x00,0x40,0x00,0x00,0x00,0x00},/*"i",73*/ +{0x00,0x10,0x00,0x10,0x04,0x10,0x27,0xE0,0x00,0x00,0x00,0x00},/*"j",74*/ +{0x20,0x40,0x3F,0xC0,0x01,0x40,0x07,0x00,0x04,0xC0,0x04,0x40},/*"k",75*/ +{0x20,0x40,0x20,0x40,0x3F,0xC0,0x00,0x40,0x00,0x40,0x00,0x00},/*"l",76*/ +{0x07,0xC0,0x04,0x00,0x07,0xC0,0x04,0x00,0x03,0xC0,0x00,0x00},/*"m",77*/ +{0x04,0x40,0x07,0xC0,0x04,0x40,0x04,0x00,0x03,0xC0,0x00,0x40},/*"n",78*/ +{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x40,0x03,0x80,0x00,0x00},/*"o",79*/ +{0x04,0x10,0x07,0xF0,0x04,0x50,0x04,0x40,0x03,0x80,0x00,0x00},/*"p",80*/ +{0x00,0x00,0x03,0x80,0x04,0x40,0x04,0x50,0x07,0xF0,0x00,0x10},/*"q",81*/ +{0x04,0x40,0x07,0xC0,0x02,0x40,0x04,0x00,0x04,0x00,0x00,0x00},/*"r",82*/ +{0x00,0x00,0x06,0x40,0x05,0x40,0x05,0x40,0x04,0xC0,0x00,0x00},/*"s",83*/ +{0x00,0x00,0x04,0x00,0x1F,0x80,0x04,0x40,0x00,0x40,0x00,0x00},/*"t",84*/ +{0x04,0x00,0x07,0x80,0x00,0x40,0x04,0x40,0x07,0xC0,0x00,0x40},/*"u",85*/ +{0x04,0x00,0x07,0x00,0x04,0xC0,0x01,0x80,0x06,0x00,0x04,0x00},/*"v",86*/ +{0x06,0x00,0x01,0xC0,0x07,0x00,0x01,0xC0,0x06,0x00,0x00,0x00},/*"w",87*/ +{0x04,0x40,0x06,0xC0,0x01,0x00,0x06,0xC0,0x04,0x40,0x00,0x00},/*"x",88*/ +{0x04,0x10,0x07,0x10,0x04,0xE0,0x01,0x80,0x06,0x00,0x04,0x00},/*"y",89*/ +{0x00,0x00,0x04,0x40,0x05,0xC0,0x06,0x40,0x04,0x40,0x00,0x00},/*"z",90*/ +{0x00,0x00,0x00,0x00,0x04,0x00,0x7B,0xE0,0x40,0x20,0x00,0x00},/*"{",91*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xF0,0x00,0x00,0x00,0x00},/*"|",92*/ +{0x00,0x00,0x40,0x20,0x7B,0xE0,0x04,0x00,0x00,0x00,0x00,0x00},/*"}",93*/ +{0x40,0x00,0x80,0x00,0x40,0x00,0x20,0x00,0x20,0x00,0x40,0x00},/*"~",94*/ +}; +//16*16 ASCII鐎涙顑侀梿鍡欏仯闂冿拷 +const unsigned char asc2_1608[95][16]={ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xCC,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/ +{0x00,0x00,0x08,0x00,0x30,0x00,0x60,0x00,0x08,0x00,0x30,0x00,0x60,0x00,0x00,0x00},/*""",2*/ +{0x02,0x20,0x03,0xFC,0x1E,0x20,0x02,0x20,0x03,0xFC,0x1E,0x20,0x02,0x20,0x00,0x00},/*"#",3*/ +{0x00,0x00,0x0E,0x18,0x11,0x04,0x3F,0xFF,0x10,0x84,0x0C,0x78,0x00,0x00,0x00,0x00},/*"$",4*/ +{0x0F,0x00,0x10,0x84,0x0F,0x38,0x00,0xC0,0x07,0x78,0x18,0x84,0x00,0x78,0x00,0x00},/*"%",5*/ +{0x00,0x78,0x0F,0x84,0x10,0xC4,0x11,0x24,0x0E,0x98,0x00,0xE4,0x00,0x84,0x00,0x08},/*"&",6*/ +{0x08,0x00,0x68,0x00,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x18,0x18,0x20,0x04,0x40,0x02,0x00,0x00},/*"(",8*/ +{0x00,0x00,0x40,0x02,0x20,0x04,0x18,0x18,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00},/*")",9*/ +{0x02,0x40,0x02,0x40,0x01,0x80,0x0F,0xF0,0x01,0x80,0x02,0x40,0x02,0x40,0x00,0x00},/*"*",10*/ +{0x00,0x80,0x00,0x80,0x00,0x80,0x0F,0xF8,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x00},/*"+",11*/ +{0x00,0x01,0x00,0x0D,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/ +{0x00,0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80},/*"-",13*/ +{0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/ +{0x00,0x00,0x00,0x06,0x00,0x18,0x00,0x60,0x01,0x80,0x06,0x00,0x18,0x00,0x20,0x00},/*"/",15*/ +{0x00,0x00,0x07,0xF0,0x08,0x08,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"0",16*/ +{0x00,0x00,0x08,0x04,0x08,0x04,0x1F,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"1",17*/ +{0x00,0x00,0x0E,0x0C,0x10,0x14,0x10,0x24,0x10,0x44,0x11,0x84,0x0E,0x0C,0x00,0x00},/*"2",18*/ +{0x00,0x00,0x0C,0x18,0x10,0x04,0x11,0x04,0x11,0x04,0x12,0x88,0x0C,0x70,0x00,0x00},/*"3",19*/ +{0x00,0x00,0x00,0xE0,0x03,0x20,0x04,0x24,0x08,0x24,0x1F,0xFC,0x00,0x24,0x00,0x00},/*"4",20*/ +{0x00,0x00,0x1F,0x98,0x10,0x84,0x11,0x04,0x11,0x04,0x10,0x88,0x10,0x70,0x00,0x00},/*"5",21*/ +{0x00,0x00,0x07,0xF0,0x08,0x88,0x11,0x04,0x11,0x04,0x18,0x88,0x00,0x70,0x00,0x00},/*"6",22*/ +{0x00,0x00,0x1C,0x00,0x10,0x00,0x10,0xFC,0x13,0x00,0x1C,0x00,0x10,0x00,0x00,0x00},/*"7",23*/ +{0x00,0x00,0x0E,0x38,0x11,0x44,0x10,0x84,0x10,0x84,0x11,0x44,0x0E,0x38,0x00,0x00},/*"8",24*/ +{0x00,0x00,0x07,0x00,0x08,0x8C,0x10,0x44,0x10,0x44,0x08,0x88,0x07,0xF0,0x00,0x00},/*"9",25*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x03,0x0C,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/ +{0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/ +{0x00,0x00,0x00,0x80,0x01,0x40,0x02,0x20,0x04,0x10,0x08,0x08,0x10,0x04,0x00,0x00},/*"<",28*/ +{0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x02,0x20,0x00,0x00},/*"=",29*/ +{0x00,0x00,0x10,0x04,0x08,0x08,0x04,0x10,0x02,0x20,0x01,0x40,0x00,0x80,0x00,0x00},/*">",30*/ +{0x00,0x00,0x0E,0x00,0x12,0x00,0x10,0x0C,0x10,0x6C,0x10,0x80,0x0F,0x00,0x00,0x00},/*"?",31*/ +{0x03,0xE0,0x0C,0x18,0x13,0xE4,0x14,0x24,0x17,0xC4,0x08,0x28,0x07,0xD0,0x00,0x00},/*"@",32*/ +{0x00,0x04,0x00,0x3C,0x03,0xC4,0x1C,0x40,0x07,0x40,0x00,0xE4,0x00,0x1C,0x00,0x04},/*"A",33*/ +{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x04,0x11,0x04,0x0E,0x88,0x00,0x70,0x00,0x00},/*"B",34*/ +{0x03,0xE0,0x0C,0x18,0x10,0x04,0x10,0x04,0x10,0x04,0x10,0x08,0x1C,0x10,0x00,0x00},/*"C",35*/ +{0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"D",36*/ +{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x04,0x17,0xC4,0x10,0x04,0x08,0x18,0x00,0x00},/*"E",37*/ +{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x00,0x17,0xC0,0x10,0x00,0x08,0x00,0x00,0x00},/*"F",38*/ +{0x03,0xE0,0x0C,0x18,0x10,0x04,0x10,0x04,0x10,0x44,0x1C,0x78,0x00,0x40,0x00,0x00},/*"G",39*/ +{0x10,0x04,0x1F,0xFC,0x10,0x84,0x00,0x80,0x00,0x80,0x10,0x84,0x1F,0xFC,0x10,0x04},/*"H",40*/ +{0x00,0x00,0x10,0x04,0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x04,0x00,0x00,0x00,0x00},/*"I",41*/ +{0x00,0x03,0x00,0x01,0x10,0x01,0x10,0x01,0x1F,0xFE,0x10,0x00,0x10,0x00,0x00,0x00},/*"J",42*/ +{0x10,0x04,0x1F,0xFC,0x11,0x04,0x03,0x80,0x14,0x64,0x18,0x1C,0x10,0x04,0x00,0x00},/*"K",43*/ +{0x10,0x04,0x1F,0xFC,0x10,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x0C,0x00,0x00},/*"L",44*/ +{0x10,0x04,0x1F,0xFC,0x1F,0x00,0x00,0xFC,0x1F,0x00,0x1F,0xFC,0x10,0x04,0x00,0x00},/*"M",45*/ +{0x10,0x04,0x1F,0xFC,0x0C,0x04,0x03,0x00,0x00,0xE0,0x10,0x18,0x1F,0xFC,0x10,0x00},/*"N",46*/ +{0x07,0xF0,0x08,0x08,0x10,0x04,0x10,0x04,0x10,0x04,0x08,0x08,0x07,0xF0,0x00,0x00},/*"O",47*/ +{0x10,0x04,0x1F,0xFC,0x10,0x84,0x10,0x80,0x10,0x80,0x10,0x80,0x0F,0x00,0x00,0x00},/*"P",48*/ +{0x07,0xF0,0x08,0x18,0x10,0x24,0x10,0x24,0x10,0x1C,0x08,0x0A,0x07,0xF2,0x00,0x00},/*"Q",49*/ +{0x10,0x04,0x1F,0xFC,0x11,0x04,0x11,0x00,0x11,0xC0,0x11,0x30,0x0E,0x0C,0x00,0x04},/*"R",50*/ +{0x00,0x00,0x0E,0x1C,0x11,0x04,0x10,0x84,0x10,0x84,0x10,0x44,0x1C,0x38,0x00,0x00},/*"S",51*/ +{0x18,0x00,0x10,0x00,0x10,0x04,0x1F,0xFC,0x10,0x04,0x10,0x00,0x18,0x00,0x00,0x00},/*"T",52*/ +{0x10,0x00,0x1F,0xF8,0x10,0x04,0x00,0x04,0x00,0x04,0x10,0x04,0x1F,0xF8,0x10,0x00},/*"U",53*/ +{0x10,0x00,0x1E,0x00,0x11,0xE0,0x00,0x1C,0x00,0x70,0x13,0x80,0x1C,0x00,0x10,0x00},/*"V",54*/ +{0x1F,0xC0,0x10,0x3C,0x00,0xE0,0x1F,0x00,0x00,0xE0,0x10,0x3C,0x1F,0xC0,0x00,0x00},/*"W",55*/ +{0x10,0x04,0x18,0x0C,0x16,0x34,0x01,0xC0,0x01,0xC0,0x16,0x34,0x18,0x0C,0x10,0x04},/*"X",56*/ +{0x10,0x00,0x1C,0x00,0x13,0x04,0x00,0xFC,0x13,0x04,0x1C,0x00,0x10,0x00,0x00,0x00},/*"Y",57*/ +{0x08,0x04,0x10,0x1C,0x10,0x64,0x10,0x84,0x13,0x04,0x1C,0x04,0x10,0x18,0x00,0x00},/*"Z",58*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xFE,0x40,0x02,0x40,0x02,0x40,0x02,0x00,0x00},/*"[",59*/ +{0x00,0x00,0x30,0x00,0x0C,0x00,0x03,0x80,0x00,0x60,0x00,0x1C,0x00,0x03,0x00,0x00},/*"\",60*/ +{0x00,0x00,0x40,0x02,0x40,0x02,0x40,0x02,0x7F,0xFE,0x00,0x00,0x00,0x00,0x00,0x00},/*"]",61*/ +{0x00,0x00,0x00,0x00,0x20,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x00,0x00},/*"^",62*/ +{0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01},/*"_",63*/ +{0x00,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/ +{0x00,0x00,0x00,0x98,0x01,0x24,0x01,0x44,0x01,0x44,0x01,0x44,0x00,0xFC,0x00,0x04},/*"a",65*/ +{0x10,0x00,0x1F,0xFC,0x00,0x88,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x70,0x00,0x00},/*"b",66*/ +{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x00},/*"c",67*/ +{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x11,0x08,0x1F,0xFC,0x00,0x04},/*"d",68*/ +{0x00,0x00,0x00,0xF8,0x01,0x44,0x01,0x44,0x01,0x44,0x01,0x44,0x00,0xC8,0x00,0x00},/*"e",69*/ +{0x00,0x00,0x01,0x04,0x01,0x04,0x0F,0xFC,0x11,0x04,0x11,0x04,0x11,0x00,0x18,0x00},/*"f",70*/ +{0x00,0x00,0x00,0xD6,0x01,0x29,0x01,0x29,0x01,0x29,0x01,0xC9,0x01,0x06,0x00,0x00},/*"g",71*/ +{0x10,0x04,0x1F,0xFC,0x00,0x84,0x01,0x00,0x01,0x00,0x01,0x04,0x00,0xFC,0x00,0x04},/*"h",72*/ +{0x00,0x00,0x01,0x04,0x19,0x04,0x19,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"i",73*/ +{0x00,0x00,0x00,0x03,0x00,0x01,0x01,0x01,0x19,0x01,0x19,0xFE,0x00,0x00,0x00,0x00},/*"j",74*/ +{0x10,0x04,0x1F,0xFC,0x00,0x24,0x00,0x40,0x01,0xB4,0x01,0x0C,0x01,0x04,0x00,0x00},/*"k",75*/ +{0x00,0x00,0x10,0x04,0x10,0x04,0x1F,0xFC,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00},/*"l",76*/ +{0x01,0x04,0x01,0xFC,0x01,0x04,0x01,0x00,0x01,0xFC,0x01,0x04,0x01,0x00,0x00,0xFC},/*"m",77*/ +{0x01,0x04,0x01,0xFC,0x00,0x84,0x01,0x00,0x01,0x00,0x01,0x04,0x00,0xFC,0x00,0x04},/*"n",78*/ +{0x00,0x00,0x00,0xF8,0x01,0x04,0x01,0x04,0x01,0x04,0x01,0x04,0x00,0xF8,0x00,0x00},/*"o",79*/ +{0x01,0x01,0x01,0xFF,0x00,0x85,0x01,0x04,0x01,0x04,0x00,0x88,0x00,0x70,0x00,0x00},/*"p",80*/ +{0x00,0x00,0x00,0x70,0x00,0x88,0x01,0x04,0x01,0x04,0x01,0x05,0x01,0xFF,0x00,0x01},/*"q",81*/ +{0x01,0x04,0x01,0x04,0x01,0xFC,0x00,0x84,0x01,0x04,0x01,0x00,0x01,0x80,0x00,0x00},/*"r",82*/ +{0x00,0x00,0x00,0xCC,0x01,0x24,0x01,0x24,0x01,0x24,0x01,0x24,0x01,0x98,0x00,0x00},/*"s",83*/ +{0x00,0x00,0x01,0x00,0x01,0x00,0x07,0xF8,0x01,0x04,0x01,0x04,0x00,0x00,0x00,0x00},/*"t",84*/ +{0x01,0x00,0x01,0xF8,0x00,0x04,0x00,0x04,0x00,0x04,0x01,0x08,0x01,0xFC,0x00,0x04},/*"u",85*/ +{0x01,0x00,0x01,0x80,0x01,0x70,0x00,0x0C,0x00,0x10,0x01,0x60,0x01,0x80,0x01,0x00},/*"v",86*/ +{0x01,0xF0,0x01,0x0C,0x00,0x30,0x01,0xC0,0x00,0x30,0x01,0x0C,0x01,0xF0,0x01,0x00},/*"w",87*/ +{0x00,0x00,0x01,0x04,0x01,0x8C,0x00,0x74,0x01,0x70,0x01,0x8C,0x01,0x04,0x00,0x00},/*"x",88*/ +{0x01,0x01,0x01,0x81,0x01,0x71,0x00,0x0E,0x00,0x18,0x01,0x60,0x01,0x80,0x01,0x00},/*"y",89*/ +{0x00,0x00,0x01,0x84,0x01,0x0C,0x01,0x34,0x01,0x44,0x01,0x84,0x01,0x0C,0x00,0x00},/*"z",90*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x3E,0xFC,0x40,0x02,0x40,0x02},/*"{",91*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00},/*"|",92*/ +{0x00,0x00,0x40,0x02,0x40,0x02,0x3E,0xFC,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"}",93*/ +{0x00,0x00,0x60,0x00,0x80,0x00,0x80,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x20,0x00},/*"~",94*/ +}; +//24*24 ASCII code +const unsigned char asc2_2412[95][36]={ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x38,0x0F,0xFE,0x38,0x0F,0x80,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x06,0x00,0x00,0x0C,0x00,0x00,0x38,0x00,0x00,0x31,0x00,0x00,0x06,0x00,0x00,0x0C,0x00,0x00,0x38,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00},/*""",2*/ +{0x00,0x00,0x00,0x00,0x61,0x80,0x00,0x67,0xF8,0x07,0xF9,0x80,0x00,0x61,0x80,0x00,0x61,0x80,0x00,0x61,0x80,0x00,0x61,0x80,0x00,0x67,0xF8,0x07,0xF9,0x80,0x00,0x61,0x80,0x00,0x00,0x00},/*"#",3*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xC0,0xE0,0x03,0xE0,0xF0,0x06,0x30,0x08,0x04,0x18,0x08,0x1F,0xFF,0xFE,0x04,0x0E,0x08,0x07,0x87,0xF0,0x03,0x81,0xE0,0x00,0x00,0x00,0x00,0x00,0x00},/*"$",4*/ +{0x01,0xF0,0x00,0x06,0x0C,0x00,0x04,0x04,0x08,0x06,0x0C,0x70,0x01,0xF9,0xC0,0x00,0x0E,0x00,0x00,0x3B,0xE0,0x00,0xEC,0x18,0x07,0x08,0x08,0x04,0x0C,0x18,0x00,0x03,0xE0,0x00,0x00,0x00},/*"%",5*/ +{0x00,0x01,0xE0,0x00,0x07,0xF0,0x03,0xF8,0x18,0x04,0x1C,0x08,0x04,0x17,0x08,0x07,0xE1,0xD0,0x03,0xC0,0xE0,0x00,0x23,0xB0,0x00,0x3C,0x08,0x00,0x20,0x08,0x00,0x00,0x10,0x00,0x00,0x00},/*"&",6*/ +{0x00,0x00,0x00,0x01,0x00,0x00,0x31,0x00,0x00,0x32,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x01,0xFF,0xC0,0x07,0x80,0xF0,0x0C,0x00,0x18,0x10,0x00,0x04,0x20,0x00,0x02,0x00,0x00,0x00},/*"(",8*/ +{0x00,0x00,0x00,0x20,0x00,0x02,0x10,0x00,0x04,0x0C,0x00,0x18,0x07,0x80,0xF0,0x01,0xFF,0xC0,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*")",9*/ +{0x00,0x00,0x00,0x00,0x42,0x00,0x00,0x66,0x00,0x00,0x66,0x00,0x00,0x3C,0x00,0x00,0x18,0x00,0x03,0xFF,0xC0,0x00,0x18,0x00,0x00,0x3C,0x00,0x00,0x66,0x00,0x00,0x66,0x00,0x00,0x42,0x00},/*"*",10*/ +{0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x01,0xFF,0xC0,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00},/*"+",11*/ +{0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x31,0x00,0x00,0x32,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/ +{0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x00,0x00},/*"-",13*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/ +{0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x1C,0x00,0x00,0x70,0x00,0x01,0x80,0x00,0x0E,0x00,0x00,0x38,0x00,0x00,0xC0,0x00,0x07,0x00,0x00,0x1C,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00},/*"/",15*/ +{0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0xFF,0xE0,0x03,0x80,0x70,0x06,0x00,0x18,0x04,0x00,0x08,0x04,0x00,0x08,0x06,0x00,0x18,0x03,0x80,0x70,0x01,0xFF,0xE0,0x00,0x7F,0x80,0x00,0x00,0x00},/*"0",16*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x08,0x01,0x00,0x08,0x01,0x00,0x08,0x03,0xFF,0xF8,0x07,0xFF,0xF8,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00},/*"1",17*/ +{0x00,0x00,0x00,0x01,0xC0,0x38,0x02,0xC0,0x58,0x04,0x00,0x98,0x04,0x01,0x18,0x04,0x02,0x18,0x04,0x04,0x18,0x06,0x1C,0x18,0x03,0xF8,0x18,0x01,0xE0,0xF8,0x00,0x00,0x00,0x00,0x00,0x00},/*"2",18*/ +{0x00,0x00,0x00,0x01,0xC0,0xE0,0x03,0xC0,0xF0,0x04,0x00,0x08,0x04,0x08,0x08,0x04,0x08,0x08,0x06,0x18,0x08,0x03,0xF4,0x18,0x01,0xE7,0xF0,0x00,0x01,0xE0,0x00,0x00,0x00,0x00,0x00,0x00},/*"3",19*/ +{0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x0D,0x00,0x00,0x11,0x00,0x00,0x61,0x00,0x00,0x81,0x08,0x03,0x01,0x08,0x07,0xFF,0xF8,0x0F,0xFF,0xF8,0x00,0x01,0x08,0x00,0x01,0x08,0x00,0x00,0x00},/*"4",20*/ +{0x00,0x00,0x00,0x00,0x00,0xE0,0x07,0xFC,0xD0,0x06,0x08,0x08,0x06,0x10,0x08,0x06,0x10,0x08,0x06,0x10,0x08,0x06,0x18,0x38,0x06,0x0F,0xF0,0x06,0x07,0xC0,0x00,0x00,0x00,0x00,0x00,0x00},/*"5",21*/ +{0x00,0x00,0x00,0x00,0x3F,0x80,0x01,0xFF,0xE0,0x03,0x84,0x30,0x02,0x08,0x18,0x04,0x10,0x08,0x04,0x10,0x08,0x04,0x10,0x08,0x07,0x18,0x10,0x03,0x0F,0xF0,0x00,0x07,0xC0,0x00,0x00,0x00},/*"6",22*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xC0,0x00,0x07,0x00,0x00,0x06,0x00,0x00,0x06,0x00,0xF8,0x06,0x07,0xF8,0x06,0x18,0x00,0x06,0xE0,0x00,0x07,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00},/*"7",23*/ +{0x00,0x00,0x00,0x01,0xE1,0xE0,0x03,0xF7,0xF0,0x06,0x34,0x10,0x04,0x18,0x08,0x04,0x18,0x08,0x04,0x0C,0x08,0x04,0x0C,0x08,0x06,0x16,0x18,0x03,0xF3,0xF0,0x01,0xC1,0xE0,0x00,0x00,0x00},/*"8",24*/ +{0x00,0x00,0x00,0x00,0xF8,0x00,0x03,0xFC,0x30,0x03,0x06,0x38,0x04,0x02,0x08,0x04,0x02,0x08,0x04,0x02,0x08,0x04,0x04,0x10,0x03,0x08,0xF0,0x01,0xFF,0xC0,0x00,0x7F,0x00,0x00,0x00,0x00},/*"9",25*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x38,0x00,0x70,0x38,0x00,0x70,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x1A,0x00,0x30,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x14,0x00,0x00,0x22,0x00,0x00,0x41,0x00,0x00,0x80,0x80,0x01,0x00,0x40,0x02,0x00,0x20,0x04,0x00,0x10,0x08,0x00,0x08,0x00,0x00,0x00},/*"<",28*/ +{0x00,0x00,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x21,0x00,0x00,0x00,0x00},/*"=",29*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x04,0x00,0x10,0x02,0x00,0x20,0x01,0x00,0x40,0x00,0x80,0x80,0x00,0x41,0x00,0x00,0x22,0x00,0x00,0x14,0x00,0x00,0x08,0x00,0x00,0x00,0x00},/*">",30*/ +{0x00,0x00,0x00,0x03,0xC0,0x00,0x04,0xC0,0x00,0x04,0x00,0x00,0x08,0x00,0x38,0x08,0x0F,0x38,0x08,0x08,0x38,0x08,0x10,0x00,0x0C,0x30,0x00,0x07,0xE0,0x00,0x03,0xC0,0x00,0x00,0x00,0x00},/*"?",31*/ +{0x00,0x00,0x00,0x00,0x3F,0x80,0x00,0xFF,0xE0,0x03,0x80,0x70,0x02,0x0F,0x10,0x06,0x70,0x88,0x04,0xC0,0x88,0x04,0x83,0x08,0x04,0x7F,0x88,0x02,0xC0,0x90,0x03,0x01,0x20,0x00,0xFE,0x40},/*"@",32*/ +{0x00,0x00,0x08,0x00,0x00,0x18,0x00,0x01,0xF8,0x00,0x3E,0x08,0x01,0xC2,0x00,0x07,0x02,0x00,0x07,0xE2,0x00,0x00,0xFE,0x00,0x00,0x1F,0xC8,0x00,0x01,0xF8,0x00,0x00,0x38,0x00,0x00,0x08},/*"A",33*/ +{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x08,0x08,0x04,0x08,0x08,0x04,0x08,0x08,0x04,0x08,0x08,0x06,0x18,0x08,0x03,0xF4,0x18,0x01,0xE7,0xF0,0x00,0x01,0xE0,0x00,0x00,0x00},/*"B",34*/ +{0x00,0x00,0x00,0x00,0x3F,0x80,0x01,0xFF,0xE0,0x03,0x80,0x70,0x02,0x00,0x18,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x10,0x06,0x00,0x20,0x07,0x80,0xC0,0x00,0x00,0x00},/*"C",35*/ +{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x18,0x02,0x00,0x10,0x03,0x80,0x70,0x01,0xFF,0xE0,0x00,0x7F,0x80,0x00,0x00,0x00},/*"D",36*/ +{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x08,0x08,0x04,0x08,0x08,0x04,0x08,0x08,0x04,0x08,0x08,0x04,0x3E,0x08,0x04,0x00,0x08,0x06,0x00,0x18,0x01,0x00,0x60,0x00,0x00,0x00},/*"E",37*/ +{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x08,0x08,0x04,0x08,0x00,0x04,0x08,0x00,0x04,0x08,0x00,0x04,0x3E,0x00,0x06,0x00,0x00,0x06,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00},/*"F",38*/ +{0x00,0x00,0x00,0x00,0x3F,0x80,0x01,0xFF,0xE0,0x03,0x80,0x70,0x06,0x00,0x18,0x04,0x00,0x08,0x04,0x02,0x08,0x04,0x02,0x08,0x02,0x03,0xF0,0x07,0x83,0xF0,0x00,0x02,0x00,0x00,0x02,0x00},/*"G",39*/ +{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x08,0x08,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x04,0x08,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08},/*"H",40*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00},/*"I",41*/ +{0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x07,0x00,0x00,0x01,0x04,0x00,0x01,0x04,0x00,0x01,0x04,0x00,0x03,0x07,0xFF,0xFE,0x07,0xFF,0xFC,0x04,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00},/*"J",42*/ +{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x0C,0x08,0x00,0x18,0x00,0x00,0x3E,0x00,0x04,0xC7,0x80,0x05,0x03,0xC8,0x06,0x00,0xF8,0x04,0x00,0x38,0x04,0x00,0x18,0x00,0x00,0x08},/*"K",43*/ +{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x18,0x00,0x00,0x60,0x00,0x00,0x00},/*"L",44*/ +{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0x80,0x08,0x07,0xFC,0x00,0x00,0x7F,0xC0,0x00,0x03,0xF8,0x00,0x07,0xC0,0x00,0x78,0x00,0x07,0x80,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08},/*"M",45*/ +{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0x00,0x08,0x03,0xC0,0x00,0x00,0xE0,0x00,0x00,0x38,0x00,0x00,0x1E,0x00,0x00,0x07,0x00,0x00,0x01,0xC0,0x04,0x00,0xF0,0x07,0xFF,0xF8,0x04,0x00,0x00},/*"N",46*/ +{0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0xFF,0xE0,0x03,0x80,0x70,0x06,0x00,0x18,0x04,0x00,0x08,0x04,0x00,0x08,0x06,0x00,0x18,0x03,0x00,0x30,0x01,0xFF,0xE0,0x00,0x7F,0x80,0x00,0x00,0x00},/*"O",47*/ +{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x04,0x08,0x04,0x04,0x00,0x04,0x04,0x00,0x04,0x04,0x00,0x04,0x04,0x00,0x06,0x0C,0x00,0x03,0xF8,0x00,0x01,0xF0,0x00,0x00,0x00,0x00},/*"P",48*/ +{0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0xFF,0xE0,0x03,0x80,0x70,0x06,0x00,0x88,0x04,0x00,0x88,0x04,0x00,0xC8,0x06,0x00,0x3C,0x03,0x00,0x3E,0x01,0xFF,0xE6,0x00,0x7F,0x84,0x00,0x00,0x00},/*"Q",49*/ +{0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x08,0x08,0x04,0x08,0x00,0x04,0x0C,0x00,0x04,0x0F,0x00,0x04,0x0B,0xC0,0x06,0x10,0xF0,0x03,0xF0,0x38,0x01,0xE0,0x08,0x00,0x00,0x08},/*"R",50*/ +{0x00,0x00,0x00,0x01,0xE0,0xF8,0x03,0xF0,0x30,0x06,0x30,0x10,0x04,0x18,0x08,0x04,0x18,0x08,0x04,0x0C,0x08,0x04,0x0C,0x08,0x02,0x06,0x18,0x02,0x07,0xF0,0x07,0x81,0xE0,0x00,0x00,0x00},/*"S",51*/ +{0x01,0x80,0x00,0x06,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x08,0x07,0xFF,0xF8,0x07,0xFF,0xF8,0x04,0x00,0x08,0x04,0x00,0x00,0x04,0x00,0x00,0x06,0x00,0x00,0x01,0x80,0x00},/*"T",52*/ +{0x04,0x00,0x00,0x07,0xFF,0xE0,0x07,0xFF,0xF0,0x04,0x00,0x18,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x04,0x00,0x10,0x07,0xFF,0xE0,0x04,0x00,0x00},/*"U",53*/ +{0x04,0x00,0x00,0x06,0x00,0x00,0x07,0xE0,0x00,0x07,0xFE,0x00,0x04,0x1F,0xE0,0x00,0x01,0xF8,0x00,0x00,0x38,0x00,0x01,0xE0,0x04,0x3E,0x00,0x07,0xC0,0x00,0x06,0x00,0x00,0x04,0x00,0x00},/*"V",54*/ +{0x04,0x00,0x00,0x07,0xE0,0x00,0x07,0xFF,0xC0,0x04,0x1F,0xF8,0x00,0x07,0xC0,0x07,0xF8,0x00,0x07,0xFF,0x80,0x04,0x3F,0xF8,0x00,0x07,0xC0,0x04,0xF8,0x00,0x07,0x00,0x00,0x04,0x00,0x00},/*"W",55*/ +{0x00,0x00,0x00,0x04,0x00,0x08,0x06,0x00,0x18,0x07,0xC0,0x78,0x05,0xF1,0xC8,0x00,0x3E,0x00,0x00,0x1F,0x80,0x04,0x63,0xE8,0x07,0x80,0xF8,0x06,0x00,0x18,0x04,0x00,0x08,0x00,0x00,0x00},/*"X",56*/ +{0x04,0x00,0x00,0x06,0x00,0x00,0x07,0x80,0x00,0x07,0xE0,0x08,0x04,0x7C,0x08,0x00,0x1F,0xF8,0x00,0x07,0xF8,0x00,0x18,0x08,0x04,0xE0,0x08,0x07,0x00,0x00,0x06,0x00,0x00,0x04,0x00,0x00},/*"Y",57*/ +{0x00,0x00,0x00,0x01,0x00,0x08,0x06,0x00,0x38,0x04,0x00,0xF8,0x04,0x03,0xE8,0x04,0x0F,0x08,0x04,0x7C,0x08,0x05,0xF0,0x08,0x07,0xC0,0x08,0x07,0x00,0x18,0x04,0x00,0x60,0x00,0x00,0x00},/*"Z",58*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xFF,0xFE,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x00,0x00,0x00},/*"[",59*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x07,0x00,0x00,0x00,0xC0,0x00,0x00,0x38,0x00,0x00,0x06,0x00,0x00,0x01,0xC0,0x00,0x00,0x30,0x00,0x00,0x0E,0x00,0x00,0x01,0x00,0x00,0x00},/*"\",60*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x20,0x00,0x02,0x3F,0xFF,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"]",61*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x10,0x00,0x00,0x30,0x00,0x00,0x20,0x00,0x00,0x30,0x00,0x00,0x10,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"^",62*/ +{0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01,0x00,0x00,0x01},/*"_",63*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x10,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/ +{0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x19,0xF8,0x00,0x1B,0x18,0x00,0x22,0x08,0x00,0x26,0x08,0x00,0x24,0x08,0x00,0x24,0x10,0x00,0x3F,0xF8,0x00,0x1F,0xF8,0x00,0x00,0x08,0x00,0x00,0x18},/*"a",65*/ +{0x00,0x00,0x00,0x04,0x00,0x00,0x07,0xFF,0xF8,0x0F,0xFF,0xF0,0x00,0x18,0x18,0x00,0x10,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x30,0x18,0x00,0x1F,0xF0,0x00,0x0F,0xC0,0x00,0x00,0x00},/*"b",66*/ +{0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x1F,0xF0,0x00,0x18,0x30,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x3C,0x08,0x00,0x1C,0x10,0x00,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00},/*"c",67*/ +{0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x1F,0xF0,0x00,0x38,0x18,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x04,0x10,0x10,0x07,0xFF,0xF8,0x0F,0xFF,0xF0,0x00,0x00,0x10,0x00,0x00,0x00},/*"d",68*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x1F,0xF0,0x00,0x12,0x30,0x00,0x22,0x18,0x00,0x22,0x08,0x00,0x22,0x08,0x00,0x32,0x08,0x00,0x1E,0x10,0x00,0x0E,0x20,0x00,0x00,0x00},/*"e",69*/ +{0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x08,0x00,0x20,0x08,0x01,0xFF,0xF8,0x03,0xFF,0xF8,0x06,0x20,0x08,0x04,0x20,0x08,0x04,0x20,0x08,0x07,0x20,0x00,0x03,0x00,0x00,0x00,0x00,0x00},/*"f",70*/ +{0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x0E,0x6E,0x00,0x1F,0xF3,0x00,0x31,0xB1,0x00,0x20,0xB1,0x00,0x20,0xB1,0x00,0x31,0x91,0x00,0x1F,0x13,0x00,0x2E,0x1E,0x00,0x20,0x0E,0x00,0x30,0x00},/*"g",71*/ +{0x00,0x00,0x00,0x04,0x00,0x08,0x07,0xFF,0xF8,0x0F,0xFF,0xF8,0x00,0x10,0x08,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x20,0x08,0x00,0x3F,0xF8,0x00,0x1F,0xF8,0x00,0x00,0x08,0x00,0x00,0x00},/*"h",72*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x06,0x3F,0xF8,0x06,0x3F,0xF8,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00},/*"i",73*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x03,0x00,0x20,0x01,0x00,0x20,0x01,0x00,0x20,0x03,0x06,0x3F,0xFE,0x06,0x3F,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"j",74*/ +{0x00,0x00,0x00,0x04,0x00,0x08,0x07,0xFF,0xF8,0x0F,0xFF,0xF8,0x00,0x01,0x88,0x00,0x03,0x00,0x00,0x2F,0xC0,0x00,0x38,0xF8,0x00,0x20,0x38,0x00,0x20,0x08,0x00,0x00,0x08,0x00,0x00,0x00},/*"k",75*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x08,0x04,0x00,0x08,0x04,0x00,0x08,0x07,0xFF,0xF8,0x0F,0xFF,0xF8,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00},/*"l",76*/ +{0x00,0x20,0x08,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x10,0x08,0x00,0x20,0x00,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x10,0x08,0x00,0x20,0x00,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x00,0x08},/*"m",77*/ +{0x00,0x00,0x00,0x00,0x20,0x08,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x10,0x08,0x00,0x10,0x00,0x00,0x20,0x00,0x00,0x20,0x08,0x00,0x3F,0xF8,0x00,0x1F,0xF8,0x00,0x00,0x08,0x00,0x00,0x00},/*"n",78*/ +{0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x0F,0xF0,0x00,0x18,0x30,0x00,0x30,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x30,0x08,0x00,0x18,0x30,0x00,0x0F,0xF0,0x00,0x07,0xC0,0x00,0x00,0x00},/*"o",79*/ +{0x00,0x00,0x00,0x00,0x20,0x01,0x00,0x3F,0xFF,0x00,0x3F,0xFF,0x00,0x10,0x11,0x00,0x20,0x09,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x30,0x38,0x00,0x1F,0xF0,0x00,0x0F,0xC0,0x00,0x00,0x00},/*"p",80*/ +{0x00,0x00,0x00,0x00,0x07,0xC0,0x00,0x1F,0xF0,0x00,0x38,0x18,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x09,0x00,0x10,0x11,0x00,0x1F,0xFF,0x00,0x3F,0xFF,0x00,0x00,0x01,0x00,0x00,0x00},/*"q",81*/ +{0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x3F,0xF8,0x00,0x3F,0xF8,0x00,0x08,0x08,0x00,0x10,0x08,0x00,0x20,0x08,0x00,0x20,0x00,0x00,0x30,0x00,0x00,0x30,0x00,0x00,0x00,0x00},/*"r",82*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x78,0x00,0x1E,0x18,0x00,0x33,0x08,0x00,0x23,0x08,0x00,0x21,0x08,0x00,0x21,0x88,0x00,0x21,0x98,0x00,0x30,0xF0,0x00,0x38,0x60,0x00,0x00,0x00},/*"s",83*/ +{0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0xFF,0xF0,0x03,0xFF,0xF8,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00},/*"t",84*/ +{0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x3F,0xF0,0x00,0x7F,0xF8,0x00,0x00,0x18,0x00,0x00,0x08,0x00,0x00,0x08,0x00,0x20,0x10,0x00,0x3F,0xF8,0x00,0x7F,0xF0,0x00,0x00,0x10,0x00,0x00,0x00},/*"u",85*/ +{0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x30,0x00,0x00,0x3C,0x00,0x00,0x3F,0x80,0x00,0x23,0xF0,0x00,0x00,0x78,0x00,0x00,0x70,0x00,0x23,0x80,0x00,0x3C,0x00,0x00,0x30,0x00,0x00,0x20,0x00},/*"v",86*/ +{0x00,0x20,0x00,0x00,0x3C,0x00,0x00,0x3F,0xE0,0x00,0x23,0xF8,0x00,0x00,0xE0,0x00,0x27,0x00,0x00,0x3E,0x00,0x00,0x3F,0xE0,0x00,0x21,0xF8,0x00,0x01,0xE0,0x00,0x3E,0x00,0x00,0x20,0x00},/*"w",87*/ +{0x00,0x00,0x00,0x00,0x20,0x08,0x00,0x20,0x08,0x00,0x38,0x38,0x00,0x3E,0x68,0x00,0x27,0x80,0x00,0x03,0xC8,0x00,0x2C,0xF8,0x00,0x38,0x38,0x00,0x20,0x18,0x00,0x20,0x08,0x00,0x00,0x00},/*"x",88*/ +{0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x30,0x03,0x00,0x3C,0x01,0x00,0x3F,0x83,0x00,0x23,0xEC,0x00,0x00,0x70,0x00,0x23,0x80,0x00,0x3C,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00,0x00,0x00},/*"y",89*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x08,0x00,0x20,0x38,0x00,0x20,0xF8,0x00,0x23,0xE8,0x00,0x2F,0x88,0x00,0x3E,0x08,0x00,0x38,0x08,0x00,0x20,0x18,0x00,0x00,0x70,0x00,0x00,0x00},/*"z",90*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x14,0x00,0x1F,0xF7,0xFC,0x30,0x00,0x06,0x20,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00},/*"{",91*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"|",92*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x02,0x30,0x00,0x06,0x1F,0xF7,0xFC,0x00,0x14,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"}",93*/ +{0x00,0x00,0x00,0x18,0x00,0x00,0x60,0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00,0x20,0x00,0x00,0x10,0x00,0x00,0x08,0x00,0x00,0x04,0x00,0x00,0x04,0x00,0x00,0x0C,0x00,0x00,0x10,0x00,0x00},/*"~",94*/ +}; + +//32*32 ASCII code +const unsigned char asc2_3216[95][128]={ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*" ",0*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xF0,0x00,0xC0,0x07,0xFF,0xE1,0xE0,0x07,0xF0,0x01,0xE0,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"!",1*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x01,0xC0,0x00,0x00,0x07,0x80,0x00,0x00,0x1F,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x1C,0x20,0x00,0x00,0x01,0xC0,0x00,0x00,0x07,0x80,0x00,0x00,0x1F,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*""",2*/ +{0x00,0x00,0x00,0x00,0x00,0x18,0x0C,0x00,0x00,0x18,0x0C,0x00,0x00,0x18,0x0F,0xE0,0x00,0x1F,0xFC,0x00,0x03,0xF8,0x0C,0x00,0x00,0x18,0x0C,0x00,0x00,0x18,0x0C,0x00,0x00,0x18,0x0C,0x00,0x00,0x18,0x0C,0x00,0x00,0x18,0x0F,0xE0,0x00,0x1F,0xFC,0x00,0x03,0xF8,0x0C,0x00,0x00,0x18,0x0C,0x00,0x00,0x18,0x0C,0x00,0x00,0x00,0x00,0x00},/*"#",3*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x00,0x78,0x07,0xC0,0x00,0xFC,0x06,0x40,0x01,0x0E,0x00,0x20,0x03,0x07,0x00,0x20,0x02,0x03,0x80,0x20,0x0F,0xFF,0xFF,0xFC,0x02,0x01,0xC0,0x20,0x02,0x00,0xE0,0x60,0x01,0x30,0x70,0x40,0x01,0xF0,0x3F,0x80,0x00,0xF0,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"$",4*/ +{0x00,0xFE,0x00,0x00,0x01,0xFF,0x00,0x00,0x03,0x01,0x80,0x00,0x02,0x00,0x80,0x60,0x03,0x01,0x81,0xC0,0x01,0xFF,0x07,0x00,0x00,0xFE,0x18,0x00,0x00,0x00,0xE0,0x00,0x00,0x03,0xBF,0x00,0x00,0x0C,0xFF,0xC0,0x00,0x71,0x80,0x60,0x01,0xC1,0x00,0x20,0x03,0x01,0x80,0x60,0x00,0x00,0xFF,0xC0,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00},/*"%",5*/ +{0x00,0x00,0x1F,0x00,0x00,0x00,0x7F,0xC0,0x00,0xFC,0xC0,0xC0,0x01,0xFF,0x80,0x60,0x03,0x03,0xE0,0x20,0x02,0x02,0x78,0x20,0x02,0x06,0x1E,0x20,0x03,0xFC,0x07,0x40,0x01,0xF0,0x03,0x80,0x00,0x01,0x03,0xC0,0x00,0x01,0x1C,0x60,0x00,0x01,0xE0,0x20,0x00,0x01,0x00,0x20,0x00,0x01,0x00,0x40,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00},/*"&",6*/ +{0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x1C,0x60,0x00,0x00,0x1C,0x40,0x00,0x00,0x1F,0x80,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"'",7*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xF8,0x00,0x00,0x3F,0xFF,0x00,0x00,0x78,0x07,0xC0,0x01,0xC0,0x00,0xE0,0x03,0x00,0x00,0x30,0x04,0x00,0x00,0x08,0x08,0x00,0x00,0x04,0x10,0x00,0x00,0x02,0x00,0x00,0x00,0x00},/*"(",8*/ +{0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x02,0x08,0x00,0x00,0x04,0x04,0x00,0x00,0x08,0x03,0x00,0x00,0x30,0x01,0xC0,0x00,0xE0,0x00,0x78,0x07,0xC0,0x00,0x3F,0xFF,0x00,0x00,0x07,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*")",9*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x18,0x00,0x00,0x0E,0x38,0x00,0x00,0x0E,0x38,0x00,0x00,0x06,0x30,0x00,0x00,0x03,0x60,0x00,0x00,0x61,0x43,0x80,0x00,0xFF,0xFF,0x80,0x00,0x61,0x43,0x00,0x00,0x03,0x60,0x00,0x00,0x06,0x30,0x00,0x00,0x0E,0x38,0x00,0x00,0x0E,0x38,0x00,0x00,0x0C,0x18,0x00,0x00,0x00,0x00,0x00},/*"*",10*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x7F,0xFF,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00},/*"+",11*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xE3,0x00,0x00,0x00,0xE2,0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*",",12*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00},/*"-",13*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x01,0xE0,0x00,0x00,0x01,0xE0,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*".",14*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x00,0x03,0x80,0x00,0x00,0x0E,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x00,0x03,0x80,0x00,0x00,0x0E,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0xE0,0x00,0x00,0x03,0x80,0x00,0x00,0x0E,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"/",15*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xF8,0x00,0x00,0x7F,0xFF,0x00,0x00,0xF0,0x07,0x80,0x01,0x80,0x00,0xC0,0x03,0x00,0x00,0x60,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0x00,0x00,0x60,0x01,0x80,0x00,0xC0,0x00,0xE0,0x03,0x80,0x00,0x7F,0xFF,0x00,0x00,0x0F,0xF8,0x00,0x00,0x00,0x00,0x00},/*"0",16*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x20,0x00,0x80,0x00,0x20,0x00,0x80,0x00,0x20,0x00,0x80,0x00,0x60,0x01,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"1",17*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0xE0,0x00,0x98,0x01,0x60,0x01,0x00,0x02,0x60,0x02,0x00,0x04,0x60,0x02,0x00,0x08,0x60,0x02,0x00,0x10,0x60,0x02,0x00,0x20,0x60,0x02,0x00,0x40,0x60,0x03,0x00,0x80,0x60,0x01,0x83,0x00,0x60,0x01,0xFE,0x00,0xE0,0x00,0x7C,0x07,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"2",18*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x07,0x80,0x01,0xF0,0x07,0xC0,0x01,0x00,0x00,0x40,0x02,0x00,0x00,0x20,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x03,0x03,0x80,0x20,0x01,0x86,0x80,0x40,0x01,0xFC,0xC0,0xC0,0x00,0x78,0x7F,0x80,0x00,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"3",19*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x38,0x00,0x00,0x00,0x48,0x00,0x00,0x01,0x88,0x00,0x00,0x06,0x08,0x00,0x00,0x0C,0x08,0x10,0x00,0x30,0x08,0x10,0x00,0x40,0x08,0x10,0x01,0xFF,0xFF,0xF0,0x03,0xFF,0xFF,0xF0,0x03,0xFF,0xFF,0xF0,0x00,0x00,0x08,0x10,0x00,0x00,0x08,0x10,0x00,0x00,0x08,0x10,0x00,0x00,0x00,0x00},/*"4",20*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x00,0x1F,0x86,0x40,0x03,0xE1,0x00,0x20,0x03,0x02,0x00,0x20,0x03,0x04,0x00,0x20,0x03,0x04,0x00,0x20,0x03,0x04,0x00,0x20,0x03,0x04,0x00,0x20,0x03,0x06,0x00,0x40,0x03,0x03,0x01,0xC0,0x03,0x01,0xFF,0x80,0x03,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"5",21*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xFC,0x00,0x00,0x3F,0xFF,0x00,0x00,0x70,0xC3,0x80,0x00,0x81,0x80,0xC0,0x01,0x01,0x00,0x60,0x03,0x02,0x00,0x20,0x02,0x02,0x00,0x20,0x02,0x02,0x00,0x20,0x02,0x02,0x00,0x20,0x02,0x03,0x00,0x40,0x01,0xC1,0x80,0xC0,0x00,0xC0,0xFF,0x80,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00},/*"6",22*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x03,0xC0,0x00,0x00,0x03,0x80,0x00,0x00,0x03,0x00,0x00,0x00,0x03,0x00,0x07,0xE0,0x03,0x00,0x3F,0xE0,0x03,0x01,0xC0,0x00,0x03,0x06,0x00,0x00,0x03,0x18,0x00,0x00,0x03,0x60,0x00,0x00,0x03,0x80,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"7",23*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x00,0x78,0x3F,0x80,0x00,0xFC,0x60,0xC0,0x01,0x8E,0xC0,0x40,0x03,0x07,0x80,0x20,0x02,0x03,0x00,0x20,0x02,0x01,0x80,0x20,0x02,0x01,0x80,0x20,0x02,0x01,0xC0,0x20,0x03,0x01,0xE0,0x40,0x01,0x86,0x70,0xC0,0x00,0xFC,0x3F,0x80,0x00,0x78,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"8",24*/ +{0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0xFF,0x81,0xC0,0x01,0xC0,0xC1,0xC0,0x01,0x00,0x60,0x20,0x02,0x00,0x20,0x20,0x02,0x00,0x20,0x20,0x02,0x00,0x20,0x20,0x02,0x00,0x20,0x60,0x02,0x00,0x40,0xC0,0x01,0x00,0xC1,0x80,0x00,0xC1,0x8F,0x00,0x00,0x7F,0xFE,0x00,0x00,0x1F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"9",25*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0xC0,0x00,0x07,0x81,0xE0,0x00,0x07,0x81,0xE0,0x00,0x03,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*":",26*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x66,0x00,0x06,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*";",27*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x01,0xC0,0x00,0x00,0x03,0x60,0x00,0x00,0x06,0x30,0x00,0x00,0x0C,0x18,0x00,0x00,0x18,0x0C,0x00,0x00,0x30,0x06,0x00,0x00,0x60,0x03,0x00,0x00,0xC0,0x01,0x80,0x01,0x00,0x00,0x40,0x02,0x00,0x00,0x20,0x04,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"<",28*/ +{0x00,0x00,0x00,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x00,0x00,0x00},/*"=",29*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x10,0x02,0x00,0x00,0x20,0x01,0x00,0x00,0x40,0x00,0xC0,0x01,0x80,0x00,0x60,0x03,0x00,0x00,0x30,0x06,0x00,0x00,0x18,0x0C,0x00,0x00,0x0C,0x18,0x00,0x00,0x06,0x30,0x00,0x00,0x03,0x60,0x00,0x00,0x01,0xC0,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*">",30*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x01,0xF8,0x00,0x00,0x02,0x38,0x00,0x00,0x02,0x00,0x00,0x00,0x04,0x00,0x00,0xC0,0x04,0x00,0x79,0xE0,0x04,0x00,0x81,0xE0,0x04,0x01,0x00,0xC0,0x04,0x03,0x00,0x00,0x02,0x02,0x00,0x00,0x03,0x06,0x00,0x00,0x01,0xFC,0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00},/*"?",31*/ +{0x00,0x00,0x00,0x00,0x00,0x0F,0xF8,0x00,0x00,0x3F,0xFE,0x00,0x00,0x70,0x07,0x80,0x00,0xC0,0x00,0xC0,0x01,0x01,0xF8,0x40,0x03,0x07,0xFC,0x20,0x02,0x1E,0x04,0x20,0x02,0x30,0x08,0x20,0x02,0x20,0x30,0x20,0x02,0x3F,0xFC,0x20,0x01,0x3F,0x04,0x40,0x01,0x80,0x0C,0xC0,0x00,0xE0,0x31,0x80,0x00,0x1F,0xC2,0x00,0x00,0x00,0x00,0x00},/*"@",32*/ +{0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x60,0x00,0x00,0x03,0xE0,0x00,0x00,0x3E,0x20,0x00,0x03,0xE0,0x20,0x00,0x3E,0x20,0x00,0x03,0xE0,0x20,0x00,0x03,0x80,0x20,0x00,0x07,0xFC,0x20,0x00,0x00,0x3F,0xE0,0x00,0x00,0x03,0xFE,0x20,0x00,0x00,0x3F,0xE0,0x00,0x00,0x01,0xE0,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00},/*"A",33*/ +{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x03,0x03,0x00,0x20,0x01,0x86,0x80,0x60,0x01,0xFC,0xC0,0xC0,0x00,0xF8,0x7F,0x80,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00},/*"B",34*/ +{0x00,0x00,0x00,0x00,0x00,0x07,0xF8,0x00,0x00,0x3F,0xFF,0x00,0x00,0x70,0x07,0x80,0x00,0xC0,0x00,0xC0,0x01,0x00,0x00,0x40,0x03,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x01,0x00,0x00,0x40,0x01,0x80,0x00,0xC0,0x03,0xC0,0x01,0x80,0x00,0x30,0x06,0x00,0x00,0x00,0x00,0x00},/*"C",35*/ +{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0x00,0x00,0x60,0x01,0x00,0x00,0x40,0x01,0x80,0x00,0xC0,0x00,0xF0,0x07,0x80,0x00,0x7F,0xFE,0x00,0x00,0x0F,0xF8,0x00,0x00,0x00,0x00,0x00},/*"D",36*/ +{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x02,0x03,0x80,0x20,0x02,0x0F,0xE0,0x20,0x03,0x00,0x00,0x60,0x03,0xC0,0x00,0xE0,0x00,0x60,0x03,0x00,0x00,0x00,0x00,0x00},/*"E",37*/ +{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x00,0x02,0x01,0x00,0x00,0x02,0x01,0x00,0x00,0x02,0x01,0x00,0x00,0x02,0x03,0x80,0x00,0x03,0x0F,0xE0,0x00,0x03,0x00,0x00,0x00,0x03,0xC0,0x00,0x00,0x00,0x60,0x00,0x00},/*"F",38*/ +{0x00,0x00,0x00,0x00,0x00,0x07,0xF8,0x00,0x00,0x3F,0xFE,0x00,0x00,0x70,0x07,0x80,0x01,0xC0,0x01,0xC0,0x01,0x00,0x00,0x40,0x03,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x01,0x00,0x20,0x20,0x01,0x00,0x20,0x40,0x03,0xC0,0x3F,0x80,0x00,0x30,0x3F,0x80,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00},/*"G",39*/ +{0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x00,0x80,0x20,0x02,0x00,0x80,0x20,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x02,0x00,0x80,0x20,0x02,0x00,0x80,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00},/*"H",40*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"I",41*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x03,0x02,0x00,0x00,0x06,0x03,0xFF,0xFF,0xFC,0x03,0xFF,0xFF,0xF8,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"J",42*/ +{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x00,0xC0,0x20,0x02,0x01,0x00,0x20,0x00,0x07,0x80,0x00,0x00,0x0F,0xE0,0x00,0x00,0x30,0xF8,0x00,0x02,0x60,0x3E,0x20,0x03,0x80,0x0F,0x20,0x03,0x00,0x03,0xE0,0x02,0x00,0x00,0xE0,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x20},/*"K",43*/ +{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0xE0,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00},/*"L",44*/ +{0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xE0,0x00,0x20,0x03,0xFF,0x00,0x20,0x00,0x1F,0xF0,0x00,0x00,0x01,0xFF,0x80,0x00,0x00,0x0F,0xE0,0x00,0x00,0x1E,0x00,0x00,0x03,0xE0,0x00,0x00,0x3E,0x00,0x20,0x03,0xE0,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20},/*"M",45*/ +{0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0x80,0x00,0x20,0x03,0xF0,0x00,0x20,0x00,0xFC,0x00,0x00,0x00,0x1F,0x00,0x00,0x00,0x07,0xC0,0x00,0x00,0x01,0xF0,0x00,0x00,0x00,0x7C,0x00,0x02,0x00,0x1F,0x80,0x02,0x00,0x07,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"N",46*/ +{0x00,0x00,0x00,0x00,0x00,0x0F,0xF8,0x00,0x00,0x3F,0xFE,0x00,0x00,0xF0,0x07,0x80,0x01,0x80,0x00,0xC0,0x01,0x00,0x00,0x40,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x01,0x00,0x00,0x40,0x01,0x80,0x00,0xC0,0x00,0xF0,0x03,0x80,0x00,0x3F,0xFE,0x00,0x00,0x0F,0xF8,0x00,0x00,0x00,0x00,0x00},/*"O",47*/ +{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x00,0x80,0x20,0x02,0x00,0x80,0x20,0x02,0x00,0x80,0x00,0x02,0x00,0x80,0x00,0x02,0x00,0x80,0x00,0x02,0x00,0x80,0x00,0x03,0x01,0x80,0x00,0x01,0x83,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00},/*"P",48*/ +{0x00,0x00,0x00,0x00,0x00,0x0F,0xF8,0x00,0x00,0x7F,0xFF,0x00,0x00,0xF0,0x03,0x80,0x01,0x80,0x01,0xC0,0x01,0x00,0x06,0x40,0x02,0x00,0x04,0x20,0x02,0x00,0x04,0x20,0x02,0x00,0x06,0x20,0x02,0x00,0x03,0xE0,0x01,0x00,0x00,0xF8,0x01,0x80,0x00,0x5C,0x00,0xE0,0x03,0x8C,0x00,0x3F,0xFF,0x0C,0x00,0x0F,0xFC,0x18,0x00,0x00,0x00,0x00},/*"Q",49*/ +{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x01,0x00,0x20,0x02,0x01,0x00,0x20,0x02,0x01,0x80,0x00,0x02,0x01,0xE0,0x00,0x02,0x01,0xFC,0x00,0x03,0x03,0x3F,0x80,0x01,0x86,0x07,0xE0,0x01,0xFC,0x00,0xE0,0x00,0xF8,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00},/*"R",50*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x06,0x00,0x00,0xFE,0x01,0xE0,0x01,0x86,0x00,0xC0,0x03,0x03,0x00,0x40,0x02,0x03,0x00,0x20,0x02,0x01,0x80,0x20,0x02,0x01,0x80,0x20,0x02,0x01,0xC0,0x20,0x02,0x00,0xC0,0x20,0x01,0x00,0xE0,0x60,0x01,0x80,0x70,0xC0,0x03,0xE0,0x3F,0x80,0x00,0x00,0x1F,0x00,0x00,0x00,0x00,0x00},/*"S",51*/ +{0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x03,0x80,0x00,0x00,0x03,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x03,0xFF,0xFF,0xE0,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0x80,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00,0x00},/*"T",52*/ +{0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0xFF,0xFF,0x00,0x03,0xFF,0xFF,0xC0,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x60,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x02,0x00,0x00,0x40,0x02,0x00,0x00,0x80,0x03,0xFF,0xFF,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"U",53*/ +{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0xC0,0x00,0x00,0x03,0xFC,0x00,0x00,0x02,0x3F,0xC0,0x00,0x00,0x03,0xF8,0x00,0x00,0x00,0x7F,0x80,0x00,0x00,0x07,0xE0,0x00,0x00,0x07,0x80,0x00,0x00,0x78,0x00,0x02,0x03,0xC0,0x00,0x02,0x3C,0x00,0x00,0x03,0xC0,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00},/*"V",54*/ +{0x02,0x00,0x00,0x00,0x03,0xC0,0x00,0x00,0x03,0xFF,0x80,0x00,0x02,0x3F,0xFE,0x00,0x02,0x00,0x7F,0xE0,0x00,0x00,0x0F,0x00,0x02,0x00,0xF0,0x00,0x03,0xEF,0x00,0x00,0x03,0xFF,0x80,0x00,0x02,0x0F,0xFE,0x00,0x00,0x00,0x3F,0xE0,0x00,0x00,0x1F,0x00,0x02,0x07,0xE0,0x00,0x03,0xF8,0x00,0x00,0x03,0x00,0x00,0x00,0x02,0x00,0x00,0x00},/*"W",55*/ +{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0x80,0x00,0xE0,0x03,0xF0,0x03,0x20,0x02,0xFC,0x0C,0x20,0x02,0x1F,0x30,0x00,0x00,0x07,0xC0,0x00,0x00,0x07,0xF0,0x00,0x02,0x18,0x7C,0x00,0x02,0x60,0x1F,0x20,0x03,0x80,0x03,0xE0,0x02,0x00,0x00,0xE0,0x02,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00},/*"X",56*/ +{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x03,0xC0,0x00,0x00,0x03,0xF8,0x00,0x00,0x02,0x3E,0x00,0x20,0x02,0x0F,0xC0,0x20,0x00,0x01,0xFF,0xE0,0x00,0x00,0x7F,0xE0,0x00,0x03,0x80,0x20,0x02,0x1C,0x00,0x20,0x02,0x70,0x00,0x00,0x03,0x80,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"Y",57*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x60,0x00,0xE0,0x03,0x80,0x03,0xE0,0x03,0x00,0x0F,0xA0,0x02,0x00,0x3E,0x20,0x02,0x00,0xF8,0x20,0x02,0x03,0xE0,0x20,0x02,0x0F,0x80,0x20,0x02,0x3E,0x00,0x20,0x02,0x78,0x00,0x20,0x03,0xE0,0x00,0x60,0x03,0x80,0x00,0xE0,0x02,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"Z",58*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0xFF,0xFF,0xFC,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"[",59*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x03,0xC0,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x03,0xC0,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x07,0x80,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"\",60*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x10,0x00,0x00,0x04,0x1F,0xFF,0xFF,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"]",61*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"^",62*/ +{0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01},/*"_",63*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"`",64*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x80,0x00,0x01,0x8F,0xC0,0x00,0x03,0x8C,0x60,0x00,0x06,0x18,0x20,0x00,0x04,0x10,0x20,0x00,0x04,0x10,0x20,0x00,0x04,0x20,0x20,0x00,0x04,0x20,0x40,0x00,0x06,0x20,0x40,0x00,0x03,0xFF,0xC0,0x00,0x01,0xFF,0xE0,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x00},/*"a",65*/ +{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x03,0xFF,0xFF,0xE0,0x07,0xFF,0xFF,0xC0,0x00,0x01,0x80,0xC0,0x00,0x02,0x00,0x60,0x00,0x02,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x06,0x00,0x40,0x00,0x03,0x00,0xC0,0x00,0x01,0xFF,0x80,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00},/*"b",66*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x01,0xFF,0x80,0x00,0x03,0x81,0xC0,0x00,0x02,0x00,0x40,0x00,0x06,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x06,0x00,0x20,0x00,0x03,0xC0,0x40,0x00,0x01,0xC0,0x80,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"c",67*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x01,0xFF,0x80,0x00,0x03,0x80,0xC0,0x00,0x06,0x00,0x60,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x02,0x04,0x00,0x40,0x02,0x02,0x00,0x80,0x03,0xFF,0xFF,0xE0,0x07,0xFF,0xFF,0xC0,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00},/*"d",68*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x01,0xFF,0x80,0x00,0x03,0x11,0xC0,0x00,0x02,0x10,0x40,0x00,0x04,0x10,0x60,0x00,0x04,0x10,0x20,0x00,0x04,0x10,0x20,0x00,0x04,0x10,0x20,0x00,0x06,0x10,0x20,0x00,0x03,0x10,0x40,0x00,0x01,0xF0,0xC0,0x00,0x00,0x71,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"e",69*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x7F,0xFF,0xE0,0x01,0xFF,0xFF,0xE0,0x01,0x04,0x00,0x20,0x03,0x04,0x00,0x20,0x02,0x04,0x00,0x20,0x02,0x04,0x00,0x20,0x02,0x04,0x00,0x00,0x02,0x00,0x00,0x00,0x01,0xC0,0x00,0x00,0x01,0xC0,0x00,0x00},/*"f",70*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x00,0xE3,0x3E,0x00,0x03,0xFF,0xC2,0x00,0x02,0x0C,0xC3,0x00,0x04,0x04,0xC1,0x00,0x04,0x04,0xC1,0x00,0x04,0x04,0xC1,0x00,0x04,0x04,0xC1,0x00,0x06,0x0C,0xC1,0x00,0x03,0xF8,0xC3,0x00,0x05,0xF0,0x62,0x00,0x06,0x00,0x7E,0x00,0x06,0x00,0x3C,0x00,0x00,0x00,0x00},/*"g",71*/ +{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x07,0xFF,0xFF,0xE0,0x00,0x01,0x00,0x20,0x00,0x02,0x00,0x20,0x00,0x06,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x20,0x00,0x06,0x00,0x20,0x00,0x03,0xFF,0xE0,0x00,0x01,0xFF,0xE0,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20},/*"h",72*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x03,0x87,0xFF,0xE0,0x03,0x8F,0xFF,0xE0,0x03,0x80,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"i",73*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x04,0x00,0x01,0x00,0x04,0x00,0x01,0x00,0x04,0x00,0x03,0x00,0x04,0x00,0x06,0x03,0x87,0xFF,0xFC,0x03,0x8F,0xFF,0xF8,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"j",74*/ +{0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x07,0xFF,0xFF,0xE0,0x00,0x00,0x08,0x20,0x00,0x00,0x10,0x20,0x00,0x00,0x30,0x00,0x00,0x00,0xFC,0x00,0x00,0x05,0x8E,0x00,0x00,0x07,0x07,0xA0,0x00,0x06,0x01,0xE0,0x00,0x04,0x00,0xE0,0x00,0x04,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00},/*"k",75*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x02,0x00,0x00,0x20,0x03,0xFF,0xFF,0xE0,0x07,0xFF,0xFF,0xE0,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"l",76*/ +{0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x20,0x00,0x07,0xFF,0xE0,0x00,0x0F,0xFF,0xE0,0x00,0x02,0x00,0x20,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x20,0x00,0x07,0xFF,0xE0,0x00,0x03,0xFF,0xE0,0x00,0x02,0x00,0x20,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x20,0x00,0x07,0xFF,0xE0,0x00,0x03,0xFF,0xE0,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00},/*"m",77*/ +{0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x07,0xFF,0xE0,0x00,0x0F,0xFF,0xE0,0x00,0x01,0x00,0x20,0x00,0x02,0x00,0x20,0x00,0x02,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x20,0x00,0x06,0x00,0x20,0x00,0x03,0xFF,0xE0,0x00,0x01,0xFF,0xE0,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20},/*"n",78*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0xFF,0x80,0x00,0x03,0x81,0xC0,0x00,0x02,0x00,0x40,0x00,0x06,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x06,0x00,0x20,0x00,0x02,0x00,0x40,0x00,0x03,0x81,0xC0,0x00,0x01,0xFF,0x80,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00},/*"o",79*/ +{0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x01,0x00,0x04,0x00,0x01,0x00,0x07,0xFF,0xFF,0x00,0x0F,0xFF,0xFF,0x00,0x01,0x00,0xC1,0x00,0x02,0x00,0x41,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x06,0x00,0x40,0x00,0x03,0x01,0xC0,0x00,0x01,0xFF,0x80,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00},/*"p",80*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x01,0xFF,0x80,0x00,0x03,0x80,0xC0,0x00,0x02,0x00,0x60,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x02,0x00,0x41,0x00,0x03,0x00,0xC1,0x00,0x03,0xFF,0xFF,0x00,0x07,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01},/*"q",81*/ +{0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x0F,0xFF,0xE0,0x00,0x0F,0xFF,0xE0,0x00,0x00,0xC0,0x20,0x00,0x01,0x00,0x20,0x00,0x02,0x00,0x20,0x00,0x06,0x00,0x20,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00},/*"r",82*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xE0,0x00,0x01,0xC0,0xE0,0x00,0x03,0xE0,0x40,0x00,0x06,0x30,0x20,0x00,0x04,0x30,0x20,0x00,0x04,0x18,0x20,0x00,0x04,0x18,0x20,0x00,0x04,0x18,0x20,0x00,0x04,0x0C,0x20,0x00,0x02,0x0C,0x60,0x00,0x03,0x07,0xC0,0x00,0x07,0x83,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"s",83*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x1F,0xFF,0x80,0x00,0xFF,0xFF,0xC0,0x00,0x04,0x00,0x60,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x40,0x00,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"t",84*/ +{0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x07,0xFF,0x80,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x40,0x00,0x04,0x00,0x80,0x00,0x07,0xFF,0xE0,0x00,0x0F,0xFF,0xC0,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40},/*"u",85*/ +{0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x07,0x80,0x00,0x00,0x07,0xF0,0x00,0x00,0x04,0xFE,0x00,0x00,0x04,0x1F,0xC0,0x00,0x00,0x03,0xE0,0x00,0x00,0x03,0x80,0x00,0x00,0x1C,0x00,0x00,0x04,0x60,0x00,0x00,0x07,0x80,0x00,0x00,0x06,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"v",86*/ +{0x00,0x04,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x07,0xC0,0x00,0x00,0x07,0xFC,0x00,0x00,0x04,0x3F,0x80,0x00,0x00,0x03,0xE0,0x00,0x04,0x0F,0x80,0x00,0x06,0xF0,0x00,0x00,0x07,0xF0,0x00,0x00,0x07,0xFF,0x80,0x00,0x04,0x0F,0xE0,0x00,0x00,0x03,0x80,0x00,0x04,0x3C,0x00,0x00,0x07,0xC0,0x00,0x00,0x06,0x00,0x00,0x00,0x04,0x00,0x00},/*"w",87*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x04,0x00,0x20,0x00,0x04,0x00,0x60,0x00,0x07,0x00,0xE0,0x00,0x07,0x83,0x20,0x00,0x07,0xE6,0x00,0x00,0x04,0xF8,0x00,0x00,0x00,0x3C,0x00,0x00,0x04,0x5E,0x20,0x00,0x05,0x87,0xA0,0x00,0x06,0x01,0xE0,0x00,0x04,0x00,0x60,0x00,0x04,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x00},/*"x",88*/ +{0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x03,0x00,0x07,0x00,0x03,0x00,0x07,0xE0,0x01,0x00,0x04,0xF8,0x01,0x00,0x04,0x1F,0x02,0x00,0x00,0x07,0xFC,0x00,0x00,0x00,0xE0,0x00,0x00,0x07,0x00,0x00,0x04,0x38,0x00,0x00,0x07,0xC0,0x00,0x00,0x06,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00},/*"y",89*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x60,0x00,0x06,0x00,0xE0,0x00,0x04,0x03,0xE0,0x00,0x04,0x07,0xA0,0x00,0x04,0x0E,0x20,0x00,0x04,0x3C,0x20,0x00,0x04,0x70,0x20,0x00,0x05,0xE0,0x20,0x00,0x07,0x80,0x20,0x00,0x07,0x00,0x60,0x00,0x04,0x00,0xE0,0x00,0x00,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"z",90*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x01,0x40,0x00,0x07,0xFE,0x3F,0xF8,0x08,0x00,0x00,0x04,0x10,0x00,0x00,0x02,0x10,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"{",91*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"|",92*/ +{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x02,0x10,0x00,0x00,0x02,0x08,0x00,0x00,0x04,0x07,0xFE,0x3F,0xF8,0x00,0x01,0x40,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"}",93*/ +{0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/*"~",94*/ +}; +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/fpioa.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/fpioa.h new file mode 100644 index 000000000..c8006b5c5 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/fpioa.h @@ -0,0 +1,1014 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file fpioa.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#ifndef __FPIOA_H__ +#define __FPIOA_H__ + +#include +#include "platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* clang-format off */ +/* Pad number settings */ +#define FPIOA_NUM_IO (48) +/* clang-format on */ + +/** + * @brief FPIOA IO functions + * + * @note FPIOA pin function table + * + * | Function | Name | Description | + * |-----------|------------------|-----------------------------------| + * | 0 | JTAG_TCLK | JTAG Test Clock | + * | 1 | JTAG_TDI | JTAG Test Data In | + * | 2 | JTAG_TMS | JTAG Test Mode Select | + * | 3 | JTAG_TDO | JTAG Test Data Out | + * | 4 | SPI0_D0 | SPI0 Data 0 | + * | 5 | SPI0_D1 | SPI0 Data 1 | + * | 6 | SPI0_D2 | SPI0 Data 2 | + * | 7 | SPI0_D3 | SPI0 Data 3 | + * | 8 | SPI0_D4 | SPI0 Data 4 | + * | 9 | SPI0_D5 | SPI0 Data 5 | + * | 10 | SPI0_D6 | SPI0 Data 6 | + * | 11 | SPI0_D7 | SPI0 Data 7 | + * | 12 | SPI0_SS0 | SPI0 Chip Select 0 | + * | 13 | SPI0_SS1 | SPI0 Chip Select 1 | + * | 14 | SPI0_SS2 | SPI0 Chip Select 2 | + * | 15 | SPI0_SS3 | SPI0 Chip Select 3 | + * | 16 | SPI0_ARB | SPI0 Arbitration | + * | 17 | SPI0_SCLK | SPI0 Serial Clock | + * | 18 | UARTHS_RX | UART High speed Receiver | + * | 19 | UARTHS_TX | UART High speed Transmitter | + * | 20 | RESV6 | Reserved function | + * | 21 | RESV7 | Reserved function | + * | 22 | CLK_SPI1 | Clock SPI1 | + * | 23 | CLK_I2C1 | Clock I2C1 | + * | 24 | GPIOHS0 | GPIO High speed 0 | + * | 25 | GPIOHS1 | GPIO High speed 1 | + * | 26 | GPIOHS2 | GPIO High speed 2 | + * | 27 | GPIOHS3 | GPIO High speed 3 | + * | 28 | GPIOHS4 | GPIO High speed 4 | + * | 29 | GPIOHS5 | GPIO High speed 5 | + * | 30 | GPIOHS6 | GPIO High speed 6 | + * | 31 | GPIOHS7 | GPIO High speed 7 | + * | 32 | GPIOHS8 | GPIO High speed 8 | + * | 33 | GPIOHS9 | GPIO High speed 9 | + * | 34 | GPIOHS10 | GPIO High speed 10 | + * | 35 | GPIOHS11 | GPIO High speed 11 | + * | 36 | GPIOHS12 | GPIO High speed 12 | + * | 37 | GPIOHS13 | GPIO High speed 13 | + * | 38 | GPIOHS14 | GPIO High speed 14 | + * | 39 | GPIOHS15 | GPIO High speed 15 | + * | 40 | GPIOHS16 | GPIO High speed 16 | + * | 41 | GPIOHS17 | GPIO High speed 17 | + * | 42 | GPIOHS18 | GPIO High speed 18 | + * | 43 | GPIOHS19 | GPIO High speed 19 | + * | 44 | GPIOHS20 | GPIO High speed 20 | + * | 45 | GPIOHS21 | GPIO High speed 21 | + * | 46 | GPIOHS22 | GPIO High speed 22 | + * | 47 | GPIOHS23 | GPIO High speed 23 | + * | 48 | GPIOHS24 | GPIO High speed 24 | + * | 49 | GPIOHS25 | GPIO High speed 25 | + * | 50 | GPIOHS26 | GPIO High speed 26 | + * | 51 | GPIOHS27 | GPIO High speed 27 | + * | 52 | GPIOHS28 | GPIO High speed 28 | + * | 53 | GPIOHS29 | GPIO High speed 29 | + * | 54 | GPIOHS30 | GPIO High speed 30 | + * | 55 | GPIOHS31 | GPIO High speed 31 | + * | 56 | GPIO0 | GPIO pin 0 | + * | 57 | GPIO1 | GPIO pin 1 | + * | 58 | GPIO2 | GPIO pin 2 | + * | 59 | GPIO3 | GPIO pin 3 | + * | 60 | GPIO4 | GPIO pin 4 | + * | 61 | GPIO5 | GPIO pin 5 | + * | 62 | GPIO6 | GPIO pin 6 | + * | 63 | GPIO7 | GPIO pin 7 | + * | 64 | UART1_RX | UART1 Receiver | + * | 65 | UART1_TX | UART1 Transmitter | + * | 66 | UART2_RX | UART2 Receiver | + * | 67 | UART2_TX | UART2 Transmitter | + * | 68 | UART3_RX | UART3 Receiver | + * | 69 | UART3_TX | UART3 Transmitter | + * | 70 | SPI1_D0 | SPI1 Data 0 | + * | 71 | SPI1_D1 | SPI1 Data 1 | + * | 72 | SPI1_D2 | SPI1 Data 2 | + * | 73 | SPI1_D3 | SPI1 Data 3 | + * | 74 | SPI1_D4 | SPI1 Data 4 | + * | 75 | SPI1_D5 | SPI1 Data 5 | + * | 76 | SPI1_D6 | SPI1 Data 6 | + * | 77 | SPI1_D7 | SPI1 Data 7 | + * | 78 | SPI1_SS0 | SPI1 Chip Select 0 | + * | 79 | SPI1_SS1 | SPI1 Chip Select 1 | + * | 80 | SPI1_SS2 | SPI1 Chip Select 2 | + * | 81 | SPI1_SS3 | SPI1 Chip Select 3 | + * | 82 | SPI1_ARB | SPI1 Arbitration | + * | 83 | SPI1_SCLK | SPI1 Serial Clock | + * | 84 | SPI_SLAVE_D0 | SPI Slave Data 0 | + * | 85 | SPI_SLAVE_SS | SPI Slave Select | + * | 86 | SPI_SLAVE_SCLK | SPI Slave Serial Clock | + * | 87 | I2S0_MCLK | I2S0 Master Clock | + * | 88 | I2S0_SCLK | I2S0 Serial Clock(BCLK) | + * | 89 | I2S0_WS | I2S0 Word Select(LRCLK) | + * | 90 | I2S0_IN_D0 | I2S0 Serial Data Input 0 | + * | 91 | I2S0_IN_D1 | I2S0 Serial Data Input 1 | + * | 92 | I2S0_IN_D2 | I2S0 Serial Data Input 2 | + * | 93 | I2S0_IN_D3 | I2S0 Serial Data Input 3 | + * | 94 | I2S0_OUT_D0 | I2S0 Serial Data Output 0 | + * | 95 | I2S0_OUT_D1 | I2S0 Serial Data Output 1 | + * | 96 | I2S0_OUT_D2 | I2S0 Serial Data Output 2 | + * | 97 | I2S0_OUT_D3 | I2S0 Serial Data Output 3 | + * | 98 | I2S1_MCLK | I2S1 Master Clock | + * | 99 | I2S1_SCLK | I2S1 Serial Clock(BCLK) | + * | 100 | I2S1_WS | I2S1 Word Select(LRCLK) | + * | 101 | I2S1_IN_D0 | I2S1 Serial Data Input 0 | + * | 102 | I2S1_IN_D1 | I2S1 Serial Data Input 1 | + * | 103 | I2S1_IN_D2 | I2S1 Serial Data Input 2 | + * | 104 | I2S1_IN_D3 | I2S1 Serial Data Input 3 | + * | 105 | I2S1_OUT_D0 | I2S1 Serial Data Output 0 | + * | 106 | I2S1_OUT_D1 | I2S1 Serial Data Output 1 | + * | 107 | I2S1_OUT_D2 | I2S1 Serial Data Output 2 | + * | 108 | I2S1_OUT_D3 | I2S1 Serial Data Output 3 | + * | 109 | I2S2_MCLK | I2S2 Master Clock | + * | 110 | I2S2_SCLK | I2S2 Serial Clock(BCLK) | + * | 111 | I2S2_WS | I2S2 Word Select(LRCLK) | + * | 112 | I2S2_IN_D0 | I2S2 Serial Data Input 0 | + * | 113 | I2S2_IN_D1 | I2S2 Serial Data Input 1 | + * | 114 | I2S2_IN_D2 | I2S2 Serial Data Input 2 | + * | 115 | I2S2_IN_D3 | I2S2 Serial Data Input 3 | + * | 116 | I2S2_OUT_D0 | I2S2 Serial Data Output 0 | + * | 117 | I2S2_OUT_D1 | I2S2 Serial Data Output 1 | + * | 118 | I2S2_OUT_D2 | I2S2 Serial Data Output 2 | + * | 119 | I2S2_OUT_D3 | I2S2 Serial Data Output 3 | + * | 120 | RESV0 | Reserved function | + * | 121 | RESV1 | Reserved function | + * | 122 | RESV2 | Reserved function | + * | 123 | RESV3 | Reserved function | + * | 124 | RESV4 | Reserved function | + * | 125 | RESV5 | Reserved function | + * | 126 | I2C0_SCLK | I2C0 Serial Clock | + * | 127 | I2C0_SDA | I2C0 Serial Data | + * | 128 | I2C1_SCLK | I2C1 Serial Clock | + * | 129 | I2C1_SDA | I2C1 Serial Data | + * | 130 | I2C2_SCLK | I2C2 Serial Clock | + * | 131 | I2C2_SDA | I2C2 Serial Data | + * | 132 | CMOS_XCLK | DVP System Clock | + * | 133 | CMOS_RST | DVP System Reset | + * | 134 | CMOS_PWDN | DVP Power Down Mode | + * | 135 | CMOS_VSYNC | DVP Vertical Sync | + * | 136 | CMOS_HREF | DVP Horizontal Reference output | + * | 137 | CMOS_PCLK | Pixel Clock | + * | 138 | CMOS_D0 | Data Bit 0 | + * | 139 | CMOS_D1 | Data Bit 1 | + * | 140 | CMOS_D2 | Data Bit 2 | + * | 141 | CMOS_D3 | Data Bit 3 | + * | 142 | CMOS_D4 | Data Bit 4 | + * | 143 | CMOS_D5 | Data Bit 5 | + * | 144 | CMOS_D6 | Data Bit 6 | + * | 145 | CMOS_D7 | Data Bit 7 | + * | 146 | SCCB_SCLK | SCCB Serial Clock | + * | 147 | SCCB_SDA | SCCB Serial Data | + * | 148 | UART1_CTS | UART1 Clear To Send | + * | 149 | UART1_DSR | UART1 Data Set Ready | + * | 150 | UART1_DCD | UART1 Data Carrier Detect | + * | 151 | UART1_RI | UART1 Ring Indicator | + * | 152 | UART1_SIR_IN | UART1 Serial Infrared Input | + * | 153 | UART1_DTR | UART1 Data Terminal Ready | + * | 154 | UART1_RTS | UART1 Request To Send | + * | 155 | UART1_OUT2 | UART1 User-designated Output 2 | + * | 156 | UART1_OUT1 | UART1 User-designated Output 1 | + * | 157 | UART1_SIR_OUT | UART1 Serial Infrared Output | + * | 158 | UART1_BAUD | UART1 Transmit Clock Output | + * | 159 | UART1_RE | UART1 Receiver Output Enable | + * | 160 | UART1_DE | UART1 Driver Output Enable | + * | 161 | UART1_RS485_EN | UART1 RS485 Enable | + * | 162 | UART2_CTS | UART2 Clear To Send | + * | 163 | UART2_DSR | UART2 Data Set Ready | + * | 164 | UART2_DCD | UART2 Data Carrier Detect | + * | 165 | UART2_RI | UART2 Ring Indicator | + * | 166 | UART2_SIR_IN | UART2 Serial Infrared Input | + * | 167 | UART2_DTR | UART2 Data Terminal Ready | + * | 168 | UART2_RTS | UART2 Request To Send | + * | 169 | UART2_OUT2 | UART2 User-designated Output 2 | + * | 170 | UART2_OUT1 | UART2 User-designated Output 1 | + * | 171 | UART2_SIR_OUT | UART2 Serial Infrared Output | + * | 172 | UART2_BAUD | UART2 Transmit Clock Output | + * | 173 | UART2_RE | UART2 Receiver Output Enable | + * | 174 | UART2_DE | UART2 Driver Output Enable | + * | 175 | UART2_RS485_EN | UART2 RS485 Enable | + * | 176 | UART3_CTS | UART3 Clear To Send | + * | 177 | UART3_DSR | UART3 Data Set Ready | + * | 178 | UART3_DCD | UART3 Data Carrier Detect | + * | 179 | UART3_RI | UART3 Ring Indicator | + * | 180 | UART3_SIR_IN | UART3 Serial Infrared Input | + * | 181 | UART3_DTR | UART3 Data Terminal Ready | + * | 182 | UART3_RTS | UART3 Request To Send | + * | 183 | UART3_OUT2 | UART3 User-designated Output 2 | + * | 184 | UART3_OUT1 | UART3 User-designated Output 1 | + * | 185 | UART3_SIR_OUT | UART3 Serial Infrared Output | + * | 186 | UART3_BAUD | UART3 Transmit Clock Output | + * | 187 | UART3_RE | UART3 Receiver Output Enable | + * | 188 | UART3_DE | UART3 Driver Output Enable | + * | 189 | UART3_RS485_EN | UART3 RS485 Enable | + * | 190 | TIMER0_TOGGLE1 | TIMER0 Toggle Output 1 | + * | 191 | TIMER0_TOGGLE2 | TIMER0 Toggle Output 2 | + * | 192 | TIMER0_TOGGLE3 | TIMER0 Toggle Output 3 | + * | 193 | TIMER0_TOGGLE4 | TIMER0 Toggle Output 4 | + * | 194 | TIMER1_TOGGLE1 | TIMER1 Toggle Output 1 | + * | 195 | TIMER1_TOGGLE2 | TIMER1 Toggle Output 2 | + * | 196 | TIMER1_TOGGLE3 | TIMER1 Toggle Output 3 | + * | 197 | TIMER1_TOGGLE4 | TIMER1 Toggle Output 4 | + * | 198 | TIMER2_TOGGLE1 | TIMER2 Toggle Output 1 | + * | 199 | TIMER2_TOGGLE2 | TIMER2 Toggle Output 2 | + * | 200 | TIMER2_TOGGLE3 | TIMER2 Toggle Output 3 | + * | 201 | TIMER2_TOGGLE4 | TIMER2 Toggle Output 4 | + * | 202 | CLK_SPI2 | Clock SPI2 | + * | 203 | CLK_I2C2 | Clock I2C2 | + * | 204 | INTERNAL0 | Internal function signal 0 | + * | 205 | INTERNAL1 | Internal function signal 1 | + * | 206 | INTERNAL2 | Internal function signal 2 | + * | 207 | INTERNAL3 | Internal function signal 3 | + * | 208 | INTERNAL4 | Internal function signal 4 | + * | 209 | INTERNAL5 | Internal function signal 5 | + * | 210 | INTERNAL6 | Internal function signal 6 | + * | 211 | INTERNAL7 | Internal function signal 7 | + * | 212 | INTERNAL8 | Internal function signal 8 | + * | 213 | INTERNAL9 | Internal function signal 9 | + * | 214 | INTERNAL10 | Internal function signal 10 | + * | 215 | INTERNAL11 | Internal function signal 11 | + * | 216 | INTERNAL12 | Internal function signal 12 | + * | 217 | INTERNAL13 | Internal function signal 13 | + * | 218 | INTERNAL14 | Internal function signal 14 | + * | 219 | INTERNAL15 | Internal function signal 15 | + * | 220 | INTERNAL16 | Internal function signal 16 | + * | 221 | INTERNAL17 | Internal function signal 17 | + * | 222 | CONSTANT | Constant function | + * | 223 | INTERNAL18 | Internal function signal 18 | + * | 224 | DEBUG0 | Debug function 0 | + * | 225 | DEBUG1 | Debug function 1 | + * | 226 | DEBUG2 | Debug function 2 | + * | 227 | DEBUG3 | Debug function 3 | + * | 228 | DEBUG4 | Debug function 4 | + * | 229 | DEBUG5 | Debug function 5 | + * | 230 | DEBUG6 | Debug function 6 | + * | 231 | DEBUG7 | Debug function 7 | + * | 232 | DEBUG8 | Debug function 8 | + * | 233 | DEBUG9 | Debug function 9 | + * | 234 | DEBUG10 | Debug function 10 | + * | 235 | DEBUG11 | Debug function 11 | + * | 236 | DEBUG12 | Debug function 12 | + * | 237 | DEBUG13 | Debug function 13 | + * | 238 | DEBUG14 | Debug function 14 | + * | 239 | DEBUG15 | Debug function 15 | + * | 240 | DEBUG16 | Debug function 16 | + * | 241 | DEBUG17 | Debug function 17 | + * | 242 | DEBUG18 | Debug function 18 | + * | 243 | DEBUG19 | Debug function 19 | + * | 244 | DEBUG20 | Debug function 20 | + * | 245 | DEBUG21 | Debug function 21 | + * | 246 | DEBUG22 | Debug function 22 | + * | 247 | DEBUG23 | Debug function 23 | + * | 248 | DEBUG24 | Debug function 24 | + * | 249 | DEBUG25 | Debug function 25 | + * | 250 | DEBUG26 | Debug function 26 | + * | 251 | DEBUG27 | Debug function 27 | + * | 252 | DEBUG28 | Debug function 28 | + * | 253 | DEBUG29 | Debug function 29 | + * | 254 | DEBUG30 | Debug function 30 | + * | 255 | DEBUG31 | Debug function 31 | + * + * Any IO of FPIOA have 256 functions, it is a IO-function matrix. + * All IO have default reset function, after reset, re-configure + * IO function is required. + */ + +/* clang-format off */ +typedef enum _fpioa_function +{ + FUNC_JTAG_TCLK = 0, /*!< JTAG Test Clock */ + FUNC_JTAG_TDI = 1, /*!< JTAG Test Data In */ + FUNC_JTAG_TMS = 2, /*!< JTAG Test Mode Select */ + FUNC_JTAG_TDO = 3, /*!< JTAG Test Data Out */ + FUNC_SPI0_D0 = 4, /*!< SPI0 Data 0 */ + FUNC_SPI0_D1 = 5, /*!< SPI0 Data 1 */ + FUNC_SPI0_D2 = 6, /*!< SPI0 Data 2 */ + FUNC_SPI0_D3 = 7, /*!< SPI0 Data 3 */ + FUNC_SPI0_D4 = 8, /*!< SPI0 Data 4 */ + FUNC_SPI0_D5 = 9, /*!< SPI0 Data 5 */ + FUNC_SPI0_D6 = 10, /*!< SPI0 Data 6 */ + FUNC_SPI0_D7 = 11, /*!< SPI0 Data 7 */ + FUNC_SPI0_SS0 = 12, /*!< SPI0 Chip Select 0 */ + FUNC_SPI0_SS1 = 13, /*!< SPI0 Chip Select 1 */ + FUNC_SPI0_SS2 = 14, /*!< SPI0 Chip Select 2 */ + FUNC_SPI0_SS3 = 15, /*!< SPI0 Chip Select 3 */ + FUNC_SPI0_ARB = 16, /*!< SPI0 Arbitration */ + FUNC_SPI0_SCLK = 17, /*!< SPI0 Serial Clock */ + FUNC_UARTHS_RX = 18, /*!< UART High speed Receiver */ + FUNC_UARTHS_TX = 19, /*!< UART High speed Transmitter */ + FUNC_RESV6 = 20, /*!< Reserved function */ + FUNC_RESV7 = 21, /*!< Reserved function */ + FUNC_CLK_SPI1 = 22, /*!< Clock SPI1 */ + FUNC_CLK_I2C1 = 23, /*!< Clock I2C1 */ + FUNC_GPIOHS0 = 24, /*!< GPIO High speed 0 */ + FUNC_GPIOHS1 = 25, /*!< GPIO High speed 1 */ + FUNC_GPIOHS2 = 26, /*!< GPIO High speed 2 */ + FUNC_GPIOHS3 = 27, /*!< GPIO High speed 3 */ + FUNC_GPIOHS4 = 28, /*!< GPIO High speed 4 */ + FUNC_GPIOHS5 = 29, /*!< GPIO High speed 5 */ + FUNC_GPIOHS6 = 30, /*!< GPIO High speed 6 */ + FUNC_GPIOHS7 = 31, /*!< GPIO High speed 7 */ + FUNC_GPIOHS8 = 32, /*!< GPIO High speed 8 */ + FUNC_GPIOHS9 = 33, /*!< GPIO High speed 9 */ + FUNC_GPIOHS10 = 34, /*!< GPIO High speed 10 */ + FUNC_GPIOHS11 = 35, /*!< GPIO High speed 11 */ + FUNC_GPIOHS12 = 36, /*!< GPIO High speed 12 */ + FUNC_GPIOHS13 = 37, /*!< GPIO High speed 13 */ + FUNC_GPIOHS14 = 38, /*!< GPIO High speed 14 */ + FUNC_GPIOHS15 = 39, /*!< GPIO High speed 15 */ + FUNC_GPIOHS16 = 40, /*!< GPIO High speed 16 */ + FUNC_GPIOHS17 = 41, /*!< GPIO High speed 17 */ + FUNC_GPIOHS18 = 42, /*!< GPIO High speed 18 */ + FUNC_GPIOHS19 = 43, /*!< GPIO High speed 19 */ + FUNC_GPIOHS20 = 44, /*!< GPIO High speed 20 */ + FUNC_GPIOHS21 = 45, /*!< GPIO High speed 21 */ + FUNC_GPIOHS22 = 46, /*!< GPIO High speed 22 */ + FUNC_GPIOHS23 = 47, /*!< GPIO High speed 23 */ + FUNC_GPIOHS24 = 48, /*!< GPIO High speed 24 */ + FUNC_GPIOHS25 = 49, /*!< GPIO High speed 25 */ + FUNC_GPIOHS26 = 50, /*!< GPIO High speed 26 */ + FUNC_GPIOHS27 = 51, /*!< GPIO High speed 27 */ + FUNC_GPIOHS28 = 52, /*!< GPIO High speed 28 */ + FUNC_GPIOHS29 = 53, /*!< GPIO High speed 29 */ + FUNC_GPIOHS30 = 54, /*!< GPIO High speed 30 */ + FUNC_GPIOHS31 = 55, /*!< GPIO High speed 31 */ + FUNC_GPIO0 = 56, /*!< GPIO pin 0 */ + FUNC_GPIO1 = 57, /*!< GPIO pin 1 */ + FUNC_GPIO2 = 58, /*!< GPIO pin 2 */ + FUNC_GPIO3 = 59, /*!< GPIO pin 3 */ + FUNC_GPIO4 = 60, /*!< GPIO pin 4 */ + FUNC_GPIO5 = 61, /*!< GPIO pin 5 */ + FUNC_GPIO6 = 62, /*!< GPIO pin 6 */ + FUNC_GPIO7 = 63, /*!< GPIO pin 7 */ + FUNC_UART1_RX = 64, /*!< UART1 Receiver */ + FUNC_UART1_TX = 65, /*!< UART1 Transmitter */ + FUNC_UART2_RX = 66, /*!< UART2 Receiver */ + FUNC_UART2_TX = 67, /*!< UART2 Transmitter */ + FUNC_UART3_RX = 68, /*!< UART3 Receiver */ + FUNC_UART3_TX = 69, /*!< UART3 Transmitter */ + FUNC_SPI1_D0 = 70, /*!< SPI1 Data 0 */ + FUNC_SPI1_D1 = 71, /*!< SPI1 Data 1 */ + FUNC_SPI1_D2 = 72, /*!< SPI1 Data 2 */ + FUNC_SPI1_D3 = 73, /*!< SPI1 Data 3 */ + FUNC_SPI1_D4 = 74, /*!< SPI1 Data 4 */ + FUNC_SPI1_D5 = 75, /*!< SPI1 Data 5 */ + FUNC_SPI1_D6 = 76, /*!< SPI1 Data 6 */ + FUNC_SPI1_D7 = 77, /*!< SPI1 Data 7 */ + FUNC_SPI1_SS0 = 78, /*!< SPI1 Chip Select 0 */ + FUNC_SPI1_SS1 = 79, /*!< SPI1 Chip Select 1 */ + FUNC_SPI1_SS2 = 80, /*!< SPI1 Chip Select 2 */ + FUNC_SPI1_SS3 = 81, /*!< SPI1 Chip Select 3 */ + FUNC_SPI1_ARB = 82, /*!< SPI1 Arbitration */ + FUNC_SPI1_SCLK = 83, /*!< SPI1 Serial Clock */ + FUNC_SPI_SLAVE_D0 = 84, /*!< SPI Slave Data 0 */ + FUNC_SPI_SLAVE_SS = 85, /*!< SPI Slave Select */ + FUNC_SPI_SLAVE_SCLK = 86, /*!< SPI Slave Serial Clock */ + FUNC_I2S0_MCLK = 87, /*!< I2S0 Master Clock */ + FUNC_I2S0_SCLK = 88, /*!< I2S0 Serial Clock(BCLK) */ + FUNC_I2S0_WS = 89, /*!< I2S0 Word Select(LRCLK) */ + FUNC_I2S0_IN_D0 = 90, /*!< I2S0 Serial Data Input 0 */ + FUNC_I2S0_IN_D1 = 91, /*!< I2S0 Serial Data Input 1 */ + FUNC_I2S0_IN_D2 = 92, /*!< I2S0 Serial Data Input 2 */ + FUNC_I2S0_IN_D3 = 93, /*!< I2S0 Serial Data Input 3 */ + FUNC_I2S0_OUT_D0 = 94, /*!< I2S0 Serial Data Output 0 */ + FUNC_I2S0_OUT_D1 = 95, /*!< I2S0 Serial Data Output 1 */ + FUNC_I2S0_OUT_D2 = 96, /*!< I2S0 Serial Data Output 2 */ + FUNC_I2S0_OUT_D3 = 97, /*!< I2S0 Serial Data Output 3 */ + FUNC_I2S1_MCLK = 98, /*!< I2S1 Master Clock */ + FUNC_I2S1_SCLK = 99, /*!< I2S1 Serial Clock(BCLK) */ + FUNC_I2S1_WS = 100, /*!< I2S1 Word Select(LRCLK) */ + FUNC_I2S1_IN_D0 = 101, /*!< I2S1 Serial Data Input 0 */ + FUNC_I2S1_IN_D1 = 102, /*!< I2S1 Serial Data Input 1 */ + FUNC_I2S1_IN_D2 = 103, /*!< I2S1 Serial Data Input 2 */ + FUNC_I2S1_IN_D3 = 104, /*!< I2S1 Serial Data Input 3 */ + FUNC_I2S1_OUT_D0 = 105, /*!< I2S1 Serial Data Output 0 */ + FUNC_I2S1_OUT_D1 = 106, /*!< I2S1 Serial Data Output 1 */ + FUNC_I2S1_OUT_D2 = 107, /*!< I2S1 Serial Data Output 2 */ + FUNC_I2S1_OUT_D3 = 108, /*!< I2S1 Serial Data Output 3 */ + FUNC_I2S2_MCLK = 109, /*!< I2S2 Master Clock */ + FUNC_I2S2_SCLK = 110, /*!< I2S2 Serial Clock(BCLK) */ + FUNC_I2S2_WS = 111, /*!< I2S2 Word Select(LRCLK) */ + FUNC_I2S2_IN_D0 = 112, /*!< I2S2 Serial Data Input 0 */ + FUNC_I2S2_IN_D1 = 113, /*!< I2S2 Serial Data Input 1 */ + FUNC_I2S2_IN_D2 = 114, /*!< I2S2 Serial Data Input 2 */ + FUNC_I2S2_IN_D3 = 115, /*!< I2S2 Serial Data Input 3 */ + FUNC_I2S2_OUT_D0 = 116, /*!< I2S2 Serial Data Output 0 */ + FUNC_I2S2_OUT_D1 = 117, /*!< I2S2 Serial Data Output 1 */ + FUNC_I2S2_OUT_D2 = 118, /*!< I2S2 Serial Data Output 2 */ + FUNC_I2S2_OUT_D3 = 119, /*!< I2S2 Serial Data Output 3 */ + FUNC_RESV0 = 120, /*!< Reserved function */ + FUNC_RESV1 = 121, /*!< Reserved function */ + FUNC_RESV2 = 122, /*!< Reserved function */ + FUNC_RESV3 = 123, /*!< Reserved function */ + FUNC_RESV4 = 124, /*!< Reserved function */ + FUNC_RESV5 = 125, /*!< Reserved function */ + FUNC_I2C0_SCLK = 126, /*!< I2C0 Serial Clock */ + FUNC_I2C0_SDA = 127, /*!< I2C0 Serial Data */ + FUNC_I2C1_SCLK = 128, /*!< I2C1 Serial Clock */ + FUNC_I2C1_SDA = 129, /*!< I2C1 Serial Data */ + FUNC_I2C2_SCLK = 130, /*!< I2C2 Serial Clock */ + FUNC_I2C2_SDA = 131, /*!< I2C2 Serial Data */ + FUNC_CMOS_XCLK = 132, /*!< DVP System Clock */ + FUNC_CMOS_RST = 133, /*!< DVP System Reset */ + FUNC_CMOS_PWDN = 134, /*!< DVP Power Down Mode */ + FUNC_CMOS_VSYNC = 135, /*!< DVP Vertical Sync */ + FUNC_CMOS_HREF = 136, /*!< DVP Horizontal Reference output */ + FUNC_CMOS_PCLK = 137, /*!< Pixel Clock */ + FUNC_CMOS_D0 = 138, /*!< Data Bit 0 */ + FUNC_CMOS_D1 = 139, /*!< Data Bit 1 */ + FUNC_CMOS_D2 = 140, /*!< Data Bit 2 */ + FUNC_CMOS_D3 = 141, /*!< Data Bit 3 */ + FUNC_CMOS_D4 = 142, /*!< Data Bit 4 */ + FUNC_CMOS_D5 = 143, /*!< Data Bit 5 */ + FUNC_CMOS_D6 = 144, /*!< Data Bit 6 */ + FUNC_CMOS_D7 = 145, /*!< Data Bit 7 */ + FUNC_SCCB_SCLK = 146, /*!< SCCB Serial Clock */ + FUNC_SCCB_SDA = 147, /*!< SCCB Serial Data */ + FUNC_UART1_CTS = 148, /*!< UART1 Clear To Send */ + FUNC_UART1_DSR = 149, /*!< UART1 Data Set Ready */ + FUNC_UART1_DCD = 150, /*!< UART1 Data Carrier Detect */ + FUNC_UART1_RI = 151, /*!< UART1 Ring Indicator */ + FUNC_UART1_SIR_IN = 152, /*!< UART1 Serial Infrared Input */ + FUNC_UART1_DTR = 153, /*!< UART1 Data Terminal Ready */ + FUNC_UART1_RTS = 154, /*!< UART1 Request To Send */ + FUNC_UART1_OUT2 = 155, /*!< UART1 User-designated Output 2 */ + FUNC_UART1_OUT1 = 156, /*!< UART1 User-designated Output 1 */ + FUNC_UART1_SIR_OUT = 157, /*!< UART1 Serial Infrared Output */ + FUNC_UART1_BAUD = 158, /*!< UART1 Transmit Clock Output */ + FUNC_UART1_RE = 159, /*!< UART1 Receiver Output Enable */ + FUNC_UART1_DE = 160, /*!< UART1 Driver Output Enable */ + FUNC_UART1_RS485_EN = 161, /*!< UART1 RS485 Enable */ + FUNC_UART2_CTS = 162, /*!< UART2 Clear To Send */ + FUNC_UART2_DSR = 163, /*!< UART2 Data Set Ready */ + FUNC_UART2_DCD = 164, /*!< UART2 Data Carrier Detect */ + FUNC_UART2_RI = 165, /*!< UART2 Ring Indicator */ + FUNC_UART2_SIR_IN = 166, /*!< UART2 Serial Infrared Input */ + FUNC_UART2_DTR = 167, /*!< UART2 Data Terminal Ready */ + FUNC_UART2_RTS = 168, /*!< UART2 Request To Send */ + FUNC_UART2_OUT2 = 169, /*!< UART2 User-designated Output 2 */ + FUNC_UART2_OUT1 = 170, /*!< UART2 User-designated Output 1 */ + FUNC_UART2_SIR_OUT = 171, /*!< UART2 Serial Infrared Output */ + FUNC_UART2_BAUD = 172, /*!< UART2 Transmit Clock Output */ + FUNC_UART2_RE = 173, /*!< UART2 Receiver Output Enable */ + FUNC_UART2_DE = 174, /*!< UART2 Driver Output Enable */ + FUNC_UART2_RS485_EN = 175, /*!< UART2 RS485 Enable */ + FUNC_UART3_CTS = 176, /*!< UART3 Clear To Send */ + FUNC_UART3_DSR = 177, /*!< UART3 Data Set Ready */ + FUNC_UART3_DCD = 178, /*!< UART3 Data Carrier Detect */ + FUNC_UART3_RI = 179, /*!< UART3 Ring Indicator */ + FUNC_UART3_SIR_IN = 180, /*!< UART3 Serial Infrared Input */ + FUNC_UART3_DTR = 181, /*!< UART3 Data Terminal Ready */ + FUNC_UART3_RTS = 182, /*!< UART3 Request To Send */ + FUNC_UART3_OUT2 = 183, /*!< UART3 User-designated Output 2 */ + FUNC_UART3_OUT1 = 184, /*!< UART3 User-designated Output 1 */ + FUNC_UART3_SIR_OUT = 185, /*!< UART3 Serial Infrared Output */ + FUNC_UART3_BAUD = 186, /*!< UART3 Transmit Clock Output */ + FUNC_UART3_RE = 187, /*!< UART3 Receiver Output Enable */ + FUNC_UART3_DE = 188, /*!< UART3 Driver Output Enable */ + FUNC_UART3_RS485_EN = 189, /*!< UART3 RS485 Enable */ + FUNC_TIMER0_TOGGLE1 = 190, /*!< TIMER0 Toggle Output 1 */ + FUNC_TIMER0_TOGGLE2 = 191, /*!< TIMER0 Toggle Output 2 */ + FUNC_TIMER0_TOGGLE3 = 192, /*!< TIMER0 Toggle Output 3 */ + FUNC_TIMER0_TOGGLE4 = 193, /*!< TIMER0 Toggle Output 4 */ + FUNC_TIMER1_TOGGLE1 = 194, /*!< TIMER1 Toggle Output 1 */ + FUNC_TIMER1_TOGGLE2 = 195, /*!< TIMER1 Toggle Output 2 */ + FUNC_TIMER1_TOGGLE3 = 196, /*!< TIMER1 Toggle Output 3 */ + FUNC_TIMER1_TOGGLE4 = 197, /*!< TIMER1 Toggle Output 4 */ + FUNC_TIMER2_TOGGLE1 = 198, /*!< TIMER2 Toggle Output 1 */ + FUNC_TIMER2_TOGGLE2 = 199, /*!< TIMER2 Toggle Output 2 */ + FUNC_TIMER2_TOGGLE3 = 200, /*!< TIMER2 Toggle Output 3 */ + FUNC_TIMER2_TOGGLE4 = 201, /*!< TIMER2 Toggle Output 4 */ + FUNC_CLK_SPI2 = 202, /*!< Clock SPI2 */ + FUNC_CLK_I2C2 = 203, /*!< Clock I2C2 */ + FUNC_INTERNAL0 = 204, /*!< Internal function signal 0 */ + FUNC_INTERNAL1 = 205, /*!< Internal function signal 1 */ + FUNC_INTERNAL2 = 206, /*!< Internal function signal 2 */ + FUNC_INTERNAL3 = 207, /*!< Internal function signal 3 */ + FUNC_INTERNAL4 = 208, /*!< Internal function signal 4 */ + FUNC_INTERNAL5 = 209, /*!< Internal function signal 5 */ + FUNC_INTERNAL6 = 210, /*!< Internal function signal 6 */ + FUNC_INTERNAL7 = 211, /*!< Internal function signal 7 */ + FUNC_INTERNAL8 = 212, /*!< Internal function signal 8 */ + FUNC_INTERNAL9 = 213, /*!< Internal function signal 9 */ + FUNC_INTERNAL10 = 214, /*!< Internal function signal 10 */ + FUNC_INTERNAL11 = 215, /*!< Internal function signal 11 */ + FUNC_INTERNAL12 = 216, /*!< Internal function signal 12 */ + FUNC_INTERNAL13 = 217, /*!< Internal function signal 13 */ + FUNC_INTERNAL14 = 218, /*!< Internal function signal 14 */ + FUNC_INTERNAL15 = 219, /*!< Internal function signal 15 */ + FUNC_INTERNAL16 = 220, /*!< Internal function signal 16 */ + FUNC_INTERNAL17 = 221, /*!< Internal function signal 17 */ + FUNC_CONSTANT = 222, /*!< Constant function */ + FUNC_INTERNAL18 = 223, /*!< Internal function signal 18 */ + FUNC_DEBUG0 = 224, /*!< Debug function 0 */ + FUNC_DEBUG1 = 225, /*!< Debug function 1 */ + FUNC_DEBUG2 = 226, /*!< Debug function 2 */ + FUNC_DEBUG3 = 227, /*!< Debug function 3 */ + FUNC_DEBUG4 = 228, /*!< Debug function 4 */ + FUNC_DEBUG5 = 229, /*!< Debug function 5 */ + FUNC_DEBUG6 = 230, /*!< Debug function 6 */ + FUNC_DEBUG7 = 231, /*!< Debug function 7 */ + FUNC_DEBUG8 = 232, /*!< Debug function 8 */ + FUNC_DEBUG9 = 233, /*!< Debug function 9 */ + FUNC_DEBUG10 = 234, /*!< Debug function 10 */ + FUNC_DEBUG11 = 235, /*!< Debug function 11 */ + FUNC_DEBUG12 = 236, /*!< Debug function 12 */ + FUNC_DEBUG13 = 237, /*!< Debug function 13 */ + FUNC_DEBUG14 = 238, /*!< Debug function 14 */ + FUNC_DEBUG15 = 239, /*!< Debug function 15 */ + FUNC_DEBUG16 = 240, /*!< Debug function 16 */ + FUNC_DEBUG17 = 241, /*!< Debug function 17 */ + FUNC_DEBUG18 = 242, /*!< Debug function 18 */ + FUNC_DEBUG19 = 243, /*!< Debug function 19 */ + FUNC_DEBUG20 = 244, /*!< Debug function 20 */ + FUNC_DEBUG21 = 245, /*!< Debug function 21 */ + FUNC_DEBUG22 = 246, /*!< Debug function 22 */ + FUNC_DEBUG23 = 247, /*!< Debug function 23 */ + FUNC_DEBUG24 = 248, /*!< Debug function 24 */ + FUNC_DEBUG25 = 249, /*!< Debug function 25 */ + FUNC_DEBUG26 = 250, /*!< Debug function 26 */ + FUNC_DEBUG27 = 251, /*!< Debug function 27 */ + FUNC_DEBUG28 = 252, /*!< Debug function 28 */ + FUNC_DEBUG29 = 253, /*!< Debug function 29 */ + FUNC_DEBUG30 = 254, /*!< Debug function 30 */ + FUNC_DEBUG31 = 255, /*!< Debug function 31 */ + FUNC_MAX = 256, /*!< Function numbers */ +} fpioa_function_t; +/* clang-format on */ + +/** + * @brief FPIOA pull settings + * + * @note FPIOA pull settings description + * + * | PU | PD | Description | + * |-----|-----|-----------------------------------| + * | 0 | 0 | No Pull | + * | 0 | 1 | Pull Down | + * | 1 | 0 | Pull Up | + * | 1 | 1 | Undefined | + * + */ + +/* clang-format off */ +typedef enum _fpioa_pull +{ + FPIOA_PULL_NONE, /*!< No Pull */ + FPIOA_PULL_DOWN, /*!< Pull Down */ + FPIOA_PULL_UP, /*!< Pull Up */ + FPIOA_PULL_MAX /*!< Count of pull settings */ +} fpioa_pull_t; +/* clang-format on */ + +/** + * @brief FPIOA driving settings + * + * @note FPIOA driving settings description + * There are 16 kinds of driving settings + * + * @note Low Level Output Current + * + * |DS[3:0] |Min(mA)|Typ(mA)|Max(mA)| + * |--------|-------|-------|-------| + * |0000 |3.2 |5.4 |8.3 | + * |0001 |4.7 |8.0 |12.3 | + * |0010 |6.3 |10.7 |16.4 | + * |0011 |7.8 |13.2 |20.2 | + * |0100 |9.4 |15.9 |24.2 | + * |0101 |10.9 |18.4 |28.1 | + * |0110 |12.4 |20.9 |31.8 | + * |0111 |13.9 |23.4 |35.5 | + * + * @note High Level Output Current + * + * |DS[3:0] |Min(mA)|Typ(mA)|Max(mA)| + * |--------|-------|-------|-------| + * |0000 |5.0 |7.6 |11.2 | + * |0001 |7.5 |11.4 |16.8 | + * |0010 |10.0 |15.2 |22.3 | + * |0011 |12.4 |18.9 |27.8 | + * |0100 |14.9 |22.6 |33.3 | + * |0101 |17.4 |26.3 |38.7 | + * |0110 |19.8 |30.0 |44.1 | + * |0111 |22.3 |33.7 |49.5 | + * + */ + +/* clang-format off */ +typedef enum _fpioa_driving +{ + FPIOA_DRIVING_0, /*!< 0000 */ + FPIOA_DRIVING_1, /*!< 0001 */ + FPIOA_DRIVING_2, /*!< 0010 */ + FPIOA_DRIVING_3, /*!< 0011 */ + FPIOA_DRIVING_4, /*!< 0100 */ + FPIOA_DRIVING_5, /*!< 0101 */ + FPIOA_DRIVING_6, /*!< 0110 */ + FPIOA_DRIVING_7, /*!< 0111 */ + FPIOA_DRIVING_8, /*!< 1000 */ + FPIOA_DRIVING_9, /*!< 1001 */ + FPIOA_DRIVING_10, /*!< 1010 */ + FPIOA_DRIVING_11, /*!< 1011 */ + FPIOA_DRIVING_12, /*!< 1100 */ + FPIOA_DRIVING_13, /*!< 1101 */ + FPIOA_DRIVING_14, /*!< 1110 */ + FPIOA_DRIVING_15, /*!< 1111 */ + FPIOA_DRIVING_MAX /*!< Count of driving settings */ +} fpioa_driving_t; +/* clang-format on */ + +/** + * @brief FPIOA IO + * + * FPIOA IO is the specific pin of the chip package. Every IO + * has a 32bit width register that can independently implement + * schmitt trigger, invert input, invert output, strong pull + * up, driving selector, static input and static output. And more, + * it can implement any pin of any peripheral devices. + * + * @note FPIOA IO's register bits Layout + * + * | Bits | Name |Description | + * |-----------|----------|---------------------------------------------------| + * | 31 | PAD_DI | Read current IO's data input. | + * | 30:24 | NA | Reserved bits. | + * | 23 | ST | Schmitt trigger. | + * | 22 | DI_INV | Invert Data input. | + * | 21 | IE_INV | Invert the input enable signal. | + * | 20 | IE_EN | Input enable. It can disable or enable IO input. | + * | 19 | SL | Slew rate control enable. | + * | 18 | SPU | Strong pull up. | + * | 17 | PD | Pull select: 0 for pull down, 1 for pull up. | + * | 16 | PU | Pull enable. | + * | 15 | DO_INV | Invert the result of data output select (DO_SEL). | + * | 14 | DO_SEL | Data output select: 0 for DO, 1 for OE. | + * | 13 | OE_INV | Invert the output enable signal. | + * | 12 | OE_EN | Output enable.It can disable or enable IO output. | + * | 11:8 | DS | Driving selector. | + * | 7:0 | CH_SEL | Channel select from 256 input. | + * + */ +typedef struct _fpioa_io_config +{ + uint32_t ch_sel : 8; + /*!< Channel select from 256 input. */ + uint32_t ds : 4; + /*!< Driving selector. */ + uint32_t oe_en : 1; + /*!< Static output enable, will AND with OE_INV. */ + uint32_t oe_inv : 1; + /*!< Invert output enable. */ + uint32_t do_sel : 1; + /*!< Data output select: 0 for DO, 1 for OE. */ + uint32_t do_inv : 1; + /*!< Invert the result of data output select (DO_SEL). */ + uint32_t pu : 1; + /*!< Pull up enable. 0 for nothing, 1 for pull up. */ + uint32_t pd : 1; + /*!< Pull down enable. 0 for nothing, 1 for pull down. */ + uint32_t resv0 : 1; + /*!< Reserved bits. */ + uint32_t sl : 1; + /*!< Slew rate control enable. */ + uint32_t ie_en : 1; + /*!< Static input enable, will AND with IE_INV. */ + uint32_t ie_inv : 1; + /*!< Invert input enable. */ + uint32_t di_inv : 1; + /*!< Invert Data input. */ + uint32_t st : 1; + /*!< Schmitt trigger. */ + uint32_t resv1 : 7; + /*!< Reserved bits. */ + uint32_t pad_di : 1; + /*!< Read current IO's data input. */ +} __attribute__((packed, aligned(4))) fpioa_io_config_t; + +/** + * @brief FPIOA tie setting + * + * FPIOA Object have 48 IO pin object and 256 bit input tie bits. + * All SPI arbitration signal will tie high by default. + * + * @note FPIOA function tie bits RAM Layout + * + * | Address | Name |Description | + * |-----------|------------------|----------------------------------| + * | 0x000 | TIE_EN[31:0] | Input tie enable bits [31:0] | + * | 0x004 | TIE_EN[63:32] | Input tie enable bits [63:32] | + * | 0x008 | TIE_EN[95:64] | Input tie enable bits [95:64] | + * | 0x00C | TIE_EN[127:96] | Input tie enable bits [127:96] | + * | 0x010 | TIE_EN[159:128] | Input tie enable bits [159:128] | + * | 0x014 | TIE_EN[191:160] | Input tie enable bits [191:160] | + * | 0x018 | TIE_EN[223:192] | Input tie enable bits [223:192] | + * | 0x01C | TIE_EN[255:224] | Input tie enable bits [255:224] | + * | 0x020 | TIE_VAL[31:0] | Input tie value bits [31:0] | + * | 0x024 | TIE_VAL[63:32] | Input tie value bits [63:32] | + * | 0x028 | TIE_VAL[95:64] | Input tie value bits [95:64] | + * | 0x02C | TIE_VAL[127:96] | Input tie value bits [127:96] | + * | 0x030 | TIE_VAL[159:128] | Input tie value bits [159:128] | + * | 0x034 | TIE_VAL[191:160] | Input tie value bits [191:160] | + * | 0x038 | TIE_VAL[223:192] | Input tie value bits [223:192] | + * | 0x03C | TIE_VAL[255:224] | Input tie value bits [255:224] | + * + * @note Function which input tie high by default + * + * | Name |Description | + * |---------------|---------------------------------------| + * | SPI0_ARB | Arbitration function of SPI master 0 | + * | SPI1_ARB | Arbitration function of SPI master 1 | + * + * Tie high means the SPI Arbitration input is 1 + * + */ +typedef struct _fpioa_tie +{ + uint32_t en[FUNC_MAX / 32]; + /*!< FPIOA GPIO multiplexer tie enable array */ + uint32_t val[FUNC_MAX / 32]; + /*!< FPIOA GPIO multiplexer tie value array */ +} __attribute__((packed, aligned(4))) fpioa_tie_t; + +/** + * @brief FPIOA Object + * + * FPIOA Object have 48 IO pin object and 256 bit input tie bits. + * All SPI arbitration signal will tie high by default. + * + * @note FPIOA IO Pin RAM Layout + * + * | Address | Name |Description | + * |-----------|----------|--------------------------------| + * | 0x000 | PAD0 | FPIOA GPIO multiplexer io 0 | + * | 0x004 | PAD1 | FPIOA GPIO multiplexer io 1 | + * | 0x008 | PAD2 | FPIOA GPIO multiplexer io 2 | + * | 0x00C | PAD3 | FPIOA GPIO multiplexer io 3 | + * | 0x010 | PAD4 | FPIOA GPIO multiplexer io 4 | + * | 0x014 | PAD5 | FPIOA GPIO multiplexer io 5 | + * | 0x018 | PAD6 | FPIOA GPIO multiplexer io 6 | + * | 0x01C | PAD7 | FPIOA GPIO multiplexer io 7 | + * | 0x020 | PAD8 | FPIOA GPIO multiplexer io 8 | + * | 0x024 | PAD9 | FPIOA GPIO multiplexer io 9 | + * | 0x028 | PAD10 | FPIOA GPIO multiplexer io 10 | + * | 0x02C | PAD11 | FPIOA GPIO multiplexer io 11 | + * | 0x030 | PAD12 | FPIOA GPIO multiplexer io 12 | + * | 0x034 | PAD13 | FPIOA GPIO multiplexer io 13 | + * | 0x038 | PAD14 | FPIOA GPIO multiplexer io 14 | + * | 0x03C | PAD15 | FPIOA GPIO multiplexer io 15 | + * | 0x040 | PAD16 | FPIOA GPIO multiplexer io 16 | + * | 0x044 | PAD17 | FPIOA GPIO multiplexer io 17 | + * | 0x048 | PAD18 | FPIOA GPIO multiplexer io 18 | + * | 0x04C | PAD19 | FPIOA GPIO multiplexer io 19 | + * | 0x050 | PAD20 | FPIOA GPIO multiplexer io 20 | + * | 0x054 | PAD21 | FPIOA GPIO multiplexer io 21 | + * | 0x058 | PAD22 | FPIOA GPIO multiplexer io 22 | + * | 0x05C | PAD23 | FPIOA GPIO multiplexer io 23 | + * | 0x060 | PAD24 | FPIOA GPIO multiplexer io 24 | + * | 0x064 | PAD25 | FPIOA GPIO multiplexer io 25 | + * | 0x068 | PAD26 | FPIOA GPIO multiplexer io 26 | + * | 0x06C | PAD27 | FPIOA GPIO multiplexer io 27 | + * | 0x070 | PAD28 | FPIOA GPIO multiplexer io 28 | + * | 0x074 | PAD29 | FPIOA GPIO multiplexer io 29 | + * | 0x078 | PAD30 | FPIOA GPIO multiplexer io 30 | + * | 0x07C | PAD31 | FPIOA GPIO multiplexer io 31 | + * | 0x080 | PAD32 | FPIOA GPIO multiplexer io 32 | + * | 0x084 | PAD33 | FPIOA GPIO multiplexer io 33 | + * | 0x088 | PAD34 | FPIOA GPIO multiplexer io 34 | + * | 0x08C | PAD35 | FPIOA GPIO multiplexer io 35 | + * | 0x090 | PAD36 | FPIOA GPIO multiplexer io 36 | + * | 0x094 | PAD37 | FPIOA GPIO multiplexer io 37 | + * | 0x098 | PAD38 | FPIOA GPIO multiplexer io 38 | + * | 0x09C | PAD39 | FPIOA GPIO multiplexer io 39 | + * | 0x0A0 | PAD40 | FPIOA GPIO multiplexer io 40 | + * | 0x0A4 | PAD41 | FPIOA GPIO multiplexer io 41 | + * | 0x0A8 | PAD42 | FPIOA GPIO multiplexer io 42 | + * | 0x0AC | PAD43 | FPIOA GPIO multiplexer io 43 | + * | 0x0B0 | PAD44 | FPIOA GPIO multiplexer io 44 | + * | 0x0B4 | PAD45 | FPIOA GPIO multiplexer io 45 | + * | 0x0B8 | PAD46 | FPIOA GPIO multiplexer io 46 | + * | 0x0BC | PAD47 | FPIOA GPIO multiplexer io 47 | + * + */ +typedef struct _fpioa +{ + fpioa_io_config_t io[FPIOA_NUM_IO]; + /*!< FPIOA GPIO multiplexer io array */ + fpioa_tie_t tie; + /*!< FPIOA GPIO multiplexer tie */ +} __attribute__((packed, aligned(4))) fpioa_t; + +/** + * @brief FPIOA object instanse + */ +extern volatile fpioa_t *const fpioa; + +/** + * @brief Initialize FPIOA user custom default settings + * + * @note This function will set all FPIOA pad registers to user-defined + * values from kconfig + * + * @return result + * - 0 Success + * - Other Fail + */ +int FpioaInit(void); + +/** + * @brief Get IO configuration + * + * @param[in] number The IO number + * @param cfg Pointer to struct of IO configuration for specified IO + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_get_io(int number, fpioa_io_config_t *cfg); + +/** + * @brief Set IO configuration + * + * @param[in] number The IO number + * @param[in] cfg Pointer to struct of IO configuration for specified IO + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_io(int number, fpioa_io_config_t *cfg); + +/** + * @brief Set IO configuration with function number + * + * @note The default IO configuration which bind to function number will + * set automatically + * + * @param[in] number The IO number + * @param[in] function The function enum number + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_function_raw(int number, fpioa_function_t function); + +/** + * @brief Set only IO configuration with function number + * + * @note The default IO configuration which bind to function number will + * set automatically + * + * @param[in] number The IO number + * @param[in] function The function enum number + * + * @return result + * - 0 Success + * - Other Fail + */ +int FpioaSetFunction(int number, fpioa_function_t function); + +/** + * @brief Set tie enable to function + * + * @param[in] function The function enum number + * @param[in] enable Tie enable to set, 1 is enable, 0 is disable + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_tie_enable(fpioa_function_t function, int enable); + +/** + * @brief Set tie value to function + * + * @param[in] function The function enum number + * @param[in] value Tie value to set, 1 is HIGH, 0 is LOW + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_tie_value(fpioa_function_t function, int value); + +/** + * @brief Set IO pull function + * + * @param[in] number The IO number + * @param[in] pull The pull enum number + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_io_pull(int number, fpioa_pull_t pull); + +/** + * @brief Get IO pull function + * + * @param[in] number The IO number + * + * @return result + * - -1 Fail + * - Other The pull enum number + */ +int fpioa_get_io_pull(int number); + +/** + * @brief Set IO driving + * + * @param[in] number The IO number + * @param[in] driving The driving enum number + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_io_driving(int number, fpioa_driving_t driving); + +/** + * @brief Get IO driving + * + * @param[in] number The IO number + * + * @return result + * - -1 Fail + * - Other The driving enum number + */ +int fpioa_get_io_driving(int number); + +/** + * @brief Get IO by function + * + * @param[in] function The function enum number + * + * @return result + * - -1 Fail + * - Other The IO number + */ +int fpioa_get_io_by_function(fpioa_function_t function); + +/** + * @brief Set IO slew rate control + * + * @param[in] number The IO number + * @param[in] sl_value Enable slew rate. 0: disable 1:enable + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_sl(int number, uint8_t sl_enable); + +/** + * @brief Set IO slew rate + * + * @param[in] number The IO number + * @param[in] st_enable Enable schmitt trigger. 0: disable 1:enable + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_st(int number, uint8_t st_enable); + +#ifdef __cplusplus +} +#endif + +#endif /* __FPIOA_H__ */ + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/gpio.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/gpio.h new file mode 100644 index 000000000..00e73fee1 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/gpio.h @@ -0,0 +1,178 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file gpio.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#ifndef __GPIO_H__ +#define __GPIO_H__ + +#include "platform.h" +#include +#include +#include "gpio_common.h" +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Structure for accessing GPIO registers by individual bit + */ +typedef struct _gpio_bits +{ + uint32_t b0 : 1; + uint32_t b1 : 1; + uint32_t b2 : 1; + uint32_t b3 : 1; + uint32_t b4 : 1; + uint32_t b5 : 1; + uint32_t b6 : 1; + uint32_t b7 : 1; + uint32_t b8 : 1; + uint32_t b9 : 1; + uint32_t b10 : 1; + uint32_t b11 : 1; + uint32_t b12 : 1; + uint32_t b13 : 1; + uint32_t b14 : 1; + uint32_t b15 : 1; + uint32_t b16 : 1; + uint32_t b17 : 1; + uint32_t b18 : 1; + uint32_t b19 : 1; + uint32_t b20 : 1; + uint32_t b21 : 1; + uint32_t b22 : 1; + uint32_t b23 : 1; + uint32_t b24 : 1; + uint32_t b25 : 1; + uint32_t b26 : 1; + uint32_t b27 : 1; + uint32_t b28 : 1; + uint32_t b29 : 1; + uint32_t b30 : 1; + uint32_t b31 : 1; +} __attribute__((packed, aligned(4))) gpio_bits_t; + +/** + * @brief Structure of templates for accessing GPIO registers + */ +typedef union _gpio_access_tp +{ + /* 32x1 bit mode */ + uint32_t u32[1]; + /* 16x2 bit mode */ + uint16_t u16[2]; + /* 8x4 bit mode */ + uint8_t u8[4]; + /* 1 bit mode */ + gpio_bits_t bits; +} __attribute__((packed, aligned(4))) gpio_access_tp_t; + +/** + * @brief The GPIO address map + */ +typedef struct _gpio +{ + /* Offset 0x00: Data (output) registers */ + gpio_access_tp_t data_output; + /* Offset 0x04: Data direction registers */ + gpio_access_tp_t direction; + /* Offset 0x08: Data source registers */ + gpio_access_tp_t source; + /* Offset 0x10 - 0x2f: Unused registers, 9x4 bytes */ + uint32_t unused_0[9]; + /* Offset 0x30: Interrupt enable/disable registers */ + gpio_access_tp_t interrupt_enable; + /* Offset 0x34: Interrupt mask registers */ + gpio_access_tp_t interrupt_mask; + /* Offset 0x38: Interrupt level registers */ + gpio_access_tp_t interrupt_level; + /* Offset 0x3c: Interrupt polarity registers */ + gpio_access_tp_t interrupt_polarity; + /* Offset 0x40: Interrupt status registers */ + gpio_access_tp_t interrupt_status; + /* Offset 0x44: Raw interrupt status registers */ + gpio_access_tp_t interrupt_status_raw; + /* Offset 0x48: Interrupt debounce registers */ + gpio_access_tp_t interrupt_debounce; + /* Offset 0x4c: Registers for clearing interrupts */ + gpio_access_tp_t interrupt_clear; + /* Offset 0x50: External port (data input) registers */ + gpio_access_tp_t data_input; + /* Offset 0x54 - 0x5f: Unused registers, 3x4 bytes */ + uint32_t unused_1[3]; + /* Offset 0x60: Sync level registers */ + gpio_access_tp_t sync_level; + /* Offset 0x64: ID code */ + gpio_access_tp_t id_code; + /* Offset 0x68: Interrupt both edge type */ + gpio_access_tp_t interrupt_bothedge; + +} __attribute__((packed, aligned(4))) gpio_t; + +/** + * @brief Bus GPIO object instance + */ +extern volatile gpio_t *const gpio; + +/** + * @brief Gpio initialize + * + * @return Result + * - 0 Success + * - Other Fail + */ +int gpio_init(void); + +/** + * @brief Set Gpio drive mode + * + * @param[in] pin Gpio pin + * @param[in] mode Gpio pin drive mode + */ +void gpio_set_drive_mode(uint8_t pin, gpio_drive_mode_t mode); + +/** + * @brief Get Gpio pin value + * + * @param[in] pin Gpio pin + * @return Pin value + * + * - GPIO_PV_Low Gpio pin low + * - GPIO_PV_High Gpio pin high + */ +gpio_pin_value_t gpio_get_pin(uint8_t pin); + +/** + * @brief Set Gpio pin value + * + * @param[in] pin Gpio pin + * @param[in] value Gpio pin value + */ +void gpio_set_pin(uint8_t pin, gpio_pin_value_t value); + +#ifdef __cplusplus +} +#endif + +#endif /* __GPIO_H__ */ + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/gpio_common.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/gpio_common.h new file mode 100644 index 000000000..08979d8ee --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/gpio_common.h @@ -0,0 +1,61 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file gpio_common.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#ifndef __GPIO_COMMON_H__ +#define __GPIO_COMMON_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum _gpio_drive_mode +{ + GPIO_DM_INPUT, + GPIO_DM_INPUT_PULL_DOWN, + GPIO_DM_INPUT_PULL_UP, + GPIO_DM_OUTPUT, +} gpio_drive_mode_t; + +typedef enum _gpio_pin_edge +{ + GPIO_PE_NONE, + GPIO_PE_FALLING, + GPIO_PE_RISING, + GPIO_PE_BOTH, + GPIO_PE_LOW, + GPIO_PE_HIGH = 8, +} GpioPinEdgeT; + +typedef enum _gpio_pin_value +{ + GPIO_PV_LOW, + GPIO_PV_HIGH +} gpio_pin_value_t; + +#ifdef __cplusplus +} +#endif + +#endif /* __GPIO_COMMON_H__ */ + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/gpiohs.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/gpiohs.h new file mode 100644 index 000000000..c58470c13 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/gpiohs.h @@ -0,0 +1,277 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file gpiohs.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#ifndef __GPIOHS_H__ +#define __GPIOHS_H__ + +#include +#include "platform.h" +#include +#include "gpio_common.h" +#include "plic.h" +#ifdef __cplusplus +extern "C" { +#endif + +/* clang-format off */ +/* Register address offsets */ +#define GPIOHS_INPUT_VAL (0x00) +#define GPIOHS_INPUT_EN (0x04) +#define GPIOHS_OUTPUT_EN (0x08) +#define GPIOHS_OUTPUT_VAL (0x0C) +#define GPIOHS_PULLUP_EN (0x10) +#define GPIOHS_DRIVE (0x14) +#define GPIOHS_RISE_IE (0x18) +#define GPIOHS_RISE_IP (0x1C) +#define GPIOHS_FALL_IE (0x20) +#define GPIOHS_FALL_IP (0x24) +#define GPIOHS_HIGH_IE (0x28) +#define GPIOHS_HIGH_IP (0x2C) +#define GPIOHS_LOW_IE (0x30) +#define GPIOHS_LOW_IP (0x34) +#define GPIOHS_IOF_EN (0x38) +#define GPIOHS_IOF_SEL (0x3C) +#define GPIOHS_OUTPUT_XOR (0x40) +/* clang-format on */ + +/** + * @brief GPIO bits raw object + */ +typedef struct _gpiohs_raw +{ + /* Address offset 0x00 */ + uint32_t input_val; + /* Address offset 0x04 */ + uint32_t input_en; + /* Address offset 0x08 */ + uint32_t output_en; + /* Address offset 0x0c */ + uint32_t output_val; + /* Address offset 0x10 */ + uint32_t pullup_en; + /* Address offset 0x14 */ + uint32_t drive; + /* Address offset 0x18 */ + uint32_t rise_ie; + /* Address offset 0x1c */ + uint32_t rise_ip; + /* Address offset 0x20 */ + uint32_t fall_ie; + /* Address offset 0x24 */ + uint32_t fall_ip; + /* Address offset 0x28 */ + uint32_t high_ie; + /* Address offset 0x2c */ + uint32_t high_ip; + /* Address offset 0x30 */ + uint32_t low_ie; + /* Address offset 0x34 */ + uint32_t low_ip; + /* Address offset 0x38 */ + uint32_t iof_en; + /* Address offset 0x3c */ + uint32_t iof_sel; + /* Address offset 0x40 */ + uint32_t output_xor; +} __attribute__((packed, aligned(4))) gpiohs_raw_t; + +/** + * @brief GPIO bits object + */ +typedef struct _gpiohs_bits +{ + uint32_t b0 : 1; + uint32_t b1 : 1; + uint32_t b2 : 1; + uint32_t b3 : 1; + uint32_t b4 : 1; + uint32_t b5 : 1; + uint32_t b6 : 1; + uint32_t b7 : 1; + uint32_t b8 : 1; + uint32_t b9 : 1; + uint32_t b10 : 1; + uint32_t b11 : 1; + uint32_t b12 : 1; + uint32_t b13 : 1; + uint32_t b14 : 1; + uint32_t b15 : 1; + uint32_t b16 : 1; + uint32_t b17 : 1; + uint32_t b18 : 1; + uint32_t b19 : 1; + uint32_t b20 : 1; + uint32_t b21 : 1; + uint32_t b22 : 1; + uint32_t b23 : 1; + uint32_t b24 : 1; + uint32_t b25 : 1; + uint32_t b26 : 1; + uint32_t b27 : 1; + uint32_t b28 : 1; + uint32_t b29 : 1; + uint32_t b30 : 1; + uint32_t b31 : 1; +} __attribute__((packed, aligned(4))) gpiohs_bits_t; + +/** + * @brief GPIO bits multi access union + */ +typedef union _gpiohs_u32 +{ + /* 32x1 bit mode */ + uint32_t u32[1]; + /* 16x2 bit mode */ + uint16_t u16[2]; + /* 8x4 bit mode */ + uint8_t u8[4]; + /* 1 bit mode */ + gpiohs_bits_t bits; +} __attribute__((packed, aligned(4))) gpiohs_u32_t; + +/** + * @brief GPIO object + * + * The GPIO controller is a peripheral device mapped in the + * internal memory map, discoverable in the Configuration String. + * It is responsible for low-level configuration of the actual + * GPIO pads on the device (direction, pull up-enable, and drive + * value), as well as selecting between various sources of the + * controls for these signals. The GPIO controller allows seperate + * configuration of each of N GPIO bits. + * + * Once the interrupt is pending, it will remain set until a 1 is + * written to the *_ip register at that bit. + */ + +typedef struct _gpiohs +{ + /* Address offset 0x00, Input Values */ + gpiohs_u32_t input_val; + /* Address offset 0x04, Input enable */ + gpiohs_u32_t input_en; + /* Address offset 0x08, Output enable */ + gpiohs_u32_t output_en; + /* Address offset 0x0c, Onput Values */ + gpiohs_u32_t output_val; + /* Address offset 0x10, Internal Pull-Ups enable */ + gpiohs_u32_t pullup_en; + /* Address offset 0x14, Drive Strength */ + gpiohs_u32_t drive; + /* Address offset 0x18, Rise interrupt enable */ + gpiohs_u32_t rise_ie; + /* Address offset 0x1c, Rise interrupt pending */ + gpiohs_u32_t rise_ip; + /* Address offset 0x20, Fall interrupt enable */ + gpiohs_u32_t fall_ie; + /* Address offset 0x24, Fall interrupt pending */ + gpiohs_u32_t fall_ip; + /* Address offset 0x28, High interrupt enable */ + gpiohs_u32_t high_ie; + /* Address offset 0x2c, High interrupt pending */ + gpiohs_u32_t high_ip; + /* Address offset 0x30, Low interrupt enable */ + gpiohs_u32_t low_ie; + /* Address offset 0x34, Low interrupt pending */ + gpiohs_u32_t low_ip; + /* Address offset 0x38, HW I/O Function enable */ + gpiohs_u32_t iof_en; + /* Address offset 0x3c, HW I/O Function select */ + gpiohs_u32_t iof_sel; + /* Address offset 0x40, Output XOR (invert) */ + gpiohs_u32_t output_xor; +} __attribute__((packed, aligned(4))) gpiohs_t; + +/** + * @brief GPIO High-speed object instanse + */ +extern volatile gpiohs_t *const gpiohs; + +/** + * @brief Set Gpiohs drive mode + * + * @param[in] pin Gpiohs pin + * @param[in] mode Gpiohs pin drive mode + */ +void gpiohs_set_drive_mode(uint8_t pin, gpio_drive_mode_t mode); + +/** + * @brief Get Gpiohs pin value + * + * @param[in] pin Gpiohs pin + * @return Pin value + * + * - GPIO_PV_Low Gpiohs pin low + * - GPIO_PV_High Gpiohs pin high + */ +gpio_pin_value_t gpiohs_get_pin(uint8_t pin); + +/** + * @brief Set Gpiohs pin value + * + * @param[in] pin Gpiohs pin + * @param[in] value Gpiohs pin value + */ +void gpiohs_set_pin(uint8_t pin, gpio_pin_value_t value); + +/** + * @brief Set Gpiohs pin edge for interrupt + * + * @param[in] pin Gpiohs pin + * @param[in] edge Gpiohs pin edge type + */ +void gpiohs_set_pin_edge(uint8_t pin, GpioPinEdgeT edge); + +/** + * @brief Set Gpiohs pin interrupt + * + * @param[in] pin Gpiohs pin + * @param[in] priority Gpiohs pin interrupt priority + * @param[in] func Gpiohs pin interrupt service routine + */ +void gpiohs_set_irq(uint8_t pin, uint32_t priority, void(*func)()); + +/** + * @brief Set Gpiohs pin interrupt + * + * @param[in] pin Gpiohs pin + * @param[in] priority Gpiohs pin interrupt priority + * @param[in] callback Gpiohs pin interrupt service routine + * @param[in] ctx Gpiohs interrupt param + */ +void gpiohs_irq_register(uint8_t pin, uint32_t priority, plic_irq_callback_t callback, void *ctx); + +/** + * @brief Unregister Gpiohs pin interrupt + * + * @param[in] pin Gpiohs pin + */ +void gpiohs_irq_unregister(uint8_t pin); + +#ifdef __cplusplus +} +#endif + +#endif /* __GPIOHS_H__ */ + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/graphic.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/graphic.h new file mode 100644 index 000000000..a57a5eb06 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/graphic.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2006-2018, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + +/** +* @file graphic.h +* @brief define aiit-riscv64-board lcd operation +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +/************************************************* +File name: graphic.h +Description: define aiit-riscv64-board lcd operation +Others: take RT-Thread v4.0.2/include/rtdef.h for references + https://github.com/RT-Thread/rt-thread/tree/v4.0.2 +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: add aiit-riscv64-board lcd configure and operation function +*************************************************/ + +#ifndef GRAPHIC_H +#define GRAPIHC_H + +#include + +#define GRAPHIC_CTRL_RECT_UPDATE 0 +#define GRAPHIC_CTRL_POWERON 1 +#define GRAPHIC_CTRL_POWEROFF 2 +#define GRAPHIC_CTRL_GET_INFO 3 +#define GRAPHIC_CTRL_SET_MODE 4 +#define GRAPHIC_CTRL_GET_EXT 5 + +enum +{ + PIXEL_FORMAT_MONO = 0, + PIXEL_FORMAT_GRAY4, + PIXEL_FORMAT_GRAY16, + PIXEL_FORMAT_RGB332, + PIXEL_FORMAT_RGB444, + PIXEL_FORMAT_RGB565 , + PIXEL_FORMAT_RGB565P, + PIXEL_FORMAT_BGR565 = PIXEL_FORMAT_RGB565P, + PIXEL_FORMAT_RGB666, + PIXEL_FORMAT_RGB888, + PIXEL_FORMAT_ARGB888, + PIXEL_FORMAT_ABGR888, + PIXEL_FORMAT_ARGB565, + PIXEL_FORMAT_ALPHA, + PIXEL_FORMAT_COLOR, +}; + +struct DeviceLcdInfo +{ + uint8 pixel_format; + uint8 bits_per_pixel; + uint16 reserved; + + uint16 width; + uint16 height; + + uint8 *framebuffer; +}; + +struct DeviceRectInfo +{ + uint16 x; + uint16 y; + uint16 width; + uint16 height; +}; + +struct DeviceGraphicDone +{ + void (*set_pixel) (const char *pixel, int x, int y); + void (*get_pixel) (char *pixel, int x, int y); + + void (*draw_hline) (const char *pixel, int x1, int x2, int y); + void (*draw_vline) (const char *pixel, int x, int y1, int y2); + + void (*blit_line) (const char *pixel, int x, int y, x_size_t size); +}; + +#define GraphixDone(device) ((struct DeviceGraphicDone *)(device->UserData)) + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_hwtimer.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_hwtimer.h new file mode 100644 index 000000000..57ac51a3c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_hwtimer.h @@ -0,0 +1,171 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file hardware_hwtimer.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef __HARDWARE_HWTIMER_H__ +#define __HARDWARE_HWTIMER_H__ + +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + +/* clang-format off */ +typedef struct _timer_channel +{ + /* TIMER_N Load Count Register (0x00+(N-1)*0x14) */ + volatile uint32_t load_count; + /* TIMER_N Current Value Register (0x04+(N-1)*0x14) */ + volatile uint32_t current_value; + /* TIMER_N Control Register (0x08+(N-1)*0x14) */ + volatile uint32_t control; + /* TIMER_N Interrupt Clear Register (0x0c+(N-1)*0x14) */ + volatile uint32_t eoi; + /* TIMER_N Interrupt Status Register (0x10+(N-1)*0x14) */ + volatile uint32_t intr_stat; +} __attribute__((packed, aligned(4))) timer_channel_t; + +typedef struct _kendryte_timer +{ + /* TIMER_N Register (0x00-0x4c) */ + volatile timer_channel_t channel[4]; + /* reserverd (0x50-0x9c) */ + volatile uint32_t resv1[20]; + /* TIMER Interrupt Status Register (0xa0) */ + volatile uint32_t intr_stat; + /* TIMER Interrupt Clear Register (0xa4) */ + volatile uint32_t eoi; + /* TIMER Raw Interrupt Status Register (0xa8) */ + volatile uint32_t raw_intr_stat; + /* TIMER Component Version Register (0xac) */ + volatile uint32_t comp_version; + /* TIMER_N Load Count2 Register (0xb0-0xbc) */ + volatile uint32_t load_count2[4]; +} __attribute__((packed, aligned(4))) kendryte_timer_t; + +typedef enum _timer_deivce_number +{ + TIMER_DEVICE_0, + TIMER_DEVICE_1, + TIMER_DEVICE_2, + TIMER_DEVICE_MAX, +} timer_device_number_t; + +typedef enum _timer_channel_number +{ + TIMER_CHANNEL_0, + TIMER_CHANNEL_1, + TIMER_CHANNEL_2, + TIMER_CHANNEL_3, + TIMER_CHANNEL_MAX, +} timer_channel_number_t; + +/* TIMER Control Register */ +#define TIMER_CR_ENABLE 0x00000001 +#define TIMER_CR_MODE_MASK 0x00000002 +#define TIMER_CR_FREE_MODE 0x00000000 +#define TIMER_CR_USER_MODE 0x00000002 +#define TIMER_CR_INTERRUPT_MASK 0x00000004 +#define TIMER_CR_PWM_ENABLE 0x00000008 +/* clang-format on */ + +extern volatile kendryte_timer_t *const timer[3]; + +/** + * @brief Definitions for the timer callbacks + */ +typedef int (*timer_callback_t)(void *ctx); + +/** + * @brief Set timer timeout + * + * @param[in] timer timer + * @param[in] channel channel + * @param[in] nanoseconds timeout + * + * @return the real timeout + */ +size_t timer_set_interval(timer_device_number_t timer_number, timer_channel_number_t channel, size_t nanoseconds); + +/** + * @brief Init timer + * + * @param[in] timer timer + */ +void timer_init(timer_device_number_t timer_number); + +/** + * @brief [DEPRECATED] Set timer timeout function + * + * @param[in] timer timer + * @param[in] channel channel + * @param[in] func timeout function + * @param[in] priority interrupt priority + * + */ +void timer_set_irq(timer_device_number_t timer_number, timer_channel_number_t channel, void(*func)(), uint32_t priority); + +/** + * @brief Register timer interrupt user callback function + * + * @param[in] device The timer device number + * @param[in] channel The channel + * @param[in] is_one_shot Indicates if single shot + * @param[in] priority The priority + * @param[in] callback The callback function + * @param[in] ctx The context + * + * @return result + * - 0 Success + * - Other Fail + */ +int timer_irq_register(timer_device_number_t device, timer_channel_number_t channel, int is_single_shot, uint32_t priority, timer_callback_t callback, void *ctx); + +/** + * @brief Deregister timer interrupt user callback function + * + * @param[in] device The timer device number + * @param[in] channel The channel + * + * @return result + * - 0 Success + * - Other Fail + */ +int timer_irq_unregister(timer_device_number_t device, timer_channel_number_t channel); + +/** + * @brief Enable timer + * + * @param[in] timer timer + * @param[in] channel channel + * @param[in] enable Enable or disable + * + */ +void timer_set_enable(timer_device_number_t timer_number, timer_channel_number_t channel, uint32_t enable); + +#ifdef __cplusplus +} +#endif + +#endif /* __TIMER_H__ */ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_i2c.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_i2c.h new file mode 100644 index 000000000..e59d13a05 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_i2c.h @@ -0,0 +1,482 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file hardware_i2c.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#ifndef __HARDWARE_I2C_H__ +#define __HARDWARE_I2C_H__ + +#include +#include +#include "dmac.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define I2C_MAX_NUM 3 + +/* clang-format off */ +typedef struct _i2c +{ + /* I2C Control Register (0x00) */ + volatile uint32_t con; + /* I2C Target Address Register (0x04) */ + volatile uint32_t tar; + /* I2C Slave Address Register (0x08) */ + volatile uint32_t sar; + /* reserved (0x0c) */ + volatile uint32_t resv1; + /* I2C Data Buffer and Command Register (0x10) */ + volatile uint32_t data_cmd; + /* I2C Standard Speed Clock SCL High Count Register (0x14) */ + volatile uint32_t ss_scl_hcnt; + /* I2C Standard Speed Clock SCL Low Count Register (0x18) */ + volatile uint32_t ss_scl_lcnt; + /* reserverd (0x1c-0x28) */ + volatile uint32_t resv2[4]; + /* I2C Interrupt Status Register (0x2c) */ + volatile uint32_t intr_stat; + /* I2C Interrupt Mask Register (0x30) */ + volatile uint32_t intr_mask; + /* I2C Raw Interrupt Status Register (0x34) */ + volatile uint32_t raw_intr_stat; + /* I2C Receive FIFO Threshold Register (0x38) */ + volatile uint32_t rx_tl; + /* I2C Transmit FIFO Threshold Register (0x3c) */ + volatile uint32_t tx_tl; + /* I2C Clear Combined and Individual Interrupt Register (0x40) */ + volatile uint32_t clr_intr; + /* I2C Clear RX_UNDER Interrupt Register (0x44) */ + volatile uint32_t clr_rx_under; + /* I2C Clear RX_OVER Interrupt Register (0x48) */ + volatile uint32_t clr_rx_over; + /* I2C Clear TX_OVER Interrupt Register (0x4c) */ + volatile uint32_t clr_tx_over; + /* I2C Clear RD_REQ Interrupt Register (0x50) */ + volatile uint32_t clr_rd_req; + /* I2C Clear TX_ABRT Interrupt Register (0x54) */ + volatile uint32_t clr_tx_abrt; + /* I2C Clear RX_DONE Interrupt Register (0x58) */ + volatile uint32_t clr_rx_done; + /* I2C Clear ACTIVITY Interrupt Register (0x5c) */ + volatile uint32_t clr_activity; + /* I2C Clear STOP_DET Interrupt Register (0x60) */ + volatile uint32_t clr_stop_det; + /* I2C Clear START_DET Interrupt Register (0x64) */ + volatile uint32_t clr_start_det; + /* I2C Clear GEN_CALL Interrupt Register (0x68) */ + volatile uint32_t clr_gen_call; + /* I2C Enable Register (0x6c) */ + volatile uint32_t enable; + /* I2C Status Register (0x70) */ + volatile uint32_t status; + /* I2C Transmit FIFO Level Register (0x74) */ + volatile uint32_t txflr; + /* I2C Receive FIFO Level Register (0x78) */ + volatile uint32_t rxflr; + /* I2C SDA Hold Time Length Register (0x7c) */ + volatile uint32_t sda_hold; + /* I2C Transmit Abort Source Register (0x80) */ + volatile uint32_t tx_abrt_source; + /* reserved (0x84) */ + volatile uint32_t resv3; + /* I2C DMA Control Register (0x88) */ + volatile uint32_t dma_cr; + /* I2C DMA Transmit Data Level Register (0x8c) */ + volatile uint32_t dma_tdlr; + /* I2C DMA Receive Data Level Register (0x90) */ + volatile uint32_t dma_rdlr; + /* I2C SDA Setup Register (0x94) */ + volatile uint32_t sda_setup; + /* I2C ACK General Call Register (0x98) */ + volatile uint32_t general_call; + /* I2C Enable Status Register (0x9c) */ + volatile uint32_t enable_status; + /* I2C SS, FS or FM+ spike suppression limit (0xa0) */ + volatile uint32_t fs_spklen; + /* reserved (0xa4-0xf0) */ + volatile uint32_t resv4[20]; + /* I2C Component Parameter Register 1 (0xf4) */ + volatile uint32_t comp_param_1; + /* I2C Component Version Register (0xf8) */ + volatile uint32_t comp_version; + /* I2C Component Type Register (0xfc) */ + volatile uint32_t comp_type; +} __attribute__((packed, aligned(4))) i2c_t; + +/* I2C Control Register*/ +#define I2C_CON_MASTER_MODE 0x00000001U +#define I2C_CON_SPEED_MASK 0x00000006U +#define I2C_CON_SPEED(x) ((x) << 1) +#define I2C_CON_10BITADDR_SLAVE 0x00000008U +#define I2C_CON_RESTART_EN 0x00000020U +#define I2C_CON_SLAVE_DISABLE 0x00000040U +#define I2C_CON_STOP_DET_IFADDRESSED 0x00000080U +#define I2C_CON_TX_EMPTY_CTRL 0x00000100U + +/* I2C Target Address Register*/ +#define I2C_TAR_ADDRESS_MASK 0x000003FFU +#define I2C_TAR_ADDRESS(x) ((x) << 0) +#define I2C_TAR_GC_OR_START 0x00000400U +#define I2C_TAR_SPECIAL 0x00000800U +#define I2C_TAR_10BITADDR_MASTER 0x00001000U + +/* I2C Slave Address Register*/ +#define I2C_SAR_ADDRESS_MASK 0x000003FFU +#define I2C_SAR_ADDRESS(x) ((x) << 0) + +/* I2C Rx/Tx Data Buffer and Command Register*/ +#define I2C_DATA_CMD_CMD 0x00000100U +#define I2C_DATA_CMD_DATA_MASK 0x000000FFU +#define I2C_DATA_CMD_DATA(x) ((x) << 0) + +/* Standard Speed I2C Clock SCL High Count Register*/ +#define I2C_SS_SCL_HCNT_COUNT_MASK 0x0000FFFFU +#define I2C_SS_SCL_HCNT_COUNT(x) ((x) << 0) + +/* Standard Speed I2C Clock SCL Low Count Register*/ +#define I2C_SS_SCL_LCNT_COUNT_MASK 0x0000FFFFU +#define I2C_SS_SCL_LCNT_COUNT(x) ((x) << 0) + +/* I2C Interrupt Status Register*/ +#define I2C_INTR_STAT_RX_UNDER 0x00000001U +#define I2C_INTR_STAT_RX_OVER 0x00000002U +#define I2C_INTR_STAT_RX_FULL 0x00000004U +#define I2C_INTR_STAT_TX_OVER 0x00000008U +#define I2C_INTR_STAT_TX_EMPTY 0x00000010U +#define I2C_INTR_STAT_RD_REQ 0x00000020U +#define I2C_INTR_STAT_TX_ABRT 0x00000040U +#define I2C_INTR_STAT_RX_DONE 0x00000080U +#define I2C_INTR_STAT_ACTIVITY 0x00000100U +#define I2C_INTR_STAT_STOP_DET 0x00000200U +#define I2C_INTR_STAT_START_DET 0x00000400U +#define I2C_INTR_STAT_GEN_CALL 0x00000800U + +/* I2C Interrupt Mask Register*/ +#define I2C_INTR_MASK_RX_UNDER 0x00000001U +#define I2C_INTR_MASK_RX_OVER 0x00000002U +#define I2C_INTR_MASK_RX_FULL 0x00000004U +#define I2C_INTR_MASK_TX_OVER 0x00000008U +#define I2C_INTR_MASK_TX_EMPTY 0x00000010U +#define I2C_INTR_MASK_RD_REQ 0x00000020U +#define I2C_INTR_MASK_TX_ABRT 0x00000040U +#define I2C_INTR_MASK_RX_DONE 0x00000080U +#define I2C_INTR_MASK_ACTIVITY 0x00000100U +#define I2C_INTR_MASK_STOP_DET 0x00000200U +#define I2C_INTR_MASK_START_DET 0x00000400U +#define I2C_INTR_MASK_GEN_CALL 0x00000800U + +/* I2C Raw Interrupt Status Register*/ +#define I2C_RAW_INTR_MASK_RX_UNDER 0x00000001U +#define I2C_RAW_INTR_MASK_RX_OVER 0x00000002U +#define I2C_RAW_INTR_MASK_RX_FULL 0x00000004U +#define I2C_RAW_INTR_MASK_TX_OVER 0x00000008U +#define I2C_RAW_INTR_MASK_TX_EMPTY 0x00000010U +#define I2C_RAW_INTR_MASK_RD_REQ 0x00000020U +#define I2C_RAW_INTR_MASK_TX_ABRT 0x00000040U +#define I2C_RAW_INTR_MASK_RX_DONE 0x00000080U +#define I2C_RAW_INTR_MASK_ACTIVITY 0x00000100U +#define I2C_RAW_INTR_MASK_STOP_DET 0x00000200U +#define I2C_RAW_INTR_MASK_START_DET 0x00000400U +#define I2C_RAW_INTR_MASK_GEN_CALL 0x00000800U + +/* I2C Receive FIFO Threshold Register*/ +#define I2C_RX_TL_VALUE_MASK 0x00000007U +#define I2C_RX_TL_VALUE(x) ((x) << 0) + +/* I2C Transmit FIFO Threshold Register*/ +#define I2C_TX_TL_VALUE_MASK 0x00000007U +#define I2C_TX_TL_VALUE(x) ((x) << 0) + +/* Clear Combined and Individual Interrupt Register*/ +#define I2C_CLR_INTR_CLR 0x00000001U + +/* Clear RX_UNDER Interrupt Register*/ +#define I2C_CLR_RX_UNDER_CLR 0x00000001U + +/* Clear RX_OVER Interrupt Register*/ +#define I2C_CLR_RX_OVER_CLR 0x00000001U + +/* Clear TX_OVER Interrupt Register*/ +#define I2C_CLR_TX_OVER_CLR 0x00000001U + +/* Clear RD_REQ Interrupt Register*/ +#define I2C_CLR_RD_REQ_CLR 0x00000001U + +/* Clear TX_ABRT Interrupt Register*/ +#define I2C_CLR_TX_ABRT_CLR 0x00000001U + +/* Clear RX_DONE Interrupt Register*/ +#define I2C_CLR_RX_DONE_CLR 0x00000001U + +/* Clear ACTIVITY Interrupt Register*/ +#define I2C_CLR_ACTIVITY_CLR 0x00000001U + +/* Clear STOP_DET Interrupt Register*/ +#define I2C_CLR_STOP_DET_CLR 0x00000001U + +/* Clear START_DET Interrupt Register*/ +#define I2C_CLR_START_DET_CLR 0x00000001U + +/* Clear GEN_CALL Interrupt Register*/ +#define I2C_CLR_GEN_CALL_CLR 0x00000001U + +/* I2C Enable Register*/ +#define I2C_ENABLE_ENABLE 0x00000001U +#define I2C_ENABLE_ABORT 0x00000002U +#define I2C_ENABLE_TX_CMD_BLOCK 0x00000004U + +/* I2C Status Register*/ +#define I2C_STATUS_ACTIVITY 0x00000001U +#define I2C_STATUS_TFNF 0x00000002U +#define I2C_STATUS_TFE 0x00000004U +#define I2C_STATUS_RFNE 0x00000008U +#define I2C_STATUS_RFF 0x00000010U +#define I2C_STATUS_MST_ACTIVITY 0x00000020U +#define I2C_STATUS_SLV_ACTIVITY 0x00000040U + +/* I2C Transmit FIFO Level Register*/ +#define I2C_TXFLR_VALUE_MASK 0x00000007U +#define I2C_TXFLR_VALUE(x) ((x) << 0) + +/* I2C Receive FIFO Level Register*/ +#define I2C_RXFLR_VALUE_MASK 0x00000007U +#define I2C_RXFLR_VALUE(x) ((x) << 0) + +/* I2C SDA Hold Time Length Register*/ +#define I2C_SDA_HOLD_TX_MASK 0x0000FFFFU +#define I2C_SDA_HOLD_TX(x) ((x) << 0) +#define I2C_SDA_HOLD_RX_MASK 0x00FF0000U +#define I2C_SDA_HOLD_RX(x) ((x) << 16) + +/* I2C Transmit Abort Source Register*/ +#define I2C_TX_ABRT_SOURCE_7B_ADDR_NOACK 0x00000001U +#define I2C_TX_ABRT_SOURCE_10B_ADDR1_NOACK 0x00000002U +#define I2C_TX_ABRT_SOURCE_10B_ADDR2_NOACK 0x00000004U +#define I2C_TX_ABRT_SOURCE_TXDATA_NOACK 0x00000008U +#define I2C_TX_ABRT_SOURCE_GCALL_NOACK 0x00000010U +#define I2C_TX_ABRT_SOURCE_GCALL_READ 0x00000020U +#define I2C_TX_ABRT_SOURCE_HS_ACKDET 0x00000040U +#define I2C_TX_ABRT_SOURCE_SBYTE_ACKDET 0x00000080U +#define I2C_TX_ABRT_SOURCE_HS_NORSTRT 0x00000100U +#define I2C_TX_ABRT_SOURCE_SBYTE_NORSTRT 0x00000200U +#define I2C_TX_ABRT_SOURCE_10B_RD_NORSTRT 0x00000400U +#define I2C_TX_ABRT_SOURCE_MASTER_DIS 0x00000800U +#define I2C_TX_ABRT_SOURCE_MST_ARBLOST 0x00001000U +#define I2C_TX_ABRT_SOURCE_SLVFLUSH_TXFIFO 0x00002000U +#define I2C_TX_ABRT_SOURCE_SLV_ARBLOST 0x00004000U +#define I2C_TX_ABRT_SOURCE_SLVRD_INTX 0x00008000U +#define I2C_TX_ABRT_SOURCE_USER_ABRT 0x00010000U + +/* DMA Control Register*/ +#define I2C_DMA_CR_RDMAE 0x00000001U +#define I2C_DMA_CR_TDMAE 0x00000002U + +/* DMA Transmit Data Level Register*/ +#define I2C_DMA_TDLR_VALUE_MASK 0x00000007U +#define I2C_DMA_TDLR_VALUE(x) ((x) << 0) + +/* DMA Receive Data Level Register*/ +#define I2C_DMA_RDLR_VALUE_MASK 0x00000007U +#define I2C_DMA_RDLR_VALUE(x) ((x) << 0) + +/* I2C SDA Setup Register*/ +#define I2C_SDA_SETUP_VALUE_MASK 0x000000FFU +#define I2C_SDA_SETUP_VALUE(x) ((x) << 0) + +/* I2C ACK General Call Register*/ +#define I2C_ACK_GENERAL_CALL_ENABLE 0x00000001U + +/* I2C Enable Status Register*/ +#define I2C_ENABLE_STATUS_IC_ENABLE 0x00000001U +#define I2C_ENABLE_STATUS_SLV_DIS_BUSY 0x00000002U +#define I2C_ENABLE_STATUS_SLV_RX_DATA_LOST 0x00000004U + +/* I2C SS, FS or FM+ spike suppression limit*/ +#define I2C_FS_SPKLEN_VALUE_MASK 0x000000FFU +#define I2C_FS_SPKLEN_VALUE(x) ((x) << 0) + +/* Component Parameter Register 1*/ +#define I2C_COMP_PARAM1_APB_DATA_WIDTH 0x00000003U +#define I2C_COMP_PARAM1_MAX_SPEED_MODE 0x0000000CU +#define I2C_COMP_PARAM1_HC_COUNT_VALUES 0x00000010U +#define I2C_COMP_PARAM1_INTR_IO 0x00000020U +#define I2C_COMP_PARAM1_HAS_DMA 0x00000040U +#define I2C_COMP_PARAM1_ENCODED_PARAMS 0x00000080U +#define I2C_COMP_PARAM1_RX_BUFFER_DEPTH 0x0000FF00U +#define I2C_COMP_PARAM1_TX_BUFFER_DEPTH 0x00FF0000U + +/* I2C Component Version Register*/ +#define I2C_COMP_VERSION_VALUE 0xFFFFFFFFU + +/* I2C Component Type Register*/ +#define I2C_COMP_TYPE_VALUE 0xFFFFFFFFU +/* clang-format on */ + +extern volatile i2c_t *const i2c[3]; + +typedef enum _i2c_device_number +{ + I2C_DEVICE_0, + I2C_DEVICE_1, + I2C_DEVICE_2, + I2C_DEVICE_MAX, +} i2c_device_number_t; + +typedef enum _i2c_bus_speed_mode +{ + I2C_BS_STANDARD, + I2C_BS_FAST, + I2C_BS_HIGHSPEED +} i2c_bus_speed_mode_t; + +typedef enum _i2c_event +{ + I2C_EV_START, + I2C_EV_RESTART, + I2C_EV_STOP +} i2c_event_id_t; + +typedef struct _i2c_slave_handler +{ + void(*on_receive)(uint32_t data); + uint32_t(*on_transmit)(); + void(*on_event)(i2c_event_id_t event); +} i2c_slave_handler_t; + +typedef enum _i2c_transfer_mode +{ + I2C_SEND, + I2C_RECEIVE, +} i2c_transfer_mode_t; + +typedef struct _i2c_data_t +{ + dmac_channel_number_t tx_channel; + dmac_channel_number_t rx_channel; + uint32_t *tx_buf; + size_t tx_len; + uint32_t *rx_buf; + size_t rx_len; + i2c_transfer_mode_t TransferMode; +} i2c_data_t; + +/** + * @brief Set i2c params + * + * @param[in] i2c_num i2c number + * @param[in] slave_address i2c slave device address + * @param[in] address_width address width 7bit or 10bit + * @param[in] i2c_clk i2c clk rate + */ +void i2c_init(i2c_device_number_t i2c_num, uint32_t slave_address, uint32_t address_width, + uint32_t i2c_clk); + +/** + * @brief I2c send data + * + * @param[in] i2c_num i2c number + * @param[in] SendBuf send data + * @param[in] send_buf_len send data length + * + * @return result + * - 0 Success + * - Other Fail + */ +int i2c_send_data(i2c_device_number_t i2c_num, const uint8_t *SendBuf, size_t send_buf_len); + +/** + * @brief Init i2c as slave mode. + * + * @param[in] i2c_num i2c number + * @param[in] slave_address i2c slave device address + * @param[in] address_width address width 7bit or 10bit + * @param[in] handler Handle of i2c slave interrupt function. + */ +void i2c_init_as_slave(i2c_device_number_t i2c_num, uint32_t slave_address, uint32_t address_width, + const i2c_slave_handler_t *handler); + +/** + * @brief I2c send data by dma + * + * @param[in] dma_channel_num dma channel + * @param[in] i2c_num i2c number + * @param[in] SendBuf send data + * @param[in] send_buf_len send data length + * + * @return result + * - 0 Success + * - Other Fail + */ +void i2c_send_data_dma(dmac_channel_number_t dma_channel_num, i2c_device_number_t i2c_num, const uint8_t *SendBuf, + size_t send_buf_len); + +/** + * @brief I2c receive data + * + * @param[in] i2c_num i2c number + * @param[in] SendBuf send data address + * @param[in] send_buf_len length of send buf + * @param[in] receive_buf receive buf address + * @param[in] receive_buf_len length of receive buf + * + * @return result + * - 0 Success + * - Other Fail +*/ +int i2c_recv_data(i2c_device_number_t i2c_num, const uint8_t *SendBuf, size_t send_buf_len, uint8_t *receive_buf, + size_t receive_buf_len); + +/** + * @brief I2c receive data by dma + * + * @param[in] dma_send_channel_num send dma channel + * @param[in] dma_receive_channel_num receive dma channel + * @param[in] i2c_num i2c number + * @param[in] SendBuf send data address + * @param[in] send_buf_len length of send buf + * @param[in] receive_buf receive buf address + * @param[in] receive_buf_len length of receive buf + * + * @return result + * - 0 Success + * - Other Fail +*/ +void i2c_recv_data_dma(dmac_channel_number_t dma_send_channel_num, dmac_channel_number_t dma_receive_channel_num, + i2c_device_number_t i2c_num, const uint8_t *SendBuf, size_t send_buf_len, + uint8_t *receive_buf, size_t receive_buf_len); +/** + * @brief I2c handle transfer data operations + * + * @param[in] i2c_num i2c number + * @param[in] data i2c data information + * @param[in] cb i2c dma callback + * +*/ +void i2c_handle_data_dma(i2c_device_number_t i2c_num, i2c_data_t data, plic_interrupt_t *cb); + +#ifdef __cplusplus +} +#endif + +#endif /* __HARDWARE_I2C_H__ */ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_rtc.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_rtc.h new file mode 100644 index 000000000..b9c416dbb --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_rtc.h @@ -0,0 +1,448 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file + * @brief A real-time clock (RTC) is a computer clock that keeps track of + * the current time. + */ + +/** +* @file hardware_rtc.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef __HARDWARE_RTC_H__ +#define __HARDWARE_RTC_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief RTC timer mode + * + * Timer mode selector + * | Mode | Description | + * |------|------------------------| + * | 0 | Timer pause | + * | 1 | Timer time running | + * | 2 | Timer time setting | + */ +typedef enum _rtc_timer_mode_e +{ + /* 0: Timer pause */ + RTC_TIMER_PAUSE, + /* 1: Timer time running */ + RTC_TIMER_RUNNING, + /* 2: Timer time setting */ + RTC_TIMER_SETTING, + /* Max count of this enum*/ + RTC_TIMER_MAX +} rtc_timer_mode_t; + +/* + * @brief RTC tick interrupt mode + * + * Tick interrupt mode selector + * | Mode | Description | + * |------|------------------------| + * | 0 | Interrupt every second | + * | 1 | Interrupt every minute | + * | 2 | Interrupt every hour | + * | 3 | Interrupt every day | + */ +typedef enum _rtc_tick_interrupt_mode_e +{ + /* 0: Interrupt every second */ + RTC_INT_SECOND, + /* 1: Interrupt every minute */ + RTC_INT_MINUTE, + /* 2: Interrupt every hour */ + RTC_INT_HOUR, + /* 3: Interrupt every day */ + RTC_INT_DAY, + /* Max count of this enum*/ + RTC_INT_MAX +} rtc_tick_interrupt_mode_t; + +/** + * @brief RTC mask structure + * + * RTC mask structure for common use + */ +typedef struct _rtc_mask +{ + /* Reserved */ + uint32_t resv : 1; + /* Second mask */ + uint32_t second : 1; + /* Minute mask */ + uint32_t minute : 1; + /* Hour mask */ + uint32_t hour : 1; + /* Week mask */ + uint32_t week : 1; + /* Day mask */ + uint32_t day : 1; + /* Month mask */ + uint32_t month : 1; + /* Year mask */ + uint32_t year : 1; +} __attribute__((packed, aligned(1))) rtc_mask_t; + +/** + * @brief RTC register + * + * @note RTC register table + * + * | Offset | Name | Description | + * |-----------|----------------|-------------------------------------| + * | 0x00 | date | Timer date information | + * | 0x04 | time | Timer time information | + * | 0x08 | alarm_date | Alarm date information | + * | 0x0c | alarm_time | Alarm time information | + * | 0x10 | initial_count | Timer counter initial value | + * | 0x14 | current_count | Timer counter current value | + * | 0x18 | interrupt_ctrl | RTC interrupt settings | + * | 0x1c | register_ctrl | RTC register settings | + * | 0x20 | reserved0 | Reserved | + * | 0x24 | reserved1 | Reserved | + * | 0x28 | extended | Timer extended information | + * + */ + + +/** + * @brief Timer date information + * + * No. 0 Register (0x00) + */ +typedef struct _rtc_date +{ + /* Week. Range [0,6]. 0 is Sunday. */ + uint32_t week : 3; + /* Reserved */ + uint32_t resv0 : 5; + /* Day. Range [1,31] or [1,30] or [1,29] or [1,28] */ + uint32_t day : 5; + /* Reserved */ + uint32_t resv1 : 3; + /* Month. Range [1,12] */ + uint32_t month : 4; + /* Year. Range [0,99] */ + uint32_t year : 12; +} __attribute__((packed, aligned(4))) rtc_date_t; + +/** + * @brief Timer time information + * + * No. 1 Register (0x04) + */ +typedef struct _rtc_time +{ + /* Reserved */ + uint32_t resv0 : 10; + /* Second. Range [0,59] */ + uint32_t second : 6; + /* Minute. Range [0,59] */ + uint32_t minute : 6; + /* Reserved */ + uint32_t resv1 : 2; + /* Hour. Range [0,23] */ + uint32_t hour : 5; + /* Reserved */ + uint32_t resv2 : 3; +} __attribute__((packed, aligned(4))) rtc_time_t; + +/** + * @brief Alarm date information + * + * No. 2 Register (0x08) + */ +typedef struct _rtc_alarm_date +{ + /* Alarm Week. Range [0,6]. 0 is Sunday. */ + uint32_t week : 3; + /* Reserved */ + uint32_t resv0 : 5; + /* Alarm Day. Range [1,31] or [1,30] or [1,29] or [1,28] */ + uint32_t day : 5; + /* Reserved */ + uint32_t resv1 : 3; + /* Alarm Month. Range [1,12] */ + uint32_t month : 4; + /* Alarm Year. Range [0,99] */ + uint32_t year : 12; +} __attribute__((packed, aligned(4))) rtc_alarm_date_t; + +/** + * @brief Alarm time information + * + * No. 3 Register (0x0c) + */ +typedef struct _rtc_alarm_time +{ + /* Reserved */ + uint32_t resv0 : 10; + /* Alarm Second. Range [0,59] */ + uint32_t second : 6; + /* Alarm Minute. Range [0,59] */ + uint32_t minute : 6; + /* Reserved */ + uint32_t resv1 : 2; + /* Alarm Hour. Range [0,23] */ + uint32_t hour : 5; + /* Reserved */ + uint32_t resv2 : 3; +} __attribute__((packed, aligned(4))) rtc_alarm_time_t; + +/** + * @brief Timer counter initial value + * + * No. 4 Register (0x10) + */ +typedef struct _rtc_initial_count +{ + /* RTC counter initial value */ + uint32_t count : 32; +} __attribute__((packed, aligned(4))) rtc_initial_count_t; + +/** + * @brief Timer counter current value + * + * No. 5 Register (0x14) + */ +typedef struct _rtc_current_count +{ + /* RTC counter current value */ + uint32_t count : 32; +} __attribute__((packed, aligned(4))) rtc_current_count_t; + +/** + * @brief RTC interrupt settings + * + * No. 6 Register (0x18) + */ +typedef struct _rtc_interrupt_ctrl +{ + /* Reserved */ + uint32_t tick_enable : 1; + /* Alarm interrupt enable */ + uint32_t alarm_enable : 1; + /* Tick interrupt enable */ + uint32_t tick_int_mode : 2; + /* Reserved */ + uint32_t resv : 20; + /* Alarm compare mask for interrupt */ + uint32_t alarm_compare_mask : 8; +} __attribute__((packed, aligned(4))) rtc_interrupt_ctrl_t; + +/** + * @brief RTC register settings + * + * No. 7 Register (0x1c) + */ +typedef struct _rtc_register_ctrl +{ + /* RTC timer read enable */ + uint32_t read_enable : 1; + /* RTC timer write enable */ + uint32_t write_enable : 1; + /* Reserved */ + uint32_t resv0 : 11; + /* RTC timer mask */ + uint32_t TimerMask : 8; + /* RTC alarm mask */ + uint32_t alarm_mask : 8; + /* RTC counter initial count value mask */ + uint32_t initial_count_mask : 1; + /* RTC interrupt register mask */ + uint32_t interrupt_register_mask : 1; + /* Reserved */ + uint32_t resv1 : 1; +} __attribute__((packed, aligned(4))) rtc_register_ctrl_t; + +/** + * @brief Reserved + * + * No. 8 Register (0x20) + */ +typedef struct _rtc_reserved0 +{ + /* Reserved */ + uint32_t resv : 32; +} __attribute__((packed, aligned(4))) rtc_reserved0_t; + +/** + * @brief Reserved + * + * No. 9 Register (0x24) + */ +typedef struct _rtc_reserved1 +{ + /* Reserved */ + uint32_t resv : 32; +} __attribute__((packed, aligned(4))) rtc_reserved1_t; + +/** + * @brief Timer extended information + * + * No. 10 Register (0x28) + */ +typedef struct _rtc_extended +{ + /* Century. Range [0,31] */ + uint32_t century : 5; + /* Is leap year. 1 is leap year, 0 is not leap year */ + uint32_t leap_year : 1; + /* Reserved */ + uint32_t resv : 26; +} __attribute__((packed, aligned(4))) rtc_extended_t; + + +/** + * @brief Real-time clock struct + * + * A real-time clock (RTC) is a computer clock that keeps track of + * the current time. + */ +typedef struct _rtc +{ + /* No. 0 (0x00): Timer date information */ + rtc_date_t date; + /* No. 1 (0x04): Timer time information */ + rtc_time_t time; + /* No. 2 (0x08): Alarm date information */ + rtc_alarm_date_t alarm_date; + /* No. 3 (0x0c): Alarm time information */ + rtc_alarm_time_t alarm_time; + /* No. 4 (0x10): Timer counter initial value */ + rtc_initial_count_t initial_count; + /* No. 5 (0x14): Timer counter current value */ + rtc_current_count_t current_count; + /* No. 6 (0x18): RTC interrupt settings */ + rtc_interrupt_ctrl_t interrupt_ctrl; + /* No. 7 (0x1c): RTC register settings */ + rtc_register_ctrl_t register_ctrl; + /* No. 8 (0x20): Reserved */ + rtc_reserved0_t reserved0; + /* No. 9 (0x24): Reserved */ + rtc_reserved1_t reserved1; + /* No. 10 (0x28): Timer extended information */ + rtc_extended_t extended; +} __attribute__((packed, aligned(4))) rtc_t; + + +/** + * @brief Real-time clock object + */ +extern volatile rtc_t *const rtc; +extern volatile uint32_t *const rtc_base; + +/** + * @brief Set date time to RTC + * + * @param[in] year The year + * @param[in] month The month + * @param[in] day The day + * @param[in] hour The hour + * @param[in] minute The minute + * @param[in] second The second + * + * @return result + * - 0 Success + * - Other Fail + */ +int rtc_timer_set(int year, int month, int day, int hour, int minute, int second); + +/** + * @brief Get date time from RTC + * + * @param year The year + * @param month The month + * @param day The day + * @param hour The hour + * @param minute The minute + * @param second The second + * + * @return result + * - 0 Success + * - Other Fail + */ +int rtc_timer_get(int *year, int *month, int *day, int *hour, int *minute, int *second); + +/** + * @brief Initialize RTC + * + * @return Result + * - 0 Success + * - Other Fail + */ +int rtc_init(void); + +/** + * @brief Set RTC in protect mode or not + * + * @param enable Enable flag + * + * @return result + * - 0 Success + * - Other Fail + */ +int rtc_protect_set(int enable); + +/** + * @brief Set RTC timer mode + * + * @param timer_mode Timer mode + * + */ +void rtc_timer_set_mode(rtc_timer_mode_t timer_mode); + +/** + * @brief Set RTC timer clock frequency + * + * @param frequency Frequency + * + * @return result + * - 0 Success + * - Other Fail + */ +int rtc_timer_set_clock_frequency(unsigned int frequency); + +/** + * @brief Set RTC timer clock count value + * + * @param count Count + * + * @return result + * - 0 Success + * - Other Fail + */ +int rtc_timer_set_clock_count_value(unsigned int count); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRIVER_RTC_H */ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_spi.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_spi.h new file mode 100644 index 000000000..4d3fd3599 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_spi.h @@ -0,0 +1,494 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file hardware_spi.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef __HARDWARE_SPI_H__ +#define __HARDWARE_SPI_H__ + +#include "dmac.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* clang-format off */ +typedef struct _spi +{ + /* SPI Control Register 0 (0x00)*/ + volatile uint32_t ctrlr0; + /* SPI Control Register 1 (0x04)*/ + volatile uint32_t ctrlr1; + /* SPI Enable Register (0x08)*/ + volatile uint32_t ssienr; + /* SPI Microwire Control Register (0x0c)*/ + volatile uint32_t mwcr; + /* SPI Slave Enable Register (0x10)*/ + volatile uint32_t ser; + /* SPI Baud Rate Select (0x14)*/ + volatile uint32_t baudr; + /* SPI Transmit FIFO Threshold Level (0x18)*/ + volatile uint32_t txftlr; + /* SPI Receive FIFO Threshold Level (0x1c)*/ + volatile uint32_t rxftlr; + /* SPI Transmit FIFO Level Register (0x20)*/ + volatile uint32_t txflr; + /* SPI Receive FIFO Level Register (0x24)*/ + volatile uint32_t rxflr; + /* SPI Status Register (0x28)*/ + volatile uint32_t sr; + /* SPI Interrupt Mask Register (0x2c)*/ + volatile uint32_t imr; + /* SPI Interrupt Status Register (0x30)*/ + volatile uint32_t isr; + /* SPI Raw Interrupt Status Register (0x34)*/ + volatile uint32_t risr; + /* SPI Transmit FIFO Overflow Interrupt Clear Register (0x38)*/ + volatile uint32_t txoicr; + /* SPI Receive FIFO Overflow Interrupt Clear Register (0x3c)*/ + volatile uint32_t rxoicr; + /* SPI Receive FIFO Underflow Interrupt Clear Register (0x40)*/ + volatile uint32_t rxuicr; + /* SPI Multi-Master Interrupt Clear Register (0x44)*/ + volatile uint32_t msticr; + /* SPI Interrupt Clear Register (0x48)*/ + volatile uint32_t icr; + /* SPI DMA Control Register (0x4c)*/ + volatile uint32_t dmacr; + /* SPI DMA Transmit Data Level (0x50)*/ + volatile uint32_t dmatdlr; + /* SPI DMA Receive Data Level (0x54)*/ + volatile uint32_t dmardlr; + /* SPI Identification Register (0x58)*/ + volatile uint32_t idr; + /* SPI DWC_ssi component version (0x5c)*/ + volatile uint32_t ssic_version_id; + /* SPI Data Register 0-36 (0x60 -- 0xec)*/ + volatile uint32_t dr[36]; + /* SPI RX Sample Delay Register (0xf0)*/ + volatile uint32_t rx_sample_delay; + /* SPI SPI Control Register (0xf4)*/ + volatile uint32_t spi_ctrlr0; + /* reserved (0xf8)*/ + volatile uint32_t resv; + /* SPI XIP Mode bits (0xfc)*/ + volatile uint32_t xip_mode_bits; + /* SPI XIP INCR transfer opcode (0x100)*/ + volatile uint32_t xip_incr_inst; + /* SPI XIP WRAP transfer opcode (0x104)*/ + volatile uint32_t xip_wrap_inst; + /* SPI XIP Control Register (0x108)*/ + volatile uint32_t xip_ctrl; + /* SPI XIP Slave Enable Register (0x10c)*/ + volatile uint32_t xip_ser; + /* SPI XIP Receive FIFO Overflow Interrupt Clear Register (0x110)*/ + volatile uint32_t xrxoicr; + /* SPI XIP time out register for continuous transfers (0x114)*/ + volatile uint32_t xip_cnt_time_out; + volatile uint32_t endian; +} __attribute__((packed, aligned(4))) spi_t; +/* clang-format on */ + +typedef enum _spi_device_num +{ + SPI_DEVICE_0, + SPI_DEVICE_1, + SPI_DEVICE_2, + SPI_DEVICE_3, + SPI_DEVICE_MAX, +} spi_device_num_t; + +typedef enum _spi_work_mode +{ + SPI_WORK_MODE_0, + SPI_WORK_MODE_1, + SPI_WORK_MODE_2, + SPI_WORK_MODE_3, +} spi_work_mode_t; + +typedef enum _spi_frame_format +{ + SPI_FF_STANDARD, + SPI_FF_DUAL, + SPI_FF_QUAD, + SPI_FF_OCTAL +} spi_frame_format_t; + +typedef enum _spi_instruction_address_trans_mode +{ + SPI_AITM_STANDARD, + SPI_AITM_ADDR_STANDARD, + SPI_AITM_AS_FRAME_FORMAT +} spi_instruction_address_trans_mode_t; + +typedef enum _spi_transfer_mode +{ + SPI_TMOD_TRANS_RECV, + SPI_TMOD_TRANS, + SPI_TMOD_RECV, + SPI_TMOD_EEROM +} spi_transfer_mode_t; + + +typedef enum _spi_transfer_width +{ + SPI_TRANS_CHAR = 0x1, + SPI_TRANS_SHORT = 0x2, + SPI_TRANS_INT = 0x4, +} spi_transfer_width_t; + +typedef enum _spi_chip_select +{ + SPI_CHIP_SELECT_0, + SPI_CHIP_SELECT_1, + SPI_CHIP_SELECT_2, + SPI_CHIP_SELECT_3, + SPI_CHIP_SELECT_MAX, +} spi_chip_select_t; + +typedef enum +{ + WRITE_CONFIG, + READ_CONFIG, + WRITE_DATA_BYTE, + READ_DATA_BYTE, + WRITE_DATA_BLOCK, + READ_DATA_BLOCK, +} spi_slave_command_e; + +typedef struct +{ + uint8_t cmd; + uint8_t err; + uint32_t addr; + uint32_t len; +} spi_slave_command_t; + +typedef enum +{ + IDLE, + COMMAND, + TRANSFER, +} spi_slave_status_e; + +typedef int (*spi_slave_receive_callback_t)(void *ctx); + +typedef struct _spi_slave_instance +{ + uint8_t int_pin; + uint8_t ready_pin; + dmac_channel_number_t dmac_channel; + uint8_t dfs; + uint8_t slv_oe; + uint8_t work_mode; + size_t data_bit_length; + volatile spi_slave_status_e status; + volatile spi_slave_command_t command; + volatile uint8_t *config_ptr; + uint32_t config_len; + spi_slave_receive_callback_t callback; +} spi_slave_instance_t; + +typedef struct _spi_data_t +{ + dmac_channel_number_t tx_channel; + dmac_channel_number_t rx_channel; + uint32_t *tx_buf; + size_t tx_len; + uint32_t *rx_buf; + size_t rx_len; + spi_transfer_mode_t TransferMode; + bool fill_mode; +} spi_data_t; + +extern volatile spi_t *const spi[4]; + +/** + * @brief Set spi configuration + * + * @param[in] spi_num Spi bus number + * @param[in] mode Spi mode + * @param[in] frame_format Spi frame format + * @param[in] data_bit_length Spi data bit length + * @param[in] endian 0:little-endian 1:big-endian + * + * @return Void + */ +void spi_init(spi_device_num_t spi_num, spi_work_mode_t work_mode, spi_frame_format_t frame_format, + size_t data_bit_length, uint32_t endian); + +/** + * @brief Set multiline configuration + * + * @param[in] spi_num Spi bus number + * @param[in] instruction_length Instruction length + * @param[in] address_length Address length + * @param[in] wait_cycles Wait cycles + * @param[in] instruction_address_trans_mode Spi transfer mode + * + */ +void spi_init_non_standard(spi_device_num_t spi_num, uint32_t instruction_length, uint32_t address_length, + uint32_t wait_cycles, spi_instruction_address_trans_mode_t instruction_address_trans_mode); + +/** + * @brief Spi send data + * + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] tx_buff Spi transmit buffer point + * @param[in] tx_len Spi transmit buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_send_data_standard(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *CmdBuff, + size_t CmdLen, const uint8_t *tx_buff, size_t tx_len); + +/** + * @brief Spi receive data + * + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] rx_buff Spi receive buffer point + * @param[in] rx_len Spi receive buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_receive_data_standard(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len); + +/** + * @brief Spi special receive data + * + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] rx_buff Spi receive buffer point + * @param[in] rx_len Spi receive buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_receive_data_multiple(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len); + +/** + * @brief Spi special send data + * + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] tx_buff Spi transmit buffer point + * @param[in] tx_len Spi transmit buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_send_data_multiple(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *CmdBuff, + size_t CmdLen, const uint8_t *tx_buff, size_t tx_len); + +/** + * @brief Spi send data by dma + * + * @param[in] channel_num Dmac channel number + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] tx_buff Spi transmit buffer point + * @param[in] tx_len Spi transmit buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_send_data_standard_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, + spi_chip_select_t chip_select, + const uint8_t *CmdBuff, size_t CmdLen, const uint8_t *tx_buff, size_t tx_len); + +/** + * @brief Spi receive data by dma + * + * @param[in] w_channel_num Dmac write channel number + * @param[in] r_channel_num Dmac read channel number + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] rx_buff Spi receive buffer point + * @param[in] rx_len Spi receive buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_receive_data_standard_dma(dmac_channel_number_t dma_send_channel_num, + dmac_channel_number_t dma_receive_channel_num, + spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len); + +/** + * @brief Spi special send data by dma + * + * @param[in] channel_num Dmac channel number + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] tx_buff Spi transmit buffer point + * @param[in] tx_len Spi transmit buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_send_data_multiple_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, + spi_chip_select_t chip_select, + const uint32_t *CmdBuff, size_t CmdLen, const uint8_t *tx_buff, size_t tx_len); + +/** + * @brief Spi special receive data by dma + * + * @param[in] dma_send_channel_num Dmac write channel number + * @param[in] dma_receive_channel_num Dmac read channel number + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] CmdBuff Spi command buffer point + * @param[in] CmdLen Spi command length + * @param[in] rx_buff Spi receive buffer point + * @param[in] rx_len Spi receive buffer length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_receive_data_multiple_dma(dmac_channel_number_t dma_send_channel_num, + dmac_channel_number_t dma_receive_channel_num, + spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len); + +/** + * @brief Spi fill dma + * + * @param[in] channel_num Dmac channel number + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] tx_buff Spi command buffer point + * @param[in] tx_len Spi command length + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_fill_data_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, spi_chip_select_t chip_select, + const uint32_t *tx_buff, size_t tx_len); + +/** + * @brief Spi normal send by dma + * + * @param[in] channel_num Dmac channel number + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] tx_buff Spi transmit buffer point + * @param[in] tx_len Spi transmit buffer length + * @param[in] stw Spi transfer width + * + * @return Result + * - 0 Success + * - Other Fail + */ +void spi_send_data_normal_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, + spi_chip_select_t chip_select, + const void *tx_buff, size_t tx_len, spi_transfer_width_t spi_transfer_width); + +/** + * @brief Spi normal send by dma + * + * @param[in] spi_num Spi bus number + * @param[in] spi_clk Spi clock rate + * + * @return The real spi clock rate + */ +uint32_t spi_set_clk_rate(spi_device_num_t spi_num, uint32_t spi_clk); + +/** + * @brief Spi full duplex send receive data by dma + * + * @param[in] dma_send_channel_num Dmac write channel number + * @param[in] dma_receive_channel_num Dmac read channel number + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] tx_buf Spi send buffer + * @param[in] tx_len Spi send buffer length + * @param[in] rx_buf Spi receive buffer + * @param[in] rx_len Spi receive buffer length + * + */ +void spi_dup_send_receive_data_dma(dmac_channel_number_t dma_send_channel_num, + dmac_channel_number_t dma_receive_channel_num, + spi_device_num_t spi_num, spi_chip_select_t chip_select, + const uint8_t *tx_buf, size_t tx_len, uint8_t *rx_buf, size_t rx_len); + +/** + * @brief Set spi slave configuration + * + * @param[in] int_pin SPI master starts sending data interrupt. + * @param[in] ready_pin SPI slave ready. + * @param[in] dmac_channel Dmac channel number for block. + * @param[in] data_bit_length Spi data bit length + * @param[in] data SPI slave device data buffer. + * @param[in] len The length of SPI slave device data buffer. + * @param[in] callback Callback of spi slave. + * + * @return Void + */ +void spi_slave_config(uint8_t int_pin, uint8_t ready_pin, dmac_channel_number_t dmac_channel, size_t data_bit_length, uint8_t *data, uint32_t len, spi_slave_receive_callback_t callback); + +/** + * @brief Spi handle transfer data operations + * + * @param[in] spi_num Spi bus number + * @param[in] chip_select Spi chip select + * @param[in] data Spi transfer data information + * @param[in] cb Spi DMA callback + * + */ +void spi_handle_data_dma(spi_device_num_t spi_num, spi_chip_select_t chip_select, spi_data_t data, plic_interrupt_t *cb); + +#ifdef __cplusplus +} +#endif + +#endif /* __HARDWARE_SPI_H__ */ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_uart.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_uart.h new file mode 100644 index 000000000..ef90bee82 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_uart.h @@ -0,0 +1,364 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * @brief Universal Asynchronous Receiver/Transmitter (UART) + * + * The UART peripheral supports the following features: + * + * - 8-N-1 and 8-N-2 formats: 8 data bits, no parity bit, 1 start + * bit, 1 or 2 stop bits + * + * - 8-entry transmit and receive FIFO buffers with programmable + * watermark interrupts + * + * - 16× Rx oversampling with 2/3 majority voting per bit + * + * The UART peripheral does not support hardware flow control or + * other modem control signals, or synchronous serial data + * tranfesrs. + * + * + */ + +/** +* @file hardware_uart.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#ifndef __HARDWARE_UART_H__ +#define __HARDWARE_UART_H__ + +#include +#include "platform.h" +#include "plic.h" +#include "dmac.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum _uart_dev +{ + UART_DEV1 = 0, + UART_DEV2, + UART_DEV3, +} uart_dev_t; + +typedef struct _uart +{ + union + { + volatile uint32_t RBR; + volatile uint32_t DLL; + volatile uint32_t THR; + }; + + union + { + volatile uint32_t DLH; + volatile uint32_t IER; + }; + + union + { + volatile uint32_t FCR; + volatile uint32_t IIR; + }; + + volatile uint32_t LCR; + volatile uint32_t MCR; + volatile uint32_t LSR; + volatile uint32_t MSR; + + volatile uint32_t SCR; + volatile uint32_t LPDLL; + volatile uint32_t LPDLH; + + volatile uint32_t reserved1[2]; + + union + { + volatile uint32_t SRBR[16]; + volatile uint32_t STHR[16]; + }; + + volatile uint32_t FAR; + volatile uint32_t TFR; + volatile uint32_t RFW; + volatile uint32_t USR; + volatile uint32_t TFL; + volatile uint32_t RFL; + volatile uint32_t SRR; + volatile uint32_t SRTS; + volatile uint32_t SBCR; + volatile uint32_t SDMAM; + volatile uint32_t SFE; + volatile uint32_t SRT; + volatile uint32_t STET; + volatile uint32_t HTX; + volatile uint32_t DMASA; + volatile uint32_t TCR; + volatile uint32_t DE_EN; + volatile uint32_t RE_EN; + volatile uint32_t DET; + volatile uint32_t TAT; + volatile uint32_t DLF; + volatile uint32_t RAR; + volatile uint32_t TAR; + volatile uint32_t LCR_EXT; + volatile uint32_t reserved2[9]; + volatile uint32_t CPR; + volatile uint32_t UCV; + volatile uint32_t CTR; +} UartT; + +typedef enum _uart_device_number +{ + UART_DEVICE_1, + UART_DEVICE_2, + UART_DEVICE_3, + UART_DEVICE_MAX, +} UartDeviceNumberT; + +typedef enum _uart_bitwidth +{ + UART_BITWIDTH_5BIT = 5, + UART_BITWIDTH_6BIT, + UART_BITWIDTH_7BIT, + UART_BITWIDTH_8BIT, +} UartBitwidthPointer; + +typedef enum _uart_stopbit +{ + UART_STOP_1, + UART_STOP_1_5, + UART_STOP_2 +} UartStopbitT; + +typedef enum _uart_rede_sel +{ + DISABLE = 0, + ENABLE, +} uart_rede_sel_t; + +typedef enum _uart_parity +{ + UART_PARITY_NONE, + UART_PARITY_ODD, + UART_PARITY_EVEN +} UartParityT; + +typedef enum _uart_interrupt_mode +{ + UART_SEND = 1, + UART_RECEIVE = 2, +} UartInterruptModeT; + +typedef enum _uart_send_trigger +{ + UART_SEND_FIFO_0, + UART_SEND_FIFO_2, + UART_SEND_FIFO_4, + UART_SEND_FIFO_8, +} uart_send_trigger_t; + +typedef enum _uart_receive_trigger +{ + UART_RECEIVE_FIFO_1, + UART_RECEIVE_FIFO_4, + UART_RECEIVE_FIFO_8, + UART_RECEIVE_FIFO_14, +} uart_receive_trigger_t; + +typedef struct _uart_data_t +{ + dmac_channel_number_t tx_channel; + dmac_channel_number_t rx_channel; + uint32_t *tx_buf; + size_t tx_len; + uint32_t *rx_buf; + size_t rx_len; + UartInterruptModeT TransferMode; +} uart_data_t; + +/** + * @brief Send data from uart + * + * @param[in] channel Uart index + * @param[in] buffer The data be transfer + * @param[in] len The data length + * + * @return Transfer length + */ +int UartSendData(UartDeviceNumberT channel, const char *buffer, size_t BufLen); + +/** + * @brief Read data from uart + * + * @param[in] channel Uart index + * @param[in] buffer The Data received + * @param[in] len Receive length + * + * @return Receive length + */ +int UartReceiveData(UartDeviceNumberT channel, char *buffer, size_t BufLen); + +/** + * @brief Init uart + * + * @param[in] channel Uart index + * + */ +void UartInit(UartDeviceNumberT channel); + +/** + * @brief Set uart param + * + * @param[in] channel Uart index + * @param[in] BaudRate Baudrate + * @param[in] DataWidth Data width + * @param[in] stopbit Stop bit + * @param[in] parity Odd Even parity + * + */ +void uart_config(UartDeviceNumberT channel, uint32_t BaudRate, UartBitwidthPointer DataWidth, UartStopbitT stopbit, UartParityT parity); + +/** + * @brief Set uart param + * + * @param[in] channel Uart index + * @param[in] BaudRate Baudrate + * @param[in] DataWidth Data width + * @param[in] stopbit Stop bit + * @param[in] parity Odd Even parity + * + */ +void uart_configure(UartDeviceNumberT channel, uint32_t BaudRate, UartBitwidthPointer DataWidth, UartStopbitT stopbit, UartParityT parity); + +/** + * @brief Register uart interrupt + * + * @param[in] channel Uart index + * @param[in] interrupt_mode Interrupt Mode receive or send + * @param[in] uart_callback Call back + * @param[in] ctx Param of call back + * @param[in] priority Interrupt priority + * + */ +void uart_irq_register(UartDeviceNumberT channel, UartInterruptModeT interrupt_mode, plic_irq_callback_t uart_callback, void *ctx, uint32_t priority); + +/** + * @brief Deregister uart interrupt + * + * @param[in] channel Uart index + * @param[in] interrupt_mode Interrupt Mode receive or send + * + */ +void uart_irq_unregister(UartDeviceNumberT channel, UartInterruptModeT interrupt_mode); + +/** + * @brief Set send interrupt threshold + * + * @param[in] channel Uart index + * @param[in] trigger Threshold of send interrupt + * + */ +void UartSetSendTrigger(UartDeviceNumberT channel, uart_send_trigger_t trigger); + +/** + * @brief Set receive interrupt threshold + * + * @param[in] channel Uart index + * @param[in] trigger Threshold of receive interrupt + * + */ +void uart_set_receive_trigger(UartDeviceNumberT channel, uart_receive_trigger_t trigger); + +/** + * @brief Send data by dma + * + * @param[in] channel Uart index + * @param[in] dmac_channel Dmac channel + * @param[in] buffer Send data + * @param[in] BufLen Data length + * + */ +void UartSendDataDma(UartDeviceNumberT uart_channel, dmac_channel_number_t dmac_channel, const uint8_t *buffer, size_t BufLen); + +/** + * @brief Receive data by dma + * + * @param[in] channel Uart index + * @param[in] dmac_channel Dmac channel + * @param[in] buffer Receive data + * @param[in] BufLen Data length + * + */ +void UartReceiveDataDma(UartDeviceNumberT uart_channel, dmac_channel_number_t dmac_channel, uint8_t *buffer, size_t BufLen); + + +/** + * @brief Send data by dma + * + * @param[in] uart_channel Uart index + * @param[in] dmac_channel Dmac channel + * @param[in] buffer Send data + * @param[in] BufLen Data length + * @param[in] uart_callback Call back + * @param[in] ctx Param of call back + * @param[in] priority Interrupt priority + * + */ +void UartSendDataDmaIrq(UartDeviceNumberT uart_channel, dmac_channel_number_t dmac_channel, + const uint8_t *buffer, size_t BufLen, plic_irq_callback_t uart_callback, + void *ctx, uint32_t priority); + +/** + * @brief Receive data by dma + * + * @param[in] uart_channel Uart index + * @param[in] dmac_channel Dmac channel + * @param[in] buffer Receive data + * @param[in] BufLen Data length + * @param[in] uart_callback Call back + * @param[in] ctx Param of call back + * @param[in] priority Interrupt priority + * + */ +void UartReceiveDataDmaIrq(UartDeviceNumberT uart_channel, dmac_channel_number_t dmac_channel, + uint8_t *buffer, size_t BufLen, plic_irq_callback_t uart_callback, + void *ctx, uint32_t priority); + +/** + * @brief Uart handle transfer data operations + * + * @param[in] uart_channel Uart index + * @param[in] data Uart data information + * @param[in] buffer Uart DMA callback + * + */ +void uart_handle_data_dma(UartDeviceNumberT uart_channel ,uart_data_t data, plic_interrupt_t *cb); + +#ifdef __cplusplus +} +#endif + +#endif /* __UART_H__ */ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_uarths.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_uarths.h new file mode 100644 index 000000000..26eb24863 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/hardware_uarths.h @@ -0,0 +1,302 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * @brief Universal Asynchronous Receiver/Transmitter (UART) + * + * The UART peripheral supports the following features: + * + * - 8-N-1 and 8-N-2 formats: 8 data bits, no parity bit, 1 start + * bit, 1 or 2 stop bits + * + * - 8-entry transmit and receive FIFO buffers with programmable + * watermark interrupts + * + * - 16× Rx oversampling with 2/3 majority voting per bit + * + * The UART peripheral does not support hardware flow control or + * other modem control signals, or synchronous serial data + * tranfesrs. + * + * @note UART RAM Layout + * + * | Address | Name | Description | + * |-----------|----------|---------------------------------| + * | 0x000 | txdata | Transmit data register | + * | 0x004 | rxdata | Receive data register | + * | 0x008 | txctrl | Transmit control register | + * | 0x00C | rxctrl | Receive control register | + * | 0x010 | ie | UART interrupt enable | + * | 0x014 | ip | UART Interrupt pending | + * | 0x018 | div | Baud rate divisor | + * + */ + +/** +* @file hardware_uarths.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#ifndef __HARDWARE_UARTHS_H__ +#define __HARDWARE_UARTHS_H__ + +#include +#include +#include "platform.h" +#include "plic.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* clang-format off */ +/* Register address offsets */ +#define UARTHS_REG_TXFIFO (0x00) +#define UARTHS_REG_RXFIFO (0x04) +#define UARTHS_REG_TXCTRL (0x08) +#define UARTHS_REG_RXCTRL (0x0c) +#define UARTHS_REG_IE (0x10) +#define UARTHS_REG_IP (0x14) +#define UARTHS_REG_DIV (0x18) + +/* TXCTRL register */ +#define UARTHS_TXEN (0x01) +#define UARTHS_TXWM(x) (((x) & 0xffff) << 16) + +/* RXCTRL register */ +#define UARTHS_RXEN (0x01) +#define UARTHS_RXWM(x) (((x) & 0xffff) << 16) + +/* IP register */ +#define UARTHS_IP_TXWM (0x01) +#define UARTHS_IP_RXWM (0x02) +/* clang-format on */ + +typedef struct _uarths_txdata +{ + /* Bits [7:0] is data */ + uint32_t data : 8; + /* Bits [30:8] is 0 */ + uint32_t zero : 23; + /* Bit 31 is full status */ + uint32_t full : 1; +} __attribute__((packed, aligned(4))) uarths_txdata_t; + +typedef struct _uarths_rxdata +{ + /* Bits [7:0] is data */ + uint32_t data : 8; + /* Bits [30:8] is 0 */ + uint32_t zero : 23; + /* Bit 31 is empty status */ + uint32_t empty : 1; +} __attribute__((packed, aligned(4))) uarths_rxdata_t; + +typedef struct _uarths_txctrl +{ + /* Bit 0 is txen, controls whether the Tx channel is active. */ + uint32_t txen : 1; + /* Bit 1 is nstop, 0 for one stop bit and 1 for two stop bits */ + uint32_t nstop : 1; + /* Bits [15:2] is reserved */ + uint32_t resv0 : 14; + /* Bits [18:16] is threshold of interrupt triggers */ + uint32_t txcnt : 3; + /* Bits [31:19] is reserved */ + uint32_t resv1 : 13; +} __attribute__((packed, aligned(4))) uarths_txctrl_t; + +typedef struct _uarths_rxctrl +{ + /* Bit 0 is txen, controls whether the Tx channel is active. */ + uint32_t rxen : 1; + /* Bits [15:1] is reserved */ + uint32_t resv0 : 15; + /* Bits [18:16] is threshold of interrupt triggers */ + uint32_t rxcnt : 3; + /* Bits [31:19] is reserved */ + uint32_t resv1 : 13; +} __attribute__((packed, aligned(4))) uarths_rxctrl_t; + +typedef struct _uarths_ip +{ + /* Bit 0 is txwm, raised less than txcnt */ + uint32_t txwm : 1; + /* Bit 1 is txwm, raised greater than rxcnt */ + uint32_t rxwm : 1; + /* Bits [31:2] is 0 */ + uint32_t zero : 30; +} __attribute__((packed, aligned(4))) uarths_ip_t; + +typedef struct _uarths_ie +{ + /* Bit 0 is txwm, raised less than txcnt */ + uint32_t txwm : 1; + /* Bit 1 is txwm, raised greater than rxcnt */ + uint32_t rxwm : 1; + /* Bits [31:2] is 0 */ + uint32_t zero : 30; +} __attribute__((packed, aligned(4))) uarths_ie_t; + +typedef struct _uarths_div +{ + /* Bits [31:2] is baud rate divisor register */ + uint32_t div : 16; + /* Bits [31:16] is 0 */ + uint32_t zero : 16; +} __attribute__((packed, aligned(4))) uarths_div_t; + +typedef struct _uarths +{ + /* Address offset 0x00 */ + uarths_txdata_t txdata; + /* Address offset 0x04 */ + uarths_rxdata_t rxdata; + /* Address offset 0x08 */ + uarths_txctrl_t txctrl; + /* Address offset 0x0c */ + uarths_rxctrl_t rxctrl; + /* Address offset 0x10 */ + uarths_ie_t ie; + /* Address offset 0x14 */ + uarths_ip_t ip; + /* Address offset 0x18 */ + uarths_div_t div; +} __attribute__((packed, aligned(4))) UarthsT; + +typedef enum _uarths_interrupt_mode +{ + UARTHS_SEND = 1, + UARTHS_RECEIVE = 2, + UARTHS_SEND_RECEIVE = 3, +} uarths_interrupt_mode_t; + +typedef enum _uarths_stopbit +{ + UARTHS_STOP_1, + UARTHS_STOP_2 +} uarths_stopbit_t; + +extern volatile UarthsT *const uarths; + +/** + * @brief Initialization Core UART + * + * @return result + * - 0 Success + * - Other Fail + */ +void uarths_init(void); + +/** + * @brief Put a char to UART + * + * @param[in] c The char to put + * + * @note If c is '\n', a '\r' will be appended automatically + * + * @return result + * - 0 Success + * - Other Fail + */ +int uarths_putchar(char c); + +/** + * @brief Send a string to UART + * + * @param[in] s The string to send + * + * @note The string must ending with '\0' + * + * @return result + * - 0 Success + * - Other Fail + */ +int uarths_puts(const char *s); + + +/** + * @brief Get a byte from UART + * + * @return byte as int type from UART + */ +int uarths_getc(void); + +/** + * @brief Set uarths interrupt callback + * + * @param[in] interrupt_mode Interrupt mode recevice or send + * @param[in] uarths_callback Interrupt callback + * @param[in] ctx Param of callback + * @param[in] priority Interrupt priority + * + */ +void uarths_set_irq(uarths_interrupt_mode_t interrupt_mode, plic_irq_callback_t uarths_callback, void *ctx, uint32_t priority); + +/** + * @brief Uarths receive data + * + * @param[in] buf The data received + * @param[in] BufLen The length of data + * + * @return Number of received data + */ +size_t uarths_receive_data(uint8_t *buf, size_t BufLen); + +/** + * @brief Uarths receive data + * + * @param[in] buf The data sended + * @param[in] BufLen The length of data + * + * @return Number of sended data + */ +size_t uarths_send_data(const uint8_t *buf, size_t BufLen); + +/** + * @brief Get interrupt mode + * + * @return Mode of interrupt + */ +uarths_interrupt_mode_t uarths_get_interrupt_mode(void); + +/** + * @brief Set uarths baud rate and stopbit + * + * @param[in] BaudRate The baud rate + * @param[in] stopbit The stopbit of data + * + */ +void uarths_config(uint32_t BaudRate, uarths_stopbit_t stopbit); + +/** + * @brief Set uart interrupt condition + * + * @param[in] interrupt_mode The interrupt mode + * @param[in] cnt The count of tigger + * + */ +void uarths_set_interrupt_cnt(uarths_interrupt_mode_t interrupt_mode, uint8_t cnt); + +#ifdef __cplusplus +} +#endif + +#endif /* __UARTHS_H__ */ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/io.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/io.h new file mode 100644 index 000000000..15d62fd0f --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/io.h @@ -0,0 +1,60 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file io.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#ifndef __IO_H__ +#define __IO_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define readb(addr) (*(volatile uint8_t *)(addr)) +#define readw(addr) (*(volatile uint16_t *)(addr)) +#define readl(addr) (*(volatile uint32_t *)(addr)) +#define readq(addr) (*(volatile uint64_t *)(addr)) + +#define writeb(v, addr) \ + { \ + (*(volatile uint8_t *)(addr)) = (v); \ + } +#define writew(v, addr) \ + { \ + (*(volatile uint16_t *)(addr)) = (v); \ + } +#define writel(v, addr) \ + { \ + (*(volatile uint32_t *)(addr)) = (v); \ + } +#define writeq(v, addr) \ + { \ + (*(volatile uint64_t *)(addr)) = (v); \ + } + +#ifdef __cplusplus +} +#endif + +#endif /* __IO_H__ */ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/plic.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/plic.h new file mode 100644 index 000000000..2404959b3 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/plic.h @@ -0,0 +1,467 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file plic.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#ifndef __PLIC_H__ +#define __PLIC_H__ + +#include +#include "encoding.h" +#include "platform.h" + +/* For c++ compatibility */ +#ifdef __cplusplus +extern "C" { +#endif + +/* clang-format off */ +/* IRQ number settings */ +#define PLIC_NUM_SOURCES (IRQN_MAX - 1) +#define PLIC_NUM_PRIORITIES (7) + +/* Real number of cores */ +#define PLIC_NUM_CORES (2) +/* clang-format on */ + +/** + * @brief PLIC External Interrupt Numbers + * + * @note PLIC interrupt sources + * + * | Source | Name | Description | + * |--------|--------------------------|------------------------------------| + * | 0 | IRQN_NO_INTERRUPT | The non-existent interrupt | + * | 1 | IRQN_SPI0_INTERRUPT | SPI0 interrupt | + * | 2 | IRQN_SPI1_INTERRUPT | SPI1 interrupt | + * | 3 | IRQN_SPI_SLAVE_INTERRUPT | SPI_SLAVE interrupt | + * | 4 | IRQN_SPI3_INTERRUPT | SPI3 interrupt | + * | 5 | IRQN_I2S0_INTERRUPT | I2S0 interrupt | + * | 6 | IRQN_I2S1_INTERRUPT | I2S1 interrupt | + * | 7 | IRQN_I2S2_INTERRUPT | I2S2 interrupt | + * | 8 | IRQN_I2C0_INTERRUPT | I2C0 interrupt | + * | 9 | IRQN_I2C1_INTERRUPT | I2C1 interrupt | + * | 10 | IRQN_I2C2_INTERRUPT | I2C2 interrupt | + * | 11 | IRQN_UART1_INTERRUPT | UART1 interrupt | + * | 12 | IRQN_UART2_INTERRUPT | UART2 interrupt | + * | 13 | IRQN_UART3_INTERRUPT | UART3 interrupt | + * | 14 | IRQN_TIMER0A_INTERRUPT | TIMER0 channel 0 or 1 interrupt | + * | 15 | IRQN_TIMER0B_INTERRUPT | TIMER0 channel 2 or 3 interrupt | + * | 16 | IRQN_TIMER1A_INTERRUPT | TIMER1 channel 0 or 1 interrupt | + * | 17 | IRQN_TIMER1B_INTERRUPT | TIMER1 channel 2 or 3 interrupt | + * | 18 | IRQN_TIMER2A_INTERRUPT | TIMER2 channel 0 or 1 interrupt | + * | 19 | IRQN_TIMER2B_INTERRUPT | TIMER2 channel 2 or 3 interrupt | + * | 20 | IRQN_RTC_INTERRUPT | RTC tick and alarm interrupt | + * | 21 | IRQN_WDT0_INTERRUPT | Watching dog timer0 interrupt | + * | 22 | IRQN_WDT1_INTERRUPT | Watching dog timer1 interrupt | + * | 23 | IRQN_APB_GPIO_INTERRUPT | APB GPIO interrupt | + * | 24 | IRQN_DVP_INTERRUPT | Digital video port interrupt | + * | 25 | IRQN_AI_INTERRUPT | AI accelerator interrupt | + * | 26 | IRQN_FFT_INTERRUPT | FFT accelerator interrupt | + * | 27 | IRQN_DMA0_INTERRUPT | DMA channel0 interrupt | + * | 28 | IRQN_DMA1_INTERRUPT | DMA channel1 interrupt | + * | 29 | IRQN_DMA2_INTERRUPT | DMA channel2 interrupt | + * | 30 | IRQN_DMA3_INTERRUPT | DMA channel3 interrupt | + * | 31 | IRQN_DMA4_INTERRUPT | DMA channel4 interrupt | + * | 32 | IRQN_DMA5_INTERRUPT | DMA channel5 interrupt | + * | 33 | IRQN_UARTHS_INTERRUPT | Hi-speed UART0 interrupt | + * | 34 | IRQN_GPIOHS0_INTERRUPT | Hi-speed GPIO0 interrupt | + * | 35 | IRQN_GPIOHS1_INTERRUPT | Hi-speed GPIO1 interrupt | + * | 36 | IRQN_GPIOHS2_INTERRUPT | Hi-speed GPIO2 interrupt | + * | 37 | IRQN_GPIOHS3_INTERRUPT | Hi-speed GPIO3 interrupt | + * | 38 | IRQN_GPIOHS4_INTERRUPT | Hi-speed GPIO4 interrupt | + * | 39 | IRQN_GPIOHS5_INTERRUPT | Hi-speed GPIO5 interrupt | + * | 40 | IRQN_GPIOHS6_INTERRUPT | Hi-speed GPIO6 interrupt | + * | 41 | IRQN_GPIOHS7_INTERRUPT | Hi-speed GPIO7 interrupt | + * | 42 | IRQN_GPIOHS8_INTERRUPT | Hi-speed GPIO8 interrupt | + * | 43 | IRQN_GPIOHS9_INTERRUPT | Hi-speed GPIO9 interrupt | + * | 44 | IRQN_GPIOHS10_INTERRUPT | Hi-speed GPIO10 interrupt | + * | 45 | IRQN_GPIOHS11_INTERRUPT | Hi-speed GPIO11 interrupt | + * | 46 | IRQN_GPIOHS12_INTERRUPT | Hi-speed GPIO12 interrupt | + * | 47 | IRQN_GPIOHS13_INTERRUPT | Hi-speed GPIO13 interrupt | + * | 48 | IRQN_GPIOHS14_INTERRUPT | Hi-speed GPIO14 interrupt | + * | 49 | IRQN_GPIOHS15_INTERRUPT | Hi-speed GPIO15 interrupt | + * | 50 | IRQN_GPIOHS16_INTERRUPT | Hi-speed GPIO16 interrupt | + * | 51 | IRQN_GPIOHS17_INTERRUPT | Hi-speed GPIO17 interrupt | + * | 52 | IRQN_GPIOHS18_INTERRUPT | Hi-speed GPIO18 interrupt | + * | 53 | IRQN_GPIOHS19_INTERRUPT | Hi-speed GPIO19 interrupt | + * | 54 | IRQN_GPIOHS20_INTERRUPT | Hi-speed GPIO20 interrupt | + * | 55 | IRQN_GPIOHS21_INTERRUPT | Hi-speed GPIO21 interrupt | + * | 56 | IRQN_GPIOHS22_INTERRUPT | Hi-speed GPIO22 interrupt | + * | 57 | IRQN_GPIOHS23_INTERRUPT | Hi-speed GPIO23 interrupt | + * | 58 | IRQN_GPIOHS24_INTERRUPT | Hi-speed GPIO24 interrupt | + * | 59 | IRQN_GPIOHS25_INTERRUPT | Hi-speed GPIO25 interrupt | + * | 60 | IRQN_GPIOHS26_INTERRUPT | Hi-speed GPIO26 interrupt | + * | 61 | IRQN_GPIOHS27_INTERRUPT | Hi-speed GPIO27 interrupt | + * | 62 | IRQN_GPIOHS28_INTERRUPT | Hi-speed GPIO28 interrupt | + * | 63 | IRQN_GPIOHS29_INTERRUPT | Hi-speed GPIO29 interrupt | + * | 64 | IRQN_GPIOHS30_INTERRUPT | Hi-speed GPIO30 interrupt | + * | 65 | IRQN_GPIOHS31_INTERRUPT | Hi-speed GPIO31 interrupt | + * + */ +/* clang-format off */ +typedef enum _plic_irq +{ + IRQN_NO_INTERRUPT = 0, /*!< The non-existent interrupt */ + IRQN_SPI0_INTERRUPT = 1, /*!< SPI0 interrupt */ + IRQN_SPI1_INTERRUPT = 2, /*!< SPI1 interrupt */ + IRQN_SPI_SLAVE_INTERRUPT = 3, /*!< SPI_SLAVE interrupt */ + IRQN_SPI3_INTERRUPT = 4, /*!< SPI3 interrupt */ + IRQN_I2S0_INTERRUPT = 5, /*!< I2S0 interrupt */ + IRQN_I2S1_INTERRUPT = 6, /*!< I2S1 interrupt */ + IRQN_I2S2_INTERRUPT = 7, /*!< I2S2 interrupt */ + IRQN_I2C0_INTERRUPT = 8, /*!< I2C0 interrupt */ + IRQN_I2C1_INTERRUPT = 9, /*!< I2C1 interrupt */ + IRQN_I2C2_INTERRUPT = 10, /*!< I2C2 interrupt */ + IRQN_UART1_INTERRUPT = 11, /*!< UART1 interrupt */ + IRQN_UART2_INTERRUPT = 12, /*!< UART2 interrupt */ + IRQN_UART3_INTERRUPT = 13, /*!< UART3 interrupt */ + IRQN_TIMER0A_INTERRUPT = 14, /*!< TIMER0 channel 0 or 1 interrupt */ + IRQN_TIMER0B_INTERRUPT = 15, /*!< TIMER0 channel 2 or 3 interrupt */ + IRQN_TIMER1A_INTERRUPT = 16, /*!< TIMER1 channel 0 or 1 interrupt */ + IRQN_TIMER1B_INTERRUPT = 17, /*!< TIMER1 channel 2 or 3 interrupt */ + IRQN_TIMER2A_INTERRUPT = 18, /*!< TIMER2 channel 0 or 1 interrupt */ + IRQN_TIMER2B_INTERRUPT = 19, /*!< TIMER2 channel 2 or 3 interrupt */ + IRQN_RTC_INTERRUPT = 20, /*!< RTC tick and alarm interrupt */ + IRQN_WDT0_INTERRUPT = 21, /*!< Watching dog timer0 interrupt */ + IRQN_WDT1_INTERRUPT = 22, /*!< Watching dog timer1 interrupt */ + IRQN_APB_GPIO_INTERRUPT = 23, /*!< APB GPIO interrupt */ + IRQN_DVP_INTERRUPT = 24, /*!< Digital video port interrupt */ + IRQN_AI_INTERRUPT = 25, /*!< AI accelerator interrupt */ + IRQN_FFT_INTERRUPT = 26, /*!< FFT accelerator interrupt */ + IRQN_DMA0_INTERRUPT = 27, /*!< DMA channel0 interrupt */ + IRQN_DMA1_INTERRUPT = 28, /*!< DMA channel1 interrupt */ + IRQN_DMA2_INTERRUPT = 29, /*!< DMA channel2 interrupt */ + IRQN_DMA3_INTERRUPT = 30, /*!< DMA channel3 interrupt */ + IRQN_DMA4_INTERRUPT = 31, /*!< DMA channel4 interrupt */ + IRQN_DMA5_INTERRUPT = 32, /*!< DMA channel5 interrupt */ + IRQN_UARTHS_INTERRUPT = 33, /*!< Hi-speed UART0 interrupt */ + IRQN_GPIOHS0_INTERRUPT = 34, /*!< Hi-speed GPIO0 interrupt */ + IRQN_GPIOHS1_INTERRUPT = 35, /*!< Hi-speed GPIO1 interrupt */ + IRQN_GPIOHS2_INTERRUPT = 36, /*!< Hi-speed GPIO2 interrupt */ + IRQN_GPIOHS3_INTERRUPT = 37, /*!< Hi-speed GPIO3 interrupt */ + IRQN_GPIOHS4_INTERRUPT = 38, /*!< Hi-speed GPIO4 interrupt */ + IRQN_GPIOHS5_INTERRUPT = 39, /*!< Hi-speed GPIO5 interrupt */ + IRQN_GPIOHS6_INTERRUPT = 40, /*!< Hi-speed GPIO6 interrupt */ + IRQN_GPIOHS7_INTERRUPT = 41, /*!< Hi-speed GPIO7 interrupt */ + IRQN_GPIOHS8_INTERRUPT = 42, /*!< Hi-speed GPIO8 interrupt */ + IRQN_GPIOHS9_INTERRUPT = 43, /*!< Hi-speed GPIO9 interrupt */ + IRQN_GPIOHS10_INTERRUPT = 44, /*!< Hi-speed GPIO10 interrupt */ + IRQN_GPIOHS11_INTERRUPT = 45, /*!< Hi-speed GPIO11 interrupt */ + IRQN_GPIOHS12_INTERRUPT = 46, /*!< Hi-speed GPIO12 interrupt */ + IRQN_GPIOHS13_INTERRUPT = 47, /*!< Hi-speed GPIO13 interrupt */ + IRQN_GPIOHS14_INTERRUPT = 48, /*!< Hi-speed GPIO14 interrupt */ + IRQN_GPIOHS15_INTERRUPT = 49, /*!< Hi-speed GPIO15 interrupt */ + IRQN_GPIOHS16_INTERRUPT = 50, /*!< Hi-speed GPIO16 interrupt */ + IRQN_GPIOHS17_INTERRUPT = 51, /*!< Hi-speed GPIO17 interrupt */ + IRQN_GPIOHS18_INTERRUPT = 52, /*!< Hi-speed GPIO18 interrupt */ + IRQN_GPIOHS19_INTERRUPT = 53, /*!< Hi-speed GPIO19 interrupt */ + IRQN_GPIOHS20_INTERRUPT = 54, /*!< Hi-speed GPIO20 interrupt */ + IRQN_GPIOHS21_INTERRUPT = 55, /*!< Hi-speed GPIO21 interrupt */ + IRQN_GPIOHS22_INTERRUPT = 56, /*!< Hi-speed GPIO22 interrupt */ + IRQN_GPIOHS23_INTERRUPT = 57, /*!< Hi-speed GPIO23 interrupt */ + IRQN_GPIOHS24_INTERRUPT = 58, /*!< Hi-speed GPIO24 interrupt */ + IRQN_GPIOHS25_INTERRUPT = 59, /*!< Hi-speed GPIO25 interrupt */ + IRQN_GPIOHS26_INTERRUPT = 60, /*!< Hi-speed GPIO26 interrupt */ + IRQN_GPIOHS27_INTERRUPT = 61, /*!< Hi-speed GPIO27 interrupt */ + IRQN_GPIOHS28_INTERRUPT = 62, /*!< Hi-speed GPIO28 interrupt */ + IRQN_GPIOHS29_INTERRUPT = 63, /*!< Hi-speed GPIO29 interrupt */ + IRQN_GPIOHS30_INTERRUPT = 64, /*!< Hi-speed GPIO30 interrupt */ + IRQN_GPIOHS31_INTERRUPT = 65, /*!< Hi-speed GPIO31 interrupt */ + IRQN_MAX +} plic_irq_t; +/* clang-format on */ + +/** + * @brief Interrupt Source Priorities + * + * Each external interrupt source can be assigned a priority by + * writing to its 32-bit memory-mapped priority register. The + * number and value of supported priority levels can vary by + * implementa- tion, with the simplest implementations having all + * devices hardwired at priority 1, in which case, interrupts with + * the lowest ID have the highest effective priority. The priority + * registers are all WARL. + */ +typedef struct _plic_source_priorities +{ + /* 0x0C000000: Reserved, 0x0C000004-0x0C000FFC: 1-1023 priorities */ + uint32_t priority[1024]; +} __attribute__((packed, aligned(4))) plic_source_priorities_t; + +/** + * @brief Interrupt Pending Bits + * + * The current status of the interrupt source pending bits in the + * PLIC core can be read from the pending array, organized as 32 + * words of 32 bits. The pending bit for interrupt ID N is stored + * in bit (N mod 32) of word (N/32). Bit 0 of word 0, which + * represents the non-existent interrupt source 0, is always + * hardwired to zero. The pending bits are read-only. A pending + * bit in the PLIC core can be cleared by setting enable bits to + * only enable the desired interrupt, then performing a claim. A + * pending bit can be set by instructing the associated gateway to + * send an interrupt service request. + */ +typedef struct _plic_pending_bits +{ + /* 0x0C001000-0x0C00107C: Bit 0 is zero, Bits 1-1023 is pending bits */ + uint32_t u32[32]; + /* 0x0C001080-0x0C001FFF: Reserved */ + uint8_t resv[0xF80]; +} __attribute__((packed, aligned(4))) plic_pending_bits_t; + +/** + * @brief Target Interrupt Enables + * + * For each interrupt target, each device’s interrupt can be + * enabled by setting the corresponding bit in that target’s + * enables registers. The enables for a target are accessed as a + * contiguous array of 32×32-bit words, packed the same way as the + * pending bits. For each target, bit 0 of enable word 0 + * represents the non-existent interrupt ID 0 and is hardwired to + * 0. Unused interrupt IDs are also hardwired to zero. The enables + * arrays for different targets are packed contiguously in the + * address space. Only 32-bit word accesses are supported by the + * enables array in RV32 systems. Implementations can trap on + * accesses to enables for non-existent targets, but must allow + * access to the full enables array for any extant target, + * treating all non-existent interrupt source’s enables as + * hardwired to zero. + */ +typedef struct _plic_target_enables +{ + /* 0x0C002000-0x0C1F1F80: target 0-15871 enables */ + struct + { + uint32_t enable[32 * 2];/* Offset 0x00-0x7C: Bit 0 is zero, Bits 1-1023 is bits*/ + } target[15872 / 2]; + + /* 0x0C1F2000-0x0C1FFFFC: Reserved, size 0xE000 */ + uint8_t resv[0xE000]; +} __attribute__((packed, aligned(4))) plic_target_enables_t; + +/** + * @brief PLIC Targets + * + * Target Priority Thresholds The threshold for a pending + * interrupt priority that can interrupt each target can be set in + * the target’s threshold register. The threshold is a WARL field, + * where different implementations can support different numbers + * of thresholds. The simplest implementation has a threshold + * hardwired to zero. + * + * Target Claim Each target can perform a claim by reading the + * claim/complete register, which returns the ID of the highest + * priority pending interrupt or zero if there is no pending + * interrupt for the target. A successful claim will also + * atomically clear the corresponding pending bit on the interrupt + * source. A target can perform a claim at any time, even if the + * EIP is not set. The claim operation is not affected by the + * setting of the target’s priority threshold register. + * + * Target Completion A target signals it has completed running a + * handler by writing the interrupt ID it received from the claim + * to the claim/complete register. This is routed to the + * corresponding interrupt gateway, which can now send another + * interrupt request to the PLIC. The PLIC does not check whether + * the completion ID is the same as the last claim ID for that + * target. If the completion ID does not match an interrupt source + * that is currently enabled for the target, the completion is + * silently ignored. + */ +typedef struct _plic_target +{ + /* 0x0C200000-0x0FFFF004: target 0-15871 */ + struct { + uint32_t priority_threshold;/* Offset 0x000 */ + uint32_t claim_complete; /* Offset 0x004 */ + uint8_t resv[0x1FF8]; /* Offset 0x008, Size 0xFF8 */ + } target[15872 / 2]; +} __attribute__((packed, aligned(4))) plic_target_t; + +/** + * @brief Platform-Level Interrupt Controller + * + * PLIC is Platform-Level Interrupt Controller. The PLIC complies + * with the RISC-V Privileged Architecture specification, and can + * support a maximum of 1023 external interrupt sources targeting + * up to 15,872 core contexts. + */ +typedef struct _plic +{ + /* 0x0C000000-0x0C000FFC */ + plic_source_priorities_t source_priorities; + /* 0x0C001000-0x0C001FFF */ + const plic_pending_bits_t pending_bits; + /* 0x0C002000-0x0C1FFFFC */ + plic_target_enables_t target_enables; + /* 0x0C200000-0x0FFFF004 */ + plic_target_t targets; +} __attribute__((packed, aligned(4))) plic_t; + +extern volatile plic_t *const plic; + +/** + * @brief Definitions for the interrupt callbacks + */ +typedef int (*plic_irq_callback_t)(void *ctx); + +/** + * @brief Definitions for IRQ table instance + */ +typedef struct _plic_instance_t +{ + plic_irq_callback_t callback; + void *ctx; +} plic_instance_t; + +typedef struct _plic_callback_t +{ + plic_irq_callback_t callback; + void *ctx; + uint32_t priority; +} plic_interrupt_t; + +/** + * @brief Initialize PLIC external interrupt + * + * @note This function will set MIP_MEIP. The MSTATUS_MIE must set by user. + * + * @return result + * - 0 Success + * - Other Fail + */ +void plic_init(void); + +/** + * @brief Enable PLIC external interrupt + * + * @param[in] irq_number external interrupt number + * + * @return result + * - 0 Success + * - Other Fail + */ + +int plic_irq_enable(plic_irq_t irq_number); + +/** + * @brief Disable PLIC external interrupt + * + * @param[in] irq_number The external interrupt number + * + * @return result + * - 0 Success + * - Other Fail + */ +int plic_irq_disable(plic_irq_t irq_number); + +/** + * @brief Set IRQ priority + * + * @param[in] irq_number The external interrupt number + * @param[in] priority The priority of external interrupt number + * + * @return result + * - 0 Success + * - Other Fail + */ +int plic_set_priority(plic_irq_t irq_number, uint32_t priority); + +/** + * @brief Get IRQ priority + * + * @param[in] irq_number The external interrupt number + * + * @return The priority of external interrupt number + */ +uint32_t plic_get_priority(plic_irq_t irq_number); + +/** + * @brief Claim an IRQ + * + * @return The current IRQ number + */ +uint32_t plic_irq_claim(void); + +/** + * @brief Complete an IRQ + * + * @param[in] source The source IRQ number to complete + * + * @return result + * - 0 Success + * - Other Fail + */ +int plic_irq_complete(uint32_t source); + +/** + * @brief Register user callback function by IRQ number + * + * @param[in] irq The irq + * @param[in] callback The callback + * @param ctx The context + * + * @return result + * - 0 Success + * - Other Fail + */ +void plic_irq_register(plic_irq_t irq, plic_irq_callback_t callback, void *ctx); + +/** + * @brief Deegister user callback function by IRQ number + * + * @param[in] irq The irq + * + * @return result + * - 0 Success + * - Other Fail + */ +void plic_irq_deregister(plic_irq_t irq); + +/** + * @brief Deegister user callback function by IRQ number + * + * @param[in] irq The irq + * + * @return result + * - 0 Success + * - Other Fail + */ +void plic_irq_unregister(plic_irq_t irq); + +/** + * @brief Get IRQ table, Usage: + * plic_instance_t (*plic_instance)[IRQN_MAX] = plic_get_instance(); + * ... plic_instance[x][y] ...; + * + * @return the point of IRQ table + */ +plic_instance_t (*plic_get_instance(void))[IRQN_MAX]; + +/* For c++ compatibility */ +#ifdef __cplusplus +} +#endif + +#endif /* __PLIC_H__ */ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/socket.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/socket.h new file mode 100755 index 000000000..91e1a7bd9 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/socket.h @@ -0,0 +1,585 @@ +//***************************************************************************** +// +//! \file socket.h +//! \brief SOCKET APIs Header file. +//! \details SOCKET APIs like as berkeley socket api. +//! \version 1.0.2 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2014/05/01> V1.0.2. Refer to M20140501 +//! 1. Modify the comment : SO_REMAINED -> PACK_REMAINED +//! 2. Add the comment as zero byte udp data reception in getsockopt(). +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** +/** + * @defgroup WIZnet_socket_APIs 1. WIZnet socket APIs + * @brief WIZnet socket APIs are based on Berkeley socket APIs, thus it has + * much similar name and interface. But there is a little bit of difference. + * @details + * Comparison between WIZnet and Berkeley SOCKET APIs + * + * + * + * + * + * + * + * + * + * + * + * + * + *
API WIZnet Berkeley
socket() O O
bind() X O
listen() O O
connect() O O
accept() X O
recv() O O
send() O O
recvfrom() O O
sendto() O O
closesocket() O
close() & disconnect()
O
+ * There are @b bind() and @b accept() functions in @b Berkeley SOCKET API but, + * not in @b WIZnet SOCKET API. Because socket() of WIZnet is not only creating + * a SOCKET but also binding a local port number, and listen() of WIZnet is not + * only listening to connection request from client but also accepting the + * connection request. \n When you program "TCP SERVER" with Berkeley SOCKET + * API, you can use only one listen port. When the listen SOCKET accepts a + * connection request from a client, it keeps listening. After accepting the + * connection request, a new SOCKET is created and the new SOCKET is used in + * communication with the client. \n Following figure shows network flow diagram + * by Berkeley SOCKET API. + * @image html Berkeley_SOCKET.jpg "" + * But, When you program "TCP SERVER" with WIZnet SOCKET API, you can use as + * many as 8 listen SOCKET with same port number. \n Because there's no accept() + * in WIZnet SOCKET APIs, when the listen SOCKET accepts a connection request + * from a client, it is changed in order to communicate with the client. And the + * changed SOCKET is not listening any more and is dedicated for communicating + * with the client. \n If there're many listen SOCKET with same listen port + * number and a client requests a connection, the SOCKET which has the smallest + * SOCKET number accepts the request and is changed as communication SOCKET. \n + * Following figure shows network flow diagram by WIZnet SOCKET API. + * @image html WIZnet_SOCKET.jpg "" + */ +#ifndef _SOCKET_H_ +#define _SOCKET_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#include "wizchip_conf.h" + +#define SOCKET uint8_t ///< SOCKET type define for legacy driver + +#define SOCK_OK 1 ///< Result is OK about socket process. +#define SOCK_BUSY \ + 0 ///< Socket is busy on processing the operation. Valid only Non-block IO + ///< Mode. +#define SOCK_FATAL -1000 ///< Result is fatal error about socket process. + +#define SOCK_ERROR 0 +#define SOCKERR_SOCKNUM (SOCK_ERROR - 1) ///< Invalid socket number +#define SOCKERR_SOCKOPT (SOCK_ERROR - 2) ///< Invalid socket option +#define SOCKERR_SOCKINIT \ + (SOCK_ERROR - 3) ///< Socket is not initialized or SIPR is Zero IP address + ///< when Sn_MR_TCP +#define SOCKERR_SOCKCLOSED (SOCK_ERROR - 4) ///< Socket unexpectedly closed. +#define SOCKERR_SOCKMODE \ + (SOCK_ERROR - 5) ///< Invalid socket mode for socket operation. +#define SOCKERR_SOCKFLAG (SOCK_ERROR - 6) ///< Invalid socket flag +#define SOCKERR_SOCKSTATUS \ + (SOCK_ERROR - 7) ///< Invalid socket status for socket operation. +#define SOCKERR_ARG (SOCK_ERROR - 10) ///< Invalid argument. +#define SOCKERR_PORTZERO (SOCK_ERROR - 11) ///< Port number is zero +#define SOCKERR_IPINVALID (SOCK_ERROR - 12) ///< Invalid IP address +#define SOCKERR_TIMEOUT (SOCK_ERROR - 13) ///< Timeout occurred +#define SOCKERR_DATALEN \ + (SOCK_ERROR - 14) ///< Data length is zero or greater than buffer max size. +#define SOCKERR_BUFFER \ + (SOCK_ERROR - 15) ///< Socket buffer is not enough for data communication. + +#define SOCKFATAL_PACKLEN \ + (SOCK_FATAL - 1) ///< Invalid packet length. Fatal Error. + +/* + * SOCKET FLAG + */ +#define SF_ETHER_OWN \ + (Sn_MR_MFEN) ///< In @ref Sn_MR_MACRAW, Receive only the packet as broadcast, + ///< multicast and own packet +#define SF_IGMP_VER2 \ + (Sn_MR_MC) ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE, Select IGMP + ///< version 2. +#define SF_TCP_NODELAY (Sn_MR_ND) ///< In @ref Sn_MR_TCP, Use to nodelayed ack. +#define SF_MULTI_ENABLE \ + (Sn_MR_MULTI) ///< In @ref Sn_MR_UDP, Enable multicast mode. + +#if _WIZCHIP_ == 5500 +#define SF_BROAD_BLOCK \ + (Sn_MR_BCASTB) ///< In @ref Sn_MR_UDP or @ref Sn_MR_MACRAW, Block broadcast + ///< packet. Valid only in W5500 +#define SF_MULTI_BLOCK \ + (Sn_MR_MMB) ///< In @ref Sn_MR_MACRAW, Block multicast packet. Valid only in + ///< W5500 +#define SF_IPv6_BLOCK \ + (Sn_MR_MIP6B) ///< In @ref Sn_MR_MACRAW, Block IPv6 packet. Valid only in + ///< W5500 +#define SF_UNI_BLOCK \ + (Sn_MR_UCASTB) ///< In @ref Sn_MR_UDP with \ref SF_MULTI_ENABLE. Valid only + ///< in W5500 +#endif + +// A201505 : For W5300 +#if _WIZCHIP_ == 5300 +#define SF_TCP_ALIGN \ + 0x02 ///< Valid only \ref Sn_MR_TCP and W5300, refer to \ref Sn_MR_ALIGN +#endif + +#define SF_IO_NONBLOCK \ + 0x01 ///< Socket nonblock io mode. It used parameter in \ref socket(). + +/* + * UDP & MACRAW Packet Infomation + */ +#define PACK_FIRST \ + 0x80 ///< In Non-TCP packet, It indicates to start receiving a packet. (When + ///< W5300, This flag can be applied) +#define PACK_REMAINED \ + 0x01 ///< In Non-TCP packet, It indicates to remain a packet to be received. + ///< (When W5300, This flag can be applied) +#define PACK_COMPLETED \ + 0x00 ///< In Non-TCP packet, It indicates to complete to receive a packet. + ///< (When W5300, This flag can be applied) +// A20150601 : For Integrating with W5300 +#define PACK_FIFOBYTE \ + 0x02 ///< Valid only W5300, It indicate to have read already the Sn_RX_FIFOR. +// + +#ifndef AF_WIZ +#define AF_WIZ 46 +#endif + +/** + * @ingroup WIZnet_socket_APIs + * @brief Open a socket. + * @details Initializes the socket with 'sn' passed as parameter and open. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param protocol Protocol type to operate such as TCP, UDP and MACRAW. + * @param port Port number to be bined. + * @param flag Socket flags as \ref SF_ETHER_OWN, \ref SF_IGMP_VER2, \ref + * SF_TCP_NODELAY, \ref SF_MULTI_ENABLE, \ref SF_IO_NONBLOCK and so on.\n Valid + * flags only in W5500 : @ref SF_BROAD_BLOCK, @ref SF_MULTI_BLOCK, @ref + * SF_IPv6_BLOCK, and @ref SF_UNI_BLOCK. + * @sa Sn_MR + * + * @return @b Success : The socket number @b 'sn' passed as parameter\n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n + * @ref SOCKERR_SOCKMODE - Not support socket mode as + * TCP, UDP, and so on. \n + * @ref SOCKERR_SOCKFLAG - Invaild socket flag. + */ +int8_t wiz_socket(uint8_t sn, uint8_t protocol, uint16_t port, uint8_t flag); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Close a socket. + * @details It closes the socket with @b'sn' passed as parameter. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * + * @return @b Success : @ref SOCK_OK \n + * @b Fail : @ref SOCKERR_SOCKNUM - Invalid socket number + */ +int8_t wiz_sock_close(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Listen to a connection request from a client. + * @details It is listening to a connection request from a client. + * If connection request is accepted successfully, the connection is + * established. Socket sn is used in passive(server) mode. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKINIT - Socket is not initialized \n + * @ref SOCKERR_SOCKCLOSED - Socket closed unexpectedly. + */ +int8_t wiz_sock_listen(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Try to connect a server. + * @details It requests connection to the server with destination IP address and + * port number passed as parameter.\n + * @note It is valid only in TCP client mode. + * In block io mode, it does not return until connection is completed. + * In Non-block io mode, it return @ref SOCK_BUSY immediately. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param addr Pointer variable of destination IP address. It should be + * allocated 4 bytes. + * @param port Destination port number. + * + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number\n + * @ref SOCKERR_SOCKMODE - Invalid socket mode\n + * @ref SOCKERR_SOCKINIT - Socket is not initialized\n + * @ref SOCKERR_IPINVALID - Wrong server IP address\n + * @ref SOCKERR_PORTZERO - Server port zero\n + * @ref SOCKERR_TIMEOUT - Timeout occurred during request + * connection\n + * @ref SOCK_BUSY - In non-block io mode, it returned + * immediately\n + */ +int8_t wiz_sock_connect(uint8_t sn, uint8_t *addr, uint16_t port); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Try to disconnect a connection socket. + * @details It sends request message to disconnect the TCP socket 'sn' passed as + parameter to the server or client. + * @note It is valid only in TCP server or client mode. \n + * In block io mode, it does not return until disconnection is completed. + \n + * In Non-block io mode, it return @ref SOCK_BUSY immediately. \n + + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @return @b Success : @ref SOCK_OK \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the + socket \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCK_BUSY - Socket is busy. + */ +int8_t wiz_sock_disconnect(uint8_t sn); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Send data to the connected peer in TCP socket. + * @details It is used to send outgoing data to the connected socket. + * @note It is valid only in TCP server or client mode. It can't send data + * greater than socket buffer size. \n In block io mode, It doesn't return until + * data send is completed - socket buffer size is greater than data. \n In + * non-block io mode, It return @ref SOCK_BUSY immediately when socket buffer is + * not enough. \n + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer containing data to be sent. + * @param len The byte length of data in buf. + * @return @b Success : The sent data size \n + * @b Fail : \n @ref SOCKERR_SOCKSTATUS - Invalid socket status for + * socket operation \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCKERR_SOCKMODE - Invalid operation in + * the socket \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t wiz_sock_send(uint8_t sn, uint8_t *buf, uint16_t len); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Receive data from the connected peer. + * @details It is used to read incoming data from the connected socket.\n + * It waits for data as much as the application wants to receive. + * @note It is valid only in TCP server or client mode. It can't receive data + * greater than socket buffer size. \n In block io mode, it doesn't return until + * data reception is completed - data is filled as len in socket buffer. + * \n In non-block io mode, it return @ref SOCK_BUSY immediately when len + * is greater than data size in socket buffer. \n + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer to read incoming data. + * @param len The max data length of data in buf. + * @return @b Success : The real received data size \n + * @b Fail :\n + * @ref SOCKERR_SOCKSTATUS - Invalid socket status for + * socket operation \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the socket + * \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t wiz_sock_recv(uint8_t sn, uint8_t *buf, uint16_t len); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Sends datagram to the peer with destination IP address and port + * number passed as parameter. + * @details It sends datagram of UDP or MACRAW to the peer with destination IP + * address and port number passed as parameter.\n Even if the connectionless + * socket has been previously connected to a specific address, the address and + * port number parameters override the destination address for that particular + * datagram only. + * @note In block io mode, It doesn't return until data send is completed - + * socket buffer size is greater than len. In non-block io mode, It + * return @ref SOCK_BUSY immediately when socket buffer is not enough. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer to send outgoing data. + * @param len The byte length of data in buf. + * @param addr Pointer variable of destination IP address. It should be + * allocated 4 bytes. + * @param port Destination port number. + * + * @return @b Success : The sent data size \n + * @b Fail :\n @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the + * socket \n + * @ref SOCKERR_SOCKSTATUS - Invalid socket status for + * socket operation \n + * @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCKERR_IPINVALID - Wrong server IP address\n + * @ref SOCKERR_PORTZERO - Server port zero\n + * @ref SOCKERR_SOCKCLOSED - Socket unexpectedly closed + * \n + * @ref SOCKERR_TIMEOUT - Timeout occurred \n + * @ref SOCK_BUSY - Socket is busy. + */ +int32_t wiz_sock_sendto(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *addr, + uint16_t port); + +/** + * @ingroup WIZnet_socket_APIs + * @brief Receive datagram of UDP or MACRAW + * @details This function is an application I/F function which is used to + * receive the data in other then TCP mode. \n This function is used to receive + * UDP and MAC_RAW mode, and handle the header as well. This function can divide + * to received the packet data. On the MACRAW SOCKET, the addr and port + * parameters are ignored. + * @note In block io mode, it doesn't return until data reception is + * completed - data is filled as len in socket buffer In non-block io + * mode, it return @ref SOCK_BUSY immediately when len is greater than + * data size in socket buffer. + * + * @param sn Socket number. It should be 0 ~ @ref \_WIZCHIP_SOCK_NUM_. + * @param buf Pointer buffer to read incoming data. + * @param len The max data length of data in buf. + * When the received packet size <= len, receives data as packet + * sized. When others, receives data as len. + * @param addr Pointer variable of destination IP address. It should be + * allocated 4 bytes. It is valid only when the first call recvfrom for + * receiving the packet. When it is valid, @ref packinfo[7] should be set as + * '1' after call @ref getsockopt(sn, SO_PACKINFO, &packinfo). + * @param port Pointer variable of destination port number. + * It is valid only when the first call recvform for receiving the + * packet. When it is valid, @ref packinfo[7] should be set as '1' after call + * @ref getsockopt(sn, SO_PACKINFO, &packinfo). + * + * @return @b Success : This function return real received data size for + * success.\n + * @b Fail : @ref SOCKERR_DATALEN - zero data length \n + * @ref SOCKERR_SOCKMODE - Invalid operation in the + * socket \n + * @ref SOCKERR_SOCKNUM - Invalid socket number \n + * @ref SOCKBUSY - Socket is busy. + */ +int32_t wiz_sock_recvfrom(uint8_t sn, uint8_t *buf, uint16_t len, uint8_t *addr, + uint16_t *port); + +///////////////////////////// +// SOCKET CONTROL & OPTION // +///////////////////////////// +#define SOCK_IO_BLOCK 0 ///< Socket Block IO Mode in @ref setsockopt(). +#define SOCK_IO_NONBLOCK 1 ///< Socket Non-block IO Mode in @ref setsockopt(). + +/** + * @defgroup DATA_TYPE DATA TYPE + */ + +/** + * @ingroup DATA_TYPE + * @brief The kind of Socket Interrupt. + * @sa Sn_IR, Sn_IMR, setSn_IR(), getSn_IR(), setSn_IMR(), getSn_IMR() + */ +typedef enum { + SIK_CONNECTED = (1 << 0), ///< connected + SIK_DISCONNECTED = (1 << 1), ///< disconnected + SIK_RECEIVED = (1 << 2), ///< data received + SIK_TIMEOUT = (1 << 3), ///< timeout occurred + SIK_SENT = (1 << 4), ///< send ok + // M20150410 : Remove the comma of last member + // SIK_ALL = 0x1F, ///< all interrupt + SIK_ALL = 0x1F ///< all interrupt +} sockint_kind; + +/** + * @ingroup DATA_TYPE + * @brief The type of @ref ctlsocket(). + */ +typedef enum { + CS_SET_IOMODE, ///< set socket IO mode with @ref SOCK_IO_BLOCK or @ref + ///< SOCK_IO_NONBLOCK + CS_GET_IOMODE, ///< get socket IO mode + CS_GET_MAXTXBUF, ///< get the size of socket buffer allocated in TX memory + CS_GET_MAXRXBUF, ///< get the size of socket buffer allocated in RX memory + CS_CLR_INTERRUPT, ///< clear the interrupt of socket with @ref sockint_kind + CS_GET_INTERRUPT, ///< get the socket interrupt. refer to @ref sockint_kind +#if _WIZCHIP_ > 5100 + CS_SET_INTMASK, ///< set the interrupt mask of socket with @ref sockint_kind, + ///< Not supported in W5100 + CS_GET_INTMASK ///< get the masked interrupt of socket. refer to @ref + ///< sockint_kind, Not supported in W5100 +#endif +} ctlsock_type; + +/** + * @ingroup DATA_TYPE + * @brief The type of socket option in @ref setsockopt() or @ref getsockopt() + */ +typedef enum { + SO_FLAG, ///< Valid only in getsockopt(), For set flag of socket refer to + ///< flag in @ref socket(). + SO_TTL, ///< Set TTL. @ref Sn_TTL ( @ref setSn_TTL(), @ref getSn_TTL() ) + SO_TOS, ///< Set TOS. @ref Sn_TOS ( @ref setSn_TOS(), @ref getSn_TOS() ) + SO_MSS, ///< Set MSS. @ref Sn_MSSR ( @ref setSn_MSSR(), @ref getSn_MSSR() ) + SO_DESTIP, ///< Set the destination IP address. @ref Sn_DIPR ( @ref + ///< setSn_DIPR(), @ref getSn_DIPR() ) + SO_DESTPORT, ///< Set the destination Port number. @ref Sn_DPORT ( @ref + ///< setSn_DPORT(), @ref getSn_DPORT() ) +#if _WIZCHIP_ != 5100 + SO_KEEPALIVESEND, ///< Valid only in setsockopt. Manually send keep-alive + ///< packet in TCP mode, Not supported in W5100 +#if !((_WIZCHIP_ == 5100) || (_WIZCHIP_ == 5200)) + SO_KEEPALIVEAUTO, ///< Set/Get keep-alive auto transmission timer in TCP + ///< mode, Not supported in W5100, W5200 +#endif +#endif + SO_SENDBUF, ///< Valid only in getsockopt. Get the free data size of Socekt + ///< TX buffer. @ref Sn_TX_FSR, @ref getSn_TX_FSR() + SO_RECVBUF, ///< Valid only in getsockopt. Get the received data size in + ///< socket RX buffer. @ref Sn_RX_RSR, @ref getSn_RX_RSR() + SO_STATUS, ///< Valid only in getsockopt. Get the socket status. @ref Sn_SR, + ///< @ref getSn_SR() + SO_REMAINSIZE, ///< Valid only in getsockopt. Get the remained packet size in + ///< other then TCP mode. + SO_PACKINFO ///< Valid only in getsockopt. Get the packet information as @ref + ///< PACK_FIRST, @ref PACK_REMAINED, and @ref PACK_COMPLETED in + ///< other then TCP mode. +} sockopt_type; + +/** + * @ingroup WIZnet_socket_APIs + * @brief Control socket. + * @details Control IO mode, Interrupt & Mask of socket and get the socket + * buffer information. Refer to @ref ctlsock_type. + * @param sn socket number + * @param cstype type of control socket. refer to @ref ctlsock_type. + * @param arg Data type and value is determined according to @ref ctlsock_type. + * \n + *
@b cstype @b data type@b + * value
@ref CS_SET_IOMODE \n @ref CS_GET_IOMODE + * uint8_t @ref SOCK_IO_BLOCK @ref SOCK_IO_NONBLOCK
+ * @ref CS_GET_MAXTXBUF \n @ref CS_GET_MAXRXBUF uint16_t 0 + * ~ 16K
@ref CS_CLR_INTERRUPT \n @ref CS_GET_INTERRUPT \n + * @ref CS_SET_INTMASK \n @ref CS_GET_INTMASK @ref sockint_kind + * @ref SIK_CONNECTED, etc.
+ * @return @b Success @ref SOCK_OK \n + * @b fail @ref SOCKERR_ARG - Invalid argument\n + */ +int8_t wiz_ctlsocket(uint8_t sn, ctlsock_type cstype, void *arg); + +/** + * @ingroup WIZnet_socket_APIs + * @brief set socket options + * @details Set socket option like as TTL, MSS, TOS, and so on. Refer to @ref + * sockopt_type. + * + * @param sn socket number + * @param sotype socket option type. refer to @ref sockopt_type + * @param arg Data type and value is determined according to sotype. \n + * + * + * + * + * + *
@b sotype @b data type@b + * value
@ref SO_TTL uint8_t 0 ~ 255 + *
@ref SO_TOS uint8_t 0 ~ 255
@ref SO_MSS uint16_t 0 ~ 65535
@ref SO_DESTIP uint8_t[4]
@ref SO_DESTPORT uint16_t 0 ~ + * 65535
@ref SO_KEEPALIVESEND null + * null
@ref SO_KEEPALIVEAUTO uint8_t + * 0 ~ 255
+ * @return + * - @b Success : @ref SOCK_OK \n + * - @b Fail + * - @ref SOCKERR_SOCKNUM - Invalid Socket number \n + * - @ref SOCKERR_SOCKMODE - Invalid socket mode \n + * - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n + * - @ref SOCKERR_TIMEOUT - Timeout occurred when sending keep-alive packet + * \n + */ +int8_t wiz_setsockopt(uint8_t sn, sockopt_type sotype, void *arg); + +/** + * @ingroup WIZnet_socket_APIs + * @brief get socket options + * @details Get socket option like as FLAG, TTL, MSS, and so on. Refer to @ref + * sockopt_type + * @param sn socket number + * @param sotype socket option type. refer to @ref sockopt_type + * @param arg Data type and value is determined according to sotype. \n + * + * + *
@b sotype @b data type@b + * value
@ref SO_FLAG uint8_t @ref + * SF_ETHER_OWN, etc...
@ref SO_TOS uint8_t + * 0 ~ 255
@ref SO_MSS uint16_t + * 0 ~ 65535
@ref SO_DESTIP + * uint8_t[4]
@ref SO_DESTPORT + * uint16_t
@ref SO_KEEPALIVEAUTO + * uint8_t 0 ~ 255
@ref SO_SENDBUF + * uint16_t 0 ~ 65535
@ref SO_RECVBUF + * uint16_t 0 ~ 65535
@ref SO_STATUS + * uint8_t @ref SOCK_ESTABLISHED, etc..
@ref + * SO_REMAINSIZE uint16_t 0~ 65535
+ * @ref SO_PACKINFO uint8_t @ref PACK_FIRST, etc... + *
+ * @return + * - @b Success : @ref SOCK_OK \n + * - @b Fail + * - @ref SOCKERR_SOCKNUM - Invalid Socket number \n + * - @ref SOCKERR_SOCKOPT - Invalid socket option or its value \n + * - @ref SOCKERR_SOCKMODE - Invalid socket mode \n + * @note + * The option as PACK_REMAINED and SO_PACKINFO is valid only in NON-TCP mode + * and after call @ref recvfrom(). \n When SO_PACKINFO value is PACK_FIRST and + * the return value of recvfrom() is zero, This means the zero byte UDP data(UDP + * Header only) received. + */ +int8_t wiz_getsockopt(uint8_t sn, sockopt_type sotype, void *arg); + +#ifdef __cplusplus +} +#endif + +#endif // _SOCKET_H_ \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/sysctl.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/sysctl.h new file mode 100644 index 000000000..927b1a063 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/sysctl.h @@ -0,0 +1,1088 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file sysctl.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#ifndef __SYSCTL_H__ +#define __SYSCTL_H__ + +#include +#include "platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief System controller register + * + * @note System controller register table + * + * | Offset | Name | Description | + * |-----------|----------------|-------------------------------------| + * | 0x00 | git_id | Git short commit id | + * | 0x04 | clk_freq | System clock base frequency | + * | 0x08 | pll0 | PLL0 controller | + * | 0x0c | pll1 | PLL1 controller | + * | 0x10 | pll2 | PLL2 controller | + * | 0x14 | resv5 | Reserved | + * | 0x18 | pll_lock | PLL lock tester | + * | 0x1c | rom_error | AXI ROM detector | + * | 0x20 | clk_sel0 | Clock select controller0 | + * | 0x24 | clk_sel1 | Clock select controller1 | + * | 0x28 | clk_en_cent | Central clock enable | + * | 0x2c | clk_en_peri | Peripheral clock enable | + * | 0x30 | soft_reset | Soft reset ctrl | + * | 0x34 | peri_reset | Peripheral reset controller | + * | 0x38 | clk_th0 | Clock threshold controller 0 | + * | 0x3c | clk_th1 | Clock threshold controller 1 | + * | 0x40 | clk_th2 | Clock threshold controller 2 | + * | 0x44 | clk_th3 | Clock threshold controller 3 | + * | 0x48 | clk_th4 | Clock threshold controller 4 | + * | 0x4c | clk_th5 | Clock threshold controller 5 | + * | 0x50 | clk_th6 | Clock threshold controller 6 | + * | 0x54 | misc | Miscellaneous controller | + * | 0x58 | peri | Peripheral controller | + * | 0x5c | spi_sleep | SPI sleep controller | + * | 0x60 | reset_status | Reset source status | + * | 0x64 | dma_sel0 | DMA handshake selector | + * | 0x68 | dma_sel1 | DMA handshake selector | + * | 0x6c | power_sel | IO Power Mode Select controller | + * | 0x70 | resv28 | Reserved | + * | 0x74 | resv29 | Reserved | + * | 0x78 | resv30 | Reserved | + * | 0x7c | resv31 | Reserved | + * + */ + +typedef enum _sysctl_pll_t +{ + SYSCTL_PLL0, + SYSCTL_PLL1, + SYSCTL_PLL2, + SYSCTL_PLL_MAX +} sysctl_pll_t; + +typedef enum _sysctl_clock_source_t +{ + SYSCTL_SOURCE_IN0, + SYSCTL_SOURCE_PLL0, + SYSCTL_SOURCE_PLL1, + SYSCTL_SOURCE_PLL2, + SYSCTL_SOURCE_ACLK, + SYSCTL_SOURCE_MAX +} sysctl_clock_source_t; + +typedef enum _sysctl_dma_channel_t +{ + SYSCTL_DMA_CHANNEL_0, + SYSCTL_DMA_CHANNEL_1, + SYSCTL_DMA_CHANNEL_2, + SYSCTL_DMA_CHANNEL_3, + SYSCTL_DMA_CHANNEL_4, + SYSCTL_DMA_CHANNEL_5, + SYSCTL_DMA_CHANNEL_MAX +} sysctl_dma_channel_t; + +typedef enum _sysctl_dma_select_t +{ + SYSCTL_DMA_SELECT_SSI0_RX_REQ, + SYSCTL_DMA_SELECT_SSI0_TX_REQ, + SYSCTL_DMA_SELECT_SSI1_RX_REQ, + SYSCTL_DMA_SELECT_SSI1_TX_REQ, + SYSCTL_DMA_SELECT_SSI2_RX_REQ, + SYSCTL_DMA_SELECT_SSI2_TX_REQ, + SYSCTL_DMA_SELECT_SSI3_RX_REQ, + SYSCTL_DMA_SELECT_SSI3_TX_REQ, + SYSCTL_DMA_SELECT_I2C0_RX_REQ, + SYSCTL_DMA_SELECT_I2C0_TX_REQ, + SYSCTL_DMA_SELECT_I2C1_RX_REQ, + SYSCTL_DMA_SELECT_I2C1_TX_REQ, + SYSCTL_DMA_SELECT_I2C2_RX_REQ, + SYSCTL_DMA_SELECT_I2C2_TX_REQ, + SYSCTL_DMA_SELECT_UART1_RX_REQ, + SYSCTL_DMA_SELECT_UART1_TX_REQ, + SYSCTL_DMA_SELECT_UART2_RX_REQ, + SYSCTL_DMA_SELECT_UART2_TX_REQ, + SYSCTL_DMA_SELECT_UART3_RX_REQ, + SYSCTL_DMA_SELECT_UART3_TX_REQ, + SYSCTL_DMA_SELECT_AES_REQ, + SYSCTL_DMA_SELECT_SHA_RX_REQ, + SYSCTL_DMA_SELECT_AI_RX_REQ, + SYSCTL_DMA_SELECT_FFT_RX_REQ, + SYSCTL_DMA_SELECT_FFT_TX_REQ, + SYSCTL_DMA_SELECT_I2S0_TX_REQ, + SYSCTL_DMA_SELECT_I2S0_RX_REQ, + SYSCTL_DMA_SELECT_I2S1_TX_REQ, + SYSCTL_DMA_SELECT_I2S1_RX_REQ, + SYSCTL_DMA_SELECT_I2S2_TX_REQ, + SYSCTL_DMA_SELECT_I2S2_RX_REQ, + SYSCTL_DMA_SELECT_I2S0_BF_DIR_REQ, + SYSCTL_DMA_SELECT_I2S0_BF_VOICE_REQ, + SYSCTL_DMA_SELECT_MAX +} sysctl_dma_select_t; + +/** + * @brief System controller clock id + */ +typedef enum _sysctl_clock_t +{ + SYSCTL_CLOCK_PLL0, + SYSCTL_CLOCK_PLL1, + SYSCTL_CLOCK_PLL2, + SYSCTL_CLOCK_CPU, + SYSCTL_CLOCK_SRAM0, + SYSCTL_CLOCK_SRAM1, + SYSCTL_CLOCK_APB0, + SYSCTL_CLOCK_APB1, + SYSCTL_CLOCK_APB2, + SYSCTL_CLOCK_ROM, + SYSCTL_CLOCK_DMA, + SYSCTL_CLOCK_AI, + SYSCTL_CLOCK_DVP, + SYSCTL_CLOCK_FFT, + SYSCTL_CLOCK_GPIO, + SYSCTL_CLOCK_SPI0, + SYSCTL_CLOCK_SPI1, + SYSCTL_CLOCK_SPI2, + SYSCTL_CLOCK_SPI3, + SYSCTL_CLOCK_I2S0, + SYSCTL_CLOCK_I2S1, + SYSCTL_CLOCK_I2S2, + SYSCTL_CLOCK_I2C0, + SYSCTL_CLOCK_I2C1, + SYSCTL_CLOCK_I2C2, + SYSCTL_CLOCK_UART1, + SYSCTL_CLOCK_UART2, + SYSCTL_CLOCK_UART3, + SYSCTL_CLOCK_AES, + SYSCTL_CLOCK_FPIOA, + SYSCTL_CLOCK_TIMER0, + SYSCTL_CLOCK_TIMER1, + SYSCTL_CLOCK_TIMER2, + SYSCTL_CLOCK_WDT0, + SYSCTL_CLOCK_WDT1, + SYSCTL_CLOCK_SHA, + SYSCTL_CLOCK_OTP, + SYSCTL_CLOCK_RTC, + SYSCTL_CLOCK_ACLK = 40, + SYSCTL_CLOCK_HCLK, + SYSCTL_CLOCK_IN0, + SYSCTL_CLOCK_MAX +} sysctl_clock_t; + +/** + * @brief System controller clock select id + */ +typedef enum _sysctl_clock_select_t +{ + SYSCTL_CLOCK_SELECT_PLL0_BYPASS, + SYSCTL_CLOCK_SELECT_PLL1_BYPASS, + SYSCTL_CLOCK_SELECT_PLL2_BYPASS, + SYSCTL_CLOCK_SELECT_PLL2, + SYSCTL_CLOCK_SELECT_ACLK, + SYSCTL_CLOCK_SELECT_SPI3, + SYSCTL_CLOCK_SELECT_TIMER0, + SYSCTL_CLOCK_SELECT_TIMER1, + SYSCTL_CLOCK_SELECT_TIMER2, + SYSCTL_CLOCK_SELECT_SPI3_SAMPLE, + SYSCTL_CLOCK_SELECT_MAX = 11 +} sysctl_clock_select_t; + +/** + * @brief System controller clock threshold id + */ +typedef enum _sysctl_threshold_t +{ + SYSCTL_THRESHOLD_ACLK, + SYSCTL_THRESHOLD_APB0, + SYSCTL_THRESHOLD_APB1, + SYSCTL_THRESHOLD_APB2, + SYSCTL_THRESHOLD_SRAM0, + SYSCTL_THRESHOLD_SRAM1, + SYSCTL_THRESHOLD_AI, + SYSCTL_THRESHOLD_DVP, + SYSCTL_THRESHOLD_ROM, + SYSCTL_THRESHOLD_SPI0, + SYSCTL_THRESHOLD_SPI1, + SYSCTL_THRESHOLD_SPI2, + SYSCTL_THRESHOLD_SPI3, + SYSCTL_THRESHOLD_TIMER0, + SYSCTL_THRESHOLD_TIMER1, + SYSCTL_THRESHOLD_TIMER2, + SYSCTL_THRESHOLD_I2S0, + SYSCTL_THRESHOLD_I2S1, + SYSCTL_THRESHOLD_I2S2, + SYSCTL_THRESHOLD_I2S0_M, + SYSCTL_THRESHOLD_I2S1_M, + SYSCTL_THRESHOLD_I2S2_M, + SYSCTL_THRESHOLD_I2C0, + SYSCTL_THRESHOLD_I2C1, + SYSCTL_THRESHOLD_I2C2, + SYSCTL_THRESHOLD_WDT0, + SYSCTL_THRESHOLD_WDT1, + SYSCTL_THRESHOLD_MAX = 28 +} sysctl_threshold_t; + +/** + * @brief System controller reset control id + */ +typedef enum _sysctl_reset_t +{ + SYSCTL_RESET_SOC, + SYSCTL_RESET_ROM, + SYSCTL_RESET_DMA, + SYSCTL_RESET_AI, + SYSCTL_RESET_DVP, + SYSCTL_RESET_FFT, + SYSCTL_RESET_GPIO, + SYSCTL_RESET_SPI0, + SYSCTL_RESET_SPI1, + SYSCTL_RESET_SPI2, + SYSCTL_RESET_SPI3, + SYSCTL_RESET_I2S0, + SYSCTL_RESET_I2S1, + SYSCTL_RESET_I2S2, + SYSCTL_RESET_I2C0, + SYSCTL_RESET_I2C1, + SYSCTL_RESET_I2C2, + SYSCTL_RESET_UART1, + SYSCTL_RESET_UART2, + SYSCTL_RESET_UART3, + SYSCTL_RESET_AES, + SYSCTL_RESET_FPIOA, + SYSCTL_RESET_TIMER0, + SYSCTL_RESET_TIMER1, + SYSCTL_RESET_TIMER2, + SYSCTL_RESET_WDT0, + SYSCTL_RESET_WDT1, + SYSCTL_RESET_SHA, + SYSCTL_RESET_RTC, + SYSCTL_RESET_MAX = 31 +} sysctl_reset_t; + +/** + * @brief System controller power bank id + */ +typedef enum _sysctl_power_bank +{ + SYSCTL_POWER_BANK0, + SYSCTL_POWER_BANK1, + SYSCTL_POWER_BANK2, + SYSCTL_POWER_BANK3, + SYSCTL_POWER_BANK4, + SYSCTL_POWER_BANK5, + SYSCTL_POWER_BANK6, + SYSCTL_POWER_BANK7, + SYSCTL_POWER_BANK_MAX, +} sysctl_power_bank_t; + +/** + * @brief System controller reset control id + */ +typedef enum _sysctl_io_power_mode +{ + SYSCTL_POWER_V33, + SYSCTL_POWER_V18 +} sysctl_io_power_mode_t; + +/** + * @brief System reset status + */ +typedef enum _sysctl_reset_enum_status +{ + SYSCTL_RESET_STATUS_HARD, + SYSCTL_RESET_STATUS_SOFT, + SYSCTL_RESET_STATUS_WDT0, + SYSCTL_RESET_STATUS_WDT1, + SYSCTL_RESET_STATUS_MAX, +} sysctl_reset_enum_status_t; + +/** + * @brief Git short commit id + * + * No. 0 Register (0x00) + */ +typedef struct _sysctl_git_id +{ + uint32_t git_id : 32; +} __attribute__((packed, aligned(4))) sysctl_git_id_t; + +/** + * @brief System clock base frequency + * + * No. 1 Register (0x04) + */ +typedef struct _sysctl_clk_freq +{ + uint32_t clk_freq : 32; +} __attribute__((packed, aligned(4))) sysctl_clk_freq_t; + +/** + * @brief PLL0 controller + * + * No. 2 Register (0x08) + */ +typedef struct _sysctl_pll0 +{ + uint32_t clkr0 : 4; + uint32_t clkf0 : 6; + uint32_t clkod0 : 4; + uint32_t bwadj0 : 6; + uint32_t pll_reset0 : 1; + uint32_t pll_pwrd0 : 1; + uint32_t pll_intfb0 : 1; + uint32_t pll_bypass0 : 1; + uint32_t pll_test0 : 1; + uint32_t pll_out_en0 : 1; + uint32_t pll_test_en : 1; + uint32_t reserved : 5; +} __attribute__((packed, aligned(4))) sysctl_pll0_t; + +/** + * @brief PLL1 controller + * + * No. 3 Register (0x0c) + */ +typedef struct _sysctl_pll1 +{ + uint32_t clkr1 : 4; + uint32_t clkf1 : 6; + uint32_t clkod1 : 4; + uint32_t bwadj1 : 6; + uint32_t pll_reset1 : 1; + uint32_t pll_pwrd1 : 1; + uint32_t pll_intfb1 : 1; + uint32_t pll_bypass1 : 1; + uint32_t pll_test1 : 1; + uint32_t pll_out_en1 : 1; + uint32_t reserved : 6; +} __attribute__((packed, aligned(4))) sysctl_pll1_t; + +/** + * @brief PLL2 controller + * + * No. 4 Register (0x10) + */ +typedef struct _sysctl_pll2 +{ + uint32_t clkr2 : 4; + uint32_t clkf2 : 6; + uint32_t clkod2 : 4; + uint32_t bwadj2 : 6; + uint32_t pll_reset2 : 1; + uint32_t pll_pwrd2 : 1; + uint32_t pll_intfb2 : 1; + uint32_t pll_bypass2 : 1; + uint32_t pll_test2 : 1; + uint32_t pll_out_en2 : 1; + uint32_t pll_ckin_sel2 : 2; + uint32_t reserved : 4; +} __attribute__((packed, aligned(4))) sysctl_pll2_t; + +/** + * @brief PLL lock tester + * + * No. 6 Register (0x18) + */ +typedef struct _sysctl_pll_lock +{ + uint32_t pll_lock0 : 2; + uint32_t pll_slip_clear0 : 1; + uint32_t test_clk_out0 : 1; + uint32_t reserved0 : 4; + uint32_t pll_lock1 : 2; + uint32_t pll_slip_clear1 : 1; + uint32_t test_clk_out1 : 1; + uint32_t reserved1 : 4; + uint32_t pll_lock2 : 2; + uint32_t pll_slip_clear2 : 1; + uint32_t test_clk_out2 : 1; + uint32_t reserved2 : 12; +} __attribute__((packed, aligned(4))) sysctl_pll_lock_t; + +/** + * @brief AXI ROM detector + * + * No. 7 Register (0x1c) + */ +typedef struct _sysctl_rom_error +{ + uint32_t rom_mul_error : 1; + uint32_t rom_one_error : 1; + uint32_t reserved : 30; +} __attribute__((packed, aligned(4))) sysctl_rom_error_t; + +/** + * @brief Clock select controller0 + * + * No. 8 Register (0x20) + */ +typedef struct _sysctl_clk_sel0 +{ + uint32_t aclk_sel : 1; + uint32_t aclk_divider_sel : 2; + uint32_t apb0_clk_sel : 3; + uint32_t apb1_clk_sel : 3; + uint32_t apb2_clk_sel : 3; + uint32_t spi3_clk_sel : 1; + uint32_t timer0_clk_sel : 1; + uint32_t timer1_clk_sel : 1; + uint32_t timer2_clk_sel : 1; + uint32_t reserved : 16; +} __attribute__((packed, aligned(4))) sysctl_clk_sel0_t; + +/** + * @brief Clock select controller1 + * + * No. 9 Register (0x24) + */ +typedef struct _sysctl_clk_sel1 +{ + uint32_t spi3_sample_clk_sel : 1; + uint32_t reserved0 : 30; + uint32_t reserved1 : 1; +} __attribute__((packed, aligned(4))) sysctl_clk_sel1_t; + +/** + * @brief Central clock enable + * + * No. 10 Register (0x28) + */ +typedef struct _sysctl_clk_en_cent +{ + uint32_t cpu_clk_en : 1; + uint32_t sram0_clk_en : 1; + uint32_t sram1_clk_en : 1; + uint32_t apb0_clk_en : 1; + uint32_t apb1_clk_en : 1; + uint32_t apb2_clk_en : 1; + uint32_t reserved : 26; +} __attribute__((packed, aligned(4))) sysctl_clk_en_cent_t; + +/** + * @brief Peripheral clock enable + * + * No. 11 Register (0x2c) + */ +typedef struct _sysctl_clk_en_peri +{ + uint32_t rom_clk_en : 1; + uint32_t dma_clk_en : 1; + uint32_t ai_clk_en : 1; + uint32_t dvp_clk_en : 1; + uint32_t fft_clk_en : 1; + uint32_t gpio_clk_en : 1; + uint32_t spi0_clk_en : 1; + uint32_t spi1_clk_en : 1; + uint32_t spi2_clk_en : 1; + uint32_t spi3_clk_en : 1; + uint32_t i2s0_clk_en : 1; + uint32_t i2s1_clk_en : 1; + uint32_t i2s2_clk_en : 1; + uint32_t i2c0_clk_en : 1; + uint32_t i2c1_clk_en : 1; + uint32_t i2c2_clk_en : 1; + uint32_t uart1_clk_en : 1; + uint32_t uart2_clk_en : 1; + uint32_t uart3_clk_en : 1; + uint32_t aes_clk_en : 1; + uint32_t fpioa_clk_en : 1; + uint32_t timer0_clk_en : 1; + uint32_t timer1_clk_en : 1; + uint32_t timer2_clk_en : 1; + uint32_t wdt0_clk_en : 1; + uint32_t wdt1_clk_en : 1; + uint32_t sha_clk_en : 1; + uint32_t otp_clk_en : 1; + uint32_t reserved : 1; + uint32_t rtc_clk_en : 1; + uint32_t reserved0 : 2; +} __attribute__((packed, aligned(4))) sysctl_clk_en_peri_t; + +/** + * @brief Soft reset ctrl + * + * No. 12 Register (0x30) + */ +typedef struct _sysctl_soft_reset +{ + uint32_t soft_reset : 1; + uint32_t reserved : 31; +} __attribute__((packed, aligned(4))) sysctl_soft_reset_t; + +/** + * @brief Peripheral reset controller + * + * No. 13 Register (0x34) + */ +typedef struct _sysctl_peri_reset +{ + uint32_t rom_reset : 1; + uint32_t dma_reset : 1; + uint32_t ai_reset : 1; + uint32_t dvp_reset : 1; + uint32_t fft_reset : 1; + uint32_t gpio_reset : 1; + uint32_t spi0_reset : 1; + uint32_t spi1_reset : 1; + uint32_t spi2_reset : 1; + uint32_t spi3_reset : 1; + uint32_t i2s0_reset : 1; + uint32_t i2s1_reset : 1; + uint32_t i2s2_reset : 1; + uint32_t i2c0_reset : 1; + uint32_t i2c1_reset : 1; + uint32_t i2c2_reset : 1; + uint32_t uart1_reset : 1; + uint32_t uart2_reset : 1; + uint32_t uart3_reset : 1; + uint32_t aes_reset : 1; + uint32_t fpioa_reset : 1; + uint32_t timer0_reset : 1; + uint32_t timer1_reset : 1; + uint32_t timer2_reset : 1; + uint32_t wdt0_reset : 1; + uint32_t wdt1_reset : 1; + uint32_t sha_reset : 1; + uint32_t reserved : 2; + uint32_t rtc_reset : 1; + uint32_t reserved0 : 2; +} __attribute__((packed, aligned(4))) sysctl_peri_reset_t; + +/** + * @brief Clock threshold controller 0 + * + * No. 14 Register (0x38) + */ +typedef struct _sysctl_clk_th0 +{ + uint32_t sram0_gclk_threshold : 4; + uint32_t sram1_gclk_threshold : 4; + uint32_t ai_gclk_threshold : 4; + uint32_t dvp_gclk_threshold : 4; + uint32_t rom_gclk_threshold : 4; + uint32_t reserved : 12; +} __attribute__((packed, aligned(4))) sysctl_clk_th0_t; + +/** + * @brief Clock threshold controller 1 + * + * No. 15 Register (0x3c) + */ +typedef struct _sysctl_clk_th1 +{ + uint32_t spi0_clk_threshold : 8; + uint32_t spi1_clk_threshold : 8; + uint32_t spi2_clk_threshold : 8; + uint32_t spi3_clk_threshold : 8; +} __attribute__((packed, aligned(4))) sysctl_clk_th1_t; + +/** + * @brief Clock threshold controller 2 + * + * No. 16 Register (0x40) + */ +typedef struct _sysctl_clk_th2 +{ + uint32_t timer0_clk_threshold : 8; + uint32_t timer1_clk_threshold : 8; + uint32_t timer2_clk_threshold : 8; + uint32_t reserved : 8; +} __attribute__((packed, aligned(4))) sysctl_clk_th2_t; + +/** + * @brief Clock threshold controller 3 + * + * No. 17 Register (0x44) + */ +typedef struct _sysctl_clk_th3 +{ + uint32_t i2s0_clk_threshold : 16; + uint32_t i2s1_clk_threshold : 16; +} __attribute__((packed, aligned(4))) sysctl_clk_th3_t; + +/** + * @brief Clock threshold controller 4 + * + * No. 18 Register (0x48) + */ +typedef struct _sysctl_clk_th4 +{ + uint32_t i2s2_clk_threshold : 16; + uint32_t i2s0_mclk_threshold : 8; + uint32_t i2s1_mclk_threshold : 8; +} __attribute__((packed, aligned(4))) sysctl_clk_th4_t; + +/** + * @brief Clock threshold controller 5 + * + * No. 19 Register (0x4c) + */ +typedef struct _sysctl_clk_th5 +{ + uint32_t i2s2_mclk_threshold : 8; + uint32_t i2c0_clk_threshold : 8; + uint32_t i2c1_clk_threshold : 8; + uint32_t i2c2_clk_threshold : 8; +} __attribute__((packed, aligned(4))) sysctl_clk_th5_t; + +/** + * @brief Clock threshold controller 6 + * + * No. 20 Register (0x50) + */ +typedef struct _sysctl_clk_th6 +{ + uint32_t wdt0_clk_threshold : 8; + uint32_t wdt1_clk_threshold : 8; + uint32_t reserved0 : 8; + uint32_t reserved1 : 8; +} __attribute__((packed, aligned(4))) sysctl_clk_th6_t; + +/** + * @brief Miscellaneous controller + * + * No. 21 Register (0x54) + */ +typedef struct _sysctl_misc +{ + uint32_t debug_sel : 6; + uint32_t reserved0 : 4; + uint32_t spi_dvp_data_enable: 1; + uint32_t reserved1 : 21; +} __attribute__((packed, aligned(4))) sysctl_misc_t; + +/** + * @brief Peripheral controller + * + * No. 22 Register (0x58) + */ +typedef struct _sysctl_peri +{ + uint32_t timer0_pause : 1; + uint32_t timer1_pause : 1; + uint32_t timer2_pause : 1; + uint32_t timer3_pause : 1; + uint32_t timer4_pause : 1; + uint32_t timer5_pause : 1; + uint32_t timer6_pause : 1; + uint32_t timer7_pause : 1; + uint32_t timer8_pause : 1; + uint32_t timer9_pause : 1; + uint32_t timer10_pause : 1; + uint32_t timer11_pause : 1; + uint32_t spi0_xip_en : 1; + uint32_t spi1_xip_en : 1; + uint32_t spi2_xip_en : 1; + uint32_t spi3_xip_en : 1; + uint32_t spi0_clk_bypass : 1; + uint32_t spi1_clk_bypass : 1; + uint32_t spi2_clk_bypass : 1; + uint32_t i2s0_clk_bypass : 1; + uint32_t i2s1_clk_bypass : 1; + uint32_t i2s2_clk_bypass : 1; + uint32_t jtag_clk_bypass : 1; + uint32_t dvp_clk_bypass : 1; + uint32_t debug_clk_bypass : 1; + uint32_t reserved0 : 1; + uint32_t reserved1 : 6; +} __attribute__((packed, aligned(4))) sysctl_peri_t; + +/** + * @brief SPI sleep controller + * + * No. 23 Register (0x5c) + */ +typedef struct _sysctl_spi_sleep +{ + uint32_t ssi0_sleep : 1; + uint32_t ssi1_sleep : 1; + uint32_t ssi2_sleep : 1; + uint32_t ssi3_sleep : 1; + uint32_t reserved : 28; +} __attribute__((packed, aligned(4))) sysctl_spi_sleep_t; + +/** + * @brief Reset source status + * + * No. 24 Register (0x60) + */ +typedef struct _sysctl_reset_status +{ + uint32_t reset_sts_clr : 1; + uint32_t pin_reset_sts : 1; + uint32_t wdt0_reset_sts : 1; + uint32_t wdt1_reset_sts : 1; + uint32_t soft_reset_sts : 1; + uint32_t reserved : 27; +} __attribute__((packed, aligned(4))) sysctl_reset_status_t; + +/** + * @brief DMA handshake selector + * + * No. 25 Register (0x64) + */ +typedef struct _sysctl_dma_sel0 +{ + uint32_t dma_sel0 : 6; + uint32_t dma_sel1 : 6; + uint32_t dma_sel2 : 6; + uint32_t dma_sel3 : 6; + uint32_t dma_sel4 : 6; + uint32_t reserved : 2; +} __attribute__((packed, aligned(4))) sysctl_dma_sel0_t; + +/** + * @brief DMA handshake selector + * + * No. 26 Register (0x68) + */ +typedef struct _sysctl_dma_sel1 +{ + uint32_t dma_sel5 : 6; + uint32_t reserved : 26; +} __attribute__((packed, aligned(4))) sysctl_dma_sel1_t; + +/** + * @brief IO Power Mode Select controller + * + * No. 27 Register (0x6c) + */ +typedef struct _sysctl_power_sel +{ + uint32_t power_mode_sel0 : 1; + uint32_t power_mode_sel1 : 1; + uint32_t power_mode_sel2 : 1; + uint32_t power_mode_sel3 : 1; + uint32_t power_mode_sel4 : 1; + uint32_t power_mode_sel5 : 1; + uint32_t power_mode_sel6 : 1; + uint32_t power_mode_sel7 : 1; + uint32_t reserved : 24; +} __attribute__((packed, aligned(4))) sysctl_power_sel_t; + +/** + * @brief System controller object + * + * The System controller is a peripheral device mapped in the + * internal memory map, discoverable in the Configuration String. + * It is responsible for low-level configuration of all system + * related peripheral device. It contain PLL controller, clock + * controller, reset controller, DMA handshake controller, SPI + * controller, timer controller, WDT controller and sleep + * controller. + */ +typedef struct _sysctl +{ + /* No. 0 (0x00): Git short commit id */ + sysctl_git_id_t git_id; + /* No. 1 (0x04): System clock base frequency */ + sysctl_clk_freq_t clk_freq; + /* No. 2 (0x08): PLL0 controller */ + sysctl_pll0_t pll0; + /* No. 3 (0x0c): PLL1 controller */ + sysctl_pll1_t pll1; + /* No. 4 (0x10): PLL2 controller */ + sysctl_pll2_t pll2; + /* No. 5 (0x14): Reserved */ + uint32_t resv5; + /* No. 6 (0x18): PLL lock tester */ + sysctl_pll_lock_t pll_lock; + /* No. 7 (0x1c): AXI ROM detector */ + sysctl_rom_error_t rom_error; + /* No. 8 (0x20): Clock select controller0 */ + sysctl_clk_sel0_t clk_sel0; + /* No. 9 (0x24): Clock select controller1 */ + sysctl_clk_sel1_t clk_sel1; + /* No. 10 (0x28): Central clock enable */ + sysctl_clk_en_cent_t clk_en_cent; + /* No. 11 (0x2c): Peripheral clock enable */ + sysctl_clk_en_peri_t clk_en_peri; + /* No. 12 (0x30): Soft reset ctrl */ + sysctl_soft_reset_t soft_reset; + /* No. 13 (0x34): Peripheral reset controller */ + sysctl_peri_reset_t peri_reset; + /* No. 14 (0x38): Clock threshold controller 0 */ + sysctl_clk_th0_t clk_th0; + /* No. 15 (0x3c): Clock threshold controller 1 */ + sysctl_clk_th1_t clk_th1; + /* No. 16 (0x40): Clock threshold controller 2 */ + sysctl_clk_th2_t clk_th2; + /* No. 17 (0x44): Clock threshold controller 3 */ + sysctl_clk_th3_t clk_th3; + /* No. 18 (0x48): Clock threshold controller 4 */ + sysctl_clk_th4_t clk_th4; + /* No. 19 (0x4c): Clock threshold controller 5 */ + sysctl_clk_th5_t clk_th5; + /* No. 20 (0x50): Clock threshold controller 6 */ + sysctl_clk_th6_t clk_th6; + /* No. 21 (0x54): Miscellaneous controller */ + sysctl_misc_t misc; + /* No. 22 (0x58): Peripheral controller */ + sysctl_peri_t peri; + /* No. 23 (0x5c): SPI sleep controller */ + sysctl_spi_sleep_t spi_sleep; + /* No. 24 (0x60): Reset source status */ + sysctl_reset_status_t reset_status; + /* No. 25 (0x64): DMA handshake selector */ + sysctl_dma_sel0_t dma_sel0; + /* No. 26 (0x68): DMA handshake selector */ + sysctl_dma_sel1_t dma_sel1; + /* No. 27 (0x6c): IO Power Mode Select controller */ + sysctl_power_sel_t power_sel; + /* No. 28 (0x70): Reserved */ + uint32_t resv28; + /* No. 29 (0x74): Reserved */ + uint32_t resv29; + /* No. 30 (0x78): Reserved */ + uint32_t resv30; + /* No. 31 (0x7c): Reserved */ + uint32_t resv31; +} __attribute__((packed, aligned(4))) sysctl_t; + +/** + * @brief Abstruct PLL struct + */ +typedef struct _sysctl_general_pll +{ + uint32_t clkr : 4; + uint32_t clkf : 6; + uint32_t clkod : 4; + uint32_t bwadj : 6; + uint32_t pll_reset : 1; + uint32_t pll_pwrd : 1; + uint32_t pll_intfb : 1; + uint32_t pll_bypass : 1; + uint32_t pll_test : 1; + uint32_t pll_out_en : 1; + uint32_t pll_ckin_sel : 2; + uint32_t reserved : 4; +} __attribute__((packed, aligned(4))) sysctl_general_pll_t; + +/** + * @brief System controller object instanse + */ +extern volatile sysctl_t *const sysctl; + +/** + * @brief Enable clock for peripheral + * + * @param[in] clock The clock to be enable + * + * @return result + * - 0 Success + * - Other Fail + */ +int sysctl_clock_enable(sysctl_clock_t clock); + +/** + * @brief Enable clock for peripheral + * + * @param[in] clock The clock to be disable + * + * @return result + * - 0 Success + * - Other Fail + */ +int sysctl_clock_disable(sysctl_clock_t clock); + +/** + * @brief Sysctl clock set threshold + * + * @param[in] which Which threshold to set + * @param[in] threshold The threshold value + * + * @return result + * - 0 Success + * - Other Fail + */ +int sysctl_clock_set_threshold(sysctl_threshold_t which, int threshold); + +/** + * @brief Sysctl clock get threshold + * + * @param[in] which Which threshold to get + * + * @return The threshold value + * - Other Value of threshold + * - -1 Fail + */ +int sysctl_clock_get_threshold(sysctl_threshold_t which); + +/** + * @brief Sysctl clock set clock select + * + * @param[in] which Which clock select to set + * @param[in] select The clock select value + * + * @return result + * - 0 Success + * - Other Fail + */ +int sysctl_clock_set_clock_select(sysctl_clock_select_t which, int select); + +/** + * @brief Sysctl clock get clock select + * + * @param[in] which Which clock select to get + * + * @return The clock select value + * - Other Value of clock select + * - -1 Fail + */ +int sysctl_clock_get_clock_select(sysctl_clock_select_t which); + +/** + * @brief Get PLL frequency + * + * @param[in] pll The PLL id + * + * @return The frequency of PLL + */ +uint32_t sysctl_pll_get_freq(sysctl_pll_t pll); + +/** + * @brief Get base clock frequency by clock id + * + * @param[in] clock The clock id + * + * @return The clock frequency + */ +uint32_t SysctlClockGetFreq(sysctl_clock_t clock); + +/** + * @brief Reset device by reset controller + * + * @param[in] reset The reset signal + */ +void sysctl_reset(sysctl_reset_t reset); + +/** + * @brief Enable the PLL and power on with reset + * + * @param[in] pll The pll id + * + * @return Result + * - 0 Success + * - Other Fail + */ +int sysctl_pll_enable(sysctl_pll_t pll); + +/** + * @brief Disable the PLL and power off + * + * @param[in] pll The pll id + * + * @return Result + * - 0 Success + * - Other Fail + */ +int sysctl_pll_disable(sysctl_pll_t pll); + +/** + * @brief Select DMA channel handshake peripheral signal + * + * @param[in] channel The DMA channel + * @param[in] select The peripheral select + * + * @return Result + * - 0 Success + * - Other Fail + */ +int sysctl_dma_select(sysctl_dma_channel_t channel, sysctl_dma_select_t select); + +/** + * @brief Set SPI0_D0-D7 DVP_D0-D7 as spi and dvp data pin + * + * @param[in] en Enable or not + * + * @return Result + * - 0 Success + * - Other Fail + */ +uint32_t sysctl_set_spi0_dvp_data(uint8_t en); + +/** + * @brief Set io power mode + * + * @param[in] power_bank IO power bank + * @param[in] io_power_mode Set power mode 3.3v or 1.8 + * + * @return Result + * - 0 Success + * - Other Fail + */ +void sysctl_set_power_mode(sysctl_power_bank_t power_bank, sysctl_io_power_mode_t io_power_mode); + +/** + * @brief get the frequency of CPU + * + * @return The frequency of CPU + */ +uint32_t sysctl_cpu_get_freq(void); + +/** + * @brief Set frequency of CPU + * @param[in] freq The desired frequency in Hz + * + * @return The actual frequency of CPU after set + */ +uint32_t sysctl_cpu_set_freq(uint32_t freq); + +/** + * @brief Init PLL freqency + * @param[in] pll The PLL id + * @param[in] pll_freq The desired frequency in Hz + + */ +uint32_t SysctlPllSetFreq(sysctl_pll_t pll, uint32_t pll_freq); + +/** + * @brief Enable interrupt + */ +void sysctl_enable_irq(void); + +/** + * @brief Disable interrupt + */ +void sysctl_disable_irq(void); + +/** + * @brief Get the time start up to now + * + * @return The time of microsecond + */ +uint64_t sysctl_get_time_us(void); + +/** + * @brief Get reset status + * + * @return The status of reset + */ +sysctl_reset_enum_status_t sysctl_get_reset_status(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __SYSCTL_H__ */ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/utils.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/utils.h new file mode 100644 index 000000000..86b017f31 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/utils.h @@ -0,0 +1,357 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file utils.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#ifndef __UTILS_H__ +#define __UTILS_H__ + +#ifdef __cplusplus +#include +#include +#include +#else /* __cplusplus */ +#include +#include +#include +#include +#endif /* __cplusplus */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define KENDRYTE_MIN(a, b) ((a) > (b) ? (b) : (a)) +#define KENDRYTE_MAX(a, b) ((a) > (b) ? (a) : (b)) + +#ifdef __ASSEMBLY__ +#define KENDRYTE_CAST(type, ptr) ptr +#else /* __ASSEMBLY__ */ +/** + * @brief Cast the pointer to specified pointer type. + * + * @param[in] type The pointer type to cast to + * @param[in] ptr The pointer to apply the type cast to + */ +#define KENDRYTE_CAST(type, ptr) ((type)(ptr)) +#endif /* __ASSEMBLY__ */ + +/** + * @addtogroup UTIL_RW_FUNC Memory Read/Write Utilities + * + * This section implements read and write functionality for various + * memory untis. The memory unit terms used for these functions are + * consistent with those used in the ARM Architecture Reference Manual + * ARMv7-A and ARMv7-R edition manual. The terms used for units of memory are: + * + * Unit of Memory | Abbreviation | Size in Bits + * :---------------|:-------------|:------------: + * Byte | byte | 8 + * Half Word | hword | 16 + * Word | word | 32 + * Double Word | dword | 64 + * + */ + +/** + * @brief Write the 8 bit byte to the destination address in device memory. + * + * @param[in] dest Write destination pointer address + * @param[in] src 8 bit data byte to write to memory + */ +#define kendryte_write_byte(dest, src) \ + (*KENDRYTE_CAST(volatile uint8_t*, (dest)) = (src)) + +/** + * @brief Read and return the 8 bit byte from the source address in device memory. + * + * @param[in] src Read source pointer address + * + * @return 8 bit data byte value + */ +#define kendryte_read_byte(src) (*KENDRYTE_CAST(volatile uint8_t*, (src))) + +/** + * @brief Write the 16 bit half word to the destination address in device memory. + * + * @param[in] dest Write destination pointer address + * @param[in] src 16 bit data half word to write to memory + */ +#define kendryte_write_hword(dest, src) \ + (*KENDRYTE_CAST(volatile uint16_t*, (dest)) = (src)) + +/** + * @brief Read and return the 16 bit half word from the source address in device + * + * @param[in] src Read source pointer address + * + * @return 16 bit data half word value + */ +#define kendryte_read_hword(src) (*KENDRYTE_CAST(volatile uint16_t*, (src))) + +/** + * @brief Write the 32 bit word to the destination address in device memory. + * + * @param[in] dest Write destination pointer address + * @param[in] src 32 bit data word to write to memory + */ +#define kendryte_write_word(dest, src) \ + (*KENDRYTE_CAST(volatile uint32_t*, (dest)) = (src)) + +/** + * @brief Read and return the 32 bit word from the source address in device memory. + * + * @param[in] src Read source pointer address + * + * @return 32 bit data half word value + */ +#define kendryte_read_word(src) (*KENDRYTE_CAST(volatile uint32_t*, (src))) + +/** + * @brief Write the 64 bit double word to the destination address in device memory. + * + * @param[in] dest Write destination pointer address + * @param[in] src 64 bit data word to write to memory + */ +#define kendryte_write_dword(dest, src) \ + (*KENDRYTE_CAST(volatile uint64_t*, (dest)) = (src)) + +/** + * @brief Read and return the 64 bit double word from the source address in device + * + * @param[in] src Read source pointer address + * + * @return 64 bit data half word value + */ +#define kendryte_read_dword(src) (*KENDRYTE_CAST(volatile uint64_t*, (src))) + +/** + * @brief Set selected bits in the 8 bit byte at the destination address in device + * + * @param[in] dest Destination pointer address + * @param[in] bits Bits to set in destination byte + */ +#define kendryte_setbits_byte(dest, bits) \ + (kendryte_write_byte(dest, kendryte_read_byte(dest) | (bits))) + +/** + * @brief Clear selected bits in the 8 bit byte at the destination address in device + * + * @param[in] dest Destination pointer address + * @param[in] bits Bits to clear in destination byte + */ +#define kendryte_clrbits_byte(dest, bits) \ + (kendryte_write_byte(dest, kendryte_read_byte(dest) & ~(bits))) + +/** + * @brief Change or toggle selected bits in the 8 bit byte at the destination address + * + * @param[in] dest Destination pointer address + * @param[in] bits Bits to change in destination byte + */ +#define kendryte_xorbits_byte(dest, bits) \ + (kendryte_write_byte(dest, kendryte_read_byte(dest) ^ (bits))) + +/** + * @brief Replace selected bits in the 8 bit byte at the destination address in device + * + * @param[in] dest Destination pointer address + * @param[in] msk Bits to replace in destination byte + * @param[in] src Source bits to write to cleared bits in destination byte + */ +#define kendryte_replbits_byte(dest, msk, src) \ + (kendryte_write_byte(dest, (kendryte_read_byte(dest) & ~(msk)) | ((src) & (msk)))) + +/** + * @brief Set selected bits in the 16 bit halfword at the destination address in + * + * @param[in] dest Destination pointer address + * @param[in] bits Bits to set in destination halfword + */ +#define kendryte_setbits_hword(dest, bits) \ + (kendryte_write_hword(dest, kendryte_read_hword(dest) | (bits))) + +/** + * @brief Clear selected bits in the 16 bit halfword at the destination address in + * + * @param[in] dest Destination pointer address + * @param[in] bits Bits to clear in destination halfword + */ +#define kendryte_clrbits_hword(dest, bits) \ + (kendryte_write_hword(dest, kendryte_read_hword(dest) & ~(bits))) + +/** + * @brief Change or toggle selected bits in the 16 bit halfword at the destination + * + * @param[in] dest Destination pointer address + * @param[in] bits Bits to change in destination halfword + */ +#define kendryte_xorbits_hword(dest, bits) \ + (kendryte_write_hword(dest, kendryte_read_hword(dest) ^ (bits))) + +/** + * @brief Replace selected bits in the 16 bit halfword at the destination address in + * + * @param[in] dest Destination pointer address + * @param[in] msk Bits to replace in destination byte + * @param[in] src Source bits to write to cleared bits in destination halfword + */ +#define kendryte_replbits_hword(dest, msk, src) \ + (kendryte_write_hword(dest, (kendryte_read_hword(dest) & ~(msk)) | ((src) & (msk)))) + +/** + * @brief Set selected bits in the 32 bit word at the destination address in device + * + * @param[in] dest Destination pointer address + * @param[in] bits Bits to set in destination word + */ +#define kendryte_setbits_word(dest, bits) \ + (kendryte_write_word(dest, kendryte_read_word(dest) | (bits))) + +/** + * @brief Clear selected bits in the 32 bit word at the destination address in device + * + * @param[in] dest Destination pointer address + * @param[in] bits Bits to clear in destination word + */ +#define kendryte_clrbits_word(dest, bits) \ + (kendryte_write_word(dest, kendryte_read_word(dest) & ~(bits))) + +/** + * @brief Change or toggle selected bits in the 32 bit word at the destination address + * + * @param[in] dest Destination pointer address + * @param[in] bits Bits to change in destination word + */ +#define kendryte_xorbits_word(dest, bits) \ + (kendryte_write_word(dest, kendryte_read_word(dest) ^ (bits))) + +/** + * @brief Replace selected bits in the 32 bit word at the destination address in + * + * @param[in] dest Destination pointer address + * @param[in] msk Bits to replace in destination word + * @param[in] src Source bits to write to cleared bits in destination word + */ +#define kendryte_replbits_word(dest, msk, src) \ + (kendryte_write_word(dest, (kendryte_read_word(dest) & ~(msk)) | ((src) & (msk)))) + +/** + * @brief Set selected bits in the 64 bit doubleword at the destination address in + * + * @param[in] dest Destination pointer address + * @param[in] bits Bits to set in destination doubleword + */ +#define kendryte_setbits_dword(dest, bits) \ + (kendryte_write_dword(dest, kendryte_read_dword(dest) | (bits))) + +/** + * @brief Clear selected bits in the 64 bit doubleword at the destination address in + * + * @param[in] dest Destination pointer address + * @param[in] bits Bits to clear in destination doubleword + */ +#define kendryte_clrbits_dword(dest, bits) \ + (kendryte_write_dword(dest, kendryte_read_dword(dest) & ~(bits))) + +/** + * @brief Change or toggle selected bits in the 64 bit doubleword at the destination + * + * @param[in] dest Destination pointer address + * @param[in] bits Bits to change in destination doubleword + */ +#define kendryte_xorbits_dword(dest, bits) \ + (kendryte_write_dword(dest, kendryte_read_dword(dest) ^ (bits))) + +/** + * @brief Replace selected bits in the 64 bit doubleword at the destination address in + * + * @param[in] dest Destination pointer address + * @param[in] msk its to replace in destination doubleword + * @param[in] src Source bits to write to cleared bits in destination word + */ +#define kendryte_replbits_dword(dest, msk, src) \ + (kendryte_write_dword(dest, (kendryte_read_dword(dest) & ~(msk)) | ((src) & (msk)))) + +#define configASSERT(x) \ + if ((x) == 0) \ + { \ + printf("(%s:%d) %s\r\n", __FILE__, __LINE__, #x); \ + for (;;) \ + ; \ + } + +/** + * @brief Set value by mask + * + * @param[in] bits The one be set + * @param[in] mask mask value + * @param[in] value The value to set + */ +void set_bit(volatile uint32_t *bits, uint32_t mask, uint32_t value); + +/** + * @brief Set value by mask + * + * @param[in] bits The one be set + * @param[in] mask Mask value + * @param[in] offset Mask's offset + * @param[in] value The value to set + */ +void set_bit_offset(volatile uint32_t *bits, uint32_t mask, size_t offset, uint32_t value); + +/** + * @brief Set bit for gpio, only set one bit + * + * @param[in] bits The one be set + * @param[in] idx Offset value + * @param[in] value The value to set + */ +void set_gpio_bit(volatile uint32_t *bits, size_t idx, uint32_t value); + +/** + * @brief Get bits value of mask + * + * @param[in] bits The source data + * @param[in] mask Mask value + * @param[in] offset Mask's offset + * + * @return The bits value of mask + */ +uint32_t get_bit(volatile uint32_t *bits, uint32_t mask, size_t offset); + +/** + * @brief Get a bit value by offset + * + * @param[in] bits The source data + * @param[in] offset Bit's offset + * + * + * @return The bit value + */ +uint32_t get_gpio_bit(volatile uint32_t *bits, size_t offset); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _DRIVER_COMMON_H */ + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/w5500.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/w5500.h new file mode 100755 index 000000000..121baab06 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/w5500.h @@ -0,0 +1,2321 @@ +//***************************************************************************** +// +//! \file w5500.h +//! \brief W5500 HAL Header File. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +// + +#ifndef _W5500_H_ +#define _W5500_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "wizchip_conf.h" +#include + + +/// @cond DOXY_APPLY_CODE +#if (_WIZCHIP_ == 5500) +/// @endcond + +#define _W5500_IO_BASE_ 0x00000000 + +#define _W5500_SPI_READ_ \ + (0x00 << 2) //< SPI interface Read operation in Control Phase +#define _W5500_SPI_WRITE_ \ + (0x01 << 2) //< SPI interface Write operation in Control Phase + +#define WIZCHIP_CREG_BLOCK 0x00 //< Common register block +#define WIZCHIP_SREG_BLOCK(N) (1 + 4 * N) //< Socket N register block +#define WIZCHIP_TXBUF_BLOCK(N) (2 + 4 * N) //< Socket N Tx buffer address block +#define WIZCHIP_RXBUF_BLOCK(N) (3 + 4 * N) //< Socket N Rx buffer address block + +#define WIZCHIP_OFFSET_INC(ADDR, N) \ + (ADDR + (N << 8)) //< Increase offset address + +/////////////////////////////////////// +// Definition For Legacy Chip Driver // +/////////////////////////////////////// +#define IINCHIP_READ(ADDR) \ + WIZCHIP_READ(ADDR) ///< The defined for legacy chip driver +#define IINCHIP_WRITE(ADDR, VAL) \ + WIZCHIP_WRITE(ADDR, VAL) ///< The defined for legacy chip driver +#define IINCHIP_READ_BUF(ADDR, BUF, LEN) \ + WIZCHIP_READ_BUF(ADDR, BUF, LEN) ///< The defined for legacy chip driver +#define IINCHIP_WRITE_BUF(ADDR, BUF, LEN) \ + WIZCHIP_WRITE(ADDR, BUF, LEN) ///< The defined for legacy chip driver + +////////////////////////////// +//-------------------------- defgroup --------------------------------- +/** + * @defgroup W5500 W5500 + * + * @brief WHIZCHIP register defines and I/O functions of @b W5500. + * + * - @ref WIZCHIP_register : @ref Common_register_group and @ref + * Socket_register_group + * - @ref WIZCHIP_IO_Functions : @ref Basic_IO_function, @ref + * Common_register_access_function and @ref Socket_register_access_function + */ + +/** + * @defgroup WIZCHIP_register WIZCHIP register + * @ingroup W5500 + * + * @brief WHIZCHIP register defines register group of @b W5500. + * + * - @ref Common_register_group : Common register group + * - @ref Socket_register_group : \c SOCKET n register group + */ + +/** + * @defgroup WIZCHIP_IO_Functions WIZCHIP I/O functions + * @ingroup W5500 + * + * @brief This supports the basic I/O functions for @ref WIZCHIP_register. + * + * - Basic I/O function \n + * WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * \n\n + * + * - @ref Common_register_group access functions \n + * -# @b Mode \n + * getMR(), setMR() + * -# @b Interrupt \n + * getIR(), setIR(), getIMR(), setIMR(), getSIR(), setSIR(), getSIMR(), + * setSIMR(), getINTLEVEL(), setINTLEVEL() + * -# Network Information \n + * getSHAR(), setSHAR(), getGAR(), setGAR(), getSUBR(), setSUBR(), getSIPR(), + * setSIPR() + * -# @b Retransmission \n + * getRCR(), setRCR(), getRTR(), setRTR() + * -# @b PPPoE \n + * getPTIMER(), setPTIMER(), getPMAGIC(), getPMAGIC(), getPSID(), setPSID(), + * getPHAR(), setPHAR(), getPMRU(), setPMRU() + * -# ICMP packet \n + * getUIPR(), getUPORTR() + * -# @b etc. \n + * getPHYCFGR(), setPHYCFGR(), getVERSIONR() \n\n + * + * - \ref Socket_register_group access functions \n + * -# SOCKET control \n + * getSn_MR(), setSn_MR(), getSn_CR(), setSn_CR(), getSn_IMR(), + * setSn_IMR(), getSn_IR(), setSn_IR() + * -# SOCKET information \n + * getSn_SR(), getSn_DHAR(), setSn_DHAR(), getSn_PORT(), setSn_PORT(), + * getSn_DIPR(), setSn_DIPR(), getSn_DPORT(), setSn_DPORT() getSn_MSSR(), + * setSn_MSSR() + * -# SOCKET communication \n + * getSn_RXBUF_SIZE(), setSn_RXBUF_SIZE(), getSn_TXBUF_SIZE(), + * setSn_TXBUF_SIZE() \n getSn_TX_RD(), getSn_TX_WR(), setSn_TX_WR() \n + * getSn_RX_RD(), setSn_RX_RD(), getSn_RX_WR() \n + * getSn_TX_FSR(), getSn_RX_RSR(), getSn_KPALVTR(), setSn_KPALVTR() + * -# IP header field \n + * getSn_FRAG(), setSn_FRAG(), getSn_TOS(), setSn_TOS() \n + * getSn_TTL(), setSn_TTL() + */ + +/** + * @defgroup Common_register_group Common register + * @ingroup WIZCHIP_register + * + * @brief Common register group\n + * It set the basic for the networking\n + * It set the configuration such as interrupt, network information, ICMP, etc. + * @details + * @sa MR : Mode register. + * @sa GAR, SUBR, SHAR, SIPR + * @sa INTLEVEL, IR, IMR, SIR, SIMR : Interrupt. + * @sa _RTR_, _RCR_ : Data retransmission. + * @sa PTIMER, PMAGIC, PHAR, PSID, PMRU : PPPoE. + * @sa UIPR, UPORTR : ICMP message. + * @sa PHYCFGR, VERSIONR : etc. + */ + +/** + * @defgroup Socket_register_group Socket register + * @ingroup WIZCHIP_register + * + * @brief Socket register group.\n + * Socket register configures and control SOCKETn which is necessary to data + * communication. + * @details + * @sa Sn_MR, Sn_CR, Sn_IR, Sn_IMR : SOCKETn Control + * @sa Sn_SR, Sn_PORT, Sn_DHAR, Sn_DIPR, Sn_DPORT : SOCKETn Information + * @sa Sn_MSSR, Sn_TOS, Sn_TTL, Sn_KPALVTR, Sn_FRAG : Internet protocol. + * @sa Sn_RXBUF_SIZE, Sn_TXBUF_SIZE, Sn_TX_FSR, Sn_TX_RD, Sn_TX_WR, Sn_RX_RSR, + * Sn_RX_RD, Sn_RX_WR : Data communication + */ + +/** + * @defgroup Basic_IO_function Basic I/O function + * @ingroup WIZCHIP_IO_Functions + * @brief These are basic input/output functions to read values from register or + * write values to register. + */ + +/** + * @defgroup Common_register_access_function Common register access functions + * @ingroup WIZCHIP_IO_Functions + * @brief These are functions to access common registers. + */ + +/** + * @defgroup Socket_register_access_function Socket register access functions + * @ingroup WIZCHIP_IO_Functions + * @brief These are functions to access socket registers. + */ + +//------------------------------- defgroup end +//-------------------------------------------- +//----------------------------- W5500 Common Registers IOMAP +//----------------------------- +/** + * @ingroup Common_register_group + * @brief Mode Register address(R/W)\n + * @ref MR is used for S/W reset, ping block mode, PPPoE mode and etc. + * @details Each bit of @ref MR defined as follows. + * + * + * + * + * + *
7 6 5 4 32 1 0
RST ReservedWOL PB PPPoE Reserved FARPReserved
+ * - \ref MR_RST : Reset + * - \ref MR_WOL : Wake on LAN + * - \ref MR_PB : Ping block + * - \ref MR_PPPOE : PPPoE mode + * - \ref MR_FARP : Force ARP mode + */ +#define MR (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Gateway IP Register address(R/W) + * @details @ref GAR configures the default gateway address. + */ +#define GAR (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Subnet mask Register address(R/W) + * @details @ref SUBR configures the subnet mask address. + */ +#define SUBR (_W5500_IO_BASE_ + (0x0005 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Source MAC Register address(R/W) + * @details @ref SHAR configures the source hardware address. + */ +#define SHAR (_W5500_IO_BASE_ + (0x0009 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Source IP Register address(R/W) + * @details @ref SIPR configures the source IP address. + */ +#define SIPR (_W5500_IO_BASE_ + (0x000F << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Set Interrupt low level timer register address(R/W) + * @details @ref INTLEVEL configures the Interrupt Assert Time. + */ +#define INTLEVEL (_W5500_IO_BASE_ + (0x0013 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Interrupt Register(R/W) + * @details @ref IR indicates the interrupt status. Each bit of @ref IR will be + * still until the bit will be written to by the host. If @ref IR is not equal + * to x00 INTn PIN is asserted to low until it is x00\n\n Each bit of @ref IR + * defined as follows. + * + * + * + *
7 6 5 43 2 1 0
CONFLICTUNREACH PPPoE MP ReservedReserved Reserved Reserved
+ * - \ref IR_CONFLICT : IP conflict + * - \ref IR_UNREACH : Destination unreachable + * - \ref IR_PPPoE : PPPoE connection close + * - \ref IR_MP : Magic packet + */ +#define IR (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Interrupt mask register(R/W) + * @details @ref _IMR_ is used to mask interrupts. Each bit of @ref _IMR_ + * corresponds to each bit of @ref IR. When a bit of @ref _IMR_ is and the + * corresponding bit of @ref IR is an interrupt will be issued. In other words, + * if a bit of @ref _IMR_ is an interrupt will not be issued even if the + * corresponding bit of @ref IR is \n\n Each bit of @ref _IMR_ defined as the + * following. + * + * + * + *
7 6 5 43 2 1 0
IM_IR7IM_IR6 IM_IR5 IM_IR4 ReservedReserved Reserved Reserved
+ * - \ref IM_IR7 : IP Conflict Interrupt Mask + * - \ref IM_IR6 : Destination unreachable Interrupt Mask + * - \ref IM_IR5 : PPPoE Close Interrupt Mask + * - \ref IM_IR4 : Magic Packet Interrupt Mask + */ +// M20150401 : Rename SYMBOE ( Re-define error in a compile) +//#define IMR (_W5500_IO_BASE_ + (0x0016 << 8) + +//(WIZCHIP_CREG_BLOCK << 3)) +#define _IMR_ (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Socket Interrupt Register(R/W) + * @details @ref SIR indicates the interrupt status of Socket.\n + * Each bit of @ref SIR be still until @ref Sn_IR is cleared by the host.\n + * If @ref Sn_IR is not equal to x00 the n-th bit of @ref SIR is and INTn PIN is + * asserted until @ref SIR is x00 */ +#define SIR (_W5500_IO_BASE_ + (0x0017 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Socket Interrupt Mask Register(R/W) + * @details Each bit of @ref SIMR corresponds to each bit of @ref SIR. + * When a bit of @ref SIMR is and the corresponding bit of @ref SIR is Interrupt + * will be issued. In other words, if a bit of @ref SIMR is an interrupt will + * be not issued even if the corresponding bit of @ref SIR is + */ +#define SIMR (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Timeout register address( 1 is 100us )(R/W) + * @details @ref _RTR_ configures the retransmission timeout period. The unit of + * timeout period is 100us and the default of @ref _RTR_ is x07D0. And so the + * default timeout period is 200ms(100us X 2000). During the time configured by + * @ref _RTR_, W5500 waits for the peer response to the packet that is + * transmitted by \ref Sn_CR (CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP + * command). If the peer does not respond within the @ref _RTR_ time, W5500 + * retransmits the packet or issues timeout. + */ +// M20150401 : Rename SYMBOE ( Re-define error in a compile) +//#define RTR (_W5500_IO_BASE_ + (0x0019 << 8) + +//(WIZCHIP_CREG_BLOCK << 3)) +#define _RTR_ (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Retry count register(R/W) + * @details @ref _RCR_ configures the number of time of retransmission. + * When retransmission occurs as many as ref _RCR_+1 Timeout interrupt is issued + * (@ref Sn_IR_TIMEOUT = '1'). + */ +// M20150401 : Rename SYMBOE ( Re-define error in a compile) +//#define RCR (_W5500_IO_BASE_ + (0x001B << 8) + +//(WIZCHIP_CREG_BLOCK << 3)) +#define _RCR_ (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP LCP Request Timer register in PPPoE mode(R/W) + * @details @ref PTIMER configures the time for sending LCP echo request. The + * unit of time is 25ms. + */ +#define PTIMER (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP LCP Magic number register in PPPoE mode(R/W) + * @details @ref PMAGIC configures the 4bytes magic number to be used in LCP + * negotiation. + */ +#define PMAGIC (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Destination MAC Register address(R/W) + * @details @ref PHAR configures the PPPoE server hardware address that is + * acquired during PPPoE connection process. + */ +#define PHAR (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Session Identification Register(R/W) + * @details @ref PSID configures the PPPoE sever session ID acquired during + * PPPoE connection process. + */ +#define PSID (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PPP Maximum Segment Size(MSS) register(R/W) + * @details @ref PMRU configures the maximum receive unit of PPPoE. + */ +#define PMRU (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Unreachable IP register address in UDP mode(R) + * @details W5500 receives an ICMP packet(Destination port unreachable) when + * data is sent to a port number which socket is not open and @ref IR_UNREACH + * bit of @ref IR becomes and @ref UIPR & @ref UPORTR indicates the destination + * IP address & port number respectively. + */ +#define UIPR (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief Unreachable Port register address in UDP mode(R) + * @details W5500 receives an ICMP packet(Destination port unreachable) when + * data is sent to a port number which socket is not open and @ref IR_UNREACH + * bit of @ref IR becomes and @ref UIPR & @ref UPORTR indicates the destination + * IP address & port number respectively. + */ +#define UPORTR (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief PHY Status Register(R/W) + * @details @ref PHYCFGR configures PHY operation mode and resets PHY. In + * addition, @ref PHYCFGR indicates the status of PHY such as duplex, Speed, + * Link. + */ +#define PHYCFGR (_W5500_IO_BASE_ + (0x002E << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +// Reserved (_W5500_IO_BASE_ + (0x002F << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0030 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0031 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0032 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0033 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0034 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0035 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0036 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0037 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0038 << 8) + +// (WIZCHIP_CREG_BLOCK << 3)) + +/** + * @ingroup Common_register_group + * @brief chip version register address(R) + * @details @ref VERSIONR always indicates the W5500 version as @b 0x04. + */ +#define VERSIONR (_W5500_IO_BASE_ + (0x0039 << 8) + (WIZCHIP_CREG_BLOCK << 3)) + +//----------------------------- W5500 Socket Registers IOMAP +//----------------------------- +/** + * @ingroup Socket_register_group + * @brief socket Mode register(R/W) + * @details @ref Sn_MR configures the option or protocol type of Socket n.\n\n + * Each bit of @ref Sn_MR defined as the following. + * + * + * + * + * + *
7 6 5 4 32 1 0
MULTI/MFENBCASTB ND/MC/MMB UCASTB/MIP6B Protocol[3]Protocol[2] Protocol[1] Protocol[0]
+ * - @ref Sn_MR_MULTI : Support UDP Multicasting + * - @ref Sn_MR_BCASTB : Broadcast block in UDP Multicasting + * - @ref Sn_MR_ND : No Delayed Ack(TCP) flag + * - @ref Sn_MR_MC : IGMP version used in UDP mulitcasting + * - @ref Sn_MR_MMB : Multicast Blocking in @ref Sn_MR_MACRAW mode + * - @ref Sn_MR_UCASTB : Unicast Block in UDP Multicating + * - @ref Sn_MR_MIP6B : IPv6 packet Blocking in @ref Sn_MR_MACRAW mode + * - Protocol + * + * + * + * + * + * + * + * + *
Protocol[3] Protocol[2]Protocol[1] Protocol[0] @b Meaning
0 0 0 0 Closed
0 0 0 1 TCP
0 0 1 0 UDP
0 1 0 0MACRAW
+ * - @ref Sn_MR_MACRAW : MAC LAYER RAW SOCK \n + * - @ref Sn_MR_UDP : UDP + * - @ref Sn_MR_TCP : TCP + * - @ref Sn_MR_CLOSE : Unused socket + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR(N) \ + (_W5500_IO_BASE_ + (0x0000 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket command register(R/W) + * @details This is used to set the command for Socket n such as OPEN, CLOSE, + * CONNECT, LISTEN, SEND, and RECEIVE.\n After W5500 accepts the command, the + * @ref Sn_CR register is automatically cleared to 0x00. Even though @ref Sn_CR + * is cleared to 0x00, the command is still being processed.\n To check whether + * the command is completed or not, please check the @ref Sn_IR or @ref Sn_SR. + * - @ref Sn_CR_OPEN : Initialize or open socket. + * - @ref Sn_CR_LISTEN : Wait connection request in TCP mode(Server + * mode) + * - @ref Sn_CR_CONNECT : Send connection request in TCP mode(Client + * mode) + * - @ref Sn_CR_DISCON : Send closing request in TCP mode. + * - @ref Sn_CR_CLOSE : Close socket. + * - @ref Sn_CR_SEND : Update TX buffer pointer and send data. + * - @ref Sn_CR_SEND_MAC : Send data with MAC address, so without ARP + * process. + * - @ref Sn_CR_SEND_KEEP : Send keep alive message. + * - @ref Sn_CR_RECV : Update RX buffer pointer and receive data. + */ +#define Sn_CR(N) \ + (_W5500_IO_BASE_ + (0x0001 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket interrupt register(R) + * @details @ref Sn_IR indicates the status of Socket Interrupt such as + * establishment, termination, receiving data, timeout).\n When an interrupt + * occurs and the corresponding bit of @ref Sn_IMR is the corresponding bit of + * @ref Sn_IR becomes \n In order to clear the @ref Sn_IR bit, the host should + * write the bit to \n + * + * + * + *
7 6 5 43 2 1 0
ReservedReserved Reserved SEND_OK TIMEOUTRECV DISCON CON
+ * - \ref Sn_IR_SENDOK : SEND_OK Interrupt + * - \ref Sn_IR_TIMEOUT : TIMEOUT Interrupt + * - \ref Sn_IR_RECV : RECV Interrupt + * - \ref Sn_IR_DISCON : DISCON Interrupt + * - \ref Sn_IR_CON : CON Interrupt + */ +#define Sn_IR(N) \ + (_W5500_IO_BASE_ + (0x0002 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Socket status register(R) + * @details @ref Sn_SR indicates the status of Socket n.\n + * The status of Socket n is changed by @ref Sn_CR or some special control + *packet as SYN, FIN packet in TCP. + * @par Normal status + * - @ref SOCK_CLOSED : Closed + * - @ref SOCK_INIT : Initiate state + * - @ref SOCK_LISTEN : Listen state + * - @ref SOCK_ESTABLISHED : Success to connect + * - @ref SOCK_CLOSE_WAIT : Closing state + * - @ref SOCK_UDP : UDP socket + * - @ref SOCK_MACRAW : MAC raw mode socket + *@par Temporary status during changing the status of Socket n. + * - @ref SOCK_SYNSENT : This indicates Socket n sent the + *connect-request packet (SYN packet) to a peer. + * - @ref SOCK_SYNRECV : It indicates Socket n successfully received + *the connect-request packet (SYN packet) from a peer. + * - @ref SOCK_FIN_WAIT : Connection state + * - @ref SOCK_CLOSING : Closing state + * - @ref SOCK_TIME_WAIT : Closing state + * - @ref SOCK_LAST_ACK : Closing state + */ +#define Sn_SR(N) \ + (_W5500_IO_BASE_ + (0x0003 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief source port register(R/W) + * @details @ref Sn_PORT configures the source port number of Socket n. + * It is valid when Socket n is used in TCP/UDP mode. It should be set before + * OPEN command is ordered. + */ +#define Sn_PORT(N) \ + (_W5500_IO_BASE_ + (0x0004 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer MAC register address(R/W) + * @details @ref Sn_DHAR configures the destination hardware address of Socket n + * when using SEND_MAC command in UDP mode or it indicates that it is acquired + * in ARP-process by CONNECT/SEND command. + */ +#define Sn_DHAR(N) \ + (_W5500_IO_BASE_ + (0x0006 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer IP register address(R/W) + * @details @ref Sn_DIPR configures or indicates the destination IP address of + * Socket n. It is valid when Socket n is used in TCP/UDP mode. In TCP client + * mode, it configures an IP address of TCP serverbefore CONNECT command. In TCP + * server mode, it indicates an IP address of TCP clientafter successfully + * establishing connection. In UDP mode, it configures an IP address of peer to + * be received the UDP packet by SEND or SEND_MAC command. + */ +#define Sn_DIPR(N) \ + (_W5500_IO_BASE_ + (0x000C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Peer port register address(R/W) + * @details @ref Sn_DPORT configures or indicates the destination port number of + * Socket n. It is valid when Socket n is used in TCP/UDP mode. In TCP + * clientmode, it configures the listen port number of TCP serverbefore CONNECT + * command. In TCP Servermode, it indicates the port number of TCP client after + * successfully establishing connection. In UDP mode, it configures the port + * number of peer to be transmitted the UDP packet by SEND/SEND_MAC command. + */ +#define Sn_DPORT(N) \ + (_W5500_IO_BASE_ + (0x0010 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Maximum Segment Size(Sn_MSSR0) register address(R/W) + * @details @ref Sn_MSSR configures or indicates the MTU(Maximum Transfer Unit) + * of Socket n. + */ +#define Sn_MSSR(N) \ + (_W5500_IO_BASE_ + (0x0012 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +// Reserved (_W5500_IO_BASE_ + (0x0014 << 8) + +// (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief IP Type of Service(TOS) Register(R/W) + * @details @ref Sn_TOS configures the TOS(Type Of Service field in IP Header) + * of Socket n. It is set before OPEN command. + */ +#define Sn_TOS(N) \ + (_W5500_IO_BASE_ + (0x0015 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +/** + * @ingroup Socket_register_group + * @brief IP Time to live(TTL) Register(R/W) + * @details @ref Sn_TTL configures the TTL(Time To Live field in IP header) of + * Socket n. It is set before OPEN command. + */ +#define Sn_TTL(N) \ + (_W5500_IO_BASE_ + (0x0016 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) +// Reserved (_W5500_IO_BASE_ + (0x0017 << 8) + +// (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x0018 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x0019 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x001A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x001B << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x001C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) Reserved +// (_W5500_IO_BASE_ + (0x001D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Receive memory size register(R/W) + * @details @ref Sn_RXBUF_SIZE configures the RX buffer block size of Socket n. + * Socket n RX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. + * If a different size is configured, the data cannot be normally received from + * a peer. Although Socket n RX Buffer Block size is initially configured to + * 2Kbytes, user can re-configure its size using @ref Sn_RXBUF_SIZE. The total + * sum of @ref Sn_RXBUF_SIZE can not be exceed 16Kbytes. When exceeded, the data + * reception error is occurred. + */ +#define Sn_RXBUF_SIZE(N) \ + (_W5500_IO_BASE_ + (0x001E << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory size register(R/W) + * @details @ref Sn_TXBUF_SIZE configures the TX buffer block size of Socket n. + * Socket n TX Buffer Block size can be configured with 1,2,4,8, and 16 Kbytes. + * If a different size is configured, the data can�t be normally transmitted to + * a peer. Although Socket n TX Buffer Block size is initially configured to + * 2Kbytes, user can be re-configure its size using @ref Sn_TXBUF_SIZE. The + * total sum of @ref Sn_TXBUF_SIZE can not be exceed 16Kbytes. When exceeded, + * the data transmission error is occurred. + */ +#define Sn_TXBUF_SIZE(N) \ + (_W5500_IO_BASE_ + (0x001F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit free memory size register(R) + * @details @ref Sn_TX_FSR indicates the free size of Socket n TX Buffer Block. + * It is initialized to the configured size by @ref Sn_TXBUF_SIZE. Data bigger + * than @ref Sn_TX_FSR should not be saved in the Socket n TX Buffer because the + * bigger data overwrites the previous saved data not yet sent. Therefore, check + * before saving the data to the Socket n TX Buffer, and if data is equal or + * smaller than its checked size, transmit the data with SEND/SEND_MAC command + * after saving the data in Socket n TX buffer. But, if data is bigger than its + * checked size, transmit the data after dividing into the checked size and + * saving in the Socket n TX buffer. + */ +#define Sn_TX_FSR(N) \ + (_W5500_IO_BASE_ + (0x0020 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory read pointer register address(R) + * @details @ref Sn_TX_RD is initialized by OPEN command. However, if + * Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with + * TCP. After its initialization, it is auto-increased by SEND command. SEND + * command transmits the saved data from the current @ref Sn_TX_RD to the @ref + * Sn_TX_WR in the Socket n TX Buffer. After transmitting the saved data, the + * SEND command increases the @ref Sn_TX_RD as same as the @ref Sn_TX_WR. If its + * increment value exceeds the maximum value 0xFFFF, (greater than 0x10000 and + * the carry bit occurs), then the carry bit is ignored and will automatically + * update with the lower 16bits value. + */ +#define Sn_TX_RD(N) \ + (_W5500_IO_BASE_ + (0x0022 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Transmit memory write pointer register address(R/W) + * @details @ref Sn_TX_WR is initialized by OPEN command. However, if + * Sn_MR(P[3:0]) is TCP mode(001, it is re-initialized while connecting with + * TCP.\n It should be read or be updated like as follows.\n + * 1. Read the starting address for saving the transmitting data.\n + * 2. Save the transmitting data from the starting address of Socket n TX + * buffer.\n + * 3. After saving the transmitting data, update @ref Sn_TX_WR to the increased + * value as many as transmitting data size. If the increment value exceeds the + * maximum value 0xFFFF(greater than 0x10000 and the carry bit occurs), then the + * carry bit is ignored and will automatically update with the lower 16bits + * value.\n + * 4. Transmit the saved data in Socket n TX Buffer by using SEND/SEND command + */ +#define Sn_TX_WR(N) \ + (_W5500_IO_BASE_ + (0x0024 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Received data size register(R) + * @details @ref Sn_RX_RSR indicates the data size received and saved in Socket + * n RX Buffer. + * @ref Sn_RX_RSR does not exceed the @ref Sn_RXBUF_SIZE and is calculated as + * the difference between �Socket n RX Write Pointer (@ref Sn_RX_WR)and �Socket + * n RX Read Pointer (@ref Sn_RX_RD) + */ +#define Sn_RX_RSR(N) \ + (_W5500_IO_BASE_ + (0x0026 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Read point of Receive memory(R/W) + * @details @ref Sn_RX_RD is initialized by OPEN command. Make sure to be read + * or updated as follows.\n + * 1. Read the starting save address of the received data.\n + * 2. Read data from the starting address of Socket n RX Buffer.\n + * 3. After reading the received data, Update @ref Sn_RX_RD to the increased + * value as many as the reading size. If the increment value exceeds the maximum + * value 0xFFFF, that is, is greater than 0x10000 and the carry bit occurs, + * update with the lower 16bits value ignored the carry bit.\n + * 4. Order RECV command is for notifying the updated @ref Sn_RX_RD to W5500. + */ +#define Sn_RX_RD(N) \ + (_W5500_IO_BASE_ + (0x0028 << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Write point of Receive memory(R) + * @details @ref Sn_RX_WR is initialized by OPEN command and it is + * auto-increased by the data reception. If the increased value exceeds the + * maximum value 0xFFFF, (greater than 0x10000 and the carry bit occurs), then + * the carry bit is ignored and will automatically update with the lower 16bits + * value. + */ +#define Sn_RX_WR(N) \ + (_W5500_IO_BASE_ + (0x002A << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief socket interrupt mask register(R) + * @details @ref Sn_IMR masks the interrupt of Socket n. + * Each bit corresponds to each bit of @ref Sn_IR. When a Socket n Interrupt is + * occurred and the corresponding bit of @ref Sn_IMR is the corresponding bit of + * @ref Sn_IR becomes When both the corresponding bit of @ref Sn_IMR and @ref + * Sn_IR are and the n-th bit of @ref IR is Host is interrupted by asserted INTn + * PIN to low. + */ +#define Sn_IMR(N) \ + (_W5500_IO_BASE_ + (0x002C << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Fragment field value in IP header register(R/W) + * @details @ref Sn_FRAG configures the FRAG(Fragment field in IP header). + */ +#define Sn_FRAG(N) \ + (_W5500_IO_BASE_ + (0x002D << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +/** + * @ingroup Socket_register_group + * @brief Keep Alive Timer register(R/W) + * @details @ref Sn_KPALVTR configures the transmitting timer of �KEEP + * ALIVE(KA)packet of SOCKETn. It is valid only in TCP mode, and ignored in + * other modes. The time unit is 5s. KA packet is transmittable after @ref Sn_SR + * is changed to SOCK_ESTABLISHED and after the data is transmitted or received + * to/from a peer at least once. In case of '@ref Sn_KPALVTR > 0', W5500 + * automatically transmits KA packet after time-period for checking the TCP + * connection (Auto-keepalive-process). In case of '@ref Sn_KPALVTR = 0', + * Auto-keep-alive-process will not operate, and KA packet can be transmitted by + * SEND_KEEP command by the host (Manual-keep-alive-process). + * Manual-keep-alive-process is ignored in case of '@ref Sn_KPALVTR > 0'. + */ +#define Sn_KPALVTR(N) \ + (_W5500_IO_BASE_ + (0x002F << 8) + (WIZCHIP_SREG_BLOCK(N) << 3)) + +//#define Sn_TSR(N) (_W5500_IO_BASE_ + (0x0030 << 8) + +//(WIZCHIP_SREG_BLOCK(N) << 3)) + +//----------------------------- W5500 Register values +//----------------------------- + +/* MODE register values */ +/** + * @brief Reset + * @details If this bit is All internal registers will be initialized. It will + * be automatically cleared as after S/W reset. + */ +#define MR_RST 0x80 + +/** + * @brief Wake on LAN + * @details 0 : Disable WOL mode\n + * 1 : Enable WOL mode\n + * If WOL mode is enabled and the received magic packet over UDP has been + * normally processed, the Interrupt PIN (INTn) asserts to low. When using WOL + * mode, the UDP Socket should be opened with any source port number. (Refer to + * Socket n Mode Register (@ref Sn_MR) for opening Socket.) + * @note The magic packet over UDP supported by W5500 consists of 6 bytes + * synchronization stream (xFFFFFFFFFFFF and 16 times Target MAC address stream + * in UDP payload. The options such like password are ignored. You can use any + * UDP source port number for WOL mode. + */ +#define MR_WOL 0x20 + +/** + * @brief Ping block + * @details 0 : Disable Ping block\n + * 1 : Enable Ping block\n + * If the bit is it blocks the response to a ping request. + */ +#define MR_PB 0x10 + +/** + * @brief Enable PPPoE + * @details 0 : DisablePPPoE mode\n + * 1 : EnablePPPoE mode\n + * If you use ADSL, this bit should be + */ +#define MR_PPPOE 0x08 + +/** + * @brief Enable UDP_FORCE_ARP CHECHK + * @details 0 : Disable Force ARP mode\n + * 1 : Enable Force ARP mode\n + * In Force ARP mode, It forces on sending ARP Request whenever data is sent. + */ +#define MR_FARP 0x02 + +/* IR register values */ +/** + * @brief Check IP conflict. + * @details Bit is set as when own source IP address is same with the sender IP + * address in the received ARP request. + */ +#define IR_CONFLICT 0x80 + +/** + * @brief Get the destination unreachable message in UDP sending. + * @details When receiving the ICMP (Destination port unreachable) packet, this + * bit is set as When this bit is Destination Information such as IP address + * and Port number may be checked with the corresponding @ref UIPR & @ref + * UPORTR. + */ +#define IR_UNREACH 0x40 + +/** + * @brief Get the PPPoE close message. + * @details When PPPoE is disconnected during PPPoE mode, this bit is set. + */ +#define IR_PPPoE 0x20 + +/** + * @brief Get the magic packet interrupt. + * @details When WOL mode is enabled and receives the magic packet over UDP, + * this bit is set. + */ +#define IR_MP 0x10 + +/* PHYCFGR register value */ +#define PHYCFGR_RST ~(1 << 7) //< For PHY reset, must operate AND mask. +#define PHYCFGR_OPMD (1 << 6) // Configre PHY with OPMDC value +#define PHYCFGR_OPMDC_ALLA (7 << 3) +#define PHYCFGR_OPMDC_PDOWN (6 << 3) +#define PHYCFGR_OPMDC_NA (5 << 3) +#define PHYCFGR_OPMDC_100FA (4 << 3) +#define PHYCFGR_OPMDC_100F (3 << 3) +#define PHYCFGR_OPMDC_100H (2 << 3) +#define PHYCFGR_OPMDC_10F (1 << 3) +#define PHYCFGR_OPMDC_10H (0 << 3) +#define PHYCFGR_DPX_FULL (1 << 2) +#define PHYCFGR_DPX_HALF (0 << 2) +#define PHYCFGR_SPD_100 (1 << 1) +#define PHYCFGR_SPD_10 (0 << 1) +#define PHYCFGR_LNK_ON (1 << 0) +#define PHYCFGR_LNK_OFF (0 << 0) + +/* IMR register values */ +/** + * @brief IP Conflict Interrupt Mask. + * @details 0: Disable IP Conflict Interrupt\n + * 1: Enable IP Conflict Interrupt + */ +#define IM_IR7 0x80 + +/** + * @brief Destination unreachable Interrupt Mask. + * @details 0: Disable Destination unreachable Interrupt\n + * 1: Enable Destination unreachable Interrupt + */ +#define IM_IR6 0x40 + +/** + * @brief PPPoE Close Interrupt Mask. + * @details 0: Disable PPPoE Close Interrupt\n + * 1: Enable PPPoE Close Interrupt + */ +#define IM_IR5 0x20 + +/** + * @brief Magic Packet Interrupt Mask. + * @details 0: Disable Magic Packet Interrupt\n + * 1: Enable Magic Packet Interrupt + */ +#define IM_IR4 0x10 + +/* Sn_MR Default values */ +/** + * @brief Support UDP Multicasting + * @details 0 : disable Multicasting\n + * 1 : enable Multicasting\n + * This bit is applied only during UDP mode(P[3:0] = 010.\n + * To use multicasting, @ref Sn_DIPR & @ref Sn_DPORT should be respectively + * configured with the multicast group IP address & port number before Socket n + * is opened by OPEN command of @ref Sn_CR. + */ +#define Sn_MR_MULTI 0x80 + +/** + * @brief Broadcast block in UDP Multicasting. + * @details 0 : disable Broadcast Blocking\n + * 1 : enable Broadcast Blocking\n + * This bit blocks to receive broadcasting packet during UDP mode(P[3:0] = + * 010.\m In addition, This bit does when MACRAW mode(P[3:0] = 100 + */ +#define Sn_MR_BCASTB 0x40 + +/** + * @brief No Delayed Ack(TCP), Multicast flag + * @details 0 : Disable No Delayed ACK option\n + * 1 : Enable No Delayed ACK option\n + * This bit is applied only during TCP mode (P[3:0] = 001.\n + * When this bit is It sends the ACK packet without delay as soon as a Data + * packet is received from a peer.\n When this bit is It sends the ACK packet + * after waiting for the timeout time configured by @ref _RTR_. + */ +#define Sn_MR_ND 0x20 + +/** + * @brief Unicast Block in UDP Multicasting + * @details 0 : disable Unicast Blocking\n + * 1 : enable Unicast Blocking\n + * This bit blocks receiving the unicast packet during UDP mode(P[3:0] = 010 and + * MULTI = + */ +#define Sn_MR_UCASTB 0x10 + +/** + * @brief MAC LAYER RAW SOCK + * @details This configures the protocol mode of Socket n. + * @note MACRAW mode should be only used in Socket 0. + */ +#define Sn_MR_MACRAW 0x04 + +#define Sn_MR_IPRAW 0x03 /**< IP LAYER RAW SOCK */ + +/** + * @brief UDP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_UDP 0x02 + +/** + * @brief TCP + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_TCP 0x01 + +/** + * @brief Unused socket + * @details This configures the protocol mode of Socket n. + */ +#define Sn_MR_CLOSE 0x00 + +/* Sn_MR values used with Sn_MR_MACRAW */ +/** + * @brief MAC filter enable in @ref Sn_MR_MACRAW mode + * @details 0 : disable MAC Filtering\n + * 1 : enable MAC Filtering\n + * This bit is applied only during MACRAW mode(P[3:0] = 100.\n + * When set as W5500 can only receive broadcasting packet or packet sent to + * itself. When this bit is W5500 can receive all packets on Ethernet. If user + * wants to implement Hybrid TCP/IP stack, it is recommended that this bit is + * set as for reducing host overhead to process the all received packets. + */ +#define Sn_MR_MFEN Sn_MR_MULTI + +/** + * @brief Multicast Blocking in @ref Sn_MR_MACRAW mode + * @details 0 : using IGMP version 2\n + * 1 : using IGMP version 1\n + * This bit is applied only during UDP mode(P[3:0] = 010 and MULTI = + * It configures the version for IGMP messages (Join/Leave/Report). + */ +#define Sn_MR_MMB Sn_MR_ND + +/** + * @brief IPv6 packet Blocking in @ref Sn_MR_MACRAW mode + * @details 0 : disable IPv6 Blocking\n + * 1 : enable IPv6 Blocking\n + * This bit is applied only during MACRAW mode (P[3:0] = 100. It blocks to + * receiving the IPv6 packet. + */ +#define Sn_MR_MIP6B Sn_MR_UCASTB + +/* Sn_MR value used with Sn_MR_UDP & Sn_MR_MULTI */ +/** + * @brief IGMP version used in UDP mulitcasting + * @details 0 : disable Multicast Blocking\n + * 1 : enable Multicast Blocking\n + * This bit is applied only when MACRAW mode(P[3:0] = 100. It blocks to receive + * the packet with multicast MAC address. + */ +#define Sn_MR_MC Sn_MR_ND + +/* Sn_MR alternate values */ +/** + * @brief For Berkeley Socket API + */ +#define SOCK_STREAM Sn_MR_TCP + +/** + * @brief For Berkeley Socket API + */ +#define SOCK_DGRAM Sn_MR_UDP + +/* Sn_CR values */ +/** + * @brief Initialize or open socket + * @details Socket n is initialized and opened according to the protocol + * selected in Sn_MR(P3:P0). The table below shows the value of @ref Sn_SR + * corresponding to @ref Sn_MR.\n + * + * + * + * + *
\b Sn_MR (P[3:0])\b Sn_SR
Sn_MR_CLOSE + * (000)
Sn_MR_TCP (001) SOCK_INIT (0x13)
Sn_MR_UDP (010) SOCK_UDP (0x22)
S0_MR_MACRAW (100) SOCK_MACRAW (0x02)
+ */ +#define Sn_CR_OPEN 0x01 + +/** + * @brief Wait connection request in TCP mode(Server mode) + * @details This is valid only in TCP mode (\ref Sn_MR(P3:P0) = \ref Sn_MR_TCP). + * In this mode, Socket n operates as a TCP serverand waits for + * connection-request (SYN packet) from any TCP client The @ref Sn_SR changes + * the state from \ref SOCK_INIT to \ref SOCKET_LISTEN. When a TCP + * clientconnection request is successfully established, the @ref Sn_SR changes + * from SOCK_LISTEN to SOCK_ESTABLISHED and the @ref Sn_IR(0) becomes But when a + * TCP clientconnection request is failed, @ref Sn_IR(3) becomes and the status + * of @ref Sn_SR changes to SOCK_CLOSED. + */ +#define Sn_CR_LISTEN 0x02 + +/** + * @brief Send connection request in TCP mode(Client mode) + * @details To connect, a connect-request (SYN packet) is sent to TCP + * serverconfigured by @ref Sn_DIPR & Sn_DPORT(destination address & port). + * If the connect-request is successful, the @ref Sn_SR is changed to @ref + * SOCK_ESTABLISHED and the Sn_IR(0) becomes \n\n The connect-request fails in + * the following three cases.\n + * 1. When a @b ARPTO occurs (@ref Sn_IR[3] = ) because destination hardware + * address is not acquired through the ARP-process.\n + * 2. When a @b SYN/ACK packet is not received and @b TCPTO (Sn_IR(3) = )\n + * 3. When a @b RST packet is received instead of a @b SYN/ACK packet. In these + * cases, @ref Sn_SR is changed to @ref SOCK_CLOSED. + * @note This is valid only in TCP mode and operates when Socket n acts as + * TCP client + */ +#define Sn_CR_CONNECT 0x04 + +/** + * @brief Send closing request in TCP mode + * @details Regardless of TCP serveror TCP client the DISCON + * command processes the disconnect-process (b>Active closeor Passive + * close.\n + * @par Active close + * it transmits disconnect-request(FIN packet) to the connected peer\n + * @par Passive close + * When FIN packet is received from peer, a FIN packet is replied back to the + * peer.\n + * @details When the disconnect-process is successful (that is, FIN/ACK packet + * is received successfully), @ref Sn_SR is changed to @ref SOCK_CLOSED.\n + * Otherwise, TCPTO occurs (\ref Sn_IR(3)='1') and then @ref Sn_SR is changed to + * @ref SOCK_CLOSED. + * @note Valid only in TCP mode. + */ +#define Sn_CR_DISCON 0x08 + +/** + * @brief Close socket + * @details Sn_SR is changed to @ref SOCK_CLOSED. + */ +#define Sn_CR_CLOSE 0x10 + +/** + * @brief Update TX buffer pointer and send data + * @details SEND transmits all the data in the Socket n TX buffer.\n + * For more details, please refer to Socket n TX Free Size Register (@ref + * Sn_TX_FSR), Socket n, TX Write Pointer Register(@ref Sn_TX_WR), and Socket n + * TX Read Pointer Register(@ref Sn_TX_RD). + */ +#define Sn_CR_SEND 0x20 + +/** + * @brief Send data with MAC address, so without ARP process + * @details The basic operation is same as SEND.\n + * Normally SEND transmits data after destination hardware address is acquired + * by the automatic ARP-process(Address Resolution Protocol).\n But SEND_MAC + * transmits data without the automatic ARP-process.\n In this case, the + * destination hardware address is acquired from @ref Sn_DHAR configured by + * host, instead of APR-process. + * @note Valid only in UDP mode. + */ +#define Sn_CR_SEND_MAC 0x21 + +/** + * @brief Send keep alive message + * @details It checks the connection status by sending 1byte keep-alive + * packet.\n If the peer can not respond to the keep-alive packet during timeout + * time, the connection is terminated and the timeout interrupt will occur. + * @note Valid only in TCP mode. + */ +#define Sn_CR_SEND_KEEP 0x22 + +/** + * @brief Update RX buffer pointer and receive data + * @details RECV completes the processing of the received data in Socket n RX + * Buffer by using a RX read pointer register (@ref Sn_RX_RD).\n For more + * details, refer to Socket n RX Received Size Register (@ref Sn_RX_RSR), Socket + * n RX Write Pointer Register (@ref Sn_RX_WR), and Socket n RX Read Pointer + * Register (@ref Sn_RX_RD). + */ +#define Sn_CR_RECV 0x40 + +/* Sn_IR values */ +/** + * @brief SEND_OK Interrupt + * @details This is issued when SEND command is completed. + */ +#define Sn_IR_SENDOK 0x10 + +/** + * @brief TIMEOUT Interrupt + * @details This is issued when ARPTO or TCPTO occurs. + */ +#define Sn_IR_TIMEOUT 0x08 + +/** + * @brief RECV Interrupt + * @details This is issued whenever data is received from a peer. + */ +#define Sn_IR_RECV 0x04 + +/** + * @brief DISCON Interrupt + * @details This is issued when FIN or FIN/ACK packet is received from a peer. + */ +#define Sn_IR_DISCON 0x02 + +/** + * @brief CON Interrupt + * @details This is issued one time when the connection with peer is successful + * and then @ref Sn_SR is changed to @ref SOCK_ESTABLISHED. + */ +#define Sn_IR_CON 0x01 + +/* Sn_SR values */ +/** + * @brief Closed + * @details This indicates that Socket n is released.\n + * When DICON, CLOSE command is ordered, or when a timeout occurs, it is changed + * to @ref SOCK_CLOSED regardless of previous status. + */ +#define SOCK_CLOSED 0x00 + +/** + * @brief Initiate state + * @details This indicates Socket n is opened with TCP mode.\n + * It is changed to @ref SOCK_INIT when @ref Sn_MR(P[3:0]) = 001 and OPEN + * command is ordered.\n After @ref SOCK_INIT, user can use LISTEN /CONNECT + * command. + */ +#define SOCK_INIT 0x13 + +/** + * @brief Listen state + * @details This indicates Socket n is operating as TCP servermode and + * waiting for connection-request (SYN packet) from a peer TCP client.\n + * It will change to @ref SOCK_ESTALBLISHED when the connection-request is + * successfully accepted.\n Otherwise it will change to @ref SOCK_CLOSED after + * TCPTO @ref Sn_IR(TIMEOUT) = '1') is occurred. + */ +#define SOCK_LISTEN 0x14 + +/** + * @brief Connection state + * @details This indicates Socket n sent the connect-request packet (SYN packet) + * to a peer.\n It is temporarily shown when @ref Sn_SR is changed from @ref + * SOCK_INIT to @ref SOCK_ESTABLISHED by CONNECT command.\n If + * connect-accept(SYN/ACK packet) is received from the peer at SOCK_SYNSENT, it + * changes to @ref SOCK_ESTABLISHED.\n Otherwise, it changes to @ref SOCK_CLOSED + * after TCPTO (@ref Sn_IR[TIMEOUT] = '1') is occurred. + */ +#define SOCK_SYNSENT 0x15 + +/** + * @brief Connection state + * @details It indicates Socket n successfully received the connect-request + * packet (SYN packet) from a peer.\n If socket n sends the response (SYN/ACK + * packet) to the peer successfully, it changes to @ref SOCK_ESTABLISHED. \n If + * not, it changes to @ref SOCK_CLOSED after timeout (@ref Sn_IR[TIMEOUT] = '1') + * is occurred. + */ +#define SOCK_SYNRECV 0x16 + +/** + * @brief Success to connect + * @details This indicates the status of the connection of Socket n.\n + * It changes to @ref SOCK_ESTABLISHED when the TCP SERVERprocessed the + * SYN packet from the TCP CLIENTduring @ref SOCK_LISTEN, or when the + * CONNECT command is successful.\n During @ref SOCK_ESTABLISHED, DATA packet + * can be transferred using SEND or RECV command. + */ +#define SOCK_ESTABLISHED 0x17 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and + * passive-close.\n When Disconnect-process is successfully completed, or when + * timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_FIN_WAIT 0x18 + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and + * passive-close.\n When Disconnect-process is successfully completed, or when + * timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_CLOSING 0x1A + +/** + * @brief Closing state + * @details These indicate Socket n is closing.\n + * These are shown in disconnect-process such as active-close and + * passive-close.\n When Disconnect-process is successfully completed, or when + * timeout occurs, these change to @ref SOCK_CLOSED. + */ +#define SOCK_TIME_WAIT 0x1B + +/** + * @brief Closing state + * @details This indicates Socket n received the disconnect-request (FIN packet) + * from the connected peer.\n This is half-closing status, and data can be + * transferred.\n For full-closing, DISCON command is used. But For + * just-closing, CLOSE command is used. + */ +#define SOCK_CLOSE_WAIT 0x1C + +/** + * @brief Closing state + * @details This indicates Socket n is waiting for the response (FIN/ACK packet) + * to the disconnect-request (FIN packet) by passive-close.\n It changes to @ref + * SOCK_CLOSED when Socket n received the response successfully, or when + * timeout(@ref Sn_IR[TIMEOUT] = '1') is occurred. + */ +#define SOCK_LAST_ACK 0x1D + +/** + * @brief UDP socket + * @details This indicates Socket n is opened in UDP mode(@ref Sn_MR(P[3:0]) = + * '010').\n It changes to SOCK_UDP when @ref Sn_MR(P[3:0]) = '010' and @ref + * Sn_CR_OPEN command is ordered.\n Unlike TCP mode, data can be transfered + * without the connection-process. + */ +#define SOCK_UDP 0x22 + +#define SOCK_IPRAW 0x32 /**< IP raw mode socket */ + +/** + * @brief MAC raw mode socket + * @details This indicates Socket 0 is opened in MACRAW mode (S0_MR(P[3:0]) = + * 100and is valid only in Socket 0.\n It changes to SOCK_MACRAW when + * S0_MR(P[3:0] = 100and OPEN command is ordered.\n Like UDP mode socket, MACRAW + * mode Socket 0 can transfer a MAC packet (Ethernet frame) without the + * connection-process. + */ +#define SOCK_MACRAW 0x42 + +//#define SOCK_PPPOE 0x5F + +/* IP PROTOCOL */ +#define IPPROTO_IP 0 //< Dummy for IP +#define IPPROTO_ICMP 1 //< Control message protocol +#define IPPROTO_IGMP 2 //< Internet group management protocol +#define IPPROTO_GGP 3 //< Gateway^2 (deprecated) +#define IPPROTO_TCP 6 //< TCP +#define IPPROTO_PUP 12 //< PUP +#define IPPROTO_UDP 17 //< UDP +#define IPPROTO_IDP 22 //< XNS idp +#define IPPROTO_ND 77 //< UNOFFICIAL net disk protocol +#define IPPROTO_RAW 255 //< Raw IP packet + +/** + * @brief Enter a critical section + * + * @details It is provided to protect your shared code which are executed + * without distribution. \n \n + * + * In non-OS environment, It can be just implemented by disabling whole + * interrupt.\n In OS environment, You can replace it to critical section api + * supported by OS. + * + * \sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * \sa WIZCHIP_CRITICAL_EXIT() + */ +#define WIZCHIP_CRITICAL_ENTER() WIZCHIP.CRIS._enter() + +#ifdef _exit +#undef _exit +#endif + +/** + * @brief Exit a critical section + * + * @details It is provided to protect your shared code which are executed + * without distribution. \n\n + * + * In non-OS environment, It can be just implemented by disabling whole + * interrupt. \n In OS environment, You can replace it to critical section api + * supported by OS. + * + * @sa WIZCHIP_READ(), WIZCHIP_WRITE(), WIZCHIP_READ_BUF(), WIZCHIP_WRITE_BUF() + * @sa WIZCHIP_CRITICAL_ENTER() + */ +#define WIZCHIP_CRITICAL_EXIT() WIZCHIP.CRIS._exit() + +//////////////////////// +// Basic I/O Function // +//////////////////////// + +/** + * @ingroup Basic_IO_function + * @brief It reads 1 byte value from a register. + * @param AddrSel Register address + * @return The value of register + */ +uint8_t WIZCHIP_READ(uint32_t AddrSel); + +/** + * @ingroup Basic_IO_function + * @brief It writes 1 byte value to a register. + * @param AddrSel Register address + * @param wb Write data + * @return void + */ +void WIZCHIP_WRITE(uint32_t AddrSel, uint8_t wb); + +/** + * @ingroup Basic_IO_function + * @brief It reads sequence data from registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to read data + * @param len Data length + */ +void WIZCHIP_READ_BUF(uint32_t AddrSel, uint8_t *pBuf, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It writes sequence data to registers. + * @param AddrSel Register address + * @param pBuf Pointer buffer to write data + * @param len Data length + */ +void WIZCHIP_WRITE_BUF(uint32_t AddrSel, uint8_t *pBuf, uint16_t len); + +///////////////////////////////// +// Common Register I/O function // +///////////////////////////////// +/** + * @ingroup Common_register_access_function + * @brief Set Mode Register + * @param (uint8_t)mr The value to be set. + * @sa getMR() + */ +#define setMR(mr) WIZCHIP_WRITE(MR, mr) + +/** + * @ingroup Common_register_access_function + * @brief Get Mode Register + * @return uint8_t. The value of Mode register. + * @sa setMR() + */ +#define getMR() WIZCHIP_READ(MR) + +/** + * @ingroup Common_register_access_function + * @brief Set gateway IP address + * @param (uint8_t*)gar Pointer variable to set gateway IP address. It should be + * allocated 4 bytes. + * @sa getGAR() + */ +#define setGAR(gar) WIZCHIP_WRITE_BUF(GAR, gar, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get gateway IP address + * @param (uint8_t*)gar Pointer variable to get gateway IP address. It should be + * allocated 4 bytes. + * @sa setGAR() + */ +#define getGAR(gar) WIZCHIP_READ_BUF(GAR, gar, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set subnet mask address + * @param (uint8_t*)subr Pointer variable to set subnet mask address. It should + * be allocated 4 bytes. + * @sa getSUBR() + */ +#define setSUBR(subr) WIZCHIP_WRITE_BUF(SUBR, subr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get subnet mask address + * @param (uint8_t*)subr Pointer variable to get subnet mask address. It should + * be allocated 4 bytes. + * @sa setSUBR() + */ +#define getSUBR(subr) WIZCHIP_READ_BUF(SUBR, subr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set local MAC address + * @param (uint8_t*)shar Pointer variable to set local MAC address. It should be + * allocated 6 bytes. + * @sa getSHAR() + */ +#define setSHAR(shar) WIZCHIP_WRITE_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Get local MAC address + * @param (uint8_t*)shar Pointer variable to get local MAC address. It should be + * allocated 6 bytes. + * @sa setSHAR() + */ +#define getSHAR(shar) WIZCHIP_READ_BUF(SHAR, shar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Set local IP address + * @param (uint8_t*)sipr Pointer variable to set local IP address. It should be + * allocated 4 bytes. + * @sa getSIPR() + */ +#define setSIPR(sipr) WIZCHIP_WRITE_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get local IP address + * @param (uint8_t*)sipr Pointer variable to get local IP address. It should be + * allocated 4 bytes. + * @sa setSIPR() + */ +#define getSIPR(sipr) WIZCHIP_READ_BUF(SIPR, sipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Set INTLEVEL register + * @param (uint16_t)intlevel Value to set @ref INTLEVEL register. + * @sa getINTLEVEL() + */ +#define setINTLEVEL(intlevel) \ + { \ + WIZCHIP_WRITE(INTLEVEL, (uint8_t)(intlevel >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(INTLEVEL, 1), (uint8_t)intlevel); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get INTLEVEL register + * @return uint16_t. Value of @ref INTLEVEL register. + * @sa setINTLEVEL() + */ +// M20150401 : Type explict declaration +/* +#define getINTLEVEL() \ + ((WIZCHIP_READ(INTLEVEL) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL,1))) +*/ +#define getINTLEVEL() \ + (((uint16_t)WIZCHIP_READ(INTLEVEL) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(INTLEVEL, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref IR register + * @param (uint8_t)ir Value to set @ref IR register. + * @sa getIR() + */ +#define setIR(ir) WIZCHIP_WRITE(IR, (ir & 0xF0)) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref IR register + * @return uint8_t. Value of @ref IR register. + * @sa setIR() + */ +#define getIR() (WIZCHIP_READ(IR) & 0xF0) +/** + * @ingroup Common_register_access_function + * @brief Set @ref _IMR_ register + * @param (uint8_t)imr Value to set @ref _IMR_ register. + * @sa getIMR() + */ +#define setIMR(imr) WIZCHIP_WRITE(_IMR_, imr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref _IMR_ register + * @return uint8_t. Value of @ref _IMR_ register. + * @sa setIMR() + */ +#define getIMR() WIZCHIP_READ(_IMR_) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref SIR register + * @param (uint8_t)sir Value to set @ref SIR register. + * @sa getSIR() + */ +#define setSIR(sir) WIZCHIP_WRITE(SIR, sir) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref SIR register + * @return uint8_t. Value of @ref SIR register. + * @sa setSIR() + */ +#define getSIR() WIZCHIP_READ(SIR) +/** + * @ingroup Common_register_access_function + * @brief Set @ref SIMR register + * @param (uint8_t)simr Value to set @ref SIMR register. + * @sa getSIMR() + */ +#define setSIMR(simr) WIZCHIP_WRITE(SIMR, simr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref SIMR register + * @return uint8_t. Value of @ref SIMR register. + * @sa setSIMR() + */ +#define getSIMR() WIZCHIP_READ(SIMR) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref _RTR_ register + * @param (uint16_t)rtr Value to set @ref _RTR_ register. + * @sa getRTR() + */ +#define setRTR(rtr) \ + { \ + WIZCHIP_WRITE(_RTR_, (uint8_t)(rtr >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(_RTR_, 1), (uint8_t)rtr); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref _RTR_ register + * @return uint16_t. Value of @ref _RTR_ register. + * @sa setRTR() + */ +// M20150401 : Type explict declaration +/* +#define getRTR() \ + ((WIZCHIP_READ(_RTR_) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_,1))) +*/ +#define getRTR() \ + (((uint16_t)WIZCHIP_READ(_RTR_) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(_RTR_, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref _RCR_ register + * @param (uint8_t)rcr Value to set @ref _RCR_ register. + * @sa getRCR() + */ +#define setRCR(rcr) WIZCHIP_WRITE(_RCR_, rcr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref _RCR_ register + * @return uint8_t. Value of @ref _RCR_ register. + * @sa setRCR() + */ +#define getRCR() WIZCHIP_READ(_RCR_) + +//================================================== test done +//=========================================================== + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PTIMER register + * @param (uint8_t)ptimer Value to set @ref PTIMER register. + * @sa getPTIMER() + */ +#define setPTIMER(ptimer) WIZCHIP_WRITE(PTIMER, ptimer) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PTIMER register + * @return uint8_t. Value of @ref PTIMER register. + * @sa setPTIMER() + */ +#define getPTIMER() WIZCHIP_READ(PTIMER) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PMAGIC register + * @param (uint8_t)pmagic Value to set @ref PMAGIC register. + * @sa getPMAGIC() + */ +#define setPMAGIC(pmagic) WIZCHIP_WRITE(PMAGIC, pmagic) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PMAGIC register + * @return uint8_t. Value of @ref PMAGIC register. + * @sa setPMAGIC() + */ +#define getPMAGIC() WIZCHIP_READ(PMAGIC) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PHAR address + * @param (uint8_t*)phar Pointer variable to set PPP destination MAC register + * address. It should be allocated 6 bytes. + * @sa getPHAR() + */ +#define setPHAR(phar) WIZCHIP_WRITE_BUF(PHAR, phar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PHAR address + * @param (uint8_t*)phar Pointer variable to PPP destination MAC register + * address. It should be allocated 6 bytes. + * @sa setPHAR() + */ +#define getPHAR(phar) WIZCHIP_READ_BUF(PHAR, phar, 6) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PSID register + * @param (uint16_t)psid Value to set @ref PSID register. + * @sa getPSID() + */ +#define setPSID(psid) \ + { \ + WIZCHIP_WRITE(PSID, (uint8_t)(psid >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PSID, 1), (uint8_t)psid); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PSID register + * @return uint16_t. Value of @ref PSID register. + * @sa setPSID() + */ +// uint16_t getPSID(void); +// M20150401 : Type explict declaration +/* +#define getPSID() \ + ((WIZCHIP_READ(PSID) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID,1))) +*/ +#define getPSID() \ + (((uint16_t)WIZCHIP_READ(PSID) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PSID, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PMRU register + * @param (uint16_t)pmru Value to set @ref PMRU register. + * @sa getPMRU() + */ +#define setPMRU(pmru) \ + { \ + WIZCHIP_WRITE(PMRU, (uint8_t)(pmru >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(PMRU, 1), (uint8_t)pmru); \ + } + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PMRU register + * @return uint16_t. Value of @ref PMRU register. + * @sa setPMRU() + */ +// M20150401 : Type explict declaration +/* +#define getPMRU() \ + ((WIZCHIP_READ(PMRU) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU,1))) +*/ +#define getPMRU() \ + (((uint16_t)WIZCHIP_READ(PMRU) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(PMRU, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Get unreachable IP address + * @param (uint8_t*)uipr Pointer variable to get unreachable IP address. It + * should be allocated 4 bytes. + */ +// M20150401 : Size Error of UIPR (6 -> 4) +/* +#define getUIPR(uipr) \ + WIZCHIP_READ_BUF(UIPR,uipr,6) +*/ +#define getUIPR(uipr) WIZCHIP_READ_BUF(UIPR, uipr, 4) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref UPORTR register + * @return uint16_t. Value of @ref UPORTR register. + */ +// M20150401 : Type explict declaration +/* +#define getUPORTR() \ + ((WIZCHIP_READ(UPORTR) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR,1))) +*/ +#define getUPORTR() \ + (((uint16_t)WIZCHIP_READ(UPORTR) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(UPORTR, 1))) + +/** + * @ingroup Common_register_access_function + * @brief Set @ref PHYCFGR register + * @param (uint8_t)phycfgr Value to set @ref PHYCFGR register. + * @sa getPHYCFGR() + */ +#define setPHYCFGR(phycfgr) WIZCHIP_WRITE(PHYCFGR, phycfgr) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref PHYCFGR register + * @return uint8_t. Value of @ref PHYCFGR register. + * @sa setPHYCFGR() + */ +#define getPHYCFGR() WIZCHIP_READ(PHYCFGR) + +/** + * @ingroup Common_register_access_function + * @brief Get @ref VERSIONR register + * @return uint8_t. Value of @ref VERSIONR register. + */ +#define getVERSIONR() WIZCHIP_READ(VERSIONR) + +///////////////////////////////////// + +/////////////////////////////////// +// Socket N register I/O function // +/////////////////////////////////// +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)mr Value to set @ref Sn_MR + * @sa getSn_MR() + */ +#define setSn_MR(sn, mr) WIZCHIP_WRITE(Sn_MR(sn), mr) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_MR. + * @sa setSn_MR() + */ +#define getSn_MR(sn) WIZCHIP_READ(Sn_MR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)cr Value to set @ref Sn_CR + * @sa getSn_CR() + */ +#define setSn_CR(sn, cr) WIZCHIP_WRITE(Sn_CR(sn), cr) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_CR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_CR. + * @sa setSn_CR() + */ +#define getSn_CR(sn) WIZCHIP_READ(Sn_CR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)ir Value to set @ref Sn_IR + * @sa getSn_IR() + */ +#define setSn_IR(sn, ir) WIZCHIP_WRITE(Sn_IR(sn), (ir & 0x1F)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_IR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_IR. + * @sa setSn_IR() + */ +#define getSn_IR(sn) (WIZCHIP_READ(Sn_IR(sn)) & 0x1F) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)imr Value to set @ref Sn_IMR + * @sa getSn_IMR() + */ +#define setSn_IMR(sn, imr) WIZCHIP_WRITE(Sn_IMR(sn), (imr & 0x1F)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_IMR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_IMR. + * @sa setSn_IMR() + */ +#define getSn_IMR(sn) (WIZCHIP_READ(Sn_IMR(sn)) & 0x1F) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_SR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_SR. + */ +#define getSn_SR(sn) WIZCHIP_READ(Sn_SR(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)port Value to set @ref Sn_PORT. + * @sa getSn_PORT() + */ +#define setSn_PORT(sn, port) \ + { \ + WIZCHIP_WRITE(Sn_PORT(sn), (uint8_t)(port >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_PORT(sn), 1), (uint8_t)port); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_PORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_PORT. + * @sa setSn_PORT() + */ +// M20150401 : Type explict declaration +/* +#define getSn_PORT(sn) \ + ((WIZCHIP_READ(Sn_PORT(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn),1))) +*/ +#define getSn_PORT(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_PORT(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_PORT(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DHAR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dhar Pointer variable to set socket n destination hardware + * address. It should be allocated 6 bytes. + * @sa getSn_DHAR() + */ +#define setSn_DHAR(sn, dhar) WIZCHIP_WRITE_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dhar Pointer variable to get socket n destination hardware + * address. It should be allocated 6 bytes. + * @sa setSn_DHAR() + */ +#define getSn_DHAR(sn, dhar) WIZCHIP_READ_BUF(Sn_DHAR(sn), dhar, 6) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dipr Pointer variable to set socket n destination IP + * address. It should be allocated 4 bytes. + * @sa getSn_DIPR() + */ +#define setSn_DIPR(sn, dipr) WIZCHIP_WRITE_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_DIPR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t*)dipr Pointer variable to get socket n destination IP + * address. It should be allocated 4 bytes. + * @sa setSn_DIPR() + */ +#define getSn_DIPR(sn, dipr) WIZCHIP_READ_BUF(Sn_DIPR(sn), dipr, 4) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)dport Value to set @ref Sn_DPORT + * @sa getSn_DPORT() + */ +#define setSn_DPORT(sn, dport) \ + { \ + WIZCHIP_WRITE(Sn_DPORT(sn), (uint8_t)(dport >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_DPORT(sn), 1), (uint8_t)dport); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_DPORT register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_DPORT. + * @sa setSn_DPORT() + */ +// M20150401 : Type explict declaration +/* +#define getSn_DPORT(sn) \ + ((WIZCHIP_READ(Sn_DPORT(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn),1))) +*/ +#define getSn_DPORT(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_DPORT(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_DPORT(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)mss Value to set @ref Sn_MSSR + * @sa setSn_MSSR() + */ +#define setSn_MSSR(sn, mss) \ + { \ + WIZCHIP_WRITE(Sn_MSSR(sn), (uint8_t)(mss >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_MSSR(sn), 1), (uint8_t)mss); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_MSSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_MSSR. + * @sa setSn_MSSR() + */ +// M20150401 : Type explict declaration +/* +#define getSn_MSSR(sn) \ + ((WIZCHIP_READ(Sn_MSSR(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn),1))) +*/ +#define getSn_MSSR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_MSSR(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_MSSR(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)tos Value to set @ref Sn_TOS + * @sa getSn_TOS() + */ +#define setSn_TOS(sn, tos) WIZCHIP_WRITE(Sn_TOS(sn), tos) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TOS register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of Sn_TOS. + * @sa setSn_TOS() + */ +#define getSn_TOS(sn) WIZCHIP_READ(Sn_TOS(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)ttl Value to set @ref Sn_TTL + * @sa getSn_TTL() + */ +#define setSn_TTL(sn, ttl) WIZCHIP_WRITE(Sn_TTL(sn), ttl) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TTL register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_TTL. + * @sa setSn_TTL() + */ +#define getSn_TTL(sn) WIZCHIP_READ(Sn_TTL(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_RXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)rxbufsize Value to set @ref Sn_RXBUF_SIZE + * @sa getSn_RXBUF_SIZE() + */ +#define setSn_RXBUF_SIZE(sn, rxbufsize) \ + WIZCHIP_WRITE(Sn_RXBUF_SIZE(sn), rxbufsize) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_RXBUF_SIZE. + * @sa setSn_RXBUF_SIZE() + */ +#define getSn_RXBUF_SIZE(sn) WIZCHIP_READ(Sn_RXBUF_SIZE(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)txbufsize Value to set @ref Sn_TXBUF_SIZE + * @sa getSn_TXBUF_SIZE() + */ +#define setSn_TXBUF_SIZE(sn, txbufsize) \ + WIZCHIP_WRITE(Sn_TXBUF_SIZE(sn), txbufsize) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TXBUF_SIZE register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_TXBUF_SIZE. + * @sa setSn_TXBUF_SIZE() + */ +#define getSn_TXBUF_SIZE(sn) WIZCHIP_READ(Sn_TXBUF_SIZE(sn)) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_FSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_FSR. + */ +uint16_t getSn_TX_FSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_RD. + */ +// M20150401 : Type explict declaration +/* +#define getSn_TX_RD(sn) \ + ((WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn),1))) +*/ +#define getSn_TX_RD(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_TX_RD(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_RD(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)txwr Value to set @ref Sn_TX_WR + * @sa GetSn_TX_WR() + */ +#define setSn_TX_WR(sn, txwr) \ + { \ + WIZCHIP_WRITE(Sn_TX_WR(sn), (uint8_t)(txwr >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn), 1), (uint8_t)txwr); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_TX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_TX_WR. + * @sa setSn_TX_WR() + */ +// M20150401 : Type explict declaration +/* +#define getSn_TX_WR(sn) \ + ((WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn),1))) +*/ +#define getSn_TX_WR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_TX_WR(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_TX_WR(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_RSR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_RSR. + */ +uint16_t getSn_RX_RSR(uint8_t sn); + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)rxrd Value to set @ref Sn_RX_RD + * @sa getSn_RX_RD() + */ +#define setSn_RX_RD(sn, rxrd) \ + { \ + WIZCHIP_WRITE(Sn_RX_RD(sn), (uint8_t)(rxrd >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn), 1), (uint8_t)rxrd); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_RD register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_RD. + * @sa setSn_RX_RD() + */ +// M20150401 : Type explict declaration +/* +#define getSn_RX_RD(sn) \ + ((WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn),1))) +*/ +#define getSn_RX_RD(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_RX_RD(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_RD(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_RX_WR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_RX_WR. + */ +// M20150401 : Type explict declaration +/* +#define getSn_RX_WR(sn) \ + ((WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn),1))) +*/ +#define getSn_RX_WR(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_RX_WR(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_RX_WR(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint16_t)frag Value to set @ref Sn_FRAG + * @sa getSn_FRAD() + */ +#define setSn_FRAG(sn, frag) \ + { \ + WIZCHIP_WRITE(Sn_FRAG(sn), (uint8_t)(frag >> 8)); \ + WIZCHIP_WRITE(WIZCHIP_OFFSET_INC(Sn_FRAG(sn), 1), (uint8_t)frag); \ + } + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_FRAG register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of @ref Sn_FRAG. + * @sa setSn_FRAG() + */ +// M20150401 : Type explict declaration +/* +#define getSn_FRAG(sn) \ + ((WIZCHIP_READ(Sn_FRAG(sn)) << 8) + +WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn),1))) +*/ +#define getSn_FRAG(sn) \ + (((uint16_t)WIZCHIP_READ(Sn_FRAG(sn)) << 8) + \ + WIZCHIP_READ(WIZCHIP_OFFSET_INC(Sn_FRAG(sn), 1))) + +/** + * @ingroup Socket_register_access_function + * @brief Set @ref Sn_KPALVTR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param (uint8_t)kpalvt Value to set @ref Sn_KPALVTR + * @sa getSn_KPALVTR() + */ +#define setSn_KPALVTR(sn, kpalvt) WIZCHIP_WRITE(Sn_KPALVTR(sn), kpalvt) + +/** + * @ingroup Socket_register_access_function + * @brief Get @ref Sn_KPALVTR register + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint8_t. Value of @ref Sn_KPALVTR. + * @sa setSn_KPALVTR() + */ +#define getSn_KPALVTR(sn) WIZCHIP_READ(Sn_KPALVTR(sn)) + +////////////////////////////////////// + +///////////////////////////////////// +// Sn_TXBUF & Sn_RXBUF IO function // +///////////////////////////////////// +/** + * @brief Socket_register_access_function + * @brief Gets the max buffer size of socket sn passed as parameter. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of Socket n RX max buffer size. + */ +// M20150401 : Type explict declaration +/* +#define getSn_RxMAX(sn) \ + (getSn_RXBUF_SIZE(sn) << 10) +*/ +#define getSn_RxMAX(sn) (((uint16_t)getSn_RXBUF_SIZE(sn)) << 10) + +/** + * @brief Socket_register_access_function + * @brief Gets the max buffer size of socket sn passed as parameters. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @return uint16_t. Value of Socket n TX max buffer size. + */ +// M20150401 : Type explict declaration +/* +#define getSn_TxMAX(sn) \ + (getSn_TXBUF_SIZE(sn) << 10) +*/ +#define getSn_TxMAX(sn) (((uint16_t)getSn_TXBUF_SIZE(sn)) << 10) + +/** + * @ingroup Basic_IO_function + * @brief It copies data to internal TX memory + * + * @details This function reads the Tx write pointer register and after that, + * it copies the wizdata(pointer buffer) of the length of + * len(variable) bytes to internal TX memory and updates the Tx write + * pointer register. This function is being called by send() and sendto() + * function also. + * + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param wizdata Pointer buffer to write data + * @param len Data length + * @sa wiz_recv_data() + */ +void wiz_send_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It copies data to your buffer from internal RX memory + * + * @details This function read the Rx read pointer register and after that, + * it copies the received data from internal RX memory + * to wizdata(pointer variable) of the length of len(variable) + * bytes. This function is being called by recv() also. + * + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param wizdata Pointer buffer to read data + * @param len Data length + * @sa wiz_send_data() + */ +void wiz_recv_data(uint8_t sn, uint8_t *wizdata, uint16_t len); + +/** + * @ingroup Basic_IO_function + * @brief It discard the received data in RX memory. + * @details It discards the data of the length of len(variable) bytes in + * internal RX memory. + * @param (uint8_t)sn Socket number. It should be 0 ~ 7. + * @param len Data length + */ +void wiz_recv_ignore(uint8_t sn, uint16_t len); + +/// @cond DOXY_APPLY_CODE +#endif +/// @endcond + +#ifdef __cplusplus +} +#endif + +#endif // _W5500_H_ \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/wdt.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/wdt.h new file mode 100644 index 000000000..cd7fc49eb --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/wdt.h @@ -0,0 +1,180 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file wdt.h +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#ifndef __WDT_H__ +#define __WDT_H__ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* clang-format off */ +typedef struct _wdt +{ + /* WDT Control Register (0x00) */ + volatile uint32_t cr; + /* WDT Timeout Range Register (0x04) */ + volatile uint32_t torr; + /* WDT Current Counter Value Register (0x08) */ + volatile uint32_t ccvr; + /* WDT Counter Restart Register (0x0c) */ + volatile uint32_t crr; + /* WDT Interrupt Status Register (0x10) */ + volatile uint32_t stat; + /* WDT Interrupt Clear Register (0x14) */ + volatile uint32_t eoi; + /* reserverd (0x18) */ + volatile uint32_t resv1; + /* WDT Protection level Register (0x1c) */ + volatile uint32_t prot_level; + /* reserved (0x20-0xe0) */ + volatile uint32_t resv4[49]; + /* WDT Component Parameters Register 5 (0xe4) */ + volatile uint32_t comp_param_5; + /* WDT Component Parameters Register 4 (0xe8) */ + volatile uint32_t comp_param_4; + /* WDT Component Parameters Register 3 (0xec) */ + volatile uint32_t comp_param_3; + /* WDT Component Parameters Register 2 (0xf0) */ + volatile uint32_t comp_param_2; + /* WDT Component Parameters Register 1 (0xf4) */ + volatile uint32_t comp_param_1; + /* WDT Component Version Register (0xf8) */ + volatile uint32_t comp_version; + /* WDT Component Type Register (0xfc) */ + volatile uint32_t comp_type; +} __attribute__((packed, aligned(4))) wdt_t; + +typedef enum _wdt_device_number +{ + WDT_DEVICE_0, + WDT_DEVICE_1, + WDT_DEVICE_MAX, +} wdt_device_number_t; + + +#define WDT_RESET_ALL 0x00000000U +#define WDT_RESET_CPU 0x00000001U + +/* WDT Control Register */ +#define WDT_CR_ENABLE 0x00000001U +#define WDT_CR_RMOD_MASK 0x00000002U +#define WDT_CR_RMOD_RESET 0x00000000U +#define WDT_CR_RMOD_INTERRUPT 0x00000002U +#define WDT_CR_RPL_MASK 0x0000001CU +#define WDT_CR_RPL(x) ((x) << 2) +/* WDT Timeout Range Register */ +#define WDT_TORR_TOP_MASK 0x000000FFU +#define WDT_TORR_TOP(x) ((x) << 4 | (x) << 0) +/* WDT Current Counter Value Register */ +#define WDT_CCVR_MASK 0xFFFFFFFFU +/* WDT Counter Restart Register */ +#define WDT_CRR_MASK 0x00000076U +/* WDT Interrupt Status Register */ +#define WDT_STAT_MASK 0x00000001U +/* WDT Interrupt Clear Register */ +#define WDT_EOI_MASK 0x00000001U +/* WDT Protection level Register */ +#define WDT_PROT_LEVEL_MASK 0x00000007U +/* WDT Component Parameter Register 5 */ +#define WDT_COMP_PARAM_5_CP_WDT_USER_TOP_MAX_MASK 0xFFFFFFFFU +/* WDT Component Parameter Register 4 */ +#define WDT_COMP_PARAM_4_CP_WDT_USER_TOP_INIT_MAX_MASK 0xFFFFFFFFU +/* WDT Component Parameter Register 3 */ +#define WDT_COMP_PARAM_3_CD_WDT_TOP_RST_MASK 0xFFFFFFFFU +/* WDT Component Parameter Register 2 */ +#define WDT_COMP_PARAM_3_CP_WDT_CNT_RST_MASK 0xFFFFFFFFU +/* WDT Component Parameter Register 1 */ +#define WDT_COMP_PARAM_1_WDT_ALWAYS_EN_MASK 0x00000001U +#define WDT_COMP_PARAM_1_WDT_DFLT_RMOD_MASK 0x00000002U +#define WDT_COMP_PARAM_1_WDT_DUAL_TOP_MASK 0x00000004U +#define WDT_COMP_PARAM_1_WDT_HC_RMOD_MASK 0x00000008U +#define WDT_COMP_PARAM_1_WDT_HC_RPL_MASK 0x00000010U +#define WDT_COMP_PARAM_1_WDT_HC_TOP_MASK 0x00000020U +#define WDT_COMP_PARAM_1_WDT_USE_FIX_TOP_MASK 0x00000040U +#define WDT_COMP_PARAM_1_WDT_PAUSE_MASK 0x00000080U +#define WDT_COMP_PARAM_1_APB_DATA_WIDTH_MASK 0x00000300U +#define WDT_COMP_PARAM_1_WDT_DFLT_RPL_MASK 0x00001C00U +#define WDT_COMP_PARAM_1_WDT_DFLT_TOP_MASK 0x000F0000U +#define WDT_COMP_PARAM_1_WDT_DFLT_TOP_INIT_MASK 0x00F00000U +#define WDT_COMP_PARAM_1_WDT_CNT_WIDTH_MASK 0x1F000000U +/* WDT Component Version Register */ +#define WDT_COMP_VERSION_MASK 0xFFFFFFFFU +/* WDT Component Type Register */ +#define WDT_COMP_TYPE_MASK 0xFFFFFFFFU +/* clang-format on */ + +/** + * @brief Feed wdt + */ +void wdt_feed(wdt_device_number_t id); + +/** + * @brief Start wdt + * + * @param[in] id Wdt id 0 or 1 + * @param[in] time_out_ms Wdt trigger time + * @param[in] on_irq Wdt interrupt callback + * + */ +void wdt_start(wdt_device_number_t id, uint64_t time_out_ms, plic_irq_callback_t on_irq); + +/** + * @brief Start wdt + * + * @param[in] id Wdt id 0 or 1 + * @param[in] time_out_ms Wdt trigger time + * @param[in] on_irq Wdt interrupt callback + * @param[in] ctx Param of callback + * + * @return Wdt time + * + */ +uint32_t wdt_init(wdt_device_number_t id, uint64_t time_out_ms, plic_irq_callback_t on_irq, void *ctx); + +/** + * @brief Stop wdt + * + * @param[in] id Wdt id 0 or 1 + * + */ +void wdt_stop(wdt_device_number_t id); + +/** + * @brief Clear wdt interrupt + * + * @param[in] id Wdt id 0 or 1 + * + */ +void wdt_clear_interrupt(wdt_device_number_t id); + +#ifdef __cplusplus +} +#endif + +#endif /* __WDT_H__ */ diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/wizchip_conf.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/wizchip_conf.h new file mode 100755 index 000000000..a58da3a19 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/include/wizchip_conf.h @@ -0,0 +1,704 @@ +//***************************************************************************** +// +//! \file wizchip_conf.h +//! \brief WIZCHIP Config Header File. +//! \version 1.0.0 +//! \date 2013/10/21 +//! \par Revision history +//! <2015/02/05> Notice +//! The version history is not updated after this point. +//! Download the latest version directly from GitHub. Please visit the +//! our GitHub repository for ioLibrary. +//! >> https://github.com/Wiznet/ioLibrary_Driver +//! <2013/10/21> 1st Release +//! \author MidnightCow +//! \copyright +//! +//! Copyright (c) 2013, WIZnet Co., LTD. +//! All rights reserved. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above copyright +//! notice, this list of conditions and the following disclaimer in the +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the nor the names of its +//! contributors may be used to endorse or promote products derived +//! from this software without specific prior written permission. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +//! AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +//! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +//! INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +//! CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +//! ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +//! THE POSSIBILITY OF SUCH DAMAGE. +// +//***************************************************************************** + +/** + * @defgroup extra_functions 2. WIZnet Extra Functions + * + * @brief These functions is optional function. It could be replaced at WIZCHIP + * I/O function because they were made by WIZCHIP I/O functions. + * @details There are functions of configuring WIZCHIP, network, interrupt, phy, + * network information and timer. \n + * + */ + +#ifndef _WIZCHIP_CONF_H_ +#define _WIZCHIP_CONF_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +/** + * @brief Select WIZCHIP. + * @todo You should select one, \b W5100, \b W5100S, \b W5200, \b W5300, \b + * W5500 or etc. \n\n ex> #define \_WIZCHIP_ W5500 + */ + +#define W5100 5100 +#define W5100S 5100 + 5 +#define W5200 5200 +#define W5300 5300 +#define W5500 5500 + +#ifndef _WIZCHIP_ +#define _WIZCHIP_ W5500 // W5100, W5100S, W5200, W5300, W5500 +#endif + +#define _WIZCHIP_IO_MODE_NONE_ 0x0000 +#define _WIZCHIP_IO_MODE_BUS_ 0x0100 /**< Bus interface mode */ +#define _WIZCHIP_IO_MODE_SPI_ 0x0200 /**< SPI interface mode */ +//#define _WIZCHIP_IO_MODE_IIC_ 0x0400 +//#define _WIZCHIP_IO_MODE_SDIO_ 0x0800 +// Add to +// + +#define _WIZCHIP_IO_MODE_BUS_DIR_ \ + (_WIZCHIP_IO_MODE_BUS_ + 1) /**< BUS interface mode for direct */ +#define _WIZCHIP_IO_MODE_BUS_INDIR_ \ + (_WIZCHIP_IO_MODE_BUS_ + 2) /**< BUS interface mode for indirect */ + +#define _WIZCHIP_IO_MODE_SPI_VDM_ \ + (_WIZCHIP_IO_MODE_SPI_ + 1) /**< SPI interface mode for variable length \ \ \ + data*/ +#define _WIZCHIP_IO_MODE_SPI_FDM_ \ + (_WIZCHIP_IO_MODE_SPI_ + \ + 2) /**< SPI interface mode for fixed length data mode*/ +#define _WIZCHIP_IO_MODE_SPI_5500_ \ + (_WIZCHIP_IO_MODE_SPI_ + \ + 3) /**< SPI interface mode for fixed length data mode*/ + +#if (_WIZCHIP_ == W5100) +#define _WIZCHIP_ID_ "W5100\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref + * \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref + * \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ + +// A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +// A20150401 : Indclude W5100.h file +#include "W5100/w5100.h" + +#elif (_WIZCHIP_ == W5100S) +#define _WIZCHIP_ID_ "W5100S\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref + * \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref + * \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +//#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_5500_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ + +// A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +// A20150401 : Indclude W5100.h file +#include "W5100S/w5100s.h" +#elif (_WIZCHIP_ == W5200) +#define _WIZCHIP_ID_ "W5200\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref + * \_WIZCHIP_IO_MODE_SPI_ or @ref \ _WIZCHIP_IO_MODE_BUS_INDIR_ + */ +#ifndef _WIZCHIP_IO_MODE_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_ +#endif +// A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +#include "W5200/w5200.h" +#elif (_WIZCHIP_ == W5500) +#define _WIZCHIP_ID_ "W5500\0" + +/** + * @brief Define interface mode. \n + * @todo Should select interface mode as chip. + * - @ref \_WIZCHIP_IO_MODE_SPI_ \n + * -@ref \_WIZCHIP_IO_MODE_SPI_VDM_ : Valid only in @ref \_WIZCHIP_ == + * W5500 \n + * -@ref \_WIZCHIP_IO_MODE_SPI_FDM_ : Valid only in @ref \_WIZCHIP_ == + * W5500 \n + * - @ref \_WIZCHIP_IO_MODE_BUS_ \n + * - @ref \_WIZCHIP_IO_MODE_BUS_DIR_ \n + * - @ref \_WIZCHIP_IO_MODE_BUS_INDIR_ \n + * - Others will be defined in future. \n\n + * ex> #define \_WIZCHIP_IO_MODE_ \_WIZCHIP_IO_MODE_SPI_VDM_ + * + * + */ +#ifndef _WIZCHIP_IO_MODE_ +//#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_FDM_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_SPI_VDM_ +#endif +// A20150601 : Define the unit of IO DATA. +typedef uint8_t iodata_t; +#include "w5500.h" +#elif (_WIZCHIP_ == W5300) +#define _WIZCHIP_ID_ "W5300\0" +/** + * @brief Define interface mode. + * @todo you should select interface mode as chip. Select one of @ref + * \_WIZCHIP_IO_MODE_SPI_ , @ref \_WIZCHIP_IO_MODE_BUS_DIR_ or @ref + * \_WIZCHIP_IO_MODE_BUS_INDIR_ + */ +#ifndef _WIZCHIP_IO_MODE_ +#define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_DIR_ +// #define _WIZCHIP_IO_MODE_ _WIZCHIP_IO_MODE_BUS_INDIR_ +#endif + +// A20150601 : Define the unit and bus width of IO DATA. +/** + * @brief Select the data width 8 or 16 bits. + * @todo you should select the bus width. Select one of 8 or 16. + */ +#ifndef _WIZCHIP_IO_BUS_WIDTH_ +#define _WIZCHIP_IO_BUS_WIDTH_ 16 // 8 +#endif +#if _WIZCHIP_IO_BUS_WIDTH_ == 8 +typedef uint8_t iodata_t; +#elif _WIZCHIP_IO_BUS_WIDTH_ == 16 +typedef uint16_t iodata_t; +#else +#error "Unknown _WIZCHIP_IO_BUS_WIDTH_. It should be 8 or 16." +#endif +// +#include "W5300/w5300.h" +#else +#error \ + "Unknown defined _WIZCHIP_. You should define one of 5100, 5200, and 5500 !!!" +#endif + +#ifndef _WIZCHIP_IO_MODE_ +#error "Undefined _WIZCHIP_IO_MODE_. You should define it !!!" +#endif + +/** + * @brief Define I/O base address when BUS IF mode. + * @todo Should re-define it to fit your system when BUS IF Mode (@ref + * \_WIZCHIP_IO_MODE_BUS_, + * @ref \_WIZCHIP_IO_MODE_BUS_DIR_, @ref \_WIZCHIP_IO_MODE_BUS_INDIR_). + * \n\n ex> #define \_WIZCHIP_IO_BASE_ 0x00008000 + */ +#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_ +// #define _WIZCHIP_IO_BASE_ 0x60000000 +//// for 5100S IND +#define _WIZCHIP_IO_BASE_ 0x68000000 // for W5300 +#elif _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_SPI_ +#define _WIZCHIP_IO_BASE_ 0x00000000 // for 5100S SPI +#endif + +#ifndef _WIZCHIP_IO_BASE_ +#define _WIZCHIP_IO_BASE_ 0x00000000 // 0x8000 +#endif + +// M20150401 : Typing Error +//#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS +#if _WIZCHIP_IO_MODE_ & _WIZCHIP_IO_MODE_BUS_ +#ifndef _WIZCHIP_IO_BASE_ +#error "You should be define _WIZCHIP_IO_BASE to fit your system memory map." +#endif +#endif + +#if _WIZCHIP_ >= W5200 +#define _WIZCHIP_SOCK_NUM_ 8 ///< The count of independant socket of @b WIZCHIP +#else +#define _WIZCHIP_SOCK_NUM_ 4 ///< The count of independant socket of @b WIZCHIP +#endif + +/******************************************************** + * WIZCHIP BASIC IF functions for SPI, SDIO, I2C , ETC. + *********************************************************/ +/** + * @ingroup DATA_TYPE + * @brief The set of callback functions for W5500:@ref WIZCHIP_IO_Functions + * W5200:@ref WIZCHIP_IO_Functions_W5200 + */ +typedef struct __WIZCHIP { + uint16_t if_mode; ///< host interface mode + uint8_t id[8]; ///< @b WIZCHIP ID such as @b 5100, @b 5100S, @b 5200, @b + ///< 5500, and so on. + /** + * The set of critical section callback func. + */ + struct _CRIS { + void (*_enter)(void); ///< crtical section enter + void (*_exit)(void); ///< critial section exit + } CRIS; + /** + * The set of @ref \_WIZCHIP_ select control callback func. + */ + struct _CS { + void (*_select)(void); ///< @ref \_WIZCHIP_ selected + void (*_deselect)(void); ///< @ref \_WIZCHIP_ deselected + } CS; + /** + * The set of interface IO callback func. + */ + union _IF { + /** + * For BUS interface IO + */ + // M20156501 : Modify the function name for integrating with W5300 + // struct + //{ + // uint8_t (*_read_byte) (uint32_t AddrSel); + // void (*_write_byte) (uint32_t AddrSel, uint8_t wb); + //}BUS; + struct { + iodata_t (*_read_data)(uint32_t AddrSel); + void (*_write_data)(uint32_t AddrSel, iodata_t wb); + } BUS; + + /** + * For SPI interface IO + */ + struct { + uint8_t (*_read_byte)(void); + void (*_write_byte)(uint8_t wb); + void (*_read_burst)(uint8_t *pBuf, uint16_t len); + void (*_write_burst)(uint8_t *pBuf, uint16_t len); + } SPI; + // To be added + // + } IF; +} _WIZCHIP; + +extern _WIZCHIP WIZCHIP; + +/** + * @ingroup DATA_TYPE + * WIZCHIP control type enumration used in @ref ctlwizchip(). + */ +typedef enum { + CW_RESET_WIZCHIP, ///< Resets WIZCHIP by softly + CW_INIT_WIZCHIP, ///< Initializes to WIZCHIP with SOCKET buffer size 2 or 1 + ///< dimension array typed uint8_t. + CW_GET_INTERRUPT, ///< Get Interrupt status of WIZCHIP + CW_CLR_INTERRUPT, ///< Clears interrupt + CW_SET_INTRMASK, ///< Masks interrupt + CW_GET_INTRMASK, ///< Get interrupt mask + CW_SET_INTRTIME, ///< Set interval time between the current and next + ///< interrupt. + CW_GET_INTRTIME, ///< Set interval time between the current and next + ///< interrupt. + CW_GET_ID, ///< Gets WIZCHIP name. + + // D20150601 : For no modification your application code + //#if _WIZCHIP_ == W5500 + CW_RESET_PHY, ///< Resets internal PHY. Valid Only W5500 + CW_SET_PHYCONF, ///< When PHY configured by internal register, PHY operation + ///< mode (Manual/Auto, 10/100, Half/Full). Valid Only W5000 + CW_GET_PHYCONF, ///< Get PHY operation mode in internal register. Valid Only + ///< W5500 + CW_GET_PHYSTATUS, ///< Get real PHY status on operating. Valid Only W5500 + CW_SET_PHYPOWMODE, ///< Set PHY power mode as normal and down when + ///< PHYSTATUS.OPMD == 1. Valid Only W5500 + //#endif + // D20150601 : For no modification your application code + //#if _WIZCHIP_ == W5200 || _WIZCHIP_ == W5500 + CW_GET_PHYPOWMODE, ///< Get PHY Power mode as down or normal, Valid Only + ///< W5100, W5200 + CW_GET_PHYLINK ///< Get PHY Link status, Valid Only W5100, W5200 + //#endif +} ctlwizchip_type; + +/** + * @ingroup DATA_TYPE + * Network control type enumration used in @ref ctlnetwork(). + */ +typedef enum { + CN_SET_NETINFO, ///< Set Network with @ref wiz_NetInfo + CN_GET_NETINFO, ///< Get Network with @ref wiz_NetInfo + CN_SET_NETMODE, ///< Set network mode as WOL, PPPoE, Ping Block, and Force + ///< ARP mode + CN_GET_NETMODE, ///< Get network mode as WOL, PPPoE, Ping Block, and Force + ///< ARP mode + CN_SET_TIMEOUT, ///< Set network timeout as retry count and time. + CN_GET_TIMEOUT, ///< Get network timeout as retry count and time. +} ctlnetwork_type; + +/** + * @ingroup DATA_TYPE + * Interrupt kind when CW_SET_INTRRUPT, CW_GET_INTERRUPT, CW_SET_INTRMASK + * and CW_GET_INTRMASK is used in @ref ctlnetwork(). + * It can be used with OR operation. + */ +typedef enum { +#if _WIZCHIP_ == W5500 + IK_WOL = + (1 << 4), ///< Wake On Lan by receiving the magic packet. Valid in W500. +#elif _WIZCHIP_ == W5300 + IK_FMTU = (1 << 4), ///< Received a ICMP message (Fragment MTU) +#endif + + IK_PPPOE_TERMINATED = (1 << 5), ///< PPPoE Disconnected + +#if _WIZCHIP_ != W5200 + IK_DEST_UNREACH = + (1 << 6), ///< Destination IP & Port Unreachable, No use in W5200 +#endif + + IK_IP_CONFLICT = (1 << 7), ///< IP conflict occurred + + IK_SOCK_0 = (1 << 8), ///< Socket 0 interrupt + IK_SOCK_1 = (1 << 9), ///< Socket 1 interrupt + IK_SOCK_2 = (1 << 10), ///< Socket 2 interrupt + IK_SOCK_3 = (1 << 11), ///< Socket 3 interrupt +#if _WIZCHIP_ > W5100S + IK_SOCK_4 = (1 << 12), ///< Socket 4 interrupt, No use in 5100 + IK_SOCK_5 = (1 << 13), ///< Socket 5 interrupt, No use in 5100 + IK_SOCK_6 = (1 << 14), ///< Socket 6 interrupt, No use in 5100 + IK_SOCK_7 = (1 << 15), ///< Socket 7 interrupt, No use in 5100 +#endif + +#if _WIZCHIP_ > W5100S + IK_SOCK_ALL = (0xFF << 8) ///< All Socket interrupt +#else + IK_SOCK_ALL = (0x0F << 8) ///< All Socket interrupt +#endif +} intr_kind; + +#define PHY_CONFBY_HW 0 ///< Configured PHY operation mode by HW pin +#define PHY_CONFBY_SW 1 ///< Configured PHY operation mode by SW register +#define PHY_MODE_MANUAL 0 ///< Configured PHY operation mode with user setting. +#define PHY_MODE_AUTONEGO \ + 1 ///< Configured PHY operation mode with auto-negotiation +#define PHY_SPEED_10 0 ///< Link Speed 10 +#define PHY_SPEED_100 1 ///< Link Speed 100 +#define PHY_DUPLEX_HALF 0 ///< Link Half-Duplex +#define PHY_DUPLEX_FULL 1 ///< Link Full-Duplex +#define PHY_LINK_OFF 0 ///< Link Off +#define PHY_LINK_ON 1 ///< Link On +#define PHY_POWER_NORM 0 ///< PHY power normal mode +#define PHY_POWER_DOWN 1 ///< PHY power down mode + +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 +/** + * @ingroup DATA_TYPE + * It configures PHY configuration when CW_SET PHYCONF or CW_GET_PHYCONF in + * W5500, and it indicates the real PHY status configured by HW or SW in all + * WIZCHIP. \n Valid only in W5500. + */ +typedef struct wiz_PhyConf_t { + uint8_t by; ///< set by @ref PHY_CONFBY_HW or @ref PHY_CONFBY_SW + uint8_t mode; ///< set by @ref PHY_MODE_MANUAL or @ref PHY_MODE_AUTONEGO + uint8_t speed; ///< set by @ref PHY_SPEED_10 or @ref PHY_SPEED_100 + uint8_t duplex; ///< set by @ref PHY_DUPLEX_HALF @ref PHY_DUPLEX_FULL + // uint8_t power; ///< set by @ref PHY_POWER_NORM or @ref PHY_POWER_DOWN + // uint8_t link; ///< Valid only in CW_GET_PHYSTATUS. set by @ref + // PHY_LINK_ON or PHY_DUPLEX_OFF +} wiz_PhyConf; +#endif + +/** + * @ingroup DATA_TYPE + * It used in setting dhcp_mode of @ref wiz_NetInfo. + */ +typedef enum { + NETINFO_STATIC = 1, ///< Static IP configuration by manually. + NETINFO_DHCP ///< Dynamic IP configruation from a DHCP sever +} dhcp_mode; + +/** + * @ingroup DATA_TYPE + * Network Information for WIZCHIP + */ +typedef struct wiz_NetInfo_t { + uint8_t mac[6]; ///< Source Mac Address + uint8_t ip[4]; ///< Source IP Address + uint8_t sn[4]; ///< Subnet Mask + uint8_t gw[4]; ///< Gateway IP Address + uint8_t dns[4]; ///< DNS server IP Address + dhcp_mode dhcp; ///< 1 - Static, 2 - DHCP +} wiz_NetInfo; + +/** + * @ingroup DATA_TYPE + * Network mode + */ +typedef enum { +#if _WIZCHIP_ == W5500 + NM_FORCEARP = (1 << 1), ///< Force to APP send whenever udp data is sent. + ///< Valid only in W5500 +#endif + NM_WAKEONLAN = (1 << 5), ///< Wake On Lan + NM_PINGBLOCK = (1 << 4), ///< Block ping-request + NM_PPPOE = (1 << 3), ///< PPPoE mode +} netmode_type; + +/** + * @ingroup DATA_TYPE + * Used in CN_SET_TIMEOUT or CN_GET_TIMEOUT of @ref ctlwizchip() for timeout + * configruation. + */ +typedef struct wiz_NetTimeout_t { + uint8_t retry_cnt; ///< retry count + uint16_t time_100us; ///< time unit 100us +} wiz_NetTimeout; + +/** + *@brief Registers call back function for critical section of I/O functions such + *as \ref WIZCHIP_READ, @ref WIZCHIP_WRITE, @ref WIZCHIP_READ_BUF and @ref + *WIZCHIP_WRITE_BUF. + *@param cris_en : callback function for critical section enter. + *@param cris_ex : callback function for critical section exit. + *@todo Describe @ref WIZCHIP_CRITICAL_ENTER and @ref WIZCHIP_CRITICAL_EXIT + *marco or register your functions. + *@note If you do not describe or register, default functions(@ref + *wizchip_cris_enter & @ref wizchip_cris_exit) is called. + */ +void reg_wizchip_cris_cbfunc(void (*cris_en)(void), void (*cris_ex)(void)); + +/** + *@brief Registers call back function for WIZCHIP select & deselect. + *@param cs_sel : callback function for WIZCHIP select + *@param cs_desel : callback fucntion for WIZCHIP deselect + *@todo Describe @ref wizchip_cs_select and @ref wizchip_cs_deselect function or + *register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_cs_cbfunc(void (*cs_sel)(void), void (*cs_desel)(void)); + +/** + *@brief Registers call back function for bus interface. + *@param bus_rb : callback function to read byte data using system bus + *@param bus_wb : callback function to write byte data using system bus + *@todo Describe @ref wizchip_bus_readbyte and @ref wizchip_bus_writebyte + *function or register your functions. + *@note If you do not describe or register, null function is called. + */ +// M20150601 : For integrating with W5300 +// void reg_wizchip_bus_cbfunc(uint8_t (*bus_rb)(uint32_t addr), void +// (*bus_wb)(uint32_t addr, uint8_t wb)); +void reg_wizchip_bus_cbfunc(iodata_t (*bus_rb)(uint32_t addr), + void (*bus_wb)(uint32_t addr, iodata_t wb)); + +/** + *@brief Registers call back function for SPI interface. + *@param spi_rb : callback function to read byte using SPI + *@param spi_wb : callback function to write byte using SPI + *@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte + *function or register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_spi_cbfunc(uint8_t (*spi_rb)(void), + void (*spi_wb)(uint8_t wb)); + +/** + *@brief Registers call back function for SPI interface. + *@param spi_rb : callback function to burst read using SPI + *@param spi_wb : callback function to burst write using SPI + *@todo Describe \ref wizchip_spi_readbyte and \ref wizchip_spi_writebyte + *function or register your functions. + *@note If you do not describe or register, null function is called. + */ +void reg_wizchip_spiburst_cbfunc(void (*spi_rb)(uint8_t *pBuf, uint16_t len), + void (*spi_wb)(uint8_t *pBuf, uint16_t len)); + +/** + * @ingroup extra_functions + * @brief Controls to the WIZCHIP. + * @details Resets WIZCHIP & internal PHY, Configures PHY mode, Monitor + * PHY(Link,Speed,Half/Full/Auto), controls interrupt & mask and so on. + * @param cwtype : Decides to the control type + * @param arg : arg type is dependent on cwtype. + * @return 0 : Success \n + * -1 : Fail because of invalid \ref ctlwizchip_type or unsupported \ref + * ctlwizchip_type in WIZCHIP + */ +int8_t ctlwizchip(ctlwizchip_type cwtype, void *arg); + +/** + * @ingroup extra_functions + * @brief Controls to network. + * @details Controls to network environment, mode, timeout and so on. + * @param cntype : Input. Decides to the control type + * @param arg : Inout. arg type is dependent on cntype. + * @return -1 : Fail because of invalid \ref ctlnetwork_type or unsupported \ref + * ctlnetwork_type in WIZCHIP \n 0 : Success + */ +int8_t ctlnetwork(ctlnetwork_type cntype, void *arg); + +/* + * The following functions are implemented for internal use. + * but You can call these functions for code size reduction instead of + * ctlwizchip() and ctlnetwork(). + */ + +/** + * @ingroup extra_functions + * @brief Reset WIZCHIP by softly. + */ +void wizchip_sw_reset(void); + +/** + * @ingroup extra_functions + * @brief Initializes WIZCHIP with socket buffer size + * @param txsize Socket tx buffer sizes. If null, initialized the default size + * 2KB. + * @param rxsize Socket rx buffer sizes. If null, initialized the default size + * 2KB. + * @return 0 : succcess \n + * -1 : fail. Invalid buffer size + */ +int8_t wizchip_init(uint8_t *txsize, uint8_t *rxsize); + +/** + * @ingroup extra_functions + * @brief Clear Interrupt of WIZCHIP. + * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +void wizchip_clrinterrupt(intr_kind intr); + +/** + * @ingroup extra_functions + * @brief Get Interrupt of WIZCHIP. + * @return @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +intr_kind wizchip_getinterrupt(void); + +/** + * @ingroup extra_functions + * @brief Mask or Unmask Interrupt of WIZCHIP. + * @param intr : @ref intr_kind value operated OR. It can type-cast to uint16_t. + */ +void wizchip_setinterruptmask(intr_kind intr); + +/** + * @ingroup extra_functions + * @brief Get Interrupt mask of WIZCHIP. + * @return : The operated OR vaule of @ref intr_kind. It can type-cast to + * uint16_t. + */ +intr_kind wizchip_getinterruptmask(void); + +// todo +#if _WIZCHIP_ > W5100 +int8_t wizphy_getphylink( + void); ///< get the link status of phy in WIZCHIP. No use in W5100 +int8_t wizphy_getphypmode( + void); ///< get the power mode of PHY in WIZCHIP. No use in W5100 +#endif + +#if _WIZCHIP_ == W5100S || _WIZCHIP_ == W5500 +void wizphy_reset(void); ///< Reset phy. Vailid only in W5500 + /** + * @ingroup extra_functions + * @brief Set the phy information for WIZCHIP without power mode + * @param phyconf : @ref wiz_PhyConf + */ +void wizphy_setphyconf(wiz_PhyConf *phyconf); +/** + * @ingroup extra_functions + * @brief Get phy configuration information. + * @param phyconf : @ref wiz_PhyConf + */ +void wizphy_getphyconf(wiz_PhyConf *phyconf); +/** + * @ingroup extra_functions + * @brief Get phy status. + * @param phyconf : @ref wiz_PhyConf + */ +void wizphy_getphystat(wiz_PhyConf *phyconf); +/** + * @ingroup extra_functions + * @brief set the power mode of phy inside WIZCHIP. Refer to @ref PHYCFGR in + * W5500, @ref PHYSTATUS in W5200 + * @param pmode Settig value of power down mode. + */ +int8_t wizphy_setphypmode(uint8_t pmode); +#endif + +/** + * @ingroup extra_functions + * @brief Set the network information for WIZCHIP + * @param pnetinfo : @ref wizNetInfo + */ +void wizchip_setnetinfo(wiz_NetInfo *pnetinfo); + +/** + * @ingroup extra_functions + * @brief Get the network information for WIZCHIP + * @param pnetinfo : @ref wizNetInfo + */ +void wizchip_getnetinfo(wiz_NetInfo *pnetinfo); + +/** + * @ingroup extra_functions + * @brief Set the network mode such WOL, PPPoE, Ping Block, and etc. + * @param pnetinfo Value of network mode. Refer to @ref netmode_type. + */ +int8_t wizchip_setnetmode(netmode_type netmode); + +/** + * @ingroup extra_functions + * @brief Get the network mode such WOL, PPPoE, Ping Block, and etc. + * @return Value of network mode. Refer to @ref netmode_type. + */ +netmode_type wizchip_getnetmode(void); + +/** + * @ingroup extra_functions + * @brief Set retry time value(@ref _RTR_) and retry count(@ref _RCR_). + * @details @ref _RTR_ configures the retransmission timeout period and @ref + * _RCR_ configures the number of time of retransmission. + * @param nettime @ref _RTR_ value and @ref _RCR_ value. Refer to @ref + * wiz_NetTimeout. + */ +void wizchip_settimeout(wiz_NetTimeout *nettime); + +/** + * @ingroup extra_functions + * @brief Get retry time value(@ref _RTR_) and retry count(@ref _RCR_). + * @details @ref _RTR_ configures the retransmission timeout period and @ref + * _RCR_ configures the number of time of retransmission. + * @param nettime @ref _RTR_ value and @ref _RCR_ value. Refer to @ref + * wiz_NetTimeout. + */ +void wizchip_gettimeout(wiz_NetTimeout *nettime); +#ifdef __cplusplus +} +#endif + +#endif // _WIZCHIP_CONF_H_ \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/lcd/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/lcd/Kconfig new file mode 100644 index 000000000..ed8ca6bad --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/lcd/Kconfig @@ -0,0 +1,36 @@ + +if BSP_USING_LCD + config LCD_BUS_NAME + string "lcd bus name" + default "lcd" + config LCD_DRV_NAME + string "lcd bus driver name" + default "lcd_drv" + config LCD_DEVICE_NAME + string "lcd bus device name" + default "lcd_dev" + config BSP_LCD_CS_PIN + int "CS pin number of 8080 interface" + default 37 + config BSP_LCD_WR_PIN + int "WR pin number of 8080 interface" + default 38 + config BSP_LCD_DC_PIN + int "DC pin number of 8080 interface" + default 39 + config BSP_LCD_RST_PIN + int "RST pin number of 8080 interface" + default 36 + config FPIOA_LCD_DC + int "DC FPIOA number of 8080 interface" + default 9 + config FPIOA_LCD_RST + int "RST FPIOA number of 8080 interface" + default 10 + config BSP_LCD_X_MAX + int "LCD Height" + default 320 + config BSP_LCD_Y_MAX + int "LCD Width" + default 320 +endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/lcd/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/lcd/Makefile new file mode 100644 index 000000000..05bd917f0 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/lcd/Makefile @@ -0,0 +1,4 @@ +SRC_FILES := connect_lcd.c + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/lcd/connect_lcd.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/lcd/connect_lcd.c new file mode 100644 index 000000000..8595bca05 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/lcd/connect_lcd.c @@ -0,0 +1,704 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file connect_lcd.c +* @brief support aiit-riscv64-board lcd function and register to bus framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +/************************************************* +File name: connect_lcd.c +Description: support aiit-riscv64-board lcd configure and lcd bus register function +Others: https://canaan-creative.com/developer +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. support aiit-riscv64-board lcd configure, write and read +2. support aiit-riscv64-board lcd bus device and driver register +*************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#define NO_OPERATION 0x00 +#define SOFTWARE_RESET 0x01 +#define READ_ID 0x04 +#define READ_STATUS 0x09 +#define READ_POWER_MODE 0x0A +#define READ_MADCTL 0x0B +#define READ_PIXEL_FORMAT 0x0C +#define READ_IMAGE_FORMAT 0x0D +#define READ_SIGNAL_MODE 0x0E +#define READ_SELT_DIAG_RESULT 0x0F +#define SLEEP_ON 0x10 +#define SLEEP_OFF 0x11 +#define PARTIAL_DISPALY_ON 0x12 +#define NORMAL_DISPALY_ON 0x13 +#define INVERSION_DISPALY_OFF 0x20 +#define INVERSION_DISPALY_ON 0x21 +#define GAMMA_SET 0x26 +#define DISPALY_OFF 0x28 +#define DISPALY_ON 0x29 +#define HORIZONTAL_ADDRESS_SET 0x2A +#define VERTICAL_ADDRESS_SET 0x2B +#define MEMORY_WRITE 0x2C +#define COLOR_SET 0x2D +#define MEMORY_READ 0x2E +#define PARTIAL_AREA 0x30 +#define VERTICAL_SCROL_DEFINE 0x33 +#define TEAR_EFFECT_LINE_OFF 0x34 +#define TEAR_EFFECT_LINE_ON 0x35 +#define MEMORY_ACCESS_CTL 0x36 +#define VERTICAL_SCROL_S_ADD 0x37 +#define IDLE_MODE_OFF 0x38 +#define IDLE_MODE_ON 0x39 +#define PIXEL_FORMAT_SET 0x3A +#define WRITE_MEMORY_CONTINUE 0x3C +#define READ_MEMORY_CONTINUE 0x3E +#define SET_TEAR_SCANLINE 0x44 +#define GET_SCANLINE 0x45 +#define WRITE_BRIGHTNESS 0x51 +#define READ_BRIGHTNESS 0x52 +#define WRITE_CTRL_DISPALY 0x53 +#define READ_CTRL_DISPALY 0x54 +#define WRITE_BRIGHTNESS_CTL 0x55 +#define READ_BRIGHTNESS_CTL 0x56 +#define WRITE_MIN_BRIGHTNESS 0x5E +#define READ_MIN_BRIGHTNESS 0x5F +#define READ_ID1 0xDA +#define READ_ID2 0xDB +#define READ_ID3 0xDC +#define RGB_IF_SIGNAL_CTL 0xB0 +#define NORMAL_FRAME_CTL 0xB1 +#define IDLE_FRAME_CTL 0xB2 +#define PARTIAL_FRAME_CTL 0xB3 +#define INVERSION_CTL 0xB4 +#define BLANK_PORCH_CTL 0xB5 +#define DISPALY_FUNCTION_CTL 0xB6 +#define ENTRY_MODE_SET 0xB7 +#define BACKLIGHT_CTL1 0xB8 +#define BACKLIGHT_CTL2 0xB9 +#define BACKLIGHT_CTL3 0xBA +#define BACKLIGHT_CTL4 0xBB +#define BACKLIGHT_CTL5 0xBC +#define BACKLIGHT_CTL7 0xBE +#define BACKLIGHT_CTL8 0xBF +#define POWER_CTL1 0xC0 +#define POWER_CTL2 0xC1 +#define VCOM_CTL1 0xC5 +#define VCOM_CTL2 0xC7 +#define NV_MEMORY_WRITE 0xD0 +#define NV_MEMORY_PROTECT_KEY 0xD1 +#define NV_MEMORY_STATUS_READ 0xD2 +#define READ_ID4 0xD3 +#define POSITIVE_GAMMA_CORRECT 0xE0 +#define NEGATIVE_GAMMA_CORRECT 0xE1 +#define DIGITAL_GAMMA_CTL1 0xE2 +#define DIGITAL_GAMMA_CTL2 0xE3 +#define INTERFACE_CTL 0xF6 + +typedef enum _lcd_dir +{ + DIR_XY_RLUD = 0x00, + DIR_YX_RLUD = 0x20, + DIR_XY_LRUD = 0x40, + DIR_YX_LRUD = 0x60, + DIR_XY_RLDU = 0x80, + DIR_YX_RLDU = 0xA0, + DIR_XY_LRDU = 0xC0, + DIR_YX_LRDU = 0xE0, + DIR_XY_MASK = 0x20, + DIR_MASK = 0xE0, +} lcd_dir_t; + +#define LCD_SPI_CHANNEL SPI_DEVICE_0 +#define LCD_SPI_CHIP_SELECT SPI_CHIP_SELECT_0 + +typedef struct Lcd8080Device +{ + struct LcdBus lcd_bus; + struct DeviceLcdInfo lcd_info; + int spi_channel; + int cs; + int dc_pin; + int dma_channel; +} * Lcd8080DeviceType; + +Lcd8080DeviceType aiit_lcd ; + +static void DrvLcdCmd(uint8 cmd) +{ + gpiohs_set_pin(aiit_lcd->dc_pin, GPIO_PV_LOW); + spi_init(aiit_lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0); + spi_init_non_standard(aiit_lcd->spi_channel/*spi num*/, 8 /*instrction length*/, 0 /*address length*/, 0 /*wait cycles*/, + SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/); + spi_send_data_normal_dma(aiit_lcd->dma_channel, aiit_lcd->spi_channel, aiit_lcd->cs, &cmd, 1, SPI_TRANS_CHAR); +} + +static void DrvLcdDataByte(uint8 *data_buf, uint32 length) +{ + gpiohs_set_pin(aiit_lcd->dc_pin, GPIO_PV_HIGH); + spi_init(aiit_lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0); + spi_init_non_standard(aiit_lcd->spi_channel, 8 /*instrction length*/, 0 /*address length*/, 0 /*wait cycles*/, + SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/); + spi_send_data_normal_dma(aiit_lcd->dma_channel, aiit_lcd->spi_channel, aiit_lcd->cs, data_buf, length, SPI_TRANS_CHAR); +} + +static void DrvLcdDataHalfWord(uint16 *data_buf, uint32 length) +{ + gpiohs_set_pin(aiit_lcd->dc_pin, GPIO_PV_HIGH); + spi_init(aiit_lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 16, 0); + spi_init_non_standard(aiit_lcd->spi_channel, 16 /*instrction length*/, 0 /*address length*/, 0 /*wait cycles*/, + SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/); + spi_send_data_normal_dma(aiit_lcd->dma_channel, aiit_lcd->spi_channel, aiit_lcd->cs, data_buf, length, SPI_TRANS_SHORT); +} + +static void DrvLcdDataWord(uint32 *data_buf, uint32 length) +{ + gpiohs_set_pin(aiit_lcd->dc_pin, GPIO_PV_HIGH); + /*spi num Polarity and phase mode Multi-line mode Data bit width little endian */ + spi_init(aiit_lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 32, 0); + +/* spi num instrction length address length wait cycles spi address trans mode*/ + spi_init_non_standard(aiit_lcd->spi_channel, 0 , 32, 0 ,SPI_AITM_AS_FRAME_FORMAT ); + + /*dma channel spi num chip_selete tx_buff tx_len spi_trans_data_width */ + spi_send_data_normal_dma(aiit_lcd->dma_channel, aiit_lcd->spi_channel, aiit_lcd->cs, data_buf, length, SPI_TRANS_INT); +} + +static void DrvLcdHwInit(Lcd8080DeviceType lcd) +{ + gpiohs_set_drive_mode(lcd->dc_pin, GPIO_DM_OUTPUT); + gpiohs_set_pin(lcd->dc_pin, GPIO_PV_HIGH); + spi_init(lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0); + spi_set_clk_rate(lcd->spi_channel, 25000000); +} + +static void DrvLcdSetDirection(lcd_dir_t dir) +{ +#if !BOARD_LICHEEDAN + dir |= 0x08; +#endif + if (dir & DIR_XY_MASK) { + aiit_lcd->lcd_info.width = BSP_LCD_Y_MAX; + aiit_lcd->lcd_info.height = BSP_LCD_X_MAX; + } else { + aiit_lcd->lcd_info.width = BSP_LCD_X_MAX; + aiit_lcd->lcd_info.height = BSP_LCD_Y_MAX; + } + + DrvLcdCmd(MEMORY_ACCESS_CTL); + DrvLcdDataByte((uint8 *)&dir, 1); +} + +static void DrvLcdSetArea(uint16 x1, uint16 y1, uint16 x2, uint16 y2) +{ + uint8 data[4] = {0}; + + data[0] = (uint8)(x1 >> 8); + data[1] = (uint8)(x1); + data[2] = (uint8)(x2 >> 8); + data[3] = (uint8)(x2); + DrvLcdCmd(HORIZONTAL_ADDRESS_SET); + DrvLcdDataByte(data, 4); + + data[0] = (uint8)(y1 >> 8); + data[1] = (uint8)(y1); + data[2] = (uint8)(y2 >> 8); + data[3] = (uint8)(y2); + DrvLcdCmd(VERTICAL_ADDRESS_SET); + DrvLcdDataByte(data, 4); + + DrvLcdCmd(MEMORY_WRITE); +} + +static void DrvLcdSetPixel(uint16_t x, uint16_t y, uint16_t color) +{ + DrvLcdSetArea(x, y, x, y); + DrvLcdDataHalfWord(&color, 1); +} + +static void DrvLcdSetPixelDot(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2,void* color) +{ + uint32 size = 0; + size = (x2- x1 + 1)*(y2 - y1 + 1); + DrvLcdSetArea(x1, y1, x2, y2); + DrvLcdDataHalfWord(color, size); +} + +void LcdShowChar(uint16 x,uint16 y,uint8 num,uint8 size,uint16 color,uint16 back_color) +{ + uint8 temp,t1,t; + uint16 y0=y; + uint8 csize=(size/8+((size%8)?1:0))*(size/2); + num=num-' '; + for (t = 0;t < csize;t ++) { + if (size==12) + temp=asc2_1206[num][t]; //1206 + else if (size==16) + temp=asc2_1608[num][t]; //1608 + else if (size==24) + temp=asc2_2412[num][t]; //2412 + else if (size==32) + temp=asc2_3216[num][t]; //3216 + else + return; + + for(t1 = 0;t1 < 8;t1 ++) { + if (temp&0x80) + DrvLcdSetPixel(x,y,color); + else + DrvLcdSetPixel(x,y,back_color); + + temp<<=1; + y++; + if(y>=aiit_lcd->lcd_info.height) + return; + if ((y-y0) == size) { + y=y0; + x++; + if(x>=aiit_lcd->lcd_info.width) + return; + break; + } + } + } +} + +void LcdShowString(uint16_t x,uint16_t y,uint16_t width,uint16_t height,uint8 size,uint8 *p,uint16_t color,uint16_t back_color) +{ + uint16_t x0 = x; + width += x; + height += y; + while ((*p<='~')&&(*p>=' ')) { + if (x>=width) { + x=x0; + y+=size; + } + if(y>=height) + break; + LcdShowChar(x,y,*p,size,color,back_color); + x += size/2; + p++; + } +} + +/* +* clear lcd by color +* para color +* return none +*/ +void DrvLcdClear(uint16 color) +{ + uint32 data = ((uint32)color << 16) | (uint32)color; + + DrvLcdSetArea(0, 0, aiit_lcd->lcd_info.width - 1, aiit_lcd->lcd_info.height - 1); + gpiohs_set_pin(aiit_lcd->dc_pin, GPIO_PV_HIGH); + spi_init(aiit_lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 32, 0); + spi_init_non_standard(aiit_lcd->spi_channel, + 0 /*instrction length*/, + 32 /*address length */, + 0 /*wait cycles */, + SPI_AITM_AS_FRAME_FORMAT ); + spi_fill_data_dma(aiit_lcd->dma_channel, aiit_lcd->spi_channel, aiit_lcd->cs, (const uint32_t *)&data, aiit_lcd->lcd_info.width * aiit_lcd->lcd_info.height / 2); +} + +static void DrvLcdRectUpdate(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height) +{ + static uint16 * rect_buffer = NONE; + if (!rect_buffer) { + rect_buffer = x_malloc(aiit_lcd->lcd_info.height * aiit_lcd->lcd_info.width * (aiit_lcd->lcd_info.bits_per_pixel / 8)); + if (!rect_buffer) { + return; + } + } + if (x1 == 0 && y1 == 0 && width == aiit_lcd->lcd_info.width && height == aiit_lcd->lcd_info.height) { + DrvLcdSetArea(x1, y1, x1 + width - 1, y1 + height - 1); + DrvLcdDataWord((uint32 *)aiit_lcd->lcd_info.framebuffer, width * height / (aiit_lcd->lcd_info.bits_per_pixel / 8)); + } else { + DrvLcdSetArea(x1, y1, x1 + width - 1, y1 + height - 1); + DrvLcdDataWord((uint32 *)rect_buffer, width * height / 2); + } +} + +x_err_t DrvLcdInit(Lcd8080DeviceType dev) +{ + x_err_t ret = EOK; + aiit_lcd = (Lcd8080DeviceType)dev; + uint8 data = 0; + + if (!aiit_lcd) + { + return -ERROR; + } + DrvLcdHwInit(aiit_lcd); + /* reset LCD */ + DrvLcdCmd(SOFTWARE_RESET); + MdelayKTask(100); + + /* Enter normal status */ + DrvLcdCmd(SLEEP_OFF); + MdelayKTask(100); + + /* pixel format rgb565 */ + DrvLcdCmd(PIXEL_FORMAT_SET); + data = 0x55; + DrvLcdDataByte(&data, 1); + + /* set direction */ + DrvLcdSetDirection(DIR_YX_RLUD); + + aiit_lcd->lcd_info.framebuffer = x_malloc(aiit_lcd->lcd_info.height * aiit_lcd->lcd_info.width * (aiit_lcd->lcd_info.bits_per_pixel / 8)); + CHECK(aiit_lcd->lcd_info.framebuffer); + + /*display on*/ + DrvLcdCmd(DISPALY_ON); + + return ret; +} + +static uint32 drv_lcd_control(void* drv, struct BusConfigureInfo *configure_info) +{ + x_err_t ret = EOK; + struct LcdDriver *lcddrv = (struct LcdDriver *)drv; + + struct DeviceRectInfo* rect_info; + NULL_PARAM_CHECK(drv); + + switch (configure_info->configure_cmd) + { + case GRAPHIC_CTRL_RECT_UPDATE: + rect_info = (struct DeviceRectInfo*)configure_info->private_data; + if(!rect_info) + { + SYS_ERR("GRAPHIC_CTRL_RECT_UPDATE error args"); + return -ERROR; + } + DrvLcdRectUpdate(rect_info->x, rect_info->y, rect_info->width, rect_info->height); + break; + + case GRAPHIC_CTRL_POWERON: + /* Todo: power on */ + ret = -ENONESYS; + break; + + case GRAPHIC_CTRL_POWEROFF: + /* Todo: power off */ + ret = -ENONESYS; + break; + + case GRAPHIC_CTRL_GET_INFO: + *(struct DeviceLcdInfo *)configure_info->private_data = aiit_lcd->lcd_info; + break; + + case GRAPHIC_CTRL_SET_MODE: + ret = -ENONESYS; + break; + case GRAPHIC_CTRL_GET_EXT: + ret = -ENONESYS; + break; + default: + SYS_ERR("drv_lcd_control cmd: %d", configure_info->configure_cmd); + break; + } + + return ret; +} + +void ClearHandwriting (void) +{ + //clear the lcd + DrvLcdClear(WHITE); + + LcdShowString(10, 10, 100, 24, 24, "RST ", RED, WHITE); +} + +#ifdef CONFIG_TOUCH +void HandTest(unsigned short *x_pos, unsigned short *y_pos) +{ + float x1,y1; + TpReadXy(x_pos,y_pos); //address + float a = 12.1875,b = 16.25; + x1 = 320 - (*x_pos)/a +10; + y1 = (* y_pos)/b; + + if ((*x_pos> 500)&&(*y_pos<500)) { + ClearHandwriting(); + } else { + DrvLcdSetPixel(x1, y1, RED); + DrvLcdSetPixel(x1+1, y1, RED); + DrvLcdSetPixel(x1-1, y1, RED); + + DrvLcdSetPixel(x1, y1+1, RED); + DrvLcdSetPixel(x1, y1-1, RED); + + DrvLcdSetPixel(x1+1, y1+1, RED); + DrvLcdSetPixel(x1-1, y1-1, RED); + + DrvLcdSetPixel(x1+1, y1-1, RED); + DrvLcdSetPixel(x1-1, y1+1, RED); + } +} +#endif + +static uint32 LcdWrite(void *dev, struct BusBlockWriteParam *write_param) +{ + if (write_param == NONE) { + return -ERROR; + } + LcdWriteParam * show = (LcdWriteParam *)write_param->buffer; + // KPrintf("DEBUG TYPE %d X1:%d X2:%d Y1:%d Y2:%d\n",show->type,show->pixel_info.x_startpos, show->pixel_info.x_endpos,show->pixel_info.y_startpos, show->pixel_info.y_endpos); + if(0 == show->type) //output string + { + LcdShowString(show->string_info.x_pos,show->string_info.y_pos,show->string_info.width,show->string_info.height,show->string_info.font_size,show->string_info.addr,show->string_info.font_color,show->string_info.back_color); + return EOK; + } + else if(1 == show->type) //output dot + { + // DrvLcdSetPixel(show->pixel_info.x_pos, show->pixel_info.y_pos, show->pixel_info.pixel_color); + DrvLcdSetPixelDot(show->pixel_info.x_startpos,show->pixel_info.y_startpos, show->pixel_info.x_endpos, show->pixel_info.y_endpos,show->pixel_info.pixel_color); + return EOK; + } + else + { + return -ERROR; + } +} + +uint32 DrvLcdClearDone(void * dev, struct BusConfigureInfo *configure_info) +{ + uint16 color = 0; + color =(uint16)(configure_info->configure_cmd |0x0000ffff ); + DrvLcdClear( color); + return 0; +} + +const struct LcdDevDone lcd_dev_done = +{ + .open = NONE, + .close = NONE, + .write = LcdWrite, + .read = NONE +}; + +static int BoardLcdBusInit(struct LcdBus * lcd_bus, struct LcdDriver * lcd_driver,const char *bus_name, const char *drv_name) +{ + x_err_t ret = EOK; + + /*Init the lcd bus */ + ret = LcdBusInit( lcd_bus, bus_name); + if (EOK != ret) { + KPrintf("Board_lcd_init LcdBusInit error %d\n", ret); + return -ERROR; + } + + /*Init the lcd driver*/ + ret = LcdDriverInit( lcd_driver, drv_name); + if (EOK != ret) { + KPrintf("Board_LCD_init LcdDriverInit error %d\n", ret); + return -ERROR; + } + + /*Attach the lcd driver to the lcd bus*/ + ret = LcdDriverAttachToBus(drv_name, bus_name); + if (EOK != ret) { + KPrintf("Board_LCD_init LcdDriverAttachToBus error %d\n", ret); + return -ERROR; + } + + return ret; +} + +/*Attach the lcd device to the lcd bus*/ +static int BoardLcdDevBend(struct LcdHardwareDevice *lcd_device, void *param, const char *bus_name, const char *dev_name) +{ + x_err_t ret = EOK; + + ret = LcdDeviceRegister(lcd_device, NONE, dev_name); + if (EOK != ret) { + KPrintf("Board_LCD_init LcdDeviceInit device %s error %d\n", dev_name, ret); + return -ERROR; + } + + ret = LcdDeviceAttachToBus(dev_name, bus_name); + if (EOK != ret) { + KPrintf("Board_LCD_init LcdDeviceAttachToBus device %s error %d\n", dev_name, ret); + return -ERROR; + } + + return ret; +} + +int HwLcdInit(void) +{ + x_err_t ret = EOK; + + static struct LcdDriver lcd_driver; + memset(&lcd_driver, 0, sizeof(struct LcdDriver)); + + Lcd8080DeviceType lcd_dev = (Lcd8080DeviceType )x_malloc(sizeof( struct Lcd8080Device)); + if (!lcd_dev) + { + return -ERROR; + } + + memset(lcd_dev, 0, sizeof(struct Lcd8080Device)); + + // FpioaSetFunction(BSP_LCD_DC_PIN, FUNC_GPIOHS9); //DC order/data + // FpioaSetFunction(BSP_LCD_BL_PIN, FUNC_GPIOHS10); //BL + // FpioaSetFunction(BSP_LCD_CS_PIN, FUNC_SPI0_SS0); //chip select + // FpioaSetFunction(BSP_LCD_WR_PIN, FUNC_SPI0_SCLK); //clk + + lcd_dev->cs = SPI_CHIP_SELECT_0; + lcd_dev->dc_pin = FPIOA_LCD_DC; + lcd_dev->dma_channel = DMAC_CHANNEL0; + lcd_dev->spi_channel = SPI_DEVICE_0; + lcd_dev->lcd_info.bits_per_pixel = 16; + lcd_dev->lcd_info.pixel_format = PIXEL_FORMAT_BGR565; + + sysctl_set_power_mode(SYSCTL_POWER_BANK6, SYSCTL_POWER_V18); + sysctl_set_power_mode(SYSCTL_POWER_BANK7, SYSCTL_POWER_V18); + + sysctl_set_spi0_dvp_data(1); //open the lcd interface with spi0 + + lcd_driver.configure = &drv_lcd_control; + + ret = BoardLcdBusInit(&lcd_dev->lcd_bus, &lcd_driver, LCD_BUS_NAME, LCD_DRV_NAME); //init lcd bus + if (EOK != ret) + { + KPrintf("Board_lcd_Init error ret %u\n", ret); + x_free(lcd_dev); + return -ERROR; + } + + static struct LcdHardwareDevice lcd_device; + memset(&lcd_device, 0, sizeof(struct LcdHardwareDevice)); + + lcd_device.dev_done = &(lcd_dev_done); + + ret = BoardLcdDevBend(&lcd_device, NONE, LCD_BUS_NAME, LCD_DEVICE_NAME); //init lcd device + if (EOK != ret) + { + KPrintf("BoardLcdDevBend error ret %u\n", ret); + x_free(lcd_dev); + return -ERROR; + } + + gpiohs_set_drive_mode(FPIOA_LCD_RST, GPIO_DM_OUTPUT); + gpiohs_set_pin(FPIOA_LCD_RST, GPIO_PV_LOW); + MdelayKTask(100); + gpiohs_set_pin(FPIOA_LCD_RST, GPIO_PV_HIGH); + MdelayKTask(100); + + KPrintf("LCD driver inited ...\r\n"); + + DrvLcdInit(lcd_dev); + + return ret; +} + +//x1,y1:start +//x2,y2:end +void LcdDrawLine(uint16 x1, uint16 y1, uint16 x2, uint16 y2,uint16 color) +{ + uint16 t; + int xerr = 0, yerr = 0, delta_x, delta_y, distance; + int incx,incy,uRow,uCol; + delta_x = x2 - x1; + delta_y = y2 - y1; + uRow = x1; + uCol = y1; + + if(delta_x>0) + incx = 1; + else if(delta_x==0) + incx = 0; + else { + incx = -1; + delta_x = -delta_x; + } + + if(delta_y>0) + incy = 1; + else if(delta_y==0) + incy = 0; + else { + incy= -1; + delta_y = -delta_y; + } + + if (delta_x>delta_y) + distance=delta_x; + else + distance=delta_y; + + for(t = 0;t <= distance+1;t ++ ) { + DrvLcdSetPixel(uRow,uCol,color); + xerr += delta_x ; + yerr += delta_y ; + if (xerr>distance) { + xerr-=distance; + uRow+=incx; + } + if (yerr>distance) { + yerr-=distance; + uCol+=incy; + } + } +} + +void LcdDrawRectangle(uint16 x1, uint16 y1, uint16 x2, uint16 y2,uint16 color) +{ + LcdDrawLine(x1,y1,x2,y1,color); + LcdDrawLine(x1,y1,x1,y2,color); + LcdDrawLine(x1,y2,x2,y2,color); + LcdDrawLine(x2,y1,x2,y2,color); +} + +void LcdDrawCircle(uint16 x0,uint16 y0,uint8 r,uint16 color) +{ + int a,b; + int di; + a = 0; + b = r; + di = 3-(r<<1); + while(a <= b) { + DrvLcdSetPixel(x0+a,y0-b,color); //5 + DrvLcdSetPixel(x0+b,y0-a,color); //0 + DrvLcdSetPixel(x0+b,y0+a,color); //4 + DrvLcdSetPixel(x0+a,y0+b,color); //6 + DrvLcdSetPixel(x0-a,y0+b,color); //1 + DrvLcdSetPixel(x0-b,y0+a,color); + DrvLcdSetPixel(x0-a,y0-b,color); //2 + DrvLcdSetPixel(x0-b,y0-a,color); //7 + a++; + //Bresenham + if(di<0) + di += 4*a+6; + else { + di += 10+4*(a-b); + b--; + } + } +} diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/plic/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/plic/Kconfig new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/plic/Kconfig @@ -0,0 +1 @@ + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/plic/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/plic/Makefile new file mode 100644 index 000000000..b72b20855 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/plic/Makefile @@ -0,0 +1,5 @@ +SRC_FILES := drv_interrupt.c plic.c clint.c + + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/plic/clint.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/plic/clint.c new file mode 100644 index 000000000..d1af79f68 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/plic/clint.c @@ -0,0 +1,229 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file clint.c +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#include +#include +#include "encoding.h" +#include "clint.h" +#include "sysctl.h" + +volatile clint_t* const clint = (volatile clint_t*)CLINT_BASE_ADDR; +static clint_timer_instance_t clint_timer_instance[CLINT_NUM_CORES]; +static clint_ipi_instance_t clint_ipi_instance[CLINT_NUM_CORES]; + +uint64_t clint_get_time(void) +{ + /* No difference on cores */ + return clint->mtime; +} + +int clint_timer_init(void) +{ + /* Read core id */ + unsigned long core_id = current_coreid(); + /* Clear the Machine-Timer bit in MIE */ + CLEAR_CSR(mie, MIP_MTIP); + /* Fill core's instance with original data */ + + /* clang-format off */ + clint_timer_instance[core_id] = (const clint_timer_instance_t) + { + .interval = 0, + .cycles = 0, + .single_shot = 0, + .callback = NULL, + .ctx = NULL, + }; + /* clang-format on */ + + return 0; +} + +int clint_timer_stop(void) +{ + /* Clear the Machine-Timer bit in MIE */ + CLEAR_CSR(mie, MIP_MTIP); + return 0; +} + +uint64_t clint_timer_get_freq(void) +{ + /* The clock is divided by CLINT_CLOCK_DIV */ + return SysctlClockGetFreq(SYSCTL_CLOCK_CPU) / CLINT_CLOCK_DIV; +} + +int clint_timer_start(uint64_t interval, int single_shot) +{ + /* Read core id */ + unsigned long core_id = current_coreid(); + /* Set timer interval */ + if (clint_timer_set_interval(interval) != 0) + return -1; + /* Set timer single shot */ + if (clint_timer_set_single_shot(single_shot) != 0) + return -1; + /* Check settings to prevent interval is 0 */ + if (clint_timer_instance[core_id].interval == 0) + return -1; + /* Check settings to prevent cycles is 0 */ + if (clint_timer_instance[core_id].cycles == 0) + return -1; + /* Add cycle interval to mtimecmp */ + uint64_t now = clint->mtime; + uint64_t then = now + clint_timer_instance[core_id].cycles; + /* Set mtimecmp by core id */ + clint->mtimecmp[core_id] = then; + /* Enable interrupts in general */ + SET_CSR(mstatus, MSTATUS_MIE); + /* Enable the Machine-Timer bit in MIE */ + SET_CSR(mie, MIP_MTIP); + return 0; +} + +uint64_t clint_timer_get_interval(void) +{ + /* Read core id */ + unsigned long core_id = current_coreid(); + return clint_timer_instance[core_id].interval; +} + +int clint_timer_set_interval(uint64_t interval) +{ + /* Read core id */ + unsigned long core_id = current_coreid(); + /* Check parameter */ + if (interval == 0) + return -1; + + /* Assign user interval with Millisecond(ms) */ + clint_timer_instance[core_id].interval = interval; + /* Convert interval to cycles */ + clint_timer_instance[core_id].cycles = interval * clint_timer_get_freq() / 1000ULL; + return 0; +} + +int clint_timer_get_single_shot(void) +{ + /* Read core id */ + unsigned long core_id = current_coreid(); + /* Get single shot mode by core id */ + return clint_timer_instance[core_id].single_shot; +} + +int clint_timer_set_single_shot(int single_shot) +{ + /* Read core id */ + unsigned long core_id = current_coreid(); + /* Set single shot mode by core id */ + clint_timer_instance[core_id].single_shot = single_shot; + return 0; +} + +int clint_timer_register(clint_timer_callback_t callback, void *ctx) +{ + /* Read core id */ + unsigned long core_id = current_coreid(); + /* Set user callback function */ + clint_timer_instance[core_id].callback = callback; + /* Assign user context */ + clint_timer_instance[core_id].ctx = ctx; + return 0; +} + +int clint_timer_unregister(void) +{ + /* Just assign NULL to user callback function and context */ + return clint_timer_register(NULL, NULL); +} + +int clint_ipi_init(void) +{ + /* Read core id */ + unsigned long core_id = current_coreid(); + /* Clear the Machine-Software bit in MIE */ + CLEAR_CSR(mie, MIP_MSIP); + /* Fill core's instance with original data */ + /* clang-format off */ + clint_ipi_instance[core_id] = (const clint_ipi_instance_t){ + .callback = NULL, + .ctx = NULL, + }; + /* clang-format on */ + + return 0; +} + +int clint_ipi_enable(void) +{ + /* Enable interrupts in general */ + SET_CSR(mstatus, MSTATUS_MIE); + /* Set the Machine-Software bit in MIE */ + SET_CSR(mie, MIP_MSIP); + return 0; +} + +int clint_ipi_disable(void) +{ + /* Clear the Machine-Software bit in MIE */ + CLEAR_CSR(mie, MIP_MSIP); + return 0; +} + +int clint_ipi_send(size_t core_id) +{ + if (core_id >= CLINT_NUM_CORES) + return -1; + clint->msip[core_id].msip = 1; + return 0; +} + +int clint_ipi_clear(size_t core_id) +{ + if (core_id >= CLINT_NUM_CORES) + return -1; + if (clint->msip[core_id].msip) + { + clint->msip[core_id].msip = 0; + return 1; + } + return 0; +} + +int clint_ipi_register(clint_ipi_callback_t callback, void *ctx) +{ + /* Read core id */ + unsigned long core_id = current_coreid(); + /* Set user callback function */ + clint_ipi_instance[core_id].callback = callback; + /* Assign user context */ + clint_ipi_instance[core_id].ctx = ctx; + return 0; +} + +int clint_ipi_unregister(void) +{ + /* Just assign NULL to user callback function and context */ + return clint_ipi_register(NULL, NULL); +} + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/plic/drv_interrupt.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/plic/drv_interrupt.c new file mode 100644 index 000000000..c41dbaead --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/plic/drv_interrupt.c @@ -0,0 +1,41 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file drv_interrupt.c +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#include + +void PlicIrqHandle(plic_irq_t irq) +{ + plic_instance_t (*plic_instance)[IRQN_MAX] = plic_get_instance(); + if (plic_instance[0][irq].callback) + { + plic_instance[0][irq].callback( + plic_instance[0][irq].ctx); + } + else if (plic_instance[1][irq].callback) + { + plic_instance[1][irq].callback( + plic_instance[1][irq].ctx); + } +} + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/plic/plic.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/plic/plic.c new file mode 100644 index 000000000..9c091ed9d --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/plic/plic.c @@ -0,0 +1,219 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file plic.c +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#include +#include +#include "encoding.h" +#include "plic.h" +#include "syscalls.h" +#include "syslog.h" + +volatile plic_t* const plic = (volatile plic_t*)PLIC_BASE_ADDR; + +static plic_instance_t plic_instance[PLIC_NUM_CORES][IRQN_MAX]; + +void plic_init(void) +{ + int i = 0; + + /* Get current core id */ + unsigned long core_id = current_coreid(); + + /* Disable all interrupts for the current core. */ + for (i = 0; i < ((PLIC_NUM_SOURCES + 32u) / 32u); i++) + plic->target_enables.target[core_id].enable[i] = 0; + + static uint8_t s_plic_priorities_init_flag = 0; + /* Set priorities to zero. */ + if(s_plic_priorities_init_flag == 0) + { + for (i = 0; i < PLIC_NUM_SOURCES; i++) + plic->source_priorities.priority[i] = 0; + s_plic_priorities_init_flag = 1; + } + + /* Set the threshold to zero. */ + plic->targets.target[core_id].priority_threshold = 0; + + /* Clear PLIC instance for every cores */ + for (i = 0; i < IRQN_MAX; i++) + { + /* clang-format off */ + plic_instance[core_id][i] = (const plic_instance_t){ + .callback = NULL, + .ctx = NULL, + }; + /* clang-format on */ + } + + /* + * A successful claim will also atomically clear the corresponding + * pending bit on the interrupt source. A target can perform a claim + * at any time, even if the EIP is not set. + */ + i = 0; + while (plic->targets.target[core_id].claim_complete > 0 && i < 100) + { + /* This loop will clear pending bit on the interrupt source */ + i++; + } + + /* Enable machine external interrupts. */ + SET_CSR(mie, MIP_MEIP); +} + +int plic_irq_enable(plic_irq_t irq_number) +{ + /* Check parameters */ + if (PLIC_NUM_SOURCES < irq_number || 0 > irq_number) + return -1; + unsigned long core_id = current_coreid(); + /* Get current enable bit array by IRQ number */ + uint32_t current = plic->target_enables.target[core_id].enable[irq_number / 32]; + /* Set enable bit in enable bit array */ + current |= (uint32_t)1 << (irq_number % 32); + /* Write back the enable bit array */ + plic->target_enables.target[core_id].enable[irq_number / 32] = current; + return 0; +} + +int plic_irq_disable(plic_irq_t irq_number) +{ + /* Check parameters */ + if (PLIC_NUM_SOURCES < irq_number || 0 > irq_number) + return -1; + unsigned long core_id = current_coreid(); + /* Get current enable bit array by IRQ number */ + uint32_t current = plic->target_enables.target[core_id].enable[irq_number / 32]; + /* Clear enable bit in enable bit array */ + current &= ~((uint32_t)1 << (irq_number % 32)); + /* Write back the enable bit array */ + plic->target_enables.target[core_id].enable[irq_number / 32] = current; + return 0; +} + +int plic_set_priority(plic_irq_t irq_number, uint32_t priority) +{ + /* Check parameters */ + if (PLIC_NUM_SOURCES < irq_number || 0 > irq_number) + return -1; + /* Set interrupt priority by IRQ number */ + plic->source_priorities.priority[irq_number] = priority; + return 0; +} + +uint32_t plic_get_priority(plic_irq_t irq_number) +{ + /* Check parameters */ + if (PLIC_NUM_SOURCES < irq_number || 0 > irq_number) + return 0; + /* Get interrupt priority by IRQ number */ + return plic->source_priorities.priority[irq_number]; +} + +uint32_t plic_irq_claim(void) +{ + unsigned long core_id = current_coreid(); + /* Perform IRQ claim */ + return plic->targets.target[core_id].claim_complete; +} + +int plic_irq_complete(uint32_t source) +{ + unsigned long core_id = current_coreid(); + /* Perform IRQ complete */ + plic->targets.target[core_id].claim_complete = source; + return 0; +} + +void plic_irq_register(plic_irq_t irq, plic_irq_callback_t callback, void *ctx) +{ + /* Read core id */ + unsigned long core_id = current_coreid(); + /* Set user callback function */ + plic_instance[core_id][irq].callback = callback; + /* Assign user context */ + plic_instance[core_id][irq].ctx = ctx; +} + +void plic_irq_unregister(plic_irq_t irq) +{ + /* Just assign NULL to user callback function and context */ + plic_irq_register(irq, NULL, NULL); +} + +void __attribute__((weak, alias("plic_irq_unregister"))) plic_irq_deregister(plic_irq_t irq); + +plic_instance_t (*plic_get_instance(void))[IRQN_MAX] +{ + return plic_instance; +} + +/*Entry Point for PLIC Interrupt Handler*/ +uintptr_t __attribute__((weak)) +HandleIrqMExt(uintptr_t cause, uintptr_t epc) +{ + /* + * After the highest-priority pending interrupt is claimed by a target + * and the corresponding IP bit is cleared, other lower-priority + * pending interrupts might then become visible to the target, and so + * the PLIC EIP bit might not be cleared after a claim. The interrupt + * handler can check the local meip/heip/seip/ueip bits before exiting + * the handler, to allow more efficient service of other interrupts + * without first restoring the interrupted context and taking another + * interrupt trap. + */ + if (READ_CSR(mip) & MIP_MEIP) + { + /* Get current core id */ + uint64_t core_id = current_coreid(); + /* Get primitive interrupt enable flag */ + uint64_t ie_flag = READ_CSR(mie); + /* Get current IRQ num */ + uint32_t int_num = plic->targets.target[core_id].claim_complete; + /* Get primitive IRQ threshold */ + uint32_t int_threshold = plic->targets.target[core_id].priority_threshold; + /* Set new IRQ threshold = current IRQ threshold */ + plic->targets.target[core_id].priority_threshold = plic->source_priorities.priority[int_num]; + /* Disable software interrupt and timer interrupt */ + CLEAR_CSR(mie, MIP_MTIP | MIP_MSIP); + /* Enable global interrupt */ + SET_CSR(mstatus, MSTATUS_MIE); + if (plic_instance[core_id][int_num].callback) + plic_instance[core_id][int_num].callback( + plic_instance[core_id][int_num].ctx); + /* Perform IRQ complete */ + plic->targets.target[core_id].claim_complete = int_num; + /* Disable global interrupt */ + CLEAR_CSR(mstatus, MSTATUS_MIE); + /* Set MPIE and MPP flag used to MRET instructions restore MIE flag */ + SET_CSR(mstatus, MSTATUS_MPIE | MSTATUS_MPP); + /* Restore primitive interrupt enable flag */ + WRITE_CSR(mie, ie_flag); + /* Restore primitive IRQ threshold */ + plic->targets.target[core_id].priority_threshold = int_threshold; + } + + return epc; +} diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/Kconfig new file mode 100644 index 000000000..e853dd40a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/Kconfig @@ -0,0 +1,11 @@ +if BSP_USING_RTC + config RTC_BUS_NAME + string "rtc bus name" + default "rtc" + config RTC_DRV_NAME + string "rtc bus driver name" + default "rtc_drv" + config RTC_DEVICE_NAME + string "rtc bus device name" + default "rtc_dev" +endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/Makefile new file mode 100644 index 000000000..23575e62e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_rtc.c hardware_rtc.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/connect_rtc.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/connect_rtc.c new file mode 100644 index 000000000..fc512b865 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/connect_rtc.c @@ -0,0 +1,183 @@ +/* +* 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_rtc.c +* @brief support aiit-riscv64-board rtc function and register to bus framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#include +#include +#include +#include +#include +#include + +static int GetWeekDay(int year, int month, int day) +{ + /* Magic method to get weekday */ + int weekday = (day += month < 3 ? year-- : year - 2, + 23 * month / 9 + day + 4 + year / 4 - year / 100 + year / 400) % 7; + return weekday; +} + +static uint32 RtcConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(drv); + + struct RtcDriver *rtc_drv = (struct RtcDriver *)drv; + struct RtcDrvConfigureParam *drv_param = (struct RtcDrvConfigureParam *)configure_info->private_data; + + int cmd = drv_param->rtc_operation_cmd; + time_t *time = drv_param->time; + + switch (cmd) + { + case OPER_RTC_GET_TIME: + { + struct tm ct; + int year,month,day,hour,minute,second; + memset(&ct,0,sizeof(struct tm)); + + rtc_timer_get(&year, &month, &day, &hour, &minute, &second); + + ct.tm_year = year - 1900; + ct.tm_mon = month - 1; + ct.tm_mday = day; + ct.tm_wday = GetWeekDay(year, month, day); + + ct.tm_hour = hour; + ct.tm_min = minute; + ct.tm_sec = second; + + *time = mktime(&ct); + } + break; + case OPER_RTC_SET_TIME: + { + struct tm *ct; + struct tm tm_new; + x_base lock; + + lock = CriticalAreaLock(); + ct = localtime(time); + memcpy(&tm_new, ct, sizeof(struct tm)); + CriticalAreaUnLock(lock); + + sysctl_reset(SYSCTL_RESET_RTC); + sysctl_clock_enable(SYSCTL_CLOCK_RTC); + rtc_protect_set(0); + rtc_timer_set_clock_frequency(SysctlClockGetFreq(SYSCTL_CLOCK_IN0)); + rtc_timer_set_clock_count_value(1); + rtc_timer_set_mode(RTC_TIMER_RUNNING); + + if (rtc_timer_set(tm_new.tm_year+1900,tm_new.tm_mon+1,tm_new.tm_mday, + tm_new.tm_hour,tm_new.tm_min,tm_new.tm_sec)==-1) + return ERROR; + } + break; + } + return EOK; +} + +/*manage the rtc device operations*/ +static const struct RtcDevDone dev_done = +{ + .open = NONE, + .close = NONE, + .write = NONE, + .read = NONE, +}; + +static int BoardRtcBusInit(struct RtcBus *rtc_bus, struct RtcDriver *rtc_driver) +{ + x_err_t ret = EOK; + + /*Init the rtc bus */ + ret = RtcBusInit(rtc_bus, RTC_BUS_NAME); + if (EOK != ret) { + KPrintf("HwRtcInit RtcBusInit error %d\n", ret); + return ERROR; + } + + /*Init the rtc driver*/ + ret = RtcDriverInit(rtc_driver, RTC_DRV_NAME); + if (EOK != ret) { + KPrintf("HwRtcInit RtcDriverInit error %d\n", ret); + return ERROR; + } + + /*Attach the rtc driver to the rtc bus*/ + ret = RtcDriverAttachToBus(RTC_DRV_NAME, RTC_BUS_NAME); + if (EOK != ret) { + KPrintf("HwRtcInit RtcDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +/*Attach the rtc device to the rtc bus*/ +static int BoardRtcDevBend(void) +{ + x_err_t ret = EOK; + + static struct RtcHardwareDevice rtc_device; + memset(&rtc_device, 0, sizeof(struct RtcHardwareDevice)); + + rtc_device.dev_done = &(dev_done); + + ret = RtcDeviceRegister(&rtc_device, NONE, RTC_DEVICE_NAME); + if (EOK != ret) { + KPrintf("HwRtcInit RtcDeviceInit device %s error %d\n", RTC_DEVICE_NAME, ret); + return ERROR; + } + + ret = RtcDeviceAttachToBus(RTC_DEVICE_NAME, RTC_BUS_NAME); + if (EOK != ret) { + KPrintf("HwRtcInit RtcDeviceAttachToBus device %s error %d\n", RTC_DEVICE_NAME, ret); + return ERROR; + } + + return ret; +} + +int HwRtcInit(void) +{ + x_err_t ret = EOK; + + static struct RtcBus rtc_bus; + memset(&rtc_bus, 0, sizeof(struct RtcBus)); + + static struct RtcDriver rtc_driver; + memset(&rtc_driver, 0, sizeof(struct RtcDriver)); + + rtc_driver.configure = &(RtcConfigure); + + ret = BoardRtcBusInit(&rtc_bus, &rtc_driver); + if (EOK != ret) { + KPrintf("HwRtcInit error ret %u\n", ret); + return ERROR; + } + + ret = BoardRtcDevBend(); + if (EOK != ret) { + KPrintf("HwRtcInit error ret %u\n", ret); + } + + rtc_init(); + + return ret; +} diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/hardware_rtc.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/hardware_rtc.c new file mode 100644 index 000000000..3f168dbf6 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/rtc/hardware_rtc.c @@ -0,0 +1,597 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file hardware_rtc.c +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#include +#include +#include +#include +#include +#include + +volatile rtc_t *const rtc = (volatile rtc_t *)RTC_BASE_ADDR; + +struct tm rtc_date_time; + +void rtc_timer_set_mode(rtc_timer_mode_t timer_mode) +{ + rtc_register_ctrl_t register_ctrl = rtc->register_ctrl; + + switch (timer_mode) + { + case RTC_TIMER_PAUSE: + register_ctrl.read_enable = 0; + register_ctrl.write_enable = 0; + break; + case RTC_TIMER_RUNNING: + register_ctrl.read_enable = 1; + register_ctrl.write_enable = 0; + break; + case RTC_TIMER_SETTING: + register_ctrl.read_enable = 0; + register_ctrl.write_enable = 1; + break; + default: + register_ctrl.read_enable = 0; + register_ctrl.write_enable = 0; + break; + } + rtc->register_ctrl = register_ctrl; +} + +rtc_timer_mode_t rtc_timer_get_mode(void) +{ + rtc_register_ctrl_t register_ctrl = rtc->register_ctrl; + rtc_timer_mode_t timer_mode = RTC_TIMER_PAUSE; + + if ((!register_ctrl.read_enable) && (!register_ctrl.write_enable)) + { + /* RTC_TIMER_PAUSE */ + timer_mode = RTC_TIMER_PAUSE; + } + else if ((register_ctrl.read_enable) && (!register_ctrl.write_enable)) + { + /* RTC_TIMER_RUNNING */ + timer_mode = RTC_TIMER_RUNNING; + } + else if ((!register_ctrl.read_enable) && (register_ctrl.write_enable)) { + /* RTC_TIMER_SETTING */ + timer_mode = RTC_TIMER_SETTING; + } + else + { + /* Something is error, reset timer mode */ + rtc_timer_set_mode(timer_mode); + } + + return timer_mode; +} + +static inline int rtc_in_range(int value, int min, int max) +{ + return ((value >= min) && (value <= max)); +} + +int rtc_timer_set_tm(const struct tm *tm) +{ + rtc_date_t timer_date; + rtc_time_t timer_time; + rtc_extended_t timer_extended; + + if (tm) + { + /* + * Range of tm->tm_sec could be [0,61] + * + * Range of tm->tm_sec allows for a positive leap second. Two + * leap seconds in the same minute are not allowed (the C90 + * range 0..61 was a defect) + */ + if (rtc_in_range(tm->tm_sec, 0, 59)) + timer_time.second = tm->tm_sec; + else + return -1; + + /* Range of tm->tm_min could be [0,59] */ + if (rtc_in_range(tm->tm_min, 0, 59)) + timer_time.minute = tm->tm_min; + else + return -1; + + /* Range of tm->tm_hour could be [0, 23] */ + if (rtc_in_range(tm->tm_hour, 0, 23)) + timer_time.hour = tm->tm_hour; + else + return -1; + + /* Range of tm->tm_mday could be [1, 31] */ + if (rtc_in_range(tm->tm_mday, 1, 31)) + timer_date.day = tm->tm_mday; + else + return -1; + + /* + * Range of tm->tm_mon could be [0, 11] + * But in this RTC, date.month should be [1, 12] + */ + if (rtc_in_range(tm->tm_mon, 0, 11)) + timer_date.month = tm->tm_mon + 1; + else + return -1; + + /* + * Range of tm->tm_year is the years since 1900 + * But in this RTC, year is split into year and century + * In this RTC, century range is [0,31], year range is [0,99] + */ + int human_year = tm->tm_year + 1900; + int rtc_year = human_year % 100; + int rtc_century = human_year / 100; + + if (rtc_in_range(rtc_year, 0, 99) && + rtc_in_range(rtc_century, 0, 31)) + { + timer_date.year = rtc_year; + timer_extended.century = rtc_century; + } + else + return -1; + + /* Range of tm->tm_wday could be [0, 6] */ + if (rtc_in_range(tm->tm_wday, 0, 6)) + timer_date.week = tm->tm_wday; + else + return -1; + + /* Set RTC mode to timer setting mode */ + rtc_timer_set_mode(RTC_TIMER_SETTING); + /* Write value to RTC */ + rtc->date = timer_date; + rtc->time = timer_time; + rtc->extended = timer_extended; + /* Get CPU current freq */ + unsigned long freq = SysctlClockGetFreq(SYSCTL_CLOCK_CPU); + /* Set threshold to 1/26000000 s */ + freq = freq / 26000000; + /* Get current CPU cycle */ + unsigned long start_cycle = read_cycle(); + /* Wait for 1/26000000 s to sync data */ + while (read_cycle() - start_cycle < freq) + continue; + /* Set RTC mode to timer running mode */ + rtc_timer_set_mode(RTC_TIMER_RUNNING); + } + + return 0; +} + +int rtc_timer_set_alarm_tm(const struct tm *tm) +{ + rtc_alarm_date_t alarm_date; + rtc_alarm_time_t alarm_time; + + if (tm) { + /* + * Range of tm->tm_sec could be [0,61] + * + * Range of tm->tm_sec allows for a positive leap second. Two + * leap seconds in the same minute are not allowed (the C90 + * range 0..61 was a defect) + */ + if (rtc_in_range(tm->tm_sec, 0, 59)) + alarm_time.second = tm->tm_sec; + else + return -1; + + /* Range of tm->tm_min could be [0,59] */ + if (rtc_in_range(tm->tm_min, 0, 59)) + alarm_time.minute = tm->tm_min; + else + return -1; + + /* Range of tm->tm_hour could be [0, 23] */ + if (rtc_in_range(tm->tm_hour, 0, 23)) + alarm_time.hour = tm->tm_hour; + else + return -1; + + /* Range of tm->tm_mday could be [1, 31] */ + if (rtc_in_range(tm->tm_mday, 1, 31)) + alarm_date.day = tm->tm_mday; + else + return -1; + + /* + * Range of tm->tm_mon could be [0, 11] + * But in this RTC, date.month should be [1, 12] + */ + if (rtc_in_range(tm->tm_mon, 0, 11)) + alarm_date.month = tm->tm_mon + 1; + else + return -1; + + /* + * Range of tm->tm_year is the years since 1900 + * But in this RTC, year is split into year and century + * In this RTC, century range is [0,31], year range is [0,99] + */ + int human_year = tm->tm_year + 1900; + int rtc_year = human_year % 100; + int rtc_century = human_year / 100; + + if (rtc_in_range(rtc_year, 0, 99) && + rtc_in_range(rtc_century, 0, 31)) + { + alarm_date.year = rtc_year; + } else + return -1; + + /* Range of tm->tm_wday could be [0, 6] */ + if (rtc_in_range(tm->tm_wday, 0, 6)) + alarm_date.week = tm->tm_wday; + else + return -1; + + /* Write value to RTC */ + rtc->alarm_date = alarm_date; + rtc->alarm_time = alarm_time; + } + + return 0; +} + +static int rtc_year_is_leap(int year) +{ + return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); +} + +static int rtc_get_yday(int year, int month, int day) +{ + static const int days[2][13] = + { + {0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, + {0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335} + }; + int leap = rtc_year_is_leap(year); + + return days[leap][month] + day; +} + +static int rtc_get_wday(int year, int month, int day) +{ + /* Magic method to get weekday */ + int weekday = (day += month < 3 ? year-- : year - 2, 23 * month / 9 + day + 4 + year / 4 - year / 100 + year / 400) % 7; + return weekday; +} + +struct tm *rtc_timer_get_tm(void) +{ + if (rtc_timer_get_mode() != RTC_TIMER_RUNNING) + return NULL; + + rtc_date_t timer_date = rtc->date; + rtc_time_t timer_time = rtc->time; + rtc_extended_t timer_extended = rtc->extended; + + struct tm *tm = &rtc_date_time; + + tm->tm_sec = timer_time.second % 60; + tm->tm_min = timer_time.minute % 60; + tm->tm_hour = timer_time.hour % 24; + tm->tm_mday = (timer_date.day - 1) % 31 + 1; + tm->tm_mon = (timer_date.month - 1)% 12; + tm->tm_year = (timer_date.year % 100) + (timer_extended.century * 100) - 1900; + tm->tm_wday = timer_date.week; + tm->tm_yday = rtc_get_yday(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); + tm->tm_isdst = -1; + + return tm; +} + +struct tm *rtc_timer_get_alarm_tm(void) +{ + if (rtc_timer_get_mode() != RTC_TIMER_RUNNING) + return NULL; + + rtc_alarm_date_t alarm_date = rtc->alarm_date; + rtc_alarm_time_t alarm_time = rtc->alarm_time; + rtc_extended_t timer_extended = rtc->extended; + + struct tm *tm = &rtc_date_time; + + tm->tm_sec = alarm_time.second % 60; + tm->tm_min = alarm_time.minute % 60; + tm->tm_hour = alarm_time.hour % 24; + tm->tm_mday = alarm_date.day % 31; + tm->tm_mon = (alarm_date.month % 12) - 1; + /* Alarm and Timer use same timer_extended.century */ + tm->tm_year = (alarm_date.year % 100) + (timer_extended.century * 100) - 1900; + tm->tm_wday = alarm_date.week; + tm->tm_yday = rtc_get_yday(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); + tm->tm_isdst = -1; + + return tm; +} + +int rtc_timer_set(int year, int month, int day, int hour, int minute, int second) +{ + struct tm date_time = + { + .tm_sec = second, + .tm_min = minute, + .tm_hour = hour, + .tm_mday = day, + .tm_mon = month - 1, + .tm_year = year - 1900, + .tm_wday = rtc_get_wday(year, month, day), + .tm_yday = rtc_get_yday(year, month, day), + .tm_isdst = -1, + }; + return rtc_timer_set_tm(&date_time); +} + +int rtc_timer_get(int *year, int *month, int *day, int *hour, int *minute, int *second) +{ + struct tm *tm = rtc_timer_get_tm(); + + if (tm) + { + if (year) + *year = tm->tm_year + 1900; + if (month) + *month = tm->tm_mon + 1; + if (day) + *day = tm->tm_mday; + if (hour) + *hour = tm->tm_hour; + if (minute) + *minute = tm->tm_min; + if (second) + *second = tm->tm_sec; + } else + return -1; + + return 0; +} + +int rtc_timer_set_alarm(int year, int month, int day, int hour, int minute, int second) +{ + struct tm date_time = { + .tm_sec = second, + .tm_min = minute, + .tm_hour = hour, + .tm_mday = day, + .tm_mon = month - 1, + .tm_year = year - 1900, + .tm_wday = rtc_get_wday(year, month, day), + .tm_yday = rtc_get_yday(year, month, day), + .tm_isdst = -1, + }; + + return rtc_timer_set_alarm_tm(&date_time); +} + +int rtc_timer_get_alarm(int *year, int *month, int *day, int *hour, int *minute, int *second) +{ + struct tm *tm = rtc_timer_get_alarm_tm(); + + if (tm) { + if (year) + *year = tm->tm_year + 1900; + if (month) + *month = tm->tm_mon + 1; + if (day) + *day = tm->tm_mday; + if (hour) + *hour = tm->tm_hour; + if (minute) + *minute = tm->tm_min; + if (second) + *second = tm->tm_sec; + } else + return -1; + + return 0; +} + +int rtc_timer_set_clock_frequency(unsigned int frequency) +{ + + rtc_initial_count_t initial_count; + + initial_count.count = frequency; + rtc_timer_set_mode(RTC_TIMER_SETTING); + rtc->initial_count = initial_count; + rtc_timer_set_mode(RTC_TIMER_RUNNING); + return 0; +} + +unsigned int rtc_timer_get_clock_frequency(void) +{ + return rtc->initial_count.count; +} + +int rtc_timer_set_clock_count_value(unsigned int count) +{ + + rtc_current_count_t current_count; + + current_count.count = count; + rtc_timer_set_mode(RTC_TIMER_SETTING); + rtc->current_count = current_count; + rtc_timer_set_mode(RTC_TIMER_RUNNING); + return 0; +} + +unsigned int rtc_timer_get_clock_count_value(void) +{ + return rtc->current_count.count; +} + +int rtc_tick_interrupt_set(int enable) +{ + rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl; + interrupt_ctrl.tick_enable = enable; + rtc_timer_set_mode(RTC_TIMER_SETTING); + rtc->interrupt_ctrl = interrupt_ctrl; + rtc_timer_set_mode(RTC_TIMER_RUNNING); + return 0; +} + +int rtc_tick_interrupt_get(void) +{ + rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl; + + return interrupt_ctrl.tick_enable; +} + +int rtc_tick_interrupt_mode_set(rtc_tick_interrupt_mode_t mode) +{ + rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl; + + interrupt_ctrl.tick_int_mode = mode; + rtc_timer_set_mode(RTC_TIMER_SETTING); + rtc->interrupt_ctrl = interrupt_ctrl; + rtc_timer_set_mode(RTC_TIMER_RUNNING); + return 0; +} + +rtc_tick_interrupt_mode_t rtc_tick_interrupt_mode_get(void) +{ + rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl; + + return interrupt_ctrl.tick_int_mode; +} + +int rtc_alarm_interrupt_set(int enable) +{ + rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl; + + interrupt_ctrl.alarm_enable = enable; + rtc->interrupt_ctrl = interrupt_ctrl; + return 0; +} + +int rtc_alarm_interrupt_get(void) +{ + rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl; + + return interrupt_ctrl.alarm_enable; +} + +int rtc_alarm_interrupt_mask_set(rtc_mask_t mask) +{ + rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl; + + interrupt_ctrl.alarm_compare_mask = *(uint8_t *)&mask; + rtc->interrupt_ctrl = interrupt_ctrl; + return 0; +} + +rtc_mask_t rtc_alarm_interrupt_mask_get(void) +{ + rtc_interrupt_ctrl_t interrupt_ctrl = rtc->interrupt_ctrl; + + uint8_t compare_mask = interrupt_ctrl.alarm_compare_mask; + + return *(rtc_mask_t *)&compare_mask; +} + +int rtc_protect_set(int enable) +{ + rtc_register_ctrl_t register_ctrl = rtc->register_ctrl; + + rtc_mask_t mask = + { + .second = 1, + /* Second mask */ + .minute = 1, + /* Minute mask */ + .hour = 1, + /* Hour mask */ + .week = 1, + /* Week mask */ + .day = 1, + /* Day mask */ + .month = 1, + /* Month mask */ + .year = 1, + }; + + rtc_mask_t unmask = + { + .second = 0, + /* Second mask */ + .minute = 0, + /* Minute mask */ + .hour = 0, + /* Hour mask */ + .week = 0, + /* Week mask */ + .day = 0, + /* Day mask */ + .month = 0, + /* Month mask */ + .year = 0, + }; + + if (enable) + { + /* Turn RTC in protect mode, no one can write time */ + register_ctrl.TimerMask = *(uint8_t *)&unmask; + register_ctrl.alarm_mask = *(uint8_t *)&unmask; + register_ctrl.initial_count_mask = 0; + register_ctrl.interrupt_register_mask = 0; + } + else + { + /* Turn RTC in unprotect mode, everyone can write time */ + register_ctrl.TimerMask = *(uint8_t *)&mask; + register_ctrl.alarm_mask = *(uint8_t *)&mask; + register_ctrl.initial_count_mask = 1; + register_ctrl.interrupt_register_mask = 1; + } + rtc_timer_set_mode(RTC_TIMER_SETTING); + rtc->register_ctrl = register_ctrl; + rtc_timer_set_mode(RTC_TIMER_RUNNING); + return 0; +} + +int rtc_init(void) +{ + /* Reset RTC */ + sysctl_reset(SYSCTL_RESET_RTC); + /* Enable RTC */ + sysctl_clock_enable(SYSCTL_CLOCK_RTC); + /* Unprotect RTC */ + rtc_protect_set(0); + /* Set RTC clock frequency */ + rtc_timer_set_clock_frequency( + SysctlClockGetFreq(SYSCTL_CLOCK_IN0) + ); + rtc_timer_set_clock_count_value(1); + + /* Set RTC mode to timer running mode */ + rtc_timer_set_mode(RTC_TIMER_RUNNING); + return 0; +} diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/sleep.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/sleep.c new file mode 100644 index 000000000..ce4160d26 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/sleep.c @@ -0,0 +1,49 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file sleep.c +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#include "sleep.h" +#include "sysctl.h" + +int usleep(uint64_t usec) +{ + uint64_t cycle = read_cycle(); + uint64_t nop_all = usec * SysctlClockGetFreq(SYSCTL_CLOCK_CPU) / 1000000UL; + while (1) + { + if(read_cycle() - cycle >= nop_all) + break; + } + return 0; +} + +int msleep(uint64_t msec) +{ + return (unsigned int)usleep(msec * 1000); +} + +unsigned int sleep(unsigned int seconds) +{ + return (unsigned int)msleep(seconds * 1000); +} + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/Kconfig new file mode 100644 index 000000000..73b7f7c4f --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/Kconfig @@ -0,0 +1,43 @@ +if BSP_USING_SOFT_SPI + config SOFT_SPI_BUS_NAME + string "soft spi bus 1 name" + default "soft_spi1_bus1" + + config SOFT_SPI_DEVICE_NAME + string "soft spi dev 1 name" + default "soft_spi1_dev1" + + config SOFT_SPI_DRV_NAME + string "soft spi drv 1 name" + default "soft_spi1_drv1" + + config SOFT_SPI_SCK + int "soft spi sck pin" + default 26 + + config SOFT_SPI_MOSI + int "soft spi mosi pin" + default 27 + + config SOFT_SPI_MISO + int "soft spi miso pin" + default 25 + + config SOFT_SPI_CS0_PIN + int "soft spi cs pin" + default 28 + + config SOFT_SPI_DEVICE_SLAVE_ID + int "soft spi slave id" + default 0 + + config SOFT_SPI_CHIP_SELECT + int "soft spi chip selected" + default 0 + + config SOFT_SPI_CLK_DELAY + int "clk in microsecond" + default 0 + +endif + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/Makefile new file mode 100644 index 000000000..8ccf2895c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_soft_spi.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/connect_soft_spi.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/connect_soft_spi.c new file mode 100644 index 000000000..9cf961d40 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/soft_spi/connect_soft_spi.c @@ -0,0 +1,295 @@ +#include +#include +#include +#include +#include "drv_io_config.h" +#include +#include +#include +#include + +#include +#include +#include + +static x_err_t softSPIinit(struct SpiDriver *spi_drv, struct BusConfigureInfo *cfg) +{ + NULL_PARAM_CHECK(spi_drv); + NULL_PARAM_CHECK(cfg); + + // mode CPOL = 0 CPHA = 0 + gpiohs_set_drive_mode(SOFT_SPI_CS0_PIN, GPIO_DM_OUTPUT); + gpiohs_set_pin(SOFT_SPI_CS0_PIN, GPIO_PV_HIGH); // set the cs gpio high + gpiohs_set_drive_mode(SOFT_SPI_SCK, GPIO_DM_OUTPUT); + gpiohs_set_drive_mode(SOFT_SPI_MOSI, GPIO_DM_OUTPUT); + gpiohs_set_drive_mode(SOFT_SPI_MISO, GPIO_DM_INPUT); + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_LOW); + KPrintf("%s init done\n", SOFT_SPI_BUS_NAME); + + return EOK; +} + +static uint32 softSpiDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + + x_err_t ret = EOK; + struct SpiDriver *spi_drv = (struct SpiDriver *)drv; + struct SpiMasterParam *spi_param; + + switch (configure_info->configure_cmd) + { + case OPE_INT: + softSPIinit(spi_drv, configure_info); + break; + + case OPE_CFG: + break; + default: + + break; + } + + return ret; +} + +static void soft_spi_writebyte(struct SpiHardwareDevice *spi_dev, uint8_t data) +{ + int8_t i = 0; + uint8_t temp = 0; + for (i = 0; i < 8; i++) + { + temp = ((data & 0x80) == 0x80) ? 1 : 0; + data = data << 1; + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_LOW); + usleep(SOFT_SPI_CLK_DELAY); + if (0 == temp) + { + gpiohs_set_pin(SOFT_SPI_MOSI, GPIO_PV_LOW); + } + else + { + gpiohs_set_pin(SOFT_SPI_MOSI, GPIO_PV_HIGH); + } + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_HIGH); + usleep(SOFT_SPI_CLK_DELAY); + } + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_LOW); +} + +/* 读一个字节 */ +static uint8_t soft_spi_readbyte(struct SpiHardwareDevice *spi_dev) +{ + uint8_t i = 0; + uint8_t read_data = 0xFF; + for (i = 0; i < 8; i++) + { + read_data = read_data << 1; + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_LOW); + usleep(SOFT_SPI_CLK_DELAY); + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_HIGH); + usleep(SOFT_SPI_CLK_DELAY); + if (1 == gpiohs_get_pin(SOFT_SPI_MISO)) + { + read_data = read_data | 0x01; + } + } + return read_data; +} + +/* 读写一个字节 */ +// this funcition is unverify until now! +static uint8_t soft_spi_readwritebyte(struct SpiHardwareDevice *spi_dev, uint8_t data) +{ + uint8_t i = 0; + uint8_t temp = 0; + uint8_t read_data = 0xFF; + for (i = 0; i < 8; i++) + { + temp = ((data & 0x80) == 0x80) ? 1 : 0; + data = data << 1; + read_data = read_data << 1; + if (temp == 0) + { + gpiohs_set_pin(SOFT_SPI_MOSI, GPIO_PV_LOW); + } + else + { + gpiohs_set_pin(SOFT_SPI_MOSI, GPIO_PV_HIGH); + } + usleep(SOFT_SPI_CLK_DELAY); + gpiohs_set_pin(SOFT_SPI_SCK, GPIO_PV_HIGH); + usleep(SOFT_SPI_CLK_DELAY); + if (gpiohs_get_pin(SOFT_SPI_MISO) == 1) + { + read_data = read_data + 1; + } + } + return read_data; +} + +static uint32 softSpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg) +{ + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); + + uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin; + const uint8_t *data_buff = spi_datacfg->tx_buff; + int data_length = spi_datacfg->length; + if (NONE == spi_datacfg->tx_buff) + { + data_length = 0; + } + + if (spi_datacfg->spi_chip_select) + { + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_LOW); + } + + for (size_t i = 0; i < data_length; i++) + { + soft_spi_writebyte(spi_dev, data_buff[i]); + } + + if (spi_datacfg->spi_cs_release) + { + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH); + } + spi_datacfg = spi_datacfg->next; + + return EOK; +} + +static uint32 softSpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg) +{ + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); + uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin; + uint8_t *recv_buff = spi_datacfg->rx_buff; + int recv_length = spi_datacfg->length; + + if (NONE == spi_datacfg->rx_buff) + { + recv_length = 0; + } + + if (spi_datacfg->spi_chip_select) + { + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_LOW); + } + + for (size_t i = 0; i < recv_length; i++) + { + recv_buff[i] = soft_spi_readbyte(spi_dev); + } + + if (spi_datacfg->spi_cs_release) + { + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH); + } + + spi_datacfg = spi_datacfg->next; + + return spi_datacfg->length; +} + +const struct SpiDevDone soft_spi_dev_done = { + .dev_close = NONE, + .dev_open = NONE, + .dev_read = softSpiReadData, + .dev_write = softSpiWriteData}; + +static int BoardSoftSpiBusInit(struct SpiBus *spi_bus, struct SpiDriver *spi_driver) +{ + x_err_t ret = EOK; + + /*Init the spi bus */ + ret = SpiBusInit(spi_bus, SOFT_SPI_BUS_NAME); + if (EOK != ret) + { + KPrintf("Board_Spi_init SpiBusInit error %d\n", ret); + return ERROR; + } + + /*Init the spi driver*/ + ret = SpiDriverInit(spi_driver, SOFT_SPI_DRV_NAME); + if (EOK != ret) + { + KPrintf("Board_Spi_init SpiDriverInit error %d\n", ret); + return ERROR; + } + + /*Attach the spi driver to the spi bus*/ + ret = SpiDriverAttachToBus(SOFT_SPI_DRV_NAME, SOFT_SPI_BUS_NAME); + if (EOK != ret) + { + KPrintf("Board_Spi_init SpiDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +static int BoardSoftSpiDevBend(void) +{ + x_err_t ret = EOK; + + static struct SpiHardwareDevice spi_device0; + memset(&spi_device0, 0, sizeof(struct SpiHardwareDevice)); + + static struct SpiSlaveParam spi_slaveparam0; + memset(&spi_slaveparam0, 0, sizeof(struct SpiSlaveParam)); + + spi_slaveparam0.spi_slave_id = SOFT_SPI_DEVICE_SLAVE_ID; + spi_slaveparam0.spi_cs_gpio_pin = SOFT_SPI_CS0_PIN; + spi_slaveparam0.spi_cs_select_id = SOFT_SPI_CHIP_SELECT; + + spi_device0.spi_param.spi_dma_param = NONE; + spi_device0.spi_param.spi_slave_param = &spi_slaveparam0; + + spi_device0.spi_dev_done = &(soft_spi_dev_done); + + ret = SpiDeviceRegister(&spi_device0, (void *)(&spi_device0.spi_param), SOFT_SPI_DEVICE_NAME); + if (EOK != ret) + { + KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", SOFT_SPI_DEVICE_NAME, ret); + return ERROR; + } + + ret = SpiDeviceAttachToBus(SOFT_SPI_DEVICE_NAME, SOFT_SPI_BUS_NAME); + if (EOK != ret) + { + KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", SOFT_SPI_DEVICE_NAME, ret); + return ERROR; + } + + return ret; +} + +int HwSoftSPIInit(void) +{ + x_err_t ret = EOK; + + static struct SpiBus spi_bus; + memset(&spi_bus, 0, sizeof(struct SpiBus)); + + static struct SpiDriver spi_driver; + memset(&spi_driver, 0, sizeof(struct SpiDriver)); + + spi_driver.configure = &(softSpiDrvConfigure); + + ret = BoardSoftSpiBusInit(&spi_bus, &spi_driver); + if (EOK != ret) + { + KPrintf("Board_Spi_Init error ret %u\n", ret); + return ERROR; + } + + ret = BoardSoftSpiDevBend(); + if (EOK != ret) + { + KPrintf("Board_Spi_Init error ret %u\n", ret); + return ERROR; + } + + return ret; +} diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/Kconfig new file mode 100644 index 000000000..d1ebdeb3c --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/Kconfig @@ -0,0 +1,102 @@ +config BSP_USING_SPI1 +bool "Using spi1 " +default y + + +if BSP_USING_SPI1 + config SPI_BUS_NAME_1 + string "spi bus 1 name" + default "spi1" + config SPI_1_DRV_NAME + string "spi bus 1 driver name" + default "spi1_drv" + config BSP_SPI1_CLK_PIN + int "spi1 clk pin number" + default 6 + config BSP_SPI1_D0_PIN + int "spi1 d0 pin number" + default 8 + config BSP_SPI1_D1_PIN + int "spi1 d1 pin number" + default 7 + menuconfig BSP_SPI1_USING_SS0 + bool "SPI1 Enable SS0" + default y + if BSP_SPI1_USING_SS0 + config SPI_1_DEVICE_NAME_0 + string "spi bus 1 device 0 name" + default "spi1_dev0" + config BSP_SPI1_SS0_PIN + int "spi1 ss0 pin number" + default 9 + menuconfig RESOURCES_SPI_LORA + bool "Using spi lora function" + default n + if RESOURCES_SPI_LORA + config SX12XX_DEVICE_NAME + string "SX1278 lora device name" + default "spi1_lora" + config SX12XX_DEVICE_RST_PIN + int + default 10 + + config SX12XX_DEVICE_DO0_PIN + int + default 10 + + config SX12XX_DEVICE_DO1_PIN + int + default 10 + + config SX12XX_DEVICE_DO2_PIN + int + default 10 + + config SX12XX_DEVICE_DO3_PIN + int + default 10 + + config SX12XX_DEVICE_DO4_PIN + int + default 10 + + config SX12XX_DEVICE_DO5_PIN + int + default 10 + endif + endif + menuconfig BSP_SPI1_USING_SS1 + bool "SPI1 Enable SS1" + default y + if BSP_SPI1_USING_SS1 + config SPI_1_DEVICE_NAME_1 + string "spi bus 1 device 1 name" + default "spi1_dev1" + config BSP_SPI1_SS1_PIN + int "spi1 ss1 pin number" + default 33 + endif + menuconfig BSP_SPI1_USING_SS2 + bool "SPI1 Enable SS2" + default n + if BSP_SPI1_USING_SS2 + config SPI_1_DEVICE_NAME_2 + string "spi bus 1 device 2 name" + default "spi1_dev2" + config BSP_SPI1_SS2_PIN + int "spi1 ss2 pin number" + default 26 + endif + menuconfig BSP_SPI1_USING_SS3 + bool "SPI1 Enable SS3" + default n + if BSP_SPI1_USING_SS3 + config SPI_1_DEVICE_NAME_3 + string "spi bus 1 device 3 name" + default "spi1_dev3" + config BSP_SPI1_SS3_PIN + int "spi1 ss3 pin number" + default 27 + endif +endif + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/Makefile new file mode 100644 index 000000000..f64c853be --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/Makefile @@ -0,0 +1,9 @@ +SRC_FILES := connect_spi.c hardware_spi.c + + +ifeq ($(CONFIG_RESOURCES_SPI_LORA),y) + SRC_DIR += third_party_spi_lora + SRC_FILES += connect_lora_spi.c +endif + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/connect_spi.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/connect_spi.c new file mode 100644 index 000000000..c2a7ee5fb --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/connect_spi.c @@ -0,0 +1,475 @@ +/* + * Copyright (c) 2020 RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-18 ZYH first version + */ + +/** +* @file connect_spi.c +* @brief support aiit-riscv64-board spi function and register to bus framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +/************************************************* +File name: connect_spi.c +Description: support aiit-riscv64-board spi configure and spi bus register function +Others: take RT-Thread v4.0.2/bsp/k210/driver/drv_spi.c for references + https://github.com/RT-Thread/rt-thread/tree/v4.0.2 +History: +1. Date: 2021-04-25 +Author: AIIT XUOS Lab +Modification: +1. support aiit-riscv64-board spi configure, write and read +2. support aiit-riscv64-board spi bus device and driver register +*************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BSP_SPI1_USING_SS0 +#define SPI_DEVICE_SLAVE_ID_0 0 +#endif + +#ifdef BSP_SPI1_USING_SS1 +#define SPI_DEVICE_SLAVE_ID_1 1 +#endif + +#ifdef BSP_SPI1_USING_SS2 +#define SPI_DEVICE_SLAVE_ID_2 2 +#endif + +#ifdef BSP_SPI1_USING_SS3 +#define SPI_DEVICE_SLAVE_ID_3 3 +#endif + +static volatile spi_t *const spi_instance[4] = +{ + (volatile spi_t *)SPI0_BASE_ADDR, + (volatile spi_t *)SPI1_BASE_ADDR, + (volatile spi_t *)SPI_SLAVE_BASE_ADDR, + (volatile spi_t *)SPI3_BASE_ADDR +}; + +void __spi_set_tmod(uint8_t spi_num, uint32_t tmod) +{ + CHECK(spi_num < SPI_DEVICE_MAX); + volatile spi_t *spi_handle = spi[spi_num]; + uint8_t tmod_offset = 0; + switch(spi_num) + { + case 0: + case 1: + case 2: + tmod_offset = 8; + break; + case 3: + default: + tmod_offset = 10; + break; + } + set_bit(&spi_handle->ctrlr0, 3 << tmod_offset, tmod << tmod_offset); +} + +/*Init the spi sdk intetface */ +static uint32 SpiSdkInit(struct SpiDriver *spi_drv) +{ + NULL_PARAM_CHECK(spi_drv); + uint8 cs_gpio_pin, cs_select_id; + uint32 max_frequency; + + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_drv->driver.private_data); + + cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin; + cs_select_id = dev_param->spi_slave_param->spi_cs_select_id; + + gpiohs_set_drive_mode(cs_select_id, GPIO_DM_OUTPUT);//Set the cs pin as output + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH);//set the cs gpio high + + spi_init(dev_param->spi_dma_param->spi_master_id, + dev_param->spi_master_param->spi_work_mode & SPI_MODE_3, + dev_param->spi_master_param->spi_frame_format, + dev_param->spi_master_param->spi_data_bit_width, + dev_param->spi_master_param->spi_data_endian); + + max_frequency = (dev_param->spi_master_param->spi_maxfrequency < SPI_MAX_CLOCK) ? dev_param->spi_master_param->spi_maxfrequency : SPI_MAX_CLOCK; + + uint32 real_freq = spi_set_clk_rate(dev_param->spi_dma_param->spi_master_id, max_frequency); + + return EOK; +} + +static uint32 SpiSdkCfg(struct SpiDriver *spi_drv, struct SpiMasterParam *spi_param) +{ + NULL_PARAM_CHECK(spi_drv); + NULL_PARAM_CHECK(spi_param); + + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_drv->driver.private_data); + + dev_param->spi_master_param = spi_param; + dev_param->spi_master_param->spi_work_mode = dev_param->spi_master_param->spi_work_mode & SPI_MODE_MASK; + dev_param->spi_master_param->spi_frame_format = SPI_FF_STANDARD; + + return EOK; +} + +/*Configure the spi device param, make sure struct (configure_info->private_data) = (SpiMasterParam)*/ +static uint32 SpiDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + + x_err_t ret = EOK; + struct SpiDriver *spi_drv = (struct SpiDriver *)drv; + struct SpiMasterParam *spi_param; + + switch (configure_info->configure_cmd) + { + case OPE_INT: + ret = SpiSdkInit(spi_drv); + break; + case OPE_CFG: + spi_param = (struct SpiMasterParam *)configure_info->private_data; + ret = SpiSdkCfg(spi_drv, spi_param); + break; + default: + break; + } + + return ret; +} + +static uint32 SpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg) +{ + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); + + uint8 device_id = dev_param->spi_slave_param->spi_slave_id; + uint8 device_master_id = dev_param->spi_dma_param->spi_master_id; + uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin; + + while (NONE != spi_datacfg) + { + uint32_t * tx_buff = NONE; + int i; + x_ubase dummy = 0xFFFFFFFFU; + + __spi_set_tmod(device_master_id, SPI_TMOD_TRANS_RECV); + + if (spi_datacfg->spi_chip_select) { + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_LOW); + } + + if (spi_datacfg->length) { + spi_instance[device_master_id]->dmacr = 0x3; + spi_instance[device_master_id]->ssienr = 0x01; + + sysctl_dma_select(dev_param->spi_dma_param->spi_dmac_txchannel, SYSCTL_DMA_SELECT_SSI0_TX_REQ + device_master_id * 2); + sysctl_dma_select(dev_param->spi_dma_param->spi_dmac_rxchannel, SYSCTL_DMA_SELECT_SSI0_RX_REQ + device_master_id* 2); + + dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_rxchannel, (void *)(&spi_instance[device_master_id]->dr[0]), &dummy, DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, spi_datacfg->length); + + if (!spi_datacfg->tx_buff) { + dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_txchannel, &dummy, (void *)(&spi_instance[device_master_id]->dr[0]), DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, spi_datacfg->length); + } else { + tx_buff = x_malloc(spi_datacfg->length * 4); + if (!tx_buff) { + goto transfer_done; + } + for (i = 0; i < spi_datacfg->length; i++) { + tx_buff[i] = ((uint8_t *)spi_datacfg->tx_buff)[i]; + } + dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_txchannel, tx_buff, (void *)(&spi_instance[device_master_id]->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, spi_datacfg->length); + } + + spi_instance[device_master_id]->ser = 1U << dev_param->spi_slave_param->spi_cs_select_id; + dmac_wait_done(dev_param->spi_dma_param->spi_dmac_txchannel); + dmac_wait_done(dev_param->spi_dma_param->spi_dmac_rxchannel); + spi_instance[device_master_id]->ser = 0x00; + spi_instance[device_master_id]->ssienr = 0x00; + + transfer_done: + if (tx_buff) { + x_free(tx_buff); + } + } + + if (spi_datacfg->spi_cs_release) { + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH); + } + + spi_datacfg = spi_datacfg->next; + } + + return EOK; +} + +static uint32 SpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg) +{ + SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data); + + uint32 spi_read_length = 0;; + uint8 device_id = dev_param->spi_slave_param->spi_slave_id; + uint8 device_master_id = dev_param->spi_dma_param->spi_master_id; + uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin; + + while (NONE != spi_datacfg) + { + uint32_t * rx_buff = NONE; + int i; + x_ubase dummy = 0xFFFFFFFFU; + + __spi_set_tmod(device_master_id, SPI_TMOD_TRANS_RECV); + + if (spi_datacfg->spi_chip_select) { + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_LOW); + } + if (spi_datacfg->length) { + spi_instance[device_master_id]->dmacr = 0x3; + spi_instance[device_master_id]->ssienr = 0x01; + + sysctl_dma_select(dev_param->spi_dma_param->spi_dmac_txchannel, SYSCTL_DMA_SELECT_SSI0_TX_REQ + device_master_id * 2); + sysctl_dma_select(dev_param->spi_dma_param->spi_dmac_rxchannel, SYSCTL_DMA_SELECT_SSI0_RX_REQ + device_master_id* 2); + + dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_txchannel, &dummy, (void *)(&spi_instance[device_master_id]->dr[0]), DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, spi_datacfg->length); + + if (!spi_datacfg->rx_buff) { + dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_rxchannel, (void *)(&spi_instance[device_master_id]->dr[0]), &dummy, DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, spi_datacfg->length); + } else { + rx_buff = x_calloc(spi_datacfg->length * 4, 1); + if(!rx_buff) + { + goto transfer_done; + } + + dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_rxchannel, (void *)(&spi_instance[device_master_id]->dr[0]), rx_buff, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, spi_datacfg->length); + } + + spi_instance[device_master_id]->ser = 1U << dev_param->spi_slave_param->spi_cs_select_id; + dmac_wait_done(dev_param->spi_dma_param->spi_dmac_txchannel); + dmac_wait_done(dev_param->spi_dma_param->spi_dmac_rxchannel); + spi_instance[device_master_id]->ser = 0x00; + spi_instance[device_master_id]->ssienr = 0x00; + + if (spi_datacfg->rx_buff) { + for (i = 0; i < spi_datacfg->length; i++) { + ((uint8_t *)spi_datacfg->rx_buff)[i] = (uint8_t)rx_buff[i]; + } + } + + transfer_done: + if (rx_buff) { + x_free(rx_buff); + } + } + + if (spi_datacfg->spi_cs_release) { + gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH); + } + + spi_read_length += spi_datacfg->length; + spi_datacfg = spi_datacfg->next; + } + + return spi_read_length; +} + +/*manage the spi device operations*/ +static const struct SpiDevDone spi_dev_done = +{ + .dev_open = NONE, + .dev_close = NONE, + .dev_write = SpiWriteData, + .dev_read = SpiReadData, +}; + +static int BoardSpiBusInit(struct SpiBus *spi_bus, struct SpiDriver *spi_driver) +{ + x_err_t ret = EOK; + + /*Init the spi bus */ + ret = SpiBusInit(spi_bus, SPI_BUS_NAME_1); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiBusInit error %d\n", ret); + return ERROR; + } + + /*Init the spi driver*/ + ret = SpiDriverInit(spi_driver, SPI_1_DRV_NAME); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDriverInit error %d\n", ret); + return ERROR; + } + + /*Attach the spi driver to the spi bus*/ + ret = SpiDriverAttachToBus(SPI_1_DRV_NAME, SPI_BUS_NAME_1); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +/*Attach the spi device to the spi bus*/ +static int BoardSpiDevBend(struct SpiDmaParam *spi_initparam) +{ + x_err_t ret = EOK; + +#ifdef BSP_SPI1_USING_SS0 + static struct SpiHardwareDevice spi_device0; + memset(&spi_device0, 0, sizeof(struct SpiHardwareDevice)); + + static struct SpiSlaveParam spi_slaveparam0; + memset(&spi_slaveparam0, 0, sizeof(struct SpiSlaveParam)); + + spi_slaveparam0.spi_slave_id = SPI_DEVICE_SLAVE_ID_0; + spi_slaveparam0.spi_cs_gpio_pin = SPI1_CS0_PIN; + spi_slaveparam0.spi_cs_select_id = SPI_CHIP_SELECT_0; + + spi_device0.spi_param.spi_dma_param = spi_initparam; + spi_device0.spi_param.spi_slave_param = &spi_slaveparam0; + + spi_device0.spi_dev_done = &(spi_dev_done); + + ret = SpiDeviceRegister(&spi_device0, (void *)(&spi_device0.spi_param), SPI_1_DEVICE_NAME_0); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", SPI_1_DEVICE_NAME_0, ret); + return ERROR; + } + + ret = SpiDeviceAttachToBus(SPI_1_DEVICE_NAME_0, SPI_BUS_NAME_1); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", SPI_1_DEVICE_NAME_0, ret); + return ERROR; + } +#endif + +#ifdef BSP_SPI1_USING_SS1 + static struct SpiHardwareDevice spi_device1; + memset(&spi_device1, 0, sizeof(struct SpiHardwareDevice)); + + static struct SpiSlaveParam spi_slaveparam1; + memset(&spi_slaveparam1, 0, sizeof(struct SpiSlaveParam)); + + spi_slaveparam1.spi_slave_id = SPI_DEVICE_SLAVE_ID_1; + spi_slaveparam1.spi_cs_gpio_pin = SPI1_CS1_PIN; + spi_slaveparam1.spi_cs_select_id = SPI_CHIP_SELECT_1; + + spi_device1.spi_param.spi_dma_param = spi_initparam; + spi_device1.spi_param.spi_slave_param = &spi_slaveparam1; + + spi_device1.spi_dev_done = &(spi_dev_done); + + ret = SpiDeviceRegister(&spi_device1, (void *)(&spi_device1.spi_param), SPI_1_DEVICE_NAME_1); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", SPI_1_DEVICE_NAME_1, ret); + return ERROR; + } + + ret = SpiDeviceAttachToBus(SPI_1_DEVICE_NAME_1, SPI_BUS_NAME_1); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", SPI_1_DEVICE_NAME_1, ret); + return ERROR; + } +#endif + +#ifdef BSP_SPI1_USING_SS2 + static struct SpiHardwareDevice spi_device2; + memset(&spi_device2, 0, sizeof(struct SpiHardwareDevice)); + + spi_initparam->spi_slave_id[SPI_DEVICE_SLAVE_ID_2] = SPI_DEVICE_SLAVE_ID_2; + spi_initparam->spi_cs_gpio_pin[SPI_DEVICE_SLAVE_ID_2] = SPI1_CS2_PIN; + spi_initparam->spi_cs_select_id[SPI_DEVICE_SLAVE_ID_2] = SPI_CHIP_SELECT_2; + + spi_device2.spi_dev_done = &(spi_dev_done); + + ret = SpiDeviceRegister(&spi_device2, (void *)(&spi_device2.spi_param), SPI_1_DEVICE_NAME_2); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", SPI_1_DEVICE_NAME_2, ret); + return ERROR; + } + + ret = SpiDeviceAttachToBus(SPI_1_DEVICE_NAME_2, SPI_BUS_NAME_1); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", SPI_1_DEVICE_NAME_2, ret); + return ERROR; + } +#endif + +#ifdef BSP_SPI1_USING_SS3 + static struct SpiHardwareDevice spi_device3; + memset(&spi_device3, 0, sizeof(struct SpiHardwareDevice)); + + spi_initparam->spi_slave_id[SPI_DEVICE_SLAVE_ID_3] = SPI_DEVICE_SLAVE_ID_3; + spi_initparam->spi_cs_gpio_pin[SPI_DEVICE_SLAVE_ID_3] = SPI1_CS3_PIN; + spi_initparam->spi_cs_select_id[SPI_DEVICE_SLAVE_ID_3] = SPI_CHIP_SELECT_3; + + spi_device3.spi_dev_done = &(spi_dev_done); + + ret = SpiDeviceRegister(&spi_device3, (void *)(&spi_device3.spi_param), SPI_1_DEVICE_NAME_3); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", SPI_1_DEVICE_NAME_3, ret); + return ERROR; + } + + ret = SpiDeviceAttachToBus(SPI_1_DEVICE_NAME_3, SPI_BUS_NAME_1); + if (EOK != ret) { + KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", SPI_1_DEVICE_NAME_3, ret); + return ERROR; + } +#endif + return ret; +} + +/*RISC-V 64 BOARD SPI INIT*/ +int HwSpiInit(void) +{ + x_err_t ret = EOK; + static struct SpiDmaParam spi_initparam; + memset(&spi_initparam, 0, sizeof(struct SpiDmaParam)); + +#ifdef BSP_USING_SPI1 + + static struct SpiBus spi_bus; + memset(&spi_bus, 0, sizeof(struct SpiBus)); + + static struct SpiDriver spi_driver; + memset(&spi_driver, 0, sizeof(struct SpiDriver)); + + spi_initparam.spi_master_id = SPI_DEVICE_1; + spi_initparam.spi_dmac_txchannel = DMAC_CHANNEL1; + spi_initparam.spi_dmac_rxchannel = DMAC_CHANNEL2; + + spi_driver.configure = &(SpiDrvConfigure); + + ret = BoardSpiBusInit(&spi_bus, &spi_driver); + if (EOK != ret) { + KPrintf("Board_Spi_Init error ret %u\n", ret); + return ERROR; + } + + ret = BoardSpiDevBend(&spi_initparam); + if (EOK != ret) { + KPrintf("Board_Spi_Init error ret %u\n", ret); + return ERROR; + } +#endif + return ret; +} diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/hardware_spi.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/hardware_spi.c new file mode 100644 index 000000000..2947682d3 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/spi/hardware_spi.c @@ -0,0 +1,1523 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file hardware_spi.c +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +volatile spi_t *const spi[4] = +{ + (volatile spi_t *)SPI0_BASE_ADDR, + (volatile spi_t *)SPI1_BASE_ADDR, + (volatile spi_t *)SPI_SLAVE_BASE_ADDR, + (volatile spi_t *)SPI3_BASE_ADDR +}; + +typedef struct _spi_dma_context +{ + uint8_t *buffer; + size_t BufLen; + uint32_t *MallocBuffer; + spi_transfer_mode_t IntMode; + dmac_channel_number_t dmac_channel; + spi_device_num_t spi_num; + plic_instance_t spi_int_instance; +} spi_dma_context_t; + +spi_dma_context_t spi_dma_context[4]; + +typedef struct _spi_instance_t +{ + spi_device_num_t spi_num; + spi_transfer_mode_t TransferMode; + dmac_channel_number_t dmac_channel; + plic_instance_t spi_int_instance; + spinlock_t lock; +} spi_instance_t; + +static spi_instance_t g_spi_instance[4]; + +static spi_slave_instance_t g_instance; + +static spi_frame_format_t spi_get_frame_format(spi_device_num_t spi_num) +{ + uint8_t frf_offset; + switch(spi_num) + { + case 0: + case 1: + frf_offset = 21; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + frf_offset = 22; + break; + } + volatile spi_t *spi_adapter = spi[spi_num]; + return ((spi_adapter->ctrlr0 >> frf_offset) & 0x3); +} + +static spi_transfer_width_t spi_get_frame_size(size_t data_bit_length) +{ + if (data_bit_length < 8) + return SPI_TRANS_CHAR; + else if (data_bit_length < 16) + return SPI_TRANS_SHORT; + return SPI_TRANS_INT; +} + +static int spi_dma_irq(void *ctx) +{ + spi_instance_t *v_instance = (spi_instance_t *)ctx; + volatile spi_t *spi_handle = spi[v_instance->spi_num]; + dmac_irq_unregister(v_instance->dmac_channel); + while ((spi_handle->sr & 0x05) != 0x04); + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; + spinlock_unlock(&v_instance->lock); + if(v_instance->spi_int_instance.callback) + { + v_instance->spi_int_instance.callback(v_instance->spi_int_instance.ctx); + } + return 0; +} + +static int spi_clk_init(uint8_t spi_num) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + if(spi_num == 3) + sysctl_clock_set_clock_select(SYSCTL_CLOCK_SELECT_SPI3, 1); + sysctl_clock_enable(SYSCTL_CLOCK_SPI0 + spi_num); + sysctl_clock_set_threshold(SYSCTL_THRESHOLD_SPI0 + spi_num, 0); + return 0; +} + +static void spi_set_tmod(uint8_t spi_num, uint32_t tmod) +{ + configASSERT(spi_num < SPI_DEVICE_MAX); + volatile spi_t *spi_handle = spi[spi_num]; + uint8_t tmod_offset = 0; + switch(spi_num) + { + case 0: + case 1: + case 2: + tmod_offset = 8; + break; + case 3: + default: + tmod_offset = 10; + break; + } + set_bit(&spi_handle->ctrlr0, 3 << tmod_offset, tmod << tmod_offset); +} + +void spi_init(spi_device_num_t spi_num, spi_work_mode_t work_mode, spi_frame_format_t frame_format, + size_t data_bit_length, uint32_t endian) +{ + configASSERT(data_bit_length >= 4 && data_bit_length <= 32); + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + spi_clk_init(spi_num); + + uint8_t dfs_offset, frf_offset, work_mode_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + frf_offset = 21; + work_mode_offset = 6; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + frf_offset = 22; + work_mode_offset = 8; + break; + } + + switch (frame_format) + { + case SPI_FF_DUAL: + configASSERT(data_bit_length % 2 == 0); + break; + case SPI_FF_QUAD: + configASSERT(data_bit_length % 4 == 0); + break; + case SPI_FF_OCTAL: + configASSERT(data_bit_length % 8 == 0); + break; + default: + break; + } + volatile spi_t *spi_adapter = spi[spi_num]; + if(spi_adapter->baudr == 0) + spi_adapter->baudr = 0x14; + spi_adapter->imr = 0x00; + spi_adapter->dmacr = 0x00; + spi_adapter->dmatdlr = 0x10; + spi_adapter->dmardlr = 0x00; + spi_adapter->ser = 0x00; + spi_adapter->ssienr = 0x00; + spi_adapter->ctrlr0 = (work_mode << work_mode_offset) | (frame_format << frf_offset) | ((data_bit_length - 1) << dfs_offset); + spi_adapter->spi_ctrlr0 = 0; + spi_adapter->endian = endian; +} + +void spi_init_non_standard(spi_device_num_t spi_num, uint32_t instruction_length, uint32_t address_length, + uint32_t wait_cycles, spi_instruction_address_trans_mode_t instruction_address_trans_mode) +{ + configASSERT(wait_cycles < (1 << 5)); + configASSERT(instruction_address_trans_mode < 3); + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + volatile spi_t *spi_handle = spi[spi_num]; + uint32_t inst_l = 0; + switch (instruction_length) + { + case 0: + inst_l = 0; + break; + case 4: + inst_l = 1; + break; + case 8: + inst_l = 2; + break; + case 16: + inst_l = 3; + break; + default: + configASSERT(!"Invalid instruction length"); + break; + } + + configASSERT(address_length % 4 == 0 && address_length <= 60); + uint32_t addr_l = address_length / 4; + + spi_handle->spi_ctrlr0 = (wait_cycles << 11) | (inst_l << 8) | (addr_l << 2) | instruction_address_trans_mode; +} + +uint32_t spi_set_clk_rate(spi_device_num_t spi_num, uint32_t spi_clk) +{ + uint32_t spi_baudr = SysctlClockGetFreq(SYSCTL_CLOCK_SPI0 + spi_num) / spi_clk; + if(spi_baudr < 2 ) + { + spi_baudr = 2; + } + else if(spi_baudr > 65534) + { + spi_baudr = 65534; + } + volatile spi_t *spi_adapter = spi[spi_num]; + spi_adapter->baudr = spi_baudr; + return SysctlClockGetFreq(SYSCTL_CLOCK_SPI0 + spi_num) / spi_baudr; +} + +void spi_send_data_normal(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *tx_buff, size_t tx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + + size_t index, fifo_len; + spi_set_tmod(spi_num, SPI_TMOD_TRANS); + + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + + uint8_t v_misalign_flag = 0; + uint32_t v_send_data; + if((uintptr_t)tx_buff % frame_width) + v_misalign_flag = 1; + + spi_handle->ssienr = 0x01; + spi_handle->ser = 1U << chip_select; + uint32_t i = 0; + while (tx_len) + { + fifo_len = 32 - spi_handle->txflr; + fifo_len = fifo_len < tx_len ? fifo_len : tx_len; + switch(frame_width) + { + case SPI_TRANS_INT: + fifo_len = fifo_len / 4 * 4; + if(v_misalign_flag) + { + for(index = 0; index < fifo_len; index +=4) + { + memcpy(&v_send_data, tx_buff + i , 4); + spi_handle->dr[0] = v_send_data; + i += 4; + } + } + else + { + for (index = 0; index < fifo_len / 4; index++) + spi_handle->dr[0] = ((uint32_t *)tx_buff)[i++]; + } + break; + case SPI_TRANS_SHORT: + fifo_len = fifo_len / 2 * 2; + if(v_misalign_flag) + { + for(index = 0; index < fifo_len; index +=2) + { + memcpy(&v_send_data, tx_buff + i, 2); + spi_handle->dr[0] = v_send_data; + i += 2; + } + } + else + { + for (index = 0; index < fifo_len / 2; index++) + spi_handle->dr[0] = ((uint16_t *)tx_buff)[i++]; + } + break; + default: + for (index = 0; index < fifo_len; index++) + spi_handle->dr[0] = tx_buff[i++]; + break; + } + tx_len -= fifo_len; + } + while ((spi_handle->sr & 0x05) != 0x04) + ; + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; + +} + +void spi_send_data_standard(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *CmdBuff, + size_t CmdLen, const uint8_t *tx_buff, size_t tx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + uint8_t *v_buf = malloc(CmdLen + tx_len); + size_t i; + for(i = 0; i < CmdLen; i++) + v_buf[i] = CmdBuff[i]; + for(i = 0; i < tx_len; i++) + v_buf[CmdLen + i] = tx_buff[i]; + + spi_send_data_normal(spi_num, chip_select, v_buf, CmdLen + tx_len); + free((void *)v_buf); +} + +void spi_send_data_standard_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, + spi_chip_select_t chip_select, + const uint8_t *CmdBuff, size_t CmdLen, const uint8_t *tx_buff, size_t tx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + + uint32_t *buf; + size_t v_send_len; + int i; + switch(frame_width) + { + case SPI_TRANS_INT: + buf = malloc(CmdLen + tx_len); + for(i = 0; i < CmdLen / 4; i++) + buf[i] = ((uint32_t *)CmdBuff)[i]; + for(i = 0; i < tx_len / 4; i++) + buf[CmdLen / 4 + i] = ((uint32_t *)tx_buff)[i]; + v_send_len = (CmdLen + tx_len) / 4; + break; + case SPI_TRANS_SHORT: + buf = malloc((CmdLen + tx_len) / 2 * sizeof(uint32_t)); + for(i = 0; i < CmdLen / 2; i++) + buf[i] = ((uint16_t *)CmdBuff)[i]; + for(i = 0; i < tx_len / 2; i++) + buf[CmdLen / 2 + i] = ((uint16_t *)tx_buff)[i]; + v_send_len = (CmdLen + tx_len) / 2; + break; + default: + buf = malloc((CmdLen + tx_len) * sizeof(uint32_t)); + for(i = 0; i < CmdLen; i++) + buf[i] = CmdBuff[i]; + for(i = 0; i < tx_len; i++) + buf[CmdLen + i] = tx_buff[i]; + v_send_len = CmdLen + tx_len; + break; + } + + spi_send_data_normal_dma(channel_num, spi_num, chip_select, buf, v_send_len, SPI_TRANS_INT); + + free((void *)buf); +} + +void spi_send_data_normal_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, + spi_chip_select_t chip_select, + const void *tx_buff, size_t tx_len, spi_transfer_width_t spi_transfer_width) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + spi_set_tmod(spi_num, SPI_TMOD_TRANS); + volatile spi_t *spi_handle = spi[spi_num]; + uint32_t *buf; + int i; + switch(spi_transfer_width) + { + case SPI_TRANS_SHORT: + buf = malloc((tx_len) * sizeof(uint32_t)); + for(i = 0; i < tx_len; i++) + buf[i] = ((uint16_t *)tx_buff)[i]; + break; + case SPI_TRANS_INT: + buf = (uint32_t *)tx_buff; + break; + case SPI_TRANS_CHAR: + default: + buf = malloc((tx_len) * sizeof(uint32_t)); + for(i = 0; i < tx_len; i++) + buf[i] = ((uint8_t *)tx_buff)[i]; + break; + } + spi_handle->dmacr = 0x2; /*enable dma transmit*/ + spi_handle->ssienr = 0x01; + + sysctl_dma_select((sysctl_dma_channel_t) channel_num, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + dmac_set_single_mode(channel_num, buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, tx_len); + spi_handle->ser = 1U << chip_select; + dmac_wait_done(channel_num); + if(spi_transfer_width != SPI_TRANS_INT) + free((void *)buf); + + while ((spi_handle->sr & 0x05) != 0x04) + ; + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; +} + +void spi_dup_send_receive_data_dma(dmac_channel_number_t dma_send_channel_num, + dmac_channel_number_t dma_receive_channel_num, + spi_device_num_t spi_num, spi_chip_select_t chip_select, + const uint8_t *tx_buf, size_t tx_len, uint8_t *rx_buf, size_t rx_len) +{ + spi_set_tmod(spi_num, SPI_TMOD_TRANS_RECV); + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + size_t v_tx_len = tx_len / frame_width; + size_t v_rx_len = rx_len / frame_width; + + size_t v_max_len = v_tx_len > v_rx_len ? v_tx_len : v_rx_len; + + uint32_t *v_tx_buf = malloc(v_max_len * 4); + uint32_t *v_rx_buf = malloc(v_max_len * 4); + uint32_t i = 0; + switch(frame_width) + { + case SPI_TRANS_INT: + for(i = 0; i < v_tx_len; i++) + { + v_tx_buf[i] = ((uint32_t *)tx_buf)[i]; + } + if(v_max_len > v_tx_len) + { + while(i < v_max_len) + { + v_tx_buf[i++] = 0xFFFFFFFF; + } + } + break; + case SPI_TRANS_SHORT: + for(i = 0; i < v_tx_len; i++) + { + v_tx_buf[i] = ((uint16_t *)tx_buf)[i]; + } + if(v_max_len > v_tx_len) + { + while(i < v_max_len) + { + v_tx_buf[i++] = 0xFFFFFFFF; + } + } + break; + default: + for(i = 0; i < v_tx_len; i++) + { + v_tx_buf[i] = tx_buf[i]; + } + if(v_max_len > v_tx_len) + { + while(i < v_max_len) + { + v_tx_buf[i++] = 0xFFFFFFFF; + } + } + break; + } + + spi_handle->dmacr = 0x3; + spi_handle->ssienr = 0x01; + + sysctl_dma_select((sysctl_dma_channel_t)dma_send_channel_num, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + sysctl_dma_select((sysctl_dma_channel_t)dma_receive_channel_num, SYSCTL_DMA_SELECT_SSI0_RX_REQ + spi_num * 2); + + dmac_set_single_mode(dma_receive_channel_num, (void *)(&spi_handle->dr[0]), v_rx_buf, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, v_max_len); + + dmac_set_single_mode(dma_send_channel_num, v_tx_buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, v_max_len); + + spi_handle->ser = 1U << chip_select; + dmac_wait_done(dma_send_channel_num); + dmac_wait_done(dma_receive_channel_num); + + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; + + switch(frame_width) + { + case SPI_TRANS_INT: + for(i = 0; i < v_rx_len; i++) + ((uint32_t *)rx_buf)[i] = v_rx_buf[i]; + break; + case SPI_TRANS_SHORT: + for(i = 0; i < v_rx_len; i++) + ((uint16_t *)rx_buf)[i] = v_rx_buf[i]; + break; + default: + for(i = 0; i < v_rx_len; i++) + rx_buf[i] = v_rx_buf[i]; + break; + } + free(v_tx_buf); + free(v_rx_buf); +} + +void spi_receive_data_standard(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + size_t index, fifo_len; + if(CmdLen == 0) + spi_set_tmod(spi_num, SPI_TMOD_RECV); + else + spi_set_tmod(spi_num, SPI_TMOD_EEROM); + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + + uint32_t i = 0; + size_t v_cmd_len = CmdLen / frame_width; + uint32_t v_rx_len = rx_len / frame_width; + + spi_handle->ctrlr1 = (uint32_t)(v_rx_len - 1); + spi_handle->ssienr = 0x01; + + while (v_cmd_len) + { + fifo_len = 32 - spi_handle->txflr; + fifo_len = fifo_len < v_cmd_len ? fifo_len : v_cmd_len; + switch(frame_width) + { + case SPI_TRANS_INT: + for (index = 0; index < fifo_len; index++) + spi_handle->dr[0] = ((uint32_t *)CmdBuff)[i++]; + break; + case SPI_TRANS_SHORT: + for (index = 0; index < fifo_len; index++) + spi_handle->dr[0] = ((uint16_t *)CmdBuff)[i++]; + break; + default: + for (index = 0; index < fifo_len; index++) + spi_handle->dr[0] = CmdBuff[i++]; + break; + } + spi_handle->ser = 1U << chip_select; + v_cmd_len -= fifo_len; + } + + if(CmdLen == 0) + { + spi_handle->dr[0] = 0xffffffff; + spi_handle->ser = 1U << chip_select; + } + + i = 0; + while (v_rx_len) + { + fifo_len = spi_handle->rxflr; + fifo_len = fifo_len < v_rx_len ? fifo_len : v_rx_len; + switch(frame_width) + { + case SPI_TRANS_INT: + for (index = 0; index < fifo_len; index++) + ((uint32_t *)rx_buff)[i++] = spi_handle->dr[0]; + break; + case SPI_TRANS_SHORT: + for (index = 0; index < fifo_len; index++) + ((uint16_t *)rx_buff)[i++] = (uint16_t)spi_handle->dr[0]; + break; + default: + for (index = 0; index < fifo_len; index++) + rx_buff[i++] = (uint8_t)spi_handle->dr[0]; + break; + } + + v_rx_len -= fifo_len; + } + + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; +} + +void spi_receive_data_normal_dma(dmac_channel_number_t dma_send_channel_num, + dmac_channel_number_t dma_receive_channel_num, + spi_device_num_t spi_num, spi_chip_select_t chip_select, const void *CmdBuff, + size_t CmdLen, void *rx_buff, size_t rx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + + if(CmdLen == 0) + spi_set_tmod(spi_num, SPI_TMOD_RECV); + else + spi_set_tmod(spi_num, SPI_TMOD_EEROM); + + volatile spi_t *spi_handle = spi[spi_num]; + + spi_handle->ctrlr1 = (uint32_t)(rx_len - 1); + spi_handle->dmacr = 0x3; + spi_handle->ssienr = 0x01; + if(CmdLen) + sysctl_dma_select((sysctl_dma_channel_t)dma_send_channel_num, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + sysctl_dma_select((sysctl_dma_channel_t)dma_receive_channel_num, SYSCTL_DMA_SELECT_SSI0_RX_REQ + spi_num * 2); + + dmac_set_single_mode(dma_receive_channel_num, (void *)(&spi_handle->dr[0]), rx_buff, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, rx_len); + if(CmdLen) + dmac_set_single_mode(dma_send_channel_num, CmdBuff, (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, CmdLen); + if(CmdLen == 0 && spi_get_frame_format(spi_num) == SPI_FF_STANDARD) + spi[spi_num]->dr[0] = 0xffffffff; + spi_handle->ser = 1U << chip_select; + if(CmdLen) + dmac_wait_done(dma_send_channel_num); + dmac_wait_done(dma_receive_channel_num); + + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; +} + + +void spi_receive_data_standard_dma(dmac_channel_number_t dma_send_channel_num, + dmac_channel_number_t dma_receive_channel_num, + spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + + size_t i; + + uint32_t *write_cmd; + uint32_t *ReadBuf; + size_t v_recv_len; + size_t v_cmd_len; + switch(frame_width) + { + case SPI_TRANS_INT: + write_cmd = malloc(CmdLen + rx_len); + for(i = 0; i < CmdLen / 4; i++) + write_cmd[i] = ((uint32_t *)CmdBuff)[i]; + ReadBuf = &write_cmd[i]; + v_recv_len = rx_len / 4; + v_cmd_len = CmdLen / 4; + break; + case SPI_TRANS_SHORT: + write_cmd = malloc((CmdLen + rx_len) /2 * sizeof(uint32_t)); + for(i = 0; i < CmdLen / 2; i++) + write_cmd[i] = ((uint16_t *)CmdBuff)[i]; + ReadBuf = &write_cmd[i]; + v_recv_len = rx_len / 2; + v_cmd_len = CmdLen / 2; + break; + default: + write_cmd = malloc((CmdLen + rx_len) * sizeof(uint32_t)); + for(i = 0; i < CmdLen; i++) + write_cmd[i] = CmdBuff[i]; + ReadBuf = &write_cmd[i]; + v_recv_len = rx_len; + v_cmd_len = CmdLen; + break; + } + + spi_receive_data_normal_dma(dma_send_channel_num, dma_receive_channel_num, spi_num, chip_select, write_cmd, v_cmd_len, ReadBuf, v_recv_len); + + switch(frame_width) + { + case SPI_TRANS_INT: + for(i = 0; i < v_recv_len; i++) + ((uint32_t *)rx_buff)[i] = ReadBuf[i]; + break; + case SPI_TRANS_SHORT: + for(i = 0; i < v_recv_len; i++) + ((uint16_t *)rx_buff)[i] = ReadBuf[i]; + break; + default: + for(i = 0; i < v_recv_len; i++) + rx_buff[i] = ReadBuf[i]; + break; + } + + free(write_cmd); +} + +void spi_receive_data_multiple(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + + size_t index, fifo_len; + if(CmdLen == 0) + spi_set_tmod(spi_num, SPI_TMOD_RECV); + else + spi_set_tmod(spi_num, SPI_TMOD_EEROM); + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + + uint32_t v_cmd_len = CmdLen; + uint32_t i = 0; + + uint32_t v_rx_len = rx_len / frame_width; + + spi_handle->ctrlr1 = (uint32_t)(v_rx_len - 1); + spi_handle->ssienr = 0x01; + + while (v_cmd_len) + { + fifo_len = 32 - spi_handle->txflr; + fifo_len = fifo_len < v_cmd_len ? fifo_len : v_cmd_len; + + for (index = 0; index < fifo_len; index++) + spi_handle->dr[0] = *CmdBuff++; + + spi_handle->ser = 1U << chip_select; + v_cmd_len -= fifo_len; + } + + if(CmdLen == 0) + { + spi_handle->ser = 1U << chip_select; + } + + while (v_rx_len) + { + fifo_len = spi_handle->rxflr; + fifo_len = fifo_len < v_rx_len ? fifo_len : v_rx_len; + switch(frame_width) + { + case SPI_TRANS_INT: + for (index = 0; index < fifo_len; index++) + ((uint32_t *)rx_buff)[i++] = spi_handle->dr[0]; + break; + case SPI_TRANS_SHORT: + for (index = 0; index < fifo_len; index++) + ((uint16_t *)rx_buff)[i++] = (uint16_t)spi_handle->dr[0]; + break; + default: + for (index = 0; index < fifo_len; index++) + rx_buff[i++] = (uint8_t)spi_handle->dr[0]; + break; + } + + v_rx_len -= fifo_len; + } + + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; + +} + +void spi_receive_data_multiple_dma(dmac_channel_number_t dma_send_channel_num, + dmac_channel_number_t dma_receive_channel_num, + spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *CmdBuff, + size_t CmdLen, uint8_t *rx_buff, size_t rx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + + size_t i; + + uint32_t *write_cmd = NULL; + uint32_t *ReadBuf; + size_t v_recv_len; + switch(frame_width) + { + case SPI_TRANS_INT: + v_recv_len = rx_len / 4; + break; + case SPI_TRANS_SHORT: + write_cmd = malloc(CmdLen + rx_len /2 * sizeof(uint32_t)); + for(i = 0; i < CmdLen; i++) + write_cmd[i] = CmdBuff[i]; + ReadBuf = &write_cmd[i]; + v_recv_len = rx_len / 2; + break; + default: + write_cmd = malloc(CmdLen + rx_len * sizeof(uint32_t)); + for(i = 0; i < CmdLen; i++) + write_cmd[i] = CmdBuff[i]; + ReadBuf = &write_cmd[i]; + v_recv_len = rx_len; + break; + } + if(frame_width == SPI_TRANS_INT) + spi_receive_data_normal_dma(dma_send_channel_num, dma_receive_channel_num, spi_num, chip_select, CmdBuff, CmdLen, rx_buff, v_recv_len); + else + spi_receive_data_normal_dma(dma_send_channel_num, dma_receive_channel_num, spi_num, chip_select, write_cmd, CmdLen, ReadBuf, v_recv_len); + + switch(frame_width) + { + case SPI_TRANS_INT: + break; + case SPI_TRANS_SHORT: + for(i = 0; i < v_recv_len; i++) + ((uint16_t *)rx_buff)[i] = ReadBuf[i]; + break; + default: + for(i = 0; i < v_recv_len; i++) + rx_buff[i] = ReadBuf[i]; + break; + } + + if(frame_width != SPI_TRANS_INT) + free(write_cmd); +} + +void spi_send_data_multiple(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *CmdBuff, + size_t CmdLen, const uint8_t *tx_buff, size_t tx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + + size_t index, fifo_len; + spi_set_tmod(spi_num, SPI_TMOD_TRANS); + volatile spi_t *spi_handle = spi[spi_num]; + spi_handle->ssienr = 0x01; + spi_handle->ser = 1U << chip_select; + + size_t v_cmd_len = CmdLen * 4; + while(v_cmd_len) + { + fifo_len = 32 - spi_handle->txflr; + fifo_len = fifo_len < v_cmd_len ? fifo_len : v_cmd_len; + fifo_len = fifo_len / 4 * 4; + for (index = 0; index < fifo_len / 4; index++) + spi_handle->dr[0] = *CmdBuff++; + v_cmd_len -= fifo_len; + } + spi_send_data_normal(spi_num, chip_select, tx_buff, tx_len); +} + +void spi_send_data_multiple_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, + spi_chip_select_t chip_select, + const uint32_t *CmdBuff, size_t CmdLen, const uint8_t *tx_buff, size_t tx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + volatile spi_t *spi_handle = spi[spi_num]; + + uint8_t dfs_offset; + switch(spi_num) + { + case 0: + case 1: + dfs_offset = 16; + break; + case 2: + configASSERT(!"Spi Bus 2 Not Support!"); + break; + case 3: + default: + dfs_offset = 0; + break; + } + uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; + spi_transfer_width_t frame_width = spi_get_frame_size(data_bit_length); + + uint32_t *buf; + size_t v_send_len; + int i; + switch(frame_width) + { + case SPI_TRANS_INT: + buf = malloc(CmdLen * sizeof(uint32_t) + tx_len); + for(i = 0; i < CmdLen; i++) + buf[i] = CmdBuff[i]; + for(i = 0; i < tx_len / 4; i++) + buf[CmdLen + i] = ((uint32_t *)tx_buff)[i]; + v_send_len = CmdLen + tx_len / 4; + break; + case SPI_TRANS_SHORT: + buf = malloc(CmdLen * sizeof(uint32_t) + tx_len / 2 * sizeof(uint32_t)); + for(i = 0; i < CmdLen; i++) + buf[i] = CmdBuff[i]; + for(i = 0; i < tx_len / 2; i++) + buf[CmdLen + i] = ((uint16_t *)tx_buff)[i]; + v_send_len = CmdLen + tx_len / 2; + break; + default: + buf = malloc((CmdLen + tx_len) * sizeof(uint32_t)); + for(i = 0; i < CmdLen; i++) + buf[i] = CmdBuff[i]; + for(i = 0; i < tx_len; i++) + buf[CmdLen + i] = tx_buff[i]; + v_send_len = CmdLen + tx_len; + break; + } + + spi_send_data_normal_dma(channel_num, spi_num, chip_select, buf, v_send_len, SPI_TRANS_INT); + + free((void *)buf); +} + +void spi_fill_data_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, spi_chip_select_t chip_select, + const uint32_t *tx_buff, size_t tx_len) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + + spi_set_tmod(spi_num, SPI_TMOD_TRANS); + volatile spi_t *spi_handle = spi[spi_num]; + spi_handle->dmacr = 0x2; /*enable dma transmit*/ + spi_handle->ssienr = 0x01; + + sysctl_dma_select((sysctl_dma_channel_t)channel_num, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + dmac_set_single_mode(channel_num, tx_buff, (void *)(&spi_handle->dr[0]), DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, tx_len); + spi_handle->ser = 1U << chip_select; + dmac_wait_done(channel_num); + + while ((spi_handle->sr & 0x05) != 0x04) + ; + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; +} + +static int spi_slave_irq(void *ctx) +{ + volatile spi_t *spi_handle = spi[2]; + + spi_handle->imr = 0x00; + *(volatile uint32_t *)((uintptr_t)spi_handle->icr); + if (g_instance.status == IDLE) + g_instance.status = COMMAND; + return 0; +} + +static void spi_slave_idle_mode(void) +{ + volatile spi_t *spi_handle = spi[2]; + uint32_t DataWidth = g_instance.data_bit_length / 8; + g_instance.status = IDLE; + spi_handle->ssienr = 0x00; + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x1 << g_instance.slv_oe) | ((g_instance.data_bit_length - 1) << g_instance.dfs); + spi_handle->rxftlr = 0x08 / DataWidth - 1; + + spi_handle->dmacr = 0x00; + spi_handle->imr = 0x10; + spi_handle->ssienr = 0x01; + gpiohs_set_pin(g_instance.ready_pin, GPIO_PV_HIGH); +} + +static void spi_slave_command_mode(void) +{ + volatile spi_t *spi_handle = spi[2]; + uint8_t CmdData[8], sum = 0; + + spi_transfer_width_t frame_width = spi_get_frame_size(g_instance.data_bit_length - 1); + uint32_t DataWidth = g_instance.data_bit_length / 8; + spi_device_num_t spi_num = SPI_DEVICE_2; + switch(frame_width) + { + case SPI_TRANS_INT: + for (uint32_t i = 0; i < 8 / 4; i++) + ((uint32_t *)CmdData)[i] = spi_handle->dr[0]; + break; + case SPI_TRANS_SHORT: + for (uint32_t i = 0; i < 8 / 2; i++) + ((uint16_t *)CmdData)[i] = spi_handle->dr[0]; + break; + default: + for (uint32_t i = 0; i < 8; i++) + CmdData[i] = spi_handle->dr[0]; + break; + } + + for (uint32_t i = 0; i < 7; i++) + { + sum += CmdData[i]; + } + if (CmdData[7] != sum) + { + spi_slave_idle_mode(); + return; + } + g_instance.command.cmd = CmdData[0]; + g_instance.command.addr = CmdData[1] | (CmdData[2] << 8) | (CmdData[3] << 16) | (CmdData[4] << 24); + g_instance.command.len = CmdData[5] | (CmdData[6] << 8); + if (g_instance.command.len == 0) + g_instance.command.len = 65536; + if ((g_instance.command.cmd < WRITE_DATA_BLOCK) && (g_instance.command.len > 8)) + { + spi_slave_idle_mode(); + return; + } + g_instance.status = TRANSFER; + spi_handle->ssienr = 0x00; + if (g_instance.command.cmd == WRITE_CONFIG) + { + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x1 << g_instance.slv_oe) | ((g_instance.data_bit_length - 1) << g_instance.dfs); + spi[2]->rxftlr = g_instance.command.len / DataWidth - 1; + spi_handle->imr = 0x00; + spi_handle->ssienr = 0x01; + } + else if (g_instance.command.cmd == READ_CONFIG) + { + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x0 << g_instance.slv_oe) | ((g_instance.data_bit_length - 1) << g_instance.dfs); + spi_set_tmod(2, SPI_TMOD_TRANS); + spi_handle->txftlr = 0x00; + spi_handle->imr = 0x00; + spi_handle->ssienr = 0x01; + switch(frame_width) + { + case SPI_TRANS_INT: + for (uint32_t i = 0; i < g_instance.command.len / 4; i++) + { + spi_handle->dr[0] = ((uint32_t *)&g_instance.config_ptr[g_instance.command.addr])[i]; + } + break; + case SPI_TRANS_SHORT: + for (uint32_t i = 0; i < g_instance.command.len / 2; i++) + { + spi_handle->dr[0] = ((uint16_t *)&g_instance.config_ptr[g_instance.command.addr])[i]; + } + break; + default: + for (uint32_t i = 0; i < g_instance.command.len; i++) + { + spi_handle->dr[0] = ((uint8_t *)&g_instance.config_ptr[g_instance.command.addr])[i]; + } + break; + } + } + else if (g_instance.command.cmd == WRITE_DATA_BYTE) + { + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x1 << g_instance.slv_oe) | ((g_instance.data_bit_length - 1) << g_instance.dfs); + spi[2]->rxftlr = g_instance.command.len / DataWidth - 1; + spi_handle->imr = 0x00; + spi_handle->ssienr = 0x01; + } + else if (g_instance.command.cmd == READ_DATA_BYTE) + { + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x0 << g_instance.slv_oe) | ((g_instance.data_bit_length - 1) << g_instance.dfs); + spi_set_tmod(2, SPI_TMOD_TRANS); + spi_handle->txftlr = 0x00; + spi_handle->imr = 0x00; + spi_handle->ssienr = 0x01; + switch(frame_width) + { + case SPI_TRANS_INT: + for (uint32_t i = 0; i < g_instance.command.len / 4; i++) + { + spi_handle->dr[0] = ((uint32_t *)(uintptr_t)g_instance.command.addr)[i]; + } + break; + case SPI_TRANS_SHORT: + for (uint32_t i = 0; i < g_instance.command.len / 2; i++) + { + spi_handle->dr[0] = ((uint16_t *)(uintptr_t)g_instance.command.addr)[i]; + } + break; + default: + for (uint32_t i = 0; i < g_instance.command.len; i++) + { + spi_handle->dr[0] = ((uint8_t *)(uintptr_t)g_instance.command.addr)[i]; + } + break; + } + } + else if (g_instance.command.cmd == WRITE_DATA_BLOCK) + { + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x1 << g_instance.slv_oe) | ((32 - 1) << g_instance.dfs); + + spi_handle->dmacr = 0x01; + spi_handle->imr = 0x00; + spi_handle->ssienr = 0x01; + + sysctl_dma_select(g_instance.dmac_channel, SYSCTL_DMA_SELECT_SSI0_RX_REQ + spi_num * 2); + + dmac_set_single_mode(g_instance.dmac_channel, (void *)(&spi_handle->dr[0]), (void *)((uintptr_t)g_instance.command.addr & 0xFFFFFFF0), DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, g_instance.command.len * 4); + } + else if (g_instance.command.cmd == READ_DATA_BLOCK) + { + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x0 << g_instance.slv_oe) | ((32 - 1) << g_instance.dfs); + spi_set_tmod(2, SPI_TMOD_TRANS); + spi_handle->dmacr = 0x02; + spi_handle->imr = 0x00; + spi_handle->ssienr = 0x01; + + sysctl_dma_select(g_instance.dmac_channel, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + dmac_set_single_mode(g_instance.dmac_channel, (void *)((uintptr_t)g_instance.command.addr & 0xFFFFFFF0), (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, g_instance.command.len * 4); + } + else + { + spi_slave_idle_mode(); + return; + } + gpiohs_set_pin(g_instance.ready_pin, GPIO_PV_LOW); +} + +static void spi_slave_transfer_mode(void) +{ + spi_transfer_width_t frame_width = spi_get_frame_size(g_instance.data_bit_length - 1); + uint32_t command_len = 0; + + switch(frame_width) + { + case SPI_TRANS_INT: + command_len = g_instance.command.len / 4; + break; + case SPI_TRANS_SHORT: + command_len = g_instance.command.len / 2; + break; + default: + command_len = g_instance.command.len; + break; + } + volatile spi_t *spi_handle = spi[2]; + g_instance.command.err = 0; + if (g_instance.command.cmd == WRITE_CONFIG || g_instance.command.cmd == WRITE_DATA_BYTE) + { + if (spi_handle->rxflr < command_len - 1) + g_instance.command.err = 1; + } + else if (g_instance.command.cmd == READ_CONFIG || g_instance.command.cmd == READ_DATA_BYTE) + { + if (spi_handle->txflr != 0) + g_instance.command.err = 2; + } else if (g_instance.command.cmd == WRITE_DATA_BLOCK || g_instance.command.cmd == READ_DATA_BLOCK) + { + if (dmac->channel[g_instance.dmac_channel].intstatus != 0x02) + g_instance.command.err = 3; + } + else + { + spi_slave_idle_mode(); + return; + } + + if (g_instance.command.err == 0) + { + if (g_instance.command.cmd == WRITE_CONFIG) + { + switch(frame_width) + { + case SPI_TRANS_INT: + for (uint32_t i = 0; i < command_len; i++) + { + ((uint32_t *)&g_instance.config_ptr[g_instance.command.addr])[i] = spi_handle->dr[0]; + } + break; + case SPI_TRANS_SHORT: + for (uint32_t i = 0; i < command_len; i++) + { + ((uint16_t *)&g_instance.config_ptr[g_instance.command.addr])[i] = spi_handle->dr[0]; + } + break; + default: + for (uint32_t i = 0; i < command_len; i++) + { + ((uint8_t *)&g_instance.config_ptr[g_instance.command.addr])[i] = spi_handle->dr[0]; + } + break; + } + } + else if (g_instance.command.cmd == WRITE_DATA_BYTE) + { + switch(frame_width) + { + case SPI_TRANS_INT: + for (uint32_t i = 0; i < command_len; i++) + { + ((uint32_t *)(uintptr_t)g_instance.command.addr)[i] = spi_handle->dr[0]; + } + break; + case SPI_TRANS_SHORT: + for (uint32_t i = 0; i < command_len; i++) + { + ((uint16_t *)(uintptr_t)g_instance.command.addr)[i] = spi_handle->dr[0]; + } + break; + default: + for (uint32_t i = 0; i < command_len; i++) + { + ((uint8_t *)(uintptr_t)g_instance.command.addr)[i] = spi_handle->dr[0]; + } + break; + } + } + } + if(g_instance.callback != NULL) + { + g_instance.callback((void *)&g_instance.command); + } + spi_slave_idle_mode(); +} + +static void spi_slave_cs_irq(void) +{ + if (g_instance.status == IDLE) + spi_slave_idle_mode(); + else if (g_instance.status == COMMAND) + spi_slave_command_mode(); + else if (g_instance.status == TRANSFER) + spi_slave_transfer_mode(); +} + +void spi_slave_config(uint8_t int_pin, uint8_t ready_pin, dmac_channel_number_t dmac_channel, size_t data_bit_length, uint8_t *data, uint32_t len, spi_slave_receive_callback_t callback) +{ + g_instance.status = IDLE; + g_instance.config_ptr = data; + g_instance.config_len = len; + g_instance.work_mode = 6; + g_instance.slv_oe = 10; + g_instance.dfs = 16; + g_instance.data_bit_length = data_bit_length; + g_instance.ready_pin = ready_pin; + g_instance.int_pin = int_pin; + g_instance.callback = callback; + g_instance.dmac_channel = dmac_channel; + sysctl_reset(SYSCTL_RESET_SPI2); + sysctl_clock_enable(SYSCTL_CLOCK_SPI2); + sysctl_clock_set_threshold(SYSCTL_THRESHOLD_SPI2, 9); + + uint32_t DataWidth = data_bit_length / 8; + volatile spi_t *spi_handle = spi[2]; + spi_handle->ssienr = 0x00; + spi_handle->ctrlr0 = (0x0 << g_instance.work_mode) | (0x1 << g_instance.slv_oe) | ((data_bit_length - 1) << g_instance.dfs); + spi_handle->dmatdlr = 0x04; + spi_handle->dmardlr = 0x03; + spi_handle->dmacr = 0x00; + spi_handle->txftlr = 0x00; + spi_handle->rxftlr = 0x08 / DataWidth - 1; + spi_handle->imr = 0x10; + spi_handle->ssienr = 0x01; + + gpiohs_set_drive_mode(g_instance.ready_pin, GPIO_DM_OUTPUT); + gpiohs_set_pin(g_instance.ready_pin, GPIO_PV_HIGH); + + gpiohs_set_drive_mode(g_instance.int_pin, GPIO_DM_INPUT_PULL_UP); + gpiohs_set_pin_edge(g_instance.int_pin, GPIO_PE_RISING); + gpiohs_set_irq(g_instance.int_pin, 3, spi_slave_cs_irq); + + plic_set_priority(IRQN_SPI_SLAVE_INTERRUPT, 4); + plic_irq_enable(IRQN_SPI_SLAVE_INTERRUPT); + plic_irq_register(IRQN_SPI_SLAVE_INTERRUPT, spi_slave_irq, NULL); +} + +void spi_handle_data_dma(spi_device_num_t spi_num, spi_chip_select_t chip_select, spi_data_t data, plic_interrupt_t *cb) +{ + configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); + configASSERT(chip_select < SPI_CHIP_SELECT_MAX); + switch(data.TransferMode) + { + case SPI_TMOD_TRANS_RECV: + case SPI_TMOD_EEROM: + configASSERT(data.tx_buf && data.tx_len && data.rx_buf && data.rx_len); + break; + case SPI_TMOD_TRANS: + configASSERT(data.tx_buf && data.tx_len); + break; + case SPI_TMOD_RECV: + configASSERT(data.rx_buf && data.rx_len); + break; + default: + configASSERT(!"Transfer Mode ERR"); + break; + } + configASSERT(data.tx_channel < DMAC_CHANNEL_MAX && data.rx_channel < DMAC_CHANNEL_MAX); + volatile spi_t *spi_handle = spi[spi_num]; + + spinlock_lock(&g_spi_instance[spi_num].lock); + if(cb) + { + g_spi_instance[spi_num].spi_int_instance.callback = cb->callback; + g_spi_instance[spi_num].spi_int_instance.ctx = cb->ctx; + } + switch(data.TransferMode) + { + case SPI_TMOD_RECV: + spi_set_tmod(spi_num, SPI_TMOD_RECV); + if(data.rx_len > 65536) + data.rx_len = 65536; + spi_handle->ctrlr1 = (uint32_t)(data.rx_len - 1); + spi_handle->dmacr = 0x03; + spi_handle->ssienr = 0x01; + if(spi_get_frame_format(spi_num) == SPI_FF_STANDARD) + spi_handle->dr[0] = 0xffffffff; + if(cb) + { + dmac_irq_register(data.rx_channel, spi_dma_irq, &g_spi_instance[spi_num], cb->priority); + g_spi_instance[spi_num].dmac_channel = data.rx_channel; + } + sysctl_dma_select((sysctl_dma_channel_t)data.rx_channel, SYSCTL_DMA_SELECT_SSI0_RX_REQ + spi_num * 2); + dmac_set_single_mode(data.rx_channel, (void *)(&spi_handle->dr[0]), (void *)data.rx_buf, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, data.rx_len); + spi_handle->ser = 1U << chip_select; + if(!cb) + dmac_wait_idle(data.rx_channel); + break; + case SPI_TMOD_TRANS: + spi_set_tmod(spi_num, SPI_TMOD_TRANS); + spi_handle->dmacr = 0x2; /*enable dma transmit*/ + spi_handle->ssienr = 0x01; + + if(cb) + { + dmac_irq_register(data.tx_channel, spi_dma_irq, &g_spi_instance[spi_num], cb->priority); + g_spi_instance[spi_num].dmac_channel = data.tx_channel; + } + sysctl_dma_select(data.tx_channel, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + if(data.fill_mode) + dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, data.tx_len); + else + dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, data.tx_len); + spi_handle->ser = 1U << chip_select; + if(!cb) + { + dmac_wait_idle(data.tx_channel); + while ((spi_handle->sr & 0x05) != 0x04) + ; + } + break; + case SPI_TMOD_EEROM: + spi_set_tmod(spi_num, SPI_TMOD_EEROM); + if(data.rx_len > 65536) + data.rx_len = 65536; + spi_handle->ctrlr1 = (uint32_t)(data.rx_len - 1); + spi_handle->dmacr = 0x3; + spi_handle->ssienr = 0x01; + sysctl_dma_select(data.tx_channel, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + if(data.fill_mode) + dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, data.tx_len); + else + dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, data.tx_len); + if(cb) + { + dmac_irq_register(data.rx_channel, spi_dma_irq, &g_spi_instance[spi_num], cb->priority); + g_spi_instance[spi_num].dmac_channel = data.rx_channel; + } + sysctl_dma_select(data.rx_channel, SYSCTL_DMA_SELECT_SSI0_RX_REQ + spi_num * 2); + dmac_set_single_mode(data.rx_channel, (void *)(&spi_handle->dr[0]), (void *)data.rx_buf, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, data.rx_len); + spi_handle->ser = 1U << chip_select; + if(!cb) + dmac_wait_idle(data.rx_channel); + break; + case SPI_TMOD_TRANS_RECV: + spi_set_tmod(spi_num, SPI_TMOD_TRANS_RECV); + if(data.rx_len > 65536) + data.rx_len = 65536; + + if(cb) + { + if(data.tx_len > data.rx_len) + { + dmac_irq_register(data.tx_channel, spi_dma_irq, &g_spi_instance[spi_num], cb->priority); + g_spi_instance[spi_num].dmac_channel = data.tx_channel; + } + else + { + dmac_irq_register(data.rx_channel, spi_dma_irq, &g_spi_instance[spi_num], cb->priority); + g_spi_instance[spi_num].dmac_channel = data.rx_channel; + } + } + spi_handle->ctrlr1 = (uint32_t)(data.rx_len - 1); + spi_handle->dmacr = 0x3; + spi_handle->ssienr = 0x01; + sysctl_dma_select(data.tx_channel, SYSCTL_DMA_SELECT_SSI0_TX_REQ + spi_num * 2); + if(data.fill_mode) + dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, data.tx_len); + else + dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&spi_handle->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, data.tx_len); + sysctl_dma_select(data.rx_channel, SYSCTL_DMA_SELECT_SSI0_RX_REQ + spi_num * 2); + dmac_set_single_mode(data.rx_channel, (void *)(&spi_handle->dr[0]), (void *)data.rx_buf, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, data.rx_len); + spi_handle->ser = 1U << chip_select; + if(!cb) + { + dmac_wait_idle(data.tx_channel); + dmac_wait_idle(data.rx_channel); + } + break; + } + if(!cb) + { + spinlock_unlock(&g_spi_instance[spi_num].lock); + spi_handle->ser = 0x00; + spi_handle->ssienr = 0x00; + } +} + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/sys_clock/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/sys_clock/Kconfig new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/sys_clock/Kconfig @@ -0,0 +1 @@ + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/sys_clock/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/sys_clock/Makefile new file mode 100644 index 000000000..ef5fda177 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/sys_clock/Makefile @@ -0,0 +1,6 @@ +SRC_FILES := sysctl.c + + + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/sys_clock/sysctl.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/sys_clock/sysctl.c new file mode 100644 index 000000000..329b59198 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/sys_clock/sysctl.c @@ -0,0 +1,1870 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file sysctl.c +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#include +#include +#include +#include +#include "sysctl.h" +#include "string.h" +#include "encoding.h" +#include "bsp.h" + +#define SYSCTRL_CLOCK_FREQ_IN0 (26000000UL) + +const uint8_t get_select_pll2[] = +{ + [SYSCTL_SOURCE_IN0] = 0, + [SYSCTL_SOURCE_PLL0] = 1, + [SYSCTL_SOURCE_PLL1] = 2, +}; + +const uint8_t get_source_pll2[] = +{ + [0] = SYSCTL_SOURCE_IN0, + [1] = SYSCTL_SOURCE_PLL0, + [2] = SYSCTL_SOURCE_PLL1, +}; + +const uint8_t get_select_aclk[] = +{ + [SYSCTL_SOURCE_IN0] = 0, + [SYSCTL_SOURCE_PLL0] = 1, +}; + +const uint8_t get_source_aclk[] = +{ + [0] = SYSCTL_SOURCE_IN0, + [1] = SYSCTL_SOURCE_PLL0, +}; + +volatile sysctl_t *const sysctl = (volatile sysctl_t *)SYSCTL_BASE_ADDR; + +uint32_t sysctl_get_git_id(void) +{ + return sysctl->git_id.git_id; +} + +uint32_t sysctl_get_freq(void) +{ + return sysctl->clk_freq.clk_freq; +} + +static void sysctl_reset_ctl(sysctl_reset_t reset, uint8_t rst_value) +{ + switch (reset) + { + case SYSCTL_RESET_SOC: + sysctl->soft_reset.soft_reset = rst_value; + break; + case SYSCTL_RESET_ROM: + sysctl->peri_reset.rom_reset = rst_value; + break; + case SYSCTL_RESET_DMA: + sysctl->peri_reset.dma_reset = rst_value; + break; + case SYSCTL_RESET_AI: + sysctl->peri_reset.ai_reset = rst_value; + break; + case SYSCTL_RESET_DVP: + sysctl->peri_reset.dvp_reset = rst_value; + break; + case SYSCTL_RESET_FFT: + sysctl->peri_reset.fft_reset = rst_value; + break; + case SYSCTL_RESET_GPIO: + sysctl->peri_reset.gpio_reset = rst_value; + break; + case SYSCTL_RESET_SPI0: + sysctl->peri_reset.spi0_reset = rst_value; + break; + case SYSCTL_RESET_SPI1: + sysctl->peri_reset.spi1_reset = rst_value; + break; + case SYSCTL_RESET_SPI2: + sysctl->peri_reset.spi2_reset = rst_value; + break; + case SYSCTL_RESET_SPI3: + sysctl->peri_reset.spi3_reset = rst_value; + break; + case SYSCTL_RESET_I2S0: + sysctl->peri_reset.i2s0_reset = rst_value; + break; + case SYSCTL_RESET_I2S1: + sysctl->peri_reset.i2s1_reset = rst_value; + break; + case SYSCTL_RESET_I2S2: + sysctl->peri_reset.i2s2_reset = rst_value; + break; + case SYSCTL_RESET_I2C0: + sysctl->peri_reset.i2c0_reset = rst_value; + break; + case SYSCTL_RESET_I2C1: + sysctl->peri_reset.i2c1_reset = rst_value; + break; + case SYSCTL_RESET_I2C2: + sysctl->peri_reset.i2c2_reset = rst_value; + break; + case SYSCTL_RESET_UART1: + sysctl->peri_reset.uart1_reset = rst_value; + break; + case SYSCTL_RESET_UART2: + sysctl->peri_reset.uart2_reset = rst_value; + break; + case SYSCTL_RESET_UART3: + sysctl->peri_reset.uart3_reset = rst_value; + break; + case SYSCTL_RESET_AES: + sysctl->peri_reset.aes_reset = rst_value; + break; + case SYSCTL_RESET_FPIOA: + sysctl->peri_reset.fpioa_reset = rst_value; + break; + case SYSCTL_RESET_TIMER0: + sysctl->peri_reset.timer0_reset = rst_value; + break; + case SYSCTL_RESET_TIMER1: + sysctl->peri_reset.timer1_reset = rst_value; + break; + case SYSCTL_RESET_TIMER2: + sysctl->peri_reset.timer2_reset = rst_value; + break; + case SYSCTL_RESET_WDT0: + sysctl->peri_reset.wdt0_reset = rst_value; + break; + case SYSCTL_RESET_WDT1: + sysctl->peri_reset.wdt1_reset = rst_value; + break; + case SYSCTL_RESET_SHA: + sysctl->peri_reset.sha_reset = rst_value; + break; + case SYSCTL_RESET_RTC: + sysctl->peri_reset.rtc_reset = rst_value; + break; + + default: + break; + } +} + +void sysctl_reset(sysctl_reset_t reset) +{ + sysctl_reset_ctl(reset, 1); + usleep(10); + sysctl_reset_ctl(reset, 0); +} + +static int sysctl_clock_bus_en(sysctl_clock_t clock, uint8_t en) +{ + /* + * The timer is under APB0, to prevent apb0_clk_en1 and apb0_clk_en0 + * on same register, we split it to peripheral and central two + * registers, to protect CPU close apb0 clock accidentally. + * + * The apb0_clk_en0 and apb0_clk_en1 have same function, + * one of them set, the APB0 clock enable. + */ + + /* The APB clock should carefully disable */ + if (en) + { + switch (clock) + { + /* + * These peripheral devices are under APB0 + * GPIO, UART1, UART2, UART3, SPI_SLAVE, I2S0, I2S1, + * I2S2, I2C0, I2C1, I2C2, FPIOA, SHA256, TIMER0, + * TIMER1, TIMER2 + */ + case SYSCTL_CLOCK_GPIO: + case SYSCTL_CLOCK_SPI2: + case SYSCTL_CLOCK_I2S0: + case SYSCTL_CLOCK_I2S1: + case SYSCTL_CLOCK_I2S2: + case SYSCTL_CLOCK_I2C0: + case SYSCTL_CLOCK_I2C1: + case SYSCTL_CLOCK_I2C2: + case SYSCTL_CLOCK_UART1: + case SYSCTL_CLOCK_UART2: + case SYSCTL_CLOCK_UART3: + case SYSCTL_CLOCK_FPIOA: + case SYSCTL_CLOCK_TIMER0: + case SYSCTL_CLOCK_TIMER1: + case SYSCTL_CLOCK_TIMER2: + case SYSCTL_CLOCK_SHA: + sysctl->clk_en_cent.apb0_clk_en = en; + break; + + /* + * These peripheral devices are under APB1 + * WDT, AES, OTP, DVP, SYSCTL + */ + case SYSCTL_CLOCK_AES: + case SYSCTL_CLOCK_WDT0: + case SYSCTL_CLOCK_WDT1: + case SYSCTL_CLOCK_OTP: + case SYSCTL_CLOCK_RTC: + sysctl->clk_en_cent.apb1_clk_en = en; + break; + + /* + * These peripheral devices are under APB2 + * SPI0, SPI1 + */ + case SYSCTL_CLOCK_SPI0: + case SYSCTL_CLOCK_SPI1: + sysctl->clk_en_cent.apb2_clk_en = en; + break; + + default: + break; + } + } + + return 0; +} + +static int sysctl_clock_device_en(sysctl_clock_t clock, uint8_t en) +{ + switch (clock) + { + /* + * These devices are PLL + */ + case SYSCTL_CLOCK_PLL0: + sysctl->pll0.pll_out_en0 = en; + break; + case SYSCTL_CLOCK_PLL1: + sysctl->pll1.pll_out_en1 = en; + break; + case SYSCTL_CLOCK_PLL2: + sysctl->pll2.pll_out_en2 = en; + break; + + /* + * These devices are CPU, SRAM, APB bus, ROM, DMA, AI + */ + case SYSCTL_CLOCK_CPU: + sysctl->clk_en_cent.cpu_clk_en = en; + break; + case SYSCTL_CLOCK_SRAM0: + sysctl->clk_en_cent.sram0_clk_en = en; + break; + case SYSCTL_CLOCK_SRAM1: + sysctl->clk_en_cent.sram1_clk_en = en; + break; + case SYSCTL_CLOCK_APB0: + sysctl->clk_en_cent.apb0_clk_en = en; + break; + case SYSCTL_CLOCK_APB1: + sysctl->clk_en_cent.apb1_clk_en = en; + break; + case SYSCTL_CLOCK_APB2: + sysctl->clk_en_cent.apb2_clk_en = en; + break; + case SYSCTL_CLOCK_ROM: + sysctl->clk_en_peri.rom_clk_en = en; + break; + case SYSCTL_CLOCK_DMA: + sysctl->clk_en_peri.dma_clk_en = en; + break; + case SYSCTL_CLOCK_AI: + sysctl->clk_en_peri.ai_clk_en = en; + break; + case SYSCTL_CLOCK_DVP: + sysctl->clk_en_peri.dvp_clk_en = en; + break; + case SYSCTL_CLOCK_FFT: + sysctl->clk_en_peri.fft_clk_en = en; + break; + case SYSCTL_CLOCK_SPI3: + sysctl->clk_en_peri.spi3_clk_en = en; + break; + + /* + * These peripheral devices are under APB0 + * GPIO, UART1, UART2, UART3, SPI_SLAVE, I2S0, I2S1, + * I2S2, I2C0, I2C1, I2C2, FPIOA, SHA256, TIMER0, + * TIMER1, TIMER2 + */ + case SYSCTL_CLOCK_GPIO: + sysctl->clk_en_peri.gpio_clk_en = en; + break; + case SYSCTL_CLOCK_SPI2: + sysctl->clk_en_peri.spi2_clk_en = en; + break; + case SYSCTL_CLOCK_I2S0: + sysctl->clk_en_peri.i2s0_clk_en = en; + break; + case SYSCTL_CLOCK_I2S1: + sysctl->clk_en_peri.i2s1_clk_en = en; + break; + case SYSCTL_CLOCK_I2S2: + sysctl->clk_en_peri.i2s2_clk_en = en; + break; + case SYSCTL_CLOCK_I2C0: + sysctl->clk_en_peri.i2c0_clk_en = en; + break; + case SYSCTL_CLOCK_I2C1: + sysctl->clk_en_peri.i2c1_clk_en = en; + break; + case SYSCTL_CLOCK_I2C2: + sysctl->clk_en_peri.i2c2_clk_en = en; + break; + case SYSCTL_CLOCK_UART1: + sysctl->clk_en_peri.uart1_clk_en = en; + break; + case SYSCTL_CLOCK_UART2: + sysctl->clk_en_peri.uart2_clk_en = en; + break; + case SYSCTL_CLOCK_UART3: + sysctl->clk_en_peri.uart3_clk_en = en; + break; + case SYSCTL_CLOCK_FPIOA: + sysctl->clk_en_peri.fpioa_clk_en = en; + break; + case SYSCTL_CLOCK_TIMER0: + sysctl->clk_en_peri.timer0_clk_en = en; + break; + case SYSCTL_CLOCK_TIMER1: + sysctl->clk_en_peri.timer1_clk_en = en; + break; + case SYSCTL_CLOCK_TIMER2: + sysctl->clk_en_peri.timer2_clk_en = en; + break; + case SYSCTL_CLOCK_SHA: + sysctl->clk_en_peri.sha_clk_en = en; + break; + + /* + * These peripheral devices are under APB1 + * WDT, AES, OTP, DVP, SYSCTL + */ + case SYSCTL_CLOCK_AES: + sysctl->clk_en_peri.aes_clk_en = en; + break; + case SYSCTL_CLOCK_WDT0: + sysctl->clk_en_peri.wdt0_clk_en = en; + break; + case SYSCTL_CLOCK_WDT1: + sysctl->clk_en_peri.wdt1_clk_en = en; + break; + case SYSCTL_CLOCK_OTP: + sysctl->clk_en_peri.otp_clk_en = en; + break; + case SYSCTL_CLOCK_RTC: + sysctl->clk_en_peri.rtc_clk_en = en; + break; + + /* + * These peripheral devices are under APB2 + * SPI0, SPI1 + */ + case SYSCTL_CLOCK_SPI0: + sysctl->clk_en_peri.spi0_clk_en = en; + break; + case SYSCTL_CLOCK_SPI1: + sysctl->clk_en_peri.spi1_clk_en = en; + break; + + default: + break; + } + + return 0; +} + +int sysctl_clock_enable(sysctl_clock_t clock) +{ + if (clock >= SYSCTL_CLOCK_MAX) + return -1; + sysctl_clock_bus_en(clock, 1); + sysctl_clock_device_en(clock, 1); + return 0; +} + +int sysctl_clock_disable(sysctl_clock_t clock) +{ + if (clock >= SYSCTL_CLOCK_MAX) + return -1; + sysctl_clock_device_en(clock, 0); + return 0; +} + +int sysctl_clock_set_threshold(sysctl_threshold_t which, int threshold) +{ + int result = 0; + switch (which) + { + /* + * These threshold is 2 bit width + */ + case SYSCTL_THRESHOLD_ACLK: + sysctl->clk_sel0.aclk_divider_sel = (uint8_t)threshold & 0x03; + break; + + /* + * These threshold is 3 bit width + */ + case SYSCTL_THRESHOLD_APB0: + sysctl->clk_sel0.apb0_clk_sel = (uint8_t)threshold & 0x07; + break; + case SYSCTL_THRESHOLD_APB1: + sysctl->clk_sel0.apb1_clk_sel = (uint8_t)threshold & 0x07; + break; + case SYSCTL_THRESHOLD_APB2: + sysctl->clk_sel0.apb2_clk_sel = (uint8_t)threshold & 0x07; + break; + + /* + * These threshold is 4 bit width + */ + case SYSCTL_THRESHOLD_SRAM0: + sysctl->clk_th0.sram0_gclk_threshold = (uint8_t)threshold & 0x0F; + break; + case SYSCTL_THRESHOLD_SRAM1: + sysctl->clk_th0.sram1_gclk_threshold = (uint8_t)threshold & 0x0F; + break; + case SYSCTL_THRESHOLD_AI: + sysctl->clk_th0.ai_gclk_threshold = (uint8_t)threshold & 0x0F; + break; + case SYSCTL_THRESHOLD_DVP: + sysctl->clk_th0.dvp_gclk_threshold = (uint8_t)threshold & 0x0F; + break; + case SYSCTL_THRESHOLD_ROM: + sysctl->clk_th0.rom_gclk_threshold = (uint8_t)threshold & 0x0F; + break; + + /* + * These threshold is 8 bit width + */ + case SYSCTL_THRESHOLD_SPI0: + sysctl->clk_th1.spi0_clk_threshold = (uint8_t)threshold; + break; + case SYSCTL_THRESHOLD_SPI1: + sysctl->clk_th1.spi1_clk_threshold = (uint8_t)threshold; + break; + case SYSCTL_THRESHOLD_SPI2: + sysctl->clk_th1.spi2_clk_threshold = (uint8_t)threshold; + break; + case SYSCTL_THRESHOLD_SPI3: + sysctl->clk_th1.spi3_clk_threshold = (uint8_t)threshold; + break; + case SYSCTL_THRESHOLD_TIMER0: + sysctl->clk_th2.timer0_clk_threshold = (uint8_t)threshold; + break; + case SYSCTL_THRESHOLD_TIMER1: + sysctl->clk_th2.timer1_clk_threshold = (uint8_t)threshold; + break; + case SYSCTL_THRESHOLD_TIMER2: + sysctl->clk_th2.timer2_clk_threshold = (uint8_t)threshold; + break; + case SYSCTL_THRESHOLD_I2S0_M: + sysctl->clk_th4.i2s0_mclk_threshold = (uint8_t)threshold; + break; + case SYSCTL_THRESHOLD_I2S1_M: + sysctl->clk_th4.i2s1_mclk_threshold = (uint8_t)threshold; + break; + case SYSCTL_THRESHOLD_I2S2_M: + sysctl->clk_th5.i2s2_mclk_threshold = (uint8_t)threshold; + break; + case SYSCTL_THRESHOLD_I2C0: + sysctl->clk_th5.i2c0_clk_threshold = (uint8_t)threshold; + break; + case SYSCTL_THRESHOLD_I2C1: + sysctl->clk_th5.i2c1_clk_threshold = (uint8_t)threshold; + break; + case SYSCTL_THRESHOLD_I2C2: + sysctl->clk_th5.i2c2_clk_threshold = (uint8_t)threshold; + break; + case SYSCTL_THRESHOLD_WDT0: + sysctl->clk_th6.wdt0_clk_threshold = (uint8_t)threshold; + break; + case SYSCTL_THRESHOLD_WDT1: + sysctl->clk_th6.wdt1_clk_threshold = (uint8_t)threshold; + break; + + /* + * These threshold is 16 bit width + */ + case SYSCTL_THRESHOLD_I2S0: + sysctl->clk_th3.i2s0_clk_threshold = (uint16_t)threshold; + break; + case SYSCTL_THRESHOLD_I2S1: + sysctl->clk_th3.i2s1_clk_threshold = (uint16_t)threshold; + break; + case SYSCTL_THRESHOLD_I2S2: + sysctl->clk_th4.i2s2_clk_threshold = (uint16_t)threshold; + break; + + default: + result = -1; + break; + } + return result; +} + +int sysctl_clock_get_threshold(sysctl_threshold_t which) +{ + int threshold = 0; + + switch (which) + { + /* + * Select and get threshold value + */ + case SYSCTL_THRESHOLD_ACLK: + threshold = (int)sysctl->clk_sel0.aclk_divider_sel; + break; + case SYSCTL_THRESHOLD_APB0: + threshold = (int)sysctl->clk_sel0.apb0_clk_sel; + break; + case SYSCTL_THRESHOLD_APB1: + threshold = (int)sysctl->clk_sel0.apb1_clk_sel; + break; + case SYSCTL_THRESHOLD_APB2: + threshold = (int)sysctl->clk_sel0.apb2_clk_sel; + break; + case SYSCTL_THRESHOLD_SRAM0: + threshold = (int)sysctl->clk_th0.sram0_gclk_threshold; + break; + case SYSCTL_THRESHOLD_SRAM1: + threshold = (int)sysctl->clk_th0.sram1_gclk_threshold; + break; + case SYSCTL_THRESHOLD_AI: + threshold = (int)sysctl->clk_th0.ai_gclk_threshold; + break; + case SYSCTL_THRESHOLD_DVP: + threshold = (int)sysctl->clk_th0.dvp_gclk_threshold; + break; + case SYSCTL_THRESHOLD_ROM: + threshold = (int)sysctl->clk_th0.rom_gclk_threshold; + break; + case SYSCTL_THRESHOLD_SPI0: + threshold = (int)sysctl->clk_th1.spi0_clk_threshold; + break; + case SYSCTL_THRESHOLD_SPI1: + threshold = (int)sysctl->clk_th1.spi1_clk_threshold; + break; + case SYSCTL_THRESHOLD_SPI2: + threshold = (int)sysctl->clk_th1.spi2_clk_threshold; + break; + case SYSCTL_THRESHOLD_SPI3: + threshold = (int)sysctl->clk_th1.spi3_clk_threshold; + break; + case SYSCTL_THRESHOLD_TIMER0: + threshold = (int)sysctl->clk_th2.timer0_clk_threshold; + break; + case SYSCTL_THRESHOLD_TIMER1: + threshold = (int)sysctl->clk_th2.timer1_clk_threshold; + break; + case SYSCTL_THRESHOLD_TIMER2: + threshold = (int)sysctl->clk_th2.timer2_clk_threshold; + break; + case SYSCTL_THRESHOLD_I2S0: + threshold = (int)sysctl->clk_th3.i2s0_clk_threshold; + break; + case SYSCTL_THRESHOLD_I2S1: + threshold = (int)sysctl->clk_th3.i2s1_clk_threshold; + break; + case SYSCTL_THRESHOLD_I2S2: + threshold = (int)sysctl->clk_th4.i2s2_clk_threshold; + break; + case SYSCTL_THRESHOLD_I2S0_M: + threshold = (int)sysctl->clk_th4.i2s0_mclk_threshold; + break; + case SYSCTL_THRESHOLD_I2S1_M: + threshold = (int)sysctl->clk_th4.i2s1_mclk_threshold; + break; + case SYSCTL_THRESHOLD_I2S2_M: + threshold = (int)sysctl->clk_th5.i2s2_mclk_threshold; + break; + case SYSCTL_THRESHOLD_I2C0: + threshold = (int)sysctl->clk_th5.i2c0_clk_threshold; + break; + case SYSCTL_THRESHOLD_I2C1: + threshold = (int)sysctl->clk_th5.i2c1_clk_threshold; + break; + case SYSCTL_THRESHOLD_I2C2: + threshold = (int)sysctl->clk_th5.i2c2_clk_threshold; + break; + case SYSCTL_THRESHOLD_WDT0: + threshold = (int)sysctl->clk_th6.wdt0_clk_threshold; + break; + case SYSCTL_THRESHOLD_WDT1: + threshold = (int)sysctl->clk_th6.wdt1_clk_threshold; + break; + + default: + break; + } + + return threshold; +} + +int sysctl_clock_set_clock_select(sysctl_clock_select_t which, int select) +{ + int result = 0; + switch (which) + { + /* + * These clock select is 1 bit width + */ + case SYSCTL_CLOCK_SELECT_PLL0_BYPASS: + sysctl->pll0.pll_bypass0 = select & 0x01; + break; + case SYSCTL_CLOCK_SELECT_PLL1_BYPASS: + sysctl->pll1.pll_bypass1 = select & 0x01; + break; + case SYSCTL_CLOCK_SELECT_PLL2_BYPASS: + sysctl->pll2.pll_bypass2 = select & 0x01; + break; + case SYSCTL_CLOCK_SELECT_ACLK: + sysctl->clk_sel0.aclk_sel = select & 0x01; + break; + case SYSCTL_CLOCK_SELECT_SPI3: + sysctl->clk_sel0.spi3_clk_sel = select & 0x01; + break; + case SYSCTL_CLOCK_SELECT_TIMER0: + sysctl->clk_sel0.timer0_clk_sel = select & 0x01; + break; + case SYSCTL_CLOCK_SELECT_TIMER1: + sysctl->clk_sel0.timer1_clk_sel = select & 0x01; + break; + case SYSCTL_CLOCK_SELECT_TIMER2: + sysctl->clk_sel0.timer2_clk_sel = select & 0x01; + break; + case SYSCTL_CLOCK_SELECT_SPI3_SAMPLE: + sysctl->clk_sel1.spi3_sample_clk_sel = select & 0x01; + break; + + /* + * These clock select is 2 bit width + */ + case SYSCTL_CLOCK_SELECT_PLL2: + sysctl->pll2.pll_ckin_sel2 = select & 0x03; + break; + + default: + result = -1; + break; + } + + return result; +} + +int sysctl_clock_get_clock_select(sysctl_clock_select_t which) +{ + int clock_select = 0; + + switch (which) + { + /* + * Select and get clock select value + */ + case SYSCTL_CLOCK_SELECT_PLL0_BYPASS: + clock_select = (int)sysctl->pll0.pll_bypass0; + break; + case SYSCTL_CLOCK_SELECT_PLL1_BYPASS: + clock_select = (int)sysctl->pll1.pll_bypass1; + break; + case SYSCTL_CLOCK_SELECT_PLL2_BYPASS: + clock_select = (int)sysctl->pll2.pll_bypass2; + break; + case SYSCTL_CLOCK_SELECT_PLL2: + clock_select = (int)sysctl->pll2.pll_ckin_sel2; + break; + case SYSCTL_CLOCK_SELECT_ACLK: + clock_select = (int)sysctl->clk_sel0.aclk_sel; + break; + case SYSCTL_CLOCK_SELECT_SPI3: + clock_select = (int)sysctl->clk_sel0.spi3_clk_sel; + break; + case SYSCTL_CLOCK_SELECT_TIMER0: + clock_select = (int)sysctl->clk_sel0.timer0_clk_sel; + break; + case SYSCTL_CLOCK_SELECT_TIMER1: + clock_select = (int)sysctl->clk_sel0.timer1_clk_sel; + break; + case SYSCTL_CLOCK_SELECT_TIMER2: + clock_select = (int)sysctl->clk_sel0.timer2_clk_sel; + break; + case SYSCTL_CLOCK_SELECT_SPI3_SAMPLE: + clock_select = (int)sysctl->clk_sel1.spi3_sample_clk_sel; + break; + + default: + break; + } + + return clock_select; +} + +uint32_t sysctl_clock_source_get_freq(sysctl_clock_source_t input) +{ + uint32_t result; + + switch (input) + { + case SYSCTL_SOURCE_IN0: + result = SYSCTRL_CLOCK_FREQ_IN0; + break; + case SYSCTL_SOURCE_PLL0: + result = sysctl_pll_get_freq(SYSCTL_PLL0); + break; + case SYSCTL_SOURCE_PLL1: + result = sysctl_pll_get_freq(SYSCTL_PLL1); + break; + case SYSCTL_SOURCE_PLL2: + result = sysctl_pll_get_freq(SYSCTL_PLL2); + break; + case SYSCTL_SOURCE_ACLK: + result = SysctlClockGetFreq(SYSCTL_CLOCK_ACLK); + break; + default: + result = 0; + break; + } + return result; +} + +static int sysctl_pll_is_lock(sysctl_pll_t pll) +{ + /* + * All bit enable means PLL lock + * + * struct pll_lock_t + * { + * uint8_t overflow : 1; + * uint8_t rfslip : 1; + * uint8_t fbslip : 1; + * }; + * + */ + + if (pll >= SYSCTL_PLL_MAX) + return 0; + + switch (pll) + { + case SYSCTL_PLL0: + return sysctl->pll_lock.pll_lock0 == 3; + + case SYSCTL_PLL1: + return sysctl->pll_lock.pll_lock1 & 1; + + case SYSCTL_PLL2: + return sysctl->pll_lock.pll_lock2 & 1; + + default: + break; + } + + return 0; +} + +static int sysctl_pll_clear_slip(sysctl_pll_t pll) +{ + if (pll >= SYSCTL_PLL_MAX) + return -1; + + switch (pll) + { + case SYSCTL_PLL0: + sysctl->pll_lock.pll_slip_clear0 = 1; + break; + + case SYSCTL_PLL1: + sysctl->pll_lock.pll_slip_clear1 = 1; + break; + + case SYSCTL_PLL2: + sysctl->pll_lock.pll_slip_clear2 = 1; + break; + + default: + break; + } + + return sysctl_pll_is_lock(pll) ? 0 : -1; +} + +int sysctl_pll_enable(sysctl_pll_t pll) +{ + /* + * ---+ + * PWRDN | + * +------------------------------------------------------------- + * ^ + * | + * | + * t1 + * +------------------+ + * RESET | | + * ----------+ +----------------------------------- + * ^ ^ ^ + * |<----- t_rst ---->|<---------- t_lock ---------->| + * | | | + * t2 t3 t4 + */ + + if (pll >= SYSCTL_PLL_MAX) + return -1; + + switch (pll) + { + case SYSCTL_PLL0: + /* Do not bypass PLL */ + sysctl->pll0.pll_bypass0 = 0; + /* + * Power on the PLL, negtive from PWRDN + * 0 is power off + * 1 is power on + */ + sysctl->pll0.pll_pwrd0 = 1; + /* + * Reset trigger of the PLL, connected RESET + * 0 is free + * 1 is reset + */ + sysctl->pll0.pll_reset0 = 0; + sysctl->pll0.pll_reset0 = 1; + asm volatile ("nop"); + asm volatile ("nop"); + sysctl->pll0.pll_reset0 = 0; + break; + + case SYSCTL_PLL1: + /* Do not bypass PLL */ + sysctl->pll1.pll_bypass1 = 0; + /* + * Power on the PLL, negtive from PWRDN + * 0 is power off + * 1 is power on + */ + sysctl->pll1.pll_pwrd1 = 1; + /* + * Reset trigger of the PLL, connected RESET + * 0 is free + * 1 is reset + */ + sysctl->pll1.pll_reset1 = 0; + sysctl->pll1.pll_reset1 = 1; + asm volatile ("nop"); + asm volatile ("nop"); + sysctl->pll1.pll_reset1 = 0; + break; + + case SYSCTL_PLL2: + /* Do not bypass PLL */ + sysctl->pll2.pll_bypass2 = 0; + /* + * Power on the PLL, negtive from PWRDN + * 0 is power off + * 1 is power on + */ + sysctl->pll2.pll_pwrd2 = 1; + /* + * Reset trigger of the PLL, connected RESET + * 0 is free + * 1 is reset + */ + sysctl->pll2.pll_reset2 = 0; + sysctl->pll2.pll_reset2 = 1; + asm volatile ("nop"); + asm volatile ("nop"); + sysctl->pll2.pll_reset2 = 0; + break; + + default: + break; + } + + return 0; +} + +int sysctl_pll_disable(sysctl_pll_t pll) +{ + if (pll >= SYSCTL_PLL_MAX) + return -1; + + switch (pll) + { + case SYSCTL_PLL0: + /* Bypass PLL */ + sysctl->pll0.pll_bypass0 = 1; + /* + * Power on the PLL, negtive from PWRDN + * 0 is power off + * 1 is power on + */ + sysctl->pll0.pll_pwrd0 = 0; + break; + + case SYSCTL_PLL1: + /* Bypass PLL */ + sysctl->pll1.pll_bypass1 = 1; + /* + * Power on the PLL, negtive from PWRDN + * 0 is power off + * 1 is power on + */ + sysctl->pll1.pll_pwrd1 = 0; + break; + + case SYSCTL_PLL2: + /* Bypass PLL */ + sysctl->pll2.pll_bypass2 = 1; + /* + * Power on the PLL, negtive from PWRDN + * 0 is power off + * 1 is power on + */ + sysctl->pll2.pll_pwrd2 = 0; + break; + + default: + break; + } + + return 0; +} + +uint32_t sysctl_pll_get_freq(sysctl_pll_t pll) +{ + uint32_t freq_in = 0, freq_out = 0; + uint32_t nr = 0, nf = 0, od = 0; + uint8_t select = 0; + + if (pll >= SYSCTL_PLL_MAX) + return 0; + + switch (pll) + { + case SYSCTL_PLL0: + freq_in = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0); + nr = sysctl->pll0.clkr0 + 1; + nf = sysctl->pll0.clkf0 + 1; + od = sysctl->pll0.clkod0 + 1; + break; + + case SYSCTL_PLL1: + freq_in = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0); + nr = sysctl->pll1.clkr1 + 1; + nf = sysctl->pll1.clkf1 + 1; + od = sysctl->pll1.clkod1 + 1; + break; + + case SYSCTL_PLL2: + /* + * Get input freq accroding select register + */ + select = sysctl->pll2.pll_ckin_sel2; + if (select < sizeof(get_source_pll2)) + freq_in = sysctl_clock_source_get_freq(get_source_pll2[select]); + else + return 0; + + nr = sysctl->pll2.clkr2 + 1; + nf = sysctl->pll2.clkf2 + 1; + od = sysctl->pll2.clkod2 + 1; + break; + + default: + break; + } + + /* + * Get final PLL output freq + * FOUT = FIN / NR * NF / OD + */ + freq_out = (double)freq_in / (double)nr * (double)nf / (double)od; + return freq_out; +} + +static uint32_t sysctl_pll_source_set_freq(sysctl_pll_t pll, sysctl_clock_source_t source, uint32_t freq) +{ + uint32_t freq_in = 0; + + if (pll >= SYSCTL_PLL_MAX) + return 0; + + if (source >= SYSCTL_SOURCE_MAX) + return 0; + + switch (pll) + { + case SYSCTL_PLL0: + case SYSCTL_PLL1: + /* + * Check input clock source + */ + if (source != SYSCTL_SOURCE_IN0) + return 0; + freq_in = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0); + /* + * Check input clock freq + */ + if (freq_in == 0) + return 0; + break; + + case SYSCTL_PLL2: + /* + * Check input clock source + */ + if (source < sizeof(get_select_pll2)) + freq_in = sysctl_clock_source_get_freq(source); + /* + * Check input clock freq + */ + if (freq_in == 0) + return 0; + break; + + default: + return 0; + } + + /* + * Begin calculate PLL registers' value + */ + + /* constants */ + const double vco_min = 3.5e+08; + const double vco_max = 1.75e+09; + const double ref_min = 1.36719e+07; + const double ref_max = 1.75e+09; + const int nr_min = 1; + const int nr_max = 16; + const int nf_min = 1; + const int nf_max = 64; + const int no_min = 1; + const int no_max = 16; + const int nb_min = 1; + const int nb_max = 64; + const int max_vco = 1; + const int ref_rng = 1; + + /* variables */ + int nr = 0; + int nrx = 0; + int nf = 0; + int nfi = 0; + int no = 0; + int noe = 0; + int not = 0; + int nor = 0; + int nore = 0; + int nb = 0; + int first = 0; + int firstx = 0; + int found = 0; + + long long nfx = 0; + double fin = 0, fout = 0, fvco = 0; + double val = 0, nval = 0, err = 0, merr = 0, terr = 0; + int x_nrx = 0, x_no = 0, x_nb = 0; + long long x_nfx = 0; + double x_fvco = 0, x_err = 0; + + fin = freq_in; + fout = freq; + val = fout / fin; + terr = 0.5 / ((double)(nf_max / 2)); + first = firstx = 1; + if (terr != -2) + { + first = 0; + if (terr == 0) + terr = 1e-16; + merr = fabs(terr); + } + found = 0; + for (nfi = val; nfi < nf_max; ++nfi) + { + nr = rint(((double)nfi) / val); + if (nr == 0) + continue; + if ((ref_rng) && (nr < nr_min)) + continue; + if (fin / ((double)nr) > ref_max) + continue; + nrx = nr; + nf = nfx = nfi; + nval = ((double)nfx) / ((double)nr); + if (nf == 0) + nf = 1; + err = 1 - nval / val; + + if ((first) || (fabs(err) < merr * (1 + 1e-6)) || (fabs(err) < 1e-16)) + { + not = floor(vco_max / fout); + for (no = (not > no_max) ? no_max : not; no > no_min; --no) + { + if ((ref_rng) && ((nr / no) < nr_min)) + continue; + if ((nr % no) == 0) + break; + } + if ((nr % no) != 0) + continue; + nor = ((not > no_max) ? no_max : not) / no; + nore = nf_max / nf; + if (nor > nore) + nor = nore; + noe = ceil(vco_min / fout); + if (!max_vco) + { + nore = (noe - 1) / no + 1; + nor = nore; + not = 0; /* force next if to fail */ + } + if ((((no * nor) < (not >> 1)) || ((no * nor) < noe)) && ((no * nor) < (nf_max / nf))) + { + no = nf_max / nf; + if (no > no_max) + no = no_max; + if (no > not) + no = not; + nfx *= no; + nf *= no; + if ((no > 1) && (!firstx)) + continue; + /* wait for larger nf in later iterations */ + } + else + { + nrx /= no; + nfx *= nor; + nf *= nor; + no *= nor; + if (no > no_max) + continue; + if ((nor > 1) && (!firstx)) + continue; + /* wait for larger nf in later iterations */ + } + + nb = nfx; + if (nb < nb_min) + nb = nb_min; + if (nb > nb_max) + continue; + + fvco = fin / ((double)nrx) * ((double)nfx); + if (fvco < vco_min) + continue; + if (fvco > vco_max) + continue; + if (nf < nf_min) + continue; + if ((ref_rng) && (fin / ((double)nrx) < ref_min)) + continue; + if ((ref_rng) && (nrx > nr_max)) + continue; + if (!(((firstx) && (terr < 0)) || (fabs(err) < merr * (1 - 1e-6)) || ((max_vco) && (no > x_no)))) + continue; + if ((!firstx) && (terr >= 0) && (nrx > x_nrx)) + continue; + + found = 1; + x_no = no; + x_nrx = nrx; + x_nfx = nfx; + x_nb = nb; + x_fvco = fvco; + x_err = err; + first = firstx = 0; + merr = fabs(err); + if (terr != -1) + continue; + } + } + if (!found) + { + return 0; + } + + nrx = x_nrx; + nfx = x_nfx; + no = x_no; + nb = x_nb; + fvco = x_fvco; + err = x_err; + if ((terr != -2) && (fabs(err) >= terr * (1 - 1e-6))) + { + return 0; + } + + /* + * Begin write PLL registers' value, + * Using atomic write method. + */ + sysctl_pll0_t pll0; + sysctl_pll1_t pll1; + sysctl_pll2_t pll2; + + switch (pll) + { + case SYSCTL_PLL0: + /* Read register from bus */ + pll0 = sysctl->pll0; + /* Set register temporary value */ + pll0.clkr0 = nrx - 1; + pll0.clkf0 = nfx - 1; + pll0.clkod0 = no - 1; + pll0.bwadj0 = nb - 1; + /* Write register back to bus */ + sysctl->pll0 = pll0; + break; + + case SYSCTL_PLL1: + /* Read register from bus */ + pll1 = sysctl->pll1; + /* Set register temporary value */ + pll1.clkr1 = nrx - 1; + pll1.clkf1 = nfx - 1; + pll1.clkod1 = no - 1; + pll1.bwadj1 = nb - 1; + /* Write register back to bus */ + sysctl->pll1 = pll1; + break; + + case SYSCTL_PLL2: + /* Read register from bus */ + pll2 = sysctl->pll2; + /* Set register temporary value */ + if (source < sizeof(get_select_pll2)) + pll2.pll_ckin_sel2 = get_select_pll2[source]; + + pll2.clkr2 = nrx - 1; + pll2.clkf2 = nfx - 1; + pll2.clkod2 = no - 1; + pll2.bwadj2 = nb - 1; + /* Write register back to bus */ + sysctl->pll2 = pll2; + break; + + default: + return 0; + } + + return sysctl_pll_get_freq(pll); +} + +uint32_t SysctlClockGetFreq(sysctl_clock_t clock) +{ + uint32_t source = 0; + uint32_t result = 0; + + switch (clock) + { + /* + * The clock IN0 + */ + case SYSCTL_CLOCK_IN0: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0); + result = source; + break; + + /* + * These clock directly under PLL clock domain + * They are using gated divider. + */ + case SYSCTL_CLOCK_PLL0: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0); + result = source; + break; + case SYSCTL_CLOCK_PLL1: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL1); + result = source; + break; + case SYSCTL_CLOCK_PLL2: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL2); + result = source; + break; + + /* + * These clock directly under ACLK clock domain + */ + case SYSCTL_CLOCK_CPU: + switch (sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_ACLK)) + { + case 0: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0); + break; + case 1: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0) / + (2ULL << sysctl_clock_get_threshold(SYSCTL_THRESHOLD_ACLK)); + break; + default: + break; + } + result = source; + break; + case SYSCTL_CLOCK_DMA: + switch (sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_ACLK)) + { + case 0: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0); + break; + case 1: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0) / + (2ULL << sysctl_clock_get_threshold(SYSCTL_THRESHOLD_ACLK)); + break; + default: + break; + } + result = source; + break; + case SYSCTL_CLOCK_FFT: + switch (sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_ACLK)) + { + case 0: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0); + break; + case 1: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0) / + (2ULL << sysctl_clock_get_threshold(SYSCTL_THRESHOLD_ACLK)); + break; + default: + break; + } + result = source; + break; + case SYSCTL_CLOCK_ACLK: + switch (sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_ACLK)) + { + case 0: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0); + break; + case 1: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0) / + (2ULL << sysctl_clock_get_threshold(SYSCTL_THRESHOLD_ACLK)); + break; + default: + break; + } + result = source; + break; + case SYSCTL_CLOCK_HCLK: + switch (sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_ACLK)) + { + case 0: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0); + break; + case 1: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0) / + (2ULL << sysctl_clock_get_threshold(SYSCTL_THRESHOLD_ACLK)); + break; + default: + break; + } + result = source; + break; + + /* + * These clock under ACLK clock domain. + * They are using gated divider. + */ + case SYSCTL_CLOCK_SRAM0: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_ACLK); + result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_SRAM0) + 1); + break; + case SYSCTL_CLOCK_SRAM1: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_ACLK); + result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_SRAM1) + 1); + break; + case SYSCTL_CLOCK_ROM: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_ACLK); + result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_ROM) + 1); + break; + case SYSCTL_CLOCK_DVP: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_ACLK); + result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_DVP) + 1); + break; + + /* + * These clock under ACLK clock domain. + * They are using even divider. + */ + case SYSCTL_CLOCK_APB0: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_ACLK); + result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_APB0) + 1); + break; + case SYSCTL_CLOCK_APB1: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_ACLK); + result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_APB1) + 1); + break; + case SYSCTL_CLOCK_APB2: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_ACLK); + result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_APB2) + 1); + break; + + /* + * These clock under AI clock domain. + * They are using gated divider. + */ + case SYSCTL_CLOCK_AI: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL1); + result = source / (sysctl_clock_get_threshold(SYSCTL_THRESHOLD_AI) + 1); + break; + + /* + * These clock under I2S clock domain. + * They are using even divider. + */ + case SYSCTL_CLOCK_I2S0: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL2); + result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_I2S0) + 1) * 2); + break; + case SYSCTL_CLOCK_I2S1: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL2); + result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_I2S1) + 1) * 2); + break; + case SYSCTL_CLOCK_I2S2: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL2); + result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_I2S2) + 1) * 2); + break; + + /* + * These clock under WDT clock domain. + * They are using even divider. + */ + case SYSCTL_CLOCK_WDT0: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0); + result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_WDT0) + 1) * 2); + break; + case SYSCTL_CLOCK_WDT1: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0); + result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_WDT1) + 1) * 2); + break; + + /* + * These clock under PLL0 clock domain. + * They are using even divider. + */ + case SYSCTL_CLOCK_SPI0: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0); + result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_SPI0) + 1) * 2); + break; + case SYSCTL_CLOCK_SPI1: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0); + result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_SPI1) + 1) * 2); + break; + case SYSCTL_CLOCK_SPI2: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0); + result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_SPI2) + 1) * 2); + break; + case SYSCTL_CLOCK_I2C0: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0); + result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_I2C0) + 1) * 2); + break; + case SYSCTL_CLOCK_I2C1: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0); + result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_I2C1) + 1) * 2); + break; + case SYSCTL_CLOCK_I2C2: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0); + result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_I2C2) + 1) * 2); + break; + + /* + * These clock under PLL0_SEL clock domain. + * They are using even divider. + */ + case SYSCTL_CLOCK_SPI3: + switch (sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_SPI3)) + { + case 0: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0); + break; + case 1: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0); + break; + default: + break; + } + + result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_SPI3) + 1) * 2); + break; + case SYSCTL_CLOCK_TIMER0: + switch (sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_TIMER0)) + { + case 0: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0); + break; + case 1: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0); + break; + default: + break; + } + + result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_TIMER0) + 1) * 2); + break; + case SYSCTL_CLOCK_TIMER1: + switch (sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_TIMER1)) + { + case 0: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0); + break; + case 1: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0); + break; + default: + break; + } + + result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_TIMER1) + 1) * 2); + break; + case SYSCTL_CLOCK_TIMER2: + switch (sysctl_clock_get_clock_select(SYSCTL_CLOCK_SELECT_TIMER2)) + { + case 0: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0); + break; + case 1: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_PLL0); + break; + default: + break; + } + + result = source / ((sysctl_clock_get_threshold(SYSCTL_THRESHOLD_TIMER2) + 1) * 2); + break; + + /* + * These clock under MISC clock domain. + * They are using even divider. + */ + + /* + * These clock under APB0 clock domain. + * They are using even divider. + */ + case SYSCTL_CLOCK_GPIO: + source = SysctlClockGetFreq(SYSCTL_CLOCK_APB0); + result = source; + break; + case SYSCTL_CLOCK_UART1: + source = SysctlClockGetFreq(SYSCTL_CLOCK_APB0); + result = source; + break; + case SYSCTL_CLOCK_UART2: + source = SysctlClockGetFreq(SYSCTL_CLOCK_APB0); + result = source; + break; + case SYSCTL_CLOCK_UART3: + source = SysctlClockGetFreq(SYSCTL_CLOCK_APB0); + result = source; + break; + case SYSCTL_CLOCK_FPIOA: + source = SysctlClockGetFreq(SYSCTL_CLOCK_APB0); + result = source; + break; + case SYSCTL_CLOCK_SHA: + source = SysctlClockGetFreq(SYSCTL_CLOCK_APB0); + result = source; + break; + + /* + * These clock under APB1 clock domain. + * They are using even divider. + */ + case SYSCTL_CLOCK_AES: + source = SysctlClockGetFreq(SYSCTL_CLOCK_APB1); + result = source; + break; + case SYSCTL_CLOCK_OTP: + source = SysctlClockGetFreq(SYSCTL_CLOCK_APB1); + result = source; + break; + case SYSCTL_CLOCK_RTC: + source = sysctl_clock_source_get_freq(SYSCTL_SOURCE_IN0); + result = source; + break; + + /* + * These clock under APB2 clock domain. + * They are using even divider. + */ + /* + * Do nothing. + */ + default: + break; + } + return result; +} + +int sysctl_dma_select(sysctl_dma_channel_t channel, sysctl_dma_select_t select) +{ + sysctl_dma_sel0_t dma_sel0; + sysctl_dma_sel1_t dma_sel1; + + /* Read register from bus */ + dma_sel0 = sysctl->dma_sel0; + dma_sel1 = sysctl->dma_sel1; + switch (channel) + { + case SYSCTL_DMA_CHANNEL_0: + dma_sel0.dma_sel0 = select; + break; + + case SYSCTL_DMA_CHANNEL_1: + dma_sel0.dma_sel1 = select; + break; + + case SYSCTL_DMA_CHANNEL_2: + dma_sel0.dma_sel2 = select; + break; + + case SYSCTL_DMA_CHANNEL_3: + dma_sel0.dma_sel3 = select; + break; + + case SYSCTL_DMA_CHANNEL_4: + dma_sel0.dma_sel4 = select; + break; + + case SYSCTL_DMA_CHANNEL_5: + dma_sel1.dma_sel5 = select; + break; + + default: + return -1; + } + + /* Write register back to bus */ + sysctl->dma_sel0 = dma_sel0; + sysctl->dma_sel1 = dma_sel1; + + return 0; +} + +uint32_t sysctl_pll_fast_enable_pll(void) +{ + /* + * Begin write PLL registers' value, + * Using atomic write method. + */ + sysctl_pll0_t pll0; + sysctl_pll1_t pll1; + sysctl_pll2_t pll2; + + /* Read register from bus */ + pll0 = sysctl->pll0; + pll1 = sysctl->pll1; + pll2 = sysctl->pll2; + + /* PLL VCO MAX freq: 1.8GHz */ + + /* PLL0: 26M reference clk get 793M output clock */ + pll0.clkr0 = 0; + pll0.clkf0 = 60; + pll0.clkod0 = 1; + pll0.bwadj0 = 60; + + /* PLL1: 26M reference clk get 390M output clock */ + pll1.clkr1 = 0; + pll1.clkf1 = 59; + pll1.clkod1 = 3; + pll1.bwadj1 = 59; + + /* PLL2: 26M reference clk get 390M output clock */ + pll2.clkr2 = 0; + pll2.clkf2 = 59; + pll2.clkod2 = 3; + pll2.bwadj2 = 59; + + /* Write register to bus */ + sysctl->pll0 = pll0; + sysctl->pll1 = pll1; + sysctl->pll2 = pll2; + + sysctl_pll_enable(SYSCTL_PLL0); + sysctl_pll_enable(SYSCTL_PLL1); + sysctl_pll_enable(SYSCTL_PLL2); + + while (sysctl_pll_is_lock(SYSCTL_PLL0) == 0) + sysctl_pll_clear_slip(SYSCTL_PLL0); + while (sysctl_pll_is_lock(SYSCTL_PLL1) == 0) + sysctl_pll_clear_slip(SYSCTL_PLL1); + while (sysctl_pll_is_lock(SYSCTL_PLL2) == 0) + sysctl_pll_clear_slip(SYSCTL_PLL2); + + sysctl_clock_enable(SYSCTL_CLOCK_PLL0); + sysctl_clock_enable(SYSCTL_CLOCK_PLL1); + sysctl_clock_enable(SYSCTL_CLOCK_PLL2); + + /* Set ACLK to PLL0 */ + sysctl_clock_set_clock_select(SYSCTL_CLOCK_SELECT_ACLK, SYSCTL_SOURCE_PLL0); + + return 0; +} + +uint32_t sysctl_set_spi0_dvp_data(uint8_t en) +{ + sysctl->misc.spi_dvp_data_enable = en; + return 0; +} + +void sysctl_set_power_mode(sysctl_power_bank_t power_bank, sysctl_io_power_mode_t io_power_mode) +{ + if(io_power_mode) + *((uint32_t *)(&sysctl->power_sel)) |= (1 << power_bank); + else + *((uint32_t *)(&sysctl->power_sel)) &= ~(1 << power_bank); +} + +uint32_t SysctlPllSetFreq(sysctl_pll_t pll, uint32_t pll_freq) +{ + if(pll_freq == 0) + return 0; + + volatile sysctl_general_pll_t *v_pll_t; + switch(pll) + { + case SYSCTL_PLL0: + v_pll_t = (sysctl_general_pll_t *)(&sysctl->pll0); + break; + case SYSCTL_PLL1: + v_pll_t = (sysctl_general_pll_t *)(&sysctl->pll1); + break; + case SYSCTL_PLL2: + v_pll_t = (sysctl_general_pll_t *)(&sysctl->pll2); + break; + default: + return 0; + break; + } + + /* 1. Change CPU CLK to XTAL */ + if(pll == SYSCTL_PLL0) + sysctl_clock_set_clock_select(SYSCTL_CLOCK_SELECT_ACLK, SYSCTL_SOURCE_IN0); + + /* 2. Disable PLL output */ + v_pll_t->pll_out_en = 0; + + /* 3. Turn off PLL */ + v_pll_t->pll_pwrd = 0; + + /* 4. Set PLL new value */ + uint32_t result; + if(pll == SYSCTL_PLL2) + result = sysctl_pll_source_set_freq(pll, v_pll_t->pll_ckin_sel, pll_freq); + else + result = sysctl_pll_source_set_freq(pll, SYSCTL_SOURCE_IN0, pll_freq); + + /* 5. Power on PLL */ + v_pll_t->pll_pwrd = 1; + /* wait >100ns */ + usleep(1); + + /* 6. Reset PLL then Release Reset*/ + v_pll_t->pll_reset = 0; + v_pll_t->pll_reset = 1; + /* wait >100ns */ + usleep(1); + v_pll_t->pll_reset = 0; + + /* 7. Get lock status, wait PLL stable */ + while (sysctl_pll_is_lock(pll) == 0) + sysctl_pll_clear_slip(pll); + + /* 8. Enable PLL output */ + v_pll_t->pll_out_en = 1; + + /* 9. Change CPU CLK to PLL */ + if(pll == SYSCTL_PLL0) + sysctl_clock_set_clock_select(SYSCTL_CLOCK_SELECT_ACLK, SYSCTL_SOURCE_PLL0); + + return result; +} + +static uint32_t cpu_freq = 390000000; + +uint32_t sysctl_cpu_get_freq(void) +{ + return cpu_freq; +} + +uint32_t sysctl_cpu_set_freq(uint32_t freq) +{ + if(freq == 0) + return 0; + + cpu_freq = SysctlPllSetFreq(SYSCTL_PLL0, (sysctl->clk_sel0.aclk_divider_sel + 1) * 2 * freq); + return cpu_freq; +} + +void sysctl_enable_irq(void) +{ + SET_CSR(mie, MIP_MEIP); + SET_CSR(mstatus, MSTATUS_MIE); +} + +void sysctl_disable_irq(void) +{ + CLEAR_CSR(mie, MIP_MEIP); + CLEAR_CSR(mstatus, MSTATUS_MIE); +} + +uint64_t sysctl_get_time_us(void) +{ + uint64_t v_cycle = read_cycle(); + return v_cycle * 1000000 / SysctlClockGetFreq(SYSCTL_CLOCK_CPU); +} + +sysctl_reset_enum_status_t sysctl_get_reset_status(void) +{ + static sysctl_reset_enum_status_t s_reset_status = 0; + if(s_reset_status != 0) + { + return s_reset_status; + } + + if(sysctl->reset_status.wdt0_reset_sts) + { + s_reset_status = SYSCTL_RESET_STATUS_WDT0; + } + else if(sysctl->reset_status.wdt1_reset_sts) + { + s_reset_status = SYSCTL_RESET_STATUS_WDT1; + } + else if(sysctl->reset_status.soft_reset_sts) + { + s_reset_status = SYSCTL_RESET_STATUS_SOFT; + } + else + { + s_reset_status = SYSCTL_RESET_STATUS_HARD; + } + sysctl->reset_status.reset_sts_clr = 1; + + return s_reset_status; +} + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/Kconfig new file mode 100644 index 000000000..fdc67b1ac --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/Kconfig @@ -0,0 +1,19 @@ +if BSP_USING_HWTIMER + config HWTIMER_BUS_NAME_1 + string "hwtimer bus name" + default "hwtim1" + + menuconfig ENABLE_TIM1 + bool "enable TIM1" + default y + + if ENABLE_TIM1 + config HWTIMER_1_DEVICE_NAME_1 + string "TIM1 dev name" + default "hwtim1_dev1" + + config HWTIMER_DRIVER_NAME_1 + string "TIM1 drv name" + default "hwtim1_drv" + endif +endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/Makefile new file mode 100644 index 000000000..24d4ccfac --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/Makefile @@ -0,0 +1,5 @@ +SRC_FILES := hardware_hwtimer.c connect_hwtimer.c + + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/connect_hwtimer.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/connect_hwtimer.c new file mode 100644 index 000000000..7a7d23c08 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/connect_hwtimer.c @@ -0,0 +1,153 @@ +/* +* 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_hwtimer.c +* @brief support aiit-riscv64-board hwtimer function and register to bus framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#include +#include +#include +#include +#include +#include +#include + +static struct HwtimerCallBackInfo *ptim2_cb_info = NULL; + +int timer_callback(void *ctx) +{ + if (ptim2_cb_info) { + if (ptim2_cb_info->timeout_callback) { + ptim2_cb_info->timeout_callback(ptim2_cb_info->param); + } + } + return 0; +} + +uint32 HwtimerOpen(void *dev) +{ + struct HwtimerHardwareDevice *hwtimer_dev = dev; + + ptim2_cb_info = &hwtimer_dev->hwtimer_param.cb_info; + + plic_init(); + sysctl_enable_irq(); + timer_init(TIMER_DEVICE_1); + + size_t real_time = timer_set_interval(TIMER_DEVICE_1, TIMER_CHANNEL_1, hwtimer_dev->hwtimer_param.period_millisecond *1000); + KPrintf("timer_set_interval -- real_time : %ld\n", real_time); + timer_irq_register(TIMER_DEVICE_1, TIMER_CHANNEL_1, !hwtimer_dev->hwtimer_param.repeat, 1, timer_callback, NULL); + + timer_set_enable(TIMER_DEVICE_1, TIMER_CHANNEL_1, 1); + + return EOK; +} + +uint32 HwtimerClose(void *dev) +{ + timer_set_enable(TIMER_DEVICE_1, TIMER_CHANNEL_1, 0); + + return EOK; +} + +/*manage the hwtimer device operations*/ +static const struct HwtimerDevDone dev_done = +{ + .open = HwtimerOpen, + .close = HwtimerClose, + .write = NONE, + .read = NONE, +}; + +/*Init hwtimer bus*/ +static int BoardHwtimerBusInit(struct HwtimerBus *hwtimer_bus, struct HwtimerDriver *hwtimer_driver) +{ + x_err_t ret = EOK; + + /*Init the hwtimer bus */ + ret = HwtimerBusInit(hwtimer_bus, HWTIMER_BUS_NAME_1); + if (EOK != ret) { + KPrintf("board_hwtimer_init HwtimerBusInit error %d\n", ret); + return ERROR; + } + + /*Init the hwtimer driver*/ + hwtimer_driver->configure = NONE; + ret = HwtimerDriverInit(hwtimer_driver, HWTIMER_DRIVER_NAME_1); + if (EOK != ret) { + KPrintf("board_hwtimer_init HwtimerDriverInit error %d\n", ret); + return ERROR; + } + + /*Attach the hwtimer driver to the hwtimer bus*/ + ret = HwtimerDriverAttachToBus(HWTIMER_DRIVER_NAME_1, HWTIMER_BUS_NAME_1); + if (EOK != ret) { + KPrintf("board_hwtimer_init USEDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +/*Attach the hwtimer device to the hwtimer bus*/ +static int BoardHwtimerDevBend(void) +{ + x_err_t ret = EOK; + static struct HwtimerHardwareDevice hwtimer_device_0; + memset(&hwtimer_device_0, 0, sizeof(struct HwtimerHardwareDevice)); + + hwtimer_device_0.dev_done = &dev_done; + + ret = HwtimerDeviceRegister(&hwtimer_device_0, NONE, HWTIMER_1_DEVICE_NAME_1); + if (EOK != ret) { + KPrintf("BoardHwtimerDevBend HwtimerDeviceRegister device %s error %d\n", HWTIMER_1_DEVICE_NAME_1, ret); + return ERROR; + } + + ret = HwtimerDeviceAttachToBus(HWTIMER_1_DEVICE_NAME_1, HWTIMER_BUS_NAME_1); + if (EOK != ret) { + KPrintf("BoardHwtimerDevBend HwtimerDeviceAttachToBus device %s error %d\n", HWTIMER_1_DEVICE_NAME_1, ret); + return ERROR; + } + + return ret; +} + +/*K210 BOARD HWTIMER INIT*/ +int HwTimerInit(void) +{ + x_err_t ret = EOK; + static struct HwtimerBus hwtimer_bus; + memset(&hwtimer_bus, 0, sizeof(struct HwtimerBus)); + + static struct HwtimerDriver hwtimer_driver; + memset(&hwtimer_driver, 0, sizeof(struct HwtimerDriver)); + + ret = BoardHwtimerBusInit(&hwtimer_bus, &hwtimer_driver); + if (EOK != ret) { + KPrintf("board_hwtimer_Init error ret %u\n", ret); + return ERROR; + } + + ret = BoardHwtimerDevBend(); + if (EOK != ret) { + KPrintf("board_hwtimer_Init error ret %u\n", ret); + return ERROR; + } + + return ret; +} diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/hardware_hwtimer.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/hardware_hwtimer.c new file mode 100644 index 000000000..62fcd84ac --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/timer/hardware_hwtimer.c @@ -0,0 +1,407 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file hardware_hwtimer.c +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * @brief Private definitions for the timer instance + */ +typedef struct timer_instance +{ + timer_callback_t callback; + void *ctx; + bool single_shot; +} timer_instance_t; + +typedef void(*irq_manager_callback_t)(int irq, void* arg); + +volatile timer_instance_t timer_instance[TIMER_DEVICE_MAX][TIMER_CHANNEL_MAX]; + +volatile kendryte_timer_t *const timer[3] = +{ + (volatile kendryte_timer_t *)TIMER0_BASE_ADDR, + (volatile kendryte_timer_t *)TIMER1_BASE_ADDR, + (volatile kendryte_timer_t *)TIMER2_BASE_ADDR +}; + +void timer_init(timer_device_number_t timer_number) +{ + for(size_t i = 0; i < TIMER_CHANNEL_MAX; i++) + timer_instance[timer_number][i] = (const timer_instance_t) { + .callback = NULL, + .ctx = NULL, + .single_shot = 0, + }; + + sysctl_clock_enable(SYSCTL_CLOCK_TIMER0 + timer_number); +} + +void timer_set_clock_div(timer_device_number_t timer_number, uint32_t div) +{ + sysctl_clock_set_threshold(timer_number == 0 ? SYSCTL_THRESHOLD_TIMER0 : + timer_number == 1 ? SYSCTL_THRESHOLD_TIMER1 : + SYSCTL_THRESHOLD_TIMER2, div); +} + +void timer_enable(timer_device_number_t timer_number, timer_channel_number_t channel) +{ + timer[timer_number]->channel[channel].control |= TIMER_CR_ENABLE; +} + +void timer_disable(timer_device_number_t timer_number, timer_channel_number_t channel) +{ + timer[timer_number]->channel[channel].control &= (~TIMER_CR_ENABLE); +} + +void timer_enable_pwm(timer_device_number_t timer_number, timer_channel_number_t channel) +{ + timer[timer_number]->channel[channel].control |= TIMER_CR_PWM_ENABLE; +} + +void timer_disable_pwm(timer_device_number_t timer_number, timer_channel_number_t channel) +{ + timer[timer_number]->channel[channel].control &= (~TIMER_CR_PWM_ENABLE); +} + +void timer_enable_interrupt(timer_device_number_t timer_number, timer_channel_number_t channel) +{ + timer[timer_number]->channel[channel].control &= (~TIMER_CR_INTERRUPT_MASK); +} + +void timer_disable_interrupt(timer_device_number_t timer_number, timer_channel_number_t channel) +{ + timer[timer_number]->channel[channel].control |= TIMER_CR_INTERRUPT_MASK; +} + +void timer_set_mode(timer_device_number_t timer_number, timer_channel_number_t channel, uint32_t mode) +{ + timer[timer_number]->channel[channel].control &= (~TIMER_CR_MODE_MASK); + timer[timer_number]->channel[channel].control |= mode; +} + +void timer_set_reload(timer_device_number_t timer_number, timer_channel_number_t channel, uint32_t count) +{ + timer[timer_number]->channel[channel].load_count = count; +} + +void timer_set_reload2(timer_device_number_t timer_number, timer_channel_number_t channel, uint32_t count) +{ + timer[timer_number]->load_count2[channel] = count; +} + +uint32_t timer_get_count(timer_device_number_t timer_number, timer_channel_number_t channel) +{ + return timer[timer_number]->channel[channel].current_value; +} + +uint32_t timer_get_reload(timer_device_number_t timer_number, timer_channel_number_t channel) +{ + return timer[timer_number]->channel[channel].load_count; +} + +uint32_t timer_get_reload2(timer_device_number_t timer_number, timer_channel_number_t channel) +{ + return timer[timer_number]->load_count2[channel]; +} + +uint32_t timer_get_interrupt_status(timer_device_number_t timer_number) +{ + return timer[timer_number]->intr_stat; +} + +uint32_t timer_get_raw_interrupt_status(timer_device_number_t timer_number) +{ + return timer[timer_number]->raw_intr_stat; +} + +uint32_t timer_channel_get_interrupt_status(timer_device_number_t timer_number, timer_channel_number_t channel) +{ + return timer[timer_number]->channel[channel].intr_stat; +} + +void timer_clear_interrupt(timer_device_number_t timer_number) +{ + timer[timer_number]->eoi = timer[timer_number]->eoi; +} + +void timer_channel_clear_interrupt(timer_device_number_t timer_number, timer_channel_number_t channel) +{ + timer[timer_number]->channel[channel].eoi = timer[timer_number]->channel[channel].eoi; +} + +void timer_set_enable(timer_device_number_t timer_number, timer_channel_number_t channel, uint32_t enable) +{ + if (enable) + timer[timer_number]->channel[channel].control = TIMER_CR_USER_MODE | TIMER_CR_ENABLE; + else + timer[timer_number]->channel[channel].control = TIMER_CR_INTERRUPT_MASK; +} + +size_t timer_set_interval(timer_device_number_t timer_number, timer_channel_number_t channel, size_t useconds) +{ + uint32_t clk_freq = SysctlClockGetFreq(SYSCTL_CLOCK_TIMER0 + timer_number); + + double min_step = 1e6 / clk_freq; + size_t value = (size_t)(useconds / min_step); + configASSERT(value > 0 && value < UINT32_MAX); + timer[timer_number]->channel[channel].load_count = (uint32_t)value; + return (size_t)(min_step * value); +} + +typedef void(*timer_ontick)(); +timer_ontick time_irq[3][4] = { NULL }; + +static int timer_isr(void *parm) +{ + uint32_t timer_number; + for (timer_number = 0; timer_number < 3; timer_number++) + { + if (parm == timer[timer_number]) + break; + } + + uint32_t channel = timer[timer_number]->intr_stat; + size_t i = 0; + for (i = 0; i < 4; i++) + { + if (channel & 1) + { + if (time_irq[timer_number][i]) + (time_irq[timer_number][i])(); + break; + } + + channel >>= 1; + } + + readl(&timer[timer_number]->eoi); + return 0; +} + +void timer_set_irq(timer_device_number_t timer_number, timer_channel_number_t channel, void(*func)(), uint32_t priority) +{ + time_irq[timer_number][channel] = func; + if (channel < 2) + { + plic_set_priority(IRQN_TIMER0A_INTERRUPT + timer_number * 2, priority); + plic_irq_register(IRQN_TIMER0A_INTERRUPT + timer_number * 2, timer_isr, (void *)timer[timer_number]); + plic_irq_enable(IRQN_TIMER0A_INTERRUPT + timer_number * 2); + } + else + { + plic_set_priority(IRQN_TIMER0B_INTERRUPT + timer_number * 2, priority); + plic_irq_register(IRQN_TIMER0B_INTERRUPT + timer_number * 2, timer_isr, (void *)timer[timer_number]); + plic_irq_enable(IRQN_TIMER0B_INTERRUPT + timer_number * 2); + } +} + +/** + * @brief Get the timer irqn by device and channel object + * + * @note Internal function, not public + * @param device The device + * @param channel The channel + * @return plic_irq_t IRQ number + */ +static plic_irq_t get_timer_irqn_by_device_and_channel(timer_device_number_t device, timer_channel_number_t channel) +{ + if (device < TIMER_DEVICE_MAX && channel < TIMER_CHANNEL_MAX) { + /* + * Select timer interrupt part + * Hierarchy of Timer interrupt to PLIC + * +---------+ +-----------+ + * | 0+----+ | | + * | | +--+0A | + * | 1+----+ | | + * | TIMER0 | | | + * | 2+----+ | | + * | | +--+0B | + * | 3+----+ | | + * +---------+ | | + * | | + * +---------+ | | + * | 0+----+ | | + * | | +--+1A | + * | 1+----+ | | + * | TIMER1 | | PLIC | + * | 2+----+ | | + * | | +--+1B | + * | 3+----+ | | + * +---------+ | | + * | | + * +---------+ | | + * | 0+----+ | | + * | | +--+2A | + * | 1+----+ | | + * | TIMER2 | | | + * | 2+----+ | | + * | | +--+2B | + * | 3+----+ | | + * +---------+ +-----------+ + * + */ + if (channel < 2) { + /* It is part A interrupt, offset + 0 */ + return IRQN_TIMER0A_INTERRUPT + device * 2; + } + else { + /* It is part B interrupt, offset + 1 */ + return IRQN_TIMER0B_INTERRUPT + device * 2; + } + } + return IRQN_NO_INTERRUPT; +} + +/** + * @brief Process user callback function + * + * @note Internal function, not public + * @param device The timer device + * @param ctx The context + * @return int The callback result + */ +static int timer_interrupt_handler(timer_device_number_t device, void *ctx) +{ + uint32_t channel_int_stat = timer[device]->intr_stat; + + for (size_t i = 0; i < TIMER_CHANNEL_MAX; i++) + { + /* Check every bit for interrupt status */ + if (channel_int_stat & 1) + { + if (timer_instance[device][i].callback) { + /* Process user callback function */ + timer_instance[device][i].callback(timer_instance[device][i].ctx); + /* Check if this timer is a single shot timer */ + if (timer_instance[device][i].single_shot) { + /* Single shot timer, disable it */ + timer_set_enable(device, i, 0); + } + } + /* Clear timer interrupt flag for specific channel */ + readl(&timer[device]->channel[i].eoi); + } + channel_int_stat >>= 1; + } + + /* + * NOTE: + * Don't read timer[device]->eoi here, or you will lost some interrupt + * readl(&timer[device]->eoi); + */ + + return 0; +} + +/** + * @brief Callback function bus for timer interrupt + * + * @note Internal function, not public + * @param ctx The context + * @return int The callback result + */ +static void timer0_interrupt_callback(int irq, void *ctx) +{ + timer_interrupt_handler(TIMER_DEVICE_0, ctx); +} + +/** + * @brief Callback function bus for timer interrupt + * + * @note Internal function, not public + * @param ctx The context + * @return int The callback result + */ +static void timer1_interrupt_callback(int irq, void *ctx) +{ + timer_interrupt_handler(TIMER_DEVICE_1, ctx); +} + +/** + * @brief Callback function bus for timer interrupt + * + * @note Internal function, not public + * @param ctx The context + * @return int The callback result + */ +static void timer2_interrupt_callback(int irq, void *ctx) +{ + timer_interrupt_handler(TIMER_DEVICE_2, ctx); +} + +int timer_irq_register(timer_device_number_t device, timer_channel_number_t channel, int is_single_shot, uint32_t priority, timer_callback_t callback, void *ctx) +{ + if (device < TIMER_DEVICE_MAX && channel < TIMER_CHANNEL_MAX) { + plic_irq_t irq_number = get_timer_irqn_by_device_and_channel(device, channel); + irq_manager_callback_t plic_irq_callback[TIMER_DEVICE_MAX] = { + timer0_interrupt_callback, + timer1_interrupt_callback, + timer2_interrupt_callback, + }; + + timer_instance[device][channel] = (const timer_instance_t) { + .callback = callback, + .ctx = ctx, + .single_shot = is_single_shot, + }; + + // plic_set_priority(irq_number, priority); + // plic_irq_register(irq_number, plic_irq_callback[device], (void *)&timer_instance[device]); + // plic_irq_enable(irq_number); + + isrManager.done->registerIrq(irq_number, plic_irq_callback[device], NULL); + isrManager.done->enableIrq(irq_number); + return 0; + } + return -1; +} + +int timer_irq_unregister(timer_device_number_t device, timer_channel_number_t channel) +{ + if (device < TIMER_DEVICE_MAX && channel < TIMER_CHANNEL_MAX) { + timer_instance[device][channel] = (const timer_instance_t) { + .callback = NULL, + .ctx = NULL, + .single_shot = 0, + }; + + /* Combine 0 and 1 to A interrupt, 2 and 3 to B interrupt */ + if ((!(timer_instance[device][TIMER_CHANNEL_0].callback || + timer_instance[device][TIMER_CHANNEL_1].callback)) || + (!(timer_instance[device][TIMER_CHANNEL_2].callback || + timer_instance[device][TIMER_CHANNEL_3].callback))) { + plic_irq_t irq_number = get_timer_irqn_by_device_and_channel(device, channel); + plic_irq_unregister(irq_number); + } + return 0; + } + return -1; +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/Kconfig new file mode 100644 index 000000000..c2b9193a0 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/Kconfig @@ -0,0 +1,17 @@ +if BSP_USING_TOUCH + config TOUCH_BUS_NAME + string "touch bus name" + default "touch" + config TOUCH_DRV_NAME + string "touch bus driver name" + default "touch_drv" + config TOUCH_DEVICE_NAME + string "touch bus device name" + default "touch_dev" + config BSP_TOUCH_TP_INT + int "touch int pin" + default 30 + config FPIOA_TOUCH_TP_INT + int "fpioa touch int pin" + default 30 +endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/Makefile new file mode 100644 index 000000000..9d30ac6b6 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/Makefile @@ -0,0 +1,4 @@ +SRC_FILES := connect_touch.c + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/connect_touch.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/connect_touch.c new file mode 100644 index 000000000..2f95c371e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/connect_touch.c @@ -0,0 +1,401 @@ +/* +* 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_touch.c +* @brief support edu-riscv64 touch function and register to bus framework +* @version 1.0 +* @author AIIT XiUOS Lab +* @date 2022-10-17 +*/ + +#include +#include +#include +#include +#include +#include +#include "gsl2038firmware.h" + + +struct Finger { + uint8_t fingerID; + uint32_t x; + uint32_t y; +}; +struct Touch_event { + uint8_t NBfingers; + struct Finger fingers[5]; +}; + +#define DEFAULT_NUM 0x0D +#define TOUCH_ADDRESS 0x44 +volatile bool SemReleaseFlag = 0; + +static struct Bus* i2c_bus = NONE; +static struct Bus* pin_bus = NONE; +int touch_sem = 0; + +#define DATA_REG 0x80 +#define STATUS_REG 0xE0 + +/* HERE WE IMPLEMENT I2C READING AND WRITING FROM SENSOR */ +/* write sensor register data */ +static x_err_t WriteReg(struct HardwareDev* dev, char* buf, int len) +{ + struct BusBlockWriteParam write_param; + write_param.pos = 0; + write_param.size = len; + write_param.buffer = (void*)buf; + + /* use I2C device API transfer data */ + return BusDevWriteData(dev, &write_param); +} + +/* read sensor register data */ +static x_err_t ReadRegs(struct HardwareDev* dev, uint8 len, uint8* buf) +{ + struct BusBlockReadParam read_param; + read_param.pos = 0; + read_param.buffer = (void*)buf; + read_param.read_length = len; + read_param.size = len; + + /* use I2C device API transfer data */ + return BusDevReadData(dev, &read_param); +} + +// not used in polling mode +static void touch_pin_irqhandler(void* arg) +{ + // KPrintf("int hdr working.\n"); + if (!SemReleaseFlag) + { + KSemaphoreAbandon(touch_sem); + SemReleaseFlag = true; + } +} + +int32_t touch_irq_init() +{ + int32_t ret = -ERROR; + struct PinParam pin_param; + struct BusConfigureInfo pin_configure_info; + + pin_bus = PinBusInitGet(); + + pin_configure_info.configure_cmd = OPE_CFG; + pin_configure_info.private_data = (void*)&pin_param; + + pin_param.cmd = GPIO_CONFIG_MODE; + pin_param.pin = BSP_TOUCH_TP_INT; + pin_param.mode = GPIO_CFG_INPUT; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("config pin_param %d input failed!\n", pin_param.pin); + return -ERROR; + } + + pin_param.cmd = GPIO_IRQ_REGISTER; + pin_param.pin = BSP_TOUCH_TP_INT; + pin_param.irq_set.irq_mode = GPIO_IRQ_EDGE_BOTH; + pin_param.irq_set.hdr = touch_pin_irqhandler; + pin_param.irq_set.args = NONE; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("register pin_param %d irq failed!\n", pin_param.pin); + return -ERROR; + } + + pin_param.cmd = GPIO_IRQ_DISABLE; + pin_param.pin = BSP_TOUCH_TP_INT; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("disable pin_param %d irq failed!\n", pin_param.pin); + return -ERROR; + } + + // 4. enable interuption + pin_param.cmd = GPIO_IRQ_ENABLE; + pin_param.pin = BSP_TOUCH_TP_INT; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("enable pin_param %d irq failed!\n", pin_param.pin); + return -ERROR; + } + + return EOK; +} + +int32_t I2cTouchInit() { + // using static bus information + int32_t ret = -1; + /* find I2C device and get I2C handle */ + i2c_bus = BusFind(I2C_BUS_NAME_1); + if (NONE == i2c_bus) { + KPrintf("MCU can't find %s bus!\n", I2C_BUS_NAME_1); + return -ERROR; + } + else { + KPrintf("MCU find %s bus!\n", I2C_BUS_NAME_1); + } + i2c_bus->owner_haldev = BusFindDevice(i2c_bus, I2C_1_DEVICE_NAME_0); + i2c_bus->owner_driver = BusFindDriver(i2c_bus, I2C_DRV_NAME_1); + + if (i2c_bus->match(i2c_bus->owner_driver, i2c_bus->owner_haldev)) { + KPrintf("i2c match drv %s %p dev %s %p error\n", + I2C_DRV_NAME_1, i2c_bus->owner_driver, + I2C_1_DEVICE_NAME_0, i2c_bus->owner_haldev); + return -ERROR; + } + else { + KPrintf("MCU successfully! write %p read %p\n", + i2c_bus->owner_haldev->dev_done->write, + i2c_bus->owner_haldev->dev_done->read); + } + struct BusConfigureInfo i2c_configure_info; + + // memset(&i2c_configure_info, 0, sizeof(struct BusConfigureInfo)); + i2c_configure_info.configure_cmd = OPE_INT; + uint16 i2c_address = TOUCH_ADDRESS; + i2c_configure_info.private_data = (void*)&i2c_address; + BusDrvConfigure(i2c_bus->owner_driver, &i2c_configure_info); + + // 3. init interruption + return touch_irq_init(); +} + +void loadfw(struct HardwareDev *dev) +{ + uint8_t addr; + uint8_t Wrbuf[5]; + size_t source_len = sizeof(GSL2038_FW) / sizeof(struct fw_data); + + for (size_t source_line = 0; source_line < source_len; source_line++) { + // addr = GSL2038_FW[source_line].offset; + memset(Wrbuf, 0 , 5); + Wrbuf[0] = GSL2038_FW[source_line].offset; + Wrbuf[1] = (char)(GSL2038_FW[source_line].val & 0x000000ff); + Wrbuf[2] = (char)((GSL2038_FW[source_line].val & 0x0000ff00) >> 8); + Wrbuf[3] = (char)((GSL2038_FW[source_line].val & 0x00ff0000) >> 16); + Wrbuf[4] = (char)((GSL2038_FW[source_line].val & 0xff000000) >> 24); + + WriteReg(dev, Wrbuf,5); + } +} + +void reset() +{ + uint8_t REG[6] = {STATUS_REG, 0xE4, 0xbc, 0xbd, 0xbe, 0xbf}; + uint8_t DATA[6] = {0x88, 0x04, 0x00, 0x00, 0x00, 0x00}; + char reg_data[2]; + + int i; + for (i = 0; i < sizeof(REG); ++i) + { + // WriteReg(i2c_bus->owner_haldev, ®[i],1); + // WriteReg(i2c_bus->owner_haldev, &DATA[i],1); + reg_data[0] = REG[i]; + reg_data[1] = DATA[i]; + WriteReg(i2c_bus->owner_haldev, reg_data,2); + MdelayKTask(10); + } +} + +void startchip() +{ + char reg_data[] = {0xE0, 0x00}; + + WriteReg(i2c_bus->owner_haldev, reg_data,2); // Registre +} + +static uint32 TouchOpen(void* dev) +{ + int32_t ret = 0; + + I2cTouchInit(); + + reset(); + loadfw(i2c_bus->owner_haldev); + reset(); + startchip(); + + touch_sem = KSemaphoreCreate(0); + if (touch_sem < 0) { + KPrintf("touch create sem failed .\n"); + return -1; + } + + return ret; +} + +static uint32 TouchClose(void* dev) +{ + int32_t ret = -ERROR; + struct PinParam pin_param; + struct BusConfigureInfo pin_configure_info; + + pin_configure_info.configure_cmd = OPE_CFG; + pin_configure_info.private_data = (void*)&pin_param; + + pin_param.cmd = GPIO_IRQ_DISABLE; + pin_param.pin = BSP_TOUCH_TP_INT; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("disable pin_param %d irq failed!\n", pin_param.pin); + return -ERROR; + } + + pin_param.cmd = GPIO_IRQ_FREE; + pin_param.pin = BSP_TOUCH_TP_INT; + ret = BusDrvConfigure(pin_bus->owner_driver, &pin_configure_info); + if (ret != EOK) { + KPrintf("register pin_param %d irq failed!\n", pin_param.pin); + return -ERROR; + } + + KSemaphoreDelete(touch_sem); + + return 0; +} + +static uint32 TouchRead(void* dev, struct BusBlockReadParam* read_param) +{ + uint32 ret = -1; + x_err_t result; + uint8_t TOUCHRECDATA[24] = {0}; + struct Touch_event ts_event; + char status_reg = 0x80; + + struct TouchDataStandard* data = (struct TouchDataStandard*)read_param->buffer; + read_param->read_length = 0; + result = KSemaphoreObtain(touch_sem, 1000); + // if (EOK == result) + // { + memset(TOUCHRECDATA, 0, 24); + memset(&ts_event, 0, sizeof(struct Touch_event)); + + WriteReg(i2c_bus->owner_haldev, &status_reg, 1); + ReadRegs(i2c_bus->owner_haldev, 24, TOUCHRECDATA); + ts_event.NBfingers = TOUCHRECDATA[0]; + + for (int i = 0; i < ts_event.NBfingers; i++) + { + ts_event.fingers[i].x = ((((uint32_t)TOUCHRECDATA[(i * 4) + 5]) << 8) | (uint32_t)TOUCHRECDATA[(i * 4) + 4]) & 0x00000FFF; // 12 bits of X coord + ts_event.fingers[i].y = ((((uint32_t)TOUCHRECDATA[(i * 4) + 7]) << 8) | (uint32_t)TOUCHRECDATA[(i * 4) + 6]) & 0x00000FFF; + ts_event.fingers[i].fingerID = (uint32_t)TOUCHRECDATA[(i * 4) + 7] >> 4; // finger that did the touch + printf("fingers[%d] x %d y %d id %d\n",i,ts_event.fingers[i].x,ts_event.fingers[i].y,ts_event.fingers[i].fingerID); + } + + data->x = ts_event.fingers[ts_event.NBfingers - 1].x; + data->y = ts_event.fingers[ts_event.NBfingers - 1].y; + + SemReleaseFlag = 0; + // } + + return ret; +} + +static uint32 TouchConfigure(void* drv, struct BusConfigureInfo* configure_info) +{ + return 0; +} + +struct TouchDevDone touch_dev_done = +{ + .open = TouchOpen, + .close = TouchClose, + .write = NONE, + .read = TouchRead +}; + +/* BUS, DRIVER, DEVICE INIT */ +// register bus and driver +static int BoardTouchBusInit(struct TouchBus* touch_bus, struct TouchDriver* touch_driver, const char* bus_name, const char* drv_name) +{ + x_err_t ret = EOK; + + /*Init the touch bus */ + ret = TouchBusInit(touch_bus, bus_name); + if (EOK != ret) { + KPrintf("Board_touch_init touchBusInit error %d\n", ret); + return -ERROR; + } + + /*Init the touch driver*/ + ret = TouchDriverInit(touch_driver, drv_name); + if (EOK != ret) { + KPrintf("Board_touch_init touchDriverInit error %d\n", ret); + return -ERROR; + } + + /*Attach the touch driver to the touch bus*/ + ret = TouchDriverAttachToBus(drv_name, bus_name); + if (EOK != ret) { + KPrintf("Board_touch_init TouchDriverAttachToBus error %d\n", ret); + return -ERROR; + } + + return ret; +} + +/*Attach the touch device to the touch bus*/ +static int BoardTouchDevBend(struct TouchHardwareDevice* touch_device, void* param, const char* bus_name, const char* dev_name) +{ + x_err_t ret = EOK; + + ret = TouchDeviceRegister(touch_device, param, dev_name); + if (EOK != ret) { + KPrintf("TouchDeviceRegister device %s error %d\n", dev_name, ret); + return -ERROR; + } + + ret = TouchDeviceAttachToBus(dev_name, bus_name); + if (EOK != ret) { + KPrintf("TouchDeviceAttachToBus device %s error %d\n", dev_name, ret); + return -ERROR; + } + + return ret; +} + +// init bus, driver and device needed. +// stored in touch_bus, touch_driver and touch_dev +int HwTouchInit(void) +{ + x_err_t ret = EOK; + + static struct TouchBus touch_bus; + static struct TouchDriver touch_driver; + static struct TouchHardwareDevice touch_dev; + + memset(&touch_bus, 0, sizeof(struct TouchBus)); + memset(&touch_driver, 0, sizeof(struct TouchDriver)); + memset(&touch_dev, 0, sizeof(struct TouchHardwareDevice)); + + touch_driver.configure = TouchConfigure; + + ret = BoardTouchBusInit(&touch_bus, &touch_driver, TOUCH_BUS_NAME, TOUCH_DRV_NAME); + if (EOK != ret) { + return -ERROR; + } + + touch_dev.dev_done = &touch_dev_done; + + ret = BoardTouchDevBend(&touch_dev, NONE, TOUCH_BUS_NAME, TOUCH_DEVICE_NAME); + if (EOK != ret) { + KPrintf("board_touch_Init error ret %u\n", ret); + return -ERROR; + } + + return EOK; +} diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/gsl2038firmware.h b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/gsl2038firmware.h new file mode 100644 index 000000000..d21c2e295 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/touch/gsl2038firmware.h @@ -0,0 +1,5009 @@ +/**************************************************************************/ +/*! + @file gsl2038firmware.h + + @thanks to wireless-tag-com for the source code this firmware : https://github.com/wireless-tag-com/8ms-esp32 +*/ + +#ifndef _GSL2038_H_ +#define _GSL2038_H_ + +struct fw_data +{ + uint8_t offset; + uint32_t val; +}; + + +const struct fw_data GSL2038_FW[] = { +//GSL_2038 +{0xf0,0x2}, +{0x00,0x00000000}, +{0x04,0x00000000}, +{0x08,0x00000000}, +{0x0c,0x00000000}, +{0x10,0x00000000}, +{0x14,0x00000000}, +{0x18,0x00000000}, +{0x1c,0x00000000}, +{0x20,0x00000000}, +{0x24,0x00000000}, +{0x28,0x00000000}, +{0x2c,0x00000000}, +{0x30,0x00000000}, +{0x34,0x00000000}, +{0x38,0x00000000}, +{0x3c,0x00000000}, +{0x40,0x00000000}, +{0x44,0x00000000}, +{0x48,0x00000000}, +{0x4c,0x00000000}, +{0x50,0x000f000f}, +{0x54,0x00000000}, +{0x58,0x00000000}, +{0x5c,0x00000000}, +{0x60,0x00000000}, +{0x64,0xf801000a}, +{0x68,0x04066414}, +{0x6c,0x1001020c}, +{0x70,0x00000fff}, +{0x74,0x00000000}, +{0x78,0x00000000}, +{0x7c,0x0c020c02}, +{0xf0,0x3}, +{0x00,0xb5cbfdad}, +{0x04,0x00000000}, +{0x08,0x00400000}, +{0x0c,0x00800000}, +{0x10,0x40020000}, +{0x14,0x00000000}, +{0x18,0xff380801}, +{0x1c,0x00000000}, +{0x20,0x00000000}, +{0x24,0x00005100}, +{0x28,0x00008e00}, +{0x2c,0x00000000}, +{0x30,0x0001005d}, +{0x34,0x007d00c6}, +{0x38,0x00e60140}, +{0x3c,0x00000000}, +{0x40,0x00010001}, +{0x44,0x0035010a}, +{0x48,0x01400140}, +{0x4c,0x00000000}, +{0x50,0x00000000}, +{0x54,0x00000000}, +{0x58,0x00000080}, +{0x5c,0x00000000}, +{0x60,0x00000000}, +{0x64,0x1a0ac00a}, +{0x68,0x00000002}, +{0x6c,0x0000000f}, +{0x70,0x00000000}, +{0x74,0x00000000}, +{0x78,0xffffffec}, +{0x7c,0x00000000}, +{0xf0,0x4}, +{0x00,0x00000000}, +{0x04,0x0000b306}, +{0x08,0x00000064}, +{0x0c,0x00000fff}, +{0x10,0xfe0cff06}, +{0x14,0x00020008}, +{0x18,0x0000008c}, +{0x1c,0x03030800}, +{0x20,0x000800c0}, +{0x24,0x00000000}, +{0x28,0x80808080}, +{0x2c,0x00000000}, +{0x30,0x00010000}, +{0x34,0x00000000}, +{0x38,0x00000000}, +{0x3c,0x00000000}, +{0x40,0x00007fff}, +{0x44,0x0040002d}, +{0x48,0x00007fff}, +{0x4c,0x0040002d}, +{0x50,0x0c182430}, +{0x54,0x0c182430}, +{0x58,0x0c182430}, +{0x5c,0x0c182430}, +{0x60,0x0005000c}, +{0x64,0x00190037}, +{0x68,0x00020004}, +{0x6c,0x0008000c}, +{0x70,0x0005000c}, +{0x74,0x00190037}, +{0x78,0x0005000c}, +{0x7c,0x00190044}, +{0xf0,0x5}, +{0x00,0x0000000a}, +{0x04,0x00000001}, +{0x08,0x0000012c}, +{0x0c,0x00000000}, +{0x10,0x0000000a}, +{0x14,0x00000000}, +{0x18,0x00000fff}, +{0x1c,0x10000000}, +{0x20,0x13520042}, +{0x24,0x00000000}, +{0x28,0x00000000}, +{0x2c,0x00000400}, +{0x30,0x00000200}, +{0x34,0x1234c878}, +{0x38,0x00000001}, +{0x3c,0x00000000}, +{0x40,0x00000000}, +{0x44,0x1f808014}, +{0x48,0x03000200}, +{0x4c,0x012c044c}, +{0x50,0x00000000}, +{0x54,0x10000050}, +{0x58,0x00010002}, +{0x5c,0x00000000}, +{0x60,0x80808080}, +{0x64,0x00000000}, +{0x68,0x00000080}, +{0x6c,0x00000080}, +{0x70,0x00000011}, +{0x74,0x00000220}, +{0x78,0x00000002}, +{0x7c,0x0000000c}, +{0xf0,0x6}, +{0x00,0x0000000b}, +{0x04,0x00000000}, +{0x08,0x00000002}, +{0x0c,0x07030203}, +{0x10,0x00000032}, +{0x14,0x01080008}, +{0x18,0x00000000}, +{0x1c,0x00000001}, +{0x20,0x00002904}, +{0x24,0x00000140}, +{0x28,0x00000140}, +{0x2c,0xf801000a}, +{0x30,0xf8010008}, +{0x34,0x0000001f}, +{0x38,0x00000003}, +{0x3c,0x00000fff}, +{0x40,0x80000000}, +{0x44,0x00190019}, +{0x48,0x00000fff}, +{0x4c,0x05030203}, +{0x50,0x00000000}, +{0x54,0x000002a4}, +{0x58,0x00000000}, +{0x5c,0x00000000}, +{0x60,0x20100804}, +{0x64,0x00000000}, +{0x68,0x00000000}, +{0x6c,0x00000000}, +{0x70,0x00000000}, +{0x74,0x000000fa}, +{0x78,0x000a003c}, +{0x7c,0x00000000}, +{0xf0,0x7}, +{0x00,0x27292819}, +{0x04,0x03090208}, +{0x08,0x050b040a}, +{0x0c,0x07110610}, +{0x10,0x09130812}, +{0x14,0x00123456}, +{0x18,0x00000000}, +{0x1c,0x000a0078}, +{0x20,0x00001081}, +{0x24,0xff080010}, +{0x28,0xff080120}, +{0x2c,0xff080140}, +{0x30,0xff080160}, +{0x34,0x000002bc}, +{0x38,0x0000017d}, +{0x3c,0x00000142}, +{0x40,0x00000000}, +{0x44,0x00000000}, +{0x48,0x00000001}, +{0x4c,0x320f0f03}, +{0x50,0x00000000}, +{0x54,0x00000002}, +{0x58,0x00040000}, +{0x5c,0x00090005}, +{0x60,0x000e000a}, +{0x64,0x0013000f}, +{0x68,0x00001000}, +{0x6c,0x0004003c}, +{0x70,0x00040000}, +{0x74,0x00040000}, +{0x78,0x00012345}, +{0x7c,0x00012345}, +{0xf0,0x8}, +{0x00,0x02090c13}, +{0x04,0x10170601}, +{0x08,0x0a0e15ff}, +{0x0c,0xffffffff}, +{0x10,0xffffffff}, +{0x14,0xffffffff}, +{0x18,0xffffffff}, +{0x1c,0xffffffff}, +{0x20,0x03081116}, +{0x24,0x0d120b04}, +{0x28,0x070f14ff}, +{0x2c,0xffffffff}, +{0x30,0xffffffff}, +{0x34,0xffffffff}, +{0x38,0xffffffff}, +{0x3c,0xffffffff}, +{0x40,0x00000000}, +{0x44,0x00000000}, +{0x48,0x00000000}, +{0x4c,0x00000000}, +{0x50,0x00000000}, +{0x54,0x00000000}, +{0x58,0x00050004}, +{0x5c,0x00000000}, +{0x60,0x00000000}, +{0x64,0x00000000}, +{0x68,0x00000000}, +{0x6c,0x00000000}, +{0x70,0x00000073}, +{0x74,0x000a0019}, +{0x78,0x10000001}, +{0x7c,0x0000000c}, +{0xf0,0x9}, +{0x00,0xff080078}, +{0x04,0x00ff0011}, +{0x08,0xff08007c}, +{0x0c,0xffc00000}, +{0x10,0xfffffff0}, +{0x14,0x00000000}, +{0x18,0xfffffff0}, +{0x1c,0x00000000}, +{0x20,0xfffffff0}, +{0x24,0x00000000}, +{0x28,0xfffffff0}, +{0x2c,0x00000000}, +{0x30,0xfffffff0}, +{0x34,0x00000000}, +{0x38,0xfffffff0}, +{0x3c,0x00000000}, +{0x40,0xfffffff0}, +{0x44,0x00000000}, +{0x48,0xfffffff0}, +{0x4c,0x00000000}, +{0x50,0xfffffff0}, +{0x54,0x00000000}, +{0x58,0xfffffff0}, +{0x5c,0x00000000}, +{0x60,0xfffffff0}, +{0x64,0x00000000}, +{0x68,0xfffffff0}, +{0x6c,0x00000000}, +{0x70,0xfffffff0}, +{0x74,0x00000000}, +{0x78,0xfffffff0}, +{0x7c,0x00000000}, +{0xf0,0x1a}, +{0x00,0x00000000}, +{0x04,0x00000000}, +{0x08,0x00000000}, +{0x0c,0x00000000}, +{0x10,0x00000000}, +{0x14,0x00000000}, +{0x18,0x00000000}, +{0x1c,0x00000000}, +{0x20,0x00020000}, +{0x24,0x00000000}, +{0x28,0x00000000}, +{0x2c,0x00000000}, +{0x30,0x00020000}, +{0x34,0x00000000}, +{0x38,0x00000000}, +{0x3c,0x00000000}, +{0x40,0x00020000}, +{0x44,0x00000000}, +{0x48,0x00000000}, +{0x4c,0x00000000}, +{0x50,0x00020000}, +{0x54,0x00000000}, +{0x58,0x00000000}, +{0x5c,0x00000000}, +{0x60,0x00020000}, +{0x64,0x00000000}, +{0x68,0x00000000}, +{0x6c,0x00000000}, +{0x70,0x00020000}, +{0x74,0x00000000}, +{0x78,0x00000000}, +{0x7c,0x00000000}, +{0xf0,0x1b}, +{0x00,0x00020000}, +{0x04,0x00000000}, +{0x08,0x00000000}, +{0x0c,0x00000000}, +{0x10,0x00020000}, +{0x14,0x00000000}, +{0x18,0x00000000}, +{0x1c,0x00000000}, +{0x20,0x00020000}, +{0x24,0x00000000}, +{0x28,0x00000000}, +{0x2c,0x00000000}, +{0x30,0x00020000}, +{0x34,0x00000000}, +{0x38,0x00000000}, +{0x3c,0x00000000}, +{0x40,0x00020000}, +{0x44,0x00000000}, +{0x48,0x00000000}, +{0x4c,0x00000000}, +{0x50,0x00020000}, +{0x54,0x00000000}, +{0x58,0x00000000}, +{0x5c,0x00000000}, +{0x60,0x00020000}, +{0x64,0x00000000}, +{0x68,0x00000000}, +{0x6c,0x00000000}, +{0x70,0x00020000}, +{0x74,0x00000000}, +{0x78,0x00000000}, +{0x7c,0x00000000}, +{0xf0,0x1c}, +{0x00,0x00009249}, +{0x04,0x02412492}, +{0x08,0x0481b6db}, +{0x0c,0x06c24924}, +{0x10,0x0902db6d}, +{0x14,0x0b436db6}, +{0x18,0x0d93ffff}, +{0x1c,0x00000000}, +{0x20,0x0000003f}, +{0x24,0x0000003f}, +{0x28,0x0000003f}, +{0x2c,0x0000003f}, +{0x30,0x0000003f}, +{0x34,0x0000003f}, +{0x38,0x0000003f}, +{0x3c,0x00000000}, +{0x40,0x7e7e7e7e}, +{0x44,0x7d7d7e7e}, +{0x48,0x7d7d7d7d}, +{0x4c,0x7b7b7b7b}, +{0x50,0x77777b7b}, +{0x54,0x77777777}, +{0x58,0x6f6f6f6f}, +{0x5c,0x5f5f6f6f}, +{0x60,0x5f5f5f5f}, +{0x64,0x3f3f3f3f}, +{0x68,0x00003f3f}, +{0x6c,0x00000000}, +{0x70,0x00000000}, +{0x74,0x00000000}, +{0x78,0x00000000}, +{0x7c,0x5a5a5a5a}, +{0xf0,0x1d}, +{0x00,0x00013c4d}, +{0x04,0x024223ab}, +{0x08,0x048298f2}, +{0x0c,0x06c0d716}, +{0x10,0x0901c499}, +{0x14,0x0b436b64}, +{0x18,0x0d93ffff}, +{0x1c,0x00000000}, +{0x20,0x0000002d}, +{0x24,0x0000003f}, +{0x28,0x0000003f}, +{0x2c,0x0000003f}, +{0x30,0x00000000}, +{0x34,0x00000000}, +{0x38,0x00000000}, +{0x3c,0x00000000}, +{0x40,0x5f7e7e6f}, +{0x44,0x6f7b7d7b}, +{0x48,0x777d7e5f}, +{0x4c,0x777b5f7d}, +{0x50,0x7d5f6f7e}, +{0x54,0x7e6f7b77}, +{0x58,0x7d7d7b7e}, +{0x5c,0x77777b77}, +{0x60,0x5f5f6f6f}, +{0x64,0x3f3f3f3f}, +{0x68,0x00003f3f}, +{0x6c,0x00000000}, +{0x70,0x00000000}, +{0x74,0x00000000}, +{0x78,0x00000000}, +{0x7c,0x5a5a5a5a}, + +/* +{0xf0,0xe0}, +{0x00,0x00000000}, +{0x04,0x00000000}, +{0x08,0x00000000}, +{0x0c,0x00000000}, +{0x10,0x00000000}, +{0x14,0x00000000}, +{0x18,0x00000000}, +{0x1c,0x00000000}, +{0x20,0x00000000}, +{0x24,0x00000000}, +{0x28,0x00000000}, +{0x2c,0x00000000}, +{0x30,0x00000000}, +{0x34,0x00000000}, +{0x38,0x00000000}, +{0x3c,0x00000000}, +{0x40,0x00780226}, +{0x44,0x00780078}, +{0x48,0x01b80078}, +{0x4c,0x007801b8}, +{0x50,0x00780078}, +{0x54,0x014a0078}, +{0x58,0x014a014a}, +{0x5c,0x0050014a}, +{0x60,0x00640000}, +{0x64,0x00640064}, +{0x68,0x0000003c}, +{0x6c,0x005a0000}, +{0x70,0x00000000}, +{0x74,0x00000000}, +{0x78,0x00000000}, +{0x7c,0x00000000}, +*/ +{0xf0,0x1e}, +{0x00,0x5a5a0f00}, +{0x04,0x00003a24}, +{0x08,0x00003a94}, +{0x0c,0x00003c88}, +{0x10,0x00003e2c}, +{0x14,0x00003e60}, +{0x18,0x00004014}, +{0x1c,0x00004198}, +{0x20,0x00004384}, +{0x24,0x00004614}, +{0x28,0x00004754}, +{0x2c,0x00004810}, +{0x30,0x00004894}, +{0x34,0x0000498c}, +{0x38,0x00004c5c}, +{0x3c,0x00004d00}, +{0x40,0x00004eb4}, +{0x44,0x00005060}, +{0x48,0x00000000}, +{0x4c,0x00000000}, +{0x50,0x00000000}, +{0x54,0x00000000}, +{0x58,0x00000000}, +{0x5c,0x00000000}, +{0x60,0x00000000}, +{0x64,0x00000000}, +{0x68,0x00000000}, +{0x6c,0x00000000}, +{0x70,0x00000000}, +{0x74,0x00000000}, +{0x78,0x00000000}, +{0x7c,0x00000000}, +{0xf0,0x1f}, +{0x00,0x00000000}, +{0x04,0x00000000}, +{0x08,0x00000000}, +{0x0c,0x00000000}, +{0x10,0x00000000}, +{0x14,0x00000000}, +{0x18,0x00000000}, +{0x1c,0x00000000}, +{0x20,0x00000000}, +{0x24,0x00000000}, +{0x28,0x00000000}, +{0x2c,0x00000000}, +{0x30,0x00000000}, +{0x34,0x00000000}, +{0x38,0x00000000}, +{0x3c,0x00000000}, +{0x40,0x00000000}, +{0x44,0x00000000}, +{0x48,0x00000000}, +{0x4c,0x00000000}, +{0x50,0x00000000}, +{0x54,0x00000000}, +{0x58,0x00000000}, +{0x5c,0x00002d70}, +{0x60,0x00003068}, +{0x64,0x000036e0}, +{0x68,0x00000000}, +{0x6c,0x0000374c}, +{0x70,0x00000000}, +{0x74,0x0000396c}, +{0x78,0x00005204}, +{0x7c,0x5a5a0ffc}, +{0xf0,0x0}, +{0x00,0x01000000}, +{0x04,0x01000000}, +{0x08,0x01000000}, +{0x0c,0x233fc0c0}, +{0x10,0xa2146004}, +{0x14,0xa4102000}, +{0x18,0xe4244000}, +{0x1c,0x233fc0c0}, +{0x20,0xa2146010}, +{0x24,0x2500003f}, +{0x28,0xa414a3ff}, +{0x2c,0xe4244000}, +{0x30,0x01000000}, +{0x34,0x821020e0}, +{0x38,0x81880001}, +{0x3c,0x01000000}, +{0x40,0x01000000}, +{0x44,0xa410200f}, +{0x48,0xe4a00040}, +{0x4c,0x01000000}, +{0x50,0xa0100000}, +{0x54,0xa2100000}, +{0x58,0xa4100000}, +{0x5c,0xa6100000}, +{0x60,0xa8100000}, +{0x64,0xaa100000}, +{0x68,0xac100000}, +{0x6c,0xae100000}, +{0x70,0x90100000}, +{0x74,0x92100000}, +{0x78,0x94100000}, +{0x7c,0x96100000}, +{0xf0,0x1}, +{0x00,0x98100000}, +{0x04,0x9a100000}, +{0x08,0x9c100000}, +{0x0c,0x9e100000}, +{0x10,0x84100000}, +{0x14,0x01000000}, +{0x18,0x01000000}, +{0x1c,0x82100000}, +{0x20,0x81900001}, +{0x24,0x82100000}, +{0x28,0x81980001}, +{0x2c,0x81800000}, +{0x30,0x01000000}, +{0x34,0x01000000}, +{0x38,0x01000000}, +{0x3c,0xbc102cfc}, +{0x40,0x9c102cf8}, +{0x44,0x01000000}, +{0x48,0x01000000}, +{0x4c,0x27001040}, +{0x50,0xa614e00f}, +{0x54,0xe6a00040}, +{0x58,0x01000000}, +{0x5c,0x400006ca}, +{0x60,0x01000000}, +{0x64,0x01000000}, +{0x68,0x10bfffff}, +{0x6c,0x01000000}, +{0x70,0x03169684}, +{0x74,0x82106053}, +{0x78,0x03296948}, +{0x7c,0x82106133}, +{0xf0,0x20}, +{0x00,0x83580000}, +{0x04,0x82086ff0}, +{0x08,0x83306004}, +{0x0c,0x80a06005}, +{0x10,0x02800027}, +{0x14,0x01000000}, +{0x18,0x80a06006}, +{0x1c,0x0280003c}, +{0x20,0x01000000}, +{0x24,0x80a06015}, +{0x28,0x02800054}, +{0x2c,0x01000000}, +{0x30,0x80a0602a}, +{0x34,0x02800090}, +{0x38,0x01000000}, +{0x3c,0x80a06018}, +{0x40,0x02800085}, +{0x44,0x01000000}, +{0x48,0x073fc180}, +{0x4c,0x8610e03c}, +{0x50,0x05169680}, +{0x54,0x84004002}, +{0x58,0xc420c000}, +{0x5c,0x073fc000}, +{0x60,0x8610e020}, +{0x64,0x84102001}, +{0x68,0xc420c000}, +{0x6c,0x0500000c}, +{0x70,0x01000000}, +{0x74,0x01000000}, +{0x78,0x8480bfff}, +{0x7c,0x12bffffe}, +{0xf0,0x21}, +{0x00,0x01000000}, +{0x04,0x01000000}, +{0x08,0x073fc000}, +{0x0c,0x8610e020}, +{0x10,0x84102000}, +{0x14,0xc420c000}, +{0x18,0x01000000}, +{0x1c,0x01000000}, +{0x20,0x81c44000}, +{0x24,0x81cc8000}, +{0x28,0x01000000}, +{0x2c,0xa7500000}, +{0x30,0xa92ce002}, +{0x34,0xa734e001}, +{0x38,0xa614c014}, +{0x3c,0xa60ce007}, +{0x40,0x81900000}, +{0x44,0x01000000}, +{0x48,0x01000000}, +{0x4c,0x81e00000}, +{0x50,0xe03ba000}, +{0x54,0xe43ba008}, +{0x58,0xe83ba010}, +{0x5c,0xec3ba018}, +{0x60,0xf03ba020}, +{0x64,0xf43ba028}, +{0x68,0xf83ba030}, +{0x6c,0xfc3ba038}, +{0x70,0x81e80000}, +{0x74,0x8194c000}, +{0x78,0x01000000}, +{0x7c,0x01000000}, +{0xf0,0x22}, +{0x00,0x81c44000}, +{0x04,0x81cc8000}, +{0x08,0x01000000}, +{0x0c,0xa7500000}, +{0x10,0xa934e002}, +{0x14,0xa72ce001}, +{0x18,0xa614c014}, +{0x1c,0xa60ce007}, +{0x20,0x81900000}, +{0x24,0x01000000}, +{0x28,0x01000000}, +{0x2c,0x81e80000}, +{0x30,0x81e80000}, +{0x34,0xe01ba000}, +{0x38,0xe41ba008}, +{0x3c,0xe81ba010}, +{0x40,0xec1ba018}, +{0x44,0xf01ba020}, +{0x48,0xf41ba028}, +{0x4c,0xf81ba030}, +{0x50,0xfc1ba038}, +{0x54,0x81e00000}, +{0x58,0x81e00000}, +{0x5c,0x8194c000}, +{0x60,0x01000000}, +{0x64,0x01000000}, +{0x68,0x81c44000}, +{0x6c,0x81cc8000}, +{0x70,0x01000000}, +{0x74,0x01000000}, +{0x78,0x82102010}, +{0x7c,0x273fc0c0}, +{0xf0,0x23}, +{0x00,0xa614e010}, +{0x04,0xc224c000}, +{0x08,0x01000000}, +{0x0c,0x033fc0c0}, +{0x10,0x82106004}, +{0x14,0xa6102000}, +{0x18,0xe6204000}, +{0x1c,0x01000000}, +{0x20,0x01000000}, +{0x24,0x01000000}, +{0x28,0xa6102020}, +{0x2c,0x83480000}, +{0x30,0x82104013}, +{0x34,0x81884000}, +{0x38,0x01000000}, +{0x3c,0x40000656}, +{0x40,0x01000000}, +{0x44,0x01000000}, +{0x48,0x01000000}, +{0x4c,0xa7500000}, +{0x50,0xa934e002}, +{0x54,0xa72ce001}, +{0x58,0xa614c014}, +{0x5c,0xa60ce007}, +{0x60,0x81900000}, +{0x64,0x01000000}, +{0x68,0x81e80000}, +{0x6c,0xe01ba000}, +{0x70,0xe41ba008}, +{0x74,0xe81ba010}, +{0x78,0xec1ba018}, +{0x7c,0xf01ba020}, +{0xf0,0x24}, +{0x00,0xf41ba028}, +{0x04,0xf81ba030}, +{0x08,0xfc1ba038}, +{0x0c,0x81e00000}, +{0x10,0x8194c000}, +{0x14,0x01000000}, +{0x18,0xa6102020}, +{0x1c,0x83480000}, +{0x20,0x82284013}, +{0x24,0x81884000}, +{0x28,0x01000000}, +{0x2c,0x033fc0c0}, +{0x30,0x82106004}, +{0x34,0xa6103fff}, +{0x38,0xe6204000}, +{0x3c,0x01000000}, +{0x40,0x01000000}, +{0x44,0x01000000}, +{0x48,0x81c44000}, +{0x4c,0x81cc8000}, +{0x50,0x01000000}, +{0x54,0x82102080}, +{0x58,0x273fc0c0}, +{0x5c,0xa614e010}, +{0x60,0xc224c000}, +{0x64,0x01000000}, +{0x68,0x81c44000}, +{0x6c,0x81cc8000}, +{0x70,0x01000000}, +{0x74,0x81c48000}, +{0x78,0x81cca004}, +{0x7c,0x01000000}, +{0xf0,0x25}, +{0x00,0x1b3fc140}, +{0x04,0x82136048}, +{0x08,0xc2104000}, +{0x0c,0x82006003}, +{0x10,0x82086003}, +{0x14,0x83286002}, +{0x18,0x9a136080}, +{0x1c,0x81c3e008}, +{0x20,0xd000400d}, +{0x24,0x9de3bf98}, +{0x28,0x9e100018}, +{0x2c,0xb4102000}, +{0x30,0xb2102000}, +{0x34,0x832ea002}, +{0x38,0xf00063a4}, +{0x3c,0xb6102000}, +{0x40,0xb806400f}, +{0x44,0xbb2ee002}, +{0x48,0xc2070000}, +{0x4c,0xb606e001}, +{0x50,0xc226001d}, +{0x54,0x80a6e002}, +{0x58,0x04bffffb}, +{0x5c,0xb8072004}, +{0x60,0xb406a001}, +{0x64,0x80a6a003}, +{0x68,0x04bffff3}, +{0x6c,0xb2066018}, +{0x70,0x81c7e008}, +{0x74,0x81e80000}, +{0x78,0x82020008}, +{0x7c,0x82004008}, +{0xf0,0x26}, +{0x00,0x9b326002}, +{0x04,0x82004001}, +{0x08,0x8200400d}, +{0x0c,0x83286002}, +{0x10,0x920a6003}, +{0x14,0x932a6003}, +{0x18,0xd00065b0}, +{0x1c,0x91320009}, +{0x20,0x81c3e008}, +{0x24,0x900a20ff}, +{0x28,0x9a020008}, +{0x2c,0x9a034008}, +{0x30,0x83326002}, +{0x34,0x9a03400d}, +{0x38,0x9a034001}, +{0x3c,0x920a6003}, +{0x40,0x932a6003}, +{0x44,0x9b2b6002}, +{0x48,0x821020ff}, +{0x4c,0xd80365b0}, +{0x50,0x83284009}, +{0x54,0x822b0001}, +{0x58,0x952a8009}, +{0x5c,0x8210400a}, +{0x60,0x81c3e008}, +{0x64,0xc22365b0}, +{0x68,0x9a020008}, +{0x6c,0x9a034008}, +{0x70,0x97326002}, +{0x74,0x9a03400d}, +{0x78,0x9a03400b}, +{0x7c,0x920a6003}, +{0xf0,0x27}, +{0x00,0x9b2b6002}, +{0x04,0x932a6003}, +{0x08,0x821020ff}, +{0x0c,0xd80365b0}, +{0x10,0x83284009}, +{0x14,0x822b0001}, +{0x18,0x952a8009}, +{0x1c,0x8210400a}, +{0x20,0xc22365b0}, +{0x24,0x912a2002}, +{0x28,0xda0223a4}, +{0x2c,0x972ae002}, +{0x30,0x81c3e008}, +{0x34,0xc223400b}, +{0x38,0x82102005}, +{0x3c,0x1b3fc200}, +{0x40,0x82204008}, +{0x44,0x9a136008}, +{0x48,0x83286002}, +{0x4c,0xd0034000}, +{0x50,0x91320001}, +{0x54,0x81c3e008}, +{0x58,0x900a200f}, +{0x5c,0xc200247c}, +{0x60,0x905a0001}, +{0x64,0x921a6001}, +{0x68,0x92024008}, +{0x6c,0x92024009}, +{0x70,0x81c3e008}, +{0x74,0xd0128009}, +{0x78,0x9de3bf98}, +{0x7c,0xc200247c}, +{0xf0,0x28}, +{0x00,0x83306001}, +{0x04,0x80a60001}, +{0x08,0x1a800006}, +{0x0c,0x90100018}, +{0x10,0x7fffffea}, +{0x14,0x01000000}, +{0x18,0x10800006}, +{0x1c,0xb0020008}, +{0x20,0x7fffffe6}, +{0x24,0x90260001}, +{0x28,0x90020008}, +{0x2c,0xb0022001}, +{0x30,0x81c7e008}, +{0x34,0x81e80000}, +{0x38,0x9de3bf90}, +{0x3c,0x03008060}, +{0x40,0xe8002348}, +{0x44,0x82106040}, +{0x48,0xc227bff0}, +{0x4c,0x03080402}, +{0x50,0x82106004}, +{0x54,0xc227bff4}, +{0x58,0xa2102000}, +{0x5c,0xc20023d4}, +{0x60,0x80a44001}, +{0x64,0x1a80002f}, +{0x68,0xa4102000}, +{0x6c,0xc200247c}, +{0x70,0x80a48001}, +{0x74,0x3a800027}, +{0x78,0xa2046001}, +{0x7c,0x7fffffdf}, +{0xf0,0x29}, +{0x00,0x90100012}, +{0x04,0xa6100008}, +{0x08,0x90100011}, +{0x0c,0x7fffff9b}, +{0x10,0x92100013}, +{0x14,0x80a62000}, +{0x18,0x12800004}, +{0x1c,0xa0100008}, +{0x20,0x10800013}, +{0x24,0xa0102000}, +{0x28,0x80a62008}, +{0x2c,0x1880000e}, +{0x30,0x80a62007}, +{0x34,0x7fffff73}, +{0x38,0x01000000}, +{0x3c,0x94100008}, +{0x40,0x90100011}, +{0x44,0x7fffffc6}, +{0x48,0x92100012}, +{0x4c,0x80a20014}, +{0x50,0x04800004}, +{0x54,0x8206001e}, +{0x58,0xc2087fef}, +{0x5c,0xa02c0001}, +{0x60,0x80a62007}, +{0x64,0x18800006}, +{0x68,0x92100013}, +{0x6c,0x8206001e}, +{0x70,0xc2087ff0}, +{0x74,0xa0140001}, +{0x78,0x92100013}, +{0x7c,0x94100010}, +{0xf0,0x2a}, +{0x00,0x7fffff9a}, +{0x04,0x90100011}, +{0x08,0x10bfffd9}, +{0x0c,0xa404a001}, +{0x10,0xc20023d4}, +{0x14,0x80a44001}, +{0x18,0x0abfffd5}, +{0x1c,0xa4102000}, +{0x20,0x81c7e008}, +{0x24,0x81e80000}, +{0x28,0x98102000}, +{0x2c,0x9610201e}, +{0x30,0x80a22000}, +{0x34,0x12800003}, +{0x38,0x8210000c}, +{0x3c,0x8222c00c}, +{0x40,0x83286002}, +{0x44,0xda006480}, +{0x48,0x80a37ff0}, +{0x4c,0x02800006}, +{0x50,0x98032002}, +{0x54,0xc2006484}, +{0x58,0x80a3201f}, +{0x5c,0x04bffff5}, +{0x60,0xc2234000}, +{0x64,0x81c3e008}, +{0x68,0x01000000}, +{0x6c,0x9de3bf98}, +{0x70,0xfa002508}, +{0x74,0x033fc000}, +{0x78,0xba0f4001}, +{0x7c,0x373fc180}, +{0xf0,0x2b}, +{0x00,0x03202020}, +{0x04,0x82106080}, +{0x08,0xb816e038}, +{0x0c,0xc2270000}, +{0x10,0x03168000}, +{0x14,0x80a74001}, +{0x18,0xc026c000}, +{0x1c,0x1280000b}, +{0x20,0x98102000}, +{0x24,0x0300003f}, +{0x28,0xfa002548}, +{0x2c,0x821063ff}, +{0x30,0xba0f4001}, +{0x34,0xf8002508}, +{0x38,0x033fffc0}, +{0x3c,0xb80f0001}, +{0x40,0xba17401c}, +{0x44,0xfa202548}, +{0x48,0x80a62000}, +{0x4c,0x1680000a}, +{0x50,0x82380018}, +{0x54,0x3b3fc040}, +{0x58,0xc2002548}, +{0x5c,0x8208401d}, +{0x60,0x3b168040}, +{0x64,0x80a0401d}, +{0x68,0x22800002}, +{0x6c,0x98102001}, +{0x70,0x82380018}, +{0x74,0x8330601f}, +{0x78,0xb410400c}, +{0x7c,0xf200254c}, +{0xf0,0x2c}, +{0x00,0xd6002548}, +{0x04,0xb8102500}, +{0x08,0x82073a50}, +{0x0c,0x80a32000}, +{0x10,0x02800009}, +{0x14,0xb61f250c}, +{0x18,0x80a060f0}, +{0x1c,0xba402000}, +{0x20,0x80a0001b}, +{0x24,0x82603fff}, +{0x28,0x80974001}, +{0x2c,0x3280000a}, +{0x30,0xb8072004}, +{0x34,0x80a6a000}, +{0x38,0x02800005}, +{0x3c,0x82073960}, +{0x40,0x80a0603f}, +{0x44,0x28800004}, +{0x48,0xb8072004}, +{0x4c,0xc0270000}, +{0x50,0xb8072004}, +{0x54,0x80a7286f}, +{0x58,0x08bfffed}, +{0x5c,0x82073a50}, +{0x60,0x80a62000}, +{0x64,0x06800005}, +{0x68,0x0300003f}, +{0x6c,0x821063ff}, +{0x70,0x820e4001}, +{0x74,0xc220254c}, +{0x78,0xc2002548}, +{0x7c,0xf6002334}, +{0xf0,0x2d}, +{0x00,0xfa0023c8}, +{0x04,0xb606e001}, +{0x08,0x9e087dff}, +{0x0c,0xbb376012}, +{0x10,0xc200254c}, +{0x14,0xba0f6200}, +{0x18,0xb936e001}, +{0x1c,0x1b3fc200}, +{0x20,0x9e13c01d}, +{0x24,0xb806c01c}, +{0x28,0x82087ffd}, +{0x2c,0xfa002344}, +{0x30,0xc220254c}, +{0x34,0xf820258c}, +{0x38,0xb4136030}, +{0x3c,0xfa268000}, +{0x40,0xb2136038}, +{0x44,0xfa264000}, +{0x48,0xb132e018}, +{0x4c,0xfa20257c}, +{0x50,0x80a6205a}, +{0x54,0xf6202554}, +{0x58,0xf6202588}, +{0x5c,0xde202548}, +{0x60,0x12800009}, +{0x64,0xfa202570}, +{0x68,0x0300003f}, +{0x6c,0x821063ff}, +{0x70,0x3b3fffc0}, +{0x74,0x820bc001}, +{0x78,0xba0ac01d}, +{0x7c,0x8210401d}, +{0xf0,0x2e}, +{0x00,0xc2202548}, +{0x04,0x80a32001}, +{0x08,0x1280000e}, +{0x0c,0x01000000}, +{0x10,0xc2002548}, +{0x14,0x83306011}, +{0x18,0x80886001}, +{0x1c,0x02800006}, +{0x20,0x82102059}, +{0x24,0xba136074}, +{0x28,0xc2002330}, +{0x2c,0xc2274000}, +{0x30,0x82102059}, +{0x34,0xc2202500}, +{0x38,0x7ffffedb}, +{0x3c,0x91e825b0}, +{0x40,0x01000000}, +{0x44,0x81c7e008}, +{0x48,0x81e80000}, +{0x4c,0x033fc200}, +{0x50,0x961060a0}, +{0x54,0x98102000}, +{0x58,0x9b2b2002}, +{0x5c,0x98032001}, +{0x60,0xc2036e80}, +{0x64,0x80a32006}, +{0x68,0x04bffffc}, +{0x6c,0xc223400b}, +{0x70,0x81c3e008}, +{0x74,0x01000000}, +{0x78,0x9de3bf98}, +{0x7c,0x3b3fc200}, +{0xf0,0x2f}, +{0x00,0x03000017}, +{0x04,0xb410001d}, +{0x08,0x9e106324}, +{0x0c,0xb817612c}, +{0x10,0xb6102000}, +{0x14,0xb0176140}, +{0x18,0xb2176160}, +{0x1c,0x80a70018}, +{0x20,0x12800004}, +{0x24,0x80a70019}, +{0x28,0x10800004}, +{0x2c,0xb816a14c}, +{0x30,0x22800002}, +{0x34,0xb816a16c}, +{0x38,0xc203c000}, +{0x3c,0x80a00001}, +{0x40,0x832ee002}, +{0x44,0xc2006ec0}, +{0x48,0xba403fff}, +{0x4c,0x8208401d}, +{0x50,0xc2270000}, +{0x54,0xb606e001}, +{0x58,0x80a6e00a}, +{0x5c,0x08bffff0}, +{0x60,0xb8072004}, +{0x64,0x81c7e008}, +{0x68,0x81e80000}, +{0x6c,0x9de3bf98}, +{0x70,0x3b3fc200}, +{0x74,0x030001c0}, +{0x78,0xb8176094}, +{0x7c,0x82106011}, +{0xf0,0x30}, +{0x00,0xc2270000}, +{0x04,0xb4176090}, +{0x08,0x03000100}, +{0x0c,0xc2268000}, +{0x10,0xb2176068}, +{0x14,0x030000c0}, +{0x18,0xc2264000}, +{0x1c,0x03004009}, +{0x20,0xb0176064}, +{0x24,0x82106182}, +{0x28,0xc2260000}, +{0x2c,0x0300065f}, +{0x30,0x9e17604c}, +{0x34,0x821063ff}, +{0x38,0xc223c000}, +{0x3c,0x033fc1c0}, +{0x40,0xb8102002}, +{0x44,0xf8204000}, +{0x48,0x96176024}, +{0x4c,0x9a176060}, +{0x50,0x03000811}, +{0x54,0xba176058}, +{0x58,0xc2274000}, +{0x5c,0x373fc140}, +{0x60,0x9816e040}, +{0x64,0x82102015}, +{0x68,0xc2230000}, +{0x6c,0x821020ff}, +{0x70,0xc222c000}, +{0x74,0xb616e020}, +{0x78,0xc0234000}, +{0x7c,0xc026c000}, +{0xf0,0x31}, +{0x00,0x81c7e008}, +{0x04,0x81e80000}, +{0x08,0x832a2008}, +{0x0c,0x1b000040}, +{0x10,0x82004008}, +{0x14,0x9a136101}, +{0x18,0x9a234001}, +{0x1c,0x033fc200}, +{0x20,0x81c3e008}, +{0x24,0xda204000}, +{0x28,0x9de3bf98}, +{0x2c,0x4000022b}, +{0x30,0x01000000}, +{0x34,0x9a102000}, +{0x38,0xc2002300}, +{0x3c,0x80a34001}, +{0x40,0x1a80000d}, +{0x44,0x03000019}, +{0x48,0x9610632c}, +{0x4c,0x98106328}, +{0x50,0x832b6003}, +{0x54,0xc020400b}, +{0x58,0xc020400c}, +{0x5c,0x9a036001}, +{0x60,0xc2002300}, +{0x64,0x80a34001}, +{0x68,0x0abffffb}, +{0x6c,0x832b6003}, +{0x70,0x9a102000}, +{0x74,0xc2002304}, +{0x78,0x80a34001}, +{0x7c,0x1a80000a}, +{0xf0,0x32}, +{0x00,0x03000019}, +{0x04,0x981063c0}, +{0x08,0x832b6002}, +{0x0c,0xc020400c}, +{0x10,0x9a036001}, +{0x14,0xc2002304}, +{0x18,0x80a34001}, +{0x1c,0x0abffffc}, +{0x20,0x832b6002}, +{0x24,0x40000460}, +{0x28,0x90102000}, +{0x2c,0x7fffffd7}, +{0x30,0x90102000}, +{0x34,0x193fc200}, +{0x38,0xa2132074}, +{0x3c,0xea0021fc}, +{0x40,0xc2002298}, +{0x44,0x98132070}, +{0x48,0xc2230000}, +{0x4c,0x033fc000}, +{0x50,0xd8002338}, +{0x54,0x82106030}, +{0x58,0xd8204000}, +{0x5c,0xc200232c}, +{0x60,0xc2244000}, +{0x64,0x1b3fc140}, +{0x68,0x0300003f}, +{0x6c,0x17000019}, +{0x70,0xa0136058}, +{0x74,0x821063ff}, +{0x78,0xc2240000}, +{0x7c,0x9e136080}, +{0xf0,0x33}, +{0x00,0x9212e0e8}, +{0x04,0xd223c000}, +{0x08,0x9412e148}, +{0x0c,0xa613608c}, +{0x10,0xa412e208}, +{0x14,0xa813605c}, +{0x18,0x90136084}, +{0x1c,0xd4220000}, +{0x20,0x9a136088}, +{0x24,0x9612e1a8}, +{0x28,0xd6234000}, +{0x2c,0x033fc0c0}, +{0x30,0xe424c000}, +{0x34,0x82106004}, +{0x38,0xc0204000}, +{0x3c,0xc0250000}, +{0x40,0x80a56000}, +{0x44,0xc2002374}, +{0x48,0xd800247c}, +{0x4c,0xd40023d4}, +{0x50,0xec0023f8}, +{0x54,0x02800006}, +{0x58,0xee002340}, +{0x5c,0x82584015}, +{0x60,0x82006800}, +{0x64,0x10800003}, +{0x68,0xab30600c}, +{0x6c,0xaa100001}, +{0x70,0x1b3fc140}, +{0x74,0x96136040}, +{0x78,0xe602c000}, +{0x7c,0x99332001}, +{0xf0,0x34}, +{0x00,0x825b000a}, +{0x04,0xa60cf800}, +{0x08,0xa614c001}, +{0x0c,0xe622c000}, +{0x10,0x82136004}, +{0x14,0xe6004000}, +{0x18,0xa60cffe0}, +{0x1c,0xa614c00c}, +{0x20,0xe6204000}, +{0x24,0x293fc200}, +{0x28,0x82152080}, +{0x2c,0xe6004000}, +{0x30,0xa60cffe0}, +{0x34,0xa614c00c}, +{0x38,0xe6204000}, +{0x3c,0x9215207c}, +{0x40,0xe6024000}, +{0x44,0x033ff000}, +{0x48,0xa62cc001}, +{0x4c,0x82102114}, +{0x50,0x96152054}, +{0x54,0xc222c000}, +{0x58,0x98152008}, +{0x5c,0xec230000}, +{0x60,0x253fc1c0}, +{0x64,0xe6224000}, +{0x68,0x9014a064}, +{0x6c,0x0300007f}, +{0x70,0xee220000}, +{0x74,0x94136010}, +{0x78,0x821063ff}, +{0x7c,0xc2228000}, +{0xf0,0x35}, +{0x00,0xa2136030}, +{0x04,0x1f07ffc0}, +{0x08,0xde244000}, +{0x0c,0xa015200c}, +{0x10,0xec240000}, +{0x14,0x82102003}, +{0x18,0x9a136014}, +{0x1c,0xc2248000}, +{0x20,0x80a56000}, +{0x24,0x0280000f}, +{0x28,0xde234000}, +{0x2c,0x952d6010}, +{0x30,0x82056001}, +{0x34,0x9b2d6004}, +{0x38,0x83286010}, +{0x3c,0x9a02800d}, +{0x40,0x98152084}, +{0x44,0xda230000}, +{0x48,0x82004015}, +{0x4c,0x96152088}, +{0x50,0x9215208c}, +{0x54,0x82006002}, +{0x58,0xd422c000}, +{0x5c,0xc2224000}, +{0x60,0xc2002174}, +{0x64,0x80a06000}, +{0x68,0x02800008}, +{0x6c,0x21000017}, +{0x70,0x173fc080}, +{0x74,0xc2082174}, +{0x78,0xda082177}, +{0x7c,0x9812e008}, +{0xf0,0x36}, +{0x00,0xc2230000}, +{0x04,0xda22c000}, +{0x08,0x8214231c}, +{0x0c,0xc0204000}, +{0x10,0x9a142318}, +{0x14,0xc0234000}, +{0x18,0x98142328}, +{0x1c,0xc0230000}, +{0x20,0x9614232c}, +{0x24,0xc022c000}, +{0x28,0x94142330}, +{0x2c,0xc0228000}, +{0x30,0x92142344}, +{0x34,0x90142334}, +{0x38,0xc0224000}, +{0x3c,0xc0222004}, +{0x40,0xc0220000}, +{0x44,0x7ffffe8a}, +{0x48,0x90103fff}, +{0x4c,0xc2002fe8}, +{0x50,0x80a06000}, +{0x54,0x12800010}, +{0x58,0x03000017}, +{0x5c,0xc20822b4}, +{0x60,0x80a06000}, +{0x64,0x0280000c}, +{0x68,0x03000017}, +{0x6c,0xc2102548}, +{0x70,0x80886001}, +{0x74,0x12800008}, +{0x78,0x03000017}, +{0x7c,0x9a142324}, +{0xf0,0x37}, +{0x00,0x82102001}, +{0x04,0x98142320}, +{0x08,0xc2234000}, +{0x0c,0x10800004}, +{0x10,0xc0230000}, +{0x14,0x82106324}, +{0x18,0xc0204000}, +{0x1c,0x7fffff14}, +{0x20,0x01000000}, +{0x24,0x7ffffe61}, +{0x28,0x90102001}, +{0x2c,0x7ffffee8}, +{0x30,0x01000000}, +{0x34,0x7ffffef1}, +{0x38,0x01000000}, +{0x3c,0xc2002fd8}, +{0x40,0x80a06000}, +{0x44,0x02800005}, +{0x48,0x1b3fc0c0}, +{0x4c,0x9fc04000}, +{0x50,0x01000000}, +{0x54,0x1b3fc0c0}, +{0x58,0x82103fff}, +{0x5c,0x9a136004}, +{0x60,0xc2234000}, +{0x64,0x03000017}, +{0x68,0x82106348}, +{0x6c,0xc0204000}, +{0x70,0x7fffff26}, +{0x74,0x90102001}, +{0x78,0xc02026f8}, +{0x7c,0x81c7e008}, +{0xf0,0x38}, +{0x00,0x81e80000}, +{0x04,0x9de3bf98}, +{0x08,0x40000010}, +{0x0c,0x01000000}, +{0x10,0x40000007}, +{0x14,0x01000000}, +{0x18,0x7fffff24}, +{0x1c,0x01000000}, +{0x20,0x40000015}, +{0x24,0x01000000}, +{0x28,0x30bffffe}, +{0x2c,0x82102001}, +{0x30,0x81904000}, +{0x34,0x01000000}, +{0x38,0x01000000}, +{0x3c,0x01000000}, +{0x40,0x81c3e008}, +{0x44,0x01000000}, +{0x48,0x03000008}, +{0x4c,0x82106342}, +{0x50,0xa3804000}, +{0x54,0x03000004}, +{0x58,0x82106000}, +{0x5c,0x81984000}, +{0x60,0x01000000}, +{0x64,0x01000000}, +{0x68,0x01000000}, +{0x6c,0x81c3e008}, +{0x70,0x01000000}, +{0x74,0x01000000}, +{0x78,0x01000000}, +{0x7c,0x01000000}, +{0xf0,0x39}, +{0x00,0xa7800000}, +{0x04,0x01000000}, +{0x08,0x01000000}, +{0x0c,0x01000000}, +{0x10,0x81c3e008}, +{0x14,0x01000000}, +{0x18,0x80a22000}, +{0x1c,0x02800006}, +{0x20,0x01000000}, +{0x24,0x01000000}, +{0x28,0x90823fff}, +{0x2c,0x12bffffe}, +{0x30,0x01000000}, +{0x34,0x81c3e008}, +{0x38,0x01000000}, +{0x3c,0x01000000}, +{0x40,0x05001040}, +{0x44,0x8410a00f}, +{0x48,0xc4a00040}, +{0x4c,0x01000000}, +{0x50,0x81c3e008}, +{0x54,0x01000000}, +{0x58,0x9de3bf98}, +{0x5c,0x82102000}, +{0x60,0x80a04019}, +{0x64,0x16800015}, +{0x68,0x9e100019}, +{0x6c,0xb6006001}, +{0x70,0x80a6c00f}, +{0x74,0x1680000f}, +{0x78,0xba10001b}, +{0x7c,0xb3286002}, +{0xf0,0x3a}, +{0x00,0xb52f6002}, +{0x04,0xf8060019}, +{0x08,0xc206001a}, +{0x0c,0x80a70001}, +{0x10,0x04800004}, +{0x14,0xba076001}, +{0x18,0xc2260019}, +{0x1c,0xf826001a}, +{0x20,0x80a7400f}, +{0x24,0x06bffff8}, +{0x28,0xb52f6002}, +{0x2c,0x80a6c00f}, +{0x30,0x06bfffef}, +{0x34,0x8210001b}, +{0x38,0x81c7e008}, +{0x3c,0x81e80000}, +{0x40,0x81c3e008}, +{0x44,0x01000000}, +{0x48,0x9de3bf98}, +{0x4c,0xf8060000}, +{0x50,0x96100018}, +{0x54,0x9a100019}, +{0x58,0x80a72000}, +{0x5c,0x12800006}, +{0x60,0x9810001a}, +{0x64,0xc2064000}, +{0x68,0x80a06000}, +{0x6c,0x0280002b}, +{0x70,0xb010001a}, +{0x74,0xb006ffff}, +{0x78,0x80a3001c}, +{0x7c,0x16800012}, +{0xf0,0x3b}, +{0x00,0xba102000}, +{0x04,0x10800024}, +{0x08,0xde034000}, +{0x0c,0x8207000d}, +{0x10,0xc2006004}, +{0x14,0xba23001b}, +{0x18,0x82204019}, +{0x1c,0x8258401d}, +{0x20,0xba26801b}, +{0x24,0x9b38601f}, +{0x28,0x81836000}, +{0x2c,0x01000000}, +{0x30,0x01000000}, +{0x34,0x01000000}, +{0x38,0x8278401d}, +{0x3c,0x10800016}, +{0x40,0x9e004019}, +{0x44,0x80a74018}, +{0x48,0x16800013}, +{0x4c,0xb92f6002}, +{0x50,0x8207000b}, +{0x54,0xf4006004}, +{0x58,0xf602c01c}, +{0x5c,0xb207000d}, +{0x60,0x80a6801b}, +{0x64,0x0680000c}, +{0x68,0xba076001}, +{0x6c,0x80a3001b}, +{0x70,0x26bffff5}, +{0x74,0xde066004}, +{0x78,0x80a3001a}, +{0x7c,0x36bffff2}, +{0xf0,0x3c}, +{0x00,0xde066004}, +{0x04,0x80a6801b}, +{0x08,0x12bfffe1}, +{0x0c,0xf203401c}, +{0x10,0x9e100019}, +{0x14,0xb010000f}, +{0x18,0x81c7e008}, +{0x1c,0x81e80000}, +{0x20,0x9de3bf98}, +{0x24,0xfa002300}, +{0x28,0x832f6002}, +{0x2c,0x82006007}, +{0x30,0x82087ff8}, +{0x34,0x9810000e}, +{0x38,0x9c238001}, +{0x3c,0x9e102000}, +{0x40,0x80a3c01d}, +{0x44,0xb003a060}, +{0x48,0x1a80001e}, +{0x4c,0xb8102000}, +{0x50,0x832f2002}, +{0x54,0xc0260001}, +{0x58,0xb8072001}, +{0x5c,0xc2002300}, +{0x60,0x80a70001}, +{0x64,0x2abffffc}, +{0x68,0x832f2002}, +{0x6c,0xb8102000}, +{0x70,0x80a70001}, +{0x74,0x1a800014}, +{0x78,0x03000019}, +{0x7c,0x9a106328}, +{0xf0,0x3d}, +{0x00,0x832f2003}, +{0x04,0xb600400d}, +{0x08,0xb32f2002}, +{0x0c,0xb4102001}, +{0x10,0xfa06c000}, +{0x14,0xc2060019}, +{0x18,0x8200401d}, +{0x1c,0xc2260019}, +{0x20,0xb486bfff}, +{0x24,0x1cbffffb}, +{0x28,0xb606e004}, +{0x2c,0xb8072001}, +{0x30,0xc2002300}, +{0x34,0x80a70001}, +{0x38,0x0abffff3}, +{0x3c,0x832f2003}, +{0x40,0xb8102000}, +{0x44,0xfa002300}, +{0x48,0x80a7001d}, +{0x4c,0x3a80000d}, +{0x50,0xc210228c}, +{0x54,0xf610228e}, +{0x58,0x832f2002}, +{0x5c,0xc2060001}, +{0x60,0x80a0401b}, +{0x64,0x04800003}, +{0x68,0xb8072001}, +{0x6c,0x9e03e001}, +{0x70,0x80a7001d}, +{0x74,0x0abffffa}, +{0x78,0x832f2002}, +{0x7c,0xc210228c}, +{0xf0,0x3e}, +{0x00,0x80a3c001}, +{0x04,0x04800006}, +{0x08,0x9c10000c}, +{0x0c,0xc200254c}, +{0x10,0x3b000200}, +{0x14,0x8210401d}, +{0x18,0xc220254c}, +{0x1c,0x81c7e008}, +{0x20,0x81e80000}, +{0x24,0x81c3e008}, +{0x28,0x01000000}, +{0x2c,0x9c03bf88}, +{0x30,0x96102000}, +{0x34,0x8203a060}, +{0x38,0x98102003}, +{0x3c,0xc0204000}, +{0x40,0x98833fff}, +{0x44,0x1cbffffe}, +{0x48,0x82006004}, +{0x4c,0x98102000}, +{0x50,0xda002514}, +{0x54,0x80a3000d}, +{0x58,0x1a800008}, +{0x5c,0x832b2002}, +{0x60,0xc2106730}, +{0x64,0x80a0400b}, +{0x68,0x04bffffb}, +{0x6c,0x98032001}, +{0x70,0x10bffff9}, +{0x74,0x96100001}, +{0x78,0xda1022cc}, +{0x7c,0xc20026e0}, +{0xf0,0x3f}, +{0x00,0x80a0400d}, +{0x04,0x04800006}, +{0x08,0x03000017}, +{0x0c,0xda0822c7}, +{0x10,0x82106348}, +{0x14,0x10800008}, +{0x18,0xda204000}, +{0x1c,0x9a106348}, +{0x20,0xc2034000}, +{0x24,0x80a06000}, +{0x28,0x04800003}, +{0x2c,0x82007fff}, +{0x30,0xc2234000}, +{0x34,0x1b000017}, +{0x38,0x82136348}, +{0x3c,0xc2004000}, +{0x40,0x80a06000}, +{0x44,0x0480002f}, +{0x48,0x8213631c}, +{0x4c,0xc2004000}, +{0x50,0x80a06002}, +{0x54,0x2280002c}, +{0x58,0xc2002514}, +{0x5c,0xc20022d4}, +{0x60,0x80886010}, +{0x64,0x02800015}, +{0x68,0x03000017}, +{0x6c,0x82136328}, +{0x70,0xda004000}, +{0x74,0xc2002514}, +{0x78,0x80a0400d}, +{0x7c,0x0280000e}, +{0xf0,0x40}, +{0x00,0x03000018}, +{0x04,0x96106058}, +{0x08,0x98102000}, +{0x0c,0x9b2b2002}, +{0x10,0x98032001}, +{0x14,0xc2036720}, +{0x18,0x80a32003}, +{0x1c,0x04bffffc}, +{0x20,0xc223400b}, +{0x24,0x03000017}, +{0x28,0xda002514}, +{0x2c,0x82106328}, +{0x30,0xda204000}, +{0x34,0x03000017}, +{0x38,0x82106328}, +{0x3c,0xc2004000}, +{0x40,0x80a06000}, +{0x44,0x0480001b}, +{0x48,0x03000018}, +{0x4c,0x96106058}, +{0x50,0x98102000}, +{0x54,0x9b2b2002}, +{0x58,0x98032001}, +{0x5c,0xc203400b}, +{0x60,0x80a32003}, +{0x64,0x04bffffc}, +{0x68,0xc2236720}, +{0x6c,0x03000017}, +{0x70,0x82106328}, +{0x74,0xc2004000}, +{0x78,0x1080000e}, +{0x7c,0xc2202514}, +{0xf0,0x41}, +{0x00,0xc2002514}, +{0x04,0x9a136328}, +{0x08,0xc2234000}, +{0x0c,0x03000018}, +{0x10,0x96106058}, +{0x14,0x98102000}, +{0x18,0x9b2b2002}, +{0x1c,0x98032001}, +{0x20,0xc2036720}, +{0x24,0x80a32003}, +{0x28,0x04bffffc}, +{0x2c,0xc223400b}, +{0x30,0x03000017}, +{0x34,0xda002514}, +{0x38,0x82106328}, +{0x3c,0xda204000}, +{0x40,0x81c3e008}, +{0x44,0x9c23bf88}, +{0x48,0x98102000}, +{0x4c,0x80a3000a}, +{0x50,0x16800008}, +{0x54,0x01000000}, +{0x58,0x9b2b2002}, +{0x5c,0x98032001}, +{0x60,0xc202400d}, +{0x64,0x80a3000a}, +{0x68,0x06bffffc}, +{0x6c,0xc222000d}, +{0x70,0x81c3e008}, +{0x74,0x01000000}, +{0x78,0x9de3bf98}, +{0x7c,0x7ffffde3}, +{0xf0,0x42}, +{0x00,0x90102000}, +{0x04,0x1b000017}, +{0x08,0x98136324}, +{0x0c,0xc2030000}, +{0x10,0x80a00001}, +{0x14,0x82603fff}, +{0x18,0x92004001}, +{0x1c,0x92024001}, +{0x20,0x9a13638c}, +{0x24,0x932a6005}, +{0x28,0x9202400d}, +{0x2c,0xc2230000}, +{0x30,0x94102018}, +{0x34,0x7fffffe5}, +{0x38,0x901025b0}, +{0x3c,0x7ffffc5a}, +{0x40,0x901025b0}, +{0x44,0x7ffffd8d}, +{0x48,0xb0102001}, +{0x4c,0x7ffffdcf}, +{0x50,0x81e80000}, +{0x54,0x01000000}, +{0x58,0x03000018}, +{0x5c,0x96106054}, +{0x60,0x9810604c}, +{0x64,0x82106050}, +{0x68,0x9a103fe0}, +{0x6c,0xda204000}, +{0x70,0xc0230000}, +{0x74,0x81c3e008}, +{0x78,0xc022c000}, +{0x7c,0xda002548}, +{0xf0,0x43}, +{0x00,0x83336010}, +{0x04,0x80886001}, +{0x08,0x0280000b}, +{0x0c,0x90102001}, +{0x10,0xc2002558}, +{0x14,0x9b336011}, +{0x18,0x80a06000}, +{0x1c,0x12800005}, +{0x20,0x90102000}, +{0x24,0x808b6001}, +{0x28,0x12800003}, +{0x2c,0x01000000}, +{0x30,0x90102001}, +{0x34,0x81c3e008}, +{0x38,0x01000000}, +{0x3c,0x94102000}, +{0x40,0xc2002514}, +{0x44,0x80a28001}, +{0x48,0x96102000}, +{0x4c,0x1a800010}, +{0x50,0x9b2ae002}, +{0x54,0xc2036720}, +{0x58,0x992aa002}, +{0x5c,0x80a06000}, +{0x60,0x02800008}, +{0x64,0x9602e001}, +{0x68,0xc2232720}, +{0x6c,0xc2036730}, +{0x70,0xc2232730}, +{0x74,0xc20367e0}, +{0x78,0x9402a001}, +{0x7c,0xc22327e0}, +{0xf0,0x44}, +{0x00,0xc2002514}, +{0x04,0x10bffff2}, +{0x08,0x80a2c001}, +{0x0c,0x81c3e008}, +{0x10,0xd4202514}, +{0x14,0x9de3bf98}, +{0x18,0xb0102000}, +{0x1c,0xf6002514}, +{0x20,0x80a6001b}, +{0x24,0x1a800012}, +{0x28,0xbb2e2002}, +{0x2c,0xc2076720}, +{0x30,0x80a06000}, +{0x34,0x02bffffb}, +{0x38,0xb0062001}, +{0x3c,0xf8176732}, +{0x40,0xc200271c}, +{0x44,0x80a70001}, +{0x48,0x34800002}, +{0x4c,0xf820271c}, +{0x50,0xfa176730}, +{0x54,0xc2002718}, +{0x58,0x80a74001}, +{0x5c,0x34bffff1}, +{0x60,0xfa202718}, +{0x64,0x10bffff0}, +{0x68,0x80a6001b}, +{0x6c,0x3b333333}, +{0x70,0xc2002500}, +{0x74,0xba1760cd}, +{0x78,0x8050401d}, +{0x7c,0xbb400000}, +{0xf0,0x45}, +{0x00,0xbb376003}, +{0x04,0xb92f6002}, +{0x08,0xb807001d}, +{0x0c,0xb807001c}, +{0x10,0x80a0401c}, +{0x14,0x1280000d}, +{0x18,0xb0102000}, +{0x1c,0xc200271c}, +{0x20,0x80a06000}, +{0x24,0x04800003}, +{0x28,0x82007fff}, +{0x2c,0xc220271c}, +{0x30,0xc2002718}, +{0x34,0x80a06000}, +{0x38,0x04800003}, +{0x3c,0x82007fff}, +{0x40,0xc2202718}, +{0x44,0xb0102000}, +{0x48,0xc2002514}, +{0x4c,0x80a60001}, +{0x50,0x1a80003e}, +{0x54,0x01000000}, +{0x58,0xb4102000}, +{0x5c,0xc20022d4}, +{0x60,0x80886010}, +{0x64,0x02800006}, +{0x68,0xfa002300}, +{0x6c,0xf616a720}, +{0x70,0xb60eefff}, +{0x74,0x10800005}, +{0x78,0x9810001d}, +{0x7c,0xc206a720}, +{0xf0,0x46}, +{0x00,0xb6086fff}, +{0x04,0x99376001}, +{0x08,0x9e102000}, +{0x0c,0xc206a720}, +{0x10,0x80a06000}, +{0x14,0x22800025}, +{0x18,0x9e03e001}, +{0x1c,0x80a3e000}, +{0x20,0x32800005}, +{0x24,0xda16a730}, +{0x28,0xda16a732}, +{0x2c,0x10800003}, +{0x30,0xf200271c}, +{0x34,0xf2002718}, +{0x38,0xb92be003}, +{0x3c,0xfa572244}, +{0x40,0x80a6c01d}, +{0x44,0x26800008}, +{0x48,0xfa572246}, +{0x4c,0x832b2006}, +{0x50,0x8220401d}, +{0x54,0x80a6c001}, +{0x58,0x24800014}, +{0x5c,0x9e03e001}, +{0x60,0xfa572246}, +{0x64,0xba5e401d}, +{0x68,0x833f601f}, +{0x6c,0x83306018}, +{0x70,0xba074001}, +{0x74,0xbb3f6008}, +{0x78,0xc2572242}, +{0x7c,0x80a74001}, +{0xf0,0x47}, +{0x00,0x34800002}, +{0x04,0xba100001}, +{0x08,0xc2572240}, +{0x0c,0x80a74001}, +{0x10,0x26800002}, +{0x14,0xba100001}, +{0x18,0x80a3401d}, +{0x1c,0x26800002}, +{0x20,0xc026a720}, +{0x24,0x9e03e001}, +{0x28,0x80a3e001}, +{0x2c,0x24bfffd9}, +{0x30,0xc206a720}, +{0x34,0xb0062001}, +{0x38,0xc2002514}, +{0x3c,0x80a60001}, +{0x40,0x0abfffc7}, +{0x44,0xb406a004}, +{0x48,0x7fffff7d}, +{0x4c,0x81e80000}, +{0x50,0x01000000}, +{0x54,0x81c3e008}, +{0x58,0x01000000}, +{0x5c,0x9de3bf78}, +{0x60,0xc20022d4}, +{0x64,0x80886010}, +{0x68,0x96100018}, +{0x6c,0xa0102000}, +{0x70,0x9a102000}, +{0x74,0x94102000}, +{0x78,0x02800004}, +{0x7c,0xc2002300}, +{0xf0,0x48}, +{0x00,0x10800003}, +{0x04,0x98100001}, +{0x08,0x99306001}, +{0x0c,0x80a2e05f}, +{0x10,0x14800006}, +{0x14,0xb12b2006}, +{0x18,0x82102060}, +{0x1c,0x9420400b}, +{0x20,0x9a102000}, +{0x24,0xa0103fff}, +{0x28,0x82063fa0}, +{0x2c,0x80a2c001}, +{0x30,0x04800006}, +{0x34,0x80a66000}, +{0x38,0x8222c018}, +{0x3c,0x94006060}, +{0x40,0x9a102001}, +{0x44,0xa0102001}, +{0x48,0x32800002}, +{0x4c,0x9a036002}, +{0x50,0x80a2a000}, +{0x54,0x16800004}, +{0x58,0x80a2a03f}, +{0x5c,0x10800004}, +{0x60,0x94102000}, +{0x64,0x34800002}, +{0x68,0x9410203f}, +{0x6c,0x912b6002}, +{0x70,0x92102000}, +{0x74,0x9607bff8}, +{0x78,0x9a020009}, +{0x7c,0x8203400d}, +{0xf0,0x49}, +{0x00,0xd8506260}, +{0x04,0xc20b6250}, +{0x08,0xc222fff0}, +{0x0c,0xd822ffe0}, +{0x10,0x92026001}, +{0x14,0x80a26003}, +{0x18,0x04bffff8}, +{0x1c,0x9602e004}, +{0x20,0x9007bfe8}, +{0x24,0x9207bfd8}, +{0x28,0x7ffffe28}, +{0x2c,0x96102004}, +{0x30,0xc20022d4}, +{0x34,0x80886020}, +{0x38,0x22800002}, +{0x3c,0xa0200010}, +{0x40,0xb05c0008}, +{0x44,0x81c7e008}, +{0x48,0x81e80000}, +{0x4c,0x90020009}, +{0x50,0x932a600a}, +{0x54,0x833a601f}, +{0x58,0x81806000}, +{0x5c,0x01000000}, +{0x60,0x01000000}, +{0x64,0x01000000}, +{0x68,0x907a4008}, +{0x6c,0x033fffaa}, +{0x70,0x9b2a2008}, +{0x74,0x82106300}, +{0x78,0x9a034001}, +{0x7c,0x030c0300}, +{0xf0,0x4a}, +{0x00,0x82106301}, +{0x04,0x805b4001}, +{0x08,0x83400000}, +{0x0c,0x83386006}, +{0x10,0x9b3b601f}, +{0x14,0x80a2a001}, +{0x18,0x12800008}, +{0x1c,0x9020400d}, +{0x20,0x90020008}, +{0x24,0x80a22100}, +{0x28,0x04800005}, +{0x2c,0x80a22000}, +{0x30,0x82102200}, +{0x34,0x90204008}, +{0x38,0x80a22000}, +{0x3c,0x16800004}, +{0x40,0x80a22100}, +{0x44,0x10800004}, +{0x48,0x90102000}, +{0x4c,0x34800002}, +{0x50,0x90102100}, +{0x54,0x81c3e008}, +{0x58,0x01000000}, +{0x5c,0x9de3bf98}, +{0x60,0x03000019}, +{0x64,0x9a100018}, +{0x68,0x9e100019}, +{0x6c,0x9610632c}, +{0x70,0xb4102000}, +{0x74,0x98106328}, +{0x78,0xc24ea400}, +{0x7c,0xb12ea003}, +{0xf0,0x4b}, +{0x00,0xb9286002}, +{0x04,0x80a06000}, +{0x08,0x06800010}, +{0x0c,0xb2004001}, +{0x10,0xc24ea420}, +{0x14,0xbb286002}, +{0x18,0x82004001}, +{0x1c,0xf603401d}, +{0x20,0xc213c001}, +{0x24,0xf803401c}, +{0x28,0xfa13c019}, +{0x2c,0x8220401b}, +{0x30,0xba27401c}, +{0x34,0xb406a001}, +{0x38,0xc226000b}, +{0x3c,0x80a6a014}, +{0x40,0x08bfffee}, +{0x44,0xfa26000c}, +{0x48,0xb4102000}, +{0x4c,0xc2002304}, +{0x50,0x80a68001}, +{0x54,0x1a800010}, +{0x58,0x03000019}, +{0x5c,0xb81063c0}, +{0x60,0xc24ea380}, +{0x64,0xbb286002}, +{0x68,0x82004001}, +{0x6c,0xfa03401d}, +{0x70,0xc213c001}, +{0x74,0x8220401d}, +{0x78,0xbb2ea002}, +{0x7c,0xc227401c}, +{0xf0,0x4c}, +{0x00,0xb406a001}, +{0x04,0xc2002304}, +{0x08,0x80a68001}, +{0x0c,0x2abffff6}, +{0x10,0xc24ea380}, +{0x14,0x81c7e008}, +{0x18,0x81e80000}, +{0x1c,0x9de3bf98}, +{0x20,0xc2002508}, +{0x24,0x808860ff}, +{0x28,0x02800015}, +{0x2c,0x1b3fc180}, +{0x30,0x82102001}, +{0x34,0x9a13603c}, +{0x38,0xc2234000}, +{0x3c,0xc2002508}, +{0x40,0x820860ff}, +{0x44,0x80a04018}, +{0x48,0x1280000b}, +{0x4c,0x033fc180}, +{0x50,0x7ffffd9b}, +{0x54,0x01000000}, +{0x58,0xda002508}, +{0x5c,0x033fc040}, +{0x60,0x9a0b60ff}, +{0x64,0x8210600c}, +{0x68,0xc0204000}, +{0x6c,0x10bffff7}, +{0x70,0x80a34018}, +{0x74,0x8210603c}, +{0x78,0xc0204000}, +{0x7c,0x81c7e008}, +{0xf0,0x4d}, +{0x00,0x81e80000}, +{0x04,0x9a102000}, +{0x08,0x832b6002}, +{0x0c,0x9a036001}, +{0x10,0x80a3602f}, +{0x14,0x08bffffd}, +{0x18,0xc0220001}, +{0x1c,0x81c3e008}, +{0x20,0x01000000}, +{0x24,0x9de3bf98}, +{0x28,0x3b000019}, +{0x2c,0x98100019}, +{0x30,0x03000017}, +{0x34,0x9a106324}, +{0x38,0x94176028}, +{0x3c,0xb2102000}, +{0x40,0x9e176268}, +{0x44,0x96176088}, +{0x48,0xb92e6003}, +{0x4c,0x81800000}, +{0x50,0xc206001c}, +{0x54,0x01000000}, +{0x58,0x01000000}, +{0x5c,0x8270400c}, +{0x60,0xc226001c}, +{0x64,0x82070018}, +{0x68,0x81800000}, +{0x6c,0xf6006004}, +{0x70,0x01000000}, +{0x74,0x01000000}, +{0x78,0xb676c00c}, +{0x7c,0xf6206004}, +{0xf0,0x4e}, +{0x00,0xfa034000}, +{0x04,0x8207401d}, +{0x08,0x8200401d}, +{0x0c,0xfa06001c}, +{0x10,0x83286003}, +{0x14,0x82004019}, +{0x18,0xbb2f6010}, +{0x1c,0x83286002}, +{0x20,0xba07401b}, +{0x24,0xfa20400f}, +{0x28,0xc2034000}, +{0x2c,0x80a06000}, +{0x30,0x1280000c}, +{0x34,0xb52e6002}, +{0x38,0xc206800f}, +{0x3c,0xc226800b}, +{0x40,0xfa034000}, +{0x44,0x8207401d}, +{0x48,0x8200401d}, +{0x4c,0x83286003}, +{0x50,0x82004019}, +{0x54,0x83286002}, +{0x58,0xc200400f}, +{0x5c,0xc226800a}, +{0x60,0xb2066001}, +{0x64,0x80a66017}, +{0x68,0x08bfffd9}, +{0x6c,0xb92e6003}, +{0x70,0x81c7e008}, +{0x74,0x81e80000}, +{0x78,0x81c3e008}, +{0x7c,0x01000000}, +{0xf0,0x4f}, +{0x00,0x9de3bf98}, +{0x04,0xf8060000}, +{0x08,0xfa064000}, +{0x0c,0x83372010}, +{0x10,0xb5376010}, +{0x14,0x82086fff}, +{0x18,0xb40eafff}, +{0x1c,0xb620401a}, +{0x20,0x03000007}, +{0x24,0x821063ff}, +{0x28,0xb40f4001}, +{0x2c,0x820f0001}, +{0x30,0xb820401a}, +{0x34,0xc2002328}, +{0x38,0xb65ec001}, +{0x3c,0xc2002324}, +{0x40,0xb05f0001}, +{0x44,0x833e201f}, +{0x48,0x83306016}, +{0x4c,0xb4060001}, +{0x50,0xc20022d4}, +{0x54,0xbb3ee01f}, +{0x58,0xbb376015}, +{0x5c,0x80886010}, +{0x60,0xc2002300}, +{0x64,0xb806c01d}, +{0x68,0xbb286006}, +{0x6c,0x0280000a}, +{0x70,0x83286005}, +{0x74,0x833ee01f}, +{0x78,0x81806000}, +{0x7c,0x01000000}, +{0xf0,0x50}, +{0x00,0x01000000}, +{0x04,0x01000000}, +{0x08,0xb67ec01d}, +{0x0c,0x10800009}, +{0x10,0xb13ea00a}, +{0x14,0x9b3e201f}, +{0x18,0x81836000}, +{0x1c,0x01000000}, +{0x20,0x01000000}, +{0x24,0x01000000}, +{0x28,0xb07e0001}, +{0x2c,0xb73f200b}, +{0x30,0x825ec01b}, +{0x34,0xb05e0018}, +{0x38,0x81c7e008}, +{0x3c,0x91e84018}, +{0x40,0x9de3bf98}, +{0x44,0x03000017}, +{0x48,0x82106324}, +{0x4c,0xfa004000}, +{0x50,0x03000019}, +{0x54,0xb2106028}, +{0x58,0x80a76000}, +{0x5c,0x02800004}, +{0x60,0x9e100019}, +{0x64,0xb21062c8}, +{0x68,0x9e100019}, +{0x6c,0xf4060000}, +{0x70,0x03000018}, +{0x74,0x82106368}, +{0x78,0xbb2ea002}, +{0x7c,0xfa074001}, +{0xf0,0x51}, +{0x00,0xb806801a}, +{0x04,0xc213c01c}, +{0x08,0xb6a74001}, +{0x0c,0x02800016}, +{0x10,0x8206801a}, +{0x14,0x80a6e000}, +{0x18,0x04800009}, +{0x1c,0x82102001}, +{0x20,0xf0062004}, +{0x24,0x83284018}, +{0x28,0x80a6c001}, +{0x2c,0x3480000d}, +{0x30,0xb73ec018}, +{0x34,0x1080000b}, +{0x38,0xb6102001}, +{0x3c,0x1680000a}, +{0x40,0x8206801a}, +{0x44,0xf0062008}, +{0x48,0x82103fff}, +{0x4c,0x83284018}, +{0x50,0x80a6c001}, +{0x54,0x36800003}, +{0x58,0xb6103fff}, +{0x5c,0xb73ec018}, +{0x60,0x8206801a}, +{0x64,0xc213c001}, +{0x68,0xb606c001}, +{0x6c,0x808ea001}, +{0x70,0x0280000d}, +{0x74,0xbb3ea01f}, +{0x78,0xbb37601f}, +{0x7c,0xba06801d}, +{0xf0,0x52}, +{0x00,0xbb3f6001}, +{0x04,0xbb2f6002}, +{0x08,0x033fffc0}, +{0x0c,0xf806401d}, +{0x10,0xb80f0001}, +{0x14,0x0300003f}, +{0x18,0x821063ff}, +{0x1c,0x1080000b}, +{0x20,0x820ec001}, +{0x24,0xbb37601f}, +{0x28,0xba06801d}, +{0x2c,0xbb3f6001}, +{0x30,0xbb2f6002}, +{0x34,0x0300003f}, +{0x38,0x821063ff}, +{0x3c,0xf806401d}, +{0x40,0xb80f0001}, +{0x44,0x832ee010}, +{0x48,0xb8170001}, +{0x4c,0xf826401d}, +{0x50,0x81c7e008}, +{0x54,0x81e80000}, +{0x58,0x9de3bf68}, +{0x5c,0x7ffffa49}, +{0x60,0xb0102001}, +{0x64,0xa4100008}, +{0x68,0xa2102000}, +{0x6c,0xa0102003}, +{0x70,0x11000016}, +{0x74,0x921223e8}, +{0x78,0x90122388}, +{0x7c,0x90044008}, +{0xf0,0x53}, +{0x00,0x92044009}, +{0x04,0x7ffffdd1}, +{0x08,0x94102018}, +{0x0c,0xa0843fff}, +{0x10,0x1cbffff8}, +{0x14,0xa2046060}, +{0x18,0x11000017}, +{0x1c,0x90122108}, +{0x20,0x92100012}, +{0x24,0x7ffffdc9}, +{0x28,0x94102018}, +{0x2c,0x8207bfe0}, +{0x30,0xa0102004}, +{0x34,0xc0204000}, +{0x38,0xa0843fff}, +{0x3c,0x1cbffffe}, +{0x40,0x82006004}, +{0x44,0xa0102000}, +{0x48,0x03000016}, +{0x4c,0x9a040010}, +{0x50,0x82106388}, +{0x54,0x9a034001}, +{0x58,0xa207bff8}, +{0x5c,0x9807bfc8}, +{0x60,0x96102004}, +{0x64,0xc2134000}, +{0x68,0xc2230000}, +{0x6c,0x9a036060}, +{0x70,0x9682ffff}, +{0x74,0x1cbffffc}, +{0x78,0x98032004}, +{0x7c,0x92102005}, +{0xf0,0x54}, +{0x00,0x7ffffcb6}, +{0x04,0x9007bfc8}, +{0x08,0x03000016}, +{0x0c,0x9a040010}, +{0x10,0x82106388}, +{0x14,0x94034001}, +{0x18,0xd207bfd0}, +{0x1c,0x98100011}, +{0x20,0x96102004}, +{0x24,0xc2128000}, +{0x28,0x82224001}, +{0x2c,0x9b38601f}, +{0x30,0x8218400d}, +{0x34,0x8220400d}, +{0x38,0xda033fe8}, +{0x3c,0x9a034001}, +{0x40,0xda233fe8}, +{0x44,0x9402a060}, +{0x48,0x9682ffff}, +{0x4c,0x1cbffff6}, +{0x50,0x98032004}, +{0x54,0xa0042001}, +{0x58,0x80a42023}, +{0x5c,0x04bfffdc}, +{0x60,0x03000016}, +{0x64,0x03001fff}, +{0x68,0x821063ff}, +{0x6c,0x9a047fe8}, +{0x70,0xa0102000}, +{0x74,0xd8034000}, +{0x78,0x80a30001}, +{0x7c,0x16800004}, +{0xf0,0x55}, +{0x00,0x9a036004}, +{0x04,0x8210000c}, +{0x08,0xb0100010}, +{0x0c,0xa0042001}, +{0x10,0x80a42004}, +{0x14,0x24bffff9}, +{0x18,0xd8034000}, +{0x1c,0x81c7e008}, +{0x20,0x81e80000}, +{0x24,0x9de3bf98}, +{0x28,0x833e201f}, +{0x2c,0xd0002320}, +{0x30,0x82204018}, +{0x34,0x80a22000}, +{0x38,0x02800015}, +{0x3c,0x9b30601f}, +{0x40,0x033fc000}, +{0x44,0xa0106020}, +{0x48,0xc200231c}, +{0x4c,0x80a00001}, +{0x50,0x82402000}, +{0x54,0x8088400d}, +{0x58,0xc2002318}, +{0x5c,0x02800009}, +{0x60,0xb01e0001}, +{0x64,0x80a00001}, +{0x68,0x82603fff}, +{0x6c,0x7ffffc6b}, +{0x70,0xc2240000}, +{0x74,0xc2002318}, +{0x78,0x10800005}, +{0x7c,0xc2240000}, +{0xf0,0x56}, +{0x00,0x033fc000}, +{0x04,0x82106020}, +{0x08,0xf0204000}, +{0x0c,0x81c7e008}, +{0x10,0x81e80000}, +{0x14,0x9de3bf98}, +{0x18,0x7ffffc69}, +{0x1c,0x01000000}, +{0x20,0x033fc040}, +{0x24,0xe2002500}, +{0x28,0x8210600c}, +{0x2c,0x80a46058}, +{0x30,0x08800013}, +{0x34,0xc0204000}, +{0x38,0xc0202584}, +{0x3c,0xa0102000}, +{0x40,0x832c2002}, +{0x44,0xc2006f04}, +{0x48,0x80a06000}, +{0x4c,0x02800074}, +{0x50,0xa0042001}, +{0x54,0x9fc04000}, +{0x58,0x01000000}, +{0x5c,0xc2002584}, +{0x60,0x80a06000}, +{0x64,0x1280006e}, +{0x68,0x80a4203b}, +{0x6c,0x24bffff6}, +{0x70,0x832c2002}, +{0x74,0x1080006b}, +{0x78,0xc2002500}, +{0x7c,0x80a46000}, +{0xf0,0x57}, +{0x00,0x1280000f}, +{0x04,0x80a46014}, +{0x08,0xc2002ff4}, +{0x0c,0x9fc04000}, +{0x10,0x01000000}, +{0x14,0x7ffffa76}, +{0x18,0x90102000}, +{0x1c,0xc24822e5}, +{0x20,0x80a06000}, +{0x24,0x3280005f}, +{0x28,0xc2002500}, +{0x2c,0x7ffffa5f}, +{0x30,0x90102001}, +{0x34,0x1080005b}, +{0x38,0xc2002500}, +{0x3c,0x1880000a}, +{0x40,0x80a46015}, +{0x44,0x808c6001}, +{0x48,0x32800056}, +{0x4c,0xc2002500}, +{0x50,0x90047ffe}, +{0x54,0x7ffffa19}, +{0x58,0x91322001}, +{0x5c,0x10800051}, +{0x60,0xc2002500}, +{0x64,0x18800011}, +{0x68,0x80a46018}, +{0x6c,0x033fc180}, +{0x70,0xda0025b0}, +{0x74,0x82106038}, +{0x78,0xda204000}, +{0x7c,0x033fc200}, +{0xf0,0x58}, +{0x00,0xda00232c}, +{0x04,0x82106074}, +{0x08,0xda204000}, +{0x0c,0x7ffffa47}, +{0x10,0x90102000}, +{0x14,0xc2002ff4}, +{0x18,0x9fc04000}, +{0x1c,0x01000000}, +{0x20,0x10800040}, +{0x24,0xc2002500}, +{0x28,0x1880000b}, +{0x2c,0x80a46058}, +{0x30,0x11000018}, +{0x34,0x7ffffe94}, +{0x38,0x90122368}, +{0x3c,0x1b000017}, +{0x40,0x033fc200}, +{0x44,0x9a1363ff}, +{0x48,0x82106070}, +{0x4c,0x10800034}, +{0x50,0xda204000}, +{0x54,0x38800033}, +{0x58,0xc2002500}, +{0x5c,0xc2002fe8}, +{0x60,0x80a06000}, +{0x64,0x02800004}, +{0x68,0x01000000}, +{0x6c,0x9fc04000}, +{0x70,0x01000000}, +{0x74,0x7ffff983}, +{0x78,0xa0102000}, +{0x7c,0x15000018}, +{0xf0,0x59}, +{0x00,0x9612a368}, +{0x04,0x82040010}, +{0x08,0x992c2002}, +{0x0c,0xda120001}, +{0x10,0xc203000b}, +{0x14,0x8200400d}, +{0x18,0xa0042001}, +{0x1c,0x80a4202f}, +{0x20,0x04bffff9}, +{0x24,0xc223000b}, +{0x28,0x80a46058}, +{0x2c,0x3280001d}, +{0x30,0xc2002500}, +{0x34,0x9012a368}, +{0x38,0x7ffffe7b}, +{0x3c,0x92102040}, +{0x40,0x1b000017}, +{0x44,0xa0136324}, +{0x48,0xc2040000}, +{0x4c,0x90004001}, +{0x50,0x90020001}, +{0x54,0x033fc200}, +{0x58,0x82106070}, +{0x5c,0x9a13638c}, +{0x60,0xd8002298}, +{0x64,0x912a2005}, +{0x68,0xd8204000}, +{0x6c,0x9002000d}, +{0x70,0x921025b0}, +{0x74,0x7ffffcf5}, +{0x78,0x94102018}, +{0x7c,0xc2040000}, +{0xf0,0x5a}, +{0x00,0x80a06001}, +{0x04,0x32800007}, +{0x08,0xc2002500}, +{0x0c,0xa2103fff}, +{0x10,0xc0240000}, +{0x14,0x7ffffa99}, +{0x18,0xe2202500}, +{0x1c,0xc2002500}, +{0x20,0x80a44001}, +{0x24,0x1280000f}, +{0x28,0x80a47fff}, +{0x2c,0x12800004}, +{0x30,0x031fffff}, +{0x34,0x10800007}, +{0x38,0xa2102000}, +{0x3c,0x821063f0}, +{0x40,0x80a44001}, +{0x44,0x38800003}, +{0x48,0x23040000}, +{0x4c,0xa2046001}, +{0x50,0x033fc180}, +{0x54,0x82106034}, +{0x58,0xe2204000}, +{0x5c,0xe2202500}, +{0x60,0x81c7e008}, +{0x64,0x81e80000}, +{0x68,0x81c3e008}, +{0x6c,0x01000000}, +{0x70,0x9de3bf98}, +{0x74,0x94100018}, +{0x78,0xb0063fff}, +{0x7c,0x9802a001}, +{0xf0,0x5b}, +{0x00,0x9210001a}, +{0x04,0x80a6000c}, +{0x08,0x1480001d}, +{0x0c,0x9e102000}, +{0x10,0x03000019}, +{0x14,0x96106328}, +{0x18,0xb72be002}, +{0x1c,0x80a62000}, +{0x20,0x06800013}, +{0x24,0xc026401b}, +{0x28,0xc2002300}, +{0x2c,0x80a60001}, +{0x30,0x3a800010}, +{0x34,0xb0062001}, +{0x38,0x832e2003}, +{0x3c,0xb800400b}, +{0x40,0xb4102001}, +{0x44,0xc2070000}, +{0x48,0xba380001}, +{0x4c,0xbb3f601f}, +{0x50,0x8208401d}, +{0x54,0xfa06401b}, +{0x58,0xba074001}, +{0x5c,0xfa26401b}, +{0x60,0xb486bfff}, +{0x64,0x1cbffff8}, +{0x68,0xb8072004}, +{0x6c,0xb0062001}, +{0x70,0x80a6000c}, +{0x74,0x04bfffe9}, +{0x78,0x9e03e001}, +{0x7c,0xf6066004}, +{0xf0,0x5c}, +{0x00,0xf8064000}, +{0x04,0x80a6c01c}, +{0x08,0x24800096}, +{0x0c,0xb0102000}, +{0x10,0xf2066008}, +{0x14,0x80a6c019}, +{0x18,0x26800092}, +{0x1c,0xb0102000}, +{0x20,0x03000017}, +{0x24,0x8210632c}, +{0x28,0xc2004000}, +{0x2c,0x80a06000}, +{0x30,0x02800004}, +{0x34,0xde1023b6}, +{0x38,0xc20822b6}, +{0x3c,0x9e03c001}, +{0x40,0xba5bc009}, +{0x44,0x833f601f}, +{0x48,0x83306019}, +{0x4c,0xba074001}, +{0x50,0x9f3f6007}, +{0x54,0xd8002470}, +{0x58,0xba5bc00c}, +{0x5c,0x833f601f}, +{0x60,0x83306018}, +{0x64,0xba074001}, +{0x68,0xbb3f6008}, +{0x6c,0x80a6c01d}, +{0x70,0x0680007c}, +{0x74,0xb0102000}, +{0x78,0x80a2a000}, +{0x7c,0x32800008}, +{0xf0,0x5d}, +{0x00,0xc2002300}, +{0x04,0x8226c019}, +{0x08,0x80a64001}, +{0x0c,0x16800011}, +{0x10,0xb4100019}, +{0x14,0x1080000f}, +{0x18,0xb4100001}, +{0x1c,0x82007fff}, +{0x20,0x80a28001}, +{0x24,0x12800008}, +{0x28,0x80a70019}, +{0x2c,0xb426c01c}, +{0x30,0x80a6801c}, +{0x34,0x16800008}, +{0x38,0x80a70019}, +{0x3c,0x10800006}, +{0x40,0xb410001c}, +{0x44,0x06800003}, +{0x48,0xb4100019}, +{0x4c,0xb410001c}, +{0x50,0x80a70019}, +{0x54,0xb406801b}, +{0x58,0x14800003}, +{0x5c,0x9626c019}, +{0x60,0x9626c01c}, +{0x64,0xba5bc00c}, +{0x68,0x833f601f}, +{0x6c,0x83306019}, +{0x70,0xba074001}, +{0x74,0xb0102003}, +{0x78,0x80a62003}, +{0x7c,0x12800004}, +{0xf0,0x5e}, +{0x00,0x80a62002}, +{0x04,0x10800004}, +{0x08,0x9a10000f}, +{0x0c,0x22800002}, +{0x10,0x9b3f6007}, +{0x14,0x8333601f}, +{0x18,0x82034001}, +{0x1c,0x80a6800d}, +{0x20,0x04800005}, +{0x24,0x83386001}, +{0x28,0x80a2c001}, +{0x2c,0x34800006}, +{0x30,0xc2002300}, +{0x34,0xb0863fff}, +{0x38,0x1cbffff1}, +{0x3c,0x80a62003}, +{0x40,0xc2002300}, +{0x44,0x82007fff}, +{0x48,0x80a28001}, +{0x4c,0x12800042}, +{0x50,0x80a62001}, +{0x54,0xb8102000}, +{0x58,0xf2002304}, +{0x5c,0x80a70019}, +{0x60,0x1a80000e}, +{0x64,0xb6102000}, +{0x68,0x03000019}, +{0x6c,0x981063c0}, +{0x70,0xbb2f2002}, +{0x74,0xc207400c}, +{0x78,0x80a06000}, +{0x7c,0x04800004}, +{0xf0,0x5f}, +{0x00,0xb8072001}, +{0x04,0xc207400c}, +{0x08,0xb606c001}, +{0x0c,0x80a70019}, +{0x10,0x0abffff9}, +{0x14,0xbb2f2002}, +{0x18,0xc20021d8}, +{0x1c,0x825ec001}, +{0x20,0xbb38601f}, +{0x24,0xbb376019}, +{0x28,0x8200401d}, +{0x2c,0x83386007}, +{0x30,0x9e03c001}, +{0x34,0xb8102003}, +{0x38,0x80a72003}, +{0x3c,0x12800004}, +{0x40,0x80a72002}, +{0x44,0x1080000a}, +{0x48,0x9a10000f}, +{0x4c,0x32800009}, +{0x50,0x8333601f}, +{0x54,0xfa002470}, +{0x58,0xba5bc01d}, +{0x5c,0x833f601f}, +{0x60,0x83306019}, +{0x64,0xba074001}, +{0x68,0x9b3f6007}, +{0x6c,0x8333601f}, +{0x70,0x82034001}, +{0x74,0x80a6800d}, +{0x78,0x04800005}, +{0x7c,0x83386001}, +{0xf0,0x60}, +{0x00,0x80a2c001}, +{0x04,0x14800006}, +{0x08,0x80a62001}, +{0x0c,0xb8873fff}, +{0x10,0x1cbfffeb}, +{0x14,0x80a72003}, +{0x18,0x80a62001}, +{0x1c,0x14800003}, +{0x20,0xba102001}, +{0x24,0xba102000}, +{0x28,0x80a72001}, +{0x2c,0x04800003}, +{0x30,0x82102001}, +{0x34,0x82102000}, +{0x38,0x808f4001}, +{0x3c,0x02800006}, +{0x40,0x80a62001}, +{0x44,0x03000048}, +{0x48,0x82106345}, +{0x4c,0x10800004}, +{0x50,0xc22026f8}, +{0x54,0x14800003}, +{0x58,0x01000000}, +{0x5c,0xb0102000}, +{0x60,0x81c7e008}, +{0x64,0x81e80000}, +{0x68,0x9de3bf88}, +{0x6c,0x821026a0}, +{0x70,0xc2202580}, +{0x74,0xc02026f8}, +{0x78,0x90102000}, +{0x7c,0x96102000}, +{0xf0,0x61}, +{0x00,0x832ae002}, +{0x04,0x9602e001}, +{0x08,0xc02067e0}, +{0x0c,0xc0206720}, +{0x10,0x80a2e003}, +{0x14,0x04bffffb}, +{0x18,0xc0206730}, +{0x1c,0x03000018}, +{0x20,0xc0202514}, +{0x24,0x9a1062a8}, +{0x28,0xa0102000}, +{0x2c,0x832c2002}, +{0x30,0xa0042001}, +{0x34,0x80a42019}, +{0x38,0x04bffffd}, +{0x3c,0xc020400d}, +{0x40,0xa0102000}, +{0x44,0xc2002300}, +{0x48,0x80a40001}, +{0x4c,0x1a800018}, +{0x50,0x03000018}, +{0x54,0x921062ac}, +{0x58,0x82006400}, +{0x5c,0x9e106328}, +{0x60,0x832c2003}, +{0x64,0x9800400f}, +{0x68,0x952c2002}, +{0x6c,0x96102001}, +{0x70,0xc2030000}, +{0x74,0x9a380001}, +{0x78,0x9b3b601f}, +{0x7c,0x8208400d}, +{0xf0,0x62}, +{0x00,0xda028009}, +{0x04,0x9a034001}, +{0x08,0xda228009}, +{0x0c,0x9682ffff}, +{0x10,0x1cbffff8}, +{0x14,0x98032004}, +{0x18,0xa0042001}, +{0x1c,0xc2002300}, +{0x20,0x80a40001}, +{0x24,0x0abffff0}, +{0x28,0x832c2003}, +{0x2c,0xa0102001}, +{0x30,0xd8002300}, +{0x34,0x80a4000c}, +{0x38,0x1a80000f}, +{0x3c,0x03000018}, +{0x40,0x941062ac}, +{0x44,0x961062a8}, +{0x48,0x832c2002}, +{0x4c,0xda00400a}, +{0x50,0xc200400b}, +{0x54,0x8200400d}, +{0x58,0x80a04008}, +{0x5c,0x04800003}, +{0x60,0xa0042001}, +{0x64,0x90100001}, +{0x68,0x80a4000c}, +{0x6c,0x0abffff8}, +{0x70,0x832c2002}, +{0x74,0x1b000017}, +{0x78,0x82136324}, +{0x7c,0xc2004000}, +{0xf0,0x63}, +{0x00,0x80a06001}, +{0x04,0x1280001f}, +{0x08,0x82136388}, +{0x0c,0x03000018}, +{0x10,0x921062ac}, +{0x14,0x98102000}, +{0x18,0x96102001}, +{0x1c,0x941062a8}, +{0x20,0x832ae002}, +{0x24,0xda004009}, +{0x28,0xc200400a}, +{0x2c,0x8200400d}, +{0x30,0x80a0400c}, +{0x34,0x04800003}, +{0x38,0x9602e001}, +{0x3c,0x98100001}, +{0x40,0x80a2e015}, +{0x44,0x04bffff8}, +{0x48,0x832ae002}, +{0x4c,0xc20022b0}, +{0x50,0x80a30001}, +{0x54,0x03000017}, +{0x58,0x8210637c}, +{0x5c,0x088000f6}, +{0x60,0xd8204000}, +{0x64,0xda002514}, +{0x68,0x03004d40}, +{0x6c,0x9a036001}, +{0x70,0x821060e3}, +{0x74,0xc2202720}, +{0x78,0x108000ef}, +{0x7c,0xda202514}, +{0xf0,0x64}, +{0x00,0xc2004000}, +{0x04,0x80a06001}, +{0x08,0x1280000e}, +{0x0c,0xa0102000}, +{0x10,0xc21022ce}, +{0x14,0x80a20001}, +{0x18,0x04800004}, +{0x1c,0x9a13632c}, +{0x20,0x10800006}, +{0x24,0x8210203c}, +{0x28,0xc2034000}, +{0x2c,0x80a06000}, +{0x30,0x04800003}, +{0x34,0x82007fff}, +{0x38,0xc2234000}, +{0x3c,0xa0102000}, +{0x40,0xc2002300}, +{0x44,0x80a40001}, +{0x48,0x1a8000b4}, +{0x4c,0xa4043fff}, +{0x50,0x92042002}, +{0x54,0x80a48009}, +{0x58,0x9a102001}, +{0x5c,0x94102001}, +{0x60,0x16800018}, +{0x64,0x98100012}, +{0x68,0x03000019}, +{0x6c,0x9e10632c}, +{0x70,0x90106328}, +{0x74,0x80a32000}, +{0x78,0x2680000f}, +{0x7c,0x98032001}, +{0xf0,0x65}, +{0x00,0xc2002300}, +{0x04,0x80a30001}, +{0x08,0x1a80000a}, +{0x0c,0x972b2003}, +{0x10,0xc202c008}, +{0x14,0x80a06000}, +{0x18,0x34800002}, +{0x1c,0x9a034001}, +{0x20,0xc202c00f}, +{0x24,0x80a06000}, +{0x28,0x34800002}, +{0x2c,0x94028001}, +{0x30,0x98032001}, +{0x34,0x80a30009}, +{0x38,0x06bffff0}, +{0x3c,0x80a32000}, +{0x40,0x9a03400a}, +{0x44,0x832aa008}, +{0x48,0x9938601f}, +{0x4c,0x81832000}, +{0x50,0x01000000}, +{0x54,0x01000000}, +{0x58,0x01000000}, +{0x5c,0x8278400d}, +{0x60,0x94007f80}, +{0x64,0x833aa01f}, +{0x68,0x941a8001}, +{0x6c,0x94228001}, +{0x70,0x82102080}, +{0x74,0x9420400a}, +{0x78,0x8238000a}, +{0x7c,0x8338601f}, +{0xf0,0x66}, +{0x00,0x940a8001}, +{0x04,0xda082479}, +{0x08,0x9a5a800d}, +{0x0c,0x833b601f}, +{0x10,0x83306019}, +{0x14,0x9a034001}, +{0x18,0x9b3b6007}, +{0x1c,0xc2102548}, +{0x20,0x80886001}, +{0x24,0x0280000a}, +{0x28,0x9403400d}, +{0x2c,0xc2002558}, +{0x30,0x80a06000}, +{0x34,0x32800007}, +{0x38,0x9402a080}, +{0x3c,0x90100010}, +{0x40,0x9207bfe8}, +{0x44,0x10800005}, +{0x48,0xd410218c}, +{0x4c,0x9402a080}, +{0x50,0x90100010}, +{0x54,0x9207bfe8}, +{0x58,0xc2002fdc}, +{0x5c,0x9fc04000}, +{0x60,0x01000000}, +{0x64,0xa2922000}, +{0x68,0x22bfffb6}, +{0x6c,0xa0042001}, +{0x70,0xda07bfec}, +{0x74,0xc207bfe8}, +{0x78,0x8200400d}, +{0x7c,0xda07bff0}, +{0xf0,0x67}, +{0x00,0xa600400d}, +{0x04,0x96102000}, +{0x08,0x9b2ae002}, +{0x0c,0x9602e001}, +{0x10,0xc2036840}, +{0x14,0x80a2e003}, +{0x18,0x04bffffc}, +{0x1c,0xc2236850}, +{0x20,0x1b000019}, +{0x24,0x992c2003}, +{0x28,0x92136328}, +{0x2c,0xc2030009}, +{0x30,0xc2202840}, +{0x34,0x9a13632c}, +{0x38,0xc203000d}, +{0x3c,0x94042001}, +{0x40,0x96100012}, +{0x44,0xc2202844}, +{0x48,0xc0202848}, +{0x4c,0x80a4800a}, +{0x50,0x14800017}, +{0x54,0xc020284c}, +{0x58,0x90100009}, +{0x5c,0x9210000d}, +{0x60,0x80a2e000}, +{0x64,0x2680000f}, +{0x68,0x9602e001}, +{0x6c,0xc2002300}, +{0x70,0x80a2c001}, +{0x74,0x1a80000a}, +{0x78,0x992ae003}, +{0x7c,0xda030008}, +{0xf0,0x68}, +{0x00,0xc2002848}, +{0x04,0x8200400d}, +{0x08,0xc2202848}, +{0x0c,0xda030009}, +{0x10,0xc200284c}, +{0x14,0x8200400d}, +{0x18,0xc220284c}, +{0x1c,0x9602e001}, +{0x20,0x80a2c00a}, +{0x24,0x04bffff0}, +{0x28,0x80a2e000}, +{0x2c,0xd0002514}, +{0x30,0x80a22004}, +{0x34,0x1280000b}, +{0x38,0x80a46001}, +{0x3c,0xc2002fe4}, +{0x40,0x80a06000}, +{0x44,0x02800007}, +{0x48,0x80a46001}, +{0x4c,0x9fc04000}, +{0x50,0x90100013}, +{0x54,0x80a23fff}, +{0x58,0x0280002e}, +{0x5c,0x80a46001}, +{0x60,0x12800007}, +{0x64,0x80a46002}, +{0x68,0x03000008}, +{0x6c,0x82040001}, +{0x70,0x9b2a2002}, +{0x74,0x10800009}, +{0x78,0xc2236720}, +{0x7c,0x12800006}, +{0xf0,0x69}, +{0x00,0x9b2a2002}, +{0x04,0x03000010}, +{0x08,0x82040001}, +{0x0c,0x10800003}, +{0x10,0xc2236720}, +{0x14,0xe0236720}, +{0x18,0xda002300}, +{0x1c,0x83336001}, +{0x20,0x80a40001}, +{0x24,0x1a800005}, +{0x28,0x03000018}, +{0x2c,0x821062b0}, +{0x30,0x10800005}, +{0x34,0xda004000}, +{0x38,0x9b2b6002}, +{0x3c,0x821062a4}, +{0x40,0xda034001}, +{0x44,0x0300003f}, +{0x48,0x821063ff}, +{0x4c,0x820b4001}, +{0x50,0x9b2ce010}, +{0x54,0x992a2002}, +{0x58,0x9a134001}, +{0x5c,0xc2032730}, +{0x60,0x8210400d}, +{0x64,0xc2232730}, +{0x68,0xe02327e0}, +{0x6c,0xc2002514}, +{0x70,0x82006001}, +{0x74,0x80a06004}, +{0x78,0x12800006}, +{0x7c,0xc2202514}, +{0xf0,0x6a}, +{0x00,0xc2002fe4}, +{0x04,0x80a06000}, +{0x08,0x22800005}, +{0x0c,0xc2002514}, +{0x10,0x10bfff4c}, +{0x14,0xa0042001}, +{0x18,0xc2002514}, +{0x1c,0x80a06000}, +{0x20,0x3280000c}, +{0x24,0xc2002520}, +{0x28,0x96102000}, +{0x2c,0x832ae002}, +{0x30,0x9602e001}, +{0x34,0xc0206850}, +{0x38,0x80a2e003}, +{0x3c,0x04bffffc}, +{0x40,0xc0206840}, +{0x44,0xc20026a0}, +{0x48,0x10800007}, +{0x4c,0x82087bff}, +{0x50,0x80a06000}, +{0x54,0x22800006}, +{0x58,0x96102000}, +{0x5c,0xc20026a0}, +{0x60,0x82106400}, +{0x64,0xc22026a0}, +{0x68,0x96102000}, +{0x6c,0xd4002350}, +{0x70,0x992ae002}, +{0x74,0xda032850}, +{0x78,0x9a5b400a}, +{0x7c,0x833b601f}, +{0xf0,0x6b}, +{0x00,0x83306019}, +{0x04,0x9a034001}, +{0x08,0xc2032840}, +{0x0c,0x9b3b6007}, +{0x10,0x80a0400d}, +{0x14,0x16800005}, +{0x18,0x9602e001}, +{0x1c,0xc20026a0}, +{0x20,0x82106400}, +{0x24,0xc22026a0}, +{0x28,0x80a2e003}, +{0x2c,0x04bffff2}, +{0x30,0x992ae002}, +{0x34,0x1b000017}, +{0x38,0x82136388}, +{0x3c,0xc2004000}, +{0x40,0x80a06001}, +{0x44,0x12800045}, +{0x48,0x82136324}, +{0x4c,0xc2004000}, +{0x50,0x80a06001}, +{0x54,0x02800041}, +{0x58,0x9e102000}, +{0x5c,0xda002514}, +{0x60,0xc02026e0}, +{0x64,0x80a3c00d}, +{0x68,0xa4102000}, +{0x6c,0xa0102000}, +{0x70,0x1a80000a}, +{0x74,0x92102000}, +{0x78,0x98102001}, +{0x7c,0x832a6002}, +{0xf0,0x6c}, +{0x00,0xc20067e0}, +{0x04,0x832b0001}, +{0x08,0x92026001}, +{0x0c,0x80a2400d}, +{0x10,0x0abffffb}, +{0x14,0xa4148001}, +{0x18,0x92102000}, +{0x1c,0xe2002514}, +{0x20,0x80a24011}, +{0x24,0x1a800026}, +{0x28,0x03000019}, +{0x2c,0xa810632c}, +{0x30,0xa6106328}, +{0x34,0x832a6002}, +{0x38,0xc20067e0}, +{0x3c,0x94007ffd}, +{0x40,0x90102001}, +{0x44,0x8238000a}, +{0x48,0x9930601f}, +{0x4c,0x833c800a}, +{0x50,0x80886001}, +{0x54,0x32800014}, +{0x58,0x90823fff}, +{0x5c,0xc2002300}, +{0x60,0x80a28001}, +{0x64,0x82402000}, +{0x68,0x8088400c}, +{0x6c,0x0280000d}, +{0x70,0x9b2aa003}, +{0x74,0xd8034013}, +{0x78,0xd6034014}, +{0x7c,0x8238000c}, +{0xf0,0x6d}, +{0x00,0x9a38000b}, +{0x04,0x8338601f}, +{0x08,0x980b0001}, +{0x0c,0x9b3b601f}, +{0x10,0x9804000c}, +{0x14,0x960ac00d}, +{0x18,0xa003000b}, +{0x1c,0x9e03e001}, +{0x20,0x90823fff}, +{0x24,0x1cbfffe8}, +{0x28,0x9402a006}, +{0x2c,0x92026001}, +{0x30,0x80a24011}, +{0x34,0x0abfffe1}, +{0x38,0x832a6002}, +{0x3c,0x9b3c201f}, +{0x40,0x81836000}, +{0x44,0x01000000}, +{0x48,0x01000000}, +{0x4c,0x01000000}, +{0x50,0x827c000f}, +{0x54,0xc22026e0}, +{0x58,0x81c7e008}, +{0x5c,0x81e80000}, +{0x60,0x031fffff}, +{0x64,0x981063ff}, +{0x68,0x9a102000}, +{0x6c,0x832b6002}, +{0x70,0xc2106730}, +{0x74,0x80a0400c}, +{0x78,0x36800005}, +{0x7c,0x9a036001}, +{0xf0,0x6e}, +{0x00,0x98100001}, +{0x04,0x9610000d}, +{0x08,0x9a036001}, +{0x0c,0x80a36003}, +{0x10,0x04bffff8}, +{0x14,0x832b6002}, +{0x18,0x80a30008}, +{0x1c,0x1680000a}, +{0x20,0x90103fff}, +{0x24,0x832ae002}, +{0x28,0xc02067e0}, +{0x2c,0xc0206720}, +{0x30,0xc0206730}, +{0x34,0xc2002514}, +{0x38,0x82007fff}, +{0x3c,0xc2202514}, +{0x40,0x9010000b}, +{0x44,0x81c3e008}, +{0x48,0x01000000}, +{0x4c,0x9de3bf50}, +{0x50,0xc20022d4}, +{0x54,0x80886010}, +{0x58,0xa0102000}, +{0x5c,0xa2102000}, +{0x60,0x02800009}, +{0x64,0x972e2002}, +{0x68,0xc202e720}, +{0x6c,0xda002324}, +{0x70,0x82086fff}, +{0x74,0x8258400d}, +{0x78,0x8330600a}, +{0x7c,0x1080000e}, +{0xf0,0x6f}, +{0x00,0xc227bff0}, +{0x04,0xc212e720}, +{0x08,0xda002328}, +{0x0c,0x82086fff}, +{0x10,0x8258400d}, +{0x14,0x8330600b}, +{0x18,0xc227bff0}, +{0x1c,0xc202e720}, +{0x20,0x82086fff}, +{0x24,0xa3306005}, +{0x28,0xa0100011}, +{0x2c,0x9b2c6005}, +{0x30,0xa220400d}, +{0x34,0xa407bff8}, +{0x38,0x96102000}, +{0x3c,0x98100012}, +{0x40,0x8202c00b}, +{0x44,0xda5061c0}, +{0x48,0xc25061b0}, +{0x4c,0xc2233fd8}, +{0x50,0xda233fb8}, +{0x54,0x9602e001}, +{0x58,0x80a2e007}, +{0x5c,0x04bffff9}, +{0x60,0x98032004}, +{0x64,0x96102008}, +{0x68,0x9007bfd0}, +{0x6c,0x9207bfb0}, +{0x70,0x7ffff956}, +{0x74,0xd407bff0}, +{0x78,0xd6502456}, +{0x7c,0x80a2e000}, +{0xf0,0x70}, +{0x00,0x02800032}, +{0x04,0x82380008}, +{0x08,0xc2002328}, +{0x0c,0x8220400b}, +{0x10,0x80a20001}, +{0x14,0x28800016}, +{0x18,0xd6502454}, +{0x1c,0xd84c2440}, +{0x20,0xc24c2441}, +{0x24,0x8220400c}, +{0x28,0x82584011}, +{0x2c,0x9b38601f}, +{0x30,0x9b33601b}, +{0x34,0x8200400d}, +{0x38,0x83386005}, +{0x3c,0x9a030001}, +{0x40,0x8222000b}, +{0x44,0x8258400b}, +{0x48,0x9a22c00d}, +{0x4c,0x9938601f}, +{0x50,0x81832000}, +{0x54,0x01000000}, +{0x58,0x01000000}, +{0x5c,0x01000000}, +{0x60,0x8278400d}, +{0x64,0x9002c001}, +{0x68,0xd6502454}, +{0x6c,0x80a2000b}, +{0x70,0x16800016}, +{0x74,0x82380008}, +{0x78,0xd84c245c}, +{0x7c,0xc24c245d}, +{0xf0,0x71}, +{0x00,0x8220400c}, +{0x04,0x82584011}, +{0x08,0x9b38601f}, +{0x0c,0x9b33601b}, +{0x10,0x8200400d}, +{0x14,0x83386005}, +{0x18,0x9a030001}, +{0x1c,0x8222c008}, +{0x20,0x8258400b}, +{0x24,0x9a22c00d}, +{0x28,0x9938601f}, +{0x2c,0x81832000}, +{0x30,0x01000000}, +{0x34,0x01000000}, +{0x38,0x01000000}, +{0x3c,0x8278400d}, +{0x40,0x9022c001}, +{0x44,0x82380008}, +{0x48,0x8338601f}, +{0x4c,0x900a0001}, +{0x50,0xc2002328}, +{0x54,0x82007fff}, +{0x58,0x80a20001}, +{0x5c,0x38800002}, +{0x60,0x90100001}, +{0x64,0xd024bff8}, +{0x68,0xc20022d4}, +{0x6c,0x80886010}, +{0x70,0x972e2002}, +{0x74,0x0280000f}, +{0x78,0xc207bff0}, +{0x7c,0x9b28600a}, +{0xf0,0x72}, +{0x00,0x81800000}, +{0x04,0xc2002324}, +{0x08,0x01000000}, +{0x0c,0x01000000}, +{0x10,0x82734001}, +{0x14,0x9a100001}, +{0x18,0xc202e720}, +{0x1c,0x9a0b6fff}, +{0x20,0x82087000}, +{0x24,0x8210400d}, +{0x28,0x1080000f}, +{0x2c,0xc222e720}, +{0x30,0x8328600b}, +{0x34,0x81800000}, +{0x38,0xd8002328}, +{0x3c,0x01000000}, +{0x40,0x01000000}, +{0x44,0x9870400c}, +{0x48,0x820b2fff}, +{0x4c,0xd802e720}, +{0x50,0x1b03ffc0}, +{0x54,0x9a2b000d}, +{0x58,0x83286010}, +{0x5c,0x9a134001}, +{0x60,0xda22e720}, +{0x64,0x81c7e008}, +{0x68,0x81e80000}, +{0x6c,0x03169696}, +{0x70,0xda002180}, +{0x74,0x8210625a}, +{0x78,0x80a34001}, +{0x7c,0x94102000}, +{0xf0,0x73}, +{0x00,0x12800006}, +{0x04,0x96102000}, +{0x08,0x033fc180}, +{0x0c,0x82106030}, +{0x10,0x10800022}, +{0x14,0xda204000}, +{0x18,0xc202c000}, +{0x1c,0x9602e004}, +{0x20,0x80a2e4ff}, +{0x24,0x08bffffd}, +{0x28,0x94028001}, +{0x2c,0x96102d00}, +{0x30,0xd2002ff8}, +{0x34,0x03000019}, +{0x38,0x80a2c009}, +{0x3c,0x1a80000b}, +{0x40,0x901063ff}, +{0x44,0xd802c000}, +{0x48,0x9602e004}, +{0x4c,0x80a2c009}, +{0x50,0x9a402000}, +{0x54,0x80a2000b}, +{0x58,0x82603fff}, +{0x5c,0x808b4001}, +{0x60,0x12bffff9}, +{0x64,0x9402800c}, +{0x68,0xc2002200}, +{0x6c,0x94228001}, +{0x70,0x03169696}, +{0x74,0x8210625a}, +{0x78,0x80a28001}, +{0x7c,0x033fc180}, +{0xf0,0x74}, +{0x00,0x82106030}, +{0x04,0x02800005}, +{0x08,0xd4204000}, +{0x0c,0x0300000a}, +{0x10,0x81c062a4}, +{0x14,0x90102001}, +{0x18,0x01000000}, +{0x1c,0x81c3e008}, +{0x20,0x01000000}, +{0x24,0x1500003f}, +{0x28,0xd8002508}, +{0x2c,0x8212a300}, +{0x30,0x808b3f00}, +{0x34,0x02800016}, +{0x38,0x9a0b0001}, +{0x3c,0xc200254c}, +{0x40,0x8210400d}, +{0x44,0xc220254c}, +{0x48,0x1b3fc000}, +{0x4c,0xc2002500}, +{0x50,0x960b000d}, +{0x54,0x80a06058}, +{0x58,0xc0202508}, +{0x5c,0x0880000c}, +{0x60,0x033fffc0}, +{0x64,0x9a0b0001}, +{0x68,0x03168000}, +{0x6c,0x80a2c001}, +{0x70,0x12800007}, +{0x74,0x9412a3ff}, +{0x78,0xc2002548}, +{0x7c,0x8208400a}, +{0xf0,0x75}, +{0x00,0x8210400d}, +{0x04,0xc2202548}, +{0x08,0xc02026e4}, +{0x0c,0x81c3e008}, +{0x10,0x01000000}, +{0x14,0x9de3bf88}, +{0x18,0x7ffff5fa}, +{0x1c,0xae102001}, +{0x20,0xaa100008}, +{0x24,0xc027bfe8}, +{0x28,0xc027bfec}, +{0x2c,0x7ffff9b4}, +{0x30,0xc027bff0}, +{0x34,0x80a22000}, +{0x38,0x0280000d}, +{0x3c,0xba102000}, +{0x40,0x03000017}, +{0x44,0x82106324}, +{0x48,0xc2004000}, +{0x4c,0x80a06000}, +{0x50,0x12800005}, +{0x54,0x82102040}, +{0x58,0xc227bfec}, +{0x5c,0x10800007}, +{0x60,0xc227bfe8}, +{0x64,0x10800005}, +{0x68,0xc227bff0}, +{0x6c,0x82102008}, +{0x70,0xc227bfe8}, +{0x74,0xba102001}, +{0x78,0xa4102000}, +{0x7c,0xa8102000}, +{0xf0,0x76}, +{0x00,0xa6102000}, +{0x04,0x23000018}, +{0x08,0xa12ca002}, +{0x0c,0x8214604c}, +{0x10,0xc2040001}, +{0x14,0x80a06000}, +{0x18,0x12800006}, +{0x1c,0xac07bff8}, +{0x20,0x90146068}, +{0x24,0x7ffffad8}, +{0x28,0x90050008}, +{0x2c,0xac07bff8}, +{0x30,0x82040016}, +{0x34,0xc2007ff0}, +{0x38,0x80a06000}, +{0x3c,0x22800014}, +{0x40,0xa404a001}, +{0x44,0x90100011}, +{0x48,0x96102000}, +{0x4c,0x94146068}, +{0x50,0x98100013}, +{0x54,0x8202c00b}, +{0x58,0xda154001}, +{0x5c,0xc203000a}, +{0x60,0x8200400d}, +{0x64,0xc223000a}, +{0x68,0x9602e001}, +{0x6c,0x80a2e02f}, +{0x70,0x04bffff9}, +{0x74,0x98032004}, +{0x78,0x9a12204c}, +{0x7c,0xc204000d}, +{0xf0,0x77}, +{0x00,0x82006001}, +{0x04,0xc224000d}, +{0x08,0xa404a001}, +{0x0c,0xa604e0c0}, +{0x10,0x80a4a002}, +{0x14,0x04bfffdc}, +{0x18,0xa80520c0}, +{0x1c,0xa4102000}, +{0x20,0xa2102000}, +{0x24,0xa12ca002}, +{0x28,0x82040016}, +{0x2c,0xda007ff0}, +{0x30,0x80a36000}, +{0x34,0x2280002f}, +{0x38,0xa404a001}, +{0x3c,0x11000018}, +{0x40,0x9812204c}, +{0x44,0xc204000c}, +{0x48,0x80a0400d}, +{0x4c,0x24800029}, +{0x50,0xa404a001}, +{0x54,0x82122068}, +{0x58,0xa610000c}, +{0x5c,0x98044001}, +{0x60,0x96102000}, +{0x64,0x94122368}, +{0x68,0xc2030000}, +{0x6c,0x9b2ae002}, +{0x70,0x9338601f}, +{0x74,0x81826000}, +{0x78,0xd2040013}, +{0x7c,0x01000000}, +{0xf0,0x78}, +{0x00,0x01000000}, +{0x04,0x82784009}, +{0x08,0x9602e001}, +{0x0c,0xc223400a}, +{0x10,0x80a2e02f}, +{0x14,0x04bffff5}, +{0x18,0x98032004}, +{0x1c,0x03000017}, +{0x20,0x82106324}, +{0x24,0xda004000}, +{0x28,0x8203400d}, +{0x2c,0x8200400d}, +{0x30,0x13000019}, +{0x34,0x83286005}, +{0x38,0x92126268}, +{0x3c,0x92004009}, +{0x40,0x7ffffa47}, +{0x44,0x90122368}, +{0x48,0xc20026e4}, +{0x4c,0x82006001}, +{0x50,0xc22026e4}, +{0x54,0xc0240013}, +{0x58,0x80a76000}, +{0x5c,0x02800004}, +{0x60,0xae102000}, +{0x64,0x7ffff93d}, +{0x68,0x01000000}, +{0x6c,0xa404a001}, +{0x70,0x80a4a002}, +{0x74,0x04bfffcc}, +{0x78,0xa20460c0}, +{0x7c,0xee202584}, +{0xf0,0x79}, +{0x00,0x81c7e008}, +{0x04,0x81e80000}, +{0x08,0x9de3bf98}, +{0x0c,0x03000017}, +{0x10,0x82106324}, +{0x14,0xc2004000}, +{0x18,0x80a06001}, +{0x1c,0x02800062}, +{0x20,0x01000000}, +{0x24,0xc2502198}, +{0x28,0x80a06000}, +{0x2c,0x0280005e}, +{0x30,0x01000000}, +{0x34,0xc2102548}, +{0x38,0x80886001}, +{0x3c,0x1280005a}, +{0x40,0x94102000}, +{0x44,0xc2002300}, +{0x48,0x80a28001}, +{0x4c,0x1a80003c}, +{0x50,0x96102000}, +{0x54,0x03000019}, +{0x58,0x90106328}, +{0x5c,0x98102000}, +{0x60,0x832ae003}, +{0x64,0xb0004008}, +{0x68,0xb2102000}, +{0x6c,0xb52b2010}, +{0x70,0xfa502198}, +{0x74,0xc2060000}, +{0x78,0x80a0401d}, +{0x7c,0x36800026}, +{0xf0,0x7a}, +{0x00,0xb2066001}, +{0x04,0xb6102000}, +{0x08,0x9a030019}, +{0x0c,0x92102001}, +{0x10,0x9e16a100}, +{0x14,0xbb2ee002}, +{0x18,0xf8076524}, +{0x1c,0x80a72000}, +{0x20,0x22800012}, +{0x24,0xc2076524}, +{0x28,0xc20f6525}, +{0x2c,0x80a0400d}, +{0x30,0x3280000e}, +{0x34,0xc2076524}, +{0x38,0x82072100}, +{0x3c,0xc2276524}, +{0x40,0xfa0f6526}, +{0x44,0xc208219a}, +{0x48,0x80a74001}, +{0x4c,0x0880000c}, +{0x50,0x832a401b}, +{0x54,0xc200254c}, +{0x58,0x3b000200}, +{0x5c,0x8210401d}, +{0x60,0x10800031}, +{0x64,0xc220254c}, +{0x68,0x80a06000}, +{0x6c,0x32800006}, +{0x70,0xb606e001}, +{0x74,0x832a401b}, +{0x78,0xde276524}, +{0x7c,0x10800005}, +{0xf0,0x7b}, +{0x00,0x94128001}, +{0x04,0x80a6e003}, +{0x08,0x04bfffe4}, +{0x0c,0xbb2ee002}, +{0x10,0xb2066001}, +{0x14,0x03000040}, +{0x18,0xb4068001}, +{0x1c,0x80a66001}, +{0x20,0x04bfffd4}, +{0x24,0xb0062004}, +{0x28,0x9602e001}, +{0x2c,0xc2002300}, +{0x30,0x80a2c001}, +{0x34,0x0abfffcb}, +{0x38,0x98032002}, +{0x3c,0xb2102000}, +{0x40,0xb6102000}, +{0x44,0xb92ee002}, +{0x48,0xc2072524}, +{0x4c,0xb4006001}, +{0x50,0xbb3a801b}, +{0x54,0x80a06000}, +{0x58,0x02800013}, +{0x5c,0xb12e6002}, +{0x60,0x808f6001}, +{0x64,0x3280000a}, +{0x68,0xc2072524}, +{0x6c,0xf4272524}, +{0x70,0xfa0f2527}, +{0x74,0xc208219b}, +{0x78,0x80a74001}, +{0x7c,0x28800004}, +{0xf0,0x7c}, +{0x00,0xc2072524}, +{0x04,0x10800004}, +{0x08,0xc0272524}, +{0x0c,0xb2066001}, +{0x10,0xc2262524}, +{0x14,0xb606e001}, +{0x18,0x80a6e003}, +{0x1c,0x04bfffeb}, +{0x20,0xb92ee002}, +{0x24,0x81c7e008}, +{0x28,0x81e80000}, +{0x2c,0x9de3bf98}, +{0x30,0x7ffff7c4}, +{0x34,0x01000000}, +{0x38,0x1b000017}, +{0x3c,0x82102001}, +{0x40,0x9a136388}, +{0x44,0xc2234000}, +{0x48,0xc2002fe0}, +{0x4c,0x9fc04000}, +{0x50,0x01000000}, +{0x54,0x01000000}, +{0x58,0x81c7e008}, +{0x5c,0x81e80000}, +{0x60,0x9de3bf98}, +{0x64,0x03000017}, +{0x68,0x82106324}, +{0x6c,0xc2004000}, +{0x70,0x80a06001}, +{0x74,0x02800066}, +{0x78,0x9a102000}, +{0x7c,0xf8002514}, +{0xf0,0x7d}, +{0x00,0xc02026e0}, +{0x04,0x80a3401c}, +{0x08,0xb0102000}, +{0x0c,0x1a80000f}, +{0x10,0xb2102000}, +{0x14,0xc2002300}, +{0x18,0xbb306001}, +{0x1c,0xb6102001}, +{0x20,0x832e6002}, +{0x24,0xc20067e0}, +{0x28,0x80a0401d}, +{0x2c,0x0a800003}, +{0x30,0xb2066001}, +{0x34,0x8220401d}, +{0x38,0x832ec001}, +{0x3c,0x80a6401c}, +{0x40,0x0abffff8}, +{0x44,0xb0160001}, +{0x48,0x3b000017}, +{0x4c,0xb4176380}, +{0x50,0xc2002300}, +{0x54,0xb93e2001}, +{0x58,0xba176384}, +{0x5c,0xb816001c}, +{0x60,0xb6060018}, +{0x64,0x83306001}, +{0x68,0xb2102000}, +{0x6c,0xc0274000}, +{0x70,0xb017001b}, +{0x74,0x80a64001}, +{0x78,0x1a80002e}, +{0x7c,0xc0268000}, +{0xf0,0x7e}, +{0x00,0x94100001}, +{0x04,0x03000019}, +{0x08,0x98106328}, +{0x0c,0x9610632c}, +{0x10,0x82007800}, +{0x14,0x9e106384}, +{0x18,0x92106380}, +{0x1c,0x833e0019}, +{0x20,0x80886001}, +{0x24,0x1280001f}, +{0x28,0xbb2e6003}, +{0x2c,0xf607400c}, +{0x30,0x8238001b}, +{0x34,0xf407400b}, +{0x38,0x8338601f}, +{0x3c,0xb60ec001}, +{0x40,0xb838001a}, +{0x44,0xfa03c000}, +{0x48,0xc2002300}, +{0x4c,0xb93f201f}, +{0x50,0xba07401b}, +{0x54,0xb40e801c}, +{0x58,0x83306001}, +{0x5c,0xba07401a}, +{0x60,0x82004019}, +{0x64,0xfa23c000}, +{0x68,0x83286003}, +{0x6c,0xf600400b}, +{0x70,0xf800400c}, +{0x74,0x8238001c}, +{0x78,0x8338601f}, +{0x7c,0xba38001b}, +{0xf0,0x7f}, +{0x00,0xb80f0001}, +{0x04,0xc2024000}, +{0x08,0xbb3f601f}, +{0x0c,0x8200401c}, +{0x10,0xb60ec01d}, +{0x14,0x8200401b}, +{0x18,0x9a036001}, +{0x1c,0xc2224000}, +{0x20,0xb2066001}, +{0x24,0x80a6400a}, +{0x28,0x0abfffd8}, +{0x2c,0x03000019}, +{0x30,0x37000017}, +{0x34,0x8216e380}, +{0x38,0xb616e384}, +{0x3c,0xf806c000}, +{0x40,0xc2004000}, +{0x44,0x82070001}, +{0x48,0x9938601f}, +{0x4c,0x81832000}, +{0x50,0x01000000}, +{0x54,0x01000000}, +{0x58,0x01000000}, +{0x5c,0x8278400d}, +{0x60,0xbb30601f}, +{0x64,0x8200401d}, +{0x68,0x993f201f}, +{0x6c,0x81832000}, +{0x70,0x01000000}, +{0x74,0x01000000}, +{0x78,0x01000000}, +{0x7c,0xb87f000d}, +{0xf0,0x80}, +{0x00,0x83386001}, +{0x04,0xf826c000}, +{0x08,0xc22026e0}, +{0x0c,0x81c7e008}, +{0x10,0x81e80000}, +{0x14,0x9de3bf98}, +{0x18,0x03000017}, +{0x1c,0x82106324}, +{0x20,0xc2004000}, +{0x24,0x80a06001}, +{0x28,0x0280005a}, +{0x2c,0x01000000}, +{0x30,0xc2002514}, +{0x34,0x80a06000}, +{0x38,0x12800056}, +{0x3c,0x01000000}, +{0x40,0xde002200}, +{0x44,0x80a3e000}, +{0x48,0x1280000a}, +{0x4c,0x03000019}, +{0x50,0xc2002548}, +{0x54,0x82087ffb}, +{0x58,0xc2202548}, +{0x5c,0x033fc180}, +{0x60,0x8210602c}, +{0x64,0xc0204000}, +{0x68,0x1080004a}, +{0x6c,0xc02026e8}, +{0x70,0xc0202504}, +{0x74,0x9a106328}, +{0x78,0xb4102000}, +{0x7c,0x10800011}, +{0xf0,0x81}, +{0x00,0xf0102214}, +{0x04,0xba00400d}, +{0x08,0xf2102216}, +{0x0c,0xb6102001}, +{0x10,0xc2074000}, +{0x14,0xba076004}, +{0x18,0x80a04019}, +{0x1c,0x04800005}, +{0x20,0xb8204019}, +{0x24,0xc2002504}, +{0x28,0x8200401c}, +{0x2c,0xc2202504}, +{0x30,0xb686ffff}, +{0x34,0x3cbffff8}, +{0x38,0xc2074000}, +{0x3c,0xb406a001}, +{0x40,0x80a62000}, +{0x44,0x32800003}, +{0x48,0x80a68018}, +{0x4c,0x80a6800f}, +{0x50,0x38800007}, +{0x54,0xfa10221a}, +{0x58,0xc2002300}, +{0x5c,0x80a68001}, +{0x60,0x08bfffe9}, +{0x64,0x832ea003}, +{0x68,0xfa10221a}, +{0x6c,0xc2002504}, +{0x70,0x80a0401d}, +{0x74,0x34800009}, +{0x78,0xc2002548}, +{0x7c,0xc2102218}, +{0xf0,0x82}, +{0x00,0x80a06000}, +{0x04,0x2280000a}, +{0x08,0xc2002548}, +{0x0c,0x80a06000}, +{0x10,0x12800007}, +{0x14,0xc2002548}, +{0x18,0x80886008}, +{0x1c,0x22800008}, +{0x20,0xc20026e8}, +{0x24,0x10800008}, +{0x28,0xc02026e8}, +{0x2c,0x80886008}, +{0x30,0x22800005}, +{0x34,0xc02026e8}, +{0x38,0xc20026e8}, +{0x3c,0x82006001}, +{0x40,0xc22026e8}, +{0x44,0xfa0026e8}, +{0x48,0xc2002290}, +{0x4c,0x80a74001}, +{0x50,0x0880000b}, +{0x54,0xfa002548}, +{0x58,0x83376003}, +{0x5c,0x82086001}, +{0x60,0x82186001}, +{0x64,0x83286002}, +{0x68,0xba0f7ffb}, +{0x6c,0xba174001}, +{0x70,0xfa202548}, +{0x74,0xc02026e8}, +{0x78,0xfa002548}, +{0x7c,0xbb376002}, +{0xf0,0x83}, +{0x00,0x033fc180}, +{0x04,0xba0f6001}, +{0x08,0x8210602c}, +{0x0c,0xfa204000}, +{0x10,0x81c7e008}, +{0x14,0x81e80000}, +{0x18,0x9de3bf60}, +{0x1c,0xc25022ba}, +{0x20,0x80a06000}, +{0x24,0x02800076}, +{0x28,0x03000017}, +{0x2c,0x82106324}, +{0x30,0xc2004000}, +{0x34,0x80a06001}, +{0x38,0x02800071}, +{0x3c,0x01000000}, +{0x40,0xc2002514}, +{0x44,0x80a06001}, +{0x48,0x1880006d}, +{0x4c,0xa0102000}, +{0x50,0xa4102000}, +{0x54,0xa32c2002}, +{0x58,0x9a07bff8}, +{0x5c,0x8204400d}, +{0x60,0xc0207fc8}, +{0x64,0x92102000}, +{0x68,0x8207bfe0}, +{0x6c,0x98102005}, +{0x70,0xc0204000}, +{0x74,0x98833fff}, +{0x78,0x1cbffffe}, +{0x7c,0x82006004}, +{0xf0,0x84}, +{0x00,0x03000019}, +{0x04,0x9e106268}, +{0x08,0x82007c00}, +{0x0c,0x90106368}, +{0x10,0x96037fe8}, +{0x14,0x98102000}, +{0x18,0x8204800c}, +{0x1c,0x82186001}, +{0x20,0x9b286002}, +{0x24,0x94004001}, +{0x28,0xc2046ea0}, +{0x2c,0x8338400c}, +{0x30,0x80886001}, +{0x34,0x02800008}, +{0x38,0x98032001}, +{0x3c,0xda034008}, +{0x40,0xc212800f}, +{0x44,0x8220400d}, +{0x48,0xc222c000}, +{0x4c,0x92026001}, +{0x50,0x9602e004}, +{0x54,0x80a32005}, +{0x58,0x04bffff1}, +{0x5c,0x8204800c}, +{0x60,0x7ffff69e}, +{0x64,0x9007bfe0}, +{0x68,0xc25022ba}, +{0x6c,0xd25022b8}, +{0x70,0x96007fff}, +{0x74,0x98100009}, +{0x78,0x80a2400b}, +{0x7c,0x1480000b}, +{0xf0,0x85}, +{0x00,0x94102000}, +{0x04,0x832a6002}, +{0x08,0x8200401e}, +{0x0c,0x9a007fe0}, +{0x10,0xc2034000}, +{0x14,0x98032001}, +{0x18,0x94028001}, +{0x1c,0x80a3000b}, +{0x20,0x04bffffc}, +{0x24,0x9a036004}, +{0x28,0x8222c009}, +{0x2c,0x82006001}, +{0x30,0x9b3aa01f}, +{0x34,0x81836000}, +{0x38,0x01000000}, +{0x3c,0x01000000}, +{0x40,0x01000000}, +{0x44,0x947a8001}, +{0x48,0xc25021ac}, +{0x4c,0x80a28001}, +{0x50,0x26800002}, +{0x54,0x94100001}, +{0x58,0x9e07bff8}, +{0x5c,0x8204400f}, +{0x60,0xa0042001}, +{0x64,0xd4207fc8}, +{0x68,0x80a42006}, +{0x6c,0x04bfffba}, +{0x70,0xa404a006}, +{0x74,0xa0102000}, +{0x78,0xc2002300}, +{0x7c,0x80a40001}, +{0xf0,0x86}, +{0x00,0x1a80001f}, +{0x04,0x03000019}, +{0x08,0x92106328}, +{0x0c,0x030aaaaa}, +{0x10,0x901062ab}, +{0x14,0x94042400}, +{0x18,0x972c2003}, +{0x1c,0x98102001}, +{0x20,0xda0a8000}, +{0x24,0x9b2b6018}, +{0x28,0x833b6018}, +{0x2c,0x9b3b601f}, +{0x30,0x80584008}, +{0x34,0x83400000}, +{0x38,0x8220400d}, +{0x3c,0x83286018}, +{0x40,0x83386016}, +{0x44,0x8200400f}, +{0x48,0xda007fc8}, +{0x4c,0xc202c009}, +{0x50,0x8220400d}, +{0x54,0xc222c009}, +{0x58,0x9602e004}, +{0x5c,0x98833fff}, +{0x60,0x1cbffff0}, +{0x64,0x9402a020}, +{0x68,0xa0042001}, +{0x6c,0xc2002300}, +{0x70,0x80a40001}, +{0x74,0x0abfffe9}, +{0x78,0x94042400}, +{0x7c,0x81c7e008}, +{0xf0,0x87}, +{0x00,0x81e80000}, +{0x04,0x9de3bf98}, +{0x08,0x1b000017}, +{0x0c,0x82102002}, +{0x10,0x9a136388}, +{0x14,0xc2234000}, +{0x18,0xc2002fe0}, +{0x1c,0x9fc04000}, +{0x20,0x01000000}, +{0x24,0x01000000}, +{0x28,0x81c7e008}, +{0x2c,0x81e80000}, +{0x30,0x9de3bf28}, +{0x34,0xb12e2002}, +{0x38,0xc2062720}, +{0x3c,0xa2086fff}, +{0x40,0x7ffff6d9}, +{0x44,0x90100011}, +{0x48,0x9a047ffe}, +{0x4c,0xa0046002}, +{0x50,0x80a34010}, +{0x54,0x14800025}, +{0x58,0x832b6003}, +{0x5c,0x90006004}, +{0x60,0x9407bff8}, +{0x64,0x25000019}, +{0x68,0xc022bfe8}, +{0x6c,0x80a36000}, +{0x70,0x06800019}, +{0x74,0xc022bfb8}, +{0x78,0xc2002300}, +{0x7c,0x80a34001}, +{0xf0,0x88}, +{0x00,0x3a800016}, +{0x04,0x9a036001}, +{0x08,0x9e14a328}, +{0x0c,0x832b6003}, +{0x10,0x9600400f}, +{0x14,0x92102000}, +{0x18,0xd802c000}, +{0x1c,0x80a32000}, +{0x20,0x04800009}, +{0x24,0x9602e004}, +{0x28,0xc202bfe8}, +{0x2c,0x8200400c}, +{0x30,0x80a26001}, +{0x34,0x12800004}, +{0x38,0xc222bfe8}, +{0x3c,0xc202000f}, +{0x40,0xc222bfb8}, +{0x44,0x92026001}, +{0x48,0x80a26001}, +{0x4c,0x24bffff4}, +{0x50,0xd802c000}, +{0x54,0x9a036001}, +{0x58,0x90022008}, +{0x5c,0x80a34010}, +{0x60,0x04bfffe2}, +{0x64,0x9402a004}, +{0x68,0x9a102020}, +{0x6c,0xa8102000}, +{0x70,0xa6102040}, +{0x74,0x80a36020}, +{0x78,0x0480000b}, +{0x7c,0x82102020}, +{0xf0,0x89}, +{0x00,0x82102060}, +{0x04,0x8220400d}, +{0x08,0x9a037fe0}, +{0x0c,0xc227bfcc}, +{0x10,0xda27bfd8}, +{0x14,0xc027bfc8}, +{0x18,0xe627bfd0}, +{0x1c,0x10800009}, +{0x20,0xe627bfd4}, +{0x24,0x8220400d}, +{0x28,0x9a036020}, +{0x2c,0xc227bfc8}, +{0x30,0xda27bfd4}, +{0x34,0xe627bfcc}, +{0x38,0xe627bfd0}, +{0x3c,0xc027bfd8}, +{0x40,0x90102000}, +{0x44,0xa4102000}, +{0x48,0xac102000}, +{0x4c,0xaa102000}, +{0x50,0x92102000}, +{0x54,0xae07bff8}, +{0x58,0xa12a6002}, +{0x5c,0x82040017}, +{0x60,0xd6007fd0}, +{0x64,0xd8007fe8}, +{0x68,0x985b000b}, +{0x6c,0x833b201f}, +{0x70,0x8330601a}, +{0x74,0x98030001}, +{0x78,0x9b2a6007}, +{0x7c,0x8223400b}, +{0xf0,0x8a}, +{0x00,0x993b2006}, +{0x04,0x9a03400b}, +{0x08,0x82006080}, +{0x0c,0x825b0001}, +{0x10,0x9a5b000d}, +{0x14,0x9730601f}, +{0x18,0x9533601f}, +{0x1c,0x8200400b}, +{0x20,0x9a03400a}, +{0x24,0x83386001}, +{0x28,0x9b3b6001}, +{0x2c,0x80a26002}, +{0x30,0x9405800c}, +{0x34,0x9e05400c}, +{0x38,0x14800004}, +{0x3c,0x96026001}, +{0x40,0x10800003}, +{0x44,0x90020001}, +{0x48,0x9002000d}, +{0x4c,0x82040017}, +{0x50,0xd8007fd0}, +{0x54,0xda007fb8}, +{0x58,0x9a5b400c}, +{0x5c,0x833b601f}, +{0x60,0x8330601a}, +{0x64,0x9a034001}, +{0x68,0x9b3b6006}, +{0x6c,0x9210000b}, +{0x70,0xa404800d}, +{0x74,0x80a2e004}, +{0x78,0xac10000a}, +{0x7c,0x04bfffd7}, +{0xf0,0x8b}, +{0x00,0xaa10000f}, +{0x04,0x9b3a201f}, +{0x08,0x81836000}, +{0x0c,0x01000000}, +{0x10,0x01000000}, +{0x14,0x01000000}, +{0x18,0x827a000a}, +{0x1c,0xa8052001}, +{0x20,0x80a52002}, +{0x24,0x04bfffb4}, +{0x28,0x9a007f80}, +{0x2c,0xa12c6006}, +{0x30,0xa0034010}, +{0x34,0xa32ca00a}, +{0x38,0x833c601f}, +{0x3c,0x81806000}, +{0x40,0x01000000}, +{0x44,0x01000000}, +{0x48,0x01000000}, +{0x4c,0xa27c400f}, +{0x50,0x90100010}, +{0x54,0x7ffff782}, +{0x58,0x92102000}, +{0x5c,0xc2062720}, +{0x60,0x1b000010}, +{0x64,0xa2044008}, +{0x68,0x8088400d}, +{0x6c,0x912c2010}, +{0x70,0x02800005}, +{0x74,0x820c6fff}, +{0x78,0x82020001}, +{0x7c,0x10800003}, +{0xf0,0x8c}, +{0x00,0x8200400d}, +{0x04,0x82020001}, +{0x08,0xc2262720}, +{0x0c,0x81c7e008}, +{0x10,0x81e80000}, +{0x14,0x9de3bf98}, +{0x18,0x7ffff801}, +{0x1c,0x9010205a}, +{0x20,0xc2002548}, +{0x24,0x9a087fbf}, +{0x28,0xc2002514}, +{0x2c,0x80a06000}, +{0x30,0x02800004}, +{0x34,0xda202548}, +{0x38,0x82136040}, +{0x3c,0xc2202548}, +{0x40,0xc20022d4}, +{0x44,0x80886200}, +{0x48,0x22800007}, +{0x4c,0xc2002514}, +{0x50,0xc20026a0}, +{0x54,0x80886400}, +{0x58,0x22800002}, +{0x5c,0xc0202514}, +{0x60,0xc2002514}, +{0x64,0xb0102000}, +{0x68,0x80a60001}, +{0x6c,0xc2202520}, +{0x70,0xa0102000}, +{0x74,0x1a800019}, +{0x78,0xa32e2002}, +{0x7c,0xc2046720}, +{0xf0,0x8d}, +{0x00,0x8330600d}, +{0x04,0x80886001}, +{0x08,0x12800010}, +{0x0c,0x90100018}, +{0x10,0x7fffff48}, +{0x14,0x01000000}, +{0x18,0xc2002fec}, +{0x1c,0x80a06000}, +{0x20,0x02800004}, +{0x24,0x90100018}, +{0x28,0x9fc04000}, +{0x2c,0x01000000}, +{0x30,0xc2046720}, +{0x34,0x80a06000}, +{0x38,0x02800004}, +{0x3c,0x9b2c2002}, +{0x40,0xa0042001}, +{0x44,0xc2236720}, +{0x48,0xb0062001}, +{0x4c,0xc2002514}, +{0x50,0x10bfffe9}, +{0x54,0x80a60001}, +{0x58,0x03000017}, +{0x5c,0x8210631c}, +{0x60,0xc2004000}, +{0x64,0x80a06002}, +{0x68,0x12800016}, +{0x6c,0xe0202514}, +{0x70,0x80a42001}, +{0x74,0x08800015}, +{0x78,0xb0102000}, +{0x7c,0x80a60010}, +{0xf0,0x8e}, +{0x00,0x1a80000e}, +{0x04,0x96100010}, +{0x08,0x992e2002}, +{0x0c,0xda132730}, +{0x10,0xc2102730}, +{0x14,0x80a34001}, +{0x18,0x08800005}, +{0x1c,0xb0062001}, +{0x20,0xda302730}, +{0x24,0xc2032720}, +{0x28,0xc2202720}, +{0x2c,0x80a6000b}, +{0x30,0x0abffff7}, +{0x34,0x992e2002}, +{0x38,0x82102001}, +{0x3c,0xc2202514}, +{0x40,0x7ffff6b5}, +{0x44,0x81e80000}, +{0x48,0x01000000}, +{0x4c,0x81c7e008}, +{0x50,0x81e80000}, +{0x54,0xc2102548}, +{0x58,0x80886001}, +{0x5c,0xc020255c}, +{0x60,0x02800007}, +{0x64,0x92102000}, +{0x68,0xc20023c8}, +{0x6c,0x8330600d}, +{0x70,0x80886001}, +{0x74,0x02800025}, +{0x78,0x01000000}, +{0x7c,0xd0002304}, +{0xf0,0x8f}, +{0x00,0x80a24008}, +{0x04,0x1a800010}, +{0x08,0x96102000}, +{0x0c,0x03000019}, +{0x10,0x941063c0}, +{0x14,0x992ae002}, +{0x18,0xc203000a}, +{0x1c,0xc203000a}, +{0x20,0x80a04009}, +{0x24,0x24800005}, +{0x28,0x9602e001}, +{0x2c,0xd203000a}, +{0x30,0x9a10000b}, +{0x34,0x9602e001}, +{0x38,0x80a2c008}, +{0x3c,0x0abffff7}, +{0x40,0x992ae002}, +{0x44,0x9b2b6008}, +{0x48,0xc2002288}, +{0x4c,0x80a24001}, +{0x50,0x0680000e}, +{0x54,0x9a036020}, +{0x58,0x98102001}, +{0x5c,0xc2002704}, +{0x60,0x80a06000}, +{0x64,0x12800009}, +{0x68,0xd820255c}, +{0x6c,0xc2002514}, +{0x70,0x80a06000}, +{0x74,0x12800005}, +{0x78,0x0303ffc4}, +{0x7c,0x82034001}, +{0xf0,0x90}, +{0x00,0xc2202720}, +{0x04,0xd8202514}, +{0x08,0x81c3e008}, +{0x0c,0x01000000}, +{0x10,0x9de3bf98}, +{0x14,0x7ffff66a}, +{0x18,0x01000000}, +{0x1c,0xc208254d}, +{0x20,0x80a06000}, +{0x24,0x02800019}, +{0x28,0x033fc180}, +{0x2c,0xc0204000}, +{0x30,0xb0102002}, +{0x34,0x7ffff89c}, +{0x38,0x90102001}, +{0x3c,0x11000099}, +{0x40,0x7ffff516}, +{0x44,0x9012233c}, +{0x48,0xb0863fff}, +{0x4c,0x1cbffffa}, +{0x50,0x01000000}, +{0x54,0xc210254c}, +{0x58,0x80886001}, +{0x5c,0x32800002}, +{0x60,0xc020250c}, +{0x64,0x7ffff342}, +{0x68,0x90102015}, +{0x6c,0xda102548}, +{0x70,0x82102001}, +{0x74,0x808b6001}, +{0x78,0x12800004}, +{0x7c,0xc2202584}, +{0xf0,0x91}, +{0x00,0x7ffff402}, +{0x04,0x91e82001}, +{0x08,0x01000000}, +{0x0c,0x81c7e008}, +{0x10,0x81e80000}, +{0x14,0x9de3bf88}, +{0x18,0x03000017}, +{0x1c,0x82106324}, +{0x20,0xc2004000}, +{0x24,0x80a06001}, +{0x28,0x02800037}, +{0x2c,0x01000000}, +{0x30,0xc208254e}, +{0x34,0x80a00001}, +{0x38,0xda102548}, +{0x3c,0x82602000}, +{0x40,0x9a0b6001}, +{0x44,0x80a0000d}, +{0x48,0x82087ffe}, +{0x4c,0x9a403fff}, +{0x50,0x82006003}, +{0x54,0x8208400d}, +{0x58,0xda086314}, +{0x5c,0xc20026e4}, +{0x60,0x80a0400d}, +{0x64,0x06800028}, +{0x68,0x80a36000}, +{0x6c,0x02800026}, +{0x70,0x01000000}, +{0x74,0xda00254c}, +{0x78,0x83336018}, +{0x7c,0x80886001}, +{0xf0,0x92}, +{0x00,0x12800007}, +{0x04,0x03004000}, +{0x08,0xc20026f4}, +{0x0c,0x80a06000}, +{0x10,0x22800008}, +{0x14,0xc200255c}, +{0x18,0x03004000}, +{0x1c,0x822b4001}, +{0x20,0xc220254c}, +{0x24,0xc027bfec}, +{0x28,0x10800009}, +{0x2c,0xc027bff0}, +{0x30,0x80a06000}, +{0x34,0x12800014}, +{0x38,0x01000000}, +{0x3c,0xc208221c}, +{0x40,0xc227bfec}, +{0x44,0xc208221d}, +{0x48,0xc227bff0}, +{0x4c,0xa0102000}, +{0x50,0xc2002304}, +{0x54,0x80a40001}, +{0x58,0x1a80000b}, +{0x5c,0x01000000}, +{0x60,0xc24c2380}, +{0x64,0xc227bfe8}, +{0x68,0x7ffff7b6}, +{0x6c,0x9007bfe8}, +{0x70,0xa0042001}, +{0x74,0xc2002304}, +{0x78,0x80a40001}, +{0x7c,0x2abffffa}, +{0xf0,0x93}, +{0x00,0xc24c2380}, +{0x04,0x81c7e008}, +{0x08,0x81e80000}, +{0x0c,0x9de3bf78}, +{0x10,0x03000017}, +{0x14,0x82106324}, +{0x18,0xc2004000}, +{0x1c,0x80a06000}, +{0x20,0x12800093}, +{0x24,0xc208254e}, +{0x28,0x80a00001}, +{0x2c,0x82602000}, +{0x30,0xa0087ffe}, +{0x34,0xd8002548}, +{0x38,0x83332010}, +{0x3c,0x80886001}, +{0x40,0x0280000c}, +{0x44,0xa0042003}, +{0x48,0x83332011}, +{0x4c,0x80886001}, +{0x50,0x02800030}, +{0x54,0xa0102000}, +{0x58,0xc2002558}, +{0x5c,0x80a06001}, +{0x60,0x28800081}, +{0x64,0xc02026e4}, +{0x68,0x1080002b}, +{0x6c,0xc20c2314}, +{0x70,0x033fc200}, +{0x74,0x82106030}, +{0x78,0xda004000}, +{0x7c,0xc2002570}, +{0xf0,0x94}, +{0x00,0x80a34001}, +{0x04,0x32800078}, +{0x08,0xc02026e4}, +{0x0c,0x808b2040}, +{0x10,0x3280000f}, +{0x14,0x21000019}, +{0x18,0xc2002200}, +{0x1c,0x80a06000}, +{0x20,0x3280000b}, +{0x24,0x21000019}, +{0x28,0xc200255c}, +{0x2c,0x80a06001}, +{0x30,0x22800007}, +{0x34,0x21000019}, +{0x38,0xc20026f8}, +{0x3c,0x80a06000}, +{0x40,0x22800015}, +{0x44,0xc20c2314}, +{0x48,0x21000019}, +{0x4c,0x92142268}, +{0x50,0x94102018}, +{0x54,0x7ffff59d}, +{0x58,0x90142088}, +{0x5c,0x92142268}, +{0x60,0x90142028}, +{0x64,0x7ffff599}, +{0x68,0x94102018}, +{0x6c,0xda082191}, +{0x70,0x832b6002}, +{0x74,0x8200400d}, +{0x78,0x82004001}, +{0x7c,0x82200001}, +{0xf0,0x95}, +{0x00,0xc22026e4}, +{0x04,0xc02026ec}, +{0x08,0x10800073}, +{0x0c,0xc02026f0}, +{0x10,0xc20c2314}, +{0x14,0x80a06000}, +{0x18,0x22800053}, +{0x1c,0xc02026e4}, +{0x20,0xc20c234c}, +{0x24,0xc227bfec}, +{0x28,0xc20c230c}, +{0x2c,0xc227bff0}, +{0x30,0xda0c2314}, +{0x34,0xc20026e4}, +{0x38,0x80a0400d}, +{0x3c,0x06800066}, +{0x40,0x1b0000c0}, +{0x44,0xc2002548}, +{0x48,0x8208400d}, +{0x4c,0x80a0400d}, +{0x50,0x3280000f}, +{0x54,0xda082191}, +{0x58,0xda082169}, +{0x5c,0xc2002710}, +{0x60,0x80a0400d}, +{0x64,0x2680000a}, +{0x68,0xda082191}, +{0x6c,0xc200270c}, +{0x70,0x82006001}, +{0x74,0xda082168}, +{0x78,0x80a0400d}, +{0x7c,0x06800039}, +{0xf0,0x96}, +{0x00,0xc220270c}, +{0x04,0xc020270c}, +{0x08,0xda082191}, +{0x0c,0xc20026ec}, +{0x10,0x80a0400d}, +{0x14,0x2680000d}, +{0x18,0xd8002548}, +{0x1c,0x21000019}, +{0x20,0x92142088}, +{0x24,0x94102018}, +{0x28,0x7ffff568}, +{0x2c,0x90142268}, +{0x30,0x92142028}, +{0x34,0x90142088}, +{0x38,0x7ffff564}, +{0x3c,0x94102018}, +{0x40,0xc02026ec}, +{0x44,0xd8002548}, +{0x48,0x030000c0}, +{0x4c,0x820b0001}, +{0x50,0x1b000040}, +{0x54,0x80a0400d}, +{0x58,0x32800010}, +{0x5c,0xc2082191}, +{0x60,0xc210218e}, +{0x64,0xda002660}, +{0x68,0x80a34001}, +{0x6c,0x14800005}, +{0x70,0x03000080}, +{0x74,0x82036001}, +{0x78,0x10800005}, +{0x7c,0xc2202660}, +{0xf0,0x97}, +{0x00,0x82130001}, +{0x04,0xc2202548}, +{0x08,0xc0202660}, +{0x0c,0xc027bfec}, +{0x10,0xc027bff0}, +{0x14,0xc2082191}, +{0x18,0xda0026f0}, +{0x1c,0x80a34001}, +{0x20,0x0680000f}, +{0x24,0x82036001}, +{0x28,0xa0102000}, +{0x2c,0xe027bfe8}, +{0x30,0x7ffff724}, +{0x34,0x9007bfe8}, +{0x38,0xa0042001}, +{0x3c,0x80a4202f}, +{0x40,0x24bffffc}, +{0x44,0xe027bfe8}, +{0x48,0xc20026ec}, +{0x4c,0x82006001}, +{0x50,0xc22026ec}, +{0x54,0x10800020}, +{0x58,0xc02026e4}, +{0x5c,0xc22026f0}, +{0x60,0xc02026e4}, +{0x64,0x1080001c}, +{0x68,0xc02026ec}, +{0x6c,0xc2002548}, +{0x70,0x80886040}, +{0x74,0x12800018}, +{0x78,0x01000000}, +{0x7c,0xc2002200}, +{0xf0,0x98}, +{0x00,0x80a06000}, +{0x04,0x12800014}, +{0x08,0x01000000}, +{0x0c,0xc200255c}, +{0x10,0x80a06001}, +{0x14,0x02800010}, +{0x18,0x01000000}, +{0x1c,0xc20026f8}, +{0x20,0x80a06000}, +{0x24,0x1280000c}, +{0x28,0x82102004}, +{0x2c,0xc227bfe0}, +{0x30,0xc227bfdc}, +{0x34,0xa0102000}, +{0x38,0xe027bfd8}, +{0x3c,0x7ffff701}, +{0x40,0x9007bfd8}, +{0x44,0xa0042001}, +{0x48,0x80a4202f}, +{0x4c,0x24bffffc}, +{0x50,0xe027bfd8}, +{0x54,0x81c7e008}, +{0x58,0x81e80000}, +{0x5c,0x03000017}, +{0x60,0x82106324}, +{0x64,0xc2004000}, +{0x68,0x80a06001}, +{0x6c,0x02800023}, +{0x70,0x01000000}, +{0x74,0xc2102548}, +{0x78,0x80886001}, +{0x7c,0x0280001f}, +{0xf0,0x99}, +{0x00,0x96102000}, +{0x04,0xd4002300}, +{0x08,0x80a2c00a}, +{0x0c,0x1a80001b}, +{0x10,0x992ae003}, +{0x14,0xc2002470}, +{0x18,0xda1023b6}, +{0x1c,0x9a5b4001}, +{0x20,0x833b601f}, +{0x24,0x83306019}, +{0x28,0x9a034001}, +{0x2c,0x03000019}, +{0x30,0x9b3b6007}, +{0x34,0x9a20000d}, +{0x38,0x9010632c}, +{0x3c,0x92106328}, +{0x40,0xc2030009}, +{0x44,0x80a0400d}, +{0x48,0x06800006}, +{0x4c,0x9602e001}, +{0x50,0xc2030008}, +{0x54,0x80a0400d}, +{0x58,0x16800006}, +{0x5c,0x80a2c00a}, +{0x60,0xc2002548}, +{0x64,0x82106040}, +{0x68,0xc2202548}, +{0x6c,0x80a2c00a}, +{0x70,0x0abffff4}, +{0x74,0x992ae003}, +{0x78,0x81c3e008}, +{0x7c,0x01000000}, +{0xf0,0x9a}, +{0x00,0x9de3bf98}, +{0x04,0x03000017}, +{0x08,0x82106324}, +{0x0c,0xc2004000}, +{0x10,0x80a06001}, +{0x14,0x02800066}, +{0x18,0xc0202580}, +{0x1c,0xd8002548}, +{0x20,0x83332010}, +{0x24,0x80886001}, +{0x28,0x02800061}, +{0x2c,0x01000000}, +{0x30,0xc2002204}, +{0x34,0x80a06000}, +{0x38,0x0280005d}, +{0x3c,0x83332011}, +{0x40,0x80886001}, +{0x44,0x32800005}, +{0x48,0xc2002514}, +{0x4c,0xc2002208}, +{0x50,0xc2202558}, +{0x54,0xc2002514}, +{0x58,0x80a06000}, +{0x5c,0x02800006}, +{0x60,0x1b000080}, +{0x64,0xc2002558}, +{0x68,0x80a06000}, +{0x6c,0x12800013}, +{0x70,0x80a0603b}, +{0x74,0x82136040}, +{0x78,0x820b0001}, +{0x7c,0x80a0400d}, +{0xf0,0x9b}, +{0x00,0x32800006}, +{0x04,0xc2002558}, +{0x08,0xc200255c}, +{0x0c,0x80a06000}, +{0x10,0x02800015}, +{0x14,0xc2002558}, +{0x18,0x80a06000}, +{0x1c,0x12800007}, +{0x20,0x80a0603b}, +{0x24,0x033fc200}, +{0x28,0xda00232c}, +{0x2c,0x82106074}, +{0x30,0x1080000a}, +{0x34,0xda204000}, +{0x38,0x08800004}, +{0x3c,0x80a06031}, +{0x40,0x10800005}, +{0x44,0xc2002208}, +{0x48,0x38800005}, +{0x4c,0xc2002558}, +{0x50,0x82102032}, +{0x54,0xc2202558}, +{0x58,0xc2002558}, +{0x5c,0x10800006}, +{0x60,0x82006001}, +{0x64,0x80a06000}, +{0x68,0x2280000a}, +{0x6c,0x033fc0c0}, +{0x70,0x82007fff}, +{0x74,0xc2202558}, +{0x78,0xc2002558}, +{0x7c,0x80a06000}, +{0xf0,0x9c}, +{0x00,0x02800004}, +{0x04,0x033fc0c0}, +{0x08,0x7ffff2a0}, +{0x0c,0x91e82001}, +{0x10,0x82106004}, +{0x14,0xc0204000}, +{0x18,0x7ffff29c}, +{0x1c,0x90102000}, +{0x20,0x01000000}, +{0x24,0x033fc1c0}, +{0x28,0x9a102001}, +{0x2c,0x821060d4}, +{0x30,0xda204000}, +{0x34,0x01000000}, +{0x38,0x193fc040}, +{0x3c,0x8213200c}, +{0x40,0xc0204000}, +{0x44,0x01000000}, +{0x48,0x032c8590}, +{0x4c,0xda002204}, +{0x50,0x821062c9}, +{0x54,0x80534001}, +{0x58,0x9b400000}, +{0x5c,0x9b336004}, +{0x60,0x8203400d}, +{0x64,0x8200400d}, +{0x68,0x83286003}, +{0x6c,0x8200400d}, +{0x70,0x83306004}, +{0x74,0x9a132004}, +{0x78,0xc2234000}, +{0x7c,0x01000000}, +{0xf0,0x9d}, +{0x00,0x82102003}, +{0x04,0x98132008}, +{0x08,0xc2230000}, +{0x0c,0x01000000}, +{0x10,0x01000000}, +{0x14,0x01000000}, +{0x18,0x033fc1c0}, +{0x1c,0x9a102081}, +{0x20,0x821060dc}, +{0x24,0xda204000}, +{0x28,0x01000000}, +{0x2c,0x81c7e008}, +{0x30,0x81e80000}, +{0x34,0x9de3bf98}, +{0x38,0x7ffff41d}, +{0x3c,0x01000000}, +{0x40,0xda002548}, +{0x44,0x808b6040}, +{0x48,0x3280000b}, +{0x4c,0xc2002280}, +{0x50,0xc2002704}, +{0x54,0x80a06000}, +{0x58,0x04800003}, +{0x5c,0x82007fff}, +{0x60,0xc2202704}, +{0x64,0x808b6040}, +{0x68,0x02800005}, +{0x6c,0x8333600e}, +{0x70,0xc2002280}, +{0x74,0xc2202704}, +{0x78,0x8333600e}, +{0x7c,0x80886001}, +{0xf0,0x9e}, +{0x00,0x12800056}, +{0x04,0x98102000}, +{0x08,0xc2002514}, +{0x0c,0x80a30001}, +{0x10,0x1a80000b}, +{0x14,0x033fc180}, +{0x18,0x96106004}, +{0x1c,0x832b2002}, +{0x20,0xda006720}, +{0x24,0xda20400b}, +{0x28,0x98032001}, +{0x2c,0xc2002514}, +{0x30,0x80a30001}, +{0x34,0x0abffffb}, +{0x38,0x832b2002}, +{0x3c,0xda00254c}, +{0x40,0x808b6001}, +{0x44,0x32800008}, +{0x48,0xc208254e}, +{0x4c,0xc2002514}, +{0x50,0x9a136001}, +{0x54,0x82106100}, +{0x58,0xda20254c}, +{0x5c,0xc2202514}, +{0x60,0xc208254e}, +{0x64,0x80a06000}, +{0x68,0x3280000b}, +{0x6c,0xd80023c8}, +{0x70,0xc20023c8}, +{0x74,0x83306016}, +{0x78,0x80886001}, +{0x7c,0x22800006}, +{0xf0,0x9f}, +{0x00,0xd80023c8}, +{0x04,0xc2002514}, +{0x08,0x82106200}, +{0x0c,0xc2202514}, +{0x10,0xd80023c8}, +{0x14,0x8333200c}, +{0x18,0x80886001}, +{0x1c,0x1280000f}, +{0x20,0xc2082517}, +{0x24,0x80a06000}, +{0x28,0x32800007}, +{0x2c,0xda002500}, +{0x30,0xc2002560}, +{0x34,0x80a06000}, +{0x38,0x22800008}, +{0x3c,0xc2082517}, +{0x40,0xda002500}, +{0x44,0xc2002514}, +{0x48,0x9b2b6010}, +{0x4c,0x8210400d}, +{0x50,0xc2202514}, +{0x54,0xc2082517}, +{0x58,0x80a06000}, +{0x5c,0x22800010}, +{0x60,0xc2002574}, +{0x64,0xc2002548}, +{0x68,0x80886800}, +{0x6c,0x02800005}, +{0x70,0x80a32000}, +{0x74,0xc2002514}, +{0x78,0x82106400}, +{0x7c,0xc2202514}, +{0xf0,0xa0}, +{0x00,0x36800007}, +{0x04,0xc2002574}, +{0x08,0xc2002514}, +{0x0c,0x1b000004}, +{0x10,0x8210400d}, +{0x14,0xc2202514}, +{0x18,0xc2002574}, +{0x1c,0x80a06000}, +{0x20,0x2280000c}, +{0x24,0xda002514}, +{0x28,0x82007fff}, +{0x2c,0xda082517}, +{0x30,0x80a36000}, +{0x34,0x02800006}, +{0x38,0xc2202574}, +{0x3c,0xc2002514}, +{0x40,0x1b000008}, +{0x44,0x8210400d}, +{0x48,0xc2202514}, +{0x4c,0xda002514}, +{0x50,0x033fc180}, +{0x54,0xda204000}, +{0x58,0x81c7e008}, +{0x5c,0x81e80000}, +{0x60,0x9de3bf98}, +{0x64,0xda002714}, +{0x68,0x80a36000}, +{0x6c,0x36800015}, +{0x70,0xc2002548}, +{0x74,0x193fc180}, +{0x78,0xda002208}, +{0x7c,0xd208216b}, +{0xf0,0xa1}, +{0x00,0x82102860}, +{0x04,0x96132004}, +{0x08,0xc222c000}, +{0x0c,0xc2002710}, +{0x10,0x94132008}, +{0x14,0xc2228000}, +{0x18,0x0316c020}, +{0x1c,0x82106002}, +{0x20,0xc2230000}, +{0x24,0x9a036001}, +{0x28,0x82102001}, +{0x2c,0xda202558}, +{0x30,0xd2202560}, +{0x34,0xc2202714}, +{0x38,0x10800014}, +{0x3c,0xc0202710}, +{0x40,0x8330600e}, +{0x44,0x80886001}, +{0x48,0x22800011}, +{0x4c,0xd8002548}, +{0x50,0xc2002560}, +{0x54,0x80a06000}, +{0x58,0x2280000d}, +{0x5c,0xd8002548}, +{0x60,0x80a36001}, +{0x64,0x2480000a}, +{0x68,0xd8002548}, +{0x6c,0x832b6010}, +{0x70,0x1b168020}, +{0x74,0x8210400d}, +{0x78,0x1b3fc180}, +{0x7c,0xc2234000}, +{0xf0,0xa2}, +{0x00,0xc2002208}, +{0x04,0xc2202558}, +{0x08,0xd8002548}, +{0x0c,0x8333200e}, +{0x10,0x80886001}, +{0x14,0x22800007}, +{0x18,0xc2102516}, +{0x1c,0xc2002714}, +{0x20,0x80a06000}, +{0x24,0x22800029}, +{0x28,0xda002548}, +{0x2c,0xc2102516}, +{0x30,0x80a06000}, +{0x34,0x02800006}, +{0x38,0x9b332002}, +{0x3c,0x808b2004}, +{0x40,0x02800009}, +{0x44,0x8333200e}, +{0x48,0x9b332002}, +{0x4c,0x83332003}, +{0x50,0x9a0b6001}, +{0x54,0x82086001}, +{0x58,0x80a34001}, +{0x5c,0x0280000b}, +{0x60,0x8333200e}, +{0x64,0x80886001}, +{0x68,0x32800009}, +{0x6c,0xc2002560}, +{0x70,0xc200231c}, +{0x74,0x80a06000}, +{0x78,0x22800008}, +{0x7c,0x82102014}, +{0xf0,0xa3}, +{0x00,0x10800006}, +{0x04,0x82102005}, +{0x08,0xc2002560}, +{0x0c,0x80a06000}, +{0x10,0x02800007}, +{0x14,0x82007fff}, +{0x18,0xc2202560}, +{0x1c,0x7ffff642}, +{0x20,0x90102001}, +{0x24,0x10800009}, +{0x28,0xda002548}, +{0x2c,0x7ffff63e}, +{0x30,0x90102000}, +{0x34,0x033fc180}, +{0x38,0xc0204000}, +{0x3c,0xc0202714}, +{0x40,0xc0202710}, +{0x44,0xda002548}, +{0x48,0x8203400d}, +{0x4c,0x82086008}, +{0x50,0x9a0b7ff7}, +{0x54,0x9a134001}, +{0x58,0x03000010}, +{0x5c,0x822b4001}, +{0x60,0x9b306010}, +{0x64,0x808b6001}, +{0x68,0x12800004}, +{0x6c,0xc2202548}, +{0x70,0x7ffff1a6}, +{0x74,0x91e82001}, +{0x78,0x01000000}, +{0x7c,0x81c7e008}, +{0xf0,0xa4}, +{0x00,0x81e80000}, +{0x04,0x00000000}, +{0x08,0x00000000}, +{0x0c,0x00000000}, +{0x10,0x00000000}, +{0x14,0x00000000}, +{0x18,0x00000000}, +{0x1c,0x00000000}, +{0x20,0x00000000}, +{0x24,0x00000000}, +{0x28,0x00000000}, +{0x2c,0x00000000}, +{0x30,0x00000000}, +{0x34,0x00000000}, +{0x38,0x00000000}, +{0x3c,0x00000000}, +{0x40,0x00000000}, +{0x44,0x00000000}, +{0x48,0x00000000}, +{0x4c,0x00000000}, +{0x50,0x00000000}, +{0x54,0x00000000}, +{0x58,0x00000000}, +{0x5c,0x00000000}, +{0x60,0x00000000}, +{0x64,0x00000000}, +{0x68,0x00000000}, +{0x6c,0x00000000}, +{0x70,0x00000000}, +{0x74,0x00000000}, +{0x78,0x00000000}, +{0x7c,0x00000000}, +{0xf0,0xa5}, +{0x00,0x00002133}, +{0x04,0xa5010503}, +{0x08,0xa5000044}, +{0x0c,0x00000000}, +{0x10,0x67616f79}, +{0x14,0x49444449}, +{0x18,0xc9c799e7}, +{0x1c,0xbca78a4f}, +{0x20,0xc40fc64d}, +{0x24,0x99e09a11}, +{0x28,0xcc479d60}, +{0x2c,0x99e1bc47}, +{0x30,0xa8980000}, +{0x34,0x00000000}, +{0x38,0x00000000}, +{0x3c,0x00000000}, +{0x40,0x00000000}, +{0x44,0x00000000}, +{0x48,0x00000000}, +{0x4c,0x00000000}, +{0x50,0x00000000}, +{0x54,0x00000000}, +{0x58,0x00000000}, +{0x5c,0x00000000}, +{0x60,0x00000000}, +{0x64,0x00000000}, +{0x68,0x53657020}, +{0x6c,0x31342032}, +{0x70,0x30313700}, +{0x74,0x00000000}, +{0x78,0x31343a35}, +{0x7c,0x343a3134}, +}; + + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/uart/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/uart/Kconfig new file mode 100644 index 000000000..9c347e9f7 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/uart/Kconfig @@ -0,0 +1,77 @@ +menuconfig BSP_USING_UART_HS + bool "Enable High Speed UART" + default y + if BSP_USING_UART_HS + config SERIAL_BUS_NAME_0 + string "serial high speed bus 0 name" + default "uart0" + config SERIAL_DRV_NAME_0 + string "serial high speed bus 0 driver name" + default "uart0_drv" + config SERIAL_0_DEVICE_NAME_0 + string "serial high speed bus 0 device 0 name" + default "uart0_dev0" + endif + +menuconfig BSP_USING_UART1 + bool "Enable UART1" + default y + if BSP_USING_UART1 + config BSP_UART1_TXD_PIN + int "uart1 TXD pin number" + default 19 + config BSP_UART1_RXD_PIN + int "uart1 RXD pin number" + default 18 + config SERIAL_BUS_NAME_1 + string "serial bus 1 name" + default "uart1" + config SERIAL_DRV_NAME_1 + string "serial bus 1 driver name" + default "uart1_drv" + config SERIAL_1_DEVICE_NAME_0 + string "serial bus 1 device 0 name" + default "uart1_dev1" + endif + +menuconfig BSP_USING_UART2 + bool "Enable UART2" + default y + if BSP_USING_UART2 + config BSP_UART2_TXD_PIN + int "uart2 TXD pin number" + default 20 + config BSP_UART2_RXD_PIN + int "uart2 RXD pin number" + default 21 + config SERIAL_BUS_NAME_2 + string "serial bus 2 name" + default "uart2" + config SERIAL_DRV_NAME_2 + string "serial bus 2 driver name" + default "uart2_drv" + config SERIAL_2_DEVICE_NAME_0 + string "serial bus 2 device 0 name" + default "uart2_dev2" + endif + +menuconfig BSP_USING_UART3 + bool "Enable UART3" + default y + if BSP_USING_UART3 + config BSP_UART3_TXD_PIN + int "uart3 TXD pin number" + default 22 + config BSP_UART3_RXD_PIN + int "uart3 RXD pin number" + default 23 + config SERIAL_BUS_NAME_3 + string "serial bus 3 name" + default "uart3" + config SERIAL_DRV_NAME_3 + string "serial bus 3 driver name" + default "uart3_drv" + config SERIAL_3_DEVICE_NAME_0 + string "serial bus 3 device 0 name" + default "uart3_dev3" + endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/uart/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/uart/Makefile new file mode 100644 index 000000000..7696ffaa7 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/uart/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_uart.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/uart/connect_uart.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/uart/connect_uart.c new file mode 100644 index 000000000..d60373bf5 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/uart/connect_uart.c @@ -0,0 +1,669 @@ +/* + * Copyright (c) 2020 RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + */ + +/** +* @file connect_uart.c +* @brief support edu-riscv64-board uart function and register to bus framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +/************************************************* +File name: connect_uart.c +Description: support edu-riscv64-board uart configure and uart bus register function +Others: take RT-Thread v4.0.2/bsp/k210/driver/drv_uart.c for references + https://github.com/RT-Thread/rt-thread/tree/v4.0.2 +History: +1. Date: 2022-10-17 +Author: AIIT XUOS Lab +Modification: +1. support edu-riscv64-board uart configure, write and read +2. support edu-riscv64-board uart bus device and driver register +*************************************************/ + +#include +#include +#include "plic.h" +#include "connect_uart.h" +#include "hardware_uart.h" +#include "hardware_uarths.h" + +static volatile UarthsT *const _uarths = (volatile UarthsT *)UARTHS_BASE_ADDR; + +/* START ported from kendryte standalone sdk uart.c */ +#define __UART_BRATE_CONST 16 + +volatile UartT* const _uart_new[3] = +{ + (volatile UartT*)UART1_BASE_ADDR, + (volatile UartT*)UART2_BASE_ADDR, + (volatile UartT*)UART3_BASE_ADDR +}; + +void _uart_init_new(UartDeviceNumberT channel) +{ + sysctl_clock_enable(SYSCTL_CLOCK_UART1 + channel); + sysctl_reset(SYSCTL_RESET_UART1 + channel); +} + +/* END ported from kendryte standalone sdk uart.c */ +static inline UartDeviceNumberT GetUartChannel(uint32 addr) +{ + switch (addr) + { + case UART1_BASE_ADDR: + return UART_DEVICE_1; + case UART2_BASE_ADDR: + return UART_DEVICE_2; + case UART3_BASE_ADDR: + return UART_DEVICE_3; + default: + return UART_DEVICE_MAX; + } +} + +extern void SerialSetIsr(struct SerialHardwareDevice *serial_dev, int event); + +static void SerialCfgParamCheck(struct SerialCfgParam *serial_cfg_default, struct SerialCfgParam *serial_cfg_new) +{ + struct SerialDataCfg *data_cfg_default = &serial_cfg_default->data_cfg; + struct SerialDataCfg *data_cfg_new = &serial_cfg_new->data_cfg; + + if ((data_cfg_default->serial_baud_rate != data_cfg_new->serial_baud_rate) && (data_cfg_new->serial_baud_rate)) { + data_cfg_default->serial_baud_rate = data_cfg_new->serial_baud_rate; + } + + if ((data_cfg_default->serial_bit_order != data_cfg_new->serial_bit_order) && (data_cfg_new->serial_bit_order)) { + data_cfg_default->serial_bit_order = data_cfg_new->serial_bit_order; + } + + if ((data_cfg_default->serial_buffer_size != data_cfg_new->serial_buffer_size) && (data_cfg_new->serial_buffer_size)) { + data_cfg_default->serial_buffer_size = data_cfg_new->serial_buffer_size; + } + + if ((data_cfg_default->serial_data_bits != data_cfg_new->serial_data_bits) && (data_cfg_new->serial_data_bits)) { + data_cfg_default->serial_data_bits = data_cfg_new->serial_data_bits; + } + + if ((data_cfg_default->serial_invert_mode != data_cfg_new->serial_invert_mode) && (data_cfg_new->serial_invert_mode)) { + data_cfg_default->serial_invert_mode = data_cfg_new->serial_invert_mode; + } + + if ((data_cfg_default->serial_parity_mode != data_cfg_new->serial_parity_mode) && (data_cfg_new->serial_parity_mode)) { + data_cfg_default->serial_parity_mode = data_cfg_new->serial_parity_mode; + } + + if ((data_cfg_default->serial_stop_bits != data_cfg_new->serial_stop_bits) && (data_cfg_new->serial_stop_bits)) { + data_cfg_default->serial_stop_bits = data_cfg_new->serial_stop_bits; + } + + if ((data_cfg_default->serial_timeout != data_cfg_new->serial_timeout) && (data_cfg_new->serial_timeout)) { + data_cfg_default->serial_timeout = data_cfg_new->serial_timeout; + } +} + +/* UARTHS ISR */ +static void UarthsIrqHandler(int irqno, void *param) +{ + struct SerialBus *serial_bus = (struct SerialBus *)param; + struct SerialDriver *serial_drv = (struct SerialDriver *)serial_bus->bus.owner_driver; + struct SerialHardwareDevice *serial_dev = (struct SerialHardwareDevice *)serial_bus->bus.owner_haldev; + struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_drv->private_data; + CHECK(UARTHS_BASE_ADDR == serial_cfg->hw_cfg.serial_register_base); + + /* read interrupt status and clear it */ + if(_uarths->ip.rxwm) + SerialSetIsr(serial_dev, SERIAL_EVENT_RX_IND); +} + +/* UART ISR */ +static void UartIrqHandler(int irqno, void *param) +{ + struct SerialBus *serial_bus = (struct SerialBus *)param; + struct SerialDriver *serial_drv = (struct SerialDriver *)serial_bus->bus.owner_driver; + struct SerialHardwareDevice *serial_dev = (struct SerialHardwareDevice *)serial_bus->bus.owner_haldev; + struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_drv->private_data; + + UartDeviceNumberT channel = GetUartChannel(serial_cfg->hw_cfg.serial_register_base); + CHECK(channel != UART_DEVICE_MAX); + + /* read interrupt status and clear it */ + if(_uart_new[channel]->LSR) + SerialSetIsr(serial_dev, SERIAL_EVENT_RX_IND); +} + +static uint32 SerialHsInit(struct SerialDriver *serial_drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(serial_drv); + + struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_drv->private_data; + + if (configure_info->private_data) { + struct SerialCfgParam *serial_cfg_new = (struct SerialCfgParam *)configure_info->private_data; + SerialCfgParamCheck(serial_cfg, serial_cfg_new); + } + + struct SerialHardwareDevice *serial_dev = (struct SerialHardwareDevice *)serial_drv->driver.owner_bus->owner_haldev; + struct SerialDevParam *dev_param = (struct SerialDevParam *)serial_dev->haldev.private_data; + + // config serial receive sem timeout + dev_param->serial_timeout = serial_cfg->data_cfg.serial_timeout; + + uint32 freq_hs = SysctlClockGetFreq(SYSCTL_CLOCK_CPU); + uint16 div_hs = freq_hs / serial_cfg->data_cfg.serial_baud_rate - 1; + + if (UARTHS_BASE_ADDR == serial_cfg->hw_cfg.serial_register_base) { + _uarths->div.div = div_hs; + _uarths->txctrl.txen = 1; + _uarths->rxctrl.rxen = 1; + _uarths->txctrl.txcnt = 0; + _uarths->rxctrl.rxcnt = 0; + _uarths->ip.txwm = 1; + _uarths->ip.rxwm = 1; + _uarths->ie.txwm = 0; + _uarths->ie.rxwm = 1; + } else { + KPrintf("SerialHsInit error base 0x%x\n", serial_cfg->hw_cfg.serial_register_base); + return ERROR; + } + + return EOK; +} + +static uint32 SerialHsConfigure(struct SerialDriver *serial_drv, int serial_operation_cmd) +{ + NULL_PARAM_CHECK(serial_drv); + + struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_drv->private_data; + struct SerialBus *serial_bus = CONTAINER_OF(serial_drv->driver.owner_bus, struct SerialBus, bus); + + switch (serial_operation_cmd) + { + case OPER_CLR_INT: + isrManager.done->disableIrq(serial_cfg->hw_cfg.serial_irq_interrupt); + break; + case OPER_SET_INT: + isrManager.done->registerIrq(serial_cfg->hw_cfg.serial_irq_interrupt, UarthsIrqHandler, serial_bus); + isrManager.done->enableIrq(serial_cfg->hw_cfg.serial_irq_interrupt); + break; + } + + return EOK; +} + +static int SerialHsPutChar(struct SerialHardwareDevice *serial_dev, char c) +{ + struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data; + CHECK(serial_cfg->hw_cfg.serial_register_base == UARTHS_BASE_ADDR); + + while (_uarths->txdata.full); + _uarths->txdata.data = (uint8)c; + + return EOK; +} + +static int SerialHsGetChar(struct SerialHardwareDevice *serial_dev) +{ + struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data; + CHECK(serial_cfg->hw_cfg.serial_register_base == UARTHS_BASE_ADDR); + + uarths_rxdata_t recv = _uarths->rxdata; + if (recv.empty) + return -ERROR; + else + return (recv.data & 0xff); + + return -ERROR; +} + +static uint32 SerialInit(struct SerialDriver *serial_drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(serial_drv); + struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_drv->private_data; + + if (configure_info->private_data) { + struct SerialCfgParam *serial_cfg_new = (struct SerialCfgParam *)configure_info->private_data; + SerialCfgParamCheck(serial_cfg, serial_cfg_new); + } + + struct SerialHardwareDevice *serial_dev = (struct SerialHardwareDevice *)serial_drv->driver.owner_bus->owner_haldev; + struct SerialDevParam *dev_param = (struct SerialDevParam *)serial_dev->haldev.private_data; + + // config serial receive sem timeout + dev_param->serial_timeout = serial_cfg->data_cfg.serial_timeout; + + UartBitwidthPointer DataWidth = (UartBitwidthPointer)serial_cfg->data_cfg.serial_data_bits; + UartStopbitT stopbit = (UartStopbitT)(serial_cfg->data_cfg.serial_stop_bits - 1); + UartParityT parity = (UartParityT)(serial_cfg->data_cfg.serial_parity_mode - 1); + + uint32 freq = SysctlClockGetFreq(SYSCTL_CLOCK_APB0); + uint32 divisor = freq / (uint32)serial_cfg->data_cfg.serial_baud_rate; + uint8 dlh = divisor >> 12; + uint8 dll = (divisor - (dlh << 12)) / __UART_BRATE_CONST; + uint8 dlf = divisor - (dlh << 12) - dll * __UART_BRATE_CONST; + + UartDeviceNumberT channel = GetUartChannel(serial_cfg->hw_cfg.serial_register_base); + CHECK(channel != UART_DEVICE_MAX); + + CHECK(DataWidth >= 5 && DataWidth <= 8); + if (DataWidth == 5) { + CHECK(stopbit != UART_STOP_2); + } else { + CHECK(stopbit != UART_STOP_1_5); + } + + uint32 stopbit_val = stopbit == UART_STOP_1 ? 0 : 1; + uint32 ParityVal; + switch (parity) + { + case UART_PARITY_NONE: + ParityVal = 0; + break; + case UART_PARITY_ODD: + ParityVal = 1; + break; + case UART_PARITY_EVEN: + ParityVal = 3; + break; + default: + CHECK(!"Invalid parity"); + break; + } + + _uart_new[channel]->LCR |= 1u << 7; + _uart_new[channel]->DLH = dlh; + _uart_new[channel]->DLL = dll; + _uart_new[channel]->DLF = dlf; + _uart_new[channel]->LCR = 0; + _uart_new[channel]->LCR = (DataWidth - 5) | + (stopbit_val << 2) | + (ParityVal << 3); + _uart_new[channel]->LCR &= ~(1u << 7); + _uart_new[channel]->IER |= 0x80; /* THRE */ + _uart_new[channel]->FCR = UART_RECEIVE_FIFO_1 << 6 | + UART_SEND_FIFO_8 << 4 | + 0x1 << 3 | + 0x1; + + return EOK; +} + +static uint32 SerialConfigure(struct SerialDriver *serial_drv, int serial_operation_cmd) +{ + NULL_PARAM_CHECK(serial_drv); + + struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_drv->private_data; + struct SerialBus *serial_bus = CONTAINER_OF(serial_drv->driver.owner_bus, struct SerialBus, bus); + + UartDeviceNumberT channel = GetUartChannel(serial_cfg->hw_cfg.serial_register_base); + CHECK(channel != UART_DEVICE_MAX); + + switch (serial_operation_cmd) + { + case OPER_CLR_INT: + /* Disable the UART Interrupt */ + isrManager.done->disableIrq(serial_cfg->hw_cfg.serial_irq_interrupt); + _uart_new[channel]->IER &= ~0x1; + break; + case OPER_SET_INT: + /* install interrupt */ + isrManager.done->registerIrq(serial_cfg->hw_cfg.serial_irq_interrupt, UartIrqHandler, serial_bus); + isrManager.done->enableIrq(serial_cfg->hw_cfg.serial_irq_interrupt); + _uart_new[channel]->IER |= 0x1; + break; + } + + return EOK; +} + +static int SerialPutChar(struct SerialHardwareDevice *serial_dev, char c) +{ + struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data; + UartDeviceNumberT channel = GetUartChannel(serial_cfg->hw_cfg.serial_register_base); + CHECK(channel != UART_DEVICE_MAX); + + while (_uart_new[channel]->LSR & (1u << 5)); + _uart_new[channel]->THR = c; + + return EOK; +} + +static int SerialGetChar(struct SerialHardwareDevice *serial_dev) +{ + struct SerialCfgParam *serial_cfg = (struct SerialCfgParam *)serial_dev->private_data; + UartDeviceNumberT channel = GetUartChannel(serial_cfg->hw_cfg.serial_register_base); + CHECK(channel != UART_DEVICE_MAX); + + if (_uart_new[channel]->LSR & 1) + return (char)(_uart_new[channel]->RBR & 0xff); + else + return -ERROR; + + return -ERROR; +} + +static uint32 SerialHsDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + + x_err_t ret = EOK; + int serial_operation_cmd; + struct SerialDriver *serial_drv = (struct SerialDriver *)drv; + + switch (configure_info->configure_cmd) + { + case OPE_INT: + ret = SerialHsInit(serial_drv, configure_info); + break; + case OPE_CFG: + serial_operation_cmd = *((int *)configure_info->private_data); + ret = SerialHsConfigure(serial_drv, serial_operation_cmd); + break; + default: + break; + } + + return ret; +} + +static uint32 SerialDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + + x_err_t ret = EOK; + int serial_operation_cmd; + struct SerialDriver *serial_drv = (struct SerialDriver *)drv; + + switch (configure_info->configure_cmd) + { + case OPE_INT: + ret = SerialInit(serial_drv, configure_info); + break; + case OPE_CFG: + serial_operation_cmd = *(int *)configure_info->private_data; + ret = SerialConfigure(serial_drv, serial_operation_cmd); + break; + default: + break; + } + + return ret; +} + +static const struct SerialDataCfg data_cfg_init = +{ + .serial_baud_rate = BAUD_RATE_115200, + .serial_data_bits = DATA_BITS_8, + .serial_stop_bits = STOP_BITS_1, + .serial_parity_mode = PARITY_NONE, + .serial_bit_order = BIT_ORDER_LSB, + .serial_invert_mode = NRZ_NORMAL, + .serial_buffer_size = SERIAL_RB_BUFSZ, + .serial_timeout = WAITING_FOREVER, +}; + +/*manage the serial high speed device operations*/ +static const struct SerialDrvDone drv_done_hs = +{ + .init = SerialHsInit, + .configure = SerialHsConfigure, +}; + +/*manage the serial high speed device hal operations*/ +static struct SerialHwDevDone hwdev_done_hs = +{ + .put_char = SerialHsPutChar, + .get_char = SerialHsGetChar, +}; + +/*manage the serial device operations*/ +static const struct SerialDrvDone drv_done = +{ + .init = SerialInit, + .configure = SerialConfigure, +}; + +/*manage the serial device hal operations*/ +static struct SerialHwDevDone hwdev_done = +{ + .put_char = SerialPutChar, + .get_char = SerialGetChar, +}; + +static int BoardSerialBusInit(struct SerialBus *serial_bus, struct SerialDriver *serial_driver, const char *bus_name, const char *drv_name) +{ + x_err_t ret = EOK; + + /*Init the serial bus */ + ret = SerialBusInit(serial_bus, bus_name); + if (EOK != ret) { + KPrintf("hw_serial_init SerialBusInit error %d\n", ret); + return ERROR; + } + + /*Init the serial driver*/ + ret = SerialDriverInit(serial_driver, drv_name); + if (EOK != ret) { + KPrintf("hw_serial_init SerialDriverInit error %d\n", ret); + return ERROR; + } + + /*Attach the serial driver to the serial bus*/ + ret = SerialDriverAttachToBus(drv_name, bus_name); + if (EOK != ret) { + KPrintf("hw_serial_init SerialDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +/*Attach the serial device to the serial bus*/ +static int BoardSerialDevBend(struct SerialHardwareDevice *serial_device, void *serial_param, const char *bus_name, const char *dev_name) +{ + x_err_t ret = EOK; + + ret = SerialDeviceRegister(serial_device, serial_param, dev_name); + if (EOK != ret) { + KPrintf("hw_serial_init SerialDeviceInit device %s error %d\n", dev_name, ret); + return ERROR; + } + + ret = SerialDeviceAttachToBus(dev_name, bus_name); + if (EOK != ret) { + KPrintf("hw_serial_init SerialDeviceAttachToBus device %s error %d\n", dev_name, ret); + return ERROR; + } + + return ret; +} + +int HwUartInit(void) +{ + x_err_t ret = EOK; + +#ifdef BSP_USING_UART_HS + static struct SerialBus serial_bus_hs; + memset(&serial_bus_hs, 0, sizeof(struct SerialBus)); + + static struct SerialDriver serial_driver_hs; + memset(&serial_driver_hs, 0, sizeof(struct SerialDriver)); + + static struct SerialHardwareDevice serial_device_hs; + memset(&serial_device_hs, 0, sizeof(struct SerialHardwareDevice)); + + static struct SerialCfgParam serial_cfg_hs; + memset(&serial_cfg_hs, 0, sizeof(struct SerialCfgParam)); + + static struct SerialDevParam serial_dev_param_hs; + memset(&serial_dev_param_hs, 0, sizeof(struct SerialDevParam)); + + serial_driver_hs.drv_done = &drv_done_hs; + serial_driver_hs.configure = &SerialHsDrvConfigure; + serial_device_hs.hwdev_done = &hwdev_done_hs; + + serial_cfg_hs.data_cfg = data_cfg_init; + + serial_cfg_hs.hw_cfg.serial_register_base = UARTHS_BASE_ADDR; + serial_cfg_hs.hw_cfg.serial_irq_interrupt = IRQN_UARTHS_INTERRUPT; + serial_driver_hs.private_data = (void *)&serial_cfg_hs; + + serial_dev_param_hs.serial_work_mode = SIGN_OPER_INT_RX; + serial_device_hs.haldev.private_data = (void *)&serial_dev_param_hs; + + ret = BoardSerialBusInit(&serial_bus_hs, &serial_driver_hs, SERIAL_BUS_NAME_0, SERIAL_DRV_NAME_0); + if (EOK != ret) { + KPrintf("hw_serial_init uarths error ret %u\n", ret); + return ERROR; + } + + ret = BoardSerialDevBend(&serial_device_hs, (void *)&serial_cfg_hs, SERIAL_BUS_NAME_0, SERIAL_0_DEVICE_NAME_0); + if (EOK != ret) { + KPrintf("hw_serial_init uarths error ret %u\n", ret); + return ERROR; + } +#endif + +#ifdef BSP_USING_UART1 + static struct SerialBus serial_bus_1; + memset(&serial_bus_1, 0, sizeof(struct SerialBus)); + + static struct SerialDriver serial_driver_1; + memset(&serial_driver_1, 0, sizeof(struct SerialDriver)); + + static struct SerialHardwareDevice serial_device_1; + memset(&serial_device_1, 0, sizeof(struct SerialHardwareDevice)); + + static struct SerialCfgParam serial_cfg_1; + memset(&serial_cfg_1, 0, sizeof(struct SerialCfgParam)); + + static struct SerialDevParam serial_dev_param_1; + memset(&serial_dev_param_1, 0, sizeof(struct SerialDevParam)); + + serial_driver_1.drv_done = &drv_done; + serial_driver_1.configure = &SerialDrvConfigure; + serial_device_1.hwdev_done = &hwdev_done; + + serial_cfg_1.data_cfg = data_cfg_init; + + serial_cfg_1.hw_cfg.serial_register_base = UART1_BASE_ADDR; + serial_cfg_1.hw_cfg.serial_irq_interrupt = IRQN_UART1_INTERRUPT; + serial_driver_1.private_data = (void *)&serial_cfg_1; + + serial_dev_param_1.serial_work_mode = SIGN_OPER_INT_RX; + serial_device_1.haldev.private_data = (void *)&serial_dev_param_1; + + _uart_init_new(UART_DEVICE_1); + + ret = BoardSerialBusInit(&serial_bus_1, &serial_driver_1, SERIAL_BUS_NAME_1, SERIAL_DRV_NAME_1); + if (EOK != ret) { + KPrintf("hw_serial_init uart1 error ret %u\n", ret); + return ERROR; + } + + ret = BoardSerialDevBend(&serial_device_1, (void *)&serial_cfg_1, SERIAL_BUS_NAME_1, SERIAL_1_DEVICE_NAME_0); + if (EOK != ret) { + KPrintf("hw_serial_init uart1 error ret %u\n", ret); + return ERROR; + } +#endif + +#ifdef BSP_USING_UART2 + static struct SerialBus serial_bus_2; + memset(&serial_bus_2, 0, sizeof(struct SerialBus)); + + static struct SerialDriver serial_driver_2; + memset(&serial_driver_2, 0, sizeof(struct SerialDriver)); + + static struct SerialHardwareDevice serial_device_2; + memset(&serial_device_2, 0, sizeof(struct SerialHardwareDevice)); + + static struct SerialCfgParam serial_cfg_2; + memset(&serial_cfg_2, 0, sizeof(struct SerialCfgParam)); + + static struct SerialDevParam serial_dev_param_2; + memset(&serial_dev_param_2, 0, sizeof(struct SerialDevParam)); + + serial_driver_2.drv_done = &drv_done; + serial_driver_2.configure = &SerialDrvConfigure; + serial_device_2.hwdev_done = &hwdev_done; + + serial_cfg_2.data_cfg = data_cfg_init; + + serial_cfg_2.hw_cfg.serial_register_base = UART2_BASE_ADDR; + serial_cfg_2.hw_cfg.serial_irq_interrupt = IRQN_UART2_INTERRUPT; + serial_driver_2.private_data = (void *)&serial_cfg_2; + + serial_dev_param_2.serial_work_mode = SIGN_OPER_INT_RX; + serial_device_2.haldev.private_data = (void *)&serial_dev_param_2; + + _uart_init_new(UART_DEVICE_2); + + ret = BoardSerialBusInit(&serial_bus_2, &serial_driver_2, SERIAL_BUS_NAME_2, SERIAL_DRV_NAME_2); + if (EOK != ret) { + KPrintf("hw_serial_init uart2 error ret %u\n", ret); + return ERROR; + } + + ret = BoardSerialDevBend(&serial_device_2, (void *)&serial_cfg_2, SERIAL_BUS_NAME_2, SERIAL_2_DEVICE_NAME_0); + if (EOK != ret) { + KPrintf("hw_serial_init uart2 error ret %u\n", ret); + return ERROR; + } +#endif + +#ifdef BSP_USING_UART3 + static struct SerialBus serial_bus_3; + memset(&serial_bus_3, 0, sizeof(struct SerialBus)); + + static struct SerialDriver serial_driver_3; + memset(&serial_driver_3, 0, sizeof(struct SerialDriver)); + + static struct SerialHardwareDevice serial_device_3; + memset(&serial_device_3, 0, sizeof(struct SerialHardwareDevice)); + + static struct SerialCfgParam serial_cfg_3; + memset(&serial_cfg_3, 0, sizeof(struct SerialCfgParam)); + + static struct SerialDevParam serial_dev_param_3; + memset(&serial_dev_param_3, 0, sizeof(struct SerialDevParam)); + + serial_driver_3.drv_done = &drv_done; + serial_driver_3.configure = &SerialDrvConfigure; + serial_device_3.hwdev_done = &hwdev_done; + + serial_cfg_3.data_cfg = data_cfg_init; + + serial_cfg_3.hw_cfg.serial_register_base = UART3_BASE_ADDR; + serial_cfg_3.hw_cfg.serial_irq_interrupt = IRQN_UART3_INTERRUPT; + serial_driver_3.private_data = (void *)&serial_cfg_3; + + serial_dev_param_3.serial_work_mode = SIGN_OPER_INT_RX; + serial_device_3.haldev.private_data = (void *)&serial_dev_param_3; + + _uart_init_new(UART_DEVICE_3); + + ret = BoardSerialBusInit(&serial_bus_3, &serial_driver_3, SERIAL_BUS_NAME_3, SERIAL_DRV_NAME_3); + if (EOK != ret) { + KPrintf("hw_serial_init uart3 error ret %u\n", ret); + return ERROR; + } + + ret = BoardSerialDevBend(&serial_device_3, (void *)&serial_cfg_3, SERIAL_BUS_NAME_3, SERIAL_3_DEVICE_NAME_0); + if (EOK != ret) { + KPrintf("hw_serial_init uart3 error ret %u\n", ret); + return ERROR; + } +#endif + + return ret; +} diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/uart/hardware_uart.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/uart/hardware_uart.c new file mode 100644 index 000000000..60684141d --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/uart/hardware_uart.c @@ -0,0 +1,424 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file hardware_uart.c +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#include +#include +#include "plic.h" +#include "sysctl.h" +#include "hardware_uart.h" +#include "utils.h" +#include "bsp_atomic.h" + +#define __UART_BRATE_CONST 16 + +volatile UartT* const uart[3] = +{ + (volatile UartT*)UART1_BASE_ADDR, + (volatile UartT*)UART2_BASE_ADDR, + (volatile UartT*)UART3_BASE_ADDR +}; + +#define UART_INTERRUPT_SEND 0x02U +#define UART_INTERRUPT_RECEIVE 0x04U +#define UART_INTERRUPT_CHARACTER_TIMEOUT 0x0CU + +typedef struct UartInterruptInstance +{ + plic_irq_callback_t callback; + void *ctx; +} UartInterruptInstanceT; + +typedef struct UartInstance +{ + UartInterruptInstanceT UartReceiveInstance; + UartInterruptInstanceT UartSendInstance; + uint32_t UartNum; +} UartInstancePointer; + +UartInstancePointer GUartInstance[3]; + +typedef struct UartDmaInstance +{ + uint8_t *buffer; + size_t BufLen; + uint32_t *MallocBuffer; + UartInterruptModeT IntMode; + dmac_channel_number_t dmac_channel; + UartDeviceNumberT UartNum; + UartInterruptInstanceT UartIntInstance; +} UartDmaInstanceT; + +UartDmaInstanceT uart_send_dma_instance[3]; +UartDmaInstanceT UartRecvDmaInstance[3]; + +typedef struct UartInstanceDma +{ + UartDeviceNumberT UartNum; + UartInterruptModeT TransferMode; + dmac_channel_number_t dmac_channel; + plic_instance_t UartIntInstance; + spinlock_t lock; +} UartInstanceDmaT; + +static UartInstanceDmaT GUartSendInstanceDma[3]; +static UartInstanceDmaT GUartRecvInstanceDma[3]; + +volatile int GWriteCount = 0; + +static int UartIrqCallback(void *param) +{ + UartInstancePointer *uart_instance = (UartInstancePointer *)param; + uint32_t v_channel = uart_instance->UartNum; + uint8_t VIntStatus = uart[v_channel]->IIR & 0xF; + + if(VIntStatus == UART_INTERRUPT_SEND && GWriteCount != 0) + { + if(uart_instance->UartSendInstance.callback != NULL) + uart_instance->UartSendInstance.callback(uart_instance->UartSendInstance.ctx); + } + else if(VIntStatus == UART_INTERRUPT_RECEIVE || VIntStatus == UART_INTERRUPT_CHARACTER_TIMEOUT) + { + if(uart_instance->UartReceiveInstance.callback != NULL) + uart_instance->UartReceiveInstance.callback(uart_instance->UartReceiveInstance.ctx); + } + return 0; +} + +static int UartapbPutc(UartDeviceNumberT channel, char c) +{ + while (uart[channel]->LSR & (1u << 5)) + continue; + uart[channel]->THR = c; + return 0; +} + +int UartapbGetc(UartDeviceNumberT channel) +{ + while (!(uart[channel]->LSR & 1)) + continue; + + return (char)(uart[channel]->RBR & 0xff); +} + +static int UartDmaCallback(void *ctx) +{ + UartDmaInstanceT *VUartDmaInstance = (UartDmaInstanceT *)ctx; + dmac_channel_number_t dmac_channel = VUartDmaInstance->dmac_channel; + dmac_irq_unregister(dmac_channel); + + if(VUartDmaInstance->IntMode == UART_RECEIVE) + { + size_t VBufLen = VUartDmaInstance->BufLen; + uint8_t *VBuffer = VUartDmaInstance->buffer; + uint32_t *VRecvBuffer = VUartDmaInstance->MallocBuffer; + for(size_t i = 0; i < VBufLen; i++) + { + VBuffer[i] = VRecvBuffer[i]; + } + } + free(VUartDmaInstance->MallocBuffer); + if(VUartDmaInstance->UartIntInstance.callback) + VUartDmaInstance->UartIntInstance.callback(VUartDmaInstance->UartIntInstance.ctx); + return 0; +} + +int UartReceiveData(UartDeviceNumberT channel, char *buffer, size_t BufLen) +{ + size_t i = 0; + for(i = 0;i < BufLen; i++) + { + if(uart[channel]->LSR & 1) + buffer[i] = (char)(uart[channel]->RBR & 0xff); + else + break; + } + return i; +} + +void UartReceiveDataDma(UartDeviceNumberT uart_channel, dmac_channel_number_t dmac_channel, uint8_t *buffer, size_t BufLen) +{ + uint32_t *VRecvBuf = malloc(BufLen * sizeof(uint32_t)); + configASSERT(VRecvBuf!=NULL); + + sysctl_dma_select((sysctl_dma_channel_t)dmac_channel, SYSCTL_DMA_SELECT_UART1_RX_REQ + uart_channel * 2); + dmac_set_single_mode(dmac_channel, (void *)(&uart[uart_channel]->RBR), VRecvBuf, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, BufLen); + dmac_wait_done(dmac_channel); + for(uint32_t i = 0; i < BufLen; i++) + { + buffer[i] = (uint8_t)(VRecvBuf[i] & 0xff); + } + free(VRecvBuf); +} + +void UartReceiveDataDmaIrq(UartDeviceNumberT uart_channel, dmac_channel_number_t dmac_channel, + uint8_t *buffer, size_t BufLen, plic_irq_callback_t uart_callback, + void *ctx, uint32_t priority) +{ + uint32_t *VRecvBuf = malloc(BufLen * sizeof(uint32_t)); + configASSERT(VRecvBuf!=NULL); + + UartRecvDmaInstance[uart_channel].dmac_channel = dmac_channel; + UartRecvDmaInstance[uart_channel].UartNum = uart_channel; + UartRecvDmaInstance[uart_channel].MallocBuffer = VRecvBuf; + UartRecvDmaInstance[uart_channel].buffer = buffer; + UartRecvDmaInstance[uart_channel].BufLen = BufLen; + UartRecvDmaInstance[uart_channel].IntMode = UART_RECEIVE; + UartRecvDmaInstance[uart_channel].UartIntInstance.callback = uart_callback; + UartRecvDmaInstance[uart_channel].UartIntInstance.ctx = ctx; + + dmac_irq_register(dmac_channel, UartDmaCallback, &UartRecvDmaInstance[uart_channel], priority); + sysctl_dma_select((sysctl_dma_channel_t)dmac_channel, SYSCTL_DMA_SELECT_UART1_RX_REQ + uart_channel * 2); + dmac_set_single_mode(dmac_channel, (void *)(&uart[uart_channel]->RBR), VRecvBuf, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, BufLen); +} + +int UartSendData(UartDeviceNumberT channel, const char *buffer, size_t BufLen) +{ + GWriteCount = 0; + while (GWriteCount < BufLen) + { + UartapbPutc(channel, *buffer++); + GWriteCount++; + } + return GWriteCount; +} + +void UartSendDataDma(UartDeviceNumberT uart_channel, dmac_channel_number_t dmac_channel, const uint8_t *buffer, size_t BufLen) +{ + uint32_t *VSendBuf = malloc(BufLen * sizeof(uint32_t)); + configASSERT(VSendBuf!=NULL); + for(uint32_t i = 0; i < BufLen; i++) + VSendBuf[i] = buffer[i]; + sysctl_dma_select((sysctl_dma_channel_t)dmac_channel, SYSCTL_DMA_SELECT_UART1_TX_REQ + uart_channel * 2); + dmac_set_single_mode(dmac_channel, VSendBuf, (void *)(&uart[uart_channel]->THR), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, BufLen); + dmac_wait_done(dmac_channel); + free((void *)VSendBuf); +} + +void UartSendDataDmaIrq(UartDeviceNumberT uart_channel, dmac_channel_number_t dmac_channel, + const uint8_t *buffer, size_t BufLen, plic_irq_callback_t uart_callback, + void *ctx, uint32_t priority) +{ + uint32_t *VSendBuf = malloc(BufLen * sizeof(uint32_t)); + configASSERT(VSendBuf!=NULL); + + uart_send_dma_instance[uart_channel] = (UartDmaInstanceT) { + .dmac_channel = dmac_channel, + .UartNum = uart_channel, + .MallocBuffer = VSendBuf, + .buffer = (uint8_t *)buffer, + .BufLen = BufLen, + .IntMode = UART_SEND, + .UartIntInstance.callback = uart_callback, + .UartIntInstance.ctx = ctx, + }; + + for(uint32_t i = 0; i < BufLen; i++) + VSendBuf[i] = buffer[i]; + dmac_irq_register(dmac_channel, UartDmaCallback, &uart_send_dma_instance[uart_channel], priority); + sysctl_dma_select((sysctl_dma_channel_t)dmac_channel, SYSCTL_DMA_SELECT_UART1_TX_REQ + uart_channel * 2); + dmac_set_single_mode(dmac_channel, VSendBuf, (void *)(&uart[uart_channel]->THR), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, BufLen); + +} + +void uart_configure(UartDeviceNumberT channel, uint32_t BaudRate, UartBitwidthPointer DataWidth, UartStopbitT stopbit, UartParityT parity) +{ + configASSERT(DataWidth >= 5 && DataWidth <= 8); + if (DataWidth == 5) + { + configASSERT(stopbit != UART_STOP_2); + } + else + { + configASSERT(stopbit != UART_STOP_1_5); + } + + uint32_t stopbit_val = stopbit == UART_STOP_1 ? 0 : 1; + uint32_t ParityVal; + switch (parity) + { + case UART_PARITY_NONE: + ParityVal = 0; + break; + case UART_PARITY_ODD: + ParityVal = 1; + break; + case UART_PARITY_EVEN: + ParityVal = 3; + break; + default: + configASSERT(!"Invalid parity"); + break; + } + + uint32_t freq = SysctlClockGetFreq(SYSCTL_CLOCK_APB0); + uint32_t divisor = freq / BaudRate; + uint8_t dlh = divisor >> 12; + uint8_t dll = (divisor - (dlh << 12)) / __UART_BRATE_CONST; + uint8_t dlf = divisor - (dlh << 12) - dll * __UART_BRATE_CONST; + + /* Set UART registers */ + uart[channel]->TCR &= ~(1u); + uart[channel]->TCR &= ~(1u << 3); + uart[channel]->TCR &= ~(1u << 4); + uart[channel]->TCR |= (1u << 2); + uart[channel]->TCR &= ~(1u << 1); + uart[channel]->DE_EN &= ~(1u); + + uart[channel]->LCR |= 1u << 7; + uart[channel]->DLH = dlh; + uart[channel]->DLL = dll; + uart[channel]->DLF = dlf; + uart[channel]->LCR = 0; + uart[channel]->LCR = (DataWidth - 5) | (stopbit_val << 2) | (ParityVal << 3); + uart[channel]->LCR &= ~(1u << 7); + uart[channel]->MCR &= ~3; + uart[channel]->IER |= 0x80; /* THRE */ + uart[channel]->FCR = UART_RECEIVE_FIFO_1 << 6 | UART_SEND_FIFO_8 << 4 | 0x1 << 3 | 0x1; +} + +void __attribute__((weak, alias("uart_configure"))) +uart_config(UartDeviceNumberT channel, uint32_t BaudRate, UartBitwidthPointer DataWidth, UartStopbitT stopbit, UartParityT parity); + +void UartInit(UartDeviceNumberT channel) +{ + sysctl_clock_enable(SYSCTL_CLOCK_UART1 + channel); +} + +void UartSetSendTrigger(UartDeviceNumberT channel, uart_send_trigger_t trigger) +{ + uart[channel]->STET = trigger; +} + +void uart_set_receive_trigger(UartDeviceNumberT channel, uart_receive_trigger_t trigger) +{ + uart[channel]->SRT = trigger; +} + +void uart_irq_register(UartDeviceNumberT channel, UartInterruptModeT interrupt_mode, plic_irq_callback_t uart_callback, void *ctx, uint32_t priority) +{ + if(interrupt_mode == UART_SEND) + { + uart[channel]->IER |= 0x2; + GUartInstance[channel].UartSendInstance.callback = uart_callback; + GUartInstance[channel].UartSendInstance.ctx = ctx; + } + else if(interrupt_mode == UART_RECEIVE) + { + uart[channel]->IER |= 0x1; + GUartInstance[channel].UartReceiveInstance.callback = uart_callback; + GUartInstance[channel].UartReceiveInstance.ctx = ctx; + } + GUartInstance[channel].UartNum = channel; + plic_set_priority(IRQN_UART1_INTERRUPT + channel, priority); + plic_irq_register(IRQN_UART1_INTERRUPT + channel, UartIrqCallback, &GUartInstance[channel]); + plic_irq_enable(IRQN_UART1_INTERRUPT + channel); +} + +void uart_irq_unregister(UartDeviceNumberT channel, UartInterruptModeT interrupt_mode) +{ + if(interrupt_mode == UART_SEND) + { + uart[channel]->IER &= ~(0x2); + GUartInstance[channel].UartSendInstance.callback = NULL; + GUartInstance[channel].UartSendInstance.ctx = NULL; + } + else if(interrupt_mode == UART_RECEIVE) + { + uart[channel]->IER &= ~(0x1); + GUartInstance[channel].UartReceiveInstance.callback = NULL; + GUartInstance[channel].UartReceiveInstance.ctx = NULL; + } + if(uart[channel]->IER == 0) + { + plic_irq_unregister(IRQN_UART1_INTERRUPT + channel); + } +} + +int uart_dma_irq(void *ctx) +{ + UartInstanceDmaT *v_instance = (UartInstanceDmaT *)ctx; + dmac_irq_unregister(v_instance->dmac_channel); + if(v_instance->TransferMode == UART_SEND) + { + while(!(uart[v_instance->UartNum]->LSR & (1u << 6))); + } + spinlock_unlock(&v_instance->lock); + if(v_instance->UartIntInstance.callback) + { + v_instance->UartIntInstance.callback(v_instance->UartIntInstance.ctx); + } + return 0; +} + +void uart_handle_data_dma(UartDeviceNumberT uart_channel ,uart_data_t data, plic_interrupt_t *cb) +{ + configASSERT(uart_channel < UART_DEVICE_MAX); + if(data.TransferMode == UART_SEND) + { + configASSERT(data.tx_buf && data.tx_len && data.tx_channel < DMAC_CHANNEL_MAX); + spinlock_lock(&GUartSendInstanceDma[uart_channel].lock); + if(cb) + { + GUartSendInstanceDma[uart_channel].UartIntInstance.callback = cb->callback; + GUartSendInstanceDma[uart_channel].UartIntInstance.ctx = cb->ctx; + GUartSendInstanceDma[uart_channel].dmac_channel = data.tx_channel; + GUartSendInstanceDma[uart_channel].TransferMode = UART_SEND; + dmac_irq_register(data.tx_channel, uart_dma_irq, &GUartSendInstanceDma[uart_channel], cb->priority); + } + sysctl_dma_select((sysctl_dma_channel_t)data.tx_channel, SYSCTL_DMA_SELECT_UART1_TX_REQ + uart_channel * 2); + dmac_set_single_mode(data.tx_channel, data.tx_buf, (void *)(&uart[uart_channel]->THR), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, data.tx_len); + if(!cb) + { + dmac_wait_done(data.tx_channel); + while(!(uart[uart_channel]->LSR & (1u << 6))); + spinlock_unlock(&GUartSendInstanceDma[uart_channel].lock); + } + } + else + { + configASSERT(data.rx_buf && data.rx_len && data.rx_channel < DMAC_CHANNEL_MAX); + spinlock_lock(&GUartRecvInstanceDma[uart_channel].lock); + if(cb) + { + GUartRecvInstanceDma[uart_channel].UartIntInstance.callback = cb->callback; + GUartRecvInstanceDma[uart_channel].UartIntInstance.ctx = cb->ctx; + GUartRecvInstanceDma[uart_channel].dmac_channel = data.rx_channel; + GUartRecvInstanceDma[uart_channel].TransferMode = UART_RECEIVE; + dmac_irq_register(data.rx_channel, uart_dma_irq, &GUartRecvInstanceDma[uart_channel], cb->priority); + } + sysctl_dma_select((sysctl_dma_channel_t)data.rx_channel, SYSCTL_DMA_SELECT_UART1_RX_REQ + uart_channel * 2); + dmac_set_single_mode(data.rx_channel, (void *)(&uart[uart_channel]->RBR), data.rx_buf, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT, + DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, data.rx_len); + if(!cb) + { + dmac_wait_done(data.rx_channel); + spinlock_unlock(&GUartRecvInstanceDma[uart_channel].lock); + } + } +} diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/uart/hardware_uarths.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/uart/hardware_uarths.c new file mode 100644 index 000000000..fc2bcae2d --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/uart/hardware_uarths.c @@ -0,0 +1,184 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file hardware_uarths.c +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-10-17 +*/ + +#include +#include +#include "hardware_uarths.h" +#include "sysctl.h" +#include "encoding.h" + +volatile UarthsT *const uarths = (volatile UarthsT *)UARTHS_BASE_ADDR; + +typedef struct _uarths_instance +{ + plic_irq_callback_t callback; + void *ctx; + uarths_interrupt_mode_t uarths_interrupt_mode; +} uarths_instance_t; + +uarths_instance_t g_uarths_instance; + +uarths_interrupt_mode_t uarths_get_interrupt_mode(void) +{ + uint32_t v_rx_interrupt = uarths->ip.rxwm; + uint32_t v_tx_interrupt = uarths->ip.txwm; + return (v_rx_interrupt << 1) | v_tx_interrupt; +} + +int uarths_irq_callback(void *ctx) +{ + uarths_instance_t *uart_context = (uarths_instance_t *)ctx; + + if(uart_context->callback) + uart_context->callback(uart_context->ctx); + return 0; +} + +void uarths_set_interrupt_cnt(uarths_interrupt_mode_t interrupt_mode, uint8_t cnt) +{ + switch(interrupt_mode) + { + case UARTHS_SEND: + uarths->txctrl.txcnt = cnt; + break; + case UARTHS_RECEIVE: + uarths->rxctrl.rxcnt = cnt; + break; + case UARTHS_SEND_RECEIVE: + default: + uarths->txctrl.txcnt = cnt; + uarths->rxctrl.rxcnt = cnt; + break; + } +} + +void uarths_set_irq(uarths_interrupt_mode_t interrupt_mode, plic_irq_callback_t uarths_callback, void *ctx, uint32_t priority) +{ + g_uarths_instance.callback = uarths_callback; + g_uarths_instance.ctx = ctx; + + switch(interrupt_mode) + { + case UARTHS_SEND: + uarths->ie.txwm = 1; + uarths->ie.rxwm = 0; + break; + case UARTHS_RECEIVE: + uarths->ie.txwm = 0; + uarths->ie.rxwm = 1; + break; + default: + uarths->ie.txwm = 1; + uarths->ie.rxwm = 1; + break; + } + g_uarths_instance.uarths_interrupt_mode = interrupt_mode; + + plic_set_priority(IRQN_UARTHS_INTERRUPT, priority); + plic_irq_register(IRQN_UARTHS_INTERRUPT, uarths_irq_callback, &g_uarths_instance); + plic_irq_enable(IRQN_UARTHS_INTERRUPT); +} + +static inline int uarths_putc(char c) +{ + while (uarths->txdata.full) + continue; + uarths->txdata.data = (uint8_t)c; + + return 0; +} + +size_t uarths_receive_data(uint8_t *buf, size_t BufLen) +{ + size_t i; + for(i = 0; i < BufLen; i++) + { + uarths_rxdata_t recv = uarths->rxdata; + if(recv.empty) + break; + else + buf[i] = (recv.data & 0xFF); + } + return i; +} + +size_t uarths_send_data(const uint8_t *buf, size_t BufLen) +{ + size_t write = 0; + while (write < BufLen) + { + uarths_putc(*buf++); + write++; + } + return write; +} + +int uarths_getc(void) +{ + /* while not empty */ + uarths_rxdata_t recv = uarths->rxdata; + + if (recv.empty) + return EOF; + else + return recv.data; +} + +int uarths_putchar(char c) +{ + return uarths_putc(c); +} + +int uarths_puts(const char *s) +{ + while (*s) + if (uarths_putc(*s++) != 0) + return -1; + return 0; +} + +void uarths_init(void) +{ + uint32_t freq = SysctlClockGetFreq(SYSCTL_CLOCK_CPU); + uint16_t div = freq / 115200 - 1; + + /* Set UART registers */ + uarths->div.div = div; + uarths->txctrl.txen = 1; + uarths->rxctrl.rxen = 1; + uarths->txctrl.txcnt = 0; + uarths->rxctrl.rxcnt = 0; + uarths->ip.txwm = 1; + uarths->ip.rxwm = 1; + uarths->ie.txwm = 0; + uarths->ie.rxwm = 1; +} + +void uarths_config(uint32_t BaudRate, uarths_stopbit_t stopbit) +{ + uint32_t freq = SysctlClockGetFreq(SYSCTL_CLOCK_CPU); + uint16_t div = freq / BaudRate - 1; + uarths->div.div = div; + uarths->txctrl.nstop = stopbit; +} diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/Kconfig new file mode 100644 index 000000000..e801fa0ea --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/Kconfig @@ -0,0 +1,34 @@ +menuconfig BSP_USING_WDT0 +bool "Using watchdog 0 " +default n +if BSP_USING_WDT0 +config WDT_BUS_NAME_0 + string "watchdog bus 0 name" + default "wdt0" + +config WDT_DRIVER_NAME_0 + string "watchdog driver 0 name" + default "wdt0_drv" + +config WDT_0_DEVICE_NAME_0 + string "watchdog device 0 name" + default "wdt0_dev0" +endif + +menuconfig BSP_USING_WDT1 +bool "Using watchdog 1 " +default n +if BSP_USING_WDT1 +config WDT_BUS_NAME_1 + string "watchdog bus 1 name" + default "wdt1" + +config WDT_DRIVER_NAME_1 + string "watchdog driver 1 name" + default "wdt1_drv" + +config WDT_1_DEVICE_NAME_1 + string "watchdog device 1 name" + default "wdt1_dev1" +endif + diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/Makefile new file mode 100644 index 000000000..c4842fd3a --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/Makefile @@ -0,0 +1,6 @@ +SRC_FILES := wdt.c connect_wdt.c + + + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/connect_wdt.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/connect_wdt.c new file mode 100644 index 000000000..30ac2630e --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/connect_wdt.c @@ -0,0 +1,176 @@ +/* +* 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_wdt.c +* @brief support aiit-riscv64-board watchdog function and register to bus framework +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#include +#include + +static uint32 WdtOpen(void *dev) +{ + NULL_PARAM_CHECK(dev); + + wdt_device_number_t id; + struct WdtHardwareDevice *wdt = (struct WdtHardwareDevice *)dev; + id = *(wdt_device_number_t *)wdt->private_data; + + wdt_init(id, 4095, NONE, NONE); + return EOK; +} + +static uint32 WdtConfigure(void *drv, struct BusConfigureInfo *args) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(args); + + struct WdtDriver *wdt = (struct WdtDriver *)drv; + wdt_device_number_t id = *(wdt_device_number_t *)wdt->private_data; + + switch (args->configure_cmd) + { + case OPER_WDT_SET_TIMEOUT: + if (wdt_init(id, (uint64_t)*(int *)args->private_data, NONE, NONE) == 0) { + return ERROR; + } + break; + case OPER_WDT_KEEPALIVE: + wdt_feed(id); + break; + default: + return ERROR; + } + return EOK; +} + +static const struct WdtDevDone dev_done = +{ + WdtOpen, + NONE, + NONE, + NONE, +}; + +/** + * @description: Watchdog function + * @return success: EOK, failure: other + */ +int StartWatchdog(void) +{ + //add feed watchdog task function + + return EOK; +} + +int HwWdtInit(void) +{ + wdt_device_number_t id; + + x_err_t ret = EOK; + +#ifdef BSP_USING_WDT0 + { + static struct WdtBus wdt0; + + ret = WdtBusInit(&wdt0, WDT_BUS_NAME_0); + if (ret != EOK) { + KPrintf("Watchdog bus init error %d\n", ret); + return ERROR; + } + + static struct WdtDriver drv0; + drv0.configure = WdtConfigure; + id = WDT_DEVICE_0; + drv0.private_data = &id; + + ret = WdtDriverInit(&drv0, WDT_DRIVER_NAME_0); + if (ret != EOK) { + KPrintf("Watchdog driver init error %d\n", ret); + return ERROR; + } + + ret = WdtDriverAttachToBus(WDT_DRIVER_NAME_0, WDT_BUS_NAME_0); + if (ret != EOK) { + KPrintf("Watchdog driver attach error %d\n", ret); + return ERROR; + } + + static struct WdtHardwareDevice dev0; + dev0.dev_done = &dev_done; + dev0.private_data = &id; + + ret = WdtDeviceRegister(&dev0, WDT_0_DEVICE_NAME_0); + if (ret != EOK) { + KPrintf("Watchdog device register error %d\n", ret); + return ERROR; + } + + ret = WdtDeviceAttachToBus(WDT_0_DEVICE_NAME_0, WDT_BUS_NAME_0); + if (ret != EOK) { + KPrintf("Watchdog device register error %d\n", ret); + return ERROR; + } + } +#endif + +#ifdef BSP_USING_WDT1 + { + static struct WdtBus wdt1; + + ret = WdtBusInit(&wdt1, WDT_BUS_NAME_1); + if (ret != EOK) { + KPrintf("Watchdog bus init error %d\n", ret); + return ERROR; + } + + static struct WdtDriver drv1; + drv1.configure = WdtConfigure; + id = WDT_DEVICE_1; + drv1.private_data = &id; + + ret = WdtDriverInit(&drv1, WDT_DRIVER_NAME_1); + if (ret != EOK) { + KPrintf("Watchdog driver init error %d\n", ret); + return ERROR; + } + + ret = WdtDriverAttachToBus(WDT_DRIVER_NAME_1, WDT_BUS_NAME_1); + if (ret != EOK) { + KPrintf("Watchdog driver attach error %d\n", ret); + return ERROR; + } + + static struct WdtHardwareDevice dev1; + dev1.dev_done = &dev_done; + dev1.private_data = &id; + + ret = WdtDeviceRegister(&dev1, WDT_1_DEVICE_NAME_1); + if (ret != EOK) { + KPrintf("Watchdog device register error %d\n", ret); + return ERROR; + } + + ret = WdtDeviceAttachToBus(WDT_1_DEVICE_NAME_1, WDT_BUS_NAME_1); + if (ret != EOK) { + KPrintf("Watchdog device register error %d\n", ret); + return ERROR; + } + } +#endif + + return ret; +} diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/wdt.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/wdt.c new file mode 100644 index 000000000..b106444a2 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/watchdog/wdt.c @@ -0,0 +1,125 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** +* @file wdt.c +* @brief add from Canaan k210 SDK +* https://canaan-creative.com/developer +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2021-04-25 +*/ + +#include +#include +#include +#include +#include +#include +#include + +volatile wdt_t *const wdt[2] = +{ + (volatile wdt_t *)WDT0_BASE_ADDR, + (volatile wdt_t *)WDT1_BASE_ADDR +}; + +static void wdt_enable(wdt_device_number_t id) +{ + wdt[id]->crr = WDT_CRR_MASK; + wdt[id]->cr |= WDT_CR_ENABLE; +} + +static void wdt_disable(wdt_device_number_t id) +{ + wdt[id]->crr = WDT_CRR_MASK; + wdt[id]->cr &= (~WDT_CR_ENABLE); +} + +static void wdt_set_timeout(wdt_device_number_t id, uint8_t timeout) +{ + wdt[id]->torr = WDT_TORR_TOP(timeout); +} + +static void wdt_response_mode(wdt_device_number_t id, uint8_t mode) +{ + wdt[id]->cr &= (~WDT_CR_RMOD_MASK); + wdt[id]->cr |= mode; +} + +static uint64_t wdt_get_pclk(wdt_device_number_t id) +{ + return id ? SysctlClockGetFreq(SYSCTL_CLOCK_WDT1) : SysctlClockGetFreq(SYSCTL_CLOCK_WDT0); +} + +static uint8_t wdt_get_top(wdt_device_number_t id, uint64_t timeout_ms) +{ + uint64_t wdt_clk = wdt_get_pclk(id); + uint64_t ret = (timeout_ms * wdt_clk / 1000) >> 16; + if (ret) + ret = (uint32_t)log2(ret); + if (ret > 0xf) + ret = 0xf; + return (uint8_t)ret; +} + +void wdt_feed(wdt_device_number_t id) +{ + wdt[id]->crr = WDT_CRR_MASK; +} + +void wdt_clear_interrupt(wdt_device_number_t id) +{ + wdt[id]->eoi = wdt[id]->eoi; +} + +void wdt_start(wdt_device_number_t id, uint64_t time_out_ms, plic_irq_callback_t on_irq) +{ + sysctl_reset(id ? SYSCTL_RESET_WDT1 : SYSCTL_RESET_WDT0); + sysctl_clock_set_threshold(id ? SYSCTL_THRESHOLD_WDT1 : SYSCTL_THRESHOLD_WDT0, 0); + sysctl_clock_enable(id ? SYSCTL_CLOCK_WDT1 : SYSCTL_CLOCK_WDT0); + + plic_set_priority(id ? IRQN_WDT1_INTERRUPT : IRQN_WDT0_INTERRUPT, 1); + plic_irq_enable(id ? IRQN_WDT1_INTERRUPT : IRQN_WDT0_INTERRUPT); + plic_irq_register(id ? IRQN_WDT1_INTERRUPT : IRQN_WDT0_INTERRUPT, on_irq, NULL); + + wdt_response_mode(id, WDT_CR_RMOD_INTERRUPT); + uint8_t m_top = wdt_get_top(id, time_out_ms); + wdt_set_timeout(id, m_top); + wdt_enable(id); +} + +uint32_t wdt_init(wdt_device_number_t id, uint64_t time_out_ms, plic_irq_callback_t on_irq, void *ctx) +{ + sysctl_reset(id ? SYSCTL_RESET_WDT1 : SYSCTL_RESET_WDT0); + sysctl_clock_set_threshold(id ? SYSCTL_THRESHOLD_WDT1 : SYSCTL_THRESHOLD_WDT0, 0); + sysctl_clock_enable(id ? SYSCTL_CLOCK_WDT1 : SYSCTL_CLOCK_WDT0); + + plic_set_priority(id ? IRQN_WDT1_INTERRUPT : IRQN_WDT0_INTERRUPT, 1); + plic_irq_enable(id ? IRQN_WDT1_INTERRUPT : IRQN_WDT0_INTERRUPT); + plic_irq_register(id ? IRQN_WDT1_INTERRUPT : IRQN_WDT0_INTERRUPT, on_irq, ctx); + + wdt_response_mode(id, WDT_CR_RMOD_INTERRUPT); + uint8_t m_top = wdt_get_top(id, time_out_ms); + wdt_set_timeout(id, m_top); + wdt_enable(id); + return (1UL << (m_top + 16 + 1)) * 1000UL / wdt_get_pclk(id); +} + +void wdt_stop(wdt_device_number_t id) +{ + wdt_disable(id); +} +