Optimize k210 serial port driver for nuttx from Wang_guozhu

it is OK
This commit is contained in:
xuedongliang 2022-12-09 11:33:52 +08:00
commit 669b7f427e
53 changed files with 6124 additions and 464 deletions

View File

@ -1,5 +1,6 @@
############################################################################
# APP_Framework/Framework/Make.defs
############################################################################
CONFIGURED_APPS += $(APPDIR)/../../../APP_Framework/Framework
CONFIGURED_APPS += $(APPDIR)/../../../APP_Framework/Framework/transform_layer/nuttx
include $(wildcard $(APPDIR)/../../../APP_Framework/Framework/*/Make.defs)

View File

@ -1,29 +1,40 @@
SRC_FILES := framework_init.c
SRC_DIR := transform_layer
include $(KERNEL_ROOT)/.config
ifeq ($(CONFIG_SUPPORT_SENSOR_FRAMEWORK),y)
SRC_DIR += sensor
ifeq ($(CONFIG_ADD_NUTTX_FETURES),y)
include $(APPDIR)/Make.defs
CSRCS += framework_init.c
include $(APPDIR)/Application.mk
endif
ifeq ($(CONFIG_SUPPORT_CONNECTION_FRAMEWORK),y)
SRC_DIR += connection
ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
SRC_FILES := framework_init.c
SRC_DIR := transform_layer
ifeq ($(CONFIG_SUPPORT_SENSOR_FRAMEWORK),y)
SRC_DIR += sensor
endif
ifeq ($(CONFIG_SUPPORT_CONNECTION_FRAMEWORK),y)
SRC_DIR += connection
endif
ifeq ($(CONFIG_SUPPORT_KNOWING_FRAMEWORK),y)
SRC_DIR += knowing
endif
ifeq ($(CONFIG_SUPPORT_CONTROL_FRAMEWORK),y)
SRC_DIR += control
endif
ifeq ($(CONFIG_CRYPTO),y)
SRC_DIR += security
endif
ifeq ($(CONFIG_MBEDTLS), y)
SRC_DIR += security
endif
include $(KERNEL_ROOT)/compiler.mk
endif
ifeq ($(CONFIG_SUPPORT_KNOWING_FRAMEWORK),y)
SRC_DIR += knowing
endif
ifeq ($(CONFIG_SUPPORT_CONTROL_FRAMEWORK),y)
SRC_DIR += control
endif
ifeq ($(CONFIG_CRYPTO),y)
SRC_DIR += security
endif
ifeq ($(CONFIG_MBEDTLS), y)
SRC_DIR += security
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,42 @@
#
# For a description of the syntax of this configuration file,
# see misc/tools/kconfig-language.txt.
#
if ARCH_BOARD_EDU_RISCV64
menuconfig BSP_USING_CH376
bool "Using CH376 device"
default n
select K210_UART
select K210_UART3
if BSP_USING_CH376
choice
prompt "select ch376 function."
default CH376_USB_FUNCTION
config CH376_USB_FUNCTION
bool "select ch376 usb function"
config CH376_SD_FUNCTION
bool "select ch376 sd function"
endchoice
config CH376_WORK_MODE
hex "ch376 work mode set:0x03 sd,0x06 u-disk"
default 0x03 if CH376_SD_FUNCTION
default 0x06 if CH376_USB_FUNCTION
endif # BSP_USING_CH376
menuconfig BSP_USING_ENET
bool "Using ENET device"
default n
menuconfig BSP_USING_TOUCH
bool "Using touch device"
default n
endif # ARCH_BOARD_EDU_RISCV64

View File

@ -0,0 +1,42 @@
1. Download and install toolchain and openocd-k210
$ curl https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-ubuntu14.tar.gz
$ export PATH=$PATH:/$TOOL_CHAIN_PATH/bin
2. Build openocd-k210
$ git clone https://github.com/kendryte/openocd-kendryte
$ cd openocd-kendryte
$ ./bootstrap & ./configure & make
3. Configure and build NuttX
$ mkdir ./nuttx; cd ./nuttx
$ git clone https://github.com/apache/incubator-nuttx.git nuttx
$ git clone https://github.com/apache/incubator-nuttx-apps.git apps
$ cd nuttx
$ make distclean
$ ./tools/configure.sh edu-riscv64:nsh
$ make V=1
4. Download and run the nuttx from SRAM (not SPI-Flash)
$ picocom -b 115200 /dev/ttyUSB0
$ sudo ./src/openocd -s ./tcl -f ./tcl/kendryte.cfg -m 0
$ riscv64-unknown-elf-gdb ./nuttx
(gdb) target extended-remote :3333
(gdb) load nuttx
(gdb) c
5. Write nuttx.bin to SPI-Flash
$ pip3 install kflash
$ kflash -p /dev/ttyUSB0 -b 1500000 ./nuttx/nuttx.bin
NOTE: The kflash_gui is not recommended because it's unstable
6. TODO
Support peripherals such as GPIO/SPI/I2C/...
Support FPU
Support RISC-V U-mode including memory protection

View File

@ -0,0 +1,80 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_NSH_DISABLE_LOSMART is not set
# CONFIG_STANDARD_SERIAL is not set
CONFIG_ADD_NUTTX_FETURES=y
CONFIG_ARCH="risc-v"
CONFIG_ARCH_BOARD="xidatong-riscv64"
CONFIG_ARCH_BOARD_XIDATONG_RISCV64=y
CONFIG_ARCH_CHIP="k210"
CONFIG_ARCH_CHIP_K210=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BINFMT_DISABLE=y
CONFIG_BOARD_LOOPSPERMSEC=46000
CONFIG_BUILTIN=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_EXAMPLES_HELLO=y
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INIT_STACKSIZE=3072
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_DISABLE_IFUPDOWN=y
CONFIG_NSH_DISABLE_MKDIR=y
CONFIG_NSH_DISABLE_RM=y
CONFIG_NSH_DISABLE_RMDIR=y
CONFIG_NSH_DISABLE_UMOUNT=y
CONFIG_NSH_READLINE=y
CONFIG_NSH_STRERROR=y
CONFIG_PREALLOC_TIMERS=4
CONFIG_RAM_SIZE=2097152
CONFIG_RAM_START=0x80400000
CONFIG_RAW_BINARY=y
CONFIG_READLINE_CMD_HISTORY=y
CONFIG_READLINE_CMD_HISTORY_LEN=100
CONFIG_READLINE_CMD_HISTORY_LINELEN=120
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_WAITPID=y
CONFIG_STACK_COLORATION=y
CONFIG_START_DAY=28
CONFIG_START_MONTH=12
CONFIG_START_YEAR=2019
CONFIG_SYSTEM_NSH=y
CONFIG_TASK_NAME_SIZE=20
CONFIG_TESTING_GETPRIME=y
CONFIG_UART0_SERIAL_CONSOLE=y
CONFIG_READLINE_TABCOMPLETION=y
CONFIG_SCHED_HPWORK=y
CONFIG_DEV_GPIO=y
CONFIG_BOARDCTL_RESET=y
CONFIG_K210_UART=y
CONFIG_K210_UART2=y
CONFIG_K210_UART2_BASE=0x50220000
CONFIG_K210_UART2_CLOCK=195000000
CONFIG_K210_UART2_IRQ=39
CONFIG_K210_UART2_BAUD=115200
CONFIG_K210_UART2_PARITY=0
CONFIG_K210_UART2_BITS=8
CONFIG_K210_UART2_2STOP=0
CONFIG_K210_UART2_RXBUFSIZE=128
CONFIG_K210_UART2_TXBUFSIZE=128
CONFIG_SUPPORT_CONNECTION_FRAMEWORK=y
CONFIG_CONNECTION_FRAMEWORK_DEBUG=y
CONFIG_CONNECTION_ADAPTER_LORA=y
CONFIG_ADAPTER_E220=y
CONFIG_ADAPTER_LORA_E220="e220"
CONFIG_ADAPTER_E220_DRIVER_EXTUART=n
CONFIG_ADAPTER_E220_DRIVER="/dev/ttyS2"
CONFIG_ADAPTER_E220_M0_PATH="/dev/gpio0"
CONFIG_ADAPTER_E220_M1_PATH="/dev/gpio1"

View File

@ -0,0 +1,60 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_NSH_DISABLE_LOSMART is not set
# CONFIG_STANDARD_SERIAL is not set
CONFIG_ADD_NUTTX_FETURES=y
CONFIG_ARCH="risc-v"
CONFIG_ARCH_BOARD="edu-riscv64"
CONFIG_ARCH_BOARD_EDU_RISCV64=y
CONFIG_ARCH_CHIP="k210"
CONFIG_ARCH_CHIP_K210=y
CONFIG_ARCH_INTERRUPTSTACK=2048
CONFIG_ARCH_RISCV=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_BINFMT_DISABLE=y
CONFIG_BOARD_LOOPSPERMSEC=46000
CONFIG_BUILTIN=y
CONFIG_DEBUG_FULLOPT=y
CONFIG_DEBUG_SYMBOLS=y
CONFIG_EXAMPLES_HELLO=y
CONFIG_IDLETHREAD_STACKSIZE=2048
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INIT_STACKSIZE=3072
CONFIG_INTELHEX_BINARY=y
CONFIG_LIBC_PERROR_STDOUT=y
CONFIG_LIBC_STRERROR=y
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_DISABLE_IFUPDOWN=y
CONFIG_NSH_DISABLE_MKDIR=y
CONFIG_NSH_DISABLE_RM=y
CONFIG_NSH_DISABLE_RMDIR=y
CONFIG_NSH_DISABLE_UMOUNT=y
CONFIG_NSH_READLINE=y
CONFIG_NSH_STRERROR=y
CONFIG_PREALLOC_TIMERS=4
CONFIG_RAM_SIZE=2097152
CONFIG_RAM_START=0x80400000
CONFIG_RAW_BINARY=y
CONFIG_READLINE_CMD_HISTORY=y
CONFIG_READLINE_CMD_HISTORY_LEN=100
CONFIG_READLINE_CMD_HISTORY_LINELEN=120
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_WAITPID=y
CONFIG_STACK_COLORATION=y
CONFIG_START_DAY=28
CONFIG_START_MONTH=12
CONFIG_START_YEAR=2019
CONFIG_SYSTEM_NSH=y
CONFIG_TASK_NAME_SIZE=20
CONFIG_TESTING_GETPRIME=y
CONFIG_UART0_SERIAL_CONSOLE=y
CONFIG_READLINE_TABCOMPLETION=y
CONFIG_SCHED_HPWORK=y
CONFIG_DEV_GPIO=y
CONFIG_BOARDCTL_RESET=y

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,175 @@
/*
* 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 board.h
* @brief edu-riscv64 board.h
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.03.17
*/
#ifndef __BOARDS_RISCV_K210_EDU_RISCV64_INCLUDE_BOARD_H
#define __BOARDS_RISCV_K210_EDU_RISCV64_INCLUDE_BOARD_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifndef __ASSEMBLY__
# include <stdint.h>
#endif
#include "k210.h"
#include "k210_fpioa.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Map pad 14 to gpiohs io 0 */
#define BOARD_LED_IO_FUNC K210_IO_FUNC_GPIOHS0
#define LED_STARTED 0 /* N/C */
#define LED_HEAPALLOCATE 1 /* N/C */
#define LED_IRQSENABLED 2 /* N/C */
#define LED_STACKCREATED 3 /* N/C */
#define LED_INIRQ 4 /* N/C */
#define LED_SIGNAL 5 /* N/C */
#define LED_ASSERTION 6 /* N/C */
#define LED_PANIC 7 /* blink */
/* GPIO pins used by the GPIO Subsystem */
#define BOARD_NGPIOOUT 3 /* Amount of register GPIO Output pins */
#define BOARD_NGPIOINT 0 /* Amount of GPIO Input */
/****************************************************************************
* Public Types
****************************************************************************/
#ifndef __ASSEMBLY__
/****************************************************************************
* Public Data
****************************************************************************/
#undef EXTERN
#if defined(__cplusplus)
#define EXTERN extern "C"
extern "C"
{
#else
#define EXTERN extern
#endif
/*************************** GPIO define ***************************/
/* UART IO */
#define GPIO_WIFI_RXD 7
#define GPIO_WIFI_TXD 6
#define GPIO_E220_RXD 21
#define GPIO_E220_TXD 20
#define GPIO_CH376T_RXD 22
#define GPIO_CH376T_TXD 23
/* w5500 IO */
#define BSP_ENET_SCLK 9
#define BSP_ENET_MISO 10
#define BSP_ENET_MOSI 11
#define BSP_ENET_NCS 12
#define BSP_ENET_NRST 13
#define BSP_ENET_NINT 14
/* LCD IO */
#define BSP_LCD_NRST 37
#define BSP_LCD_SCLK 38
#define BSP_LCD_MOSI 39
#define BSP_LCD_MISO 40
#define BSP_LCD_NCS 41
#define BSP_LCD_BL_PIN 47
/* I2C */
#define BSP_IIC_SDA 15
#define BSP_IIC_SCL 17
/* other mode io */
#define GPIO_E220_M0 32
#define GPIO_E220_M1 33
#define GPIO_E18_MODE 46
#define GPIO_WIFI_EN 8
#define GPIO_CAN_CFG 43
/************************** end GPIO define **************************/
/*************************** FPIOA define ***************************/
/* UART FPOA */
#define FPOA_USART1_RX K210_IO_FUNC_UART1_RX
#define FPOA_USART1_TX K210_IO_FUNC_UART1_TX
#define FPOA_USART2_RX K210_IO_FUNC_UART2_RX
#define FPOA_USART2_TX K210_IO_FUNC_UART2_TX
#define FPOA_USART3_RX K210_IO_FUNC_UART3_RX
#define FPOA_USART3_TX K210_IO_FUNC_UART3_TX
/* w5500 FPIOA */
#define FPIOA_ENET_NRST 0
#define FPIOA_ENET_NINT 9
#define FPIOA_ENET_SCLK 28
#define FPIOA_ENET_MISO 29
#define FPIOA_ENET_MOSI 23
#define FPIOA_ENET_NCS 31
/* LCD FPIOA */
#define FPIOA_LCD_NRST 0
#define FPIOA_LCD_BL 9
#define FPIOA_LCD_SCLK 28
#define FPIOA_LCD_MOSI 29
#define FPIOA_LCD_MISO 23
#define FPIOA_LCD_NCS 31
/* I2C */
#define FPIOA_IIC_SDA 7
#define FPIOA_IIC_SCL 8
/* other mode FPIOA */
#define FPIOA_E220_M0 1
#define FPIOA_E220_M1 2
#define FPIOA_E18_MODE 3
#define FPIOA_WIFI_EN 4
#define FPIOA_CAN_NCFG 5
/************************** end FPIOA define **************************/
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: k210_boardinitialize
****************************************************************************/
void k210_boardinitialize(void);
#undef EXTERN
#if defined(__cplusplus)
}
#endif
#endif /* __ASSEMBLY__ */
#endif /* __BOARDS_RISC-V_K210_EDU_RISCV64_INCLUDE_BOARD_H */

View File

@ -0,0 +1,92 @@
############################################################################
# boards/risc-v/k210/edu-riscv64/kernel/Makefile
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you 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.
#
############################################################################
include $(TOPDIR)/Make.defs
# The entry point name (if none is provided in the .config file)
CONFIG_INIT_ENTRYPOINT ?= user_start
ENTRYPT = $(patsubst "%",%,$(CONFIG_INIT_ENTRYPOINT))
# Get the paths to the libraries and the links script path in format that
# is appropriate for the host OS
USER_LIBPATHS = $(addprefix -L,$(call CONVERT_PATH,$(addprefix $(TOPDIR)$(DELIM),$(dir $(USERLIBS)))))
USER_LDSCRIPT = -T $(call CONVERT_PATH,$(BOARD_DIR)$(DELIM)scripts$(DELIM)memory.ld)
USER_LDSCRIPT += -T $(call CONVERT_PATH,$(BOARD_DIR)$(DELIM)scripts$(DELIM)user-space.ld)
USER_HEXFILE += $(call CONVERT_PATH,$(TOPDIR)$(DELIM)nuttx_user.hex)
USER_SRECFILE += $(call CONVERT_PATH,$(TOPDIR)$(DELIM)nuttx_user.srec)
USER_BINFILE += $(call CONVERT_PATH,$(TOPDIR)$(DELIM)nuttx_user.bin)
USER_LDFLAGS = --undefined=$(ENTRYPT) --entry=$(ENTRYPT) $(USER_LDSCRIPT)
USER_LDLIBS = $(patsubst lib%,-l%,$(basename $(notdir $(USERLIBS))))
USER_LIBGCC = "${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name}"
# Source files
CSRCS = k210_userspace.c
COBJS = $(CSRCS:.c=$(OBJEXT))
OBJS = $(COBJS)
# Targets:
all: $(TOPDIR)$(DELIM)nuttx_user.elf $(TOPDIR)$(DELIM)User.map
.PHONY: nuttx_user.elf depend clean distclean
$(COBJS): %$(OBJEXT): %.c
$(call COMPILE, $<, $@)
# Create the nuttx_user.elf file containing all of the user-mode code
nuttx_user.elf: $(OBJS)
$(Q) $(LD) -o $@ $(USER_LDFLAGS) $(USER_LIBPATHS) $(OBJS) --start-group $(USER_LDLIBS) --end-group $(USER_LIBGCC)
$(TOPDIR)$(DELIM)nuttx_user.elf: nuttx_user.elf
@echo "LD: nuttx_user.elf"
$(Q) cp -a nuttx_user.elf $(TOPDIR)$(DELIM)nuttx_user.elf
ifeq ($(CONFIG_INTELHEX_BINARY),y)
@echo "CP: nuttx_user.hex"
$(Q) $(OBJCOPY) $(OBJCOPYARGS) -O ihex nuttx_user.elf $(USER_HEXFILE)
endif
ifeq ($(CONFIG_MOTOROLA_SREC),y)
@echo "CP: nuttx_user.srec"
$(Q) $(OBJCOPY) $(OBJCOPYARGS) -O srec nuttx_user.elf $(USER_SRECFILE)
endif
ifeq ($(CONFIG_RAW_BINARY),y)
@echo "CP: nuttx_user.bin"
$(Q) $(OBJCOPY) $(OBJCOPYARGS) -O binary nuttx_user.elf $(USER_BINFILE)
endif
$(TOPDIR)$(DELIM)User.map: nuttx_user.elf
@echo "MK: User.map"
$(Q) $(NM) -n nuttx_user.elf >$(TOPDIR)$(DELIM)User.map
$(Q) $(CROSSDEV)size nuttx_user.elf
.depend:
depend: .depend
clean:
$(call DELFILE, nuttx_user.elf)
$(call DELFILE, "$(TOPDIR)$(DELIM)nuttx_user.*")
$(call DELFILE, "$(TOPDIR)$(DELIM)User.map")
$(call CLEAN)
distclean: clean

View File

@ -0,0 +1,114 @@
/*
* 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 k210_userspace.c
* @brief edu-riscv64 k210_userspace.c
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.03.17
*/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdlib.h>
#include <nuttx/arch.h>
#include <nuttx/mm/mm.h>
#include <nuttx/wqueue.h>
#include <nuttx/userspace.h>
#if defined(CONFIG_BUILD_PROTECTED) && !defined(__KERNEL__)
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Configuration ************************************************************/
#ifndef CONFIG_NUTTX_USERSPACE
# error "CONFIG_NUTTX_USERSPACE not defined"
#endif
#if CONFIG_NUTTX_USERSPACE != 0x80100000
# error "CONFIG_NUTTX_USERSPACE must match the value in memory.ld"
#endif
/****************************************************************************
* Public Data
****************************************************************************/
/* These 'addresses' of these values are setup by the linker script.
* They are not actual uint32_t storage locations!
* They are only used meaningfully in the following way:
*
* - The linker script defines, for example, the symbol_sdata.
* - The declaration extern uint32_t _sdata; makes C happy. C will believe
* that the value _sdata is the address of a uint32_t variable _data
* (it is not!).
* - We can recover the linker value then by simply taking the address of
* of _data. like: uint32_t *pdata = &_sdata;
*/
extern uint32_t _stext; /* Start of .text */
extern uint32_t _etext; /* End_1 of .text + .rodata */
extern const uint32_t _eronly; /* End+1 of read only section */
extern uint32_t _sdata; /* Start of .data */
extern uint32_t _edata; /* End+1 of .data */
extern uint32_t _sbss; /* Start of .bss */
extern uint32_t _ebss; /* End+1 of .bss */
/* This is the user space entry point */
int CONFIG_INIT_ENTRYPOINT(int argc, char *argv[]);
const struct userspace_s userspace locate_data(".userspace") =
{
/* General memory map */
.us_entrypoint = (main_t)CONFIG_INIT_ENTRYPOINT,
.us_textstart = (uintptr_t)&_stext,
.us_textend = (uintptr_t)&_etext,
.us_datasource = (uintptr_t)&_eronly,
.us_datastart = (uintptr_t)&_sdata,
.us_dataend = (uintptr_t)&_edata,
.us_bssstart = (uintptr_t)&_sbss,
.us_bssend = (uintptr_t)&_ebss,
/* Memory manager heap structure */
.us_heap = &g_mmheap,
/* Task/thread startup routines */
.task_startup = nxtask_startup,
/* Signal handler trampoline */
.signal_handler = up_signal_handler,
/* User-space work queue support (declared in include/nuttx/wqueue.h) */
#ifdef CONFIG_LIBC_USRWORK
.work_usrstart = work_usrstart,
#endif
};
/****************************************************************************
* Public Functions
****************************************************************************/
#endif /* CONFIG_BUILD_PROTECTED && !__KERNEL__ */

View File

@ -0,0 +1,174 @@
# 从零开始构建矽璓工业物联操作系统使用ARM架构的矽达通
# edu-riscv64
[XiUOS](http://xuos.io/) (X Industrial Ubiquitous Operating System) 矽璓XiUOS是一款面向智慧车间的工业物联网操作系统主要由一个极简的微型实时操作系统内核和其上的工业物联框架构成通过高效管理工业物联网设备、支撑工业物联应用在生产车间内实现智能化的“感知环境、联网传输、知悉识别、控制调整”促进以工业设备和工业控制系统为核心的人、机、物深度互联帮助提升生产线的数字化和智能化水平。
## 1. 简介
| 硬件 | 描述 |
| -- | -- |
|芯片型号| 勘智K210 |
|架构| 双核riscv64 |
|主频| 400MHz |
|片内SRAM| 8M |
|外设支持| 内嵌AES与SHA256算法加速器 |
|| DVP、JTAG、OTP、FPIOA、GPIO、UART、SPI、RTC、I²S、I²C、WDT、Timer与PWM |
XiUOS板级当前支持使用CH438、GPIO、UART等。
## 2. 开发环境搭建
### 推荐使用:
**操作系统:** ubuntu18.04 [https://ubuntu.com/download/desktop](https://ubuntu.com/download/desktop)
更新`ubuntu 18.04`源的方法:(根据自身情况而定,可以不更改)
第一步:打开sources.list文件
```c
sudo vim /etc/apt/sources.list
```
第二步:将以下内容复制到sources.list文件
```c
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
```
第三步:更新源和系统软件
```c
sudo apt-get update
sudo apt-get upgrade
```
**开发工具推荐使用 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 git
$ sudo apt install gcc make libncurses5-dev openssl libssl-dev bison flex libelf-dev autoconf libtool gperf libc6-dev
```
**XiUOS操作系统源码下载这个仓里的代码可能不是最新的最好git clone自己仓里的代码** 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
git checkout origin/prepare_for_master (以实际分支为准)
```
打开XiUOS源码文件包可以看到以下目录
| 名称 | 说明 |
| -- | -- |
| APP_Framework | 应用代码 |
| Ubiquitous | 板级支持包,支持NuttX、RT-Thread和XiZi内核 |
### 裁减配置工具的下载
裁减配置工具:
**工具地址:** 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
```
### 编译工具链:
Riscv64 riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14.tar在我的个人仓保存有一份
https://gitlink.org.cn/wgzAIIT/build_tools.git
下载后解压到Ubantu环境的/opt目录下。
再将/opt/riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14/bin目录下的全部二进制文件软连接到/usr/bin例如
![gccdir](img/gccdir.jpg)
## 3.编译bin包
1.XiUOS操作系统源码下载 [https://www.gitlink.org.cn/xuos/xiuos](https://www.gitlink.org.cn/xuos/xiuos)
目前大家都使用的个人仓,请注意此处的路径及分支,如果需要须进行分支切换
2.在Ubuntu18.04环境中的代码路径,执行以下命令,生成配置文件
```shell
cd ./Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx
source build.sh
执行完毕会自动进入./Ubiquitous/Nuttx_Fusion_XiUOS/nuttx下继续执行
./tools/configure.sh edu-riscv64:nsh
make menuconfig
视情况而定如果需要前面加sudo
```
3..在menuconfig界面配置需要关闭和开启的功能按回车键进入下级菜单按Y键选中需要开启的功能按N键选中需要关闭的功能配置结束后保存并退出本例旨在演示简单的输出例程所以没有需要配置的选项双击快捷键ESC退出配置
![menuconfig](./img/menuconfig.png)
退出时选择`yes`保存上面所配置的内容,如下图所示:
![menuconfig1](./img/menuconfigexit.png)
4.继续执行以下命令,进行编译
```shell
make
make -j8
```
make时加上V=1参数可以看到较为详细的编译信息但是编译过程会比较慢。
5.如果编译正确无误会在当前目录下产生nuttx.bin、nuttx、nuttx.hex等文件。
## 4. 烧写及运行
### 4.1 烧写
1、烧写工具K-Flash.exe可https://gitlink.org.cn/wgzAIIT/build_tools.git下载
![K-Flash](img/K-Flash.jpg)
在①选择串口 com 号
在②处选择波特率,选择 115200
在③处选择编译出的 nuttx.bin 文件
设备在上电时确保 Boot 和 GND 短接,这是升级模式。
点击④处 Flash 开始烧录,显示烧录完成即可,中间有报错的话,重新 Flash。
### 4.2 运行结果
烧写完毕重新上电,进入 shell。
![k210-shell](img/k210-shell.jpg)

View File

@ -0,0 +1,70 @@
############################################################################
# boards/risc-v/k210/edu-riscv64/scripts/Make.defs
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you 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.
#
############################################################################
include $(TOPDIR)/.config
include $(TOPDIR)/tools/Config.mk
include $(TOPDIR)/arch/risc-v/src/common/Toolchain.defs
LDSCRIPT = ld.script
ARCHSCRIPT += $(BOARD_DIR)$(DELIM)scripts$(DELIM)$(LDSCRIPT)
ifeq ($(CONFIG_DEBUG_SYMBOLS),y)
ARCHOPTIMIZATION = -g
ASARCHCPUFLAGS += -Wa,-g
endif
MAXOPTIMIZATION = -Os
ifneq ($(CONFIG_DEBUG_NOOPT),y)
ARCHOPTIMIZATION += $(MAXOPTIMIZATION) -fno-strict-aliasing
endif
ARCHCPUFLAGS += -mcmodel=medany -mstrict-align
ARCHCFLAGS = -fno-common -ffunction-sections -fdata-sections
ARCHCXXFLAGS = -fno-common -fno-exceptions -fcheck-new -fno-rtti
ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef
ARCHWARNINGSXX = -Wall -Wshadow -Wundef
CFLAGS := $(APPPATHS) $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe
CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS)
CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe
CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS)
AFLAGS += $(CFLAGS) -D__ASSEMBLY__ $(ASARCHCPUFLAGS)
# Loadable module definitions
CMODULEFLAGS = $(CFLAGS)
LDMODULEFLAGS = -r -e module_initialize
LDMODULEFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/modlib/gnu-elf.ld)
# ELF module definitions
CELFFLAGS = $(CFLAGS)
CXXELFFLAGS = $(CXXFLAGS)
LDELFFLAGS = -r -e main
LDELFFLAGS += -T $(call CONVERT_PATH,$(BOARD_DIR)$(DELIM)scripts$(DELIM)gnu-elf.ld)
# File extensions
LDFLAGS += --gc-sections -melf64lriscv

View File

@ -0,0 +1,115 @@
/****************************************************************************
* boards/risc-v/k210/edu-riscv64/scripts/gnu-elf.ld
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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.
*
****************************************************************************/
SECTIONS
{
.text 0x00000000 :
{
_stext = . ;
*(.text)
*(.text.*)
*(.gnu.warning)
*(.stub)
*(.glue_7)
*(.glue_7t)
*(.jcr)
/* C++ support: The .init and .fini sections contain specific logic
* to manage static constructors and destructors.
*/
*(.gnu.linkonce.t.*)
*(.init) /* Old ABI */
*(.fini) /* Old ABI */
_etext = . ;
}
.rodata :
{
_srodata = . ;
*(.rodata)
*(.rodata1)
*(.rodata.*)
*(.gnu.linkonce.r*)
_erodata = . ;
}
.data :
{
_sdata = . ;
*(.data)
*(.data1)
*(.data.*)
*(.gnu.linkonce.d*)
. = ALIGN(4);
_edata = . ;
}
/* C++ support. For each global and static local C++ object,
* GCC creates a small subroutine to construct the object. Pointers
* to these routines (not the routines themselves) are stored as
* simple, linear arrays in the .ctors section of the object file.
* Similarly, pointers to global/static destructor routines are
* stored in .dtors.
*/
.ctors :
{
_sctors = . ;
*(.ctors) /* Old ABI: Unallocated */
*(.init_array) /* New ABI: Allocated */
_edtors = . ;
}
.dtors :
{
_sdtors = . ;
*(.dtors) /* Old ABI: Unallocated */
*(.fini_array) /* New ABI: Allocated */
_edtors = . ;
}
.bss :
{
_sbss = . ;
*(.bss)
*(.bss.*)
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.b*)
*(COMMON)
_ebss = . ;
}
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_info 0 : { *(.debug_info) }
.debug_line 0 : { *(.debug_line) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_aranges 0 : { *(.debug_aranges) }
}

View File

@ -0,0 +1,100 @@
/****************************************************************************
* boards/risc-v/k210/edu-riscv64/scripts/ld.script
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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.
*
****************************************************************************/
/* Reg Access Start addr End addr Size
* MEM0 CPU w/ cache 0x80000000 - 0x803fffff : 4MB
* MEM1 CPU w/ cache 0x80400000 - 0x805fffff : 2MB
* MEM0 CPU w/o cache 0x40000000 - 0x403fffff : 4MB
* MEM1 CPU w/o cache 0x40400000 - 0x405fffff : 4MB
*/
MEMORY
{
progmem (rx) : ORIGIN = 0x80000000, LENGTH = 4096K /* w/ cache */
sram (rwx) : ORIGIN = 0x80400000, LENGTH = 2048K /* w/ cache */
}
OUTPUT_ARCH("riscv")
ENTRY(_stext)
EXTERN(_vectors)
SECTIONS
{
.text : {
_stext = ABSOLUTE(.);
*(.vectors)
*(.text .text.*)
*(.fixup)
*(.gnu.warning)
*(.rodata .rodata.* .srodata .srodata.*)
*(.gnu.linkonce.t.*)
*(.glue_7)
*(.glue_7t)
*(.got)
*(.gcc_except_table)
*(.gnu.linkonce.r.*)
_etext = ABSOLUTE(.);
} > progmem
.init_section : ALIGN(4) {
_sinit = ABSOLUTE(.);
KEEP(*(.init_array .init_array.*))
_einit = ABSOLUTE(.);
} > progmem
_eronly = ABSOLUTE(.);
.data : ALIGN(4) {
_sdata = ABSOLUTE(.);
*(.data .data.*)
*(.sdata .sdata.* .sdata2.*)
*(.gnu.linkonce.d.*)
*(.gnu.linkonce.s.*)
CONSTRUCTORS
. = ALIGN(4);
_edata = ABSOLUTE(.);
} > sram AT > progmem
.bss : ALIGN(4) {
_sbss = ABSOLUTE(.);
*(.bss .bss.*)
*(.sbss .sbss.*)
*(.gnu.linkonce.b.*)
*(.gnu.linkonce.sb.*)
*(COMMON)
. = ALIGN(32);
_ebss = ABSOLUTE(.);
} > sram
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_info 0 : { *(.debug_info) }
.debug_line 0 : { *(.debug_line) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_aranges 0 : { *(.debug_aranges) }
}

View File

@ -0,0 +1,37 @@
/****************************************************************************
* boards/risc-v/k210/edu-riscv64/scripts/memory.ld
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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.
*
****************************************************************************/
/* Reg Access Start addr End addr Size
* MEM0 CPU w/ cache 0x80000000 - 0x803fffff : 4MB
* MEM1 CPU w/ cache 0x80400000 - 0x805fffff : 2MB
* MEM0 CPU w/o cache 0x40000000 - 0x403fffff : 4MB
* MEM1 CPU w/o cache 0x40400000 - 0x405fffff : 4MB
*/
MEMORY
{
kflash (rx) : ORIGIN = 0x80000000, LENGTH = 1024K /* w/ cache */
uflash (rx) : ORIGIN = 0x80100000, LENGTH = 1024K /* w/ cache */
xflash (rx) : ORIGIN = 0x80200000, LENGTH = 2048K /* w/ cache */
ksram (rwx) : ORIGIN = 0x80400000, LENGTH = 512K /* w/ cache */
usram (rwx) : ORIGIN = 0x80480000, LENGTH = 512K /* w/ cache */
xsram (rwx) : ORIGIN = 0x80500000, LENGTH = 1024K /* w/ cache */
}

View File

@ -0,0 +1,94 @@
/****************************************************************************
* boards/risc-v/k210/edu-riscv64/scripts/user-space.ld
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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.
*
****************************************************************************/
/* NOTE: This depends on the memory.ld script having been included prior to
* this script.
*/
OUTPUT_ARCH("riscv")
SECTIONS
{
.userspace : {
*(.userspace)
} > uflash
.text : {
_stext = ABSOLUTE(.);
*(.text .text.*)
*(.fixup)
*(.gnu.warning)
*(.rodata .rodata.*)
*(.gnu.linkonce.t.*)
*(.glue_7)
*(.glue_7t)
*(.got)
*(.gcc_except_table)
*(.gnu.linkonce.r.*)
_etext = ABSOLUTE(.);
} > uflash
.init_section : {
_sinit = ABSOLUTE(.);
KEEP(*(.init_array .init_array.*))
_einit = ABSOLUTE(.);
} > uflash
__exidx_start = ABSOLUTE(.);
__exidx_end = ABSOLUTE(.);
_eronly = ABSOLUTE(.);
.data : {
_sdata = ABSOLUTE(.);
*(.data .data.*)
*(.sdata .sdata.* .sdata2.*)
*(.gnu.linkonce.d.*)
CONSTRUCTORS
. = ALIGN(4);
_edata = ABSOLUTE(.);
} > usram AT > uflash
.bss : {
_sbss = ABSOLUTE(.);
*(.bss .bss.*)
*(.sbss .sbss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
_ebss = ABSOLUTE(.);
} > usram
/* Stabs debugging sections */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_info 0 : { *(.debug_info) }
.debug_line 0 : { *(.debug_line) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_aranges 0 : { *(.debug_aranges) }
}

View File

@ -0,0 +1,57 @@
############################################################################
# boards/risc-v/k210/edu-riscv64/src/Makefile
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you 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.
#
############################################################################
include $(TOPDIR)/Make.defs
CSRCS = k210_bringup.c k210_boot.c
ifeq ($(CONFIG_BOARDCTL_RESET),y)
CSRCS += k210_reset.c
endif
ifeq ($(CONFIG_BOARDCTL),y)
CSRCS += k210_appinit.c
endif
ifeq ($(CONFIG_ARCH_LEDS),y)
CSRCS += k210_leds.c
endif
ifeq ($(CONFIG_K210_LCD),y)
CSRCS += k210_lcd.c
endif
ifeq ($(CONFIG_DEV_GPIO),y)
CSRCS += k210_gpio.c
endif
ifeq ($(CONFIG_BSP_USING_CH376),y)
CSRCS += k210_ch376.c ch376_demo.c
endif
ifeq ($(CONFIG_BSP_USING_ENET),y)
CSRCS += k210_w5500.c
endif
ifeq ($(CONFIG_BSP_USING_TOUCH),y)
CSRCS += k210_touch.c
endif
include $(TOPDIR)/boards/Board.mk

View File

@ -0,0 +1,70 @@
/*
* 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 ch376_demo.c
* @brief edu-riscv64 ch376_demo.c
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.10.11
*/
/****************************************************************************
* Included Files
****************************************************************************/
#include "k210_ch376.h"
uint8_t buf[64];
void CH376Demo(void)
{
uint8_t s;
s = mInitCH376Host();
printf ("ch376 init stat=0x%02x\n",(uint16_t)s);
#ifdef CONFIG_CH376_USB_FUNCTION
printf( "Wait Udisk/SD\n" );
while ( CH376DiskConnect( ) != USB_INT_SUCCESS )
{
up_mdelay( 100 );
}
#endif
for ( s = 0; s < 10; s ++ )
{
up_mdelay( 50 );
printf( "Ready ?\n" );
if ( CH376DiskMount( ) == USB_INT_SUCCESS ) break;
}
s = CH376ReadBlock( buf );
if ( s == sizeof( INQUIRY_DATA ) )
{
buf[ s ] = 0;
printf( "UdiskInfo: %s\n", ((P_INQUIRY_DATA)buf) -> VendorIdStr );
}
printf( "Create /YEAR2022/DEMO2022.TXT \n" );
s = CH376DirCreate((PUINT8)"/YEAR2022" );
printf("CH376DirCreate:0x%02x\n",(uint16_t)s );
s = CH376FileCreatePath((PUINT8)"/YEAR2022/DEMO2022.TXT" );
printf( "CH376FileCreatePath:0x%02x\n",(uint16_t)s );
printf( "Write some data to file\n" );
strcpy( (char *)buf, "This is test case!\xd\xa" );
s = CH376ByteWrite(buf, strlen((char *)buf), NULL );
printf( "CH376ByteWrite:0x%02x\n",(uint16_t)s );
printf( "Close\n" );
s = CH376FileClose( TRUE );
printf( "CH376FileClose:0x%02x\n",(uint16_t)s );
}

View File

@ -0,0 +1,584 @@
/*
* 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 ch376inc.h
* @brief edu-riscv64 ch376inc.h
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.10.10
*/
#ifndef __CH376INC_H__
#define __CH376INC_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Common types and constant definitions */
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
#ifndef NULL
#define NULL 0
#endif
#ifndef UINT8
typedef unsigned char UINT8;
#endif
#ifndef UINT16
typedef unsigned short UINT16;
#endif
#ifndef UINT32
typedef unsigned long UINT32;
#endif
#ifndef PUINT8
typedef unsigned char *PUINT8;
#endif
#ifndef PUINT16
typedef unsigned short *PUINT16;
#endif
#ifndef PUINT32
typedef unsigned long *PUINT32;
#endif
#ifndef UINT8V
typedef unsigned char volatile UINT8V;
#endif
#ifndef PUINT8V
typedef unsigned char volatile *PUINT8V;
#endif
#define CH376_DAT_BLOCK_LEN 0x40
#define CMD01_GET_IC_VER 0x01
#define CMD21_SET_BAUDRATE 0x02
#define CMD00_ENTER_SLEEP 0x03
#define CMD00_RESET_ALL 0x05
#define CMD11_CHECK_EXIST 0x06
#define CMD20_CHK_SUSPEND 0x0B
#define CMD20_SET_SDO_INT 0x0B
#define CMD14_GET_FILE_SIZE 0x0C
#define CMD50_SET_FILE_SIZE 0x0D
#define CMD11_SET_USB_MODE 0x15
#define CMD01_GET_STATUS 0x22
#define CMD00_UNLOCK_USB 0x23
#define CMD01_RD_USB_DATA0 0x27
#define CMD01_RD_USB_DATA 0x28
#define CMD10_WR_USB_DATA7 0x2B
#define CMD10_WR_HOST_DATA 0x2C
#define CMD01_WR_REQ_DATA 0x2D
#define CMD20_WR_OFS_DATA 0x2E
#define CMD10_SET_FILE_NAME 0x2F
#define CMD0H_DISK_CONNECT 0x30
#define CMD0H_DISK_MOUNT 0x31
#define CMD0H_FILE_OPEN 0x32
#define CMD0H_FILE_ENUM_GO 0x33
#define CMD0H_FILE_CREATE 0x34
#define CMD0H_FILE_ERASE 0x35
#define CMD1H_FILE_CLOSE 0x36
#define CMD1H_DIR_INFO_READ 0x37
#define CMD0H_DIR_INFO_SAVE 0x38
#define CMD4H_BYTE_LOCATE 0x39
#define CMD2H_BYTE_READ 0x3A
#define CMD0H_BYTE_RD_GO 0x3B
#define CMD2H_BYTE_WRITE 0x3C
#define CMD0H_BYTE_WR_GO 0x3D
#define CMD0H_DISK_CAPACITY 0x3E
#define CMD0H_DISK_QUERY 0x3F
#define CMD0H_DIR_CREATE 0x40
#define CMD4H_SEC_LOCATE 0x4A
#define CMD1H_SEC_READ 0x4B
#define CMD1H_SEC_WRITE 0x4C
#define CMD0H_DISK_BOC_CMD 0x50
#define CMD5H_DISK_READ 0x54
#define CMD0H_DISK_RD_GO 0x55
#define CMD5H_DISK_WRITE 0x56
#define CMD0H_DISK_WR_GO 0x57
#define CMD10_SET_USB_SPEED 0x04
#define CMD11_GET_DEV_RATE 0x0A
#define CMD11_GET_TOGGLE 0x0A
#define CMD11_READ_VAR8 0x0A
#define CMD20_SET_RETRY 0x0B
#define CMD20_WRITE_VAR8 0x0B
#define CMD14_READ_VAR32 0x0C
#define CMD50_WRITE_VAR32 0x0D
#define CMD01_DELAY_100US 0x0F
#define CMD40_SET_USB_ID 0x12
#define CMD10_SET_USB_ADDR 0x13
#define CMD01_TEST_CONNECT 0x16
#define CMD00_ABORT_NAK 0x17
#define CMD10_SET_ENDP2 0x18
#define CMD10_SET_ENDP3 0x19
#define CMD10_SET_ENDP4 0x1A
#define CMD10_SET_ENDP5 0x1B
#define CMD10_SET_ENDP6 0x1C
#define CMD10_SET_ENDP7 0x1D
#define CMD00_DIRTY_BUFFER 0x25
#define CMD10_WR_USB_DATA3 0x29
#define CMD10_WR_USB_DATA5 0x2A
#define CMD1H_CLR_STALL 0x41
#define CMD1H_SET_ADDRESS 0x45
#define CMD1H_GET_DESCR 0x46
#define CMD1H_SET_CONFIG 0x49
#define CMD0H_AUTO_SETUP 0x4D
#define CMD2H_ISSUE_TKN_X 0x4E
#define CMD1H_ISSUE_TOKEN 0x4F
#define CMD0H_DISK_INIT 0x51
#define CMD0H_DISK_RESET 0x52
#define CMD0H_DISK_SIZE 0x53
#define CMD0H_DISK_INQUIRY 0x58
#define CMD0H_DISK_READY 0x59
#define CMD0H_DISK_R_SENSE 0x5A
#define CMD0H_RD_DISK_SEC 0x5B
#define CMD0H_WR_DISK_SEC 0x5C
#define CMD0H_DISK_MAX_LUN 0x5D
/* The following definitions are only for compatibility with the command name format in the INCLUDE file of CH375 */
#ifndef _NO_CH375_COMPATIBLE_
#define CMD_GET_IC_VER CMD01_GET_IC_VER
#define CMD_SET_BAUDRATE CMD21_SET_BAUDRATE
#define CMD_ENTER_SLEEP CMD00_ENTER_SLEEP
#define CMD_RESET_ALL CMD00_RESET_ALL
#define CMD_CHECK_EXIST CMD11_CHECK_EXIST
#define CMD_CHK_SUSPEND CMD20_CHK_SUSPEND
#define CMD_SET_SDO_INT CMD20_SET_SDO_INT
#define CMD_GET_FILE_SIZE CMD14_GET_FILE_SIZE
#define CMD_SET_FILE_SIZE CMD50_SET_FILE_SIZE
#define CMD_SET_USB_MODE CMD11_SET_USB_MODE
#define CMD_GET_STATUS CMD01_GET_STATUS
#define CMD_UNLOCK_USB CMD00_UNLOCK_USB
#define CMD_RD_USB_DATA0 CMD01_RD_USB_DATA0
#define CMD_RD_USB_DATA CMD01_RD_USB_DATA
#define CMD_WR_USB_DATA7 CMD10_WR_USB_DATA7
#define CMD_WR_HOST_DATA CMD10_WR_HOST_DATA
#define CMD_WR_REQ_DATA CMD01_WR_REQ_DATA
#define CMD_WR_OFS_DATA CMD20_WR_OFS_DATA
#define CMD_SET_FILE_NAME CMD10_SET_FILE_NAME
#define CMD_DISK_CONNECT CMD0H_DISK_CONNECT
#define CMD_DISK_MOUNT CMD0H_DISK_MOUNT
#define CMD_FILE_OPEN CMD0H_FILE_OPEN
#define CMD_FILE_ENUM_GO CMD0H_FILE_ENUM_GO
#define CMD_FILE_CREATE CMD0H_FILE_CREATE
#define CMD_FILE_ERASE CMD0H_FILE_ERASE
#define CMD_FILE_CLOSE CMD1H_FILE_CLOSE
#define CMD_DIR_INFO_READ CMD1H_DIR_INFO_READ
#define CMD_DIR_INFO_SAVE CMD0H_DIR_INFO_SAVE
#define CMD_BYTE_LOCATE CMD4H_BYTE_LOCATE
#define CMD_BYTE_READ CMD2H_BYTE_READ
#define CMD_BYTE_RD_GO CMD0H_BYTE_RD_GO
#define CMD_BYTE_WRITE CMD2H_BYTE_WRITE
#define CMD_BYTE_WR_GO CMD0H_BYTE_WR_GO
#define CMD_DISK_CAPACITY CMD0H_DISK_CAPACITY
#define CMD_DISK_QUERY CMD0H_DISK_QUERY
#define CMD_DIR_CREATE CMD0H_DIR_CREATE
#define CMD_SEC_LOCATE CMD4H_SEC_LOCATE
#define CMD_SEC_READ CMD1H_SEC_READ
#define CMD_SEC_WRITE CMD1H_SEC_WRITE
#define CMD_DISK_BOC_CMD CMD0H_DISK_BOC_CMD
#define CMD_DISK_READ CMD5H_DISK_READ
#define CMD_DISK_RD_GO CMD0H_DISK_RD_GO
#define CMD_DISK_WRITE CMD5H_DISK_WRITE
#define CMD_DISK_WR_GO CMD0H_DISK_WR_GO
#define CMD_SET_USB_SPEED CMD10_SET_USB_SPEED
#define CMD_GET_DEV_RATE CMD11_GET_DEV_RATE
#define CMD_GET_TOGGLE CMD11_GET_TOGGLE
#define CMD_READ_VAR8 CMD11_READ_VAR8
#define CMD_SET_RETRY CMD20_SET_RETRY
#define CMD_WRITE_VAR8 CMD20_WRITE_VAR8
#define CMD_READ_VAR32 CMD14_READ_VAR32
#define CMD_WRITE_VAR32 CMD50_WRITE_VAR32
#define CMD_DELAY_100US CMD01_DELAY_100US
#define CMD_SET_USB_ID CMD40_SET_USB_ID
#define CMD_SET_USB_ADDR CMD10_SET_USB_ADDR
#define CMD_TEST_CONNECT CMD01_TEST_CONNECT
#define CMD_ABORT_NAK CMD00_ABORT_NAK
#define CMD_SET_ENDP2 CMD10_SET_ENDP2
#define CMD_SET_ENDP3 CMD10_SET_ENDP3
#define CMD_SET_ENDP4 CMD10_SET_ENDP4
#define CMD_SET_ENDP5 CMD10_SET_ENDP5
#define CMD_SET_ENDP6 CMD10_SET_ENDP6
#define CMD_SET_ENDP7 CMD10_SET_ENDP7
#define CMD_DIRTY_BUFFER CMD00_DIRTY_BUFFER
#define CMD_WR_USB_DATA3 CMD10_WR_USB_DATA3
#define CMD_WR_USB_DATA5 CMD10_WR_USB_DATA5
#define CMD_CLR_STALL CMD1H_CLR_STALL
#define CMD_SET_ADDRESS CMD1H_SET_ADDRESS
#define CMD_GET_DESCR CMD1H_GET_DESCR
#define CMD_SET_CONFIG CMD1H_SET_CONFIG
#define CMD_AUTO_SETUP CMD0H_AUTO_SETUP
#define CMD_ISSUE_TKN_X CMD2H_ISSUE_TKN_X
#define CMD_ISSUE_TOKEN CMD1H_ISSUE_TOKEN
#define CMD_DISK_INIT CMD0H_DISK_INIT
#define CMD_DISK_RESET CMD0H_DISK_RESET
#define CMD_DISK_SIZE CMD0H_DISK_SIZE
#define CMD_DISK_INQUIRY CMD0H_DISK_INQUIRY
#define CMD_DISK_READY CMD0H_DISK_READY
#define CMD_DISK_R_SENSE CMD0H_DISK_R_SENSE
#define CMD_RD_DISK_SEC CMD0H_RD_DISK_SEC
#define CMD_WR_DISK_SEC CMD0H_WR_DISK_SEC
#define CMD_DISK_MAX_LUN CMD0H_DISK_MAX_LUN
#endif
/* ********************************************************************************************************************* */
#ifndef PARA_STATE_INTB
#define PARA_STATE_INTB 0x80
#define PARA_STATE_BUSY 0x10
#endif
#ifndef SER_CMD_TIMEOUT
#define SER_CMD_TIMEOUT 32
#define SER_SYNC_CODE1 0x57
#define SER_SYNC_CODE2 0xAB
#endif
#ifndef CMD_RET_SUCCESS
#define CMD_RET_SUCCESS 0x51
#define CMD_RET_ABORT 0x5F
#endif
/***********************************************************************************************************************/
#ifndef USB_INT_EP0_SETUP
#define USB_INT_USB_SUSPEND 0x05
#define USB_INT_WAKE_UP 0x06
#define USB_INT_EP0_SETUP 0x0C
#define USB_INT_EP0_OUT 0x00
#define USB_INT_EP0_IN 0x08
#define USB_INT_EP1_OUT 0x01
#define USB_INT_EP1_IN 0x09
#define USB_INT_EP2_OUT 0x02
#define USB_INT_EP2_IN 0x0A
#define USB_INT_BUS_RESET1 0x03
#define USB_INT_BUS_RESET2 0x07
#define USB_INT_BUS_RESET3 0x0B
#define USB_INT_BUS_RESET4 0x0F
#endif
#ifndef USB_INT_SUCCESS
#define USB_INT_SUCCESS 0x14
#define USB_INT_CONNECT 0x15
#define USB_INT_DISCONNECT 0x16
#define USB_INT_BUF_OVER 0x17
#define USB_INT_USB_READY 0x18
#define USB_INT_DISK_READ 0x1D
#define USB_INT_DISK_WRITE 0x1E
#define USB_INT_DISK_ERR 0x1F
#endif
#ifndef ERR_DISK_DISCON
#define ERR_DISK_DISCON 0x82
#define ERR_LARGE_SECTOR 0x84
#define ERR_TYPE_ERROR 0x92
#define ERR_BPB_ERROR 0xA1
#define ERR_DISK_FULL 0xB1
#define ERR_FDT_OVER 0xB2
#define ERR_FILE_CLOSE 0xB4
#define ERR_OPEN_DIR 0x41
#define ERR_MISS_FILE 0x42
#define ERR_FOUND_NAME 0x43
#define ERR_MISS_DIR 0xB3
#define ERR_LONG_BUF_OVER 0x48
#define ERR_LONG_NAME_ERR 0x49
#define ERR_NAME_EXIST 0x4A
#endif
/* ******************************************************************************************************************** */
#ifndef DEF_DISK_UNKNOWN
#define DEF_DISK_UNKNOWN 0x00
#define DEF_DISK_DISCONN 0x01
#define DEF_DISK_CONNECT 0x02
#define DEF_DISK_MOUNTED 0x03
#define DEF_DISK_READY 0x10
#define DEF_DISK_OPEN_ROOT 0x12
#define DEF_DISK_OPEN_DIR 0x13
#define DEF_DISK_OPEN_FILE 0x14
#endif
/* **********************************************************************************************************************/
#ifndef DEF_SECTOR_SIZE
#define DEF_SECTOR_SIZE 512
#endif
#ifndef DEF_WILDCARD_CHAR
#define DEF_WILDCARD_CHAR 0x2A
#define DEF_SEPAR_CHAR1 0x5C
#define DEF_SEPAR_CHAR2 0x2F
#define DEF_FILE_YEAR 2004
#define DEF_FILE_MONTH 1
#define DEF_FILE_DATE 1
#endif
#ifndef ATTR_DIRECTORY
typedef struct _FAT_DIR_INFO {
UINT8 DIR_Name[11];
UINT8 DIR_Attr;
UINT8 DIR_NTRes;
UINT8 DIR_CrtTimeTenth;
UINT16 DIR_CrtTime;
UINT16 DIR_CrtDate;
UINT16 DIR_LstAccDate;
UINT16 DIR_FstClusHI;
UINT16 DIR_WrtTime;
UINT16 DIR_WrtDate;
UINT16 DIR_FstClusLO;
UINT32 DIR_FileSize;
} FAT_DIR_INFO, *P_FAT_DIR_INFO;
#define ATTR_READ_ONLY 0x01
#define ATTR_HIDDEN 0x02
#define ATTR_SYSTEM 0x04
#define ATTR_VOLUME_ID 0x08
#define ATTR_DIRECTORY 0x10
#define ATTR_ARCHIVE 0x20
#define ATTR_LONG_NAME (ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID)
#define ATTR_LONG_NAME_MASK (ATTR_LONG_NAME | ATTR_DIRECTORY | ATTR_ARCHIVE)
#define MAKE_FILE_TIME( h, m, s ) ( (h<<11) + (m<<5) + (s>>1) )
#define MAKE_FILE_DATE( y, m, d ) ( ((y-1980)<<9) + (m<<5) + d )
#define LONE_NAME_MAX_CHAR (255*2)
#define LONG_NAME_PER_DIR (13*2)
#endif
/* ********************************************************************************************************************* */
#ifndef SPC_CMD_INQUIRY
#define SPC_CMD_INQUIRY 0x12
#define SPC_CMD_READ_CAPACITY 0x25
#define SPC_CMD_READ10 0x28
#define SPC_CMD_WRITE10 0x2A
#define SPC_CMD_TEST_READY 0x00
#define SPC_CMD_REQUEST_SENSE 0x03
#define SPC_CMD_MODESENSE6 0x1A
#define SPC_CMD_MODESENSE10 0x5A
#define SPC_CMD_START_STOP 0x1B
typedef struct _BULK_ONLY_CBW {
UINT32 CBW_Sig;
UINT32 CBW_Tag;
UINT8 CBW_DataLen0;
UINT8 CBW_DataLen1;
UINT16 CBW_DataLen2;
UINT8 CBW_Flag;
UINT8 CBW_LUN;
UINT8 CBW_CB_Len;
UINT8 CBW_CB_Buf[16];
} BULK_ONLY_CBW, *P_BULK_ONLY_CBW;
typedef struct _INQUIRY_DATA {
UINT8 DeviceType;
UINT8 RemovableMedia;
UINT8 Versions;
UINT8 DataFormatAndEtc;
UINT8 AdditionalLength;
UINT8 Reserved1;
UINT8 Reserved2;
UINT8 MiscFlag;
UINT8 VendorIdStr[8];
UINT8 ProductIdStr[16];
UINT8 ProductRevStr[4];
} INQUIRY_DATA, *P_INQUIRY_DATA;
typedef struct _SENSE_DATA {
UINT8 ErrorCode;
UINT8 SegmentNumber;
UINT8 SenseKeyAndEtc;
UINT8 Information0;
UINT8 Information1;
UINT8 Information2;
UINT8 Information3;
UINT8 AdditSenseLen;
UINT8 CmdSpecInfo[4];
UINT8 AdditSenseCode;
UINT8 AddSenCodeQual;
UINT8 FieldReplaUnit;
UINT8 SenseKeySpec[3];
} SENSE_DATA, *P_SENSE_DATA;
#endif
/* ********************************************************************************************************************* */
#ifndef MAX_FILE_NAME_LEN
#define MAX_FILE_NAME_LEN (13+1)
typedef union _CH376_CMD_DATA {
struct {
UINT8 mBuffer[ MAX_FILE_NAME_LEN ];
} Default;
INQUIRY_DATA DiskMountInq;
FAT_DIR_INFO OpenDirInfo;
FAT_DIR_INFO EnumDirInfo;
struct {
UINT8 mUpdateFileSz;
} FileCLose;
struct {
UINT8 mDirInfoIndex;
} DirInfoRead;
union {
UINT32 mByteOffset;
UINT32 mSectorLba;
} ByteLocate;
struct {
UINT16 mByteCount;
} ByteRead;
struct {
UINT16 mByteCount;
} ByteWrite;
union {
UINT32 mSectorOffset;
UINT32 mSectorLba;
} SectorLocate;
struct {
UINT8 mSectorCount;
UINT8 mReserved1;
UINT8 mReserved2;
UINT8 mReserved3;
UINT32 mStartSector;
} SectorRead;
struct {
UINT8 mSectorCount;
UINT8 mReserved1;
UINT8 mReserved2;
UINT8 mReserved3;
UINT32 mStartSector;
} SectorWrite;
struct {
UINT32 mDiskSizeSec;
} DiskCapacity;
struct {
UINT32 mTotalSector;
UINT32 mFreeSector;
UINT8 mDiskFat;
} DiskQuery;
BULK_ONLY_CBW DiskBocCbw;
struct {
UINT8 mMaxLogicUnit;
} DiskMaxLun;
INQUIRY_DATA DiskInitInq;
INQUIRY_DATA DiskInqData;
SENSE_DATA ReqSenseData;
struct {
UINT32 mDiskSizeSec;
} DiskSize;
struct {
UINT32 mStartSector;
UINT8 mSectorCount;
} DiskRead;
struct {
UINT32 mStartSector;
UINT8 mSectorCount;
} DiskWrite;
} CH376_CMD_DATA, *P_CH376_CMD_DATA;
#endif
/* ********************************************************************************************************************* */
#ifndef VAR_FILE_SIZE
#define VAR_SYS_BASE_INFO 0x20
#define VAR_RETRY_TIMES 0x25
#define VAR_FILE_BIT_FLAG 0x26
#define VAR_DISK_STATUS 0x2B
#define VAR_SD_BIT_FLAG 0x30
#define VAR_UDISK_TOGGLE 0x31
#define VAR_UDISK_LUN 0x34
#define VAR_SEC_PER_CLUS 0x38
#define VAR_FILE_DIR_INDEX 0x3B
#define VAR_CLUS_SEC_OFS 0x3C
#define VAR_DISK_ROOT 0x44
#define VAR_DSK_TOTAL_CLUS 0x48
#define VAR_DSK_START_LBA 0x4C
#define VAR_DSK_DAT_START 0x50
#define VAR_LBA_BUFFER 0x54
#define VAR_LBA_CURRENT 0x58
#define VAR_FAT_DIR_LBA 0x5C
#define VAR_START_CLUSTER 0x60
#define VAR_CURRENT_CLUST 0x64
#define VAR_FILE_SIZE 0x68
#define VAR_CURRENT_OFFSET 0x6C
#endif
/* ********************************************************************************************************************* */
#ifndef DEF_USB_PID_SETUP
#define DEF_USB_PID_NULL 0x00
#define DEF_USB_PID_SOF 0x05
#define DEF_USB_PID_SETUP 0x0D
#define DEF_USB_PID_IN 0x09
#define DEF_USB_PID_OUT 0x01
#define DEF_USB_PID_ACK 0x02
#define DEF_USB_PID_NAK 0x0A
#define DEF_USB_PID_STALL 0x0E
#define DEF_USB_PID_DATA0 0x03
#define DEF_USB_PID_DATA1 0x0B
#define DEF_USB_PID_PRE 0x0C
#endif
#ifndef DEF_USB_REQ_TYPE
#define DEF_USB_REQ_READ 0x80
#define DEF_USB_REQ_WRITE 0x00
#define DEF_USB_REQ_TYPE 0x60
#define DEF_USB_REQ_STAND 0x00
#define DEF_USB_REQ_CLASS 0x20
#define DEF_USB_REQ_VENDOR 0x40
#define DEF_USB_REQ_RESERVE 0x60
#endif
#ifndef DEF_USB_GET_DESCR
#define DEF_USB_CLR_FEATURE 0x01
#define DEF_USB_SET_FEATURE 0x03
#define DEF_USB_GET_STATUS 0x00
#define DEF_USB_SET_ADDRESS 0x05
#define DEF_USB_GET_DESCR 0x06
#define DEF_USB_SET_DESCR 0x07
#define DEF_USB_GET_CONFIG 0x08
#define DEF_USB_SET_CONFIG 0x09
#define DEF_USB_GET_INTERF 0x0A
#define DEF_USB_SET_INTERF 0x0B
#define DEF_USB_SYNC_FRAME 0x0C
#endif
/* ********************************************************************************************************************* */
#ifdef __cplusplus
}
#endif
#endif

View File

@ -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 edu-riscv64.h
* @brief edu-riscv64 edu-riscv64.h
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.03.17
*/
#ifndef __BOARDS_RISCV_K210_EDU_RISCV64_SRC_EDU_RISCV64_H
#define __BOARDS_RISCV_K210_EDU_RISCV64_SRC_EDU_RISCV64_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
int k210_bringup(void);
#ifdef CONFIG_DEV_GPIO
int k210_gpio_init(void);
#endif
#endif /* __BOARDS_RISCV_K210_EDU_RISCV64_SRC_EDU_RISCV64_H */

View File

@ -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.
*/
/**
* @file k210_appinit.c
* @brief edu-riscv64 k210_appinit.c
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.03.17
*/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdbool.h>
#include <stdio.h>
#include <syslog.h>
#include <errno.h>
#include <nuttx/board.h>
#include "k210.h"
#include "edu-riscv64.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: board_app_initialize
*
* Description:
* Perform architecture specific initialization
*
* Input Parameters:
* arg - The boardctl() argument is passed to the board_app_initialize()
* implementation without modification. The argument has no
* meaning to NuttX; the meaning of the argument is a contract
* between the board-specific initialization logic and the
* matching application logic. The value could be such things as a
* mode enumeration value, a set of DIP switch switch settings, a
* pointer to configuration data read from a file or serial FLASH,
* or whatever you would like to do with it. Every implementation
* should accept zero/NULL as a default configuration.
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned on
* any failure to indicate the nature of the failure.
*
****************************************************************************/
int board_app_initialize(uintptr_t arg)
{
#ifdef CONFIG_BOARD_LATE_INITIALIZE
/* Board initialization already performed by board_late_initialize() */
return OK;
#else
/* Perform board-specific initialization */
return k210_bringup();
#endif
}

View File

@ -0,0 +1,59 @@
/*
* 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 k210_boot.c
* @brief edu-riscv64 k210_boot.c
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.03.17
*/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <debug.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: k210_boardinitialize
*
* Description:
* All K210 architectures must provide the following entry point.
* This entry point is called early in the initialization -- after all
* memory has been configured and mapped but before any devices have been
* initialized.
*
****************************************************************************/
void k210_boardinitialize(void)
{
board_autoled_initialize();
}

View File

@ -0,0 +1,125 @@
/*
* 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 k210_bringup.c
* @brief edu-riscv64 k210_bringup.c
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.03.17
*/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdbool.h>
#include <stdio.h>
#include <debug.h>
#include <errno.h>
#include <nuttx/board.h>
#include <nuttx/fs/fs.h>
#include <nuttx/arch.h>
#include "k210.h"
#include "k210_clockconfig.h"
#include "edu-riscv64.h"
#include <arch/board/board.h>
#include "k210_sysctl.h"
#include "k210_fpioa.h"
#include "k210_gpiohs.h"
#include "k210_gpio_common.h"
#ifdef CONFIG_BSP_USING_CH438
# include "k210_ch438.h"
#endif
#ifdef CONFIG_BSP_USING_TOUCH
# include "k210_touch.h"
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: k210_bringup
****************************************************************************/
int k210_bringup(void)
{
int ret = OK;
#ifdef CONFIG_FS_PROCFS
/* Mount the procfs file system */
ret = nx_mount(NULL, "/proc", "procfs", 0, NULL);
if (ret < 0)
{
serr("ERROR: Failed to mount procfs at %s: %d\n", "/proc", ret);
}
#endif
#ifdef CONFIG_DEV_GPIO
ret = k210_gpio_init();
if (ret < 0)
{
syslog(LOG_ERR, "Failed to initialize GPIO Driver: %d\n", ret);
return ret;
}
#endif
#ifdef CONFIG_K210_LCD
k210_sysctl_init();
board_lcd_initialize();
#endif
#ifdef CONFIG_BSP_USING_TOUCH
board_touch_initialize();
#endif
#ifdef CONFIG_K210_UART1
sysctl_clock_enable(SYSCTL_CLOCK_UART1);
sysctl_reset(SYSCTL_RESET_UART1);
fpioa_set_function(GPIO_WIFI_TXD, FPOA_USART1_RX);
fpioa_set_function(GPIO_WIFI_RXD, FPOA_USART1_TX);
fpioa_set_function(GPIO_WIFI_EN, K210_IO_FUNC_GPIOHS0 + FPIOA_WIFI_EN);
k210_gpiohs_set_direction(FPIOA_WIFI_EN, GPIO_DM_OUTPUT);
k210_gpiohs_set_value(FPIOA_WIFI_EN, GPIO_PV_LOW);
up_mdelay(50);
k210_gpiohs_set_value(FPIOA_WIFI_EN, GPIO_PV_HIGH);
#endif
#ifdef CONFIG_K210_UART2
sysctl_clock_enable(SYSCTL_CLOCK_UART2);
sysctl_reset(SYSCTL_RESET_UART2);
fpioa_set_function(GPIO_E220_RXD, FPOA_USART2_RX);
fpioa_set_function(GPIO_E220_TXD, FPOA_USART2_TX);
#endif
#ifdef CONFIG_K210_UART3
sysctl_clock_enable(SYSCTL_CLOCK_UART3);
sysctl_reset(SYSCTL_RESET_UART3);
fpioa_set_function(GPIO_CH376T_RXD, FPOA_USART3_RX);
fpioa_set_function(GPIO_CH376T_TXD, FPOA_USART3_TX);
#endif
return ret;
}

View File

@ -0,0 +1,960 @@
/*
* 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 k210_ch376.c
* @brief edu-riscv64 k210_ch376.c
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.10.10
*/
#if 0
#define DEF_IC_V43_U 1
#endif
#include "k210_ch376.h"
/****************************************************************************
* Private Data
****************************************************************************/
static int fd;
/* Serial port mode is not used */
void xEndCH376Cmd(void)
{
}
void xWriteCH376Cmd(UINT8 cmd)
{
UINT8 temp[3];
temp[0] = 0x57;
temp[1] = 0xab;
temp[2] = cmd;
up_udelay(5);
write(fd, temp, 3);
}
void xWriteCH376Data(UINT8 dat)
{
UINT8 tmp = dat;
write(fd, &tmp, 1);
up_udelay(2);
}
UINT8 xReadCH376Data(void)
{
UINT32 i;
UINT8 data;
int res;
for(i=0;i<500000;i++)
{
res = read(fd, &data, 1);
if(res == 1)
{
return ((UINT8)data);
}
up_udelay(1);
}
return ERR_USB_UNKNOWN;
}
UINT8 CH376ReadBlock(PUINT8 buf)
{
UINT8 s, l;
xWriteCH376Cmd( CMD01_RD_USB_DATA0 );
s = l = xReadCH376Data( );
if ( l ) {
do {
*buf = xReadCH376Data( );
buf ++;
} while ( -- l );
}
xEndCH376Cmd( );
return( s );
}
UINT8 Query376Interrupt(void)
{
//When an interrupt occurs, the serial port will receive a data, read it directly, and discard it
if(xReadCH376Data() == ERR_USB_UNKNOWN) return FALSE ;
else return TRUE ;
}
/* CH376 INIT */
UINT8 mInitCH376Host(void)
{
UINT8 res;
/* After power on, delay operation for at least 50ms */
up_mdelay(50);
fd = open("/dev/ttyS3", O_RDWR);
up_mdelay(600);
/* Test the communication interface between SCM and CH376 */
xWriteCH376Cmd(CMD11_CHECK_EXIST);
xWriteCH376Data(0x65);
res = xReadCH376Data();
xEndCH376Cmd();
if ( res != 0x9A ) return( ERR_USB_UNKNOWN );
xWriteCH376Cmd(CMD11_SET_USB_MODE); /* SET USB MODE */
xWriteCH376Data(CONFIG_CH376_WORK_MODE);
up_udelay(20);
res = xReadCH376Data();
xEndCH376Cmd();
if (res == CMD_RET_SUCCESS) return(USB_INT_SUCCESS);
else return(ERR_USB_UNKNOWN); /* SET MODE ERROR */
}
/* Write the requested data block to the internally specified buffer, and return the length */
UINT8 CH376WriteReqBlock(PUINT8 buf)
{
UINT8 s, l;
xWriteCH376Cmd( CMD01_WR_REQ_DATA );
s = l = xReadCH376Data();
if ( l ) {
do {
xWriteCH376Data( *buf );
buf ++;
} while ( -- l );
}
xEndCH376Cmd( );
return( s );
}
/* Write data block to the send buffer of USB host endpoint */
void CH376WriteHostBlock(PUINT8 buf, UINT8 len)
{
xWriteCH376Cmd( CMD10_WR_HOST_DATA );
xWriteCH376Data( len );
if ( len ) {
do {
xWriteCH376Data( *buf );
buf ++;
} while ( -- len );
}
xEndCH376Cmd( );
}
/* Specify offset address to write data block to internal buffer */
void CH376WriteOfsBlock( PUINT8 buf, UINT8 ofs, UINT8 len )
{
xWriteCH376Cmd( CMD20_WR_OFS_DATA );
xWriteCH376Data( ofs ); /* Offset address */
xWriteCH376Data( len ); /* length */
if ( len ) {
do {
xWriteCH376Data( *buf );
buf ++;
} while ( -- len );
}
xEndCH376Cmd( );
}
/* Set the file name of the file to be operated on */
void CH376SetFileName( PUINT8 name )
{
UINT8 c;
#ifndef DEF_IC_V43_U
UINT8 s;
xWriteCH376Cmd( CMD01_GET_IC_VER );
if ( xReadCH376Data( ) < 0x43 ) {
if ( CH376ReadVar8( VAR_DISK_STATUS ) < DEF_DISK_READY ) {
xWriteCH376Cmd( CMD10_SET_FILE_NAME );
xWriteCH376Data( 0 );
s = CH376SendCmdWaitInt( CMD0H_FILE_OPEN );
if ( s == USB_INT_SUCCESS ) {
s = CH376ReadVar8( 0xCF );
if ( s ) {
CH376WriteVar32( 0x4C, CH376ReadVar32( 0x4C ) + ( (UINT16)s << 8 ) );
CH376WriteVar32( 0x50, CH376ReadVar32( 0x50 ) + ( (UINT16)s << 8 ) );
CH376WriteVar32( 0x70, 0 );
}
}
}
}
#endif
xWriteCH376Cmd( CMD10_SET_FILE_NAME );
c = *name;
xWriteCH376Data( c );
while ( c ) {
name ++;
c = *name;
/* Force the file name to expire */
if ( c == DEF_SEPAR_CHAR1 || c == DEF_SEPAR_CHAR2 ) c = 0;
xWriteCH376Data( c );
}
xEndCH376Cmd( );
}
/* Read 32-bit data from CH376 chip and end the command */
UINT32 CH376Read32bitDat( void )
{
UINT8 c0, c1, c2, c3;
c0 = xReadCH376Data( );
c1 = xReadCH376Data( );
c2 = xReadCH376Data( );
c3 = xReadCH376Data( );
xEndCH376Cmd( );
return( c0 | (UINT16)c1 << 8 | (UINT32)c2 << 16 | (UINT32)c3 << 24 );
}
UINT8 CH376ReadVar8( UINT8 var )
{
UINT8 c0;
xWriteCH376Cmd( CMD11_READ_VAR8 );
xWriteCH376Data( var );
c0 = xReadCH376Data( );
xEndCH376Cmd( );
return( c0 );
}
void CH376WriteVar8( UINT8 var, UINT8 dat )
{
xWriteCH376Cmd( CMD20_WRITE_VAR8 );
xWriteCH376Data( var );
xWriteCH376Data( dat );
xEndCH376Cmd( );
}
UINT32 CH376ReadVar32( UINT8 var )
{
xWriteCH376Cmd( CMD14_READ_VAR32 );
xWriteCH376Data( var );
return( CH376Read32bitDat( ) );
}
void CH376WriteVar32( UINT8 var, UINT32 dat )
{
xWriteCH376Cmd( CMD50_WRITE_VAR32 );
xWriteCH376Data( var );
xWriteCH376Data( (UINT8)dat );
xWriteCH376Data( (UINT8)( (UINT16)dat >> 8 ) );
xWriteCH376Data( (UINT8)( dat >> 16 ) );
xWriteCH376Data( (UINT8)( dat >> 24 ) );
xEndCH376Cmd( );
}
void CH376EndDirInfo( void )
{
CH376WriteVar8( 0x0D, 0x00 );
}
UINT32 CH376GetFileSize( void )
{
return( CH376ReadVar32( VAR_FILE_SIZE ) );
}
UINT8 CH376GetDiskStatus( void )
{
return( CH376ReadVar8( VAR_DISK_STATUS ) );
}
UINT8 CH376GetIntStatus( void )
{
UINT8 s;
xWriteCH376Cmd( CMD01_GET_STATUS );
s = xReadCH376Data( );
xEndCH376Cmd( );
return( s );
}
#ifndef NO_DEFAULT_CH376_INT
UINT8 Wait376Interrupt( void )
{
#ifdef DEF_INT_TIMEOUT
#if DEF_INT_TIMEOUT < 1
while ( Query376Interrupt( ) == FALSE );
return( CH376GetIntStatus( ) );
#else
UINT32 i;
for ( i = 0; i < DEF_INT_TIMEOUT; i ++ ) {
if ( Query376Interrupt( ) ) return( CH376GetIntStatus( ) );
}
return( ERR_USB_UNKNOWN );
#endif
#else
UINT32 i;
for ( i = 0; i < 5000000; i ++ ) {
if ( Query376Interrupt( ) ) return( CH376GetIntStatus( ) );
}
return( ERR_USB_UNKNOWN );
#endif
}
#endif
UINT8 CH376SendCmdWaitInt( UINT8 mCmd )
{
xWriteCH376Cmd( mCmd );
xEndCH376Cmd( );
return( Wait376Interrupt( ) );
}
UINT8 CH376SendCmdDatWaitInt( UINT8 mCmd, UINT8 mDat )
{
xWriteCH376Cmd( mCmd );
xWriteCH376Data( mDat );
xEndCH376Cmd( );
return(Wait376Interrupt());
}
UINT8 CH376DiskReqSense( void )
{
UINT8 s;
up_mdelay( 5 );
s = CH376SendCmdWaitInt( CMD0H_DISK_R_SENSE );
up_mdelay( 5 );
return( s );
}
UINT8 CH376DiskConnect( void )
{
if ( Query376Interrupt( ) ) CH376GetIntStatus( );
return( CH376SendCmdWaitInt( CMD0H_DISK_CONNECT ) );
}
UINT8 CH376DiskMount( void )
{
return( CH376SendCmdWaitInt( CMD0H_DISK_MOUNT ) );
}
UINT8 CH376FileOpen( PUINT8 name )
{
CH376SetFileName( name );
#ifndef DEF_IC_V43_U
if ( name[0] == DEF_SEPAR_CHAR1 || name[0] == DEF_SEPAR_CHAR2 ) CH376WriteVar32( VAR_CURRENT_CLUST, 0 );
#endif
return( CH376SendCmdWaitInt( CMD0H_FILE_OPEN ) );
}
UINT8 CH376FileCreate( PUINT8 name )
{
if ( name ) CH376SetFileName( name );
return( CH376SendCmdWaitInt( CMD0H_FILE_CREATE ) );
}
UINT8 CH376DirCreate( PUINT8 name )
{
CH376SetFileName( name );
#ifndef DEF_IC_V43_U
if ( name[0] == DEF_SEPAR_CHAR1 || name[0] == DEF_SEPAR_CHAR2 ) CH376WriteVar32( VAR_CURRENT_CLUST, 0 );
#endif
return( CH376SendCmdWaitInt( CMD0H_DIR_CREATE ) );
}
UINT8 CH376SeparatePath( PUINT8 path )
{
PUINT8 pName;
for ( pName = path; *pName != 0; ++ pName );
while ( *pName != DEF_SEPAR_CHAR1 && *pName != DEF_SEPAR_CHAR2 && pName != path ) pName --;
if ( pName != path ) pName ++;
return( pName - path );
}
UINT8 CH376FileOpenDir( PUINT8 PathName, UINT8 StopName )
{
UINT8 i, s;
s = 0;
i = 1;
while ( 1 ) {
while ( PathName[i] != DEF_SEPAR_CHAR1 && PathName[i] != DEF_SEPAR_CHAR2 && PathName[i] != 0 ) ++ i;
if ( PathName[i] ) i ++;
else i = 0;
s = CH376FileOpen( &PathName[s] );
if ( i && i != StopName ) {
if ( s != ERR_OPEN_DIR ) {
if ( s == USB_INT_SUCCESS ) return( ERR_FOUND_NAME );
else if ( s == ERR_MISS_FILE ) return( ERR_MISS_DIR );
else return( s );
}
s = i;
}
else return( s );
}
}
UINT8 CH376FileOpenPath( PUINT8 PathName )
{
return( CH376FileOpenDir( PathName, 0xFF ) );
}
UINT8 CH376FileCreatePath( PUINT8 PathName )
{
UINT8 s;
UINT8 Name;
Name = CH376SeparatePath( PathName );
if ( Name ) {
s = CH376FileOpenDir( PathName, Name );
if ( s != ERR_OPEN_DIR ) {
if ( s == USB_INT_SUCCESS ) return( ERR_FOUND_NAME );
else if ( s == ERR_MISS_FILE ) return( ERR_MISS_DIR );
else return( s );
}
}
return( CH376FileCreate( &PathName[Name] ) );
}
#ifdef EN_DIR_CREATE
UINT8 CH376DirCreatePath( PUINT8 PathName )
{
UINT8 s;
UINT8 Name;
UINT8 ClustBuf[4];
Name = CH376SeparatePath( PathName );
if ( Name ) {
s = CH376FileOpenDir( PathName, Name );
if ( s != ERR_OPEN_DIR ) {
if ( s == USB_INT_SUCCESS ) return( ERR_FOUND_NAME );
else if ( s == ERR_MISS_FILE ) return( ERR_MISS_DIR );
else return( s );
}
xWriteCH376Cmd( CMD14_READ_VAR32 );
xWriteCH376Data( VAR_START_CLUSTER );
for ( s = 0; s != 4; s ++ ) ClustBuf[ s ] = xReadCH376Data( );
xEndCH376Cmd( );
s = CH376DirCreate( &PathName[Name] );
if ( s != USB_INT_SUCCESS ) return( s );
CH376WriteVar32( VAR_FILE_SIZE, sizeof(FAT_DIR_INFO) * 2 );
s = CH376ByteLocate( sizeof(FAT_DIR_INFO) + STRUCT_OFFSET( FAT_DIR_INFO, DIR_FstClusHI ) );
if ( s != USB_INT_SUCCESS ) return( s );
s = CH376ByteWrite( &ClustBuf[2], 2, NULL );
if ( s != USB_INT_SUCCESS ) return( s );
s = CH376ByteLocate( sizeof(FAT_DIR_INFO) + STRUCT_OFFSET( FAT_DIR_INFO, DIR_FstClusLO ) );
if ( s != USB_INT_SUCCESS ) return( s );
s = CH376ByteWrite( ClustBuf, 2, NULL );
if ( s != USB_INT_SUCCESS ) return( s );
s = CH376ByteLocate( 0 );
if ( s != USB_INT_SUCCESS ) return( s );
CH376WriteVar32( VAR_FILE_SIZE, 0 );
return( s );
}
else {
if ( PathName[0] == DEF_SEPAR_CHAR1 || PathName[0] == DEF_SEPAR_CHAR2 ) return( CH376DirCreate( PathName ) );
else return( ERR_MISS_DIR );
}
}
#endif
UINT8 CH376FileErase( PUINT8 PathName )
{
UINT8 s;
if ( PathName ) {
for ( s = 1; PathName[s] != DEF_SEPAR_CHAR1 && PathName[s] != DEF_SEPAR_CHAR2 && PathName[s] != 0; ++ s );
if ( PathName[s] ) {
s = CH376FileOpenPath( PathName );
if ( s != USB_INT_SUCCESS && s != ERR_OPEN_DIR ) return( s );
}
else CH376SetFileName( PathName );
}
return( CH376SendCmdWaitInt( CMD0H_FILE_ERASE ) );
}
UINT8 CH376FileClose( UINT8 UpdateSz )
{
return( CH376SendCmdDatWaitInt( CMD1H_FILE_CLOSE, UpdateSz ) );
}
UINT8 CH376DirInfoRead( void )
{
return( CH376SendCmdDatWaitInt( CMD1H_DIR_INFO_READ, 0xFF ) );
}
UINT8 CH376DirInfoSave( void )
{
return( CH376SendCmdWaitInt( CMD0H_DIR_INFO_SAVE ) );
}
UINT8 CH376ByteLocate( UINT32 offset )
{
xWriteCH376Cmd( CMD4H_BYTE_LOCATE );
xWriteCH376Data( (UINT8)offset );
xWriteCH376Data( (UINT8)((UINT16)offset>>8) );
xWriteCH376Data( (UINT8)(offset>>16) );
xWriteCH376Data( (UINT8)(offset>>24) );
xEndCH376Cmd( );
return( Wait376Interrupt( ) );
}
UINT8 CH376ByteRead( PUINT8 buf, UINT16 ReqCount, PUINT16 RealCount )
{
UINT8 s;
xWriteCH376Cmd( CMD2H_BYTE_READ );
xWriteCH376Data( (UINT8)ReqCount );
xWriteCH376Data( (UINT8)(ReqCount>>8) );
xEndCH376Cmd( );
if ( RealCount ) *RealCount = 0;
while ( 1 ) {
s = Wait376Interrupt( );
if ( s == USB_INT_DISK_READ ) {
s = CH376ReadBlock( buf );
xWriteCH376Cmd( CMD0H_BYTE_RD_GO );
xEndCH376Cmd( );
buf += s;
if ( RealCount ) *RealCount += s;
}
else return( s );
}
}
UINT8 CH376ByteWrite( PUINT8 buf, UINT16 ReqCount, PUINT16 RealCount )
{
UINT8 s;
xWriteCH376Cmd( CMD2H_BYTE_WRITE );
xWriteCH376Data( (UINT8)ReqCount );
xWriteCH376Data( (UINT8)(ReqCount>>8) );
xEndCH376Cmd( );
if ( RealCount ) *RealCount = 0;
while ( 1 ) {
s = Wait376Interrupt( );
if ( s == USB_INT_DISK_WRITE ) {
s = CH376WriteReqBlock( buf );
xWriteCH376Cmd( CMD0H_BYTE_WR_GO );
xEndCH376Cmd( );
buf += s;
if ( RealCount ) *RealCount += s;
}
else return( s );
}
}
#ifdef EN_DISK_QUERY
UINT8 CH376DiskCapacity( PUINT32 DiskCap )
{
UINT8 s;
s = CH376SendCmdWaitInt( CMD0H_DISK_CAPACITY );
if ( s == USB_INT_SUCCESS ) {
xWriteCH376Cmd( CMD01_RD_USB_DATA0 );
xReadCH376Data( );
*DiskCap = CH376Read32bitDat( );
}
else *DiskCap = 0;
return( s );
}
UINT8 CH376DiskQuery( PUINT32 DiskFre )
{
UINT8 s;
UINT8 c0, c1, c2, c3;
#ifndef DEF_IC_V43_U
xWriteCH376Cmd( CMD01_GET_IC_VER );
if ( xReadCH376Data( ) < 0x43 ) {
if ( CH376ReadVar8( VAR_DISK_STATUS ) >= DEF_DISK_READY ) CH376WriteVar8( VAR_DISK_STATUS, DEF_DISK_MOUNTED );
}
#endif
s = CH376SendCmdWaitInt( CMD0H_DISK_QUERY );
if ( s == USB_INT_SUCCESS ) {
xWriteCH376Cmd( CMD01_RD_USB_DATA0 );
xReadCH376Data( );
xReadCH376Data( );
xReadCH376Data( );
xReadCH376Data( );
xReadCH376Data( );
c0 = xReadCH376Data( );
c1 = xReadCH376Data( );
c2 = xReadCH376Data( );
c3 = xReadCH376Data( );
*DiskFre = c0 | (UINT16)c1 << 8 | (UINT32)c2 << 16 | (UINT32)c3 << 24;
xReadCH376Data( );
xEndCH376Cmd( );
}
else *DiskFre = 0;
return( s );
}
#endif
UINT8 CH376SecLocate( UINT32 offset )
{
xWriteCH376Cmd( CMD4H_SEC_LOCATE );
xWriteCH376Data( (UINT8)offset );
xWriteCH376Data( (UINT8)((UINT16)offset>>8) );
xWriteCH376Data( (UINT8)(offset>>16) );
xWriteCH376Data( 0 );
xEndCH376Cmd( );
return( Wait376Interrupt( ) );
}
#ifdef EN_SECTOR_ACCESS
UINT8 CH376DiskReadSec( PUINT8 buf, UINT32 iLbaStart, UINT8 iSectorCount )
{
UINT8 s, err;
UINT16 mBlockCount;
for ( err = 0; err != 3; ++ err ) {
xWriteCH376Cmd( CMD5H_DISK_READ );
xWriteCH376Data( (UINT8)iLbaStart );
xWriteCH376Data( (UINT8)( (UINT16)iLbaStart >> 8 ) );
xWriteCH376Data( (UINT8)( iLbaStart >> 16 ) );
xWriteCH376Data( (UINT8)( iLbaStart >> 24 ) );
xWriteCH376Data( iSectorCount );
xEndCH376Cmd( );
for ( mBlockCount = iSectorCount * DEF_SECTOR_SIZE / CH376_DAT_BLOCK_LEN; mBlockCount != 0; -- mBlockCount ) {
s = Wait376Interrupt( );
if ( s == USB_INT_DISK_READ ) {
s = CH376ReadBlock( buf );
xWriteCH376Cmd( CMD0H_DISK_RD_GO );
xEndCH376Cmd( );
buf += s;
}
else break;
}
if ( mBlockCount == 0 ) {
s = Wait376Interrupt( );
if ( s == USB_INT_SUCCESS ) return( USB_INT_SUCCESS );
}
if ( s == USB_INT_DISCONNECT ) return( s );
CH376DiskReqSense( );
}
return( s );
}
UINT8 CH376DiskWriteSec( PUINT8 buf, UINT32 iLbaStart, UINT8 iSectorCount )
{
UINT8 s, err;
UINT16 mBlockCount;
for ( err = 0; err != 3; ++ err ) {
xWriteCH376Cmd( CMD5H_DISK_WRITE );
xWriteCH376Data( (UINT8)iLbaStart );
xWriteCH376Data( (UINT8)( (UINT16)iLbaStart >> 8 ) );
xWriteCH376Data( (UINT8)( iLbaStart >> 16 ) );
xWriteCH376Data( (UINT8)( iLbaStart >> 24 ) );
xWriteCH376Data( iSectorCount );
xEndCH376Cmd( );
for ( mBlockCount = iSectorCount * DEF_SECTOR_SIZE / CH376_DAT_BLOCK_LEN; mBlockCount != 0; -- mBlockCount ) {
s = Wait376Interrupt( );
if ( s == USB_INT_DISK_WRITE ) {
CH376WriteHostBlock( buf, CH376_DAT_BLOCK_LEN );
xWriteCH376Cmd( CMD0H_DISK_WR_GO );
xEndCH376Cmd( );
buf += CH376_DAT_BLOCK_LEN;
}
else break;
}
if ( mBlockCount == 0 ) {
s = Wait376Interrupt( );
if ( s == USB_INT_SUCCESS ) return( USB_INT_SUCCESS );
}
if ( s == USB_INT_DISCONNECT ) return( s );
CH376DiskReqSense( );
}
return( s );
}
UINT8 CH376SecRead( PUINT8 buf, UINT8 ReqCount, PUINT8 RealCount )
{
UINT8 s;
UINT8 cnt;
UINT32 StaSec;
#ifndef DEF_IC_V43_U
UINT32 fsz, fofs;
#endif
if ( RealCount ) *RealCount = 0;
do {
#ifndef DEF_IC_V43_U
xWriteCH376Cmd( CMD01_GET_IC_VER );
cnt = xReadCH376Data( );
if ( cnt == 0x41 ) {
xWriteCH376Cmd( CMD14_READ_VAR32 );
xWriteCH376Data( VAR_FILE_SIZE );
xReadCH376Data( );
fsz = xReadCH376Data( );
fsz |= (UINT16)(xReadCH376Data( )) << 8;
cnt = xReadCH376Data( );
fsz |= (UINT32)cnt << 16;
xWriteCH376Cmd( CMD14_READ_VAR32 );
xWriteCH376Data( VAR_CURRENT_OFFSET );
xReadCH376Data( );
fofs = xReadCH376Data( );
fofs |= (UINT16)(xReadCH376Data( )) << 8;
fofs |= (UINT32)(xReadCH376Data( )) << 16;
if ( fsz >= fofs + 510 ) CH376WriteVar8( VAR_FILE_SIZE + 3, 0xFF );
else cnt = 0xFF;
}
else cnt = 0xFF;
#endif
xWriteCH376Cmd( CMD1H_SEC_READ );
xWriteCH376Data( ReqCount );
xEndCH376Cmd( );
s = Wait376Interrupt( );
#ifndef DEF_IC_V43_U
if ( cnt != 0xFF ) CH376WriteVar8( VAR_FILE_SIZE + 3, cnt );
#endif
if ( s != USB_INT_SUCCESS ) return( s );
xWriteCH376Cmd( CMD01_RD_USB_DATA0 );
xReadCH376Data( );
cnt = xReadCH376Data( );
xReadCH376Data( );
xReadCH376Data( );
xReadCH376Data( );
StaSec = CH376Read32bitDat( );
if ( cnt == 0 ) break;
s = CH376DiskReadSec( buf, StaSec, cnt );
if ( s != USB_INT_SUCCESS ) return( s );
buf += cnt * DEF_SECTOR_SIZE;
if ( RealCount ) *RealCount += cnt;
ReqCount -= cnt;
} while ( ReqCount );
return( s );
}
UINT8 CH376SecWrite( PUINT8 buf, UINT8 ReqCount, PUINT8 RealCount )
{
UINT8 s;
UINT8 cnt;
UINT32 StaSec;
if ( RealCount ) *RealCount = 0;
do {
xWriteCH376Cmd( CMD1H_SEC_WRITE );
xWriteCH376Data( ReqCount );
xEndCH376Cmd( );
s = Wait376Interrupt( );
if ( s != USB_INT_SUCCESS ) return( s );
xWriteCH376Cmd( CMD01_RD_USB_DATA0 );
xReadCH376Data( );
cnt = xReadCH376Data( );
xReadCH376Data( );
xReadCH376Data( );
xReadCH376Data( );
StaSec = CH376Read32bitDat( );
if ( cnt == 0 ) break;
s = CH376DiskWriteSec( buf, StaSec, cnt );
if ( s != USB_INT_SUCCESS ) return( s );
buf += cnt * DEF_SECTOR_SIZE;
if ( RealCount ) *RealCount += cnt;
ReqCount -= cnt;
} while ( ReqCount );
return( s );
}
#endif
#ifdef EN_LONG_NAME
UINT8 CH376LongNameWrite( PUINT8 buf, UINT16 ReqCount )
{
UINT8 s;
#ifndef DEF_IC_V43_U
UINT8 c;
c = CH376ReadVar8( VAR_DISK_STATUS );
if ( c == DEF_DISK_OPEN_ROOT ) CH376WriteVar8( VAR_DISK_STATUS, DEF_DISK_OPEN_DIR );
#endif
xWriteCH376Cmd( CMD2H_BYTE_WRITE );
xWriteCH376Data( (UINT8)ReqCount );
xWriteCH376Data( (UINT8)(ReqCount>>8) );
xEndCH376Cmd( );
while ( 1 ) {
s = Wait376Interrupt( );
if ( s == USB_INT_DISK_WRITE ) {
if ( buf ) buf += CH376WriteReqBlock( buf );
else {
xWriteCH376Cmd( CMD01_WR_REQ_DATA );
s = xReadCH376Data( );
while ( s -- ) xWriteCH376Data( 0 );
}
xWriteCH376Cmd( CMD0H_BYTE_WR_GO );
xEndCH376Cmd( );
}
else {
#ifndef DEF_IC_V43_U
if ( c == DEF_DISK_OPEN_ROOT ) CH376WriteVar8( VAR_DISK_STATUS, c );
#endif
return( s );
}
}
}
UINT8 CH376CheckNameSum( PUINT8 DirName )
{
UINT8 NameLen;
UINT8 CheckSum;
CheckSum = 0;
for ( NameLen = 0; NameLen != 11; NameLen ++ ) CheckSum = ( CheckSum & 1 ? 0x80 : 0x00 ) + ( CheckSum >> 1 ) + *DirName++;
return( CheckSum );
}
UINT8 CH376LocateInUpDir( PUINT8 PathName )
{
UINT8 s;
xWriteCH376Cmd( CMD14_READ_VAR32 );
xWriteCH376Data( VAR_FAT_DIR_LBA );
for ( s = 4; s != 8; s ++ ) GlobalBuf[ s ] = xReadCH376Data( );
xEndCH376Cmd( );
s = CH376SeparatePath( PathName );
if ( s ) s = CH376FileOpenDir( PathName, s );
else s = CH376FileOpen( "/" );
if ( s != ERR_OPEN_DIR ) return( s );
*(PUINT32)(&GlobalBuf[0]) = 0;
while ( 1 ) {
s = CH376SecLocate( *(PUINT32)(&GlobalBuf[0]) );
if ( s != USB_INT_SUCCESS ) return( s );
CH376ReadBlock( &GlobalBuf[8] );
if ( *(PUINT32)(&GlobalBuf[8]) == *(PUINT32)(&GlobalBuf[4]) ) return( USB_INT_SUCCESS );
xWriteCH376Cmd( CMD50_WRITE_VAR32 );
xWriteCH376Data( VAR_FAT_DIR_LBA );
for ( s = 8; s != 12; s ++ ) xWriteCH376Data( GlobalBuf[ s ] );
xEndCH376Cmd( );
++ *(PUINT32)(&GlobalBuf[0]);
}
}
UINT8 CH376GetLongName( PUINT8 PathName, PUINT8 LongName )
{
UINT8 s;
UINT16 NameCount;
s = CH376FileOpenPath( PathName );
if ( s != USB_INT_SUCCESS && s != ERR_OPEN_DIR ) return( s );
s = CH376DirInfoRead( );
if ( s != USB_INT_SUCCESS ) return( s );
CH376ReadBlock( GlobalBuf );
CH376EndDirInfo( );
GlobalBuf[32] = CH376CheckNameSum( GlobalBuf );
GlobalBuf[33] = CH376ReadVar8( VAR_FILE_DIR_INDEX );
NameCount = 0;
while ( 1 ) {
if ( GlobalBuf[33] == 0 ) {
s = CH376LocateInUpDir( PathName );
if ( s != USB_INT_SUCCESS ) break;
if ( CH376ReadVar32( VAR_CURRENT_OFFSET ) == 0 ) {
s = ERR_LONG_NAME_ERR;
break;
}
GlobalBuf[33] = DEF_SECTOR_SIZE / sizeof( FAT_DIR_INFO );
}
GlobalBuf[33] --;
s = CH376SendCmdDatWaitInt( CMD1H_DIR_INFO_READ, GlobalBuf[33] );
if ( s != USB_INT_SUCCESS ) break;
CH376ReadBlock( GlobalBuf );
CH376EndDirInfo( );
if ( ( GlobalBuf[11] & ATTR_LONG_NAME_MASK ) != ATTR_LONG_NAME || GlobalBuf[13] != GlobalBuf[32] ) {
s = ERR_LONG_NAME_ERR;
break;
}
for ( s = 1; s < sizeof( FAT_DIR_INFO ); s += 2 ) {
if ( s == 1 + 5 * 2 ) s = 14;
else if ( s == 14 + 6 * 2 ) s = 28;
LongName[ NameCount++ ] = GlobalBuf[ s ];
LongName[ NameCount++ ] = GlobalBuf[ s + 1 ];
if ( GlobalBuf[ s ] == 0 && GlobalBuf[ s + 1 ] == 0 ) break;
if ( NameCount >= LONG_NAME_BUF_LEN ) {
s = ERR_LONG_BUF_OVER;
goto CH376GetLongNameE;
}
}
if ( GlobalBuf[0] & 0x40 ) {
if ( s >= sizeof( FAT_DIR_INFO ) ) *(PUINT16)( &LongName[ NameCount ] ) = 0x0000;
s = USB_INT_SUCCESS;
break;
}
}
CH376GetLongNameE:
CH376FileClose( FALSE );
return( s );
}
UINT8 CH376CreateLongName( PUINT8 PathName, PUINT8 LongName )
{
UINT8 s, i;
UINT8 DirBlockCnt;
UINT16 count;
UINT16 NameCount;
UINT32 NewFileLoc;
for ( count = 0; count < LONG_NAME_BUF_LEN; count += 2 ) if ( *(PUINT16)(&LongName[count]) == 0 ) break;
if ( count == 0 || count >= LONG_NAME_BUF_LEN || count > LONE_NAME_MAX_CHAR ) return( ERR_LONG_NAME_ERR );
DirBlockCnt = count / LONG_NAME_PER_DIR;
i = count - DirBlockCnt * LONG_NAME_PER_DIR;
if ( i ) {
if ( ++ DirBlockCnt * LONG_NAME_PER_DIR > LONG_NAME_BUF_LEN ) return( ERR_LONG_BUF_OVER );
count += 2;
i += 2;
if ( i < LONG_NAME_PER_DIR ) {
while ( i++ < LONG_NAME_PER_DIR ) LongName[count++] = 0xFF;
}
}
s = CH376FileOpenPath( PathName );
if ( s == USB_INT_SUCCESS ) {
s = ERR_NAME_EXIST;
goto CH376CreateLongNameE;
}
if ( s != ERR_MISS_FILE ) return( s );
s = CH376FileCreatePath( PathName );
if ( s != USB_INT_SUCCESS ) return( s );
i = CH376ReadVar8( VAR_FILE_DIR_INDEX );
s = CH376LocateInUpDir( PathName );
if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE;
NewFileLoc = CH376ReadVar32( VAR_CURRENT_OFFSET ) + i * sizeof(FAT_DIR_INFO);
s = CH376ByteLocate( NewFileLoc );
if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE;
s = CH376ByteRead( &GlobalBuf[ sizeof(FAT_DIR_INFO) ], sizeof(FAT_DIR_INFO), NULL );
if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE;
for ( i = DirBlockCnt; i != 0; -- i ) {
s = CH376ByteRead( GlobalBuf, sizeof(FAT_DIR_INFO), &count );
if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE;
if ( count == 0 ) break;
if ( GlobalBuf[0] && GlobalBuf[0] != 0xE5 ) {
s = CH376ByteLocate( NewFileLoc );
if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE;
GlobalBuf[ 0 ] = 0xE5;
for ( s = 1; s != sizeof(FAT_DIR_INFO); s ++ ) GlobalBuf[ s ] = GlobalBuf[ sizeof(FAT_DIR_INFO) + s ];
s = CH376LongNameWrite( GlobalBuf, sizeof(FAT_DIR_INFO) );
if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE;
do {
s = CH376ByteRead( GlobalBuf, sizeof(FAT_DIR_INFO), &count );
if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE;
} while ( count && GlobalBuf[0] );
NewFileLoc = CH376ReadVar32( VAR_CURRENT_OFFSET );
i = DirBlockCnt + 1;
if ( count == 0 ) break;
NewFileLoc -= sizeof(FAT_DIR_INFO);
}
}
if ( i ) {
s = CH376ReadVar8( VAR_SEC_PER_CLUS );
if ( s == 128 ) {
s = ERR_FDT_OVER;
goto CH376CreateLongNameE;
}
count = s * DEF_SECTOR_SIZE;
if ( count < i * sizeof(FAT_DIR_INFO) ) count <<= 1;
s = CH376LongNameWrite( NULL, count );
if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE;
}
s = CH376ByteLocate( NewFileLoc );
if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE;
GlobalBuf[11] = ATTR_LONG_NAME;
GlobalBuf[12] = 0x00;
GlobalBuf[13] = CH376CheckNameSum( &GlobalBuf[ sizeof(FAT_DIR_INFO) ] );
GlobalBuf[26] = 0x00;
GlobalBuf[27] = 0x00;
for ( s = 0; DirBlockCnt != 0; ) {
GlobalBuf[0] = s ? DirBlockCnt : DirBlockCnt | 0x40;
DirBlockCnt --;
NameCount = DirBlockCnt * LONG_NAME_PER_DIR;
for ( s = 1; s < sizeof( FAT_DIR_INFO ); s += 2 ) {
if ( s == 1 + 5 * 2 ) s = 14;
else if ( s == 14 + 6 * 2 ) s = 28;
GlobalBuf[ s ] = LongName[ NameCount++ ];
GlobalBuf[ s + 1 ] = LongName[ NameCount++ ];
}
s = CH376LongNameWrite( GlobalBuf, sizeof(FAT_DIR_INFO) );
if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE;
}
s = CH376LongNameWrite( &GlobalBuf[ sizeof(FAT_DIR_INFO) ], sizeof(FAT_DIR_INFO) );
CH376CreateLongNameE:
CH376FileClose( FALSE );
return( s );
}
#endif

View File

@ -0,0 +1,124 @@
/*
* 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 k210_ch376.h
* @brief edu-riscv64 k210_ch376.h
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.10.10
* */
#ifndef __CH376_FS_H__
#define __CH376_FS_H__
#include "ch376inc.h"
#include <nuttx/config.h>
#include <sys/ioctl.h>
#include <nuttx/time.h>
#include <nuttx/fs/fs.h>
#include <nuttx/fs/ioctl.h>
#include <nuttx/arch.h>
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include <stdbool.h>
#include <debug.h>
#include <assert.h>
#include <fcntl.h>
#include <nuttx/ioexpander/gpio.h>
#include "k210_uart.h"
#define ERR_USB_UNKNOWN 0xFA
void xEndCH376Cmd( void );
void xWriteCH376Cmd( UINT8 mCmd );
void xWriteCH376Data( UINT8 mData );
UINT8 xReadCH376Data( void );
UINT8 Query376Interrupt( void );
UINT8 mInitCH376Host( void );
#define STRUCT_OFFSET( s, m ) ( (UINT8)( & ((s *)0) -> m ) )
#ifdef EN_LONG_NAME
#ifndef LONG_NAME_BUF_LEN
#define LONG_NAME_BUF_LEN ( LONG_NAME_PER_DIR * 20 )
#endif
#endif
UINT8 CH376ReadBlock( PUINT8 buf );
UINT8 CH376WriteReqBlock( PUINT8 buf );
void CH376WriteHostBlock( PUINT8 buf, UINT8 len );
void CH376WriteOfsBlock( PUINT8 buf, UINT8 ofs, UINT8 len );
void CH376SetFileName( PUINT8 name );
UINT32 CH376Read32bitDat( void );
UINT8 CH376ReadVar8( UINT8 var );
void CH376WriteVar8( UINT8 var, UINT8 dat );
UINT32 CH376ReadVar32( UINT8 var );
void CH376WriteVar32( UINT8 var, UINT32 dat );
void CH376EndDirInfo( void );
UINT32 CH376GetFileSize( void );
UINT8 CH376GetDiskStatus( void );
UINT8 CH376GetIntStatus( void );
#ifndef NO_DEFAULT_CH376_INT
UINT8 Wait376Interrupt( void );
#endif
UINT8 CH376SendCmdWaitInt( UINT8 mCmd );
UINT8 CH376SendCmdDatWaitInt( UINT8 mCmd, UINT8 mDat );
UINT8 CH376DiskReqSense( void );
UINT8 CH376DiskConnect( void );
UINT8 CH376DiskMount( void );
UINT8 CH376FileOpen( PUINT8 name );
UINT8 CH376FileCreate( PUINT8 name );
UINT8 CH376DirCreate( PUINT8 name );
UINT8 CH376SeparatePath( PUINT8 path );
UINT8 CH376FileOpenDir( PUINT8 PathName, UINT8 StopName );
UINT8 CH376FileOpenPath( PUINT8 PathName );
UINT8 CH376FileCreatePath( PUINT8 PathName );
#ifdef EN_DIR_CREATE
UINT8 CH376DirCreatePath( PUINT8 PathName );
#endif
UINT8 CH376FileErase( PUINT8 PathName );
UINT8 CH376FileClose( UINT8 UpdateSz );
UINT8 CH376DirInfoRead( void );
UINT8 CH376DirInfoSave( void );
UINT8 CH376ByteLocate( UINT32 offset );
UINT8 CH376ByteRead( PUINT8 buf, UINT16 ReqCount, PUINT16 RealCount );
UINT8 CH376ByteWrite( PUINT8 buf, UINT16 ReqCount, PUINT16 RealCount );
#ifdef EN_DISK_QUERY
UINT8 CH376DiskCapacity( PUINT32 DiskCap );
UINT8 CH376DiskQuery( PUINT32 DiskFre );
#endif
UINT8 CH376SecLocate( UINT32 offset );
#ifdef EN_SECTOR_ACCESS
UINT8 CH376DiskReadSec( PUINT8 buf, UINT32 iLbaStart, UINT8 iSectorCount );
UINT8 CH376DiskWriteSec( PUINT8 buf, UINT32 iLbaStart, UINT8 iSectorCount );
UINT8 CH376SecRead( PUINT8 buf, UINT8 ReqCount, PUINT8 RealCount );
UINT8 CH376SecWrite( PUINT8 buf, UINT8 ReqCount, PUINT8 RealCount );
#endif
#ifdef EN_LONG_NAME
UINT8 CH376LongNameWrite( PUINT8 buf, UINT16 ReqCount );
UINT8 CH376CheckNameSum( PUINT8 DirName );
UINT8 CH376LocateInUpDir( PUINT8 PathName );
UINT8 CH376GetLongName( PUINT8 PathName, PUINT8 LongName );
UINT8 CH376CreateLongName( PUINT8 PathName, PUINT8 LongName );
#endif
#endif

View File

@ -0,0 +1,180 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiOS 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 k210_gpio.c
* @brief edu-riscv64 k210_gpio.c
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.06.08
*/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <syslog.h>
#include <assert.h>
#include <debug.h>
#include <errno.h>
#include <nuttx/irq.h>
#include <arch/irq.h>
#include <nuttx/ioexpander/gpio.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#include "k210_fpioa.h"
#include "k210_gpiohs.h"
#if defined(CONFIG_DEV_GPIO) && !defined(CONFIG_GPIO_LOWER_HALF)
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Pin 1 and 2 are used for this example as GPIO outputs. */
/****************************************************************************
* Private Types
****************************************************************************/
struct k210gpio_dev_s
{
struct gpio_dev_s gpio;
uint8_t id;
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
#if BOARD_NGPIOOUT > 0
static int gpout_read(FAR struct gpio_dev_s *dev, FAR bool *value);
static int gpout_write(FAR struct gpio_dev_s *dev, bool value);
#endif
/****************************************************************************
* Private Data
****************************************************************************/
#if BOARD_NGPIOOUT > 0
static const struct gpio_operations_s gpout_ops =
{
.go_read = gpout_read,
.go_write = gpout_write,
.go_attach = NULL,
.go_enable = NULL,
};
/* This array maps the GPIO pins used as OUTPUT */
static const uint32_t g_gpiooutputs[BOARD_NGPIOOUT] =
{
GPIO_E220_M0,
GPIO_E220_M1,
GPIO_E18_MODE
};
static const uint32_t g_fpioa[BOARD_NGPIOOUT] =
{
FPIOA_E220_M0,
FPIOA_E220_M1,
FPIOA_E18_MODE
};
static struct k210gpio_dev_s g_gpout[BOARD_NGPIOOUT];
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: gpout_read
****************************************************************************/
#if BOARD_NGPIOOUT > 0
static int gpout_read(FAR struct gpio_dev_s *dev, FAR bool *value)
{
FAR struct k210gpio_dev_s *k210gpio =
(FAR struct k210gpio_dev_s *)dev;
DEBUGASSERT(k210gpio != NULL && value != NULL);
DEBUGASSERT(k210gpio->id < BOARD_NGPIOOUT);
gpioinfo("Reading...\n");
*value = (int) k210_gpiohs_get_value(g_fpioa[k210gpio->id]);
return OK;
}
/****************************************************************************
* Name: gpout_write
****************************************************************************/
static int gpout_write(FAR struct gpio_dev_s *dev, bool value)
{
FAR struct k210gpio_dev_s *k210gpio =
(FAR struct k210gpio_dev_s *)dev;
DEBUGASSERT(k210gpio != NULL);
DEBUGASSERT(k210gpio->id < BOARD_NGPIOOUT);
gpioinfo("Writing %d\n", (int)value);
k210_gpiohs_set_value(g_fpioa[k210gpio->id], value);
return OK;
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: k210_gpio_init
****************************************************************************/
int k210_gpio_init(void)
{
int i;
int pincount = 0;
#if BOARD_NGPIOOUT > 0
for (i = 0; i < BOARD_NGPIOOUT; i++)
{
/* Setup and register the GPIO pin */
g_gpout[i].gpio.gp_pintype = GPIO_OUTPUT_PIN;
g_gpout[i].gpio.gp_ops = &gpout_ops;
g_gpout[i].id = i;
gpio_pin_register(&g_gpout[i].gpio, pincount);
/* Configure the pins that will be used as output */
k210_fpioa_config(g_gpiooutputs[i],
(K210_IO_FUNC_GPIOHS0 + g_fpioa[i]) | K210_IOFLAG_GPIOHS);
k210_gpiohs_set_direction(g_fpioa[i], GPIO_DM_OUTPUT);
k210_gpiohs_set_value(g_fpioa[i], false);
pincount++;
}
#endif
return OK;
}
#endif /* CONFIG_DEV_GPIO && !CONFIG_GPIO_LOWER_HALF */

View File

@ -0,0 +1,353 @@
/*
* Copyright (c) 2022 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 k210_lcd.c
* @brief LCD relative driver
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.7.21
*/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include "k210_fpioa.h"
#include "k210_gpiohs.h"
#include "nuttx/arch.h"
#include "nuttx/lcd/lt768.h"
#include "nuttx/lcd/lt768_lib.h"
#include "nuttx/lcd/if_port.h"
#include "nuttx/lcd/lt768_learn.h"
#include <nuttx/board.h>
#include <arch/board/board.h>
#include <nuttx/fs/fs.h>
#include <nuttx/fs/ioctl.h>
#ifdef CONFIG_LCD_LCDDRV_SPIIF
#include "nuttx/lcd/lcddrv_spiif.h"
#endif
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
#define NCS_H() k210_gpiohs_set_value(FPIOA_LCD_NCS, GPIO_PV_HIGH); up_udelay(20)
#define NCS_L() k210_gpiohs_set_value(FPIOA_LCD_NCS, GPIO_PV_LOW); up_udelay(20)
#define CLK_H() k210_gpiohs_set_value(FPIOA_LCD_SCLK, GPIO_PV_HIGH); up_udelay(20)
#define CLK_L() k210_gpiohs_set_value(FPIOA_LCD_SCLK, GPIO_PV_LOW); up_udelay(20)
#define MOSI_H() k210_gpiohs_set_value(FPIOA_LCD_MOSI, GPIO_PV_HIGH)
#define MOSI_L() k210_gpiohs_set_value(FPIOA_LCD_MOSI, GPIO_PV_LOW)
static int lcd_open(FAR struct file *filep);
static int lcd_close(FAR struct file *filep);
static ssize_t lcd_read(FAR struct file *filep, FAR char *buffer, size_t buflen);
static ssize_t lcd_write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
/****************************************************************************
* Private Data
****************************************************************************/
/* LCD POSIX interface */
static const struct file_operations g_lcdfops =
{
lcd_open,
lcd_close,
lcd_read,
lcd_write,
NULL,
NULL,
NULL
};
/****************************************************************************
* Public Functions
****************************************************************************/
void lcd_pin_init(void)
{
k210_fpioa_config(BSP_LCD_NRST, HS_GPIO(FPIOA_LCD_NRST) | K210_IOFLAG_GPIOHS);
k210_fpioa_config(BSP_LCD_SCLK, HS_GPIO(FPIOA_LCD_SCLK) | K210_IOFLAG_GPIOHS);
k210_fpioa_config(BSP_LCD_MOSI, HS_GPIO(FPIOA_LCD_MOSI) | K210_IOFLAG_GPIOHS);
k210_fpioa_config(BSP_LCD_MISO, HS_GPIO(FPIOA_LCD_MISO) | K210_IOFLAG_GPIOHS);
k210_fpioa_config(BSP_LCD_NCS, HS_GPIO(FPIOA_LCD_NCS) | K210_IOFLAG_GPIOHS);
k210_gpiohs_set_direction(FPIOA_LCD_MISO, GPIO_DM_INPUT);
k210_gpiohs_set_direction(FPIOA_LCD_NRST, GPIO_DM_OUTPUT);
k210_gpiohs_set_direction(FPIOA_LCD_SCLK, GPIO_DM_OUTPUT);
k210_gpiohs_set_direction(FPIOA_LCD_MOSI, GPIO_DM_OUTPUT);
k210_gpiohs_set_direction(FPIOA_LCD_NCS, GPIO_DM_OUTPUT);
k210_gpiohs_set_value(FPIOA_LCD_SCLK, GPIO_PV_HIGH);
k210_gpiohs_set_value(FPIOA_LCD_NCS, GPIO_PV_HIGH);
k210_gpiohs_set_value(FPIOA_LCD_NRST, GPIO_PV_HIGH);
}
void lcd_backlight_init(bool enable)
{
k210_fpioa_config(BSP_LCD_BL_PIN, HS_GPIO(FPIOA_LCD_BL) | K210_IOFLAG_GPIOHS);
k210_gpiohs_set_direction(FPIOA_LCD_BL, GPIO_DM_OUTPUT);
k210_gpiohs_set_value(FPIOA_LCD_BL, enable);
}
#ifdef CONFIG_LCD_LCDDRV_SPIIF
int spiif_backlight(FAR struct lcddrv_lcd_s *lcd, int level)
{
lcd_backlight_init(true);
return 1;
}
#endif
uint8_t lcd_transfer_byte(uint8_t dat)
{
uint8_t i, rx_data = 0;
for(i = 0; i < 8; i++)
{
CLK_H();
// MOSI during falling edge
if((dat << i) & 0x80)
{
MOSI_H();
}
else
{
MOSI_L();
}
CLK_L();
// MISO during rising edge
rx_data <<= 1;
if(k210_gpiohs_get_value(FPIOA_LCD_MISO))
rx_data ++;
}
CLK_H();
return rx_data;
}
void LCD_CmdWrite(uint8_t cmd)
{
NCS_L();
lcd_transfer_byte(0x00);
lcd_transfer_byte(cmd);
NCS_H();
}
void LCD_DataWrite(uint8_t data)
{
NCS_L();
lcd_transfer_byte(0x80);
lcd_transfer_byte(data);
NCS_H();
}
void LCD_DataWrite_Pixel(uint8_t data)
{
NCS_L();
lcd_transfer_byte(0x80);
lcd_transfer_byte(data);
NCS_H();
NCS_L();
lcd_transfer_byte(0x80);
lcd_transfer_byte(data >> 8);
NCS_H();
}
uint8_t LCD_StatusRead(void)
{
uint8_t temp = 0;
NCS_L();
lcd_transfer_byte(0x40);
temp = lcd_transfer_byte(0xff);
NCS_H();
return temp;
}
uint8_t LCD_DataRead(void)
{
uint8_t temp = 0;
NCS_L();
lcd_transfer_byte(0xc0);
temp = lcd_transfer_byte(0xff);
NCS_H();
return temp;
}
/*****************************************************************************/
void lcd_drv_init(void)
{
uint8_t PwmControl = 100;
lcd_pin_init();
lt768_init();
Select_SFI_Dual_Mode0();
// PWM1 enable backlight
LT768_PWM1_Init(1, 0, 200, 100, PwmControl);
// enable RGB output
Display_ON();
Main_Image_Start_Address(LCD_START_ADDR);
Main_Image_Width(LCD_XSIZE_TFT);
Main_Window_Start_XY(0, 0);
Canvas_Image_Start_address(LCD_START_ADDR);
Canvas_image_width(LCD_XSIZE_TFT);
Active_Window_XY(0, 0);
Active_Window_WH(LCD_XSIZE_TFT, LCD_YSIZE_TFT);
up_mdelay(10);
Canvas_Image_Start_address(LCD_START_ADDR);
//fill blue background
LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE);
}
/****************************************************************************
* Name: k210_backlight
*
* Description:
* If CONFIG_K210_LCD_BACKLIGHT is defined, then the board-specific
* logic must provide this interface to turn the backlight on and off.
*
****************************************************************************/
#ifdef CONFIG_K210_LCD_BACKLIGHT
void k210_backlight(bool blon)
{
lcd_backlight_init(blon);
}
#endif
/****************************************************************************
* Name: lcd_open
****************************************************************************/
static int lcd_open(FAR struct file *filep)
{
return OK;
}
/****************************************************************************
* Name: lcd_close
****************************************************************************/
static int lcd_close(FAR struct file *filep)
{
return OK;
}
/****************************************************************************
* Name: lcd_read
****************************************************************************/
static ssize_t lcd_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
{
return OK;
}
/****************************************************************************
* Name: ch438_write
****************************************************************************/
static ssize_t lcd_write(FAR struct file *filep, FAR const char *buffer, size_t buflen)
{
ssize_t ret = buflen;
if (buffer == NULL)
{
return -ERROR;
}
LcdWriteParam * show = (LcdWriteParam *)buffer;
/* output string */
switch (show->type)
{
/* output string */
case SHOW_STRING:
LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE);
LT768_Select_Internal_Font_Init(show->string_info.height, 1, 1, 1, 1);
LT768_Print_Internal_Font_String(show->string_info.x_pos, show->string_info.y_pos, show->string_info.font_color,show->string_info.back_color,show->string_info.addr);
break;
/* output dot */
case SHOW_WDOT:
LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE);
LT768_DrawSquare_Fill(show->pixel_info.x_startpos,show->pixel_info.y_startpos, show->pixel_info.x_endpos, show->pixel_info.y_endpos, *(uint32_t *)(show->pixel_info.pixel_color));
break;
/* output rgb */
case SHOW_RGB:
LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE);
Display_RGB();
break;
/* output pip */
case SHOW_PIP:
LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE);
Display_PIP();
break;
/* output Internal Font */
case SHOW_INTERNAL_FONT:
LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE);
Display_Internal_Font();
break;
/* output Outside Font */
case SHOW_OUTSIDE_FONT:
LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE);
Display_Outside_Font();
break;
/* output Triangle */
case SHOW_TRIANGLE:
LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE);
Display_Triangle();
break;
/* output picture */
case SHOW_PICTURE:
LT768_DrawSquare_Fill(0, 0, LCD_XSIZE_TFT, LCD_YSIZE_TFT, WHITE);
Display_Picture();
break;
default:
ret = -ERROR;
break;
}
return ret;
}
/****************************************************************************
* Name: k210_lcd_initialize
*
* Description:
* Initialize the LCD. Setup backlight (initially off)
*
****************************************************************************/
int board_lcd_initialize(void)
{
/* Configure the LCD backlight (and turn the backlight off) */
lcd_backlight_init(true);
lcd_drv_init();
up_mdelay(10);
Main_Image_Start_Address(LCD_START_ADDR);
Main_Image_Width(LCD_XSIZE_TFT);
Main_Window_Start_XY(0, 0);
Canvas_Image_Start_address(LCD_START_ADDR);
Canvas_image_width(LCD_XSIZE_TFT);
Active_Window_XY(0, 0);
Active_Window_WH(LCD_XSIZE_TFT, LCD_YSIZE_TFT);
up_mdelay(10);
Canvas_Image_Start_address(LCD_START_ADDR);
/* register device */
register_driver("/dev/lcd_dev", &g_lcdfops, 0666, NULL);
return OK;
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiOS 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 k210_leds.c
* @brief edu-riscv64 k210_leds.c
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.06.08
*/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#include "k210_fpioa.h"
#include "k210_gpiohs.h"
/****************************************************************************
* Public Functions
****************************************************************************/
void board_autoled_initialize(void)
{
}
void board_autoled_on(int led)
{
}
void board_autoled_off(int led)
{
}

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiOS 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 k210_reset.c
* @brief k210_reset.c support reboot
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.06.27
*/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/board.h>
#include <nuttx/arch.h>
#ifdef CONFIG_BOARDCTL_RESET
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: board_reset
*
* Description:
* Reset board. Support for this function is required by board-level
* logic if CONFIG_BOARDCTL_RESET is selected.
*
* Input Parameters:
* status - Status information provided with the reset event. This
* meaning of this status information is board-specific. If not
* used by a board, the value zero may be provided in calls to
* board_reset().
*
* Returned Value:
* If this function returns, then it was not possible to power-off the
* board due to some constraints. The return value int this case is a
* board-specific reason for the failure to shutdown.
*
****************************************************************************/
int board_reset(int status)
{
up_systemreset();
return 0;
}
#endif /* CONFIG_BOARDCTL_RESET */

View File

@ -0,0 +1,475 @@
/*
* Copyright (c) 2022 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 k210_touch.c
* @brief gt911 touch driver
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.10.25
*/
/****************************************************************************
* Included Files
****************************************************************************/
#include "k210_touch.h"
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
static void IIC_Init(void);
static void SDA_IN(void);
static void SDA_OUT(void);
static uint8_t READ_SDA(void);
static void IIC_SCL(uint8_t val);
static void IIC_SDA(uint8_t val);
static void IIC_Start(void);
static void IIC_Stop(void);
static uint8_t IIC_Wait_Ack(void);
static void IIC_Ack(void);
static void IIC_NAck(void);
static void IIC_Send_Byte(uint8_t txd);
static uint8_t IIC_Read_Byte(uint8_t ack);
static bool GT911_Scan(POINT* point);
static int touch_open(FAR struct file *filep);
static int touch_close(FAR struct file *filep);
static ssize_t touch_read(FAR struct file *filep, FAR char *buffer, size_t buflen);
static ssize_t touch_write(FAR struct file *filep, FAR const char *buffer, size_t buflen);
/****************************************************************************
* Private Data
****************************************************************************/
/* touch POSIX interface */
static const struct file_operations g_touchfops =
{
touch_open,
touch_close,
touch_read,
touch_write,
NULL,
NULL,
NULL
};
/****************************************************************************
* Name: IIC_Init
* Description: i2c pin mode configure
* input: None
* output: None
* return:none
****************************************************************************/
static void IIC_Init(void)
{
/* config simluate IIC bus */
k210_fpioa_config(BSP_IIC_SDA, GT911_FUNC_GPIO(FPIOA_IIC_SDA));
k210_fpioa_config(BSP_IIC_SCL, GT911_FUNC_GPIO(FPIOA_IIC_SCL));
k210_gpiohs_set_direction(FPIOA_IIC_SDA, GPIO_DM_OUTPUT);
k210_gpiohs_set_direction(FPIOA_IIC_SCL, GPIO_DM_OUTPUT);
}
/****************************************************************************
* Name: SDA_IN
* Description: set sda input mode
* input: None
* output: None
* return:none
****************************************************************************/
static void SDA_IN(void)
{
k210_gpiohs_set_direction(FPIOA_IIC_SDA, GPIO_DM_INPUT_PULL_UP);
}
/****************************************************************************
* Name: SDA_OUT
* Description: set sda output mode
* input: None
* output: None
* return:none
****************************************************************************/
static void SDA_OUT(void)
{
k210_gpiohs_set_direction(FPIOA_IIC_SDA, GPIO_DM_OUTPUT);
}
/****************************************************************************
* Name: READ_SDA
* Description: read sda value
* input: None
* output: None
* return: sda pin value
****************************************************************************/
static uint8_t READ_SDA(void)
{
return k210_gpiohs_get_value(FPIOA_IIC_SDA);
}
/****************************************************************************
* Name: IIC_SCL
* Description: set the value of scl
* input: val:the value to be set
* output: None
* return: None
****************************************************************************/
static void IIC_SCL(uint8_t val)
{
if (val)
k210_gpiohs_set_value(FPIOA_IIC_SCL,GPIO_PV_HIGH);
else
{
k210_gpiohs_set_value(FPIOA_IIC_SCL,GPIO_PV_LOW);
}
}
/****************************************************************************
* Name: IIC_SDA
* Description: set the value of sda
* input: val:the value to be set
* output: None
* return: None
****************************************************************************/
static void IIC_SDA(uint8_t val)
{
if (val)
k210_gpiohs_set_value(FPIOA_IIC_SDA,GPIO_PV_HIGH);
else
{
k210_gpiohs_set_value(FPIOA_IIC_SDA,GPIO_PV_LOW);
}
}
/****************************************************************************
* Name: IIC_Start
* Description: Generate i2c start signal
* input: None
* output: None
* return: None
****************************************************************************/
static void IIC_Start(void)
{
SDA_OUT();
IIC_SDA(1);
IIC_SCL(1);
up_mdelay(30);
IIC_SDA(0);
up_mdelay(2);
IIC_SCL(0);
}
/****************************************************************************
* Name: IIC_Start
* Description: Generate i2c stop signal
* input: None
* output: None
* return: None
****************************************************************************/
static void IIC_Stop(void)
{
SDA_OUT();
IIC_SCL(1);
up_mdelay(30);
IIC_SDA(0);
up_mdelay(2);
IIC_SDA(1);
}
/*******************************************************************************************
* Name: IIC_Wait_Ack
* Description: Wait for the reply signal to arrive
* input: None
* output: None
* return: Return value: 1:failed to receive response,0:the received response is successful.
********************************************************************************************/
static uint8_t IIC_Wait_Ack(void)
{
uint16_t ucErrTime=0;
SDA_IN();
IIC_SDA(1);
IIC_SCL(1);
up_mdelay(2);
while(READ_SDA())
{
ucErrTime++;
if(ucErrTime>2500)
{
IIC_Stop();
return 1;
}
up_mdelay(2);
}
IIC_SCL(0);
return 0;
}
/****************************************************************************
* Name: IIC_Ack
* Description: generate ack response
* input: None
* output: None
* return: None
****************************************************************************/
static void IIC_Ack(void)
{
IIC_SCL(0);
SDA_OUT();
up_mdelay(2);
IIC_SDA(0);
up_mdelay(2);
IIC_SCL(1);
up_mdelay(2);
IIC_SCL(0);
}
/****************************************************************************
* Name: IIC_NAck
* Description: No ACK response is generated
* input: None
* output: None
* return: None
****************************************************************************/
static void IIC_NAck(void)
{
IIC_SCL(0);
SDA_OUT();
up_mdelay(2);
IIC_SDA(1);
up_mdelay(2);
IIC_SCL(1);
up_mdelay(2);
IIC_SCL(0);
}
/****************************************************************************
* Name: IIC_Send_Byte
* Description: IIC sends a byte,Return whether the slave has a response
* input: None
* output: None
* return: 1:there is a response,0:no response
****************************************************************************/
static void IIC_Send_Byte(uint8_t txd)
{
uint8_t t;
SDA_OUT();
IIC_SCL(0);
up_mdelay(2);
for(t=0;t<8;t++)
{
IIC_SDA((txd&0x80)>>7);
txd<<=1;
IIC_SCL(1);
up_mdelay(2);
IIC_SCL(0);
up_mdelay(2);
}
}
/****************************************************************************
* Name: IIC_Read_Byte
* Description: Read 1 byte, when ack=1, send ACK, when ack=0, send nACK
* input: None
* output: None
* return: Returns one byte of data read
****************************************************************************/
static uint8_t IIC_Read_Byte(uint8_t ack)
{
uint8_t i,receive=0;
SDA_IN();
up_mdelay(30);
for(i=0;i<8;i++ )
{
IIC_SCL(0);
up_mdelay(2);
IIC_SCL(1);
up_udelay(1);
receive<<=1;
if(READ_SDA())receive++;
up_udelay(1);
}
if (!ack)
IIC_NAck();
else
IIC_Ack();
return receive;
}
/***********************************************************************************
* Name: GT911_WR_Reg
* Description: Write data to GT911 once
* input: reg: start register address,buf: data cache area,len: write data length
* output: None
* return: Return value: 0, success; 1, failure.
***********************************************************************************/
static uint8_t GT911_WR_Reg(uint16_t reg,uint8_t *buf,uint8_t len)
{
uint8_t i;
uint8_t ret=0;
IIC_Start();
IIC_Send_Byte(CT_CMD_WR);
IIC_Wait_Ack();
IIC_Send_Byte(reg>>8);
IIC_Wait_Ack();
IIC_Send_Byte(reg&0XFF);
IIC_Wait_Ack();
for(i=0;i<len;i++)
{
IIC_Send_Byte(buf[i]);
ret=IIC_Wait_Ack();
if(ret)break;
}
IIC_Stop();
return ret;
}
/***********************************************************************************
* Name: GT911_RD_Reg
* Description: Read data from GT911 once
* input: reg: start register address,buf: data cache area,len: read data length
* output: None
* return: None
***********************************************************************************/
static void GT911_RD_Reg(uint16_t reg,uint8_t *buf,uint8_t len)
{
uint8_t i;
IIC_Start();
IIC_Send_Byte(CT_CMD_WR);
IIC_Wait_Ack();
IIC_Send_Byte(reg>>8);
IIC_Wait_Ack();
IIC_Send_Byte(reg&0XFF);
IIC_Wait_Ack();
IIC_Stop();
IIC_Start();
IIC_Send_Byte(CT_CMD_RD);
IIC_Wait_Ack();
for(i=0;i<len;i++)
{
buf[i]=IIC_Read_Byte(i==(len-1)?0:1);
}
IIC_Stop();
}
/***********************************************************************************
* Name: GT911_Scan
* Description: point:structure to store coordinates
* input: None
* output: None
* return: Returns true for touch, false for no touch
***********************************************************************************/
static bool GT911_Scan(POINT* point)
{
GT911_Dev Dev_Now;
uint8_t Clearbuf = 0;
uint8_t buf[41];
GT911_RD_Reg(GT911_READ_XY_REG, buf, 1);
if ((buf[0]&0x80) == 0x00)
{
GT911_WR_Reg(GT911_READ_XY_REG, (uint8_t *)&Clearbuf, 1);
return false;
}
else
{
Dev_Now.TouchCount = buf[0] & 0x0f;
if((Dev_Now.TouchCount > 5) || (Dev_Now.TouchCount == 0) )
{
GT911_WR_Reg(GT911_READ_XY_REG, (uint8_t *)&Clearbuf, 1);
return false;
}
GT911_RD_Reg(GT911_READ_XY_REG + 1, &buf[1], Dev_Now.TouchCount*8);
GT911_WR_Reg(GT911_READ_XY_REG, (uint8_t *)&Clearbuf, 1);
for (uint8_t i = 0;i < Dev_Now.TouchCount; i++)
{
Dev_Now.Touchkeytrackid[i] = buf[1+(8*i)];
Dev_Now.X[i] = ((uint16_t)buf[3+(8*i)] << 8) + buf[2+(8*i)];
Dev_Now.Y[i] = ((uint16_t)buf[5+(8*i)] << 8) + buf[4+(8*i)];
Dev_Now.S[i] = ((uint16_t)buf[7+(8*i)] << 8) + buf[6+(8*i)];
if(Dev_Now.Y[i] < 20) Dev_Now.Y[i] = 20;
if(Dev_Now.Y[i] > GT911_MAX_HEIGHT -20) Dev_Now.Y[i]=GT911_MAX_HEIGHT - 20;
if(Dev_Now.X[i] < 20) Dev_Now.X[i] = 20;
if(Dev_Now.X[i] > GT911_MAX_WIDTH-20) Dev_Now.X[i] = GT911_MAX_WIDTH - 20;
point->x = Dev_Now.X[i];
point->y = Dev_Now.Y[i];
}
}
return true;
}
/****************************************************************************
* Name: touch_open
****************************************************************************/
static int touch_open(FAR struct file *filep)
{
return OK;
}
/****************************************************************************
* Name: touch_close
****************************************************************************/
static int touch_close(FAR struct file *filep)
{
return OK;
}
/****************************************************************************
* Name: lcd_read
****************************************************************************/
static ssize_t touch_read(FAR struct file *filep, FAR char *buffer, size_t buflen)
{
int ret = -ERROR;
POINT touch_point = {0, 0, 0};
if (buffer == NULL)
{
return -ERROR;
}
POINT* data = (POINT*)buffer;
while(1)
{
if(GT911_Scan(&touch_point))
{
data->x = touch_point.x;
data->y = touch_point.y;
ret = buflen;
break;
}
}
return ret;
}
/****************************************************************************
* Name: lcd_read
****************************************************************************/
static ssize_t touch_write(FAR struct file *filep, FAR const char *buffer, size_t buflen)
{
return OK;
}
/***********************************************************************************
* Name: board_touch_initialize
* Description: touch initialize
* input: None
* output: None
* return: None
***********************************************************************************/
void board_touch_initialize(void)
{
IIC_Init();
/* register device */
register_driver("/dev/touch_dev", &g_touchfops, 0666, NULL);
}

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2022 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 k210_touch.h
* @brief gt911 touch driver
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.10.25
*/
#ifndef _K210_TOUCH_H_
#define _K210_TOUCH_H_
#include <nuttx/config.h>
#include <nuttx/kmalloc.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#include <nuttx/time.h>
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <debug.h>
#include <assert.h>
#include <nuttx/time.h>
#include <nuttx/fs/fs.h>
#include "k210_config.h"
#include "k210_fpioa.h"
#include "k210_gpiohs.h"
#include "nuttx/arch.h"
#include "k210_gpio_common.h"
#define GT911_FUNC_GPIO(n) ((K210_IO_FUNC_GPIOHS0 + n) | K210_IOFLAG_GPIOHS)
#define GT911_MAX_WIDTH (uint16_t)800
#define GT911_MAX_HEIGHT (uint16_t)480
#define CT_CMD_WR (uint8_t)0XBA
#define CT_CMD_RD (uint8_t)0XBB
#define CT_MAX_TOUCH (uint8_t)5
#define GT911_COMMAND_REG (uint16_t)0x8040
#define GT911_CONFIG_REG (uint16_t)0x8047
#define GT911_PRODUCT_ID_REG (uint16_t)0x8140
#define GT911_FIRMWARE_VERSION_REG (uint16_t)0x8144
#define GT911_READ_XY_REG (uint16_t)0x814E
typedef struct
{
uint8_t TouchCount;
uint8_t Touchkeytrackid[CT_MAX_TOUCH];
uint16_t X[CT_MAX_TOUCH];
uint16_t Y[CT_MAX_TOUCH];
uint16_t S[CT_MAX_TOUCH];
}GT911_Dev;
typedef struct
{
uint16_t x;
uint16_t y;
uint16_t press;
}POINT;
void board_touch_initialize(void);
#endif

View File

@ -0,0 +1,840 @@
/*
* Copyright (c) 2022 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 k210_w5500.c
* @brief w5500 driver based on simulated SPI
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-9-14
*/
#include "nuttx/arch.h"
#include "k210_w5500.h"
#include "k210_gpio_common.h"
/****************************************************************************
* Private Data
****************************************************************************/
w5500_param_t w5500_param;
static uint8_t rx_buf[256];
static uint8_t tx_buf[256];
static uint8_t config_ip_addr[] = {10, 0, 30, 50};
static uint8_t config_ip_mask[] = {255, 255, 255, 0};
static uint8_t config_gw_addr[] = {10, 0, 30, 1};
static uint8_t config_mac_addr[] = {0x0C, 0x29, 0xAB, 0x7C, 0x00, 0x01};
static uint8_t config_dst_ip[] = {10, 0, 30, 57};
static uint16_t config_local_port = 5000;
static uint16_t config_dst_port = 6000;
static uint8_t config_mode = SOCK_TCP_CLI;
/****************************************************************************
* Name: spi_read_byte
* Description: Read one byte spi data returned
* input: None
* output: None
* return:Read register data
****************************************************************************/
static uint8_t spi_read_byte(void)
{
uint8_t i, dat = 0;
SCLK_L();
for(i = 0; i < 8; i++)
{
SCLK_H();
dat <<= 1;
dat |= k210_gpiohs_get_value(FPIOA_ENET_MISO);
up_udelay(1);
SCLK_L();
}
return dat;
}
/****************************************************************************
* Name: spi_write_byte
* Description: send 1 byte to spi
* input: data
* output: None
* return: None
****************************************************************************/
static void spi_write_byte(uint8_t dat)
{
uint8_t i;
for(i = 0; i < 8; i++)
{
SCLK_L();
if((dat << i) & 0x80)
{
MOSI_H();
}
else
{
MOSI_L();
}
SCLK_H();
}
SCLK_L();
}
/****************************************************************************
* Name: spi_write_short
* Description: send 2 bytes to spi
* input: data
* output: None
* return: None
****************************************************************************/
static void spi_write_short(uint16_t dat)
{
spi_write_byte((uint8_t)(dat / 256));
spi_write_byte(dat);
}
/****************************************************************************
* Name: w5500_write_byte
*Description: Write 1 byte data to the specified address register through SPI
*Input: reg: 16 bit register address, dat: data to be written
* output: None
* return: None
****************************************************************************/
static void w5500_write_byte(uint16_t reg, uint8_t dat)
{
NCS_L();
spi_write_short(reg);
spi_write_byte(FDM1 | RWB_WRITE | COMMON_R);
spi_write_byte(dat);
NCS_H();
}
/****************************************************************************
* Name: w5500_write_short
* Description: Write 2 bytes data to the specified address register through SPI
* Input: reg: 16 bit register address, dat: data to be written
* output: None
* return: None
****************************************************************************/
static void w5500_write_short(uint16_t reg, uint16_t dat)
{
NCS_L();
spi_write_short(reg);
spi_write_byte(FDM2 | RWB_WRITE | COMMON_R);
spi_write_short(dat);
NCS_H();
}
/****************************************************************************
* Name: w5500_write_bytes
* Description: Write n bytes data to the specified address register through SPI
* Input: reg: 16 bit register address, dat: data to be written,size:Length of data to be written
* output: None
* return: None
****************************************************************************/
static void w5500_write_bytes(uint16_t reg, uint8_t *dat, uint16_t size)
{
uint16_t i;
NCS_L();
spi_write_short(reg);
spi_write_byte(VDM | RWB_WRITE | COMMON_R);
for(i = 0; i < size; i++)
{
spi_write_byte(*dat++);
}
NCS_H();
}
/****************************************************************************
* Name: w5500_write_sock_byte
* Description: Write 1 byte data to the specified port register through SPI
* Input: sock: port number, reg: 16 bit register address, dat: data to be written
* Output: None
* return: None
****************************************************************************/
void w5500_write_sock_byte(socket_t sock, uint16_t reg, uint8_t dat)
{
NCS_L();
spi_write_short(reg);
spi_write_byte(FDM1 | RWB_WRITE | (sock * 0x20 + 0x08));
spi_write_byte(dat);
NCS_H();
}
/****************************************************************************
* Name: w5500_write_sock_short
* Description: Write 2 bytes data to the specified port register through SPI
* Input: sock: port number, reg: 16 bit register address, dat: data to be written
* Output: None
* return: None
****************************************************************************/
void w5500_write_sock_short(socket_t sock, uint16_t reg, uint16_t dat)
{
NCS_L();
spi_write_short(reg);
spi_write_byte(FDM2 | RWB_WRITE | (sock * 0x20 + 0x08));
spi_write_short(dat);
NCS_H();
}
/****************************************************************************
* Name: w5500_write_sock_long
* Description: Write 4 bytes data to the specified port register through SPI
* Input: sock: port number, reg: 16 bit register address, dat: 4 byte buffer pointers to be written
* Output: None
* return: None
****************************************************************************/
void w5500_write_sock_long(socket_t sock, uint16_t reg, uint8_t *dat)
{
NCS_L();
spi_write_short(reg);
spi_write_byte(FDM4 | RWB_WRITE | (sock * 0x20 + 0x08));
spi_write_byte(*dat++);
spi_write_byte(*dat++);
spi_write_byte(*dat++);
spi_write_byte(*dat++);
NCS_H();
}
/*******************************************************************************
*Function name: w5500_read_byte
*Description: Read 1 byte data of W5500 specified address register
*Input: reg: 16 bit register address
*Output: None
*Return : 1 byte data read from the register
*******************************************************************************/
uint8_t w5500_read_byte(uint16_t reg)
{
uint8_t val;
NCS_L();
spi_write_short(reg);
spi_write_byte(FDM1 | RWB_READ | COMMON_R);
val = spi_read_byte();
NCS_H();
return val;
}
/*******************************************************************************
*Function name: w5500_read_sock_byte
*Description: Read 1 byte data of W5500 specified port register
*Input: sock: port number, reg: 16 bit register address
*Output: None
*Return: 1 byte data read from the register
*Description: None
*******************************************************************************/
uint8_t w5500_read_sock_byte(socket_t sock, uint16_t reg)
{
uint8_t val;
NCS_L();
spi_write_short(reg);
spi_write_byte(FDM1 | RWB_READ | (sock * 0x20 + 0x08));
val = spi_read_byte();
NCS_H();
return val;
}
/*******************************************************************************
*Function name: w5500_read_sock_short
*Description: Read 2 bytes of W5500 specified port register
*Input: sock: port number, reg: 16 bit register address
*Output: None
*Return: read 2 bytes of data from the register (16 bits)
*******************************************************************************/
uint16_t w5500_read_sock_short(socket_t sock, uint16_t reg)
{
uint16_t val;
NCS_L();
spi_write_short(reg);
spi_write_byte(FDM2 | RWB_READ |(sock * 0x20 + 0x08));
val = spi_read_byte();
val *= 256;
val |= spi_read_byte();
NCS_H();
return val;
}
/*******************************************************************************
*Function name: w5500_read_sock_bytes
*Description: Read data from W5500 receive data buffer
*Input: sock: port number, * dat: data saving buffer pointer
*Output: None
*Return: read data length
*******************************************************************************/
uint16_t w5500_read_sock_bytes(socket_t sock, uint8_t *dat)
{
uint16_t recv_size, write_addr;
uint16_t recv_addr;
uint16_t i;
uint8_t val;
recv_size = w5500_read_sock_short(sock, W5500_SN_RX_RSR_REG);
/* no receive data */
if(recv_size == 0)
{
return 0;
}
if(recv_size > W5500_MAX_PACK_SIZE)
{
recv_size = W5500_MAX_PACK_SIZE;
}
recv_addr = w5500_read_sock_short(sock, W5500_SN_RX_RD_REG);
write_addr = recv_addr;
/* calculate physical address */
recv_addr &= (SOCK_RECV_SIZE - 1);
NCS_L();
spi_write_short(recv_addr);
spi_write_byte(VDM | RWB_READ | (sock * 0x20 + 0x18));
if((recv_addr + recv_size) < SOCK_RECV_SIZE)
{
for(i = 0; i < recv_size; i++)
{
val = spi_read_byte();
*dat = val;
dat++;
}
}
else
{
recv_addr = SOCK_RECV_SIZE - recv_addr;
for(i = 0; i < recv_addr; i++)
{
val = spi_read_byte();
*dat = val;
dat++;
}
NCS_H();
NCS_L();
spi_write_short(0x00);
spi_write_byte(VDM | RWB_READ | (sock * 0x20 + 0x18));
for(; i < recv_size; i++)
{
val= spi_read_byte();
*dat = val;
dat++;
}
}
NCS_H();
write_addr += recv_size;
w5500_write_sock_short(sock, W5500_SN_RX_RD_REG, write_addr);
/* start receive */
w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_RECV);
return recv_size;
}
/*******************************************************************************
*Function name: w5500_write_sock_bytes
*Description: Write data to the data sending buffer of W5500
*Input: sock: port number, dat: data storage buffer pointer, size: length of data to be written
*Output: None
*Return: None
*******************************************************************************/
void w5500_write_sock_bytes(socket_t sock, uint8_t *dat, uint16_t size)
{
uint16_t recv_addr, write_addr;
uint16_t i;
/* if udp mode, set ip and port */
if(w5500_read_sock_byte(sock, W5500_SN_MR_REG) != SOCK_UDP)
{
w5500_write_sock_long(sock, W5500_SN_DIPR_REG, w5500_param.udp_ip);
w5500_write_sock_short(sock, W5500_SN_DPORTR_REG, w5500_param.udp_port);
}
recv_addr = w5500_read_sock_short(sock, W5500_SN_TX_WR_REG);
write_addr = recv_addr;
recv_addr &= (SOCK_SEND_SIZE - 1);
NCS_L();
spi_write_short(recv_addr);
spi_write_byte(VDM | RWB_WRITE | (sock * 0x20 + 0x10));
if((recv_addr + size) < SOCK_SEND_SIZE)
{
for(i = 0; i < size; i++)
{
spi_write_byte(*dat++);
}
}
else
{
recv_addr = SOCK_SEND_SIZE - recv_addr;
for(i = 0; i < recv_addr; i++)
{
spi_write_byte(*dat++);
}
NCS_H();
NCS_L();
spi_write_short(0x00);
spi_write_byte(VDM | RWB_WRITE | (sock * 0x20 + 0x10));
for(; i < size; i++)
{
spi_write_byte(*dat++);
}
}
NCS_H();
write_addr += size;
w5500_write_sock_short(sock, W5500_SN_TX_WR_REG, write_addr);
w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_SEND);
}
/*******************************************************************************
*Function name: w5500_reset
*Description: Hardware reset W5500
*Input: None
*Output: None
*Return value: None
*Note: The reset pin of the W5500 can be encircled only when the low level is at least 500us
*******************************************************************************/
void w5500_reset(void)
{
uint8_t dat = 0;
RST_L();
RST_H();
/* wait connect ok */
while((dat & LINK) == 0)
{
up_mdelay(500);
dat = w5500_read_byte(W5500_PHYCFGR_REG);
}
}
/*******************************************************************************
*Function name: w5500_config_init
*Description: Initialize W5500 register functions
*Input: None
*Output: None
*Return value: None
*Note: Before using W5500, initialize W5500
*******************************************************************************/
void w5500_config_init(void)
{
uint8_t i = 0;
/* software reset, set 1 and auto clear 0 */
w5500_write_byte(W5500_MR_REG, MR_RST);
up_mdelay(100);
w5500_write_bytes(W5500_GAR_REG, w5500_param.gw_addr, 4);
w5500_write_bytes(W5500_SUBR_REG, w5500_param.ip_mask, 4);
w5500_write_bytes(W5500_SHAR_REG, w5500_param.mac_addr, 6);
w5500_write_bytes(W5500_SIPR_REG, w5500_param.ip_addr, 4);
/* set socket rx and tx memory size 2k */
for(i = 0; i < 8; i++)
{
w5500_write_sock_byte(i, W5500_SN_RXBUF_SIZE_REG, 0x02);
w5500_write_sock_byte(i, W5500_SN_TXBUF_SIZE_REG, 0x02);
}
/* set retry time 200ms (0x07d0 = 2000) */
w5500_write_short(W5500_RTR_REG, 0x07d0);
/* retry time with 8, when exceed it, produce overtime interrupt, set W5500_SN_IR_REG(TIMEOUT) */
w5500_write_byte(W5500_RCR_REG, 8);
}
/*******************************************************************************
*Function name: Detect_Gateway
*Description: Check the gateway server
*Input: None
*Output: None
*Return value: TRUE (0xFF) for success, FALSE (0x00) for failure
*******************************************************************************/
uint8_t w5500_detect_gateway(void)
{
uint8_t ip_addr[4] = {w5500_param.ip_addr[0] + 1, w5500_param.ip_addr[1] + 1, w5500_param.ip_addr[2] + 1, w5500_param.ip_addr[3] + 1};
/* check gateway and get gateway phyiscal address */
w5500_write_sock_long(0, W5500_SN_DIPR_REG, ip_addr);
w5500_write_sock_byte(0, W5500_SN_MR_REG, SN_MR_TCP);
w5500_write_sock_byte(0, W5500_SN_CR_REG, SN_CR_OPEN);
up_mdelay(5);
if(w5500_read_sock_byte(0, W5500_SN_SR_REG) != SOCK_INIT)
{
w5500_write_sock_byte(0, W5500_SN_CR_REG, SN_CR_CLOSE);
return FALSE;
}
/* set socket connection mode */
w5500_write_sock_byte(0, W5500_SN_CR_REG, SN_CR_CONNECT);
do
{
uint8_t val = 0;
/* read socket0 interrupt register */
val = w5500_read_sock_byte(0, W5500_SN_IR_REG);
if(val != 0)
{
w5500_write_sock_byte(0, W5500_SN_IR_REG, val);
}
up_mdelay(5);
if((val & IR_TIMEOUT) == IR_TIMEOUT)
{
return FALSE;
}
else if(w5500_read_sock_byte(0, W5500_SN_DHAR_REG) != 0xff)
{
/* close socket */
w5500_write_sock_byte(0, W5500_SN_CR_REG, SN_CR_CLOSE);
return TRUE;
}
} while(1);
return TRUE;
}
/*******************************************************************************
*Function name: w5500_socket_init
*Description: Specify Socket (0~7) initialization
*Input: sock: port to be initialized
*Output: None
*Return value: None
*******************************************************************************/
void w5500_socket_init(socket_t sock)
{
/* max partition bytes = 30 */
w5500_write_sock_short(0, W5500_SN_MSSR_REG, 30);
switch(sock)
{
case 0:
w5500_write_sock_short(0, W5500_SN_PORT_REG, w5500_param.sock.local_port);
w5500_write_sock_short(0, W5500_SN_DPORTR_REG, w5500_param.sock.dst_port);
w5500_write_sock_long(0, W5500_SN_DIPR_REG, w5500_param.sock.dst_ip);
break;
default:
break;
}
}
/*******************************************************************************
*Function name: w5500_socket_connect
*Description: Set the specified Socket (0~7) as the client to connect with the remote server
*Input: sock: port to be set
*Output: None
*Return value: TRUE (0xFF) for success, FALSE (0x00) for failure
*******************************************************************************/
uint8_t w5500_socket_connect(socket_t sock)
{
w5500_write_sock_byte(sock, W5500_SN_MR_REG, SN_MR_TCP);
w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_OPEN);
up_mdelay(5);
if(w5500_read_sock_byte(sock, W5500_SN_SR_REG) != SOCK_INIT)
{
w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_CLOSE);
return FALSE;
}
w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_CONNECT);
return TRUE;
}
/*******************************************************************************
*Function name: w5500_socket_listen
*Description: Set the specified Socket (0~7) as the server to wait for the connection of the remote host
*Input: sock: port to be set
*Output: None
*Return value: TRUE (0xFF) for success, FALSE (0x00) for failure
*******************************************************************************/
uint8_t w5500_socket_listen(socket_t sock)
{
w5500_write_sock_byte(sock, W5500_SN_MR_REG, SN_MR_TCP);
w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_OPEN);
up_mdelay(5);
if(w5500_read_sock_byte(sock, W5500_SN_SR_REG) != SOCK_INIT)
{
w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_CLOSE);
return FALSE;
}
w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_LISTEN);
up_mdelay(5);
if(w5500_read_sock_byte(sock, W5500_SN_SR_REG) != SOCK_LISTEN)
{
w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_CLOSE);
return FALSE;
}
return TRUE;
}
/*******************************************************************************
*Function name: w5500_socket_set_udp
*Description: Set the specified Socket (0~7) to UDP mode
*Input: sock: port to be set
*Output: None
*Return value: TRUE (0xFF) for success, FALSE (0x00) for failure
*******************************************************************************/
uint8_t w5500_socket_set_udp(socket_t sock)
{
w5500_write_sock_byte(sock, W5500_SN_MR_REG, SN_MR_UDP);
w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_OPEN);
up_mdelay(5);
if(w5500_read_sock_byte(sock, W5500_SN_SR_REG) != SOCK_UDP)
{
w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_CLOSE);
return FALSE;
}
return TRUE;
}
/*******************************************************************************
*Function name: w5500_irq_process
*Description: W5500 interrupt handler framework
*Input: None
*Output: None
*Return value: None
*Description: None
*******************************************************************************/
void w5500_irq_process(void)
{
uint8_t ir_flag, sn_flag;
ir_flag = w5500_read_byte(W5500_SIR_REG);
do
{
/* handle socket0 event */
if((ir_flag & S0_INT) == S0_INT)
{
sn_flag = w5500_read_sock_byte(0, W5500_SN_IR_REG);
w5500_write_sock_byte(0, W5500_SN_IR_REG, sn_flag);
if(sn_flag & IR_CON)
{
/* socket connection finished */
w5500_param.sock.flag |= SOCK_FLAG_CONN;
}
if(sn_flag & IR_DISCON)
{
/* disconnect state */
w5500_write_sock_byte(0, W5500_SN_CR_REG, SN_CR_CLOSE);
w5500_socket_init(0);
w5500_param.sock.flag = 0;
}
if(sn_flag & IR_SEND_OK)
{
/* send one package ok */
w5500_param.sock.state |= SOCK_STAT_SEND;
}
if(sn_flag & IR_RECV)
{
w5500_param.sock.state |= SOCK_STAT_RECV;
}
if(sn_flag & IR_TIMEOUT)
{
/* close socket, connection failed */
w5500_write_sock_byte(0, W5500_SN_CR_REG, SN_CR_CLOSE);
w5500_param.sock.flag = 0;
}
}
ir_flag = w5500_read_byte(W5500_SIR_REG);
}while(ir_flag);
}
/*******************************************************************************
*Function name: w5500_intialization
*Description: W5500 initial configuration
*Input: None
*Output: None
*Return value: None
*******************************************************************************/
void w5500_intialization(void)
{
w5500_config_init();
w5500_detect_gateway();
w5500_socket_init(0);
}
/*******************************************************************************
*Function name: w5500_load_param
*Description: load param to w5500_param
*Input: None
*Output: None
*Return value: None
*******************************************************************************/
void w5500_load_param(void)
{
w5500_param_t *param = &w5500_param;
memcpy(param->ip_addr, config_ip_addr, sizeof(config_ip_addr));
memcpy(param->ip_mask, config_ip_mask, sizeof(config_ip_mask));
memcpy(param->gw_addr, config_gw_addr, sizeof(config_gw_addr));
memcpy(param->mac_addr, config_mac_addr, sizeof(config_mac_addr));
memcpy(param->sock.dst_ip, config_dst_ip, sizeof(config_dst_ip));
param->sock.local_port = config_local_port;
param->sock.dst_port = config_dst_port;
param->sock.mode = config_mode;
}
/*******************************************************************************
*Function name: w5500_socket_config
*Description: W5500 port initialization configuration
*Input: None
*Output: None
*Return value: None
*******************************************************************************/
void w5500_socket_config(void)
{
if(w5500_param.sock.flag == 0)
{
/* TCP Sever */
if(w5500_param.sock.mode == SOCK_TCP_SVR)
{
if(w5500_socket_listen(0) == TRUE)
w5500_param.sock.flag = SOCK_FLAG_INIT;
else
w5500_param.sock.flag = 0;
}
/* TCP Client */
else if(w5500_param.sock.mode == SOCK_TCP_CLI)
{
if(w5500_socket_connect(0) == TRUE)
w5500_param.sock.flag = SOCK_FLAG_INIT;
else
w5500_param.sock.flag = 0;
}
/* UDP */
else
{
if(w5500_socket_set_udp(0) == TRUE)
w5500_param.sock.flag = SOCK_FLAG_INIT|SOCK_FLAG_CONN;
else
w5500_param.sock.flag = 0;
}
}
}
/*******************************************************************************
*Function name: Process_Socket_Data
*Description: W5500 receives and sends the received data
*Input: sock: port number
*Output: None
*Return value: receive data length
*******************************************************************************/
uint16_t Process_Socket_Data(socket_t sock)
{
uint16_t size;
size = w5500_read_sock_bytes(sock, rx_buf);
memcpy(tx_buf, rx_buf, size);
w5500_write_sock_bytes(sock, tx_buf, size);
return size;
}
/****************************************************************************
* Name: SPI_Configuration
* Description: spi pin mode configure
* input: None
* output: None
* return:none
****************************************************************************/
void SPI_Configuration(void)
{
/* config simluate SPI bus */
k210_fpioa_config(BSP_ENET_SCLK, HS_GPIO(FPIOA_ENET_SCLK) | K210_IOFLAG_GPIOHS);
k210_fpioa_config(BSP_ENET_NRST, HS_GPIO(FPIOA_ENET_NRST) | K210_IOFLAG_GPIOHS);
k210_fpioa_config(BSP_ENET_MOSI, HS_GPIO(FPIOA_ENET_MOSI) | K210_IOFLAG_GPIOHS);
k210_fpioa_config(BSP_ENET_MISO, HS_GPIO(FPIOA_ENET_MISO) | K210_IOFLAG_GPIOHS);
k210_fpioa_config(BSP_ENET_NCS, HS_GPIO(FPIOA_ENET_NCS) | K210_IOFLAG_GPIOHS);
k210_fpioa_config(BSP_ENET_NINT, HS_GPIO(FPIOA_ENET_NINT) | K210_IOFLAG_GPIOHS);
k210_gpiohs_set_direction(FPIOA_ENET_MISO, GPIO_DM_INPUT);
k210_gpiohs_set_direction(FPIOA_ENET_NRST, GPIO_DM_OUTPUT);
k210_gpiohs_set_direction(FPIOA_ENET_SCLK, GPIO_DM_OUTPUT);
k210_gpiohs_set_direction(FPIOA_ENET_MOSI, GPIO_DM_OUTPUT);
k210_gpiohs_set_direction(FPIOA_ENET_NCS, GPIO_DM_OUTPUT);
k210_gpiohs_set_direction(FPIOA_ENET_NINT, GPIO_DM_INPUT);
k210_gpiohs_set_value(FPIOA_ENET_SCLK, GPIO_PV_HIGH);
k210_gpiohs_set_value(FPIOA_ENET_MOSI, GPIO_PV_HIGH);
k210_gpiohs_set_value(FPIOA_ENET_NCS, GPIO_PV_LOW);
k210_gpiohs_set_value(FPIOA_ENET_NRST, GPIO_PV_HIGH);
}
void w5500_test(void)
{
uint8_t cnt = 0;
uint8_t length = 0;
SPI_Configuration();
w5500_load_param();
w5500_reset();
w5500_intialization();
while(1)
{
w5500_socket_config();
w5500_irq_process();
/* If Socket0 receives data */
if((w5500_param.sock.state & SOCK_STAT_RECV) == SOCK_STAT_RECV)
{
w5500_param.sock.state &= ~SOCK_STAT_RECV;
length = Process_Socket_Data(0);
printf("w5500 receive: ");
for(int i = 0; i < length; i++)
{
printf("%x ", rx_buf[i]);
}
printf("\n");
}
/* Otherwise, send data regularly */
else if(cnt >= 5)
{
if(w5500_param.sock.flag == (SOCK_FLAG_INIT|SOCK_FLAG_CONN))
{
w5500_param.sock.state &= ~SOCK_STAT_SEND;
memcpy(tx_buf, "\r\nWelcome To internet!\r\n", 21);
w5500_write_sock_bytes(0, tx_buf, 21);
}
cnt = 0;
}
up_mdelay(100);
cnt++;
}
}

View File

@ -0,0 +1,319 @@
/*
* Copyright (c) 2022 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 k210_w5500.h
* @brief w5500 driver
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-9-15
*/
#ifndef _K210_W5500_H_
#define _K210_W5500_H_
#include <nuttx/config.h>
#include <nuttx/board.h>
#include <arch/board/board.h>
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <debug.h>
#include <assert.h>
#include <nuttx/time.h>
#include <nuttx/fs/fs.h>
#include "k210_config.h"
#include "k210_fpioa.h"
#include "k210_gpiohs.h"
#include "nuttx/arch.h"
#include "k210_gpio_common.h"
/***************** Common Register *****************/
#define W5500_MR_REG 0x0000
#define MR_RST 0x80
#define MR_WOL 0x20
#define MR_PB 0x10
#define MR_PPP 0x08
#define MR_FARP 0x02
#define W5500_GAR_REG 0x0001
#define W5500_SUBR_REG 0x0005
#define W5500_SHAR_REG 0x0009
#define W5500_SIPR_REG 0x000f
#define W5500_INT_REG 0x0013
#define W5500_IR_REG 0x0015
#define IR_CONFLICT 0x80
#define IR_UNREACH 0x40
#define IR_PPPOE 0x20
#define IR_MP 0x10
#define W5500_IMR_REG 0x0016
#define IMR_IR7 0x80
#define IMR_IR6 0x40
#define IMR_IR5 0x20
#define IMR_IR4 0x10
#define W5500_SIR_REG 0x0017
#define S7_INT 0x80
#define S6_INT 0x40
#define S5_INT 0x20
#define S4_INT 0x10
#define S3_INT 0x08
#define S2_INT 0x04
#define S1_INT 0x02
#define S0_INT 0x01
#define W5500_SIMR_REG 0x0018
#define S7_IMR 0x80
#define S6_IMR 0x40
#define S5_IMR 0x20
#define S4_IMR 0x10
#define S3_IMR 0x08
#define S2_IMR 0x04
#define S1_IMR 0x02
#define S0_IMR 0x01
#define W5500_RTR_REG 0x0019
#define W5500_RCR_REG 0x001B
#define W5500_PTIMER_REG 0x001C
#define W5500_PMAGIC_REG 0x001D
#define W5500_PHA_REG 0x001E
#define W5500_PSID_REG 0x0024
#define W5500_PMRU_REG 0x0026
#define W5500_UIPR_REG 0x0028
#define W5500_UPORT_REG 0x002C
#define W5500_PHYCFGR_REG 0x002E
#define RST_PHY 0x80
#define OPMODE 0x40
#define DPX 0x04
#define SPD 0x02
#define LINK 0x01
#define W5500_VER_REG 0x0039
/********************* Socket Register *******************/
#define W5500_SN_MR_REG 0x0000
#define SN_MR_MULTI_MFEN 0x80
#define SN_MR_BCASTB 0x40
#define SN_MR_ND_MC_MMB 0x20
#define SN_MR_UCASTB_MIP6B 0x10
#define SN_MR_CLOSE 0x00
#define SN_MR_TCP 0x01
#define SN_MR_UDP 0x02
#define SN_MR_MACRAW 0x04
#define W5500_SN_CR_REG 0x0001
#define SN_CR_OPEN 0x01
#define SN_CR_LISTEN 0x02
#define SN_CR_CONNECT 0x04
#define SN_CR_DISCON 0x08
#define SN_CR_CLOSE 0x10
#define SN_CR_SEND 0x20
#define SN_CR_SEND_MAC 0x21
#define SN_CR_SEND_KEEP 0x22
#define SN_CR_RECV 0x40
#define W5500_SN_IR_REG 0x0002
#define IR_SEND_OK 0x10
#define IR_TIMEOUT 0x08
#define IR_RECV 0x04
#define IR_DISCON 0x02
#define IR_CON 0x01
#define W5500_SN_SR_REG 0x0003
#define SOCK_CLOSED 0x00
#define SOCK_INIT 0x13
#define SOCK_LISTEN 0x14
#define SOCK_ESTABLISHED 0x17
#define SOCK_CLOSE_WAIT 0x1C
#define SOCK_UDP 0x22
#define SOCK_MACRAW 0x02
#define SOCK_SYNSEND 0x15
#define SOCK_SYNRECV 0x16
#define SOCK_FIN_WAI 0x18
#define SOCK_CLOSING 0x1A
#define SOCK_TIME_WAIT 0x1B
#define SOCK_LAST_ACK 0x1D
#define W5500_SN_PORT_REG 0x0004
#define W5500_SN_DHAR_REG 0x0006
#define W5500_SN_DIPR_REG 0x000C
#define W5500_SN_DPORTR_REG 0x0010
#define W5500_SN_MSSR_REG 0x0012
#define W5500_SN_TOS_REG 0x0015
#define W5500_SN_TTL_REG 0x0016
#define W5500_SN_RXBUF_SIZE_REG 0x001E
#define W5500_SN_TXBUF_SIZE_REG 0x001F
#define W5500_SN_TX_FSR_REG 0x0020
#define W5500_SN_TX_RD_REG 0x0022
#define W5500_SN_TX_WR_REG 0x0024
#define W5500_SN_RX_RSR_REG 0x0026
#define W5500_SN_RX_RD_REG 0x0028
#define W5500_SN_RX_WR_REG 0x002A
#define W5500_SN_IMR_REG 0x002C
#define IMR_SENDOK 0x10
#define IMR_TIMEOUT 0x08
#define IMR_RECV 0x04
#define IMR_DISCON 0x02
#define IMR_CON 0x01
#define W5500_SN_FRAG_REG 0x002D
#define W5500_SN_KPALVTR_REG 0x002F
/************************ SPI Control Data *************************/
/* Operation mode bits */
#define VDM 0x00
#define FDM1 0x01
#define FDM2 0x02
#define FDM4 0x03
/* Read_Write control bit */
#define RWB_READ 0x00
#define RWB_WRITE 0x04
/* Block select bits */
#define COMMON_R 0x00
/* Socket 0 */
#define S0_REG 0x08
#define S0_TX_BUF 0x10
#define S0_RX_BUF 0x18
/* Socket 1 */
#define S1_REG 0x28
#define S1_TX_BUF 0x30
#define S1_RX_BUF 0x38
/* Socket 2 */
#define S2_REG 0x48
#define S2_TX_BUF 0x50
#define S2_RX_BUF 0x58
/* Socket 3 */
#define S3_REG 0x68
#define S3_TX_BUF 0x70
#define S3_RX_BUF 0x78
/* Socket 4 */
#define S4_REG 0x88
#define S4_TX_BUF 0x90
#define S4_RX_BUF 0x98
/* Socket 5 */
#define S5_REG 0xa8
#define S5_TX_BUF 0xb0
#define S5_RX_BUF 0xb8
/* Socket 6 */
#define S6_REG 0xc8
#define S6_TX_BUF 0xd0
#define S6_RX_BUF 0xd8
/* Socket 7 */
#define S7_REG 0xe8
#define S7_TX_BUF 0xf0
#define S7_RX_BUF 0xf8
// socket receive buffer size based on RMSR
#define SOCK_RECV_SIZE 2048
// socket send buffer size based on RMSR
#define SOCK_SEND_SIZE 2048
#define W5500_IP_ADDR_LEN 4
#define W5500_IP_MASK_LEN 4
#define W5500_GW_ADDR_LEN 4
#define W5500_MAC_ADDR_LEN 6
//for every socket
// socket mode
#define SOCK_TCP_SVR 0 //server mode
#define SOCK_TCP_CLI 1 //client mode
#define SOCK_UDP_MOD 2 //udp mode
// socket flag
#define SOCK_FLAG_INIT 1
#define SOCK_FLAG_CONN 2
// socket data state
#define SOCK_STAT_RECV 1
#define SOCK_STAT_SEND 2
typedef struct w5500_socket_s
{
uint16_t local_port;
uint8_t dst_ip[W5500_IP_ADDR_LEN];
uint16_t dst_port;
uint8_t mode; // 0: TCP Server; 1: TCP client; 2: UDP
uint8_t flag; // 1: init ok; 2: connected
uint8_t state; // 1: receive one; 2: send ok
}w5500_socket_t;
typedef struct
{
uint8_t ip_addr[W5500_IP_ADDR_LEN];
uint8_t ip_mask[W5500_IP_MASK_LEN];
uint8_t gw_addr[W5500_GW_ADDR_LEN];
uint8_t mac_addr[W5500_MAC_ADDR_LEN];
uint8_t udp_ip[4];
uint16_t udp_port;
w5500_socket_t sock;
}w5500_param_t;
#define W5500_MAX_PACK_SIZE 1460
typedef unsigned char socket_t;
#define NCS_L() k210_gpiohs_set_value(FPIOA_ENET_NCS, GPIO_PV_LOW); up_udelay(1);
#define NCS_H() k210_gpiohs_set_value(FPIOA_ENET_NCS, GPIO_PV_HIGH); up_udelay(1);
#define SCLK_L() k210_gpiohs_set_value(FPIOA_ENET_SCLK, GPIO_PV_LOW); up_udelay(1);
#define SCLK_H() k210_gpiohs_set_value(FPIOA_ENET_SCLK, GPIO_PV_HIGH); up_udelay(1);
#define MOSI_L() k210_gpiohs_set_value(FPIOA_ENET_MOSI, GPIO_PV_LOW); up_udelay(1);
#define MOSI_H() k210_gpiohs_set_value(FPIOA_ENET_MOSI, GPIO_PV_HIGH); up_udelay(1);
#define RST_L() k210_gpiohs_set_value(FPIOA_ENET_NRST, GPIO_PV_LOW); up_mdelay(200);
#define RST_H() k210_gpiohs_set_value(FPIOA_ENET_NRST, GPIO_PV_HIGH); up_mdelay(200);
void w5500_write_sock_byte(socket_t sock, uint16_t reg, uint8_t dat);
void w5500_write_sock_short(socket_t sock, uint16_t reg, uint16_t dat);
void w5500_write_sock_long(socket_t sock, uint16_t reg, uint8_t *dat);
uint8_t w5500_read_byte(uint16_t reg);
uint8_t w5500_read_sock_byte(socket_t sock, uint16_t reg);
uint16_t w5500_read_sock_short(socket_t sock, uint16_t reg);
void w5500_write_sock_bytes(socket_t sock, uint8_t *dat, uint16_t size);
void w5500_reset(void);
void w5500_config_init(void);
uint8_t w5500_detect_gateway(void);
void w5500_socket_init(socket_t sock);
uint8_t w5500_socket_connect(socket_t sock);
uint8_t w5500_socket_listen(socket_t sock);
uint8_t w5500_socket_set_udp(socket_t sock);
void w5500_irq_process(void);
void w5500_intialization(void);
void w5500_load_param(void);
void w5500_socket_config(void);
uint16_t Process_Socket_Data(socket_t sock);
void SPI_Configuration(void);
void w5500_test(void);
#endif

View File

@ -8,8 +8,8 @@ if ARCH_BOARD_XIDATONG_RISCV64
menuconfig BSP_USING_CH376
bool "Using CH376 device"
default n
select K210_16550_UART
select K210_16550_UART3
select K210_UART
select K210_UART3
if BSP_USING_CH376
@ -40,8 +40,8 @@ menuconfig BSP_USING_TOUCH
default n
menuconfig BSP_USING_CAN
select K210_16550_UART
select K210_16550_UART1
select K210_UART
select K210_UART1
bool "Using CAN device"
default n

View File

@ -58,17 +58,17 @@ CONFIG_READLINE_TABCOMPLETION=y
CONFIG_SCHED_HPWORK=y
CONFIG_DEV_GPIO=y
CONFIG_BOARDCTL_RESET=y
CONFIG_K210_16550_UART=y
CONFIG_K210_16550_UART2=y
CONFIG_K210_16550_UART2_BASE=0x50220000
CONFIG_K210_16550_UART2_CLOCK=195000000
CONFIG_K210_16550_UART2_IRQ=39
CONFIG_K210_16550_UART2_BAUD=115200
CONFIG_K210_16550_UART2_PARITY=0
CONFIG_K210_16550_UART2_BITS=8
CONFIG_K210_16550_UART2_2STOP=0
CONFIG_K210_16550_UART2_RXBUFSIZE=128
CONFIG_K210_16550_UART2_TXBUFSIZE=128
CONFIG_K210_UART=y
CONFIG_K210_UART2=y
CONFIG_K210_UART2_BASE=0x50220000
CONFIG_K210_UART2_CLOCK=195000000
CONFIG_K210_UART2_IRQ=39
CONFIG_K210_UART2_BAUD=115200
CONFIG_K210_UART2_PARITY=0
CONFIG_K210_UART2_BITS=8
CONFIG_K210_UART2_2STOP=0
CONFIG_K210_UART2_RXBUFSIZE=128
CONFIG_K210_UART2_TXBUFSIZE=128
CONFIG_SUPPORT_CONNECTION_FRAMEWORK=y
CONFIG_CONNECTION_FRAMEWORK_DEBUG=y
CONFIG_CONNECTION_ADAPTER_4G=y

View File

@ -58,16 +58,16 @@ CONFIG_READLINE_TABCOMPLETION=y
CONFIG_SCHED_HPWORK=y
CONFIG_DEV_GPIO=y
CONFIG_BOARDCTL_RESET=y
CONFIG_K210_16550_UART=y
CONFIG_K210_16550_UART1=y
CONFIG_K210_16550_UART1_BASE=0x50210000
CONFIG_K210_16550_UART1_CLOCK=195000000
CONFIG_K210_16550_UART1_IRQ=38
CONFIG_K210_16550_UART1_BAUD=115200
CONFIG_K210_16550_UART1_PARITY=0
CONFIG_K210_16550_UART1_BITS=8
CONFIG_K210_16550_UART1_2STOP=0
CONFIG_K210_16550_UART1_RXBUFSIZE=128
CONFIG_K210_16550_UART1_TXBUFSIZE=128
CONFIG_K210_UART=y
CONFIG_K210_UART1=y
CONFIG_K210_UART1_BASE=0x50210000
CONFIG_K210_UART1_CLOCK=195000000
CONFIG_K210_UART1_IRQ=38
CONFIG_K210_UART1_BAUD=115200
CONFIG_K210_UART1_PARITY=0
CONFIG_K210_UART1_BITS=8
CONFIG_K210_UART1_2STOP=0
CONFIG_K210_UART1_RXBUFSIZE=128
CONFIG_K210_UART1_TXBUFSIZE=128
CONFIG_BSP_USING_CAN=y
CONFIG_SERIAL_TERMIOS=y

View File

@ -58,6 +58,6 @@ CONFIG_READLINE_TABCOMPLETION=y
CONFIG_SCHED_HPWORK=y
CONFIG_DEV_GPIO=y
CONFIG_BOARDCTL_RESET=y
CONFIG_K210_16550_UART=y
CONFIG_K210_16550_UART3=y
CONFIG_K210_UART=y
CONFIG_K210_UART3=y
CONFIG_BSP_USING_TOUCH=y

View File

@ -58,17 +58,17 @@ CONFIG_READLINE_TABCOMPLETION=y
CONFIG_SCHED_HPWORK=y
CONFIG_DEV_GPIO=y
CONFIG_BOARDCTL_RESET=y
CONFIG_K210_16550_UART=y
CONFIG_K210_16550_UART1=y
CONFIG_K210_16550_UART1_BASE=0x50210000
CONFIG_K210_16550_UART1_CLOCK=195000000
CONFIG_K210_16550_UART1_IRQ=38
CONFIG_K210_16550_UART1_BAUD=115200
CONFIG_K210_16550_UART1_PARITY=0
CONFIG_K210_16550_UART1_BITS=8
CONFIG_K210_16550_UART1_2STOP=0
CONFIG_K210_16550_UART1_RXBUFSIZE=128
CONFIG_K210_16550_UART1_TXBUFSIZE=128
CONFIG_K210_UART=y
CONFIG_K210_UART1=y
CONFIG_K210_UART1_BASE=0x50210000
CONFIG_K210_UART1_CLOCK=195000000
CONFIG_K210_UART1_IRQ=38
CONFIG_K210_UART1_BAUD=115200
CONFIG_K210_UART1_PARITY=0
CONFIG_K210_UART1_BITS=8
CONFIG_K210_UART1_2STOP=0
CONFIG_K210_UART1_RXBUFSIZE=128
CONFIG_K210_UART1_TXBUFSIZE=128
CONFIG_SUPPORT_CONNECTION_FRAMEWORK=y
CONFIG_CONNECTION_FRAMEWORK_DEBUG=y
CONFIG_CONNECTION_ADAPTER_WIFI=y

View File

@ -40,7 +40,7 @@
#include <fcntl.h>
#include <termios.h>
#include <nuttx/ioexpander/gpio.h>
#include "k210_uart_16550.h"
#include "k210_uart.h"
#include "k210_fpioa.h"
#include "k210_gpiohs.h"
#include "k210_gpio_common.h"

View File

@ -95,7 +95,7 @@ int k210_bringup(void)
board_touch_initialize();
#endif
#ifdef CONFIG_K210_16550_UART1
#ifdef CONFIG_K210_UART1
#ifdef CONFIG_ADAPTER_ESP8285_WIFI
sysctl_clock_enable(SYSCTL_CLOCK_UART1);
sysctl_reset(SYSCTL_RESET_UART1);
@ -121,7 +121,7 @@ int k210_bringup(void)
#endif
#endif
#ifdef CONFIG_K210_16550_UART2
#ifdef CONFIG_K210_UART2
sysctl_clock_enable(SYSCTL_CLOCK_UART2);
sysctl_reset(SYSCTL_RESET_UART2);
@ -129,7 +129,7 @@ int k210_bringup(void)
fpioa_set_function(GPIO_EC200T_TXD, FPOA_USART2_TX);
#endif
#ifdef CONFIG_K210_16550_UART3
#ifdef CONFIG_K210_UART3
sysctl_clock_enable(SYSCTL_CLOCK_UART3);
sysctl_reset(SYSCTL_RESET_UART3);

View File

@ -36,7 +36,7 @@
#include <assert.h>
#include <fcntl.h>
#include <nuttx/ioexpander/gpio.h>
#include "k210_uart_16550.h"
#include "k210_uart.h"
#define ERR_USB_UNKNOWN 0xFA

View File

@ -18,6 +18,7 @@ cp -rf $current/apps $nuttx
cp -rf $nuttx/aiit_board/aiit-arm32-board $nuttx/nuttx/boards/arm/stm32
cp -rf $nuttx/aiit_board/aiit-riscv64-board $nuttx/nuttx/boards/risc-v/k210
cp -rf $nuttx/aiit_board/xidatong-riscv64 $nuttx/nuttx/boards/risc-v/k210
cp -rf $nuttx/aiit_board/edu-riscv64 $nuttx/nuttx/boards/risc-v/k210
cp -rf $nuttx/aiit_board/xidatong-arm32 $nuttx/nuttx/boards/arm/imxrt
cp -rf $nuttx/aiit_board/hc32f4a0 $nuttx/nuttx/boards/arm/hc32

View File

@ -40,13 +40,13 @@ config K210_LCD_BACKLIGHT
endmenu
menuconfig K210_16550_UART
bool "K210 16550 UART Chip support"
menuconfig K210_UART
bool "K210 UART Chip support"
select ARCH_HAVE_SERIAL_TERMIOS
default n
if K210_16550_UART
config K210_16550_SERIAL_DISABLE_REORDERING
if K210_UART
config K210_SERIAL_DISABLE_REORDERING
bool "Disable reordering of ttySx devices."
default n
---help---
@ -54,227 +54,227 @@ if K210_16550_UART
console is always on /dev/ttyS0. If more than one UART is in use this
can, however, have the side-effect that all port mappings
(hardware USART1 -> /dev/ttyS0) change if the console is moved to another
UART. This option disables that re-ordering for 16550 UARTs.
UART. This option disables that re-ordering for UARTs.
config K210_16550_UART1
bool "K210 16550 UART1"
config K210_UART1
bool "K210 UART1"
default n
if K210_16550_UART1
if K210_UART1
config K210_16550_UART1_BASE
hex "K210 16550 UART1 base address"
config K210_UART1_BASE
hex "K210 UART1 base address"
default 0x50210000
config K210_16550_UART1_CLOCK
int "K210 16550 UART1 clock"
config K210_UART1_CLOCK
int "K210 UART1 clock"
default 195000000
config K210_16550_UART1_IRQ
int "K210 16550 UART1 IRQ number"
config K210_UART1_IRQ
int "K210 UART1 IRQ number"
default 38
config K210_16550_UART1_BAUD
int "K210 16550 UART1 BAUD"
config K210_UART1_BAUD
int "K210 UART1 BAUD"
default 115200
config K210_16550_UART1_PARITY
int "K210 16550 UART1 parity"
config K210_UART1_PARITY
int "K210 UART1 parity"
default 0
range 0 2
---help---
K210 16550 UART1 parity. 0=None, 1=Odd, 2=Even. Default: None
K210 UART1 parity. 0=None, 1=Odd, 2=Even. Default: None
config K210_16550_UART1_BITS
int "K210 16550 UART1 number of bits"
config K210_UART1_BITS
int "K210 UART1 number of bits"
default 8
---help---
K210 16550 UART1 number of bits. Default: 8
K210 UART1 number of bits. Default: 8
config K210_16550_UART1_2STOP
int "K210 16550 UART1 two stop bits"
config K210_UART1_2STOP
int "K210 UART1 two stop bits"
default 0
---help---
0=1 stop bit, 1=Two stop bits. Default: 1 stop bit
config K210_16550_UART1_RXBUFSIZE
int "K210 16550 UART1 Rx buffer size"
config K210_UART1_RXBUFSIZE
int "K210 UART1 Rx buffer size"
default 256
---help---
K210 16550 UART1 Rx buffer size. Default: 128
K210 UART1 Rx buffer size. Default: 128
config K210_16550_UART1_TXBUFSIZE
int "K210 16550 UART1 Tx buffer size"
config K210_UART1_TXBUFSIZE
int "K210 UART1 Tx buffer size"
default 256
---help---
K210 16550 UART1 Tx buffer size. Default: 128
K210 UART1 Tx buffer size. Default: 128
config K210_16550_UART1_IFLOWCONTROL
bool "K210 16550 UART1 RTS flow control"
config K210_UART1_IFLOWCONTROL
bool "K210 UART1 RTS flow control"
default n
select SERIAL_IFLOWCONTROL
---help---
Enable K210 16550 UART1 RTS flow control
Enable K210 UART1 RTS flow control
config K210_16550_UART1_OFLOWCONTROL
bool "K210 16550 UART1 CTS flow control"
config K210_UART1_OFLOWCONTROL
bool "K210 UART1 CTS flow control"
default n
select SERIAL_OFLOWCONTROL
---help---
Enable K210 16550 UART1 CTS flow control
Enable K210 UART1 CTS flow control
endif # K210_16550_UART1
endif # K210_UART1
config K210_16550_UART2
bool "K210 16550 UART2"
config K210_UART2
bool "K210 UART2"
default n
if K210_16550_UART2
if K210_UART2
config K210_16550_UART2_BASE
hex "K210 16550 UART2 base address"
config K210_UART2_BASE
hex "K210 UART2 base address"
default 0x50220000
config K210_16550_UART2_CLOCK
int "K210 16550 UART2 clock"
config K210_UART2_CLOCK
int "K210 UART2 clock"
default 195000000
config K210_16550_UART2_IRQ
int "K210 16550 UART2 IRQ number"
config K210_UART2_IRQ
int "K210 UART2 IRQ number"
default 39
config K210_16550_UART2_BAUD
int "K210 16550 UART2 BAUD"
config K210_UART2_BAUD
int "K210 UART2 BAUD"
default 115200
config K210_16550_UART2_PARITY
int "K210 16550 UART2 parity"
config K210_UART2_PARITY
int "K210 UART2 parity"
default 0
range 0 2
---help---
K210 16550 UART2 parity. 0=None, 1=Odd, 2=Even. Default: None
K210 UART2 parity. 0=None, 1=Odd, 2=Even. Default: None
config K210_16550_UART2_BITS
int "K210 16550 UART2 number of bits"
config K210_UART2_BITS
int "K210 UART2 number of bits"
default 8
---help---
K210 16550 UART2 number of bits. Default: 8
K210 UART2 number of bits. Default: 8
config K210_16550_UART2_2STOP
int "K210 16550 UART2 two stop bits"
config K210_UART2_2STOP
int "K210 UART2 two stop bits"
default 0
---help---
0=1 stop bit, 1=Two stop bits. Default: 1 stop bit
config K210_16550_UART2_RXBUFSIZE
int "K210 16550 UART2 Rx buffer size"
config K210_UART2_RXBUFSIZE
int "K210 UART2 Rx buffer size"
default 256
---help---
K210 16550 UART2 Rx buffer size. Default: 128
K210 UART2 Rx buffer size. Default: 128
config K210_16550_UART2_TXBUFSIZE
int "K210 16550 UART2 Tx buffer size"
config K210_UART2_TXBUFSIZE
int "K210 UART2 Tx buffer size"
default 256
---help---
K210 16550 UART2 Tx buffer size. Default: 128
K210 UART2 Tx buffer size. Default: 128
config K210_16550_UART2_IFLOWCONTROL
bool "K210 16550 UART2 RTS flow control"
config K210_UART2_IFLOWCONTROL
bool "K210 UART2 RTS flow control"
default n
select SERIAL_IFLOWCONTROL
---help---
Enable K210 16550 UART2 RTS flow control
Enable K210 UART2 RTS flow control
config K210_16550_UART2_OFLOWCONTROL
bool "K210 16550 UART2 CTS flow control"
config K210_UART2_OFLOWCONTROL
bool "K210 UART2 CTS flow control"
default n
select SERIAL_OFLOWCONTROL
---help---
Enable K210 16550 UART2 CTS flow control
Enable K210 UART2 CTS flow control
endif # K210_16550_UART2
endif # K210_UART2
config K210_16550_UART3
bool "K210 16550 UART3"
config K210_UART3
bool "K210 UART3"
default n
if K210_16550_UART3
if K210_UART3
config K210_16550_UART3_BASE
hex "K210 16550 UART3 base address"
config K210_UART3_BASE
hex "K210 UART3 base address"
default 0x50230000
config K210_16550_UART3_CLOCK
int "K210 16550 UART3 clock"
config K210_UART3_CLOCK
int "K210 UART3 clock"
default 195000000
config K210_16550_UART3_IRQ
int "K210 16550 UART3 IRQ number"
config K210_UART3_IRQ
int "K210 UART3 IRQ number"
default 40
config K210_16550_UART3_BAUD
int "K210 16550 UART3 BAUD"
config K210_UART3_BAUD
int "K210 UART3 BAUD"
default 115200
config K210_16550_UART3_PARITY
int "K210 16550 UART3 parity"
config K210_UART3_PARITY
int "K210 UART3 parity"
default 0
range 0 2
---help---
K210 16550 UART3 parity. 0=None, 1=Odd, 2=Even. Default: None
K210 UART3 parity. 0=None, 1=Odd, 2=Even. Default: None
config K210_16550_UART3_BITS
int "K210 16550 UART3 number of bits"
config K210_UART3_BITS
int "K210 UART3 number of bits"
default 8
---help---
K210 16550 UART3 number of bits. Default: 8
K210 UART3 number of bits. Default: 8
config K210_16550_UART3_2STOP
int "K210 16550 UART3 two stop bits"
config K210_UART3_2STOP
int "K210 UART3 two stop bits"
default 0
---help---
0=1 stop bit, 1=Two stop bits. Default: 1 stop bit
config K210_16550_UART3_RXBUFSIZE
int "K210 16550 UART3 Rx buffer size"
config K210_UART3_RXBUFSIZE
int "K210 UART3 Rx buffer size"
default 256
---help---
K210 16550 UART3 Rx buffer size. Default: 128
K210 UART3 Rx buffer size. Default: 128
config K210_16550_UART3_TXBUFSIZE
int "K210 16550 UART3 Tx buffer size"
config K210_UART3_TXBUFSIZE
int "K210 UART3 Tx buffer size"
default 256
---help---
K210 16550 UART3 Tx buffer size. Default: 128
K210 UART3 Tx buffer size. Default: 128
config K210_16550_UART3_IFLOWCONTROL
bool "K210 16550 UART3 RTS flow control"
config K210_UART3_IFLOWCONTROL
bool "K210 UART3 RTS flow control"
default n
select SERIAL_IFLOWCONTROL
---help---
Enable K210 16550 UART3 RTS flow control
Enable K210 UART3 RTS flow control
config K210_16550_UART3_OFLOWCONTROL
bool "K210 16550 UART3 CTS flow control"
config K210_UART3_OFLOWCONTROL
bool "K210 UART3 CTS flow control"
default n
select SERIAL_OFLOWCONTROL
---help---
Enable K210 16550 UART3 CTS flow control
Enable K210 UART3 CTS flow control
endif # K210_16550_UART3
endif # K210_UART3
config K210_16550_SUPRESS_CONFIG
bool "Suppress K210 16550 configuration"
config K210_UART_SUPRESS_CONFIG
bool "Suppress K210 configuration"
default n
config K210_16550_SUPRESS_INITIAL_CONFIG
bool "Suppress initial K210 16550 configuration"
depends on !K210_16550_SUPRESS_CONFIG
config K210_UART_SUPRESS_INITIAL_CONFIG
bool "Suppress initial K210 configuration"
depends on !K210_UART_SUPRESS_CONFIG
default y
---help---
This option is useful, for example, if you are using a bootloader
that configures the K210_16550_UART. In that case, you may want to
that configures the K210_UART. In that case, you may want to
just leave the existing console configuration in place. Default: n
config SERIAL_UART_ARCH_MMIO
@ -285,21 +285,21 @@ if K210_16550_UART
bool "Platform has own custom IOCTL"
default n
config K210_16550_REGINCR
int "Address increment between K210 16550 registers"
config K210_UART_REGINCR
int "Address increment between K210 registers"
default 4
---help---
The address increment between K210 16550 registers. Options are 1, 2, or 4.
The address increment between K210 registers. Options are 1, 2, or 4.
Default: 1
config K210_16550_REGWIDTH
int "Bit width of K210 16550 registers"
config K210_UART_REGWIDTH
int "Bit width of K210 registers"
default 32
---help---
The bit width of registers. Options are 8, 16, or 32. Default: 32
config K210_16550_ADDRWIDTH
int "Address width of K210 16550 registers"
config K210_UART_ADDRWIDTH
int "Address width of K210 registers"
default 32
---help---
The bit width of registers. Options are 0, 8, 16, or 32.

View File

@ -57,7 +57,7 @@ CHIP_CSRCS = k210_allocateheap.c k210_clockconfig.c
CHIP_CSRCS += k210_irq.c k210_irq_dispatch.c k210_systemreset.c
CHIP_CSRCS += k210_lowputc.c k210_serial.c k210_fpioa.c fpioa.c
CHIP_CSRCS += k210_start.c k210_timerisr.c k210_gpiohs.c k210_gpio.c
CHIP_CSRCS += k210_sysctl.c k210_uart_16550.c
CHIP_CSRCS += k210_sysctl.c k210_uart.c
ifeq ($(CONFIG_BUILD_PROTECTED),y)
CMN_CSRCS += riscv_task_start.c riscv_pthread_start.c

View File

@ -52,7 +52,7 @@
#include "k210_config.h"
#include "chip.h"
#include "k210.h"
#include "k210_uart_16550.h"
#include "k210_uart.h"
/****************************************************************************
* Pre-processor Definitions
@ -649,9 +649,9 @@ void riscv_serialinit(void)
/* Register all UARTs */
uart_register("/dev/ttyS0", &TTYS0_DEV);
#ifdef CONFIG_K210_16550_UART
#ifdef CONFIG_K210_UART
/* Register UART1-UART3 */
k210_uart_16550_register();
k210_uart_register();
#endif
}

View File

@ -11,7 +11,7 @@
*/
/**
* @file k210_uart_16550.c
* @file k210_uart.c
* @brief k210 uart1-uart3 support
* @version 1.0
* @author AIIT XUOS Lab
@ -37,13 +37,13 @@
#include <nuttx/arch.h>
#include <nuttx/serial/serial.h>
#include <nuttx/fs/ioctl.h>
#include "k210_uart_16550.h"
#include "k210_uart.h"
#ifdef CONFIG_SERIAL_TERMIOS
# include <termios.h>
#endif
#ifdef CONFIG_K210_16550_UART
#ifdef CONFIG_K210_UART
/****************************************************************************
@ -58,31 +58,31 @@
* Private Function Prototypes
****************************************************************************/
static int k210_16550_setup(FAR struct uart_dev_s *dev);
static void k210_16550_shutdown(FAR struct uart_dev_s *dev);
static int k210_16550_attach(FAR struct uart_dev_s *dev);
static void k210_16550_detach(FAR struct uart_dev_s *dev);
static int k210_16550_interrupt(int irq, FAR void *context, FAR void *arg);
static int k210_16550_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
static int k210_16550_receive(FAR struct uart_dev_s *dev, unsigned int *status);
static void k210_16550_rxint(FAR struct uart_dev_s *dev, bool enable);
static bool k210_16550_rxavailable(FAR struct uart_dev_s *dev);
static int k210_uart_setup(FAR struct uart_dev_s *dev);
static void k210_uart_shutdown(FAR struct uart_dev_s *dev);
static int k210_uart_attach(FAR struct uart_dev_s *dev);
static void k210_uart_detach(FAR struct uart_dev_s *dev);
static int k210_uart_interrupt(int irq, FAR void *context, FAR void *arg);
static int k210_uart_ioctl(FAR struct file *filep, int cmd, unsigned long arg);
static int k210_uart_receive(FAR struct uart_dev_s *dev, unsigned int *status);
static void k210_uart_rxint(FAR struct uart_dev_s *dev, bool enable);
static bool k210_uart_rxavailable(FAR struct uart_dev_s *dev);
#ifdef CONFIG_SERIAL_IFLOWCONTROL
static bool k210_16550_rxflowcontrol(struct uart_dev_s *dev,
static bool k210_uart_rxflowcontrol(struct uart_dev_s *dev,
unsigned int nbuffered, bool upper);
#endif
#ifdef CONFIG_SERIAL_TXDMA
static void k210_16550_dmasend(FAR struct uart_dev_s *dev);
static void k210_16550_dmatxavail(FAR struct uart_dev_s *dev);
static void k210_uart_dmasend(FAR struct uart_dev_s *dev);
static void k210_uart_dmatxavail(FAR struct uart_dev_s *dev);
#endif
#ifdef CONFIG_SERIAL_RXDMA
static void k210_16550_dmareceive(FAR struct uart_dev_s *dev);
static void k210_16550_dmarxfree(FAR struct uart_dev_s *dev);
static void k210_uart_dmareceive(FAR struct uart_dev_s *dev);
static void k210_uart_dmarxfree(FAR struct uart_dev_s *dev);
#endif
static void k210_16550_send(FAR struct uart_dev_s *dev, int ch);
static void k210_16550_txint(FAR struct uart_dev_s *dev, bool enable);
static bool k210_16550_txready(FAR struct uart_dev_s *dev);
static bool k210_16550_txempty(FAR struct uart_dev_s *dev);
static void k210_uart_send(FAR struct uart_dev_s *dev, int ch);
static void k210_uart_txint(FAR struct uart_dev_s *dev, bool enable);
static bool k210_uart_txready(FAR struct uart_dev_s *dev);
static bool k210_uart_txempty(FAR struct uart_dev_s *dev);
/****************************************************************************
* Private Data
@ -90,64 +90,64 @@ static bool k210_16550_txempty(FAR struct uart_dev_s *dev);
static const struct uart_ops_s g_uart_ops =
{
.setup = k210_16550_setup,
.shutdown = k210_16550_shutdown,
.attach = k210_16550_attach,
.detach = k210_16550_detach,
.ioctl = k210_16550_ioctl,
.receive = k210_16550_receive,
.rxint = k210_16550_rxint,
.rxavailable = k210_16550_rxavailable,
.setup = k210_uart_setup,
.shutdown = k210_uart_shutdown,
.attach = k210_uart_attach,
.detach = k210_uart_detach,
.ioctl = k210_uart_ioctl,
.receive = k210_uart_receive,
.rxint = k210_uart_rxint,
.rxavailable = k210_uart_rxavailable,
#ifdef CONFIG_SERIAL_IFLOWCONTROL
.rxflowcontrol = k210_16550_rxflowcontrol,
.rxflowcontrol = k210_uart_rxflowcontrol,
#endif
#ifdef CONFIG_SERIAL_TXDMA
.dmasend = k210_16550_dmasend,
.dmasend = k210_uart_dmasend,
#endif
#ifdef CONFIG_SERIAL_RXDMA
.dmareceive = k210_16550_dmareceive,
.dmarxfree = k210_16550_dmarxfree,
.dmareceive = k210_uart_dmareceive,
.dmarxfree = k210_uart_dmarxfree,
#endif
#ifdef CONFIG_SERIAL_TXDMA
.dmatxavail = k210_16550_dmatxavail,
.dmatxavail = k210_uart_dmatxavail,
#endif
.send = k210_16550_send,
.txint = k210_16550_txint,
.txready = k210_16550_txready,
.txempty = k210_16550_txempty,
.send = k210_uart_send,
.txint = k210_uart_txint,
.txready = k210_uart_txready,
.txempty = k210_uart_txempty,
};
/* I/O buffers */
#ifdef CONFIG_K210_16550_UART1
static char g_uart1rxbuffer[CONFIG_K210_16550_UART1_RXBUFSIZE];
static char g_uart1txbuffer[CONFIG_K210_16550_UART1_TXBUFSIZE];
#ifdef CONFIG_K210_UART1
static char g_uart1rxbuffer[CONFIG_K210_UART1_RXBUFSIZE];
static char g_uart1txbuffer[CONFIG_K210_UART1_TXBUFSIZE];
#endif
#ifdef CONFIG_K210_16550_UART2
static char g_uart2rxbuffer[CONFIG_K210_16550_UART2_RXBUFSIZE];
static char g_uart2txbuffer[CONFIG_K210_16550_UART2_TXBUFSIZE];
#ifdef CONFIG_K210_UART2
static char g_uart2rxbuffer[CONFIG_K210_UART2_RXBUFSIZE];
static char g_uart2txbuffer[CONFIG_K210_UART2_TXBUFSIZE];
#endif
#ifdef CONFIG_K210_16550_UART3
static char g_uart3rxbuffer[CONFIG_K210_16550_UART3_RXBUFSIZE];
static char g_uart3txbuffer[CONFIG_K210_16550_UART3_TXBUFSIZE];
#ifdef CONFIG_K210_UART3
static char g_uart3rxbuffer[CONFIG_K210_UART3_RXBUFSIZE];
static char g_uart3txbuffer[CONFIG_K210_UART3_TXBUFSIZE];
#endif
/* This describes the state of the 16550 uart1 port. */
/* This describes the state of the uart1 port. */
#ifdef CONFIG_K210_16550_UART1
static struct k210_16550_s g_uart1priv =
#ifdef CONFIG_K210_UART1
static struct k210_uart_s g_uart1priv =
{
.uartbase = CONFIG_K210_16550_UART1_BASE,
#ifndef CONFIG_K210_16550_SUPRESS_CONFIG
.baud = CONFIG_K210_16550_UART1_BAUD,
.uartclk = CONFIG_K210_16550_UART1_CLOCK,
.uartbase = CONFIG_K210_UART1_BASE,
#ifndef CONFIG_K210_UART_SUPRESS_CONFIG
.baud = CONFIG_K210_UART1_BAUD,
.uartclk = CONFIG_K210_UART1_CLOCK,
#endif
.irq = CONFIG_K210_16550_UART1_IRQ,
#ifndef CONFIG_K210_16550_SUPRESS_CONFIG
.parity = CONFIG_K210_16550_UART1_PARITY,
.bits = CONFIG_K210_16550_UART1_BITS,
.stopbits2 = CONFIG_K210_16550_UART1_2STOP,
#if defined(CONFIG_K210_16550_UART1_IFLOWCONTROL) || defined(CONFIG_K210_16550_UART1_OFLOWCONTROL)
.irq = CONFIG_K210_UART1_IRQ,
#ifndef CONFIG_K210_UART_SUPRESS_CONFIG
.parity = CONFIG_K210_UART1_PARITY,
.bits = CONFIG_K210_UART1_BITS,
.stopbits2 = CONFIG_K210_UART1_2STOP,
#if defined(CONFIG_K210_UART1_IFLOWCONTROL) || defined(CONFIG_K210_UART1_OFLOWCONTROL)
.flow = true,
#endif
#endif
@ -157,12 +157,12 @@ static uart_dev_t g_uart1port =
{
.recv =
{
.size = CONFIG_K210_16550_UART1_RXBUFSIZE,
.size = CONFIG_K210_UART1_RXBUFSIZE,
.buffer = g_uart1rxbuffer,
},
.xmit =
{
.size = CONFIG_K210_16550_UART1_TXBUFSIZE,
.size = CONFIG_K210_UART1_TXBUFSIZE,
.buffer = g_uart1txbuffer,
},
.ops = &g_uart_ops,
@ -170,22 +170,22 @@ static uart_dev_t g_uart1port =
};
#endif
/* This describes the state of the 16550 uart2 port. */
/* This describes the state of the uart2 port. */
#ifdef CONFIG_K210_16550_UART2
static struct k210_16550_s g_uart2priv =
#ifdef CONFIG_K210_UART2
static struct k210_uart_s g_uart2priv =
{
.uartbase = CONFIG_K210_16550_UART2_BASE,
#ifndef CONFIG_K210_16550_SUPRESS_CONFIG
.baud = CONFIG_K210_16550_UART2_BAUD,
.uartclk = CONFIG_K210_16550_UART2_CLOCK,
.uartbase = CONFIG_K210_UART2_BASE,
#ifndef CONFIG_K210_UART_SUPRESS_CONFIG
.baud = CONFIG_K210_UART2_BAUD,
.uartclk = CONFIG_K210_UART2_CLOCK,
#endif
.irq = CONFIG_K210_16550_UART2_IRQ,
#ifndef CONFIG_K210_16550_SUPRESS_CONFIG
.parity = CONFIG_K210_16550_UART2_PARITY,
.bits = CONFIG_K210_16550_UART2_BITS,
.stopbits2 = CONFIG_K210_16550_UART2_2STOP,
#if defined(CONFIG_K210_16550_UART2_IFLOWCONTROL) || defined(CONFIG_K210_16550_UART2_OFLOWCONTROL)
.irq = CONFIG_K210_UART2_IRQ,
#ifndef CONFIG_K210_UART_SUPRESS_CONFIG
.parity = CONFIG_K210_UART2_PARITY,
.bits = CONFIG_K210_UART2_BITS,
.stopbits2 = CONFIG_K210_UART2_2STOP,
#if defined(CONFIG_K210_UART2_IFLOWCONTROL) || defined(CONFIG_K210_UART2_OFLOWCONTROL)
.flow = true,
#endif
#endif
@ -195,12 +195,12 @@ static uart_dev_t g_uart2port =
{
.recv =
{
.size = CONFIG_K210_16550_UART2_RXBUFSIZE,
.size = CONFIG_K210_UART2_RXBUFSIZE,
.buffer = g_uart2rxbuffer,
},
.xmit =
{
.size = CONFIG_K210_16550_UART2_TXBUFSIZE,
.size = CONFIG_K210_UART2_TXBUFSIZE,
.buffer = g_uart2txbuffer,
},
.ops = &g_uart_ops,
@ -209,22 +209,22 @@ static uart_dev_t g_uart2port =
#endif
/* This describes the state of the 16550 uart1 port. */
/* This describes the state of the uart1 port. */
#ifdef CONFIG_K210_16550_UART3
static struct k210_16550_s g_uart3priv =
#ifdef CONFIG_K210_UART3
static struct k210_uart_s g_uart3priv =
{
.uartbase = CONFIG_K210_16550_UART3_BASE,
#ifndef CONFIG_K210_16550_SUPRESS_CONFIG
.baud = CONFIG_K210_16550_UART3_BAUD,
.uartclk = CONFIG_K210_16550_UART3_CLOCK,
.uartbase = CONFIG_K210_UART3_BASE,
#ifndef CONFIG_K210_UART_SUPRESS_CONFIG
.baud = CONFIG_K210_UART3_BAUD,
.uartclk = CONFIG_K210_UART3_CLOCK,
#endif
.irq = CONFIG_K210_16550_UART3_IRQ,
#ifndef CONFIG_K210_16550_SUPRESS_CONFIG
.parity = CONFIG_K210_16550_UART3_PARITY,
.bits = CONFIG_K210_16550_UART3_BITS,
.stopbits2 = CONFIG_K210_16550_UART3_2STOP,
#if defined(CONFIG_K210_16550_UART3_IFLOWCONTROL) || defined(CONFIG_K210_16550_UART3_OFLOWCONTROL)
.irq = CONFIG_K210_UART3_IRQ,
#ifndef CONFIG_K210_UART_SUPRESS_CONFIG
.parity = CONFIG_K210_UART3_PARITY,
.bits = CONFIG_K210_UART3_BITS,
.stopbits2 = CONFIG_K210_UART3_2STOP,
#if defined(CONFIG_K210_UART3_IFLOWCONTROL) || defined(CONFIG_K210_UART3_OFLOWCONTROL)
.flow = true,
#endif
#endif
@ -234,12 +234,12 @@ static uart_dev_t g_uart3port =
{
.recv =
{
.size = CONFIG_K210_16550_UART3_RXBUFSIZE,
.size = CONFIG_K210_UART3_RXBUFSIZE,
.buffer = g_uart3rxbuffer,
},
.xmit =
{
.size = CONFIG_K210_16550_UART3_TXBUFSIZE,
.size = CONFIG_K210_UART3_TXBUFSIZE,
.buffer = g_uart3txbuffer,
},
.ops = &g_uart_ops,
@ -253,10 +253,10 @@ static uart_dev_t g_uart3port =
****************************************************************************/
/****************************************************************************
* Name: k210_16550_serialin
* Name: k210_uart_serialin
****************************************************************************/
static inline uart_datawidth_t k210_16550_serialin(FAR struct k210_16550_s *priv,
static inline uart_datawidth_t k210_uart_serialin(FAR struct k210_uart_s *priv,
int offset)
{
#ifdef CONFIG_SERIAL_UART_ARCH_MMIO
@ -267,10 +267,10 @@ static inline uart_datawidth_t k210_16550_serialin(FAR struct k210_16550_s *priv
}
/****************************************************************************
* Name: k210_16550_serialout
* Name: k210_uart_serialout
****************************************************************************/
static inline void k210_16550_serialout(FAR struct k210_16550_s *priv, int offset,
static inline void k210_uart_serialout(FAR struct k210_uart_s *priv, int offset,
uart_datawidth_t value)
{
#ifdef CONFIG_SERIAL_UART_ARCH_MMIO
@ -281,10 +281,10 @@ static inline void k210_16550_serialout(FAR struct k210_16550_s *priv, int offse
}
/****************************************************************************
* Name: k210_16550_disableuartint
* Name: k210_uart_disableuartint
****************************************************************************/
static inline void k210_16550_disableuartint(FAR struct k210_16550_s *priv,
static inline void k210_uart_disableuartint(FAR struct k210_uart_s *priv,
FAR uart_datawidth_t *ier)
{
if (ier)
@ -293,28 +293,28 @@ static inline void k210_16550_disableuartint(FAR struct k210_16550_s *priv,
}
priv->ier &= ~UART_IER_ALLIE;
k210_16550_serialout(priv, UART_IER_OFFSET, priv->ier);
k210_uart_serialout(priv, UART_IER_OFFSET, priv->ier);
}
/****************************************************************************
* Name: k210_16550_restoreuartint
* Name: k210_uart_restoreuartint
****************************************************************************/
static inline void k210_16550_restoreuartint(FAR struct k210_16550_s *priv,
static inline void k210_uart_restoreuartint(FAR struct k210_uart_s *priv,
uint32_t ier)
{
priv->ier |= ier & UART_IER_ALLIE;
k210_16550_serialout(priv, UART_IER_OFFSET, priv->ier);
k210_uart_serialout(priv, UART_IER_OFFSET, priv->ier);
}
/****************************************************************************
* Name: k210_16550_enablebreaks
* Name: k210_uart_enablebreaks
****************************************************************************/
static inline void k210_16550_enablebreaks(FAR struct k210_16550_s *priv,
static inline void k210_uart_enablebreaks(FAR struct k210_uart_s *priv,
bool enable)
{
uint32_t lcr = k210_16550_serialin(priv, UART_LCR_OFFSET);
uint32_t lcr = k210_uart_serialin(priv, UART_LCR_OFFSET);
if (enable)
{
@ -325,11 +325,11 @@ static inline void k210_16550_enablebreaks(FAR struct k210_16550_s *priv,
lcr &= ~UART_LCR_BRK;
}
k210_16550_serialout(priv, UART_LCR_OFFSET, lcr);
k210_uart_serialout(priv, UART_LCR_OFFSET, lcr);
}
/****************************************************************************
* Name: k210_16550_divisor
* Name: k210_uart_divisor
*
* Description:
* Select a divider to produce the BAUD from the UART_CLK.
@ -341,8 +341,8 @@ static inline void k210_16550_enablebreaks(FAR struct k210_16550_s *priv,
*
****************************************************************************/
#ifndef CONFIG_K210_16550_SUPRESS_CONFIG
static inline uint32_t k210_16550_divisor(FAR struct k210_16550_s *priv)
#ifndef CONFIG_K210_UART_SUPRESS_CONFIG
static inline uint32_t k210_uart_divisor(FAR struct k210_uart_s *priv)
{
return (priv->uartclk / (uint32_t)priv->baud);
// return (priv->uartclk + (priv->baud << 3)) / (priv->baud << 4);
@ -350,7 +350,7 @@ static inline uint32_t k210_16550_divisor(FAR struct k210_16550_s *priv)
#endif
/****************************************************************************
* Name: k210_16550_setup
* Name: k210_uart_setup
*
* Description:
* Configure the UART baud, bits, parity, fifos, etc. This
@ -359,10 +359,10 @@ static inline uint32_t k210_16550_divisor(FAR struct k210_16550_s *priv)
*
****************************************************************************/
static int k210_16550_setup(FAR struct uart_dev_s *dev)
static int k210_uart_setup(FAR struct uart_dev_s *dev)
{
#ifndef CONFIG_K210_16550_SUPRESS_CONFIG
FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv;
#ifndef CONFIG_K210_UART_SUPRESS_CONFIG
FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv;
uint16_t div;
uint8_t dlh, dll, dlf;
uint32_t lcr;
@ -372,17 +372,17 @@ static int k210_16550_setup(FAR struct uart_dev_s *dev)
/* Clear fifos */
k210_16550_serialout(priv, UART_FCR_OFFSET,
k210_uart_serialout(priv, UART_FCR_OFFSET,
(UART_FCR_RXRST | UART_FCR_TXRST));
/* Set trigger */
k210_16550_serialout(priv, UART_FCR_OFFSET,
k210_uart_serialout(priv, UART_FCR_OFFSET,
(UART_FCR_FIFOEN | UART_FCR_RXTRIGGER_8));
/* Set up the IER */
priv->ier = k210_16550_serialin(priv, UART_IER_OFFSET);
priv->ier = k210_uart_serialin(priv, UART_IER_OFFSET);
/* Set up the LCR */
@ -423,33 +423,33 @@ static int k210_16550_setup(FAR struct uart_dev_s *dev)
/* Enter DLAB=1 */
k210_16550_serialout(priv, UART_LCR_OFFSET, (lcr | UART_LCR_DLAB));
k210_uart_serialout(priv, UART_LCR_OFFSET, (lcr | UART_LCR_DLAB));
/* Set the BAUD divisor */
div = k210_16550_divisor(priv);
div = k210_uart_divisor(priv);
dlh = div >> 12;
dll = (div - (dlh << 12)) / 16;
dlf = div - (dlh << 12) - dll * 16;
k210_16550_serialout(priv, UART_DLM_OFFSET, dlh);
k210_16550_serialout(priv, UART_DLL_OFFSET, dll);
k210_16550_serialout(priv, UART_DLF_OFFSET, dlf);
k210_uart_serialout(priv, UART_DLM_OFFSET, dlh);
k210_uart_serialout(priv, UART_DLL_OFFSET, dll);
k210_uart_serialout(priv, UART_DLF_OFFSET, dlf);
/* Clear DLAB */
k210_16550_serialout(priv, UART_LCR_OFFSET, lcr);
k210_uart_serialout(priv, UART_LCR_OFFSET, lcr);
/* Configure the FIFOs */
k210_16550_serialout(priv, UART_FCR_OFFSET,
k210_uart_serialout(priv, UART_FCR_OFFSET,
(UART_FCR_RXTRIGGER_8 | UART_FCR_TXRST | UART_FCR_RXRST |
UART_FCR_FIFOEN));
/* Set up the auto flow control */
#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL)
mcr = k210_16550_serialin(priv, UART_MCR_OFFSET);
mcr = k210_uart_serialin(priv, UART_MCR_OFFSET);
if (priv->flow)
{
mcr |= UART_MCR_AFCE;
@ -461,9 +461,9 @@ static int k210_16550_setup(FAR struct uart_dev_s *dev)
mcr |= UART_MCR_RTS;
k210_16550_serialout(priv, UART_MCR_OFFSET, mcr);
k210_uart_serialout(priv, UART_MCR_OFFSET, mcr);
k210_16550_serialout(priv, UART_SRT_OFFSET, 0x0);
k210_uart_serialout(priv, UART_SRT_OFFSET, 0x0);
#endif /* defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) */
@ -472,7 +472,7 @@ static int k210_16550_setup(FAR struct uart_dev_s *dev)
}
/****************************************************************************
* Name: k210_16550_shutdown
* Name: k210_uart_shutdown
*
* Description:
* Disable the UART. This method is called when the serial
@ -480,14 +480,14 @@ static int k210_16550_setup(FAR struct uart_dev_s *dev)
*
****************************************************************************/
static void k210_16550_shutdown(struct uart_dev_s *dev)
static void k210_uart_shutdown(struct uart_dev_s *dev)
{
FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv;
k210_16550_disableuartint(priv, NULL);
FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv;
k210_uart_disableuartint(priv, NULL);
}
/****************************************************************************
* Name: k210_16550_attach
* Name: k210_uart_attach
*
* Description:
* Configure the UART to operation in interrupt driven mode. This method
@ -502,14 +502,14 @@ static void k210_16550_shutdown(struct uart_dev_s *dev)
*
****************************************************************************/
static int k210_16550_attach(struct uart_dev_s *dev)
static int k210_uart_attach(struct uart_dev_s *dev)
{
FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv;
FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv;
int ret;
/* Attach and enable the IRQ */
ret = irq_attach(priv->irq, k210_16550_interrupt, dev);
ret = irq_attach(priv->irq, k210_uart_interrupt, dev);
#ifndef CONFIG_ARCH_NOINTC
if (ret == OK)
{
@ -525,7 +525,7 @@ static int k210_16550_attach(struct uart_dev_s *dev)
}
/****************************************************************************
* Name: k210_16550_detach
* Name: k210_uart_detach
*
* Description:
* Detach UART interrupts. This method is called when the serial port is
@ -534,36 +534,36 @@ static int k210_16550_attach(struct uart_dev_s *dev)
*
****************************************************************************/
static void k210_16550_detach(FAR struct uart_dev_s *dev)
static void k210_uart_detach(FAR struct uart_dev_s *dev)
{
FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv;
FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv;
up_disable_irq(priv->irq);
irq_detach(priv->irq);
}
/****************************************************************************
* Name: k210_16550_interrupt
* Name: k210_uart_interrupt
*
* Description:
* This is the UART interrupt handler. It will be invoked when an
* interrupt received on the 'irq' It should call uart_transmitchars or
* uart_receivechar to perform the appropriate data transfers. The
* interrupt handling logic must be able to map the 'irq' number into the
* appropriate k210_16550_s structure in order to call these functions.
* appropriate k210_uart_s structure in order to call these functions.
*
****************************************************************************/
static int k210_16550_interrupt(int irq, FAR void *context, FAR void *arg)
static int k210_uart_interrupt(int irq, FAR void *context, FAR void *arg)
{
FAR struct uart_dev_s *dev = (struct uart_dev_s *)arg;
FAR struct k210_16550_s *priv;
FAR struct k210_uart_s *priv;
uint32_t status;
int passes;
uint8_t v_int_status;
DEBUGASSERT(dev != NULL && dev->priv != NULL);
priv = (FAR struct k210_16550_s *)dev->priv;
priv = (FAR struct k210_uart_s *)dev->priv;
/* Loop until there are no characters to be transferred or,
* until we have been looping for a long time.
@ -575,7 +575,7 @@ static int k210_16550_interrupt(int irq, FAR void *context, FAR void *arg)
* termination conditions
*/
status = k210_16550_serialin(priv, UART_IIR_OFFSET);
status = k210_uart_serialin(priv, UART_IIR_OFFSET);
if (status == 0)
{
@ -603,18 +603,18 @@ static int k210_16550_interrupt(int irq, FAR void *context, FAR void *arg)
}
/****************************************************************************
* Name: k210_16550_ioctl
* Name: k210_uart_ioctl
*
* Description:
* All ioctl calls will be routed through this method
*
****************************************************************************/
static int k210_16550_ioctl(struct file *filep, int cmd, unsigned long arg)
static int k210_uart_ioctl(struct file *filep, int cmd, unsigned long arg)
{
FAR struct inode *inode = filep->f_inode;
FAR struct uart_dev_s *dev = inode->i_private;
FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv;
FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv;
int ret;
#ifdef CONFIG_SERIAL_UART_ARCH_IOCTL
@ -634,14 +634,14 @@ static int k210_16550_ioctl(struct file *filep, int cmd, unsigned long arg)
#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT
case TIOCSERGSTRUCT:
{
FAR struct k210_16550_s *user = (FAR struct k210_16550_s *)arg;
FAR struct k210_uart_s *user = (FAR struct k210_uart_s *)arg;
if (!user)
{
ret = -EINVAL;
}
else
{
memcpy(user, dev, sizeof(struct k210_16550_s));
memcpy(user, dev, sizeof(struct k210_uart_s));
}
}
break;
@ -650,7 +650,7 @@ static int k210_16550_ioctl(struct file *filep, int cmd, unsigned long arg)
case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */
{
irqstate_t flags = enter_critical_section();
k210_16550_enablebreaks(priv, true);
k210_uart_enablebreaks(priv, true);
leave_critical_section(flags);
}
break;
@ -659,12 +659,12 @@ static int k210_16550_ioctl(struct file *filep, int cmd, unsigned long arg)
{
irqstate_t flags;
flags = enter_critical_section();
k210_16550_enablebreaks(priv, false);
k210_uart_enablebreaks(priv, false);
leave_critical_section(flags);
}
break;
#if defined(CONFIG_SERIAL_TERMIOS) && !defined(CONFIG_K210_16550_SUPRESS_CONFIG)
#if defined(CONFIG_SERIAL_TERMIOS) && !defined(CONFIG_K210_UART_SUPRESS_CONFIG)
case TCGETS:
{
FAR struct termios *termiosp = (FAR struct termios *)arg;
@ -758,7 +758,7 @@ static int k210_16550_ioctl(struct file *filep, int cmd, unsigned long arg)
priv->flow = (termiosp->c_cflag & CRTSCTS) != 0;
#endif
k210_16550_setup(dev);
k210_uart_setup(dev);
leave_critical_section(flags);
}
break;
@ -773,7 +773,7 @@ static int k210_16550_ioctl(struct file *filep, int cmd, unsigned long arg)
}
/****************************************************************************
* Name: k210_16550_receive
* Name: k210_uart_receive
*
* Description:
* Called (usually) from the interrupt level to receive one
@ -782,26 +782,26 @@ static int k210_16550_ioctl(struct file *filep, int cmd, unsigned long arg)
*
****************************************************************************/
static int k210_16550_receive(struct uart_dev_s *dev, unsigned int *status)
static int k210_uart_receive(struct uart_dev_s *dev, unsigned int *status)
{
FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv;
FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv;
uint32_t rbr = 0;
*status = k210_16550_serialin(priv, UART_LSR_OFFSET);
rbr = k210_16550_serialin(priv, UART_RBR_OFFSET);
*status = k210_uart_serialin(priv, UART_LSR_OFFSET);
rbr = k210_uart_serialin(priv, UART_RBR_OFFSET);
return rbr;
}
/****************************************************************************
* Name: k210_16550_rxint
* Name: k210_uart_rxint
*
* Description:
* Call to enable or disable RX interrupts
*
****************************************************************************/
static void k210_16550_rxint(struct uart_dev_s *dev, bool enable)
static void k210_uart_rxint(struct uart_dev_s *dev, bool enable)
{
FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv;
FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv;
if (enable)
{
@ -812,25 +812,25 @@ static void k210_16550_rxint(struct uart_dev_s *dev, bool enable)
priv->ier &= ~UART_IER_ERBFI;
}
k210_16550_serialout(priv, UART_IER_OFFSET, priv->ier);
k210_uart_serialout(priv, UART_IER_OFFSET, priv->ier);
}
/****************************************************************************
* Name: k210_16550_rxavailable
* Name: k210_uart_rxavailable
*
* Description:
* Return true if the receive fifo is not empty
*
****************************************************************************/
static bool k210_16550_rxavailable(struct uart_dev_s *dev)
static bool k210_uart_rxavailable(struct uart_dev_s *dev)
{
FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv;
return ((k210_16550_serialin(priv, UART_LSR_OFFSET) & UART_LSR_DR) != 0);
FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv;
return ((k210_uart_serialin(priv, UART_LSR_OFFSET) & UART_LSR_DR) != 0);
}
/****************************************************************************
* Name: k210_16550_dma*
* Name: k210_uart_dma*
*
* Description:
* Stubbed out DMA-related methods
@ -838,11 +838,11 @@ static bool k210_16550_rxavailable(struct uart_dev_s *dev)
****************************************************************************/
#ifdef CONFIG_SERIAL_IFLOWCONTROL
static bool k210_16550_rxflowcontrol(struct uart_dev_s *dev,
static bool k210_uart_rxflowcontrol(struct uart_dev_s *dev,
unsigned int nbuffered, bool upper)
{
#ifndef CONFIG_K210_16550_SUPRESS_CONFIG
FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv;
#ifndef CONFIG_K210_UART_SUPRESS_CONFIG
FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv;
if (priv->flow)
{
@ -853,7 +853,7 @@ static bool k210_16550_rxflowcontrol(struct uart_dev_s *dev,
* input is received.
*/
k210_16550_rxint(dev, !upper);
k210_uart_rxint(dev, !upper);
return true;
}
#endif
@ -863,7 +863,7 @@ static bool k210_16550_rxflowcontrol(struct uart_dev_s *dev,
#endif
/****************************************************************************
* Name: k210_16550_dma*
* Name: k210_uart_dma*
*
* Description:
* Stub functions used when serial DMA is enabled.
@ -871,59 +871,59 @@ static bool k210_16550_rxflowcontrol(struct uart_dev_s *dev,
****************************************************************************/
#ifdef CONFIG_SERIAL_TXDMA
static void k210_16550_dmasend(FAR struct uart_dev_s *dev)
static void k210_uart_dmasend(FAR struct uart_dev_s *dev)
{
}
#endif
#ifdef CONFIG_SERIAL_RXDMA
static void k210_16550_dmareceive(FAR struct uart_dev_s *dev)
static void k210_uart_dmareceive(FAR struct uart_dev_s *dev)
{
}
static void k210_16550_dmarxfree(FAR struct uart_dev_s *dev)
static void k210_uart_dmarxfree(FAR struct uart_dev_s *dev)
{
}
#endif
#ifdef CONFIG_SERIAL_TXDMA
static void k210_16550_dmatxavail(FAR struct uart_dev_s *dev)
static void k210_uart_dmatxavail(FAR struct uart_dev_s *dev)
{
}
#endif
/****************************************************************************
* Name: k210_16550_send
* Name: k210_uart_send
*
* Description:
* This method will send one byte on the UART
*
****************************************************************************/
static void k210_16550_send(struct uart_dev_s *dev, int ch)
static void k210_uart_send(struct uart_dev_s *dev, int ch)
{
FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv;
k210_16550_serialout(priv, UART_THR_OFFSET, (uart_datawidth_t)ch);
FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv;
k210_uart_serialout(priv, UART_THR_OFFSET, (uart_datawidth_t)ch);
}
/****************************************************************************
* Name: k210_16550_txint
* Name: k210_uart_txint
*
* Description:
* Call to enable or disable TX interrupts
*
****************************************************************************/
static void k210_16550_txint(struct uart_dev_s *dev, bool enable)
static void k210_uart_txint(struct uart_dev_s *dev, bool enable)
{
FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv;
FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv;
irqstate_t flags;
flags = enter_critical_section();
if (enable)
{
priv->ier |= UART_IER_ETBEI;
k210_16550_serialout(priv, UART_IER_OFFSET, priv->ier);
k210_uart_serialout(priv, UART_IER_OFFSET, priv->ier);
/* Fake a TX interrupt here by just calling uart_xmitchars() with
* interrupts disabled (note this may recurse).
@ -934,38 +934,38 @@ static void k210_16550_txint(struct uart_dev_s *dev, bool enable)
else
{
priv->ier &= ~UART_IER_ETBEI;
k210_16550_serialout(priv, UART_IER_OFFSET, priv->ier);
k210_uart_serialout(priv, UART_IER_OFFSET, priv->ier);
}
leave_critical_section(flags);
}
/****************************************************************************
* Name: k210_16550_txready
* Name: k210_uart_txready
*
* Description:
* Return true if the tranmsit fifo is not full
*
****************************************************************************/
static bool k210_16550_txready(struct uart_dev_s *dev)
static bool k210_uart_txready(struct uart_dev_s *dev)
{
FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv;
return (((k210_16550_serialin(priv, UART_LSR_OFFSET) & UART_LSR_THRE) != 0));
FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv;
return (((k210_uart_serialin(priv, UART_LSR_OFFSET) & UART_LSR_THRE) != 0));
}
/****************************************************************************
* Name: k210_16550_txempty
* Name: k210_uart_txempty
*
* Description:
* Return true if the transmit fifo is empty
*
****************************************************************************/
static bool k210_16550_txempty(struct uart_dev_s *dev)
static bool k210_uart_txempty(struct uart_dev_s *dev)
{
FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv;
return ((k210_16550_serialin(priv, UART_LSR_OFFSET) & UART_LSR_TEMT) != 0);
FAR struct k210_uart_s *priv = (FAR struct k210_uart_s *)dev->priv;
return ((k210_uart_serialin(priv, UART_LSR_OFFSET) & UART_LSR_TEMT) != 0);
}
/****************************************************************************
@ -973,7 +973,7 @@ static bool k210_16550_txempty(struct uart_dev_s *dev)
****************************************************************************/
/****************************************************************************
* Name: k210_uart_16550_register
* Name: k210_uart_register
*
* Description:
* Register serial console and serial ports. This assumes that
@ -981,20 +981,20 @@ static bool k210_16550_txempty(struct uart_dev_s *dev)
*
****************************************************************************/
void k210_uart_16550_register(void)
void k210_uart_register(void)
{
#if defined(CONFIG_K210_16550_UART1)
k210_16550_setup(&g_uart1port);
#if defined(CONFIG_K210_UART1)
k210_uart_setup(&g_uart1port);
uart_register("/dev/ttyS1", &g_uart1port);
#endif
#if defined(CONFIG_K210_16550_UART2)
k210_16550_setup(&g_uart2port);
#if defined(CONFIG_K210_UART2)
k210_uart_setup(&g_uart2port);
uart_register("/dev/ttyS2", &g_uart2port);
#endif
#if defined(CONFIG_K210_16550_UART3)
k210_16550_setup(&g_uart3port);
#if defined(CONFIG_K210_UART3)
k210_uart_setup(&g_uart3port);
uart_register("/dev/ttyS3", &g_uart3port);
#endif
}
#endif /* CONFIG_K210_16550_UART */
#endif /* CONFIG_K210_UART */

View File

@ -18,8 +18,8 @@
* @date 2022.09.28
*/
#ifndef __INCLUDE_NUTTX_SERIAL_UART_K210_16550_H
#define __INCLUDE_NUTTX_SERIAL_UART_K210_16550_H
#ifndef __INCLUDE_NUTTX_SERIAL_UART_K210_H
#define __INCLUDE_NUTTX_SERIAL_UART_K210_H
/****************************************************************************
* Included Files
@ -27,7 +27,7 @@
#include <nuttx/config.h>
#ifdef CONFIG_K210_16550_UART
#ifdef CONFIG_K210_UART
/****************************************************************************
* Pre-processor Definitions
@ -38,7 +38,7 @@
/* Are any UARTs enabled? */
#undef HAVE_UART
#if defined(CONFIG_K210_16550_UART1) || defined(CONFIG_K210_16550_UART2) || defined(CONFIG_K210_16550_UART3)
#if defined(CONFIG_K210_UART1) || defined(CONFIG_K210_UART2) || defined(CONFIG_K210_UART3)
# define HAVE_UART 1
#endif
@ -46,78 +46,78 @@
* register bit width.
*/
#ifndef CONFIG_K210_16550_REGINCR
# error "CONFIG_K210_16550_REGINCR not defined"
#ifndef CONFIG_K210_UART_REGINCR
# error "CONFIG_K210_UART_REGINCR not defined"
#endif
#if CONFIG_K210_16550_REGINCR != 1 && CONFIG_K210_16550_REGINCR != 2 && CONFIG_K210_16550_REGINCR != 4
# error "CONFIG_K210_16550_REGINCR not supported"
#if CONFIG_K210_UART_REGINCR != 1 && CONFIG_K210_UART_REGINCR != 2 && CONFIG_K210_UART_REGINCR != 4
# error "CONFIG_K210_UART_REGINCR not supported"
#endif
#ifndef CONFIG_K210_16550_REGWIDTH
# error "CONFIG_K210_16550_REGWIDTH not defined"
#ifndef CONFIG_K210_UART_REGWIDTH
# error "CONFIG_K210_UART_REGWIDTH not defined"
#endif
#if CONFIG_K210_16550_REGWIDTH != 8 && CONFIG_K210_16550_REGWIDTH != 16 && CONFIG_K210_16550_REGWIDTH != 32
# error "CONFIG_K210_16550_REGWIDTH not supported"
#if CONFIG_K210_UART_REGWIDTH != 8 && CONFIG_K210_UART_REGWIDTH != 16 && CONFIG_K210_UART_REGWIDTH != 32
# error "CONFIG_K210_UART_REGWIDTH not supported"
#endif
#ifndef CONFIG_K210_16550_ADDRWIDTH
# error "CONFIG_K210_16550_ADDRWIDTH not defined"
#ifndef CONFIG_K210_UART_ADDRWIDTH
# error "CONFIG_K210_UART_ADDRWIDTH not defined"
#endif
#if CONFIG_K210_16550_ADDRWIDTH != 0 && CONFIG_K210_16550_ADDRWIDTH != 8 && \
CONFIG_K210_16550_ADDRWIDTH != 16 && CONFIG_K210_16550_ADDRWIDTH != 32 && \
CONFIG_K210_16550_ADDRWIDTH != 64
# error "CONFIG_K210_16550_ADDRWIDTH not supported"
#if CONFIG_K210_UART_ADDRWIDTH != 0 && CONFIG_K210_UART_ADDRWIDTH != 8 && \
CONFIG_K210_UART_ADDRWIDTH != 16 && CONFIG_K210_UART_ADDRWIDTH != 32 && \
CONFIG_K210_UART_ADDRWIDTH != 64
# error "CONFIG_K210_UART_ADDRWIDTH not supported"
#endif
/* If a UART is enabled, then its base address, clock, and IRQ
* must also be provided
*/
#ifdef CONFIG_K210_16550_UART1
# ifndef CONFIG_K210_16550_UART1_BASE
# error "CONFIG_K210_16550_UART1_BASE not provided"
# undef CONFIG_K210_16550_UART1
#ifdef CONFIG_K210_UART1
# ifndef CONFIG_K210_UART1_BASE
# error "CONFIG_K210_UART1_BASE not provided"
# undef CONFIG_K210_UART1
# endif
# ifndef CONFIG_K210_16550_UART1_CLOCK
# error "CONFIG_K210_16550_UART1_CLOCK not provided"
# undef CONFIG_K210_16550_UART1
# ifndef CONFIG_K210_UART1_CLOCK
# error "CONFIG_K210_UART1_CLOCK not provided"
# undef CONFIG_K210_UART1
# endif
# ifndef CONFIG_K210_16550_UART1_IRQ
# error "CONFIG_K210_16550_UART1_IRQ not provided"
# undef CONFIG_K210_16550_UART1
# ifndef CONFIG_K210_UART1_IRQ
# error "CONFIG_K210_UART1_IRQ not provided"
# undef CONFIG_K210_UART1
# endif
#endif
#ifdef CONFIG_K210_16550_UART2
# ifndef CONFIG_K210_16550_UART2_BASE
# error "CONFIG_K210_16550_UART2_BASE not provided"
# undef CONFIG_K210_16550_UART2
#ifdef CONFIG_K210_UART2
# ifndef CONFIG_K210_UART2_BASE
# error "CONFIG_K210_UART2_BASE not provided"
# undef CONFIG_K210_UART2
# endif
# ifndef CONFIG_K210_16550_UART2_CLOCK
# error "CONFIG_K210_16550_UART2_CLOCK not provided"
# undef CONFIG_K210_16550_UART2
# ifndef CONFIG_K210_UART2_CLOCK
# error "CONFIG_K210_UART2_CLOCK not provided"
# undef CONFIG_K210_UART2
# endif
# ifndef CONFIG_K210_16550_UART2_IRQ
# error "CONFIG_K210_16550_UART2_IRQ not provided"
# undef CONFIG_K210_16550_UART2
# ifndef CONFIG_K210_UART2_IRQ
# error "CONFIG_K210_UART2_IRQ not provided"
# undef CONFIG_K210_UART2
# endif
#endif
#ifdef CONFIG_K210_16550_UART3
# ifndef CONFIG_K210_16550_UART3_BASE
# error "CONFIG_K210_16550_UART3_BASE not provided"
# undef CONFIG_K210_16550_UART3
#ifdef CONFIG_K210_UART3
# ifndef CONFIG_K210_UART3_BASE
# error "CONFIG_K210_UART3_BASE not provided"
# undef CONFIG_K210_UART3
# endif
# ifndef CONFIG_K210_16550_UART3_CLOCK
# error "CONFIG_K210_16550_UART3_CLOCK not provided"
# undef CONFIG_K210_16550_UART3
# ifndef CONFIG_K210_UART3_CLOCK
# error "CONFIG_K210_UART3_CLOCK not provided"
# undef CONFIG_K210_UART3
# endif
# ifndef CONFIG_K210_16550_UART3_IRQ
# error "CONFIG_K210_16550_UART3_IRQ not provided"
# undef CONFIG_K210_16550_UART3
# ifndef CONFIG_K210_UART3_IRQ
# error "CONFIG_K210_UART3_IRQ not provided"
# undef CONFIG_K210_UART3
# endif
#endif
@ -143,21 +143,21 @@
#define UART_DLF_INCR 48 /* Divisor factor Register*/
#define UART_CPR_INCR 61 /* Component Register */
#define UART_RBR_OFFSET (CONFIG_K210_16550_REGINCR*UART_RBR_INCR)
#define UART_THR_OFFSET (CONFIG_K210_16550_REGINCR*UART_THR_INCR)
#define UART_DLL_OFFSET (CONFIG_K210_16550_REGINCR*UART_DLL_INCR)
#define UART_DLM_OFFSET (CONFIG_K210_16550_REGINCR*UART_DLM_INCR)
#define UART_IER_OFFSET (CONFIG_K210_16550_REGINCR*UART_IER_INCR)
#define UART_IIR_OFFSET (CONFIG_K210_16550_REGINCR*UART_IIR_INCR)
#define UART_FCR_OFFSET (CONFIG_K210_16550_REGINCR*UART_FCR_INCR)
#define UART_LCR_OFFSET (CONFIG_K210_16550_REGINCR*UART_LCR_INCR)
#define UART_MCR_OFFSET (CONFIG_K210_16550_REGINCR*UART_MCR_INCR)
#define UART_LSR_OFFSET (CONFIG_K210_16550_REGINCR*UART_LSR_INCR)
#define UART_MSR_OFFSET (CONFIG_K210_16550_REGINCR*UART_MSR_INCR)
#define UART_SCR_OFFSET (CONFIG_K210_16550_REGINCR*UART_SCR_INCR)
#define UART_SRT_OFFSET (CONFIG_K210_16550_REGINCR*UART_SRT_INCR)
#define UART_DLF_OFFSET (CONFIG_K210_16550_REGINCR*UART_DLF_INCR)
#define UART_CPR_OFFSET (CONFIG_K210_16550_REGINCR*UART_CPR_INCR)
#define UART_RBR_OFFSET (CONFIG_K210_UART_REGINCR*UART_RBR_INCR)
#define UART_THR_OFFSET (CONFIG_K210_UART_REGINCR*UART_THR_INCR)
#define UART_DLL_OFFSET (CONFIG_K210_UART_REGINCR*UART_DLL_INCR)
#define UART_DLM_OFFSET (CONFIG_K210_UART_REGINCR*UART_DLM_INCR)
#define UART_IER_OFFSET (CONFIG_K210_UART_REGINCR*UART_IER_INCR)
#define UART_IIR_OFFSET (CONFIG_K210_UART_REGINCR*UART_IIR_INCR)
#define UART_FCR_OFFSET (CONFIG_K210_UART_REGINCR*UART_FCR_INCR)
#define UART_LCR_OFFSET (CONFIG_K210_UART_REGINCR*UART_LCR_INCR)
#define UART_MCR_OFFSET (CONFIG_K210_UART_REGINCR*UART_MCR_INCR)
#define UART_LSR_OFFSET (CONFIG_K210_UART_REGINCR*UART_LSR_INCR)
#define UART_MSR_OFFSET (CONFIG_K210_UART_REGINCR*UART_MSR_INCR)
#define UART_SCR_OFFSET (CONFIG_K210_UART_REGINCR*UART_SCR_INCR)
#define UART_SRT_OFFSET (CONFIG_K210_UART_REGINCR*UART_SRT_INCR)
#define UART_DLF_OFFSET (CONFIG_K210_UART_REGINCR*UART_DLF_INCR)
#define UART_CPR_OFFSET (CONFIG_K210_UART_REGINCR*UART_CPR_INCR)
/* Register bit definitions *************************************************/
@ -267,36 +267,36 @@
* Public Types
****************************************************************************/
#if CONFIG_K210_16550_REGWIDTH == 8
#if CONFIG_K210_UART_REGWIDTH == 8
typedef uint8_t uart_datawidth_t;
#elif CONFIG_K210_16550_REGWIDTH == 16
#elif CONFIG_K210_UART_REGWIDTH == 16
typedef uint16_t uart_datawidth_t;
#elif CONFIG_K210_16550_REGWIDTH == 32
#elif CONFIG_K210_UART_REGWIDTH == 32
typedef uint32_t uart_datawidth_t;
#endif
#if CONFIG_K210_16550_ADDRWIDTH == 0
#if CONFIG_K210_UART_ADDRWIDTH == 0
typedef uintptr_t uart_addrwidth_t;
#elif CONFIG_K210_16550_ADDRWIDTH == 8
#elif CONFIG_K210_UART_ADDRWIDTH == 8
typedef uint8_t uart_addrwidth_t;
#elif CONFIG_K210_16550_ADDRWIDTH == 16
#elif CONFIG_K210_UART_ADDRWIDTH == 16
typedef uint16_t uart_addrwidth_t;
#elif CONFIG_K210_16550_ADDRWIDTH == 32
#elif CONFIG_K210_UART_ADDRWIDTH == 32
typedef uint32_t uart_addrwidth_t;
#elif CONFIG_K210_16550_ADDRWIDTH == 64
#elif CONFIG_K210_UART_ADDRWIDTH == 64
typedef uint64_t uart_addrwidth_t;
#endif
struct k210_16550_s
struct k210_uart_s
{
uart_addrwidth_t uartbase; /* Base address of UART registers */
#ifndef CONFIG_K210_16550_SUPRESS_CONFIG
#ifndef CONFIG_K210_UART_SUPRESS_CONFIG
uint32_t baud; /* Configured baud */
uint32_t uartclk; /* UART clock frequency */
#endif
uart_datawidth_t ier; /* Saved IER value */
uint8_t irq; /* IRQ associated with this UART */
#ifndef CONFIG_K210_16550_SUPRESS_CONFIG
#ifndef CONFIG_K210_UART_SUPRESS_CONFIG
uint8_t parity; /* 0=none, 1=odd, 2=even */
uint8_t bits; /* Number of bits (7 or 8) */
int stopbits2; /* true: Configure with 2 stop bits instead of 1 */
@ -319,7 +319,7 @@ struct k210_16550_s
*
* Description:
* These functions must be provided by the processor-specific code in order
* to correctly access 16550 registers
* to correctly access registers
* uart_ioctl() is optional to provide custom IOCTLs
*
****************************************************************************/
@ -334,6 +334,6 @@ void uart_putreg(uart_addrwidth_t base,
struct file; /* Forward reference */
int uart_ioctl(struct file *filep, int cmd, unsigned long arg);
void k210_uart_16550_register(void);
#endif /* CONFIG_K210_16550_UART */
void k210_uart_register(void);
#endif /* CONFIG_K210_UART */
#endif /* __INCLUDE_NUTTX_SERIAL_UART_16550_H */

View File

@ -702,6 +702,14 @@ config ARCH_BOARD_XIDATONG_RISCV64
This is the board configuration for the port of NuttX to the
xidatong-riscv64 board. This board features the RISC-V K210
config ARCH_BOARD_EDU_RISCV64
bool "edu riscv64 board"
depends on ARCH_CHIP_K210
select ARCH_HAVE_LEDS if !K210_WITH_QEMU
---help---
This is the board configuration for the port of NuttX to the
edu-riscv64 board. This board features the RISC-V K210
config ARCH_BOARD_SMARTL_C906
bool "smartl evaluation board for C906"
depends on ARCH_CHIP_C906
@ -2502,6 +2510,7 @@ config ARCH_BOARD
default "maix-bit" if ARCH_BOARD_MAIX_BIT
default "aiit-riscv64-board" if ARCH_BOARD_AIIT_RISCV64
default "xidatong-riscv64" if ARCH_BOARD_XIDATONG_RISCV64
default "edu-riscv64" if ARCH_BOARD_EDU_RISCV64
default "smartl-c906" if ARCH_BOARD_SMARTL_C906
default "icicle" if ARCH_BOARD_ICICLE_MPFS
default "m100pfsevp" if ARCH_BOARD_M100PFSEVP_MPFS
@ -3338,6 +3347,9 @@ endif
if ARCH_BOARD_XIDATONG_RISCV64
source "boards/risc-v/k210/xidatong-riscv64/Kconfig"
endif
if ARCH_BOARD_EDU_RISCV64
source "boards/risc-v/k210/edu-riscv64/Kconfig"
endif
if ARCH_BOARD_SMARTL_C906
source "boards/risc-v/c906/smartl-c906/Kconfig"
endif